Literate Programming with Org Mode

1 Why Literate Programming?

There are lot of data on internet about "Literate Programming" already, I blog about this just for personal opinion.

It can organize things better with literal document style. Code is just another kind of text or meta-text used to generate other data like text results, tables, images, JSON, XML data etc.

Anyway, the start point is that I like Emacs and Org-mode very much, they are powerful, organize anything with them can be very flexible. I use Org-mode as the ultimate tool to organize knowledge and data as my external brain database, and my other applications of Org Mode.

2 How to Literate Programming with Org Mode?

2.1 LP: organize things in text and code

2.2 LP: organize logic with "headlines" and "tags"

You can navigation and filter Literate Programming document logic with headlines and tags. When a file grows large, organize your document with clear structure and better tags group is very necessary.

2.3 LP: write code with Org Babel source code blocks

Org Mode Babel are technology that can evaluate source code blocks and insert result into Org buffer. Babel is powerful by backend with many different programming languages and tools. On essention, Babel is send source code block text to another binary to be evaluated, then return the result to be inserted in Org buffer.

2.3.1 LP: support many different languages with Babel languages

For now, Org Babel has many languages supported now. Official support in Org-mode packages has a lot. Here is my loaded languages alist. They are many more, and you can search in Org source code, and GitHub, and maybe somewhere else.

- (sclang . t)
- (spice . t)
- (lilypond . t)
- (smiles . t)
- (coq . t)
- (arduino . t)
- (http . t)
- (restclient . t)
- (elasticsearch . t)
- (prolog . t)
- (matlab . t)
- (octave . t)
- (gnuplot . t)
- (julia . t)
- (R . t)
- (haskell . t)
- (redis . t)
- (mongo . t)
- (sqlite . t)
- (sql . t)
- (js . t)
- (css . t)
- (php . t)
- (java . t)
- (swift . t)
- (lua . t)
- (rust . t)
- (go . t)
- (C . t)
- (ruby . t)
- (python . t)
- (clojurescript . t)
- (scheme . t)
- (lisp . t)
- (emacs-lisp . t)
- (makefile . t)
- (ledger . t)
- (blockdiag . t)
- (ditaa . t)
- (dot . t)
- (clojure . t)
- (asymptote . t)
- (translate . t)
- (latex . t)
- (org . t)
- (shell . t)
- (calc . t)
  1. LP: use different languages to processing data in mixture

    You can process JSON data with JavaScript, then pass result data to Python to process to generate XML data, then pass the XML data to gnuplot to generate image result.

2.3.2 LP: Babel header arguments

There are many source code block header arguments, you can check out Org Mode Info document. And I after some years usage of Org Mode, I found there are some merely used header arguments are not mentioned in Org Mode Manual. And some header arguments are language specific only.

2.4 LP: separate code logic and reference with "noweb"

Tangling functionality is controlled by the tangle family of tangle header arguments. These arguments can be used to turn tangling on or off (the default), either for the code block or the Org-mode heading level.

The following code blocks demonstrate how to tangle them into a single source code file using org-babel-tangle.

The following two code blocks have no tangle header arguments and so will not, by themselves, create source code files. They are included in the source code file by the third code block, which does have a tangle header argument.

In the Org-mode file:

#+name: hello-world-prefix
#+begin_src shell :exports none
  echo "/-----------------------------------------------------------\\"

HTML export of code: In the Org-mode file

#+name: hello-world-postfix
#+begin_src shell :exports none
  echo "\-----------------------------------------------------------/"

HTML export of code: The third code block does have a tangle header argument indicating the name of the file to which the tangled source code will be written. It also has Noweb style references to the two previous code blocks. These references will be expanded during tangling to include them in the output file as well.

In the Org-mode file:

#+name: hello-world
#+begin_src shell :tangle hello.sh :exports none :noweb yes
  echo "|                       hello world                         |"

HTML export of code: Calling org-babel-tangle will result in the following shell source code being written to the hello.sh file:

echo "/-----------------------------------------------------------\\"
echo "|                       hello world                         |"
echo "\-----------------------------------------------------------/"
#!/usr/bin/env sh

# [[file:~/org/temp/index.org::*Noweb%20test][hello-world]]

echo "/-----------------------------------------------------------\\"
echo "|                       hello world                         |"
echo "\-----------------------------------------------------------/"
# hello-world ends here

In addition, the following syntax can be used to insert the results of evaluating a code block, in this case one named example-block.

# <<example-block()>>

Any optional arguments can be passed to example-block() by placing the arguments inside the parentheses following the convention defined when calling source block functions (see the Library of babel). For example,

# <<example-block(a=9)>>

sets the value of argument a equal to 9. Note that these arguments are not evaluated in the current source-code block but are passed literally to example-block().

2.5 LP: export to source code with "tangling"

2.5.1 LP: tangle single source code block

2.5.2 LP: tangle the section of headline

2.5.3 LP: tangle whole file

2.6 LP: display result

2.6.1 LP: display image result with Org inline image display

You can manually insert a file link to image file as inline image. You also can let source code block generate a file link to plot image file. Toggle inline image display in Org-mode with [M-x org-display-inline-images].

2.6.2 LP: display table result with Org table

Org-mode supports table. Support many manipulations. Also there are many advanced usage of Org table, like use table as data input for source code block, radio table, etc.

2.7 LP: reference to text, code and each other

2.7.1 text->code with coderef

(defun hello (name)                               ; (define function hello)
  (print (format "Hello, %s" name)))

define function hello

2.7.2 text->text with link

2.7.3 code->code with noweb

(defun hello (name)                               ; (define function hello)
  (print (format "Hello, %s" name)))

(hello "stardiviner")
Hello, stardiviner

2.7.4 code->text with link

  1. org-link in source code block comment

2.8 LP: navigation in text and code

  • org-babel-goto-named-src-block
  • org-babel-goto-named-result
  • org-babel-goto-src-block-head

You can jump back in mark ring with [M-,] / org-mark-ring-goto.

3 TODO complete this post

Still there are many things need to write. But temporary like this for now.