Illustrate your Point with Literate Programming
Using Graphviz in Org-Mode

07 May 2019

I’ve previously written about how I use Literate Programming to augment my writing process with the powers of programming. In another previous article, I wrote about a program called Graphviz, which makes it easy to draw graphs, like flow charts, class diagrams, or mind maps.

Today, I’d like to highlight how well these two tools work together in Emacs Org-mode.

Recap: What is Literate Programming?

Literate programming is a paradigm where executable code and written prose are mixed together. You write a document using a literate programming language and insert blocks of code as part of the document. There are then two types of compilers that you can pass your document to:

  • A weaver takes your document source code and produces something for people to read, like a printable document in PDF format, or a web page in HTML format. This document might include the code blocks, the results of running those code blocks, or both.
  • A tangler takes your document source code and extracts only the code blocks. Those blocks are put together and passed to the normal compiler for that programming language, producing executable code.

Most people have actually encountered this before, but haven’t thought to label it as such. The way that spreadsheet programs let you mix executable formulae into your tables of data is a form of literate programming!

My blog posts often include code blocks as part of the thing I’m writing about. Writing them using a literate programming language called “Org-mode”, which is part of the Emacs text editor, lets me test that the code blocks I’m sharing actually work, and makes it easy to include the results of running the code.

In my personal notes, I also find it useful to be able to quickly drop in a code block if I need to do some calculations. A recent example of where I used this is that I’ve been tracking my weight, and I wanted to calculate the trend line of my weight changing over time. I could add a block to calculate the change over time, and include it in my notes. The classic spreadsheet problems also fit well into Org-mode, like working out a budget, or calculating the average marks for a class.

Basically literate programming is a great fit anywhere that you’re writing notes and want to include the results of some computations in your notes.

You can read more about literate programming in this article I wrote: Literate Programming: Empower your Writing with Emacs Org-mode.

Recap: What is Graphviz?

Graphviz is a graph visualization program. Unfortunately, “graph” is an ambiguous term in English, so from just that description you might have the wrong idea about exactly what it draws. In this case, when I say graph I mean the data structure with “nodes” that are joined by “edges”.

/assets/posts/graph-recap.svg

Graphs come up all over the place as a way of showing things that are somehow connected. To use Graphviz to visualize a graph, you first write a description of your graph in the Dot language. Then, you pass the Dot code to Graphviz and it draws the graph for you.

For example, if I were writing about the Plan Do Study Adjust cycle, I might want to draw that life cycle out graphically.

This is the Dot code that I would write for Graphviz to draw the cycle:

digraph {
  Plan -> Do -> Study -> Adjust -> Plan
  {
    rank="same"
    Do
    Adjust
  }
}

And this is the image that it will produce:

/assets/posts/pdca-graph.svg

You can read more about Graphviz and the Dot language in this article I wrote: A Quick Introduction to Graphviz.

Bringing the two together

The core premise of bringing the two together is that, when you get to a point in your writing where you want to draw a bunch of boxes linked with lines, you open up a code block and start writing Dot code.

This example comes from some slides for a talk I did a while back talking about Browser Games, Rust and WebAssembly. I wanted to draw a graph showing how Rust fit into the web technologies that make a browser game. This is the code block that I wrote in Org-mode:

#+BEGIN_SRC dot :file rust-wasm.svg :exports results
  digraph {
    "Rust" -> "Compiler" -> "WASM" -> "Web page"
    "JavaScript" -> "Web page"
    "CSS" -> "Web page"
    "HTML" -> "Web page"
  }
#+END_SRC

When I build the Org-mode file to an HTML file for the presentation (using Reveal.js), it calls Graphviz to generate the file, and saves it as rust-wasm.svg. The source block has the header :exports results, so the generated HTML doesn’t include the Dot code, but it does include the image, that looks like this:

/assets/posts/rust-wasm.svg

The combination of Org-mode and Graphviz makes it very simple to add visualizations of graphs to your writing without needing to switch away from your writing.

It also makes it very easy to update your diagrams if you’re changing the exact wording in the rest of your article. You find and replace in the code blocks the same way you find and replace in the rest of your writing. Even if you don’t like exactly how Graphviz pictures look, it can be a good fast option to include in your first draft, to replace with a more polished after the content has gone through a few editing passes.

Setup

Org-mode, and the Graphviz support in Org-mode, are part of the core distribution in Emacs. If you install Emacs from your system’s package manager, or from the Emacs website, you already have everything you need installed.

You just need to add this line to your Emacs config to enable the Dot / Graphviz language bindings:

(require 'ob-dot)

Usage

Let’s break down that previous example into chunks. The first is Org-mode’s syntax for beginning a block of source code:

#+BEGIN_SRC dot :file rust-wasm.svg :exports results

The block start with #+BEGIN_SRC, followed by the programming language. In this case, the programming language is dot. In the setup section, when we enabled ob-dot, that added the code for Org-mode to know how to call Graphviz on code written in the Dot language.

After the programming language, the block has some headers. The syntax here is :key value, so the first header is :file rust-wasm.svg. This argument is passed on to Graphviz so that it knows where you want the image file created. Graphviz also supports a number of different image formats, so this could also be .png, .gif, .jpg, and several others.

The second header is :exports results. This is read by Org-mode weavers (the compiler that produces a document for humans to read) to tell it what to include. If it was set to code, then you would only see the source code. It’s set to results, so you only see the image on the slide. I’m often writing about the code itself, and want to show the code and its results, so I’d usually set this to both.

The next few lines are the Dot code:

digraph {
  "Rust" -> "Compiler" -> "WASM" -> "Web page"
  "JavaScript" -> "Web page"
  "CSS" -> "Web page"
  "HTML" -> "Web page"
}

The code block ends similarly to how it started, just with an END instead of a BEGIN:

#+END_SRC

For any questions on how exactly something works, I suggest starting with the Org-mode manual.

What else can Org-mode do?

Org-mode is a great platform for literate programming because it provides a generic interface that can have arbitrary languages plugged into it. Out of the box it supports a good assortment of programming languages, with even more languages available separately, and documentation on how to add support for your own language.

Most of the examples that I shared in my previous literate programming article showed the code blocks producing text output, but the Org-mode framework also supports producing images and inserting them into the document. This is useful for rendering graphs, like in this article, but it can also be useful for rendering all sorts of images. For example, you can render charts using Gnuplot, or write your own programs that produce images.

I hope this helps you to use the power of programming to augment your own writing and personal note taking!