Org Mode Syllabus

Table of Contents

1. Week 1: Foundation (10 hours)

Org-mode is plain text with structure. Headlines, lists, and markup create documents that export to HTML, PDF, or other formats.

1.1. Installation

corrected · pilot-annotation-pass · 2026-10-08

Org-mode has shipped with Emacs by default since Emacs 22.1 (2007). Check your version.

(org-version)

For the latest version, install from MELPA.

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(package-refresh-contents)
(package-install 'org)

1.2. Syntax Basics

Headlines use asterisks. More asterisks mean deeper nesting.

#+begin_example

2. Top level

2.1. Second level

2.1.1. Third level

#+end_example

Lists use hyphens, plus signs, or numbers.

- Unordered item
- Another item
  - Nested item

1. Ordered item
2. Second item

Definition lists pair terms with descriptions.

- Term :: Definition
- Org-mode :: Plain text markup system

2.2. Text Formatting

Emphasis markers surround text. They require whitespace or punctuation boundaries.

*bold* /italic/ _underline_ =verbatim= ~code~

Formatted output:

bold italic underline verbatim code

2.3. Links

Internal links target headlines, custom IDs, or line numbers.

[[*Week 1: Foundation]]
[[#custom-id]]

External links use URL syntax.

[[https://orgmode.org][Org-mode website]]
[[file:~/documents/notes.org]]
[[file:~/documents/notes.org::*Specific Headline]]

File links can jump to specific headlines within the target.

2.4. TODO Keywords

Tasks use TODO states. Default keywords: TODO and DONE.

#+begin_example

3. TODO Write documentation

4. DONE Review pull request

#+end_example

Cycle states with C-c C-t. Org records completion timestamps when configured.

(setq org-log-done 'time)

With logging enabled:

#+begin_example

5. DONE Review pull request

#+end_example

5.1. Priorities

Three priority levels: [#A], [#B], [#C]. Set with C-c ,.

#+begin_example

6. TODO Fix critical bug

7. TODO Update documentation

8. TODO Refactor helper function

#+end_example

Priorities affect agenda sorting.

8.1. Tags

Tags group related items. Attach with C-c C-q.

#+begin_example

9. TODO Review PR   code review

10. DONE Write blog post   writing published

#+end_example

Tags inherit down the tree.

Search by tag with C-c / m (sparse tree) or C-c a m (agenda).

10.1. Configuration

Create ~/.emacs.d/init.el or use M-x customize-group RET org RET.

Essential settings:

;; Set agenda files
(setq org-agenda-files '("~/org/"))

;; Log completion time
(setq org-log-done 'time)

;; Enable speed keys (single-key commands on headlines)
(setq org-use-speed-commands t)

;; Indent content under headlines
(setq org-startup-indented t)

Speed keys allow single-key navigation when point is at headline start: n next, p previous, u up, t cycle TODO state.

11. Week 2: Task Management (10 hours)

Org-mode tracks tasks, deadlines, and schedules. The agenda view aggregates items across files into a daily or weekly dashboard.

11.1. Timestamps

Three timestamp types: plain, scheduled, and deadline.

#+begin_example

12. Meeting notes

<2026-05-22 Fri 14:00>

13. TODO Write report

14. TODO Submit proposal

#+end_example

Insert timestamps with C-c .. Time-of-day is optional.

Repeating intervals use +1d, +1w, +1m, +1y syntax.

#+begin_example

15. TODO Weekly review

#+end_example

Org shifts the date forward when marked DONE.

15.1. Agenda Views

The agenda compiles items from all files in org-agenda-files.

Open agenda with C-c a. Common commands:

Key Command
a Week view
t Global TODO list
m Tag search
s Text search

Week view shows scheduled and deadline items by date.

;; Set agenda span to 7 days
(setq org-agenda-span 7)

;; Start week on Monday
(setq org-agenda-start-on-weekday 1)

Agenda navigation:

Key Action
n/p Next/previous line
f/b Forward/backward one span
. Go to today
j Jump to date

Agenda actions:

Key Action
t Cycle TODO state
, Set priority
: Set tags
C-c C-s Schedule
C-c C-d Set deadline

15.2. Clocking

Track time spent on tasks. Start with C-c C-x C-i, stop with C-c C-x C-o.

#+begin_example

16. TODO Write documentation

#+end_example

Clock reports summarize time.

#+BEGIN: clocktable :scope file :maxlevel 2
#+CAPTION: Clock summary at [2026-05-22 Fri 15:30]
| Headline              | Time   |
|-----------------------+--------|
| *Total time*          | *1:30* |
|-----------------------+--------|
| TODO Write documentation | 1:30   |
#+END:

Update reports with C-c C-c on the #+BEGIN: line.

16.1. Properties and Columns

Properties attach metadata to headlines.

#+begin_example

17. TODO Review PR #347

#+end_example

Set properties with C-c C-x p.

Column view displays properties as a table. Define columns:

#+COLUMNS: %40ITEM %TODO %EFFORT %ASSIGNED

Open column view with C-c C-x C-c. Edit values inline.

17.1. Custom TODO Workflows

Extend TODO keywords beyond TODO/DONE.

(setq org-todo-keywords
      '((sequence "TODO(t)" "IN-PROGRESS(i)" "BLOCKED(b)" "|" "DONE(d)" "CANCELLED(c)")))

The pipe separates active states from completed states. Letters in parentheses are selection keys.

Multi-workflow configuration:

(setq org-todo-keywords
      '((sequence "TODO(t)" "IN-PROGRESS(i)" "|" "DONE(d)")
        (sequence "REPORT(r)" "BUG(b)" "|" "FIXED(f)")
        (sequence "|" "CANCELLED(c)")))

18. Week 3: Literate Programming with Org-babel (10 hours)

verified · pilot-annotation-pass · 2026-10-08

Org-babel executes code blocks inside documents. Results appear inline. The system supports 40+ languages.

18.1. Code Block Syntax

Blocks start with #+begin_src and end with #+end_src.

#+begin_src python
return 2 + 2
#+end_src

Execute with C-c C-c.

#+RESULTS:
: 4

18.2. Language Support

Enable languages in init.el.

(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)
   (shell . t)
   (emacs-lisp . t)
   (sql . t)
   (js . t)))

Each language requires its runtime installed on the system.

18.3. Header Arguments

Header arguments control execution behavior.

#+begin_src python :results output
print("Hello")
print("World")
#+end_src

#+RESULTS:
: Hello
: World

Common arguments:

Argument Effect
:results output Capture stdout
:results value Return final expression (default)
:results silent Don't insert results
:exports code Export only code
:exports results Export only results
:exports both Export code and results
:session name Persistent interpreter session

18.4. Sessions

Sessions maintain state across blocks.

#+begin_src python :session analysis
data = [1, 2, 3, 4, 5]
#+end_src

#+begin_src python :session analysis
sum(data)
#+end_src

#+RESULTS:
: 15

Both blocks share the analysis session. The data variable persists.

18.5. File Output

Write results to files.

#+begin_src python :results file :file histogram.png
import matplotlib.pyplot as plt
plt.hist([1, 2, 2, 3, 3, 3, 4, 4, 5])
plt.savefig('histogram.png')
return 'histogram.png'
#+end_src

#+RESULTS:
[[file:histogram.png]]

The file link embeds in the document.

18.6. Tangling

Extract code blocks to source files. Add :tangle header.

#+begin_src python :tangle analysis.py
def process_data(items):
    return [x * 2 for x in items]

if __name__ == '__main__':
    print(process_data([1, 2, 3]))
#+end_src

Run C-c C-v t to write analysis.py.

Directory-level tangling:

#+PROPERTY: header-args :tangle yes

All blocks in the file tangle by default.

18.7. Noweb References

Reference other blocks by name.

#+name: load-data
#+begin_src python
data = [1, 2, 3, 4, 5]
#+end_src

#+begin_src python :noweb yes
<<load-data>>
print(sum(data))
#+end_src

The <<load-data>> reference expands to the named block's content.

18.8. Variables

Pass data between blocks.

#+begin_src python :var x=5 :var y=10
return x + y
#+end_src

#+RESULTS:
: 15

Variables can reference tables, lists, or other block results.

#+name: data-table
| Name  | Value |
|-------+-------|
| Alpha |    10 |
| Beta  |    20 |

#+begin_src python :var table=data-table
return sum([row[1] for row in table])
#+end_src

#+RESULTS:
: 30

19. Week 4: Export and Publishing (10 hours)

Org-mode exports to HTML, LaTeX, PDF, Markdown, and other formats. The publishing system manages multi-file projects with cross-references and sitemaps.

19.1. Basic Export

Export current file with C-c C-e. The export dispatcher shows available backends.

Key Backend
h h HTML
h o HTML and open in browser
l l LaTeX
l p PDF via LaTeX
m Markdown
t Plain text

HTML export creates a standalone file with embedded CSS.

19.2. Export Options

Control export with #+OPTIONS:.

#+OPTIONS: toc:2 num:t timestamp:nil author:t email:t
Option Effect
toc:2 Table of contents, 2 levels
num:t Number headlines
timestamp:nil Omit timestamp
author:t Include author
email:t Include email
^:nil Disable sub/superscripts

19.3. HTML Customization

Add custom CSS.

#+HTML_HEAD: <link rel="stylesheet" href="style.css"/>

Or inline styles:

(setq org-html-head-include-default-style nil)
(setq org-html-head "<style>
body { max-width: 800px; margin: auto; }
h1, h2, h3 { color: #333; }
</style>")

19.4. Publishing Projects

Define projects in init.el.

(setq org-publish-project-alist
      '(("website"
         :base-directory "~/site/org/"
         :publishing-directory "~/site/html/"
         :publishing-function org-html-publish-to-html
         :recursive t
         :section-numbers nil
         :with-toc t)))

Publish with C-c C-e P x (choose project from list).

Multi-component projects:

(setq org-publish-project-alist
      '(("org-notes"
         :base-directory "~/site/org/"
         :publishing-directory "~/site/html/"
         :publishing-function org-html-publish-to-html)

        ("org-static"
         :base-directory "~/site/org/"
         :publishing-directory "~/site/html/"
         :base-extension "css\\|js\\|png\\|jpg"
         :publishing-function org-publish-attachment)

        ("website" :components ("org-notes" "org-static"))))

The website project composes the other two.

19.5. Cross-References

Link between files.

See [[file:other-document.org][the other document]] for details.

Links resolve during export. The HTML export converts file links to .html extensions.

19.6. Sitemap Generation

Enable automatic sitemap.

(setq org-publish-project-alist
      '(("website"
         :base-directory "~/site/org/"
         :publishing-directory "~/site/html/"
         :publishing-function org-html-publish-to-html
         :auto-sitemap t
         :sitemap-filename "sitemap.org"
         :sitemap-title "Site Index"
         :sitemap-sort-files anti-chronologically)))

Org generates sitemap.org listing all published files.

19.7. PDF Export

PDF export uses LaTeX. Requires pdflatex or xelatex.

(setq org-latex-pdf-process
      '("pdflatex -interaction nonstopmode %f"
        "pdflatex -interaction nonstopmode %f"))

For bibliographies, add bibtex:

(setq org-latex-pdf-process
      '("pdflatex %f"
        "bibtex %b"
        "pdflatex %f"
        "pdflatex %f"))

Custom LaTeX classes:

(add-to-list 'org-latex-classes
             '("article"
               "\\documentclass[11pt]{article}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")))

20. Week 5: Capture and Refile (8 hours)

Capture templates create structured notes from anywhere in Emacs. Refile moves entries between files and headlines.

20.1. Capture Setup

Configure capture templates.

(setq org-capture-templates
      '(("t" "Task" entry (file+headline "~/org/tasks.org" "Inbox")
         "* TODO %?\n  %i\n  %a")

        ("n" "Note" entry (file+datetree "~/org/notes.org")
         "* %?\n%U\n")))

Template components:

  • t - Selection key
  • "Task" - Description
  • entry - Type (entry, item, checkitem, table-line, plain)
  • (file+headline ...) - Target location
  • * TODO %? - Template content

Template expansion codes:

Code Expands to
%? Cursor position after expansion
%i Selected text
%a Link to current location
%U Inactive timestamp
%t Active timestamp
%^{Prompt} Interactive prompt

20.2. Capture Workflow

Invoke capture with C-c c. Select template. Fill content. Finalize with C-c C-c or abort with C-c C-k.

From anywhere in Emacs:

  1. C-c c t (capture task)
  2. Type task description
  3. C-c C-c (file to ~/org/tasks.org)

The original buffer is restored.

20.3. Advanced Templates

Multi-field templates use prompts.

(setq org-capture-templates
      '(("m" "Meeting" entry (file+headline "~/org/work.org" "Meetings")
         "* %^{Meeting Title} %^g\n%U\n** Attendees\n- %?\n** Notes\n")))

%^{Meeting Title} prompts for input. %^g prompts for tags.

20.4. Refile

Move entries to different locations.

Basic refile targets:

(setq org-refile-targets
      '((org-agenda-files :maxlevel . 2)))

This allows refiling to any level-1 or level-2 headline in agenda files.

Refined targeting:

(setq org-refile-targets
      '(("~/org/tasks.org" :maxlevel . 2)
        ("~/org/projects.org" :level . 1)
        ("~/org/archive.org" :maxlevel . 1)))

Refile current entry with C-c C-w. Select target with completion.

20.5. Refile Configuration

Allow creating new parent nodes:

(setq org-refile-allow-creating-parent-nodes 'confirm)

Use full outline paths for disambiguation:

(setq org-refile-use-outline-path 'file)

Show full path in completion:

(setq org-outline-path-complete-in-steps nil)

21. Week 6: Advanced Features (12 hours)

Archive completed tasks. Build custom agenda views. Extend Org with hooks and functions.

21.1. Archiving

Archive moves old entries out of active files.

Default archive location: <filename>_archive. Archive with C-c C-x C-a.

#+begin_example

22. DONE Old task

#+end_example

After archiving, the entry moves to <filename>_archive::* Archived tasks.

Custom archive location:

(setq org-archive-location "~/org/archive.org::* From %s")

%s expands to the source filename.

Per-file archive:

#+ARCHIVE: archive.org::* Archived

Archive subtree: C-c C-x C-s. Org archives children too.

22.1. Custom Agenda Views

Define multi-step agenda views.

(setq org-agenda-custom-commands
      '(("w" "Work Dashboard"
         ((agenda "" ((org-agenda-span 7)))
          (tags-todo "work"
                     ((org-agenda-overriding-header "Work Tasks")))
          (tags-todo "urgent"
                     ((org-agenda-overriding-header "Urgent Items")))))))

Access with C-c a w.

Filtering by property:

(setq org-agenda-custom-commands
      '(("p" "Project Review"
         ((tags "PROJECT=\"website\""
                ((org-agenda-overriding-header "Website Tasks")))))))

22.2. Stuck Projects

Identify stalled projects.

(setq org-stuck-projects
      '("+PROJECT/-DONE"  ; Tags/todo match for projects
        ("TODO" "IN-PROGRESS")  ; Active todo keywords
        nil  ; No skip conditions
        ""))  ; Property match

View with C-c a #.

A project is stuck if it has no next actions (no TODO or IN-PROGRESS children).

22.3. Hooks

Run functions on specific events.

;; After marking DONE, clock out automatically
(add-hook 'org-after-todo-state-change-hook
          (lambda ()
            (when (string= org-state "DONE")
              (org-clock-out-if-current))))

;; Before saving, clean whitespace
(add-hook 'org-mode-hook
          (lambda ()
            (add-hook 'before-save-hook 'whitespace-cleanup nil 'local)))

22.4. Custom Functions

Extend Org with elisp.

Auto-tag entries based on headline text:

(defun my/auto-tag-bug ()
  "Add :bug: tag to headlines containing 'bug' or 'fix'."
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "^\\*+ .*(bug|fix)" nil t)
      (org-set-tags ":bug:"))))

Call with M-x my/auto-tag-bug.

22.5. Org-attach

Attach files to headlines.

Create attachment directory: C-c C-a m.

Attach file: C-c C-a a. Org copies the file to data/<uuid>/.

Open attachments: C-c C-a o.

Configuration:

(setq org-attach-directory "~/org/attachments/")
(setq org-attach-method 'mv)  ; Move instead of copy

Attachments link to headlines via ID property.

22.6. Encryption

Encrypt entries with GPG.

(require 'org-crypt)
(org-crypt-use-before-save-magic)
(setq org-crypt-key "your@email.com")

Tag entries for encryption:

#+begin_example

23. Encrypted Heading   crypt

This content will be encrypted. #+end_example

Encrypt with M-x org-encrypt-entry. Decrypt with M-x org-decrypt-entry.

Org auto-encrypts tagged entries on save.

24. Extensions and Ecosystem

24.1. org-roam

Zettelkasten note-taking system.

(use-package org-roam
  :ensure t
  :custom
  (org-roam-directory "~/org-roam/")
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert))
  :config
  (org-roam-db-autosync-mode))

Create notes with C-c n f. Link notes with C-c n i. The backlinks buffer shows connections.

24.2. org-ref

Citation management for academic writing.

(use-package org-ref
  :ensure t
  :config
  (setq org-ref-default-bibliography '("~/bibliography/references.bib")))

Insert citations with C-c ]. Export to LaTeX includes BibTeX references.

24.3. ox-hugo

Export to Hugo markdown.

(use-package ox-hugo
  :ensure t
  :after ox)

Add Hugo front-matter:

#+begin_example

25. Post Title

Content here. #+end_example

Export with C-c C-e H H.

25.1. org-journal

Daily journal entries.

(use-package org-journal
  :ensure t
  :custom
  (org-journal-dir "~/org/journal/")
  (org-journal-file-format "%Y-%m-%d.org"))

Create today's entry with C-c C-j.

25.2. org-super-agenda

Enhanced agenda grouping.

(use-package org-super-agenda
  :ensure t
  :config
  (org-super-agenda-mode))

(setq org-super-agenda-groups
      '((:name "Today"
         :time-grid t
         :scheduled today)
        (:name "Urgent"
         :priority "A")
        (:name "Work"
         :tag "work")))

26. Assessment and Practice

26.1. Exercise 1: Task Management System

Build a personal task system.

  1. Create ~/org/tasks.org
  2. Add three TODO items with priorities
  3. Schedule one for today, set deadline on another
  4. Configure org-agenda-files to include tasks.org
  5. Open agenda (C-c a a) and verify items appear
  6. Mark one DONE from the agenda

Expected time: 30 minutes.

26.2. Exercise 2: Weekly Review Template

Create a capture template for weekly reviews.

(setq org-capture-templates
      '(("w" "Weekly Review" entry
         (file+datetree "~/org/reviews.org")
         "* Week %<%U> Review\n** Completed\n- %?\n** Goals\n- \n** Notes\n- ")))
  1. Add this template
  2. Capture a review (C-c c w)
  3. Fill in completed items and goals
  4. Finalize with C-c C-c

Expected time: 20 minutes.

26.3. Exercise 3: Literate Analysis

Analyze a CSV dataset with org-babel.

  1. Create analysis.org
  2. Add a Python block to load data
  3. Add blocks to compute mean, median, standard deviation
  4. Use :session to share data between blocks
  5. Export to HTML

Sample structure:

#+begin_example

27. Data Analysis

import pandas as pd
data = pd.read_csv('data.csv')
print(data.head())
data['value'].mean()

#+end_example

Expected time: 45 minutes.

27.1. Exercise 4: Publishing Workflow

Publish a multi-file project.

  1. Create directory ~/site/org/ with three .org files
  2. Create ~/site/static/ with style.css
  3. Configure org-publish-project-alist
  4. Add cross-reference links between files
  5. Publish project (C-c C-e P x)
  6. Verify HTML output and links

Expected time: 60 minutes.

27.2. Exercise 5: Custom Agenda View

Build a context-based agenda.

(setq org-agenda-custom-commands
      '(("h" "Home Context"
         ((tags-todo "@home"
                     ((org-agenda-overriding-header "Home Tasks")))
          (tags-todo "@errands"
                     ((org-agenda-overriding-header "Errands")))))
        ("o" "Office Context"
         ((agenda "" ((org-agenda-span 1)))
          (tags-todo "@office"
                     ((org-agenda-overriding-header "Office Tasks")))))))
  1. Tag tasks with @home, @office, @errands
  2. Add this configuration
  3. Test views with C-c a h and C-c a o

Expected time: 30 minutes.

28. Reference

28.1. Essential Keybindings

Command Key
Cycle visibility TAB
Cycle all S-TAB
Cycle TODO state C-c C-t
Set priority C-c ,
Set tags C-c C-q
Insert timestamp C-c .
Schedule C-c C-s
Set deadline C-c C-d
Open agenda C-c a
Capture C-c c
Refile C-c C-w
Archive C-c C-x C-a
Clock in C-c C-x C-i
Clock out C-c C-x C-o
Execute code block C-c C-c
Export C-c C-e

28.2. Common Export Options

Option Effect
#+TITLE: Document title
#+AUTHOR: Author name
#+DATE: Publication date
#+EMAIL: Author email
#+DESCRIPTION: Meta description
#+KEYWORDS: Meta keywords
#+OPTIONS: toc:n Table of contents depth
#+OPTIONS: num:t Number headlines
#+OPTIONS: ^:nil Disable sub/superscripts

28.3. Org-babel Languages

Partial list. Enable in org-babel-load-languages.

Language Key
Python python
Shell shell
Emacs Lisp emacs-lisp
SQL sql
JavaScript js
R R
Ruby ruby
Go go
Rust rust
C C

28.4. Further Resources

verified · pilot-annotation-pass · 2026-10-08
  • Org Manual - Complete reference
  • Worg - Community wiki
  • org-roam-ui - Graph visualization
  • M-x org-info - Built-in info manual
  • C-h f org-<TAB> - List all org functions

29. Related