KaTeX with ASCIIMathML input and MathJax fallback
By Murray Bourne, 19 Sep 2014
I recently wrote about the new way to deliver math on the Web, called KaTeX (a direct competitor to MathJax, which I've been using on IntMath for some time now).
KaTeX only accepts LaTeX input
While KaTeX is a lot faster than MathJax, for me there are 2 downsides with KaTeX:
- KaTeX only accepts LaTeX input. However, I have used ASCIIMathML for all the equations and formulas on IntMath, because it is signiicantly simpler and easier to use than LaTeX. If I wanted to use KaTeX for my site, I'm stuck.
- KaTeX doesn't recognize many math expressions yet, for example matrices, determinants, various symbols, "aligned" environments (where you can align everything on the equal sign), various accents, case definitions and so on.
So I set about writing a page that handles both of these issues.
ASCIIMathML input, fallback to MathJax
I needed a system that recognised ASCIIMathML input, converted it to LaTeX, and then was processed by KaTeX so it looked like "real" math. In the cases where KaTeX cannot handle the math, it needs to fall back to MathJax so all the math is rendered properly.
Here is a demo of my solution:
You'll see some equations appear quickly (those done by KaTeX), then the MathJax-rendered ones will appear. They have a green mark next to them so you can see what MathJax can do that KaTeX cannot.
This is deliberately a "heavy" page (with many equations) to push its performance.
How is it done?
Fortunately, ASCIIMathML comes with a script, ASCIIMathTeXImg.js, which converts the simple ASCIIMathML input to LaTeX, and then outputs each math expression as an image (using MimeTex or MathTex).
I modified the function AMTparseMath() in ASCIIMathTeXImg.js, so it no longer converts math to images, but outputs LaTeX.
My tweaks were:
- Create a span in the place of each piece of ASCIIMathML
- Give the span a unique id
- Try first to render it with KaTeX
- If that fails, put back the original ASCIIMathML and render it with MathJax
Here's the relevant parts of the changed script.
var node = document.createElement("span"); thisId = "mathId"+counter; node.id = thisId; try { katex.render(texstring,node); } catch(err) { node.className = "mj"; node.innerHTML = "`"+str+"`"; MathJax.Hub.Queue(["Typeset",MathJax.Hub,thisId]); } counter++;
Downsides to the approach
Of course, the main aim is speed, and if the user needs to download both KaTeX and MathJax, as well as ASCIIMathTeXImg.js, there is going to be a significant delay before any rendering occurs, especially on a mobile device.
On my phone, the first KaTeX equations on the demo page appeared in about 6 seconds, and the MathJax matrix came in around the 13 second mark.
But it is a feasible solution for mobile devices, especially if your more complicated equations are low down the page (so they will process in the background and be done before the user gets to them).
Another downside is that the user will need to download 2 sets of fonts - one for MathJax and one for KaTeX. One way out of that would be to specify one or the other.
Related pages
You may also be interested in this demo, where you can see how much faster KaTeX does its thing compared to MathJax:
This page gives background on KaTeX:
This page is a sandbox where you can play with ASCIIMathML input:
This page uses the script mentioned above, ASCIIMathTeXImg.js, to send math in emails:
And finally, this page gives examples of how to enter math using ASCIIMathML:
Credits
Peter Jipsen and David Lippman for ASCIIMathML.
The MathJax team (especially Davide and Peter) for MathJax.
The Khan Academy team for KaTeX.
Be the first to comment below.