Yesterday I wrote about ASCII art diagrams and gave four reasons you might want to use this ancient approach to creating simple diagrams:
- It could be quicker than creating a graphical image .
- You can paste them into plain text documents like source code files.
- They can be produced programmatically.
- There is software to turn ASCII art into more polished images.
Today I’ll post a few notes about how to create graphical versions of ASCII diagrams in Emacs with org-mode.
Running code inside org-mode
You can embed and execute source code in org-mode files. I wrote a couple posts about this, one showing how to run Python and R inside org-mode and another showing how to mix languages in org-mode. The latter shows Perl calling R and Python, all in 14 lines of code.
There are currently 39 programming languages that org-mode can call by default. In addition to conventional programming languages like the ones listed above, org-mode also supports ditaa, the language that treats ASCII art as a specification language to produce graphics.
You can edit code blocks just as you would other text in an org-mode file. But if you’d like to edit a code block in its language’s mode, type
C-c ' from inside the code block. If you’re editing Python code, for example, this will open a new window, in Python mode, containing just that code block. If you type
C-c ' inside a ditaa code block, Emacs opens a new window in “artist mode,” a mode specifically for editing ASCII art.
You can run code inside org-mode two ways: interactively and for export. With your cursor inside a block of code, type
C-c C-c to execute the code and report the results. You can also export an entire org-mode document and have the results of code execution embedded in the final document. This works much the same as “*weave” projects like Sweave, Pweave, and Hweave. But while each of these is specific to a particular programming language (R, Python, and Haskell respectively), org-mode works with dozens of languages, including ditaa.
Running ditaa inside org-mode
You embed ditaa code just like you’d embed any other code. In the first post mentioned above, I gave this example of calling R:
#+begin_src R sqrt(42) #+end_src
Here’s the analogous code for ditaa:
#+BEGIN_SRC ditaa :file foo.png +-------+ | Hello | +-------+ #+END_SRC
The markers to begin and end a source code segment can be upper or lower case. I used lower case in my previous post, but it may be more readable to use upper case so that the markers stand out better from their arguments.
The R example above didn’t use any header arguments, though it could have. With ditaa, you must provide a header argument: the name of the file to save the graphics in.
If you run the ditaa code by navigating inside the code block and running
C-c C-c, Emacs will add a couple lines after the code block:
This is the literal text, what you’d see if you opened the file in another editor. But org-mode uses the double brackets for links. You wouldn’t see the double brackets. Instead you’d see a hyperlink with text
file:foo.png. Clicking on that link opens the image.
You can export the org-mode file with the command
C-c C-e. This brings up a menu of export options:
h for HTML,
l for LaTeX, etc. Within each of these are further options. For example, you could type
l for LaTeX and then type
l again to select export to LaTeX or type
p to have org-mode run LaTeX on the file and produce a PDF. If you know you want a PDF, you could do this all in one command:
C-c C-l l p.
You can control whether org-mode exports code or the results of running code (or both or neither). Org-mode exports the results of ditaa code, i.e. graphics files, by default. This makes sense: your PDF file will have a nice image version of your diagram, not the ASCII art used as its source code.
Configuration and troubleshooting
By default, the only programming language you can run inside org-mode is Emacs Lisp. This makes sense. You want to be deliberate about what code you run, but if you don’t want to run Emacs Lisp you’d better not run Emacs!
Inside your Emacs configuration file, you specify what languages org-mode is allowed to run. Here’s an example allowing Python and ditaa:
(org-babel-do-load-languages 'org-babel-load-languages '( (python . t) (ditaa . t)) )
Recent versions of Emacs are supposed to ship with ditaa, but the ditaa jar file was missing from the two computers I experimented with. Emacs complained
org-babel-execute:ditaa: Could not find ditaa.jar at ...
and so I copied
ditaa.jar to the place where Emacs said it was looking for it. That worked, but it’s kind of a kludge because now I had two copies of the jar file. A better solution is to tell Emacs where you already have ditaa.
I like to use the exact same
init.el file on every machine I use and so I added a section where I put OS-specific and machine-specific configuration. Here I put a different path to ditaa for each OS.
;;---------------------------------------------------------------------- ;; OS specific (cond ((string-equal system-type "windows-nt") ; Microsoft Windows (progn (setq-default ispell-program-name "C:/bin/Aspell/bin/aspell.exe") # etc. (setq org-ditaa-jar-path "c:/bin/ditaa/ditaa.jar") ) ) ((string-equal system-type "gnu/linux") ; Linux (progn (setq x-select-enable-clipboard t) # etc. (setq org-ditaa-jar-path "/usr/bin/ditaa") ) ) )