Typst 是一个把文档排版成 PDF、SVG、PNG 以及仍在开发中的 HTML 等格式的系统,擅长处理技术材料,常被视为 LaTeX 的最终替代者。一年前我们关注它时,版本为 0.13。0.15 版已于 6 月发布,带来可变字体、MathML、多文献支持等大量新功能。Typst 是免费、采用 Apache-2.0 许可的软件,用 Rust 编写。它新增的可变字体支持,让不同字重与斜体、粗体等变体可以集中在一个字体文件中。
正文
Typst 是一套把文档排版成 PDF、SVG、PNG 以及(仍在开发中的)HTML 等格式的系统。它擅长处理技术材料,常被视为 LaTeX 的最终替代品。一年前我们关注它时,版本是 0.13。新版本 0.15 已于 6 月发布,带来大量新特性,包括对可变字体、MathML、多份参考文献等的支持。Typst 是自由软件,采用 Apache-2.0 许可,用 Rust 编写。
可变字体
Typst 现在支持可变字体。多数字体以一组文件分发,各文件包含不同字重,以及斜体、粗体等变体。排版领域近年来的一个进展是可变字体的出现,它可以把所有变体装进单个文件,既省空间,也让作者或设计者有更大的灵活度。
字体特性和变体通过给“轴”设值来选取,每根轴改变渲染字形的某个方面。通常有多根轴,取值可以是离散的,用来开关各种特性,也可以是两个界限之间的连续值,比如沿连续区间选择字重。
为测试这项新功能,我下载了两款开源可变字体:通用字体 Roboto Flex,有 13 根轴;以及 Zycon,它不含字母,却有 17 张小装饰图。Zycon 的六根连续轴能平滑地改变图形的各个方面,因此适合做动画。
文中给出的 Typst 文档同时使用这两款字体,各自改变一根轴的值:先用 text() 函数按名称设定字体,然后用 for 循环,在循环内再次调用 text() 设定 variations 变量。Roboto Flex 的文字直接输入,而 Zycon 的输出是用 str.from-unicode() 指定的单个字符——本可以直接输入,但读者的浏览器字体未必覆盖该字符。
在 Typst 中,“#”字符让文档进入“代码模式”,其后本行或本块内容按 Typst 内置语言的代码解释;代码模式中方括号里的内容又被当作“文本模式”,即待排版的文字。
我们在 Roboto Flex 上操作的轴叫 YTDE。如下图,这根轴决定字体下伸部的长度,其他特征不变。这在排版表格时可能有用,比如避免下伸部与单元格边界相撞。Zycon 的六根轴之一名为“M1 ”(末尾两个空格是名称的一部分;所有轴名都是四个字符),它对不同字符有不同作用,对月亮字形而言就是改变月相。
用 typst compile vfont.typ 编译该文档会生成 vfont.pdf,即下图所示:

MathML
HTML 导出仍是 Typst 的实验性功能,但这个版本显示出明显进展。新的 HTML 主要特性是把数学公式翻译成 MathML。上一篇文章展示了某个定积分的标记,以及 Typst 渲染成 PDF 的结果。同一段 Typst 代码渲染成 HTML 时,会产出一长串 MathML 标记,几乎所有较新的浏览器都能解释。结果如下:
$$ \int_{0}^{1} \left(\left(\right. arcsin x \left.\right)\right)^{2} \frac{d x}{x^{2} \sqrt{1 - x^{2}}} = \pi ln 2 $$
如果你看不到上面的公式,说明浏览器不支持 MathML。如果能看到,与上一篇文章中排出的公式相比,PDF 和 HTML 的结果基本一致。能用 Typst 在浏览器里生成 TeX 品质的数学公式,既不需要 MathJax 这类 JavaScript 库,也不必退而使用图片,这对科学传播是一大好事。
要启用实验性的 HTML 输出,Typst 需要特殊标志:typst c --features html integral.typ integral.html,这条命令把 integral.typ 中的公式标记排版成 HTML。
“Bundle”输出
Typst 这类软件的典型用途是生成单个文件,通常是 PDF 形式的论文或书籍。新的“bundle”功能允许作者在单个源文件里指定一组输出文件,格式可以是 Typst 支持的任何一种。这些文件可以共享数据,并包含文档内和文档间的链接。
该功能非常适合创建网站——网站本就是由互相链接的 HTML 文件构成的网络。对学者也有吸引力:他们可以想从同一个源文件同时生成会议演讲幻灯片和相关预印本。
文中给出一个简单例子:一个 Typst 文件创建三份互链文档,两个 HTML 页面加一个 PDF,共享一段文本。三个 #document() 分别对应 poems.html、jabberwocky.html 和 jabberwocky.pdf,各自带标题,末尾用尖括号里的标签作为链接目标。若代码保存在 bundle.typ,处理命令是 typst c --features html,bundle --format bundle bundle.typ。
在我的测试中,bundle 功能表现符合宣传,但由于它和 HTML 输出一样仍属半成品,编译器要求加 --features 标志。上述命令会新建一个名为“bundle”的目录,里面是 #document() 函数定义的三个文件。它们都含有存在 text 变量里的诗的头两行。HTML 页面之间有超链接,其中一个页面链接到 PDF,PDF 又链回这两页网站。链接通过每个 document 函数后面尖括号里的标签定位。
多份参考文献
Typst 现在允许在单个文档里放多份参考文献,这是备受期待的功能。最典型的应用是需要为每章单独列参考书目的书籍。文中用一个玩具例子说明:第一行设定参考文献的字体比正文默认字号小;正文中“@”前缀生成默认的方括号数字引用;每章末尾调用 bibliography() 函数,第一个参数指定用哪个书目数据库(各节可以不同,也可以是一组数据库),group 参数控制引用编号方式,取 none 时每节都从 1 开始,也可以全篇连续编号或任意分组。
下图是该清单在 PDF 中的输出效果:

多种 PDF 标准
只要不使用专有扩展,通常就足以保证 Typst、LaTeX 或任何合格软件生成的 PDF 兑现格式的承诺:文档能在所有阅读器中打开、显示一致,现在如此,将来也如此。但更深一层看,PDF 并不只是 PDF。存在各种 PDF 版本,在版本之上还有几十种关于归档性和可访问性的正式标准。归档标准意在确保文档确实能在多种阅读软件中长期使用;可访问性标准则关乎各类残障人士使用 PDF 的便利。
Typst 原本就能针对不同的 PDF 版本和归档或可访问性标准。新特性是编译文档时可以同时针对多个标准。这很有用,因为人们可能想要一个兼具归档和可访问性属性的 PDF。该实现会在组合不兼容、或未遵循所针对标准的最佳实践时给出警告或错误,帮作者在 PDF 标准之林中导航。
例如,下面这条命令试图编译上一节的“book”文档,同时要求 PDF 1.7 版和 A-1b 归档标准:typst c --pdf-standard 1.7,a-1b book.typ。编译器报错:PDF 1.7 与 PDF/A-1b 不兼容,并提示 PDF/A-1b 要求 1.4 版。PDF 1.7 与 A-2b 兼容,所以 typst c --pdf-standard 1.7,a-2b book.typ 可行。但如果再加上 UA-1 可访问性标准,写成 typst c --pdf-standard 1.7,a-2b,ua-1 book.typ,又会报错:PDF/UA-1 错误——缺少文档标题,并提示用 set document(title: [...]) 设置标题。通常 Typst 编译器除语法正确外不作要求,但一旦指定某个可访问性标准,文档就必须符合该标准,UA-1 的要求之一就是文档标题。
这些并非纯粹的秘辛,尽管对普通科研论文或教材作者来说似乎关系不大。这些细节对档案管理者和出版者很重要;除了帮助残障用户,生成可访问的 PDF 在美国和许多其他国家对州及联邦政府都是法律要求。Typst 对多种 PDF 标准的高级处理,使它在这些场景中成为有用的工具。
结论
Typst 0.15 还有其他改进本文未详述,比如对专色(spot color)的支持、能说明编译过程中收敛失败原因的详细诊断信息,以及内置脚本语言中新的 map 和 filter 函数。文档已更新覆盖新版本,现有 26MB 的 PDF 可下载。
Typst 在 GitHub 上开发,有 460 名贡献者。项目创建者写了新贡献者指南,说明 PR 应该是什么样,并警告任何由 LLM 生成的代码或描述都会被拒绝。他们也很直白地表示,Typst 既是开源项目也是一家公司,关于项目方向和具体贡献是否合适的决定会考虑公司的需要。这是潜在贡献者和用户应当记住的一点。
这个系统的发展速度令人印象深刻。用户社区热情高涨,其参与已使 Typst 生态扩展到 1500 多个包。
然而,出版界的网络效应正阻止 Typst 实现我们在上一篇文章中看到的潜力。尽管用户已经做出模板来匹配若干期刊的样式规范,那些要求提交源文件(而不只是 PDF)的期刊仍坚持 LaTeX、Word 或其他格式,接受 Typst 标记稿的极少。只要 Typst 还处于 1.0 之前的状态(这大概还需时日),而且有对文档做出重大甚至破坏性改动的风险,这种情况就不太可能改变。
尽管如此,Typst 今天已是非常有用的工具。比如我最近需要做一个 SVG 标志,发现用 Typst 内置的绘图命令写一段文字描述,比动用绘图程序更快也更容易。很难说 Typst 的这些优势是否会让它成为许多人称道的“LaTeX 替代品”。但如果开发保持目前的速度,这完全可能——只是也许要一二十年才能实现。
评论
讨论整体是压倒性的正面:多数人把 Typst 视为终于可以摆脱 LaTeX 日常折磨的替代品,尤其推崇编译速度、语法和内置能力;分歧主要在于它能否完全取代 LaTeX,以及在引用样式、MathML 等学术和特定排版场景上是否已经成熟。
认为 Typst 已经在多数场景里明显优于 LaTeX
- 有人把丘吉尔那句“民主是最坏的制度,除了其他所有制度”套在 LaTeX 上,并庆幸现在有了新选择。(较多人) > 把丘吉尔的话改一改,LaTeX 是最差的排版体验——除了我们试过的其他所有技术;好在现在不是了。(@criemen)
- 从“写你真正想写的东西”这个角度看,Typst 把类 Markdown 语法和文档布局、样式结合得最好,在线和本地都让人愉快。(较多人)
- 重度 LaTeX 用户转来做活动邀请函觉得体验很好,愿意推荐;写论文的人也称其顺滑。(较多人)
编译速度和资源占用是压过其他方案的关键
- 与 PeachPDF、iText 等生成大型报告比较后,Typst 生成 2000 页 PDF 只需数秒,内存通常约 250MB,峰值约 2GB;对比方案分别要 15–30GB 和 4GB,CPU 也快得多。(较多人) > 现在下载并在 PDF 阅读器里渲染反而成了新的瓶颈。(@merb)
迁移者最看重的是单文件、单遍编译、诊断和版本控制
- 编译不产生一堆中间文件,几乎瞬间完成;报错像 Rust 编译器建议一样好懂;语法更易读,列表可写成方括号形式便于括号匹配和导航。(较多人)
- 布局、页边距、间距、带页码的页脚更容易调;宏可放在使用处附近;大多数基础功能内置,不必像 LaTeX 那样先堆一堆包;发行版也轻量。(较多人) > 我还没遇到需要额外导入包或模板的情况,而最基础的 LaTeX 文档往往也要靠 fancyhdr 之类的包。(@commandersaki)
在实际生产工具里已经承担发票、报告、证书等批量生成
- 客户应用里用于会议胸牌、客户发票、社交媒体素材、完成证书、进度报告等,稳定高效,跨环境可用,不用再为“HTML 转 PDF”的格式问题操心。(较多人)
- 简历和模板填充是常见入口,有人把 TOML 或 JSON 数据直接导入模板,从其他工具生成内容;也有人给自己的所见即所得 Markdown/Typst 编辑器加了原生支持。(较多人)
仍有人怀疑它在特定排版质量与学术标准上追不上 LaTeX
- 页面里的 MathML 示例被指不像 TeX 质量,在手机上看起来歪歪扭扭。(少数人)
- 用 AGLC4 法学引用时,CSL 模板的 XML 确认无误却在 Typst 里渲染不对,只能手工排版引用和参考文献。(少数人)
- 论文投稿若必须套 IEEE LaTeX 模板,Typst 的顺滑体验会立刻被拉回现实。(少数人) > 半年后把论文改成会议论文,必须用 IEEE 的 LaTeX 格式提交,那一下真是让人清醒。(@andonvr)
输出 HTML 和可访问性被看作 PDF 之外的重要价值
- 长期受 PDF 折磨的学术阅读体验对屏幕阅读器极不友好,Typst 能同时发布 HTML 版本,是改善可访问性和互操作性的关键。(少数人) > PDF 格式本身就是个灾难,让可访问性乃至互操作性都变得不必要地痛苦。(@ethin)
社区支持和付费意愿被反复提及
- 在线编辑器尽管不常用也愿意付费,认为这是值得付钱的软件;Discord 社区虽然有人讨厌,但提问几乎能实时得到友好回答,比 LaTeX 求助容易。(较多人)
- 也有人提到模型已经比较会写 Typst 语法,不想学语法的人可以直接让模型代劳。(少数人)
有价值的补充
- Typst 可读取 TOML 或 JSON 作为数据源,把内容填充和模板分离,适合由其他工具批量生成文档。
- 除了 PDF,它还可以输出 HTML,这为既有排版需求又有网页发布需求的用户省掉两套工作流。
- Typst 只有一个精简发行版,不像 TeXLive 那样动辄数 GB;但也有人希望未来出现多个实现。
- 编译始终单遍完成,配合语义换行更容易做版本控制和 diff。
- 有评论者后来纠正了自己早先关于 LaTeX 不能在使用处定义宏的看法,指出 LaTeX 其实允许这样做。