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 (inepub3
,docbook4
,docbook5
,jats
,html4
andhtml5
).
--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:
--mathjax[=URL]
- Is a super massive JS library.--mathml
- Only works for Firefox and Safari. There is hope that in the future it will have native support across all browsers though.--webtex[=URL]
- Relies on external services to render equations for you - really against the point of self-hosting my server.--katex[=URL]
- I didn’t check out this option, but it is very large and will always depend on JS.--gladtex
- This is the closest to what I actually wanted, but introduces a bunch of problems in itself. It can generate images from equations, but I wanted them to be embedded into the page - otherwise I then have to figure out how to find somewhere to store the images and not mess up the auto-pull script in git. It was a lot more headache than I wanted.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:
When all is said and done, it should look like this:
We represent this as a half, .
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.