← 11. Literate Programming 13. Advanced Features →

Chapter 12: Export and Publishing - From Plain Text to Beautiful Documents My Document

Your org files are packed with knowledge, tasks, code, and data. Sometimes you need to share them with people who don’t use Org-Mode (the unfortunate majority). Time to export.

Press C-c C-e and watch plain text become polished documents.

1. The Export Dispatcher

C-c C-e opens the export menu:

Export dispatcher

Select an export method:
 [h] HTML
 [l] LaTeX
 [p] PDF
 [m] Markdown
 [a] ASCII/UTF-8/Latin1
 [o] ODT (OpenDocument)
 [i] iCalendar
...

Each format has sub-options (export to file, copy to clipboard, open in browser, etc.).

Most common: C-c C-e h o - Export to HTML and open in browser.

2. HTML Export

C-c C-e h h - Export to HTML file

Org converts:

  • Headings → HTML headers (<h1>, <h2>, etc.)
  • Lists → <ul>, <ol>, <li>
  • Tables → <table> with styling
  • Code blocks → Syntax-highlighted <pre> blocks
  • Links → <a href>
  • Emphasis → <strong>, <em>, etc.

The result? Professional web pages from plain text.

2.1. HTML Export Options

Control export with options at file start:

#+TITLE: My Document
#+AUTHOR: Your Name
#+EMAIL: you@example.com
#+DATE: 2025-01-15
#+OPTIONS: toc:2 num:t ^:nil
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css" />

Common OPTIONS:

  • toc:2 - Table of contents, 2 levels deep
  • toc:nil - No table of contents
  • num:t - Number headings
  • num:nil - Don’t number headings
  • ^:nil - Don’t treat ^ as superscript
  • ':t - Smart quotes
  • H:3 - Export 3 heading levels (rest become lists)

2.2. Custom CSS

Make it beautiful:

#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="my-style.css" />
#+HTML_HEAD: <style>body { font-family: sans-serif; max-width: 800px; margin: auto; }</style>

Or use export templates (more later).

2.3. HTML5 Export

Modern semantic HTML:

(setq org-html-html5-fancy t)
(setq org-html-doctype "html5")

Generates clean, semantic markup.

3. PDF Export (via LaTeX)

C-c C-e l p - Export to PDF via LaTeX

Org generates LaTeX, then compiles to PDF. Result: professional typesetting.

Requires LaTeX installed (TeXLive, MiKTeX, MacTeX).

3.1. LaTeX Configuration

#+LATEX_CLASS: article
#+LATEX_CLASS_OPTIONS: [12pt,a4paper]
#+LATEX_HEADER: \usepackage{geometry}
#+LATEX_HEADER: \geometry{margin=1in}

Control document class, packages, formatting.

3.2. Custom LaTeX Classes

Define document types:

(add-to-list 'org-latex-classes
             '("myarticle"
               "\\documentclass{article}
                \\usepackage[margin=1in]{geometry}
                \\usepackage{palatino}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))

Then in org file:

#+LATEX_CLASS: myarticle

Custom layouts for reports, papers, books.

3.3. Beamer Presentations

Academic presentations:

#+begin_example

4. Introduction

4.1. Slide One

  • Point one
  • Point two

4.2. Slide Two

More content #+end_example

Export to PDF: instant presentation slides.

5. Markdown Export

C-c C-e m m - Export to Markdown

For GitHub READMEs, Jekyll blogs, or Markdown-based systems.

Org’s Markdown export supports:

  • GitHub Flavored Markdown
  • Standard Markdown
  • Various Markdown dialects

Configure:

(setq org-md-headline-style 'atx)  ; Use ## style headers

6. ASCII/Text Export

C-c C-e t A - Export to plain text

No formatting, just text. Perfect for email or environments without rich text.

Org maintains structure through indentation and ASCII art.

7. ODT (OpenDocument) Export

C-c C-e o o - Export to ODT

Opens in LibreOffice, Word, Google Docs. For corporate environments stuck on proprietary formats.

Custom styles:

#+ODT_STYLES_FILE: "my-styles.odt"

8. Publishing Systems

Export single files is fine. Publishing entire sites from org files? Next level.

8.1. Simple Publishing Setup

(setq org-publish-project-alist
      '(("my-website"
         :base-directory "~/org/website/"
         :publishing-directory "~/public_html/"
         :publishing-function org-html-publish-to-html
         :section-numbers nil
         :with-toc nil
         :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />")))

Run M-x org-publish-project RET my-website

Every .org file in ~/org/website/ converts to HTML in ~/public_html/. Upload to server. Instant website.

8.2. Project Components

Separate org files and static assets:

(setq org-publish-project-alist
      '(("org-files"
         :base-directory "~/website/org/"
         :publishing-directory "~/website/public/"
         :publishing-function org-html-publish-to-html)

        ("static-files"
         :base-directory "~/website/org/"
         :publishing-directory "~/website/public/"
         :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf"
         :publishing-function org-publish-attachment)

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

M-x org-publish-project RET website publishes everything.

8.3. Blog with Org

Many use org-publish for blogs:

~/blog/
  ├── posts/
  │   ├── 2025-01-15-first-post.org
  │   ├── 2025-01-20-second-post.org
  │   └── index.org
  ├── style.css
  └── publish.el

Each post is an org file. Publish generates static site. Add git hooks to auto-publish on commit.

Static site generators like Hugo can consume org files directly.

9. Selective Export

9.1. Export Subtrees

Don’t want to export entire file? Export one subtree:

  1. Navigate to heading
  2. C-c C-e C-s - Enable subtree export
  3. Choose format

Only that section exports.

9.2. Export Settings per Heading

#+begin_example

10. Document for Client

10.1. Background

10.2. Approach

10.3. Budget

#+end_example

Export this subtree → generates proposal.pdf with custom title and no table of contents.

10.4. Tags and Export

Exclude sections:

#+begin_example

11. Published Section

This exports.

12. Introduction

13. Methods

14. Results

15. Export Filters and Hooks

Customize export process:

(defun my-org-export-filter (text backend info)
  "Replace TODO with custom formatting."
  (when (org-export-derived-backend-p backend 'html)
    (replace-regexp-in-string
     "TODO" "<span class=\"todo\">TODO</span>" text)))

(add-to-list 'org-export-filter-final-output-functions
             'my-org-export-filter)

Transform exported content programmatically.

16. Code Block Export

Remember :exports from Chapter 11?

#+BEGIN_SRC python :exports both
print("Hello!")
#+end_src
  • :exports code - Show only code in export
  • :exports results - Show only output
  • :exports both - Show code and output
  • :exports none - Execute but hide from export

Control what readers see.

17. Custom Export Templates

Create reusable export configurations:

#+SETUPFILE: ~/.emacs.d/org-templates/article.setup

In article.setup:

#+OPTIONS: toc:2 num:t
#+LATEX_CLASS: article
#+LATEX_HEADER: \usepackage{my-packages}
#+HTML_HEAD: <link rel="stylesheet" href="style.css" />

Consistent formatting across documents.

18. Export to Different Formats from Same Source

Write once, export many:

#+begin_example

19. Introduction

Content here.

20. Details

More content. #+end_example

Export as:

  • HTML for web
  • PDF for print
  • Markdown for GitHub
  • ODT for collaborators on Word

Single source, multiple outputs. Change once, re-export all.

21. Advanced: Custom Exporters

Org’s export framework is extensible. Define custom backends:

(org-export-define-derived-backend 'my-custom 'html
  :translate-alist '((headline . my-custom-headline)))

(defun my-custom-headline (headline contents info)
  ;; Custom headline formatting
  )

Export to custom formats, APIs, databases—anything.

22. iCalendar Export

Export TODOs and scheduled items to calendar format:

C-c C-e c f - Export to .ics file

Import into Google Calendar, Outlook, Apple Calendar. Your org tasks sync to external calendars.

Automate:

(setq org-icalendar-include-todo t)
(setq org-icalendar-use-deadline '(event-if-todo event-if-not-todo))

23. Continuous Publishing Workflow

Automate publishing:

  1. Write in org
  2. Save
  3. Export hook auto-generates HTML
  4. Git commit hook pushes to server
  5. Website updates

One command from edit to publish:

(defun my-org-publish-on-save ()
  (when (eq major-mode 'org-mode)
    (org-publish-current-file)))

(add-hook 'after-save-hook 'my-org-publish-on-save)

Every save publishes. Instant feedback.

24. Your Exercise

  1. Create a document with headings, lists, tables, and code blocks
  2. Export to HTML (C-c C-e h o)
  3. Export to PDF if you have LaTeX installed (C-c C-e l p)
  4. Export to Markdown (C-c C-e m m)
  5. Try exporting just a subtree
  6. Add export options (title, author, CSS)
  7. Experiment with :exports options in code blocks
  8. Set up a simple publishing project (even if just for local HTML)

25. The Philosophy of Export

Plain text is the source of truth. Everything else is a view.

Write in org—structured, powerful, future-proof. Export for specific audiences and contexts. HTML for web, PDF for print, Markdown for GitHub, ODT for corporate.

Single source, infinite presentations.

Other tools force you to choose: write for web or print? Org says “write once, choose later.”

26. Next: Advanced Features and the Road Ahead

You’ve learned the core: structure, tasks, time tracking, capture, code, export. Chapter 13 explores the advanced features that make Org-Mode inexhaustible: advanced agenda, custom workflows, encryption, integration, and the broader ecosystem. The journey continues.

Org-Mode with Emacs — CC0 1.0 Universal  ·  Built with Org-Mode & Emacs