Org Babel
Code Blocks
At the heart of Babel are Org code blocks. Code blocks are delimited with a special comment syntax. Here is an example code block in Elisp:
#+BEGIN_SRC elisp (defun mccarthy91 (n) "McCarthy 91 is used as a formal verification test case." (if (<= n 100) (mccarthy91 (mccarthy91 (+ n 11))) (- n 10))) #+END_SRC
The basic form is simple. A chunk of code is surrounded by
#+BEGIN_SRC lang
… #+END_SRC
.
Code blocks can be modified with annotations, switches, and header arguments. The expanded structure follows
#+NAME: <name> #+BEGIN_SRC <language> <switches> <header arguments> <body> #+END_SRC
Especially useful are header arguments such as :session
, :results
,
and :exports
. Header arguments can be placed on the #+BEGIN_SRC
line as follows
#+BEGIN_SRC elisp :exports code <body> #+END_SRC
Or they can be placed as code block annotations as follows
#+HEADER: :exports code #+BEGIN_SRC elisp <body> #+END_SRC
Multiple header blocks can be used in either form.
#+BEGIN_SRC elisp :exports code :results replace table <body> #+END_SRC #+HEADER: :exports code #+HEADER: :results replace table #+BEGIN_SRC elisp <body> #+END_SRC
The :exports
header argument is incredibly useful. It controls how
the code block is used when exporting. It can simply list its code in
the exported document by using :exports code
. Or it can evaluate the
code and export just the results using :exports results
. To include
both the code and the results in the exported document use :exports
both
. Finally the code and the results can be excluded from the
exported document using :exports none
.
Code Block Variables in Elisp
Simple example shows setting a variable in a header comment.
#+NAME: square_el #+HEADER: :var x=0 #+BEGIN_SRC elisp (* x x) #+END_SRC
Now we can use #+CALL:
to invoke the named code block.
#+CALL: square_el(x=6)
36
Code Block Variables in Python
Now a simple example in Python.
#+NAME: square_py #+HEADER: :var x=0 #+BEGIN_SRC python return x * x #+END_SRC
Likewise we can use #+CALL:
to invoke the named Python code block.
#+CALL: square_py(x=5)
25
Inline Code Block
Code can be evaluated inline using src_lang{code}
. Thus to get the
current Emacs version use src_elisp{(format "%s"
emacs-major-version)}
. This document was prepared with Emacs
26
.
Inline Code Block with Arguments
Inline code with arguments has the form src_lang[args]{code}
. Thus
we can assign a variable inline like so src_elisp[:var x=25]{(sqrt
x)}
can be used to show that \( \sqrt{25} = \) 5.0
.
Named Inline Calls
Named code blocks can be called in a similar fashion and syntax used
for inline code blocks. The form is call_name()
or the expanded form
call_name[inside-header-args](args)[end-header-args]
.
#+NAME: mcpython91 #+BEGIN_SRC python :var in_from_org=0 :exports none def mccarthy91(n): "McCarthy 91 is used as a formal verification test case." if n <= 100: return mccarthy91(mccarthy91(n + 11)) else: return n - 10 return mccarthy91(in_from_org) #+END_SRC
The McCarthy 91 function with the argument 4
evaluates to
91
and with the argument 246
evaluates to
236
.
Likewise the following are true
call_mcpython91(0)
=91
call_mcpython91(1)
=91
call_mcpython91(85)
=91
call_mcpython91(101)
=91
call_mcpython91(102)
=92
call_mcpython91(185)
=175
The McCarthy 91 function has the property \( \forall n \in \mathbb{N} \), if \( n \leq 100 \) then \( f(n) = 91 \) else \( f(n) = n - 10 \).
Use a Org table as Input
Take from Org Babel: Introduction.
Given this table of numbers
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |
It is expressed in an Org file like so
#+TBLNAME: fibonacci-inputs | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |
We can use the table named fibonacci-inputs
as inputs to a Fibonacci
function called while we "map" the rows' values to \( f(n) \).
(defun fibonacci (n)
(if (< n 2) n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(mapcar (lambda (row)
(mapcar #'fibonacci row)) fib-inputs)
In an Org file that looks like so
#+NAME: fibonacci-seq #+HEADER: :exports both #+BEGIN_SRC elisp :var fib-inputs=fibonacci-inputs (defun fibonacci (n) (if (< n 2) n (+ (fibonacci (- n 1)) (fibonacci (- n 2))))) (mapcar (lambda (row) (mapcar #'fibonacci row)) fib-inputs) #+END_SRC
And produces the following table of Fibonacci numbers
1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 |
1 | 3 | 8 | 21 | 55 | 144 | 377 | 987 | 2584 | 6765 |
Preview Variable or Tangle Expansion/Substitution
Use C-c C-v v
or C-c C-v C-v
to preview the expanded content with
org-babel-expand-src-block
.
Pascals Triangle in Python
Taken from a journal paper on reproducible research.
def pascals_triangle(n):
if n == 0:
return [[1]]
prev_triangle = pascals_triangle(n-1)
prev_row = prev_triangle[n-1]
this_row = map(sum, zip([0] + prev_row, prev_row + [0]))
return prev_triangle + [this_row]
return pascals_triangle(n)
1 | |||||
1 | 1 | ||||
1 | 2 | 1 | |||
1 | 3 | 3 | 1 | ||
1 | 4 | 6 | 4 | 1 | |
1 | 5 | 10 | 10 | 5 | 1 |
Last modified: 2020-01-20 00:00:00 +0000 UTC