Today’s short and tangential note is an account of how I dug myself out of Documentation Despair. I’ve been working on some block diagrams. You know, this sort of thing, to describe feedback control systems:

And I had a problem. How do I draw diagrams like this?

I don’t have Visio and I don’t like Visio. I used to like Visio. But then it got Microsofted.

I can use MATLAB and Simulink, which are great for drawing block diagrams. Normally you use them to create a model for simulation, but you can just use them for illustrations. Except that Simulink’s support for TeX output is very limited and not very easy to use. You have to create a masked subsystem and use icon drawing commands with (..., 'texmode', 'on') . Basically it’s just a bunch of basic math characters, and the ability to use subscripts and superscripts. You can’t even draw simple rational transfer functions like \( H(s) = \frac{1}{s^2 + 2Kbs + b^2} \) because MATLAB’s TeX support hasn’t done anything new in at least the last 12 years, and use of the TeX \frac{}{} macro isn’t supported.

I found the blockdiag program, which is Python-based (yay!!!), and kind of like the dot program in graphviz, but a little bit better-suited to block diagrams. But it doesn’t have equation support either.

Argh! So I turned to the Internet and looked up to see how to put MathJax equations in SVG. MathJax is the client-side JavaScript framework that is the de facto standard for math typesetting in HTML. I use it all the time in my articles. You can do stuff like this without lifting an eyelash:

$$ \gamma = \lim_{n \to \infty} \left(2\sqrt{n+1} - \sum\limits_{k=1}^n \tan^{-1}\frac{1}{\sqrt{k}}\right) = 2.157782996659446…$$

Here’s how MathJax works: it goes in like a bunch of mini-math ninjas and rips through your HTML and looks for text in special delimiters \( \) or \[ \] or $$ $$ , and merrily interprets it as TeX math mode, typesetting the results as a huge ugly nested tree of HTML <span> elements to place math text characters in exactly the right places so it looks like a professionally-typeset math equation. It’s not a bitmap! You can zoom in on equations to your heart’s content and it gets sharper-looking.

But it doesn’t work in SVG, at least not without some hackery. One approach is to use the SVG <foreignObject> tag, and I tried it and couldn’t get that to work either. Then I found this post on StackOverflow which uses a different approach. Basically all it does is to render MathJax equations normally, outside of the desired SVG elements, and render the equations as SVG, then copy the resulting SVG nodes into the relevant place inside the desired SVG elements. It took me a little while to figure out what it was doing. The author uses CoffeeScript and jQuery to create equations in SVG. Which is great, but I don’t know CoffeeScript, and I don’t want to mess around with something I don’t know unless I’m going to use it a lot, and it doesn’t seem like these dependencies are really necessary to get things done.

So I wrote my own method, which is pretty simple. You just add a few lines of Javascript at the top of your HTML file, and pretend that MathJax markup works properly in SVG:

Here’s how it works:

Include the MathJax scripts with SVG rendering

Before MathJax runs: For each <text> element inside a <svg> element, where the <text> node’s content consists entirely of a MathJax equation (with optional spaces outside the equation delimiters): Copy the text content of the <text> element to a temporary <div> element elsewhere on-screen, so that MathJax can typeset the equation properly. Copy these two elements (the original <text> element and the temporary <div> element) to a temporary list in Javascript.

After MathJax runs: For each pair of elements in the temporary list: Clone the resulting elements and replace the original <text> element in the SVG with the results of MathJax typesetting. Remove the temporary <div> elements.



That’s it! Excluding the Apache License notice at the top of the file, the Javascript source is less than 100 lines.

I’m happy with the results; I’ve been using this technique to add blocks to Simulink diagrams which have MathJax equations in them.

Here’s an example of a Simulink diagram with the raw MathJax markup: (sorry, it’s only a PNG file so you can’t zoom in)

And here’s what happens when I include it in an HTML file along with my SVG_MathJax script: Presto-chango!

I put the Javascript file svg_mathjax.js into a Bitbucket repository — feel free to use it yourself. Maybe someday soon, the MathJax people will make it obsolete by getting their excellent software to work properly when used in SVG elements.

In the meantime, happy typesetting!