Skip to content

Latest commit

 

History

History
350 lines (251 loc) · 13.2 KB

babel.org

File metadata and controls

350 lines (251 loc) · 13.2 KB

Source Block Execution

There are several names associated with the ability to execute a source block from within an org document. The tech that backs most of this ability is called babel. It has as its primary goal the ideas of literate programming and reproducible research. What has made it a popular feature is the combination of babel with many of the other emacs features.

Babel Active Code In OrgMode

As some examples:

  • Using babel with tools like gnuplot, plantuml, ditaa and graphviz allows presenters to build diagrams dynamically from their notes.
  • The integration with tools like TRAMP in emacs allows developers to dynamically build reports from running processes on remote boxes.
  • Emacs ledger mode and the org mode spreadsheets have empowered some org mode users to build complex budget reports from their financial data.
  • Clocking and some of the project management tools in org mode have allowed contractors to dynamically build timesheets from work notes.
  • Or… I suppose you could use it for what it was intended for, as a means of facilitating a research paper.

Babel really made orgmode the original jupyt*r notebook.

Basic Usage

Babel treats a source block in an org document as an active function call that can be called in various ways.

Here we have a basic python source block:

##+BEGIN_SRC python :var x=5
  print(str(x))
##+END_SRC

images/babel_hello_world.gif

There are a couple of things of note here:

  1. The source block states what language it belongs to, in this case python.
  2. We have specified a variable x that is set to the value of 5.
  3. We are able to access that variable from within the source block.

Executing this source block will produce a #+RESULTS comment:

#+RESULTS:
: 5

Supported Modules

The following are the currently supported executable source blocks:

Diagrams

  • plantuml
  • graphviz
  • ditaa
  • gnuplot

Source Code

  • python
  • javascript / js

Shell Scripts

  • powershell
  • cmd / bat
  • sh / bash

Variables

Variables can come from a few different sources other than the source block fence itself. Variales can be in property blocks or property comments as seen below:

:PROPERTIES:
:header-args:           :var g=global
:header-args:python:    :var x=5
:var: v=10
:END: 

#+PROPERTY: header-args: :var y=11
#+PROPERTY: header-args:python: :var z=12
    

Language specific variables can be defined as well using the language suffix

Variables are only one type of parameter than can be specified as an argument. Options such as results, noweb-href, eval, cache etc can all be specified in the manner shown above. In addition there is a global option that allows you to specify options for all blocks in any org file unless overriden.

The defaults can be found in the core settings file:

"orgBabelDefaultHeaderArgs": ":results replace :exports code :cache no :noweb no",

Inputs

While variables are nice, babel becomes even more useful when connected to data tables and lists in your documents. Tables and lists can both have a name. This name allows them to be referenced as the source of a variable.

#+NAME: my-source-block
| name  | value |
| Hello | 25    |
| World | 42    |

##+BEGIN_SRC python :var DATA=my-source-block
  print(DATA)
##+END_SRC

#+RESULTS:
: [['name', 'value'], ['Hello', 25], ['World', 42]]

Execution Types

Up till now we have been ignoring one of the important parts of babel which is the execution type. Babel supports 2 execution modes:

  • Output - This is the default and what we have seen so far. The stdout of a source block is captured and used as the return value.
  • Value - This is more the traditional function call style.
##+BEGIN_SRC python :results value
  return 5     
##+END_SRC   

#+RESULTS:
: 5

Results

The results keyword really has 4 dimensions

Execution Type
output vs value - what do we capture?
Output Handling
table vs list vs raw - does the output get interpreted as something else?
Formatting
verbatim vs html vs org vs drawer vs code - do we wrap the output in something?
Output Mode
append vs prepend vs silent vs replace - how do we insert the output into the buffer?

Each results keyword can have a combination of those 4.

##+BEGIN_SRC python :results output table drawer
  print("Hello World")
##+END_SRC

#+RESULTS:
:results:
| Hello | World |
:end:

Here we have formatted the output as a table and put it in a drawer. You can also output the results to a file with the :file <filename> parameter.

Here is some powershell doing the same thing as our python

#+NAME: in-table
| a | b | c | d | e |
| 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 0 |
   
##+BEGIN_SRC powershell :var DATA=in-table :results table
 $DATA | %{"$_"}
##+END_SRC

#+RESULTS:
| a | b | c | d | e |
| 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 0 |
  

images/babel_simple_eval.gif

Call

Org Mode treats source blocks like functions in some strange programming language tapestry. The call statements lets you call a source block with a different set of parameters. Executing one of these blocks will produce a new set of results below the call, but with the alternate set of parameters.

#+CALL: name-to-call(x=5)

Inline Source Blocks

Sometimes you would like to specify a quick little source snippet inline in your text. This can be done with the inline source block. Inline blocks should get parsed out by an exporter, support parameters and can be used for dynamic elements such as page numbers and other dynamics inline content.

src_python[:var x=5]{print("hello" + str(x))} {{{results(=hello5=)}}}       

Chaining Source Blocks

Variable inputs can not only be tables, lists or plain old data types but they can be other named source blocks. Here is a silly example. In this little example the second source block will have “hi” as its output. It has chained the results into x and used that variable in the print statement.

##+NAME: my-function
##+BEGIN_SRC python
    print("hi")
##+END_SRC

##+BEGIN_SRC python :var x=my-function
    print(x)
##+END_SRC

This can be really powerful for situations where you have one language well suited for a certain kind of data manipulation. For example, you use powershell to pull some data from azure. You then pipe that data into a different language to help manipulate the data in some fashion. For example, python. Finally you push the output of the python script into a gnuplot source block and graph it to visualize what is going on.

Cache

Sometimes it is handy to avoid recalculating something if the inputs have not changed. Org has a mechanism called cache. Be careful as this can have odd side effects if your code has side effects.

:cache yes

When you turn on caching the results block will get a SHA1 hash. This is a hash of the source code and parameters being passed to generate that output. If the hash matches the block will NOT get re-evaluated when you try to execute it later.

Full Circle SBE

Things get even more interesting once we start to look at the sbe (Source Block Execute) table function. With this we come full circle. Not only can tables act as inputs to source blocks but source blocks can act as inputs to tables.

Remember that example in the chaining section above? We chained hi from the output of one source block into a variable and used it as input. Here we are calling that same block but providing a different input. Here the input is just a string. The result then gets inserted into my table. I can even pass cell references from the table as parameters to those functions.

| pulled from python |
| hello world        |
#+TBLFM:@2$1=sbe('my-function',x="hello world")

Here is an example of this in action. The evalutation of the table takes a bit as it is waiting on images to be generated by graphviz ditaa and plantuml, the resulting file links are passed in the table. You can bring up this little unit test by calling the “Org Show Source Tests” method. You will need plantuml, ditaa and graphviz installed to run the tests.

The sbe calls chain to a method that is using a table or a list as source. The image examples generate an image and use a test source block to validate the file exists on disk.

images/babel_chained_functions.gif

Tangle and Export

Literate programming and reproducible research require several things:

  1. You can easily publish your document.
  2. You can easily have someone else run your source code with your data.
  3. All of your code and data can live in one seamless package.

These things are supported by the 3 core pillars of babel:

Execute
Run a source block inline in my code.
Tangle
Extract my source code with embeded data into pure source.
Export
Export my document to another format.
  • Execute we have already been covering at length in this document.
  • Export is supported by our html exporter, the reveal js exporter for presentations and pandoc for conversion to a ton of other formats.
  • Finally tangling is supported by our detangler. Org Tangle File will attempt to create pure source files from the source found in your org document.

Security

Babel has support for some security features. The eval parameter can be used to stop a block from being executed:

Either of the following will stop a block from ever being executed

:eval never
:eval no

In addition you can use the query option to cause the system to prompt with a popup on whether or not you would like to execute the source block:

:eval query

NOTE: query or never can be used as a global option in your settings file to avoid accidental execution.

NoWeb

One final tool makes the literate programming toolset complete. This is support for the NoWeb macro language. Org has limited support for noweb macros. Much like macros in C or C++ NoWeb lets you paste either your source code between source blocks OR the results of the execution of the source block.

NoWeb

Here is a simple example where we paste the source in the block above into our source block.

##+begin_src python :noweb-href print-it
  print("Hello World")
##+end_src
##+begin_src python :noweb yes
  <<print-it>>
##+end_src

Pasting Results

Just like you can paste a blocks contents into another block you can paste the results:

##+BEGIN_SRC python :var x=10 :noweb-ref evalsource :results raw
  print("print('hi "+str(x)+"')")
##+END_SRC
##+BEGIN_SRC python :noweb yes
  <<evalsource(x=20)>>
##+END_SRC
##+RESULTS:
: hi 20

This is kind of a crazy example. Here we have a noweb macro calling another source block that when run generates some code that is pasted into the first block and executed to generate “hi 20” as a result.

Remember the power of this system is that you can mix and match. Choose the right tool for the job.

Extending Source Block Handling

You can add your own source block handlers. In fact, you can replace the built in ones. If you do not like that the built in python handler uses the version of python built in to sublime you can change the:

"builtinSourceBlockHandlers": [LIST]

Remove python from that list and then add your own python.py file in:

Packages/User/orgsrc/python.py

That will let you write your own handler. Any language that orgmode knows how to syntax highlight can have a source handler written for it. I am working to eventually support as many languages as I can. That said, there will always be cases where you need a language I cannot yet support.

Right now the easiest way to do this is to take a look at the powershell.py or cmd.py handlers in the orgsrc folder inside this package. You will see examples of how a handler can be written. You will need to write a couple of methods and I encourage you to share your handlers with me so I can include them in the main package or reference them from this documentation.