A Python-Markdown Extension for Embedding Graphviz

January 16, 2010. Filed under python 59 markdown 6

Two of the tools I use most frequently in my writing (both public writing on this blog and notes I jot down for personal consumption) are graphviz and markdown. The last few days I've been tossing around the idea of embedding Graphviz graphs into Markdown, and today I had a couple of hours to quickly throw it together.

The proof of concept, python-markdown-graphviz, is available on Github.

I chose to extend Python-Markdown because that is how I implemented my custom (and some have claimed, arbitrary) Markdown extensions I use for this blog.

The syntax for writing documents is straightforward: enclose the Graphviz graphs in a tag whose type corresponds with the Graphviz executable to render the snippet (dot, neato, lefty, dotty).

* hi
* there
digraph a {
    b -> c -> d
## And a title
digraph a {
    b -> c -> d
This is some text

A simple example of usage is (requiring that mdx_graphviz.py be in the Python path):

import markdown
txt = "* this is some\n<dot>\ndigraph a {\n a -> b;\n}\n</dot>\nhi\n"
md = markdown.Markdown(extensions=['graphviz'])
print md.convert(txt)

You can customize a few settings:

  • BINARY_PATH is the path to the dot, neato, etc executables (defaults to no path, i.e. assumes will be in $PATH).
  • FORMAT is the format for images created by Graphviz (defaults to png).
  • WRITE_IMGS_DIR is the directory to write images into (defaults to local directory).
  • BASE_IMG_LINK_DIR is the base directory for the links to the generated images (defaults to local directory).

An example of changing the defaults settings:

import markdown
txt = "* this is some\n<dot>\ndigraph a {\n a -> b;\n}\n</dot>\nhi\n"
md = markdown.Markdown(
print md.convert(txt)

There is a lot of room for improvement, in particular a few ideas:

  • use the name of the graph (extracted from the graphviz syntax) for the filename instead of numeric filenames.
  • option to specify dimensions of graphs, or at least specify the width and auto-calculate the height.

That's all there really is to it. I'll probably make some improvements as I keep using it, but would always be glad to have others build on it as well if it's useful.

Repository is available here.