Org-mode Babel is cool

Literate programming is what you need to rise above the ordinary level of achievement. But I don’t believe in forcing ideas on anybody. If literate programming isn’t your style, please forget it and do what you like. If nobody likes it but me, let it die.

~ Donald Knuth

Babel is Org-mode’s ability to execute source code within Org-mode documents. And is a cool tool for programming, especially if you are a student. I have been programming (mostly small projects) and using emacs (for everything) for more than 6 years. Sadly, I have discovered the power of Babel only recently.

In a learning environment it is often the case that comments are longer than code lines, therefore literate programming looks like the natural paradigm to adopt. And Babel is the perfect tool for literate programming.

If you are given a script and you have to modify it, comment and then send it back to your instructor, then Babel comes really in handy: you start by putting the whole script in one big code block, and as you start commenting and modifying it, you just split it and add the comments as pure text between blocks.

It might be the case that you only have to submit the script as a single, executable file: in that case all you have to do is calling the org-babel-tangle function and emacs will create a new file named after your *.org file but containing only source code.

I define the options for Babel per buffer by putting the following line on top of my *.org document.

#+PROPERTY:header-args :results output :session :cache yes :tangle yes :comments org :exports both

With this properties, emacs will:

  • print all the output of the code, and not just the last produced values
  • make all the code blocks run in the same session
  • make use of cache to save you some time
  • export the whole file as a script when tangling
  • export the text between code as comments in the output script
  • when exporting (for example to html), include both the code and the output

That said, there are a few things to tune in your init file.

First, you have to define which languages you want to enable in Babel: I regularly use haskell, elisp, R, python and — yes — you can lunch shell commands from within org!

(org-babel-do-load-languages
 'org-babel-load-languages
 '((haskell . t)
   (emacs-lisp . t)
   (sh . t)
   (R . t)
   (python . t)
   ))

Then, you can have syntax highlighthing in the code blocks:

(setq org-src-fontify-natively t)

But remember that you can also edit a block in its own native mode by pressing C-c ‘.

Finally, if you work with white-space sensitive languages such as python, remember to add the followings:

(setq org-edit-src-content-indentation 0)
(setq org-src-tab-acts-natively t)
(setq org-src-preserve-indentation t)

If you want to learn more, make sure to check Howard Abrams’s tutorial on literate programming for DevOps: there is a lot to learn, even if you are not doing DevOps.