Source code in org-mode with ox-twbs

Using org-mode to write about computer programming

June 18th, 2017 - Brandon van Beekum - @marsmining

Summary

As a programmer by trade, I spend a lot of time writing about software. Most often I'm writing notes for myself, or perhaps something to share with my colleagues at work. Emacs with org-mode is a great tool for working on small technical documents, or even full articles, blogs or websites. In this article, I'd like to share a few tips about including both source code and math in your own org-mode documents.

In this article we'll create an example document that renders to this HTML.

Background

Org-mode is a major mode in Emacs which allows you to create documents in plain-text, which can then be output to a number of formats. Perhaps most common are HTML and PDF outputs, where each output requires an org "backend" which takes an AST of the document, and emits whatever particular output (in the case of PDF, TeX is first output, which is then exported to PDF).

Org-mode ships with a comprehensive HTML backend, but the design of the output is a bit dated. I copied this standard exporter ox-html to a new project, ox-twbs, and made a relatively small number of changes required to emit HTML compatible with Twitter Bootstrap. This gives org-mode's HTML output a bit more modern feel. This document assumes you've installed this package which is called ox-twbs (org-mode exporters tend to be prefixed/namespaced with "ox").

Start

The first thing I do when creating a new document is give it a title and perhaps a starting headline or two. Let's create a new document, I'll pick an example using a paper I'm currently reading.

For the remainder of the document I'll show some blocks of text from an org-mode document, and what immediately follows is a screenshot of Firefox rendering the document after it was exported with org-twbs-export-to-html.

#+TITLE: Typeclass Inferencing Rules

* Summary

* Links

typeclass-start.png

Figure 1: Our first export!

Defaults

Most documents I create are my own notes and are not very long. I generally have a few defaults I copy over when I start a new document. Often the first thing I like to do is remove the table of contents and footer. In addition, lately I really like the style of the Bootstrap lead, and it seems a good place for a subtitle. Here you'll see how to put raw HTML into your document as well as setting per document options (which can also be set per project).

#+TITLE: Typeclass Inferencing Rules
#+OPTIONS: html-postamble:nil toc:nil

#+BEGIN_EXPORT html
<p class="lead">
  Notes on Wadler's paper "How to make ad-hoc polymorphism less ad-hoc"
<p>
#+END_EXPORT

* Summary

* Links

typeclass-notoc.png

Figure 2: Less clutter!

The document so far is mostly boilerplate I'll have copied from a previous document. In the remaining examples I'll omit this boilerplate.

Example Blocks

I'm often writing notes about the runtime behavior of a system. This means I might want to include some snippets of a log file. Example blocks work great for this, and you can insert them via templates quickly. Start by typing <e and press tab to complete. Then insert a few log lines:

* Log output

#+BEGIN_EXAMPLE
16:37:17.332 14:37:13.161 [New I/O worker #7] WARN  customer-stream: [customer-uuid-job] Customer stream ended, closing channel
16:37:17.332 14:37:13.161 [async-dispatch-1]  ERROR cache: [customer-uuid-job] Stop setting keys
16:37:22.428 14:37:18.162 [async-dispatch-2]  INFO  jobs: [customer-uuid-job] Started customer-uuid maintenance job
#+END_EXAMPLE

typeclass-wlog.png

Figure 3: Not so nice log output!

The output above is ok, but depending on your preferences, you might like to tweak a few things. If you have dense info like long log file lines, you might prefer a smaller font. I'll often use the following snippet to reduce the font size and use a softer white for less contrast.

#+TITLE: Typeclass Inferencing Rules
#+OPTIONS: html-postamble:nil toc:nil
#+HTML_HEAD_EXTRA: <style>pre { font-size: 13px; background-color: #000; color: #bbb; }</style>

typeclass-slog.png

Figure 4: Log output fits and is not so strong.

Source Blocks

Finally, let's try some blocks of code!

#+BEGIN_SRC haskell
  class Eq a where
    (==) :: a -> a -> Bool
  instance Eq Int where
    (==) = eqInt
  instance Eq Char where
    (==) = eqChar

  member          :: Eq a => [a] -> a -> Bool
  member []       = False
  member (x:xs) y = (x == y) \/ member xs y
#+END SRC

Note that in the above example, the source code is not highlighted, but importantly, in your org-mode buffer it will be syntax highlighted. It is not in the above example because I have it wrapped in an org source code block for this document (an example of an example).

Also, my lack of understanding in how to do escaping is showing, I've been forced to cheat and put #+END SRC rather than the correct #+END_SRC. The above snippet renders like:

typeclass-src.png

Figure 5: First source code block.

Rather unusually, org-mode exports source code with the same colors as your Emacs theme. I happen to be using an old Twilight theme, which uses a black background. Therefore, the syntax coloring of the HTML export will likely look best with the same black background. This is why the CSS snippet we added earlier included a background-color: #000 rule:

#+HTML_HEAD_EXTRA: <style>pre { font-size: 13px; background-color: #000; color: #bbb; }</style>

I recommend you play around with these rules depending on what Emacs theme you use. Generally the main foreground and background colors should be sufficient to get a look you like.

Org-mode has really powerful abilities in working with and even evaluating source code blocks. First read about the basics and then if you're interested in evaluation check out Babel.

Math

Often in your writing you will want to reference a variable, or perhaps a small equation. Well org-mode has fantastic support for LaTeX, which can be very helpful. Often you might want to reference some variable "x", which perhaps you might write in italics, like x, but it's much clearer to use inline latex like $x$ which renders an \(x\) which more clearly stands out as a symbol. Also, if you need a symbol from the Greek alphabet, just do $\alpha$ for \(\alpha\) or $\tau$ for \(\tau\) as an example.

With the inline syntax you can do full equations, not only symbols. For example:

$x=\sqrt{b}$

Will render inline as \(x=\sqrt{b}\).

But often you might want to emphasize an equation, or have something larger to express. For example, let's add the following two LaTeX blocks:

Small example:

\begin{equation}
    \forall a . a \to a
\end{equation}

Large example:

\begin{align*}
    \text{Eq} \,=\, &\{\, \text{Bool, Char, Int, Integer, Float, Double} \,\}\, \cup \\
    &\{\, [\tau ] \mid \tau \in \text{Eq} \,\}\, \cup \\
    &\{\, (\tau_1, \tau_2) \mid \tau_1,\tau_2 \in \text{Eq} \,\}\, \cup \\
    &\{\, (\tau_1, \tau_2, \tau_3) \mid \tau_1,\tau_2,\tau_3 \in \text{Eq} \,\}\, \cup \\
    &\{\, (\tau_1, \tau_2, \tau_3, \tau_4) \mid \tau_1,\tau_2,\tau_3,\tau_4 \in \text{Eq} \,\}\, \cup \\
    &\dots
\end{align*}

typeclass-eqid.png

Figure 6: First LaTeX equation blocks!

Maybe you'd like the equation to be larger? Most likely MathJax is rendering the LaTeX so a snippet like the following should scale up the equations:

#+HTML_MATHJAX: scale:100 dscale:190 align:center messages:none

The pertinent parameter is dscale but included above are a few other parameters to get started on controlling the MathJax library.

typeclass-eqbig.png

Figure 7: First LaTeX equation blocks, but bigger.

Conclusion

The HTML output of our, at this point incoherent document can be seen here. We've see an example of including text verbatim with an example block, syntax highlighted code with a source block, and finally a few equations inline and on their own.

Hopefully you'll find the few tips in this article helpful in improving your own workflows with org-mode. If you have trouble with the ox-twbs package, please create a GitHub issue. I'm not actively working on the project, but do try to make sure it is compatible with the latest Emacs and org-mode versions.

I wrote a more introductory article on org-mode which might interest you. It is similar to this article but without the focus on writing about software.

Good luck in your future usage of org-mode!