Use Typst for Math in Blog
I just replaced the math rendering method in my blog from MathJax to Typst.
If you do not know what Typst is yet, it is a relatively new typesetting system. I would not say it can replace LaTeX in all senarios, but it is a good choice for typesetting simple documents. Besides, there is a JavaScript library named typst.ts which embeds Typst as WASM, making it possible to use almost the full power of Typst in the JavaScript world, including in the browser.
This replacement has the following advantages:
- No client-side rendering, because math are displayed as SVG images rendered when the page is built;
- One less JavaScript library to load;
- Ability to use the full math syntax of Typst, compared to MathJax as a subset of LaTeX.
There is also some disadvantages:
- Not friendly to accessibility, because the math are rendered as SVG images; however, I noticed that the produced SVGs have the text content embedded, so maybe it could work with screen readers, but I have not tested it yet;
- Different syntax from LaTeX (personally I consider this as an advantage, but it could be awkward to migrate previous posts);
- Not so convenient to integrate with all kinds of site builders, but this is not a problem for me (see the next section).
For some examples, you can see the math in this post.
Integration
typst.ts provides a Hexo renderer plugin and a rehype plugin officially. This blog is now built with Astro, so it is as simple as adding a new rehype plugin to the Astro configuration file:
import remarkMath from 'remark-math';
import rehypeTypst from '@myriaddreamin/rehype-typst';
export default defineConfig({
markdown: {
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeTypst]
},
})
and then formulas wrapped in dollar signs in Markdown files will be rendered by Typst.
I guess it would be a little more complicated to integrate it with other non-JavaScript site builders.
Fix in Dark Mode
One problem I encountered is that the default color of the SVG images is black, which is not suitable for dark mode. This can be fixed by adding a CSS filter to the SVG images:
@media (prefers-color-scheme: dark) {
svg.typst-doc {
filter: invert(100%) sepia(0%) saturate(367%) hue-rotate(19deg) brightness(105%) contrast(101%);
}
}
This CSS filter changes the color of the SVG images to #ffffff
, which is the text color in dark mode in this blog.
It is generated by this Codepen snippet mentioned in
this StackOverflow answer.
Fix Line Height
Another problem is that the line height of the SVG images is not the same as the text. The SVGs generated by typst.ts is calculated to have a specific height, which is slightly larger than the line-height
of <p>
elements in this blog. This leads to the result that paragraphs with math formulas have a larger line height than those without math formulas, which is very ugly.
The hard point is that these SVGs have their height
and width
attributes set by typst.ts and I cannot interfere with them directly, so I have to find a way not modifying the SVGs themselves.
Also, just scaling is not enough, because the baseline of the SVGs is aligned with the bottom of text, so scaling the SVGs will break this alignment.
The final solution is a bit tricky. It consists of two parts:
- slightly increase the
line-height
of the<p>
elements (from1.5
to1.6
); - manually set the
font-size
of the SVGs to16px
, compared to18px
of<body>
.
This way, the SVGs are not too small, the line-height (hence the line spacing) of text is not too large, and the baseline of the SVGs is still aligned with the bottom of text.
Conclusion
Using Typst for math display is good but not enough for me. Personally, Typst seems to me more like a “better Markdown” due to its markup syntax, its math support and the fact that it provides a more modern yet simpler language than LaTeX. It is a little unfair to it as it intends to compete with LaTeX though. For now, it can only be rendered to SVG and PDF in release versions, but the the basic support for HTML export is already merged into the main branch, and I am looking forward to it.