Org Babel API
Table of Contents
- Overview
- The Babel Codebase
- Babel Basics
- Function:
org-babel-execute:template
- TODO Function:
org-babel-template-initiate-session
- TODO Function:
org-babel-expand-body:template
- TODO Function:
org-babel-prep-session:template
- TODO Function:
org-babel-template-var-to-template
- TODO Function:
org-babel-template-table-or-string
- Function:
org-babel-process-params
- TODO Variable:
org-babel-tangle-lang-exts
- Variable:
org-babel-default-header-args:template
- TODO Function:
org-babel-header-args:template
- Function:
org-babel-load-session:template
- Function:
org-babel-variable-assignments:template
- TODO Function: org-babel-comint-wait-for-output
- Undocumented behavior
- Terminology
- The
:var
parameter - References
Overview
Babel is part of Emacs Org mode which allows for interactive code blocks within a text document.
This is what a text document containing Org blocks looks like. Below is a shell block which installs some Python libraries. #+begin_src sh :results output :exports both :eval never-export :session *worg-babel* guix install python-matplotlib python-numpy #+end_src #+RESULTS: #+begin_example The following package will be upgraded: python-numpy (dependencies or package changed) The following derivation will be built: /gnu/store/yh1wjfmy4jy75wswkdsfa0lrfw7jrxs9-profile.drv building CA certificate bundle... listing Emacs sub-directories... building fonts directory... generating GdkPixbuf loaders cache... generating GLib schema cache... creating GTK+ icon theme cache... building cache files for GTK+ input methods... building directory of Info manuals... building XDG desktop file cache... building XDG MIME database... building profile with 127 packages... #+end_example Now that we've installed the Python package, let's run it. #+name: python-array #+begin_src python :results value :session *worg-python* import numpy as np a = np.arange(15).reshape(3, 5) a #+end_src #+RESULTS: python-array : array([[ 0, 1, 2, 3, 4], : [ 5, 6, 7, 8, 9], : [10, 11, 12, 13, 14]]) For fun, let's take this result and pass it to the shell. #+begin_src sh :results output :exports both :eval never-export :var x=python-array echo $x | sed 's/],/],\n\t/g' #+end_src #+RESULTS: : array([[ 0, 1, 2, 3, 4], : [ 5, 6, 7, 8, 9], : [10, 11, 12, 13, 14]]) It's just text, so we can pass it around. #+begin_src scheme :results output :var x=python-array (display "This is from Guile Scheme:\n") (display x) #+end_src #+RESULTS: : This is from Guile Scheme: : array([[ 0, 1, 2, 3, 4], : [ 5, 6, 7, 8, 9], : [10, 11, 12, 13, 14]])
At the time of writing, the Org Babel API is only described in three places:
ob-template.el
,- the email thread linked to in the Worg docs, and,
- the source code itself.
The functions that need to be (or even can be) defined aren't really laid out anywhere, nor are the ways they interact explained in one place. This document aims to change that.
NOTE At some point I'll merge this into Worg1. However, this is still a draft and I don't feel it's right to host it there yet. These are my active notes and people probably expect Worg to be somewhat more complete.
The Babel Codebase
Org Babel is defined by a collection of Emacs Lisp files. Babel files
begin with "ob-" (for "Org Babel") and are found in the lisp/
directory of the Org project2. The primary file is ob-core.el
.
ls $ORGDIR | grep "ob-" | grep "el$" | head -n 10 && echo "..."
At the time of writing, Babel is useable with more than 40 different languages.
ls $ORGDIR | grep "ob-" | grep "el$" | wc -l
Babel is no longer maintained by the original author. Instead, extensions have individual maintainers. Each extension varies in quality and consistency. Some see regular updates whereas others don't seem to have changed much.
It's convention in Elisp to choose a prefix to distinguish functions
and variables between packages. The name "Org Babel" implies the
package prefix "org-babel-"3. This is the prefix used within
Babel as well as other Org extensions (e.g. Org Links, Org Export
Framework, etc.). That is, symbols defined in ob-<lang>.el
don't
use a "ob-<lang>-" prefix–they use "org-babel-". It's impossible to
distinguish Org Babel symbols from other Org symbols by name alone.
Babel Basics
Babel works by defining certain functions that ob-core.el
expects.
If we compare ob-template.el
and ob-core.el
, we get the following
in no particular order:
function name | ob-core.el | ob-template.el |
---|---|---|
org-babel-execute:template |
X | X |
org-babel-template-initiate-session |
X | X |
org-babel-expand-body:template |
X | X |
org-babel-prep-session:template |
X | X |
[BROKEN LINK: =org-babel-template-var-to-template=] | X | |
[BROKEN LINK: =org-babel-template-table-or-string=] | X | |
org-babel-variable-assignments:template |
X | |
org-babel-process-params |
X |
variable name | ob-core.el | ob-template.el |
---|---|---|
[BROKEN LINK: =org-babel-tangle-lang-exts=] | X | |
org-babel-default-header-args:template |
X | X |
Functions from ob-core.el
not in ob-template.el
, but still used in
some ob-template.el
derived languages (e.g. ob-shell.el
):
org-babel-header-args:template
org-babel-load-session:template
org-babel-variable-assignments:template
Important functions to understand for any extension that uses a comint (all of them?):
Function: org-babel-execute:template
Arguments: body, params
Returns: emacs-lisp containing the results of evaluating body in template language.
The function called to actually evaluate a code block. It is defined
in an "ob-" file and gets called by org-babel-execute-src-block
.
The org-babel-execute:template
function will evaluate the body of
the source code and return the results as emacs-lisp depending on the
value of the :results header
argument:
:results output
means that the output to STDOUT will be captured and returned:results value
means that the value of the last statement in the source code block will be returned
The ob-template.el file claims that "the most common first step in
this function is the expansion of the PARAMS argument using
org-babel-process-params
." This was probably true when that was
written. At the time of writing, however, only four of the files in the
org-babel suite use it.
Please feel free to not implement options which aren't appropriate for your language (e.g. not all languages support interactive "session" evaluation). Also you are free to define any new header arguments which you feel may be useful – all header arguments specified by the user will be available in the PARAMS variable.
TODO Function: org-babel-expand-body:template
Called by org-babel-execute:template
.
TODO Function: org-babel-template-var-to-template
This is cruft. It's only defined in ob-template.el
. All it does is this:
(defun org-babel-template-var-to-template (var) "Convert an elisp var into a string of template source code specifying a var of the same value." (format "%S" var))
Surely this doesn't deserve a whole function.
TODO Function: org-babel-template-table-or-string
This is cruft. It is defined in ob-template.el
but not used
anywhere, in that file or elsewhere.
TODO Variable: org-babel-tangle-lang-exts
Gets called by ob-tangle.el
in the
org-babel-effective-tangled-filename
function.
Variable: org-babel-default-header-args:template
Documented in org-babel-default-header-args
:
This is a list in which each element is an alist. Each key corresponds to a header argument, and each value to that header's value. The value can either be a string or a closure that evaluates to a string.
It's important to note that org-babel-default-header-args
is
actually different from org-babel-default-header-args:template
.
org-babel-default-header-args
is only used for inline source blocks:
(defvar org-babel-default-inline-header-args '((:session . "none") (:results . "replace") (:exports . "results") (:hlines . "yes")) "Default arguments to use when evaluating an inline source block.") (put 'org-babel-default-inline-header-args 'safe-local-variable (org-babel-header-args-safe-fn org-babel-safe-header-args))
The variable org-babel-default-header-args:template
is used by
org-babel-get-src-block-info
. During block evaluation, the language
is grabbed from the source block definition and constructed to form
the language specific variable. For example, if a "shell" block is
evaluated, the corresponding variable
org-babel-default-header-args:shell
is constructed and referenced.
Function: org-babel-load-session:template
Called by the ob-core.el
function org-babel-load-in-session
. That
function handles header args, mainly no-web expansion. It then starts
the comint process and opens the associated process buffer. The
org-babel-load-in-session
function is, basically, called by the
"org-metaup-hook" which is attached to M-up by default. Otherwise,
this function is never called. Also, AFAICT, this behavior is not
documented anywhere.
For ob-shell.el, this function is implemented, but only for the "shell" language. For example, press M-up when in the following block. The body will be inserted in a new process buffer "my-shell".
#+begin_src shell :session my-shell echo "hello, world!" #+end_src #+begin_src sh :session my-sh echo "hello, world!" #+end_src #+begin_src bash :session my-bash echo "hello, world!" #+end_src
Function: org-babel-variable-assignments:template
Used during tangle (ob-tangle.el) and eval.
It is used as an argument for org-babel-expand-body:generic
.
It is used in org-babel-prep-session:template
"Return list of template statements assigning the block's variables."
Undocumented behavior
Don't be surprised if there is undocumented behavior defined within an ob file.
The following were undocumented features of ob-shell.el
:
- :stdin passes org reference (#+name) as stdin
- :cmdline with :shebang runs body with given command-line arg(s)
- :cmdline without :shebang runs body with shell-file-name and command-line arg(s)
- org-babel-load-session:shell (see org-babel-load-session:template)
Terminology
To quote (org) Structure of Code Blocks,
A source code block conforms to this structure: #+NAME: <name> #+BEGIN_SRC <language> <switches> <header arguments> <body> #+END_SRC
TODO info
params
'params' is an alist derived from the src block header. Element keys
are referred to as "header args". These are defined in
org-babel-common-header-args-w-values
, but are not exclusive to
that list. Any ":header-arg value" pair defined in the header will
appear in the list.
switch
Switches control evaluation, export and tangling of code blocks.
For example, the following block uses the "-n" switch to toggle line numbers in the HTML output:
#+begin_src elisp -n (message "hello, world!") #+end_src
1: (message "hello, world!")
header argument
Header arguments are keywords which control block evaluation or
expansion. For instance, the :session <session-name>
argument runs
a block in a separate shell. Another example is the :var NAME=VALUE
argument which passes data between blocks such that NAME
gets
defined as VALUE
within the block environment.
Header arguments can be more general, however. To quote ob-template.el,
"you are free to define any new header arguments which you feel may be useful – all header arguments specified by the user will be available in the PARAMS variable."
Arguments can be system-wide, using org-babel-default-header-args
or
language specific with org-babel-default-header-args:<LANG>
.
For common header arguments, see
org-babel-common-header-args-w-values
.
expansion
"Expand" and "expansion" are overloaded terms. Generally, they mean to replace something within a form.
When org-babel "expands" the body of a source block, it resolves any noweb references (noweb is the functionality that allows different source blocks to reference one another).
To expand a variable, in the context of Org babel, means to assign a header variable as a variable within the language runtime.
For example, the table named tbl
gets "expanded" and assigned to
data
within the Python runtime.
#+name: tbl | 1 | 2 | | 3 | 4 | #+BEGIN_SRC python :var data=tbl :results value return data #+END_SRC #+RESULTS: | 1 | 2 | | 3 | 4 |
The :var
parameter
The :var
parameter has the form
(:var name . value)
where "value", the cdr, should be a cons cell whose car is the name of the variable "as a symbol" and whose value is the value of the variable.
That is,
(:var name . (name-symbol . "it's value"))
Footnotes:
Technically, Emacs doesn't have namespaces. Instead, a prefix is given to symbols so that various packages don't conflict.