There are multiple ways of invoking MathJax, but the one I’ve been using is simply to put a line in my html headers saying to load the MathJax library from a content distribution network (asynchronously, so that it doesn’t delay the pages from being shown to readers). Once MathJax loads, it scans through the html that it has been applied to, looking for blocks of math to reformat. The default way of marking these blocks is to include them in
\( ... \) or
\[ ... \] delimiters (for inline formulas and display formulas that go on a line of their own, as you might use in LaTeX if you aren’t still using
$ ... $ or
$$ ... $$ instead). There are ways of changing the defaults, and those ways have also changed between MathJax 2 and MathJax 3, but I wasn’t using them.
In kramdown, you don’t use the same delimiters for math. Kramdown expects to see mathematical formulas delimited by
$$ ... $$ in its marked-up text input, always. It will determine from context whether it’s an inline formula or a display formula. It also doesn’t use the default delimiters in the html that it generates. Instead it outputs html that puts inline formulas inside
<script type="math/tex"> ... </script> html tags, and, similarly, puts display formulas inside
<script type="math/tex; mode=display"> ... </script> tags. This all worked in MathJax 2, and these script delimiters are still recommended in the MathJax 3 documentation, but they don’t work any more.
_includes/head.html that gets copied into the headers of my html pages. It waits until the entire document is loaded, converts the delimiters, and then loads the MathJax library.
…and I thought I was done, until I started looking at some mathematics-intensive older posts, and found some more problems. In a few cases, kramdown has been putting more than just the script delimiters around its math formulas. Within the script tags, the math has been surrounded by a second level of delimiters,
% <![CDATA[ ... %]]>. This coding tells the html parser not to worry about weird special characters in the formula, and it was ignored by the old MathJax because the percent signs cause the rest of their lines to be treated as a comment. But the new MathJax parser doesn’t like the comments (or maybe treats the whole formula as a comment despite the newline characters within it) and displays a blank. This behavior is triggered in kramdown when a formula uses
< instead of
\lt (easy enough to avoid), or when it uses
& (e.g. in an aligned set of equations, not easy to avoid). So the actual code I ended up with is a little more complicated:
If you see any mathematics glitches in any of my old or new posts, please tell me; they could be more interactions like this that I haven’t spotted yet.
Edited (2019-10-31) to add: Thanks to Alexander Kalinin for pointing me to the official solution (see final bullet point under “Changes in the MathJax API”; via). It does much the same replacement by text, but at MathJax processing time rather than at DOMContentLoaded time, and (I’m told) works for CDATA without special handling.