Writing an Org-mode backend

\(\DeclareMathOperator{\Spec}{Spec}\) \(\DeclareMathOperator{\Proj}{Proj}\) \(\DeclareMathOperator{\dom}{dom}\) \(\DeclareMathOperator{\ran}{ran}\) \(\DeclareMathOperator{\ar}{ar}\) \(\DeclareMathOperator{\var}{var}\) \(\DeclareMathOperator{\pred}{Pred(V,\mathcal{R})}\) \(\DeclareMathOperator{\encode}{encode}\) \(\DeclareMathOperator{\decode}{decode}\) \(\DeclareMathOperator{\supp}{supp}\) \(\DeclareMathOperator{\lcm}{lcm}\) \(\DeclareMathOperator{\seq}{seq}\) \(\DeclareMathOperator{\var}{var}\)

1. Introduction

If you have an org file how do you export it to HTML using your custom exporter? This is the question I set to answer for myself to improve my blog's generated pages. The org exporter framework is called ox, and below its usage is detailed. A good place to find documentation on ox is the ox.el file itself that distributes with Emacs, and in particular one can start with the ;;; Commentary: comments in it. The entire exporting process is described in Advanced Export Configuration in the org manual.

2. Parsing org files in elisp

The syntax parser is called Org Elements, and its functions start with org-element-*. A blob in org-mode is the AST of a self-contained piece of the org file, such as a subtree, or a single element.

The function org-element-parse-buffer will return the AST of the entire org buffer.

(org-element-parse-buffer)

This AST blob is complicated and typically it is passed to other functions that can access its parts. A selective tree-walker is org-element-map, allowing us for instance to walk over the entire document, performing actions only on selected elements, while org-element-property can be used to extract a particular property of an element:

(org-element-map
  (org-element-parse-buffer)
  'headline
  (lambda (element)
    (format "%s" (org-element-property :raw-value element))))

Evaluating the above with the contents of this blog post thusfar will give:

("Introduction" "Parsing org files in elisp")

In the opposite direction we may convert a blob into its unparsed state with org-export-expand.

3. The transcoder

With ox.el, one does not need to sully their hands directly with the parsing functions. The transformation of the AST into the final output text is done by the transcoder, which calls programmer-specified transcoding functions, each of which is passed the blob, its contents, and a communication channel property list. The communication channel contains useful information, e.g. to find the author, date, and so on, typically set with #+AUTHOR:, #+DATE:, etc, one peeks at the communication channel with plist-get for :author, :date, and so on (for more see here).

The transcoder is defined using org-export-define-backend by a cons list of org element types and their corresponding transcoding functions.

4. Examples

A minimal example may be found here. The helpful comments in the elisp source file should aid you. It is a slimmed down version of ox-org.el that ships with Emacs. It essentially exports Org files to Org files, with minimal modification.

A more involved example is this blog! You can find the source code in ox-blorg.el, which is complemented by the publish.el script in my blog.