
MathJax Turns 3.0 - pcr910303
http://bit-player.org/2020/mathjax-turns-3-0
======
svat
Any software project should be lucky to have a post like this written by a
user, let alone as wonderful a writer as Brian Hayes.

On comparison with KaTeX:

• It appears from this comparison page ([https://www.intmath.com/cg5/katex-
mathjax-comparison.php](https://www.intmath.com/cg5/katex-mathjax-
comparison.php)) that MathJax 3 is about twice as fast as MathJax 2, but still
slower than KaTeX. (Though it's variable, e.g. by directly reloading
[https://www.intmath.com/cg5/katex-mathjax-
comparison.php?pro...](https://www.intmath.com/cg5/katex-mathjax-
comparison.php?processor=MathJax3) enough times, I was able sometimes to get
load times for MathJax faster than some load times for KaTeX.)

• It is surprisingly difficult to get a clear answer to _what_ exactly one
gets in MathJax, in return for this slower speed. One relatively clear thing
is that MathJax supports more features, e.g. last I tried something I
considered basic was unavailable in KaTeX (IIRC it was adding a \label to an
equation and referring to it again elsewhere in the page with \ref). But
beyond that, if everything one needs happens to be supported by KaTeX, are
there still reasons to use MathJax? One would imagine that someone on the
MathJax team, or even a devoted user, would have such a list somewhere, but I
haven't been able to find one.

• One thing I remember reading is that MathJax takes a fundamentally different
approach, and that a lot of the time it spends is in measuring things on the
page to get things exactly right, while KaTeX is looser about things. I do
notice just now that on my mobile, where I have accessibility features turned
on to zoom text to a larger default font size, with MathJax (on the above
comparison page) all the equations are scaled up such that the font size of
symbols in the page matches the font size of surrounding text, while KaTeX
gets this wrong. What is the extent of such differences?

• Both MathJax and KaTeX support server-side rendering, and the speed
differences vanish (for the reader at least) when nothing is being done
client-side.

On MathML:

• Disclaimer: I must confess to an annoyance with MathML proponents because
(1) they seem to advocate using MathML even though it has poor browser
support. (Even in Firefox where it's supported the rendering is often poorer
than TeX's), and (2) they seem to imagine (somewhat like the "semantic web"
people) some ideal world where authors bother to indicate the semantics of
their equations (e.g. what a \sum is a sum over) rather than simply
communicate in notation. (Don't want to repeat comments; see this year-old
thread:
[https://news.ycombinator.com/item?id=19347737](https://news.ycombinator.com/item?id=19347737)
— in particular see the examples and comparison on the Wikipedia article
[https://en.wikipedia.org/w/index.php?title=MathML&oldid=9454...](https://en.wikipedia.org/w/index.php?title=MathML&oldid=945451833#Presentation_and_semantics)
)

• MathJax does support MathML as an input format (for some tools I guess?),
and support for MathML as output format is no longer built-in: see
[http://docs.mathjax.org/en/latest/output/mathml.html](http://docs.mathjax.org/en/latest/output/mathml.html)
versus
[https://docs.mathjax.org/en/v2.7-latest/mathml.html](https://docs.mathjax.org/en/v2.7-latest/mathml.html)
Anyway, whatever the future of MathML (i.e. even if browsers someday care
enough about “proper” mathematics typesetting to render it natively and like
TeX), we'll still need something like MathJax or KaTeX running somewhere, as
(La)TeX notation is what mathematicians are familiar with, and something like
it is what they're likely to want to write.

~~~
joppy
I am a MathJax/KaTeX user, not developer, so some of what I say could be
incorrect. I was under the impression that KaTeX does _no_ horizontal
measurement to speak of, deferring it instead into CSS and styling
calculations carried out by the browser. This is why at the moment KaTeX
cannot write to a canvas / SVG representation, only to HTML. On the other
hand, I think MathJax takes the more fundamental approach of knowing how to
absolutely position every single glyph (although for HTML output, some of
these absolute positions are perhaps replaced by more KaTeX-style rules).

This means that at the moment it would be fairly annoying to create a library
which renders a commutative diagram such as [1] in KaTeX, as one would have to
render each part of the diagram in the browser to calculate sizes, and only
then compute positions for arrows - in particular this could only be done
ahead-of-time by firing up some headless browser, taking measurements, and
then hoping for the best (the client isn't using different font sizes, for
example). MathJax seems more suitable for that application due to knowing the
sizes of things.

[1]:
[https://en.wikipedia.org/wiki/Monoid_(category_theory)#/medi...](https://en.wikipedia.org/wiki/Monoid_\(category_theory\)#/media/File:Monoid_multiplication.svg)

~~~
svat
Ah that's interesting, thank you. Looks like an interesting design choice, and
would explain how it manages to be so fast.

------
sleavey
I've been using KaTeX [1] for browser-based scientific logbook software since
it loads and renders much more quickly than MathJax and doesn't make the page
text move around while it renders. It doesn't support the complete TeX
instruction set (yet) but it gets pretty close.

EDIT: looks like MathJax 3 is a lot quicker to render than older versions [2]
- interesting.

[1] [https://katex.org/](https://katex.org/)

[2] [https://www.intmath.com/cg5/katex-mathjax-
comparison.php](https://www.intmath.com/cg5/katex-mathjax-comparison.php)

~~~
tomxor
Me too, I made an early decision to _not_ use MathJax in our product due to
the instant hit to page weight and rendering performance... With Katex you
forget that it's even there, we've managed the lack of certain features better
than expected - I suppose the general takeaway is that comprehensive features
are not always worth the technical cost, especially when they have a direct
impact on user experience.

------
saagarjha
Interestingly, the second demo with the “fixed” layout behavior actually has
digits cut off as I move the slider around in my browser; I’m not sure why.
More on topic, though, I’m somewhat disappointed that MathML doesn’t seem to
have taken off as much as it could have: it would be really nice to be able to
send some code embedded in HTML and have it render on the client without any
JavaScript at all. I wonder if the delay in implementation has anything to do
with the abundance of use of MathJax, making working on it low-priority.

~~~
btrettel
> I wonder if the delay in implementation has anything to do with the
> abundance of use of MathJax, making working on it low-priority.

I've thought the exact same thing before.

In the future I'm planning some articles with math on my personal website, and
my current intention is to only use MathML without any JS renderer. I use
Firefox so this isn't a problem for me. This would make the page a fair bit
lighter, rendering time faster, and maybe make web developers using Chrome
think twice about ensuring compatibility as too many websites are Chrome-only
these days. ;-) [1]

Seems that there is some progress in getting MathML in Chrome so possibly by
the time these articles go online, there won't be an issue.

[https://mathml.igalia.com/faq/#When%20will%20it%20be%20in%20...](https://mathml.igalia.com/faq/#When%20will%20it%20be%20in%20Chrome%3F)

> We have, however, set what we believe is a very achievable and safe target
> goal: to get MathML support fully upstreamed and shipping in Chrome by
> August 2020.

[1] One major example I noticed in the past few days is that
[https://wiki.c2.com/](https://wiki.c2.com/) no longer seems to work in
Firefox at all. I just get an error saying "Trouble Encountered". Works fine
in Chromium.

~~~
the_why_of_y
It's a pity that Google is so short on cash that they apparently can't spare
the $320k that's still missing from the funding of the Igalia implementation.
All those ads on Google web properties that tell users of MathML supporting
browsers to _upgrade to Google Chrome_ must have eaten their development
budget.

------
Myrmornis
Can anyone point me to (or post) an explanation of how MathJax/Katex work?
I.e. what exactly does one have to implement in order to provide the
functionality they do? I'm particularly interested in the fonts and rendering
side of this. In fact I'd be interested also in reading about how the font and
rendering process in a standard desktop LaTeX / dvi / $outputformat works in
comparison to the javascript emulations.

~~~
svat
Broadly speaking:

1\. Parse the user's input (e.g. "{-b \pm \sqrt{b^2-4ac} \over 2a}") into an
internal data structure (math lists, etc -- MathJax apparently uses MathML
internally)

2\. Classify the symbols and operators into different styles, with associated
sizes and spacing, etc.

3\. Ultimately, decide the position and size of each glyph (where each
separate "blob of ink" should go).

4\. Express these positions in the output format, e.g. for MathJax or KaTeX
with their native HTML+CSS, you'll get a tag soup of spans with styles like
"position: absolute; top: -4.333em; left: 0.566em;" etc. DVI or PDF output
formats have their own operators for expressing positions of glyphs.

As far as fonts and rendering are concerned there is not much to this; the
glyphs are just picked from a math font that someone has designed (containing
glyphs for, say, the integral sign or summation sign or "x" etc).

The interesting work of _typesetting_ that happens in 2 and 3 is described
(for TeX, and used by MathJax/KaTeX) in Appendix G of _The TeXbook_ ; you may
find it useful to supplement it with pictures and explanation from this
article:
[https://www.tug.org/TUGboat/tb27-1/tb86jackowski.pdf](https://www.tug.org/TUGboat/tb27-1/tb86jackowski.pdf)

If you'd like to know one of these in further detail I can try to explain or
look it up :)

~~~
Myrmornis
Wow, thanks very much. I have not yet studied Appendix G or the Jackowski
article, but let me see if I have this straight:

Suppose we give the string `\int` to the `latex` executable, and it produces a
DVI file.

The DVI file that was produced specifies exactly how the integral symbol
should be shaped. It does this by specifying (a) the name of a font that is
installed on the user's system and (b) the identity of a glyph within that
font that should be used to display the integral symbol.

So, if we now run dvipng, what dvipng does is look up the glyph from that
font, and create a rectangular array of pixels that approximate that shape.

Similarly, if we were to run dvisvgm, it would look up the glyph in the font,
and create an SVG specification of some curves that can be used to approximate
that symbol.

(I have no knowledge of how a font specifies a "glyph"; is it conceptually
similar to the way SVG specifies curves?)

~~~
svat
Yes that's right. Consider a TeX file test.tex containing

    
    
        $\int$ \nopagenumbers \bye
    

or if you prefer LaTeX, containing

    
    
        \documentclass{article}\pagestyle{empty}\begin{document}$\int$\end{document}
    

If you run "tex" or "latex" on this, it will generate a test.dvi. You can look
at a human-readable representation of the DVI file with dvitype or dviasm —
what it says is to move to a particular position, and set the character at
position 82 ('R') from the font "cmex10 at 10pt".

Then you can run either dvipng or dvisvgm (or dvipdfmx, or…) on this, which
will take this instruction, read in the font (for example, it may load file
/usr/local/texlive/2019/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb)
and replace it with the pixels (at a given resolution) or shape from the font.
In case of SVG, it may pick the actual description (as a path) from the
(vector) font:

    
    
        <glyph unicode='' horiz-adv-x='472' vert-adv-y='472' glyph-name='integraltext' d='M272 -880C259 -1044 223 -1089 166 -1089C153 -1089 123 -1086 102 -1068C131 -1064 139 -1041 139 -1027C139 -998 117 -985 98 -985C78 -985 56 -998 56 -1028C56 -1076 106 -1111 166 -1111C261 -1111 309 -1024 331 -934C344 -882 380 -591 388 -480L407 -231C421 -47 455 -22 500 -22C510 -22 541 -24 563 -43C534 -47 526 -70 526 -84C526 -113 548 -126 567 -126C587 -126 609 -113 609 -83C609 -35 559 0 499 0C404 0 365 -97 348 -173C336 -228 300 -510 291 -631L272 -880Z'/>
    

\----

You may be interested to know _where_ the description in the font came from.
The short answer is "the font designer" (of whatever font is being used). In
this case, cmex10 is the "math extension" font from the Computer Modern family
designed by Donald Knuth (the author of TeX and METAFONT). He described the
shape in METAFONT, etc. All that's another story :)

~~~
Myrmornis
Thank you, very interesting and helpful. (I ran dvitype on that as you
suggested.)

I think I'm just going to describe what I'm doing in case you have any more
helpful words of advice or thoughts! Obviously no worries if not.

I'm working on a project that involves generating images from LaTeX math
fragments and displaying them in a text editor buffer inline with the text, to
create an environment for editing LaTeX math without needing to constantly
regenerate the PDF. So similar to what also exists in various places, e.g.
preview-latex and org-mode in Emacs.

In one sentence: I am struggling to produce non-fuzzy images when using dvipng
or imagemagick to produce a PNG.

I am at the stage where I am trying to identify the best image-generation
workflows to support. Users might have conventional screens, or high res
("4k?") screens, or high res Apple Retina screens. For example, Emacs org-mode
offers the following 3 flows:

* dvisvgm - LaTeX DVI output is converted to SVG and Emacs displays the SVG.

* imagemagick - LaTeX PDF output is converted to PNG by imagemagick and Emacs displays the PNG.

* dvipng - LaTeX DVI output is converted to PNG and Emacs displays the PNG.

I personally own a Macbook Pro with a Retina screen and what I have observed
is:

Iff your text editor is built with special support for Retina screens:

1\. Beautiful crisp results can be obtained via dvisvgm.

2\. It is also possible to produce a high resolution PNG and then resize it
down in the editor so that it retains its crisp appearance at small size.

However, using dvipng (latex -> dvi -> png) or imagemagick (latex -> pdf ->
png) I have not yet managed to obtain any crisp images of math fragments when
they are at the size of a conventional line of text on the screen. That's on a
Retina screen; I'm also planning to test against a conventional monitor via a
raspberry pi.

I believe that dvipng does not include a "pHYs" chunk in the PNG data, and
that this may be one reason that I am struggling to create small PNGs with
high pixel density.

~~~
svat
Ah rasterization is another rabbit hole that I don't know much about and can't
say anything without trial-and-error experimentation on the specific device
:-) But first I'd recommend checking whether the image is being displayed at
its natural size, pixel-for-pixel (or conversely that it is being generated to
have the number of pixels at which it is going to be displayed -- both
imagemagick and dvipng take a dpi option). See also some approaches at
[https://tex.stackexchange.com/questions/44486/pixel-
perfect-...](https://tex.stackexchange.com/questions/44486/pixel-perfect-
vertical-alignment-of-image-rendered-tex-snippets)

~~~
Myrmornis
Thanks! (And crikey, that is quite a post!)

------
nicodjimenez
MathJax 3.0 is a fantastic project and is a huge improvement over MathJax 2.0
(much faster, uses SVG) as well as Katex (by just supporting much more math
than Katex).

We use it throughout our company (mathpix.com) and in fact built an
abstraction on top of it to render markdown + latex together:

[https://github.com/Mathpix/mathpix-markdown-
it](https://github.com/Mathpix/mathpix-markdown-it)

which uses MathJax 3.0 to render math and to do math conversion.

------
qubyte
I integrated MathJax 2 into my static site generator, and just recently bumped
it to version 3 (which is quite different). You can see the result here:

[https://qubyte.codes/blog/the-maths-of-domains-of-points-
wit...](https://qubyte.codes/blog/the-maths-of-domains-of-points-with-spokes)

And you can see the code which integrates version 3 (in this case by hacking
marked to render it in fenced markdown blocks labelled as mathematics) here:

[https://github.com/qubyte/qubyte-
codes/blob/master/lib/rende...](https://github.com/qubyte/qubyte-
codes/blob/master/lib/render.js)

------
terhechte
Does anybody know if there is a C/C++ (MIT oder equal) library that has few
dependencies and can generate images from equations, similar to MathJax? (I.e.
not LaTeX due to not a library and a lot of dependencies)

~~~
ivan_ah
Not a C/C++ library, but you can maybe call out to node to get SVGs, see
[https://github.com/mathjax/MathJax-demos-
node/blob/master/co...](https://github.com/mathjax/MathJax-demos-
node/blob/master/component/tex2svg) via
[http://docs.mathjax.org/en/latest/server/start.html#node-
sta...](http://docs.mathjax.org/en/latest/server/start.html#node-start) then
Inkscape for svg to png conversion, see
[https://github.com/softcover/softcover/blob/master/lib/softc...](https://github.com/softcover/softcover/blob/master/lib/softcover/builders/epub.rb#L361-L369)

But I think the above pipeline is even more external-dependecyful than using
the real latex...

------
mbeex
Does someone know, if MathJax can be utilized as renderer for a static web
site? I do this with KaTeX for my Pelican-based blog successfully, after I
found no way to integrate MathJax easily into the workflow.

~~~
qubyte
I commented elsewhere, but yes it can! It took a bit of head scratching but I
got there in the end with my own Node.js based static site generator. This
code integrates version 3 of MathJax, which was considerably different to
version 2.

[https://github.com/qubyte/qubyte-
codes/blob/master/lib/rende...](https://github.com/qubyte/qubyte-
codes/blob/master/lib/render.js)

See in particular the top of that file, and the renderMaths function. I'm not
sure how you'll integrate MathJax into Pelican given the language gap, but in
principle it's possible.

~~~
mbeex
My KaTex/Pelican-based solution is here (don't mind - new blog, no real
content yet, but the technical side is visible):

[https://depot.traits.de/](https://depot.traits.de/)

Feature test here:

[https://depot.traits.de/pages/2020/02/21-rest-
example.html](https://depot.traits.de/pages/2020/02/21-rest-example.html)

------
frank2
I wish I could copy math from the document I am reading, then paste it into a
text editor like I can with ordinary non-math text on most web pages.

~~~
joppy
Plain monospaced text is pretty awful for reading mathematics - why not switch
to something higher-bandwidth with rich text, pictures, and mathematics?

~~~
frank2
Good point. My comment would've been better with "editor" instead of "text
editor".

