Coffee Space


MathML Render

Preview Image

This is quick one from me - but thought it was worth documenting based on the fact that there doesn’t seem to be much information out there about it. I wanted to show some equations in a recent article about polygon images and thought I would share my solution to this problem.

Essentially I’m just going to explain how to setup pandoc with some ‘minimal’ JS to render MathML in most browsers. It’s not perfect, but it’s much lighter.


What is MathML?

Mathematical Markup Language (MathML) is a mathematical markup language, an application of XML for describing mathematical notations and capturing both its structure and content. It aims at integrating mathematical formulae into World Wide Web pages and other documents. It is part of HTML5 and an ISO standard ISO/IEC 40314 since 2015.

It essentially is a more standardized version of TeX equations rendered in an XML format, that says “put this here, relative to this”. One of the great things about it is that with no JS enabled on the page, Firefox will still render equations!


So this is a pretty awesome thing for displaying math natively in browsers, but currently only gecko-based browsers actually support it. This means that anybody using Chrome or Chromium won’t see it, Microsoft browsers, Safari, etc.

Many people use MathJax to render, but using their current version 3 minified JS means adding a whopping 794.4kB per page! Just to render a few equations! Holy balls batman!

Surely we can do better?


So the first place I check out is a little Google-foo (but in DuckDuckGo instead), and there are reccomendations to checkout the pandoc manual. Here are the options we are provided:

--mathjax[=URL] Use MathJax to display embedded TeX math in HTML output.

--mathml Convert TeX math to MathML (in epub3, docbook4, docbook5, jats, html4 and html5).

--webtex[=URL] Convert TeX formulas to <img> tags that link to an external script that converts formulas to images.

--katex[=URL] Use KaTeX to display embedded TeX math in HTML output.

--gladtex Enclose TeX math in <eq> tags in HTML output.

Pick your poison!

I checked out several of the options and had various criticisms of each:

Given --mathml’s eventual native support in-browser without requiring JS, it seems like the best time investment and best future compatibility option. Given the big names behind it, I don’t really see it going anywhere for now.


I’m using an old project by pshihn to render MathML instead, measuring in at just 75kB for the main script and 1.3kB for the PolyFill. The puts us nicely in a ten times saving.

Sure, the project is old and likely not rendering everything perfectly, but it works good enough for any equations I’m going to be writing on here. I can always upgrade to a beefier version at a later date.


So how does this all work with pandoc?

When I writing a document, I’ll have something like this:

0001 We represent this as a half, $\frac{1}{2}$.

In the compile script, you then add --mathml option on the command line for pandoc.

This of course will only work for Firefox et al, so now you need to link your JS to get Chrome et al playing well. At the bottom of the page you add:

0002 <script src="/mathml.js" defer></script>
0003 <script src="/mathml-poly.js" defer></script>

The defer loads the script after the page is loaded. There are a few reasons for this:

  1. Time till initial render is important. I want a read-able web-page ASAP, even if the equations look screwed. If you have potato internet, you want to be able to read the page as soon as possible.
  2. It’s unlikely there will even be equations on the page, so don’t stall the rendering process for an unlikely use case.
  3. Equations are really not that large in general, I wouldn’t expect the web-page to move around tonnes anyway.

When all is said and done, it should look like this:

We represent this as a half, 12\frac{1}{2}.


Of course, it’s not quite as simple as this. Chromium (and possibly Chrome) like to display annotations, which screws up the look after the rendering process. This can be fixed by adding the following CSS:

0004 annotation{ display: none; }

This just hides annotations, as they should be hidden.


Ideally I want to be able to detect if math is even used on the page at all and only add the resource if required. Almost 100kB for something that is mostly not used is still way too much for my liking.

At some point I will figure out how to statically render equations instead of having to use JS-based solutions - there is no reason at all that I couldn’t just produce an SVG and embed it into the page. Unfortunately the support for such a thing is really not great at all at the moment, so I am stuck with this hacky option.