11ty Math
Markdown, LaTex and ASCII - who writes HTML?
Very nearly none of the content that we encounter online is entirely hand authored from opening doctype to closing HTML tag - it's assembled. We have layouts, and includes and templates and so on. And, most of the actual content that we produce and consume is written in some more familiar or easier to write shorthand. For most of the people reading this, it's probably mostly markdown.
But did you know that lots of the places that you use markdown like GitHub and GitLab, and Visual Studio support embedding mathematical expressions written in LaTex surrounded by $
(inline) or $$
(block)? Those are then transformed for you to rendered Math with MathML?
It got me thinking that we should have a kind of similarly standard easy setup for 11ty. It would be a huge win to process it on the server, MathML will render natively, fast, without FOUC. It will be accessible, styleable, scale appropriately with text-size and zoom and so on.
The super interesting thing to note about most of the tools where you can use markup is that so many of them are built on common infrastructure: markdown-it. The architectural pattern of markdown-it allows people to write plugins, and if you're looking to match those above, you can do it pretty easily with the @mdit/plugin-katex:
/* eleventy.config.js */
const markdownIt = require("markdown-it");
module.exports = async function (eleventyConfig) {
const { katex } = (await import("@mdit/plugin-katex"));
eleventyConfig.setLibrary(
"md",
markdownIt().use(katex, {output: "mathml"})
);
}
And... That's it. Now you can embed LaTex math in your markdown just as you can in those other places and it will do the work of generating fast, native, accessible, and styleable MathML...
Some math $\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1$ whee.
Yields...
<p>Some math <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><msup><mi>x</mi><mn>2</mn></msup><msup><mi>a</mi><mn>2</mn></msup></mfrac><mo>+</mo><mfrac><msup><mi>y</mi><mn>2</mn></msup><msup><mi>b</mi><mn>2</mn></msup></mfrac><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1</annotation></semantics></math></span> whee.</p>
Which your browser renders as...
Some math inline whee.
Surrounding the math part alone with $$
instead yields block math, which renders as..
<link href="https://fred-wang.github.io/MathFonts/STIX/mathfonts.css" />
.
You can read a lot more about this on MDN.
AsciiMath Math / Mathup
While LaTeX is by far the most common way that people author math, there are people who prefer AsciiMath. Rúnar Berg Baugsson Sigríðarson (@runarberg) has a nice explanation as to why they prefer to not use TeX.
His mathup package seems pretty nice (an AsciiMath dialect more than just AsciiMath), and there is also a corresponding markdown-it-math which is similarly easy to use...
/* eleventy.config.js */
const markdownIt = require("markdown-it");
module.exports = async function (eleventyConfig) {
const markdownItMath =
(await import('markdown-it-math')).default;
eleventyConfig.setLibrary(
"md",
markdownIt().use(markdownItMath)
);
}
Then, you can embed AsciiMath in your markdown, fenced by the same $
or $$
and it will generate some nice MathML. For example...
$$
e = sum_(n=0)^oo 1/n!
$$
Will be transformed at build time and render in your browser as...
Make sure you get markdown-it-math 5.0.0-rc.0 or above or this won't work. You might also consider including their stylesheet.
markdown-it-math also supports a nice pattern for easily integrating other engines for embedded transformations like Ron Kok's Temml or Fred Wang's TeXZilla.
Unicode Math
There is also Unicode Math, which Murray Sargent III developed and had integrated into all of the Microsoft products. It's pretty nifty too if you ask me. This repo has a nice comparison of the three.
Unfortunately there is no npm module for it (yet), so for now, unfortunately that remains an open wish.
So, that's it. Enjoy. Mathify your static sites.
Before you go... The work of Math rendering in browsers is severely under funded. Almost none of the effort or funding over the last 30 years to make this possible has come from browser vendors, but rather from individual contributors and those willing to help fund them. If you appreciate the importance of this work, please consider helping to support the work with a small monthly donation, and please help us to publicly lobby implementers to invest in it.