Written by: algebnaly
Date: 2026-03-29T16:45:12.000Z
尽管有astro-typst这样的 astro集成可以直接在astro中使用typst渲染博客页面。但是它基于主线typst release版本, 而截至这篇博客编写的时候 mkorje的mathml分支 还没有被合并进主线, 但是我已经按耐不住想用typst编写数学博客的心情, 开始着手实现使用mkorje的mathml分支渲染typst博客页面。
基本上代码全是gemini写的, 基本的做法就是通过vite plugin把typst文件编译成html, 然后使用正则表达式取出<style>和<body> 合并成一个html片段字符串, 然后使用typst query 命令取出frontmatter的内容。然后把这两个部分作为js模块的两个导出变量。
return {
code: `
export const frontmatter = ${JSON.stringify(frontmatter)};
export const html = ${JSON.stringify(finalHtml)};
export default html;
`,
map: null
};
接着就是使用astro提供的[…slug].astro生成动态路由, 把那两个导出的变量填进astro页面的模板中, 就能访问typst生成的博客页面了。
也就是说vite插件实际上是把typst的渲染结果(html)作为js变量导入到astro中。
我使用cloudflare pages托管我的博客, 由于我使用的是自己编译的特定版本的typst, 构建环境并不能直接获取这个特殊版本的typst可执行文件, 我编译了一个musl静态链接的typst可执行文件(至于为什么要使用musl, 那就是另一个故事了), 并上传到cloudflare R2上, 然后在vite插件中下载该typst可执行文件, 这样就搞定了!
$ e^(pi i) + 1 = 0 $
$ mat(1,2,3 ; 4,5,6; 7,8,9) $
下面的几种字体都是typst官网的例子:
sans:
$ sans(A B C) $
frak:
$ frak(P) $
mono:
$ mono(x + y = z) $
bb:
$ bb(b) $
$ bb(N) = NN $
$ f: NN -> RR $
cal:
Let $cal(P)$ be the set of ...
Let be the set of …
scr:
$scr(L)$ is not the set of linear maps $cal(L)$.
is not the set of linear maps .
看起来Script font还是有点问题。不过我已经很满意了。