~hanwen >_

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:

There is also some disadvantages:

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:

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.