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. The system scales from quick notes to entire publishing workflows.

1.1. Installation

Org-mode ships with Emacs 27+. 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. A subtask inherits parent tags.

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 Thu 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)

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

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

Beyond core Org-mode, extensions provide specialized workflows.

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")))

The agenda groups items by criteria.

26. Assessment and Practice

Mastery requires practice. These exercises build fluency.

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

Quick reference for daily use.

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

  • 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