Org Babel API
Table of Contents
- Undocumented behavior
- TODO things to do
This document aims to explain the Org Babel API with a focus on maintenance and extension. Org Babel is a part of Emacs which allows for embedded code blocks within a text document1.
At the time of writing, the Org Babel API is only described in
ob-template.el, the email thread linked to in the Worg docs, and, of
course, 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 Worg2. 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 project is no longer maintained by the original author. Instead, the various "ob" (for "org-babel") extensions have individual maintainers. Each extension varies in quality and consistency with the other extensions. Some see regular updates whereas others don't seem to have had much interaction since they were created.
Org Babel is not a single file/package. It's a suite of files. The
files are found in the
lisp/ directory of the Org project3.
The primary file is
ls /home/ahab/.emacs.d/straight/repos/org/lisp | grep "ob-" | grep "el$" | head -n 10
The package is called Org Babel, which implies the namespace
"org-babel-"4. Note that the various "ob-" extensions also use
the "org-babel-" prefix. That is, symbols defined in
don't use an "ob-core-" prefix and symbols defined in
That all Babel files use the same prefix makes it difficult to tell which functions are core and which are extensions. It also makes it hard to figure out what the actual API is. Hence, this document.
The basic idea is to define functions that
In no particular order:
|[BROKEN LINK: =org-babel-template-var-to-template=]||X|
|[BROKEN LINK: =org-babel-template-table-or-string=]||X|
ob-core.el not in
ob-template.el, but still used in
ob-template.el languages (e.g.
Important functions to understand for any extension that use a comint (all of them?):
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
'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.
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 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
argument which passes data between blocks such that
ASSIGN 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
language specific with
For common header arguments, see
"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 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 named table
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 |
: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.
(:var name . (name-symbol . "it's value"))
Arguments: body, params
Returns: emacs-lisp containing the results of evaluating body in template language.
The function called to evaluate a code block. It is defined in an
"ob-" file and gets called by
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 outputmeans that the output to STDOUT will be captured and returned
:results valuemeans 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.
This function is called by
Used during tangle (ob-tangle.el) and eval.
It is used as an argument for
It is used in
"Return list of template statements assigning the block's variables."
Don't be surprised if there is undocumented behavior defined within an ob file.
The following were undocumented features of ob-shell:
- :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)
Called by the ob-core.el function
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
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
This is cruft. It is defined in
ob-template.el but not used
anywhere, in that file or elsewhere.
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 things to do
[ ]explain each function
[ ]explain terms
[ ]remove cruft functions from
ob-template.el(or just refactor that example)
Gets called by
ob-tangle.el in the
Technically, Emacs doesn't have namespaces. Instead, a prefix is given to symbols so that various packages don't conflict.