Org Mode Syllabus
Table of Contents
- 1. Week 1: Foundation (10 hours)
- 2. Top level
- 3. TODO Write documentation
- 4. DONE Review pull request
- 5. DONE Review pull request
- 6. TODO Fix critical bug
- 7. TODO Update documentation
- 8. TODO Refactor helper function
- 9. TODO Review PR code review
- 10. DONE Write blog post writing published
- 11. Week 2: Task Management (10 hours)
- 12. Meeting notes
- 13. TODO Write report
- 14. TODO Submit proposal
- 15. TODO Weekly review
- 16. TODO Write documentation
- 17. TODO Review PR #347
- 18. Week 3: Literate Programming with Org-babel (10 hours)
- 19. Week 4: Export and Publishing (10 hours)
- 20. Week 5: Capture and Refile (8 hours)
- 21. Week 6: Advanced Features (12 hours)
- 22. DONE Old task
- 23. Encrypted Heading crypt
- 24. Extensions and Ecosystem
- 25. Post Title
- 26. Assessment and Practice
- 27. Data Analysis
- 28. Reference
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
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
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
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
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:
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"- Descriptionentry- 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:
C-c c t(capture task)- Type task description
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.
- Create
~/org/tasks.org - Add three TODO items with priorities
- Schedule one for today, set deadline on another
- Configure
org-agenda-filesto includetasks.org - Open agenda (
C-c a a) and verify items appear - 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- ")))
- Add this template
- Capture a review (
C-c c w) - Fill in completed items and goals
- Finalize with
C-c C-c
Expected time: 20 minutes.
26.3. Exercise 3: Literate Analysis
Analyze a CSV dataset with org-babel.
- Create
analysis.org - Add a Python block to load data
- Add blocks to compute mean, median, standard deviation
- Use
:sessionto share data between blocks - 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.
- Create directory
~/site/org/with three.orgfiles - Create
~/site/static/withstyle.css - Configure
org-publish-project-alist - Add cross-reference links between files
- Publish project (
C-c C-e P x) - 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")))))))
- Tag tasks with
@home,@office,@errands - Add this configuration
- Test views with
C-c a handC-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 manualC-h f org-<TAB>- List all org functions