A simpler KaTeX alternative that works today

Summary

By updating pulldown-cmark to 0.11, we can instruct it to parse parts between single or double dollar signs as math. Then we can use latex2mathml to turn the math text into mathml. I have a prototype of this ready in a fork of zola.

Motivation

Supporting the rendering of mathematical formulas at generation time has been a wish of many for a few years now, given the posts here and the github issues about this. There was a PR to add KaTeX support to do this, which from my brief scanning of the comments got stuck on windows support? I believe my proposal is worthwhile because it’s a small, simple change that can immediately support the most common use cases, even if it may not be as complete as KaTeX.

Guide-level explanation

You can opt into support for rendering math formulas to mathml by specifying this in your config file under the markdown settings with math = true. Then LaTeX formulas between single dollars will be rendered as inline mathml formulas, while formulas between double dollars will be rendered as display style formulas. Zola uses the latex2mathml crate for this conversion. If you find yourself missing support for a particular LaTeX feature, check their documentation for more information or feature requests.

Reference-level explanation

As mentioned in the summary, we need pulldown-cmark version 0.11 to parse math as events. Then we can add latex2mathml to the libs component to use it in the markdown component. In particular, markdown_to_html we can add an if based on the new Zola config option markdown.math to add Options::ENABLE_MATH to the markdown parser. Then within the big event loop in the same function we match against the new DisplayMath and InlineMath events, call the latex_to_mathml function with the text from the event and the appropriate DisplayStyle option, and return the result as an Html event.
A wrong formula makes latex2mathml return an Err. In my branch I’m currently then returning the math event unchanged and putting the error in the mutable local variable for an error from the event processing loop.

Drawbacks

I don’t know that much about KaTeX except that it seems pretty complete, and outputs HTML for displaying formulas while also outputting (styled invisible) MathML to be semantically descriptive. By comparison, latex2mathml only outputs MathML and is limited by it. For example, MathML lacks the calligraphic mathvariant. I imagine this has some influence on browser support for displaying formulas as well.

Rationale and Alternatives

Given the technical difficulty with getting KaTeX support into Zola, I think this solution is simpler and still achieves support for most people’s needs. It’s also just a single, pure-rust dependency (which has no further dependencies), and seems to take very little time to do its thing. I don’t know how integration of KaTeX was envisioned, but I’ve had bad experiences in the past with a KaTeX plugin in Jekyll that made site generation significantly slower.

Prior Art

  • KaTeX, which can be used client-side with JavaScript and was attempted to be added into Zola so it could be rendered ahead of time.
  • MathJax, another JavaScript based client-side renderer of LaTeX formulas.

Unresolved Questions

  1. It’s unclear to me how the parsing of dollar signs changes in pulldown-cmark when you enable math mode. I think it would be nice be able to document this or point to more complete documentation. I think this can be easily resolved by asking nicely in their community. (So far I’ve changed single dollar signs in markdown to $, but haven’t checked yet with escaping with backslash works too, and whether that works inside a formula. I’ll do that soon, but I want to finish writing this post first.)
  2. Should we support multiple errors from the event processing loop? The single mutable variable seems a bit off to me, there can be multiple latex formulas with errors after all…
  3. Should the latex2mathml functionality be exposed as a filter too?

Future possibilities

I purposely named the config option in markdown math to be pretty generic. We could also call it latex. This way if it turns out KaTeX can be fully supported in Zola in the future and has a clear benefit worth the change, the latex2mathml crate can be removed in favour of KaTeX as the implementation for this feature.

1 Like

To answer question number 1: just a backslash in front of a dollar will work just fine.

A bit of experience with this latex2mathml crate has taught me that this thing is pretty limited. But hey, better than nothing. It also looks like things it doesn’t like will end up as MathML output rather than an error… So far that’s not been a problem for me, but that’s because I was paying attention.
Looks like it would be nice to eventually switch to KaTeX, but I still think it can be nice to start with this.

It’s also a very small change, have a look: Comparing getzola:next...Apanatshka:latex2mathml · getzola/zola · GitHub