Pre-rendering maths with Hugo
By Patrick Wigmore, , published:
When I started putting content into my new Hugo static site template, I quickly realised I was going to need a way to include mathematical expressions.
Perhaps the best-established way to do this is to write the maths in LaTeX between delimiting dollar signs and then load a big JavaScript library like MathJax on the client side to post-process your web pages and turn that LaTeX into fancy-looking formulas, with accessibility features and such.
But I don’t want to load a big JavaScript library. I don’t want to load a small one either. I want it all to be pre-rendered before I upload it to the web server.
I spent quite a long time considering how I was going to achieve this. Hugo doesn’t natively support any kind of maths expression pre-rendering. In fact, it is a little awkward when it comes to passing through dollar signs and underscores for client-side rendering, too. And there isn’t a way to get Hugo to process content using a separate utility program during page rendering.
Someone went as far as to fork Hugo to add the required functionality, and I expect in the long run Hugo will gain this capability. But I needed something now and I didn’t want to go in that deep.
In my case, it’s only me authoring the content, and there isn’t likely to be that much maths in it, so I am happy to do things slightly manually. When I include images, I accept that I might need to prepare the images in a separate software package. I am taking a similar approach with maths:
- Pre-render the expressions into separate files, using KaTeX’s command line interface.
- Include the contents of those files in a page using a Hugo shortcode.
- Get Hugo to reference the KaTeX CSS file only on pages that use the shortcode.
This gives me visually-hidden MathML combined with a visual HTML and CSS version of the same thing that’s hidden from the accessibility tree.
Ideally I’d just use MathML, as that’s about the most accessible way to do this. But broad browser support for MathML is fairly new, so I feel it necessary to include some kind of fallback for now.
I was worried about the accessibility of visually hiding the MathML by default, but it seems this is not considered to be terrible and there probably isn’t a better way for the time being.