This post is part of the Orgmode Almanac series.

Background

One of the best things about writing in orgmode is that we can embed and execute arbitrary code snippets. However, not all languages have an exporter, for obvious reasons. Somewhat surprisingly, there is no way to call pandoc on embedded snippets, which feels like a waste, especially when a whole bunch of documentation formats can be converted to orgmode with it.

Consider the following beautifully highlighted snippet of an rst (ReStructured Text) list table.

 1.. list-table:: Title
 2   :widths: 25 25 50
 3   :header-rows: 1
 4
 5   * - Heading row 1, column 1
 6     - Heading row 1, column 2
 7     - Heading row 1, column 3
 8   * - Row 1, column 1
 9     -
10     - Row 1, column 3
11   * - Row 2, column 1
12     - Row 2, column 2
13   - Row 2, column 3

Trying to run this will generate the sort of obvious error:

1org-babel-execute-src-block: No org-babel-execute function for rst!

Writing an Exporter

For this post, I will be focusing on rst, but this can be defined for any of the pandoc back-ends. The approach was inspired by ob-markdown.

 1(defun org-babel-execute:rst (body params)
 2  "Execute a block of rst code with org-babel.
 3This function is called by `org-babel-execute-src-block'."
 4  (let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
 5       (in-file (org-babel-temp-file "rst-"))
 6       (cmdline (cdr (assoc :cmdline params)))
 7       (to (cdr (assoc :to params)))
 8       (template (cdr (assoc :template params)))
 9       (cmd (concat "pandoc"
10                    " -t  org"
11                    " -i " (org-babel-process-file-name in-file)
12                    " -f rst "
13                    " " cmdline)))
14    (with-temp-file in-file (insert body))
15    (message cmd)
16    (shell-command-to-string cmd))) ;; Send to results
17
18(defun org-babel-prep-session:rst (session params)
19  "Return an error because rst does not support sessions."
20  (error "rst does not support sessions"))

Trying it out

With that done, it is pretty trivial to re-run the above example.

 1.. list-table:: Title
 2   :widths: 25 25 50
 3   :header-rows: 1
 4
 5   * - Heading row 1, column 1
 6     - Heading row 1, column 2
 7     - Heading row 1, column 3
 8   * - Row 1, column 1
 9     -
10     - Row 1, column 3
11   * - Row 2, column 1
12     - Row 2, column 2
13   - Row 2, column 3
Heading row 1, column 1Heading row 1, column 2Heading row 1, column 3
Row 1, column 1Row 1, column 3
Row 2, column 1Row 2, column 2

Note that we have used rst :exports both :results raw as the header argument.

Conclusions

Will probably follow this up with an actual package, which should handle the entire spectrum of pandoc back-ends.


Series info

Orgmode Almanac series

  1. Replacing Jupyter with Orgmode
  2. Using Mathematica with Orgmode
  3. Pandoc to Orgmode with Babel <-- You are here!
  4. An Orgmode Note Workflow
  5. Temporary LaTeX Documents with Orgmode
  6. Anki Decks with Orgmode