Typst 很容易被包装成一套更快、使用起来更流畅的 PDF 生成工具。项目自己的 open-source 页面也确实提供了这套入口:开源编译器、CLI、可嵌入库,以及从 PDF、图片到网页的输出能力。[2] 这些说法都成立,只是还没有碰到真正决定 Typst 深浅的一层。只要把它往复杂一点的方向推,Typst 立刻会超出“舒服的标记语言”这一印象,显出一套上下文化排版引擎的形状。很多值要等编译器知道内容最终落在页面哪里之后,才会真正有意义。[1][2]
Laurenz Mädje 这场十五分钟的 Typst meetup 演讲,值得看正在这里。它没有停留在抽象层面上反复兜售优雅,转而挑出几组看上去带着玩笑意味、实际很有结构分量的边角案例。[1] 这场分享录于 2024 年 12 月 14 日柏林的 Typst 线下活动,随后在 12 月 20 日发布到官方 YouTube 频道。[1] 顺着这些例子往下看,整场演讲不断回到同一个中心:Typst 允许你对规则、计数器与文档位置做编程,可这些能力都发生在一套感知版面位置的执行模型里,离一条从上到下的单线文本处理流程很远。[1][3][4]
图像说明:题图里的 Monotype 键盘操作场景,是 Typst 所处理问题的早期物理形态:书写指令经由排版系统进入页面结构。它比代码截图或活动标题页更有现场感,也让这篇文章回到“让文档服从规则”的工艺现场。[1][2]
大约在 0:30,循环里生成 show rules,说明样式本身就在语言表面上
演讲开头先抛出一个看似带点恶作剧意味的例子:在循环里生成 set 与 show rules。[1] 如果你对 Typst 的预期仍停留在“把标记写漂亮一点”,这个例子会显得有些古怪;如果你把 Typst 放回可编程文档系统里,它却是很准确的开场。样式文档把 set rules 解释成设定默认样式的机制,把 show rules 解释成对匹配内容做变换的机制。[3] 这场演讲补上的,是更偏运行层的含义:这些规则早已超出躺在配置角落里的静态主题,它们本来就在语言表面上,可以被生成、组合、继续往下接。[1][3]
这件事会直接改变阅读 Typst 的方式。它已经超出“先写内容,后面再铺一层样式”的流程。在 Typst 里,样式行为本身可以从普通语言结构里长出来,呈现逻辑本身就待在程序里面,成为程序的一部分。把演讲与文档放在一起看,我的判断是:Typst 更深的一条边界,落在“可以继续做结构变换的内容”与“要等排版过程推进以后才能安全定型的结果”之间,而传统意义上的“内容”和“样式”分界反倒退到次要位置。[1][3][4]
大约在 3:18,计数器要等页面进入计算之后,才会真正稳下来
计数器这一段,是 Typst 超出“使用起来更流畅的 Markdown”并显出排版运行时气质的地方。[1] Mädje 展示了一个 weak page break 和 page counter reset 要彼此配合的场景,里头真正值得抓住的点很细:计数器更新能否成立,要看周围内容最后落在什么页面上。[1] 文档从两条线把这件事写清楚。counter 参考页把计数器定义成上下文化的值,可以显示、步进、更新,也可以读取最终值。[5] context 文档又解释了原因:有些表达式依赖位置、样式与周围状态,它们要等到合适的文档语境出现之后,意义才会完整。[4]
这层意思远强于“Typst 支持页码”这么一句概括。很多工具都能做页码,Typst 暴露出来的是更普遍的一条规则:只看源码顺序,很多文档状态还没有真正定型。[4][5] 这套前提一旦进入脑子,计数器的行为就会顺很多。一次 reset 超出凭空改一个整数的动作,它是一种和版面落点绑在一起的动作,要和引擎最后给出的页面位置对齐。所以这场演讲里的例子哪怕不被原样照搬,它仍然很有解释力。[1]
大约在 9:20,context 与 measure 连在一起,说明版面测量被有意推迟
演讲中段最值得反复看的位置,是 context 配合 measure 的那一段。[1] 这里真正重要的,核心问题超出 Typst 能测宽度这一层,落在它拒绝过早假装宽度已经存在。context 文档写得很明确:上下文化表达式可以依赖计数器、状态、位置与样式,因此放在不同地方,求值结果也会随之改变。[4] 这条规则反过来恰好说明,为什么测量动作会自然地待在 context block 里。[1][4]
这是一个很好的设计选择,因为文档排版原本就不像模板引擎处理 JSON。宽度没有作为某一段源文本天然自带的常量存在,它依赖字体度量、当前样式和页面里的实际落位。Typst 完全可以把这些依赖藏进一层看似便利的魔法里,然后把复杂文档的可预测性一层层吃掉;它没有这么做,转而把依赖关系直接摊开。state 文档又从另一边把同一世界观补齐:持久化文档状态确实存在,只是状态的更新与观察,都要通过参与编译求值过程的上下文化操作来完成。[6] 放回工程语境里,这意味着 Typst 允许你对排版条件作出真实反应,同时又要求你承认一件事:排版本身就是计算。[4][6]
大约在 12:34,locate 把自省能力的力量与边界一起露了出来
演讲最后进入 locate,这里也是整套编译器模型最完整显影的地方。[1] locate 参考页说明,这个函数可以让你拿到元素的位置,由此继续触到页码、坐标和其他与文档落点相关的信息。[7] 单看这一层,它已经很强;再往里一步,更重要的是它为什么必须带着边界一起出现。文档一旦可以反过来问“这个东西现在在哪里”,编译器就常常需要多于一轮的求值,才能把答案收敛稳妥,因为查询版面这件事本身,也会继续影响版面。[1][6][7]
Mädje 在这里带着一点玩笑感去讲,恰好也是理解 Typst 的正确入口。[1] 一套允许自省却没有收敛纪律的文档引擎,会很快变得难以预料。Typst 采取的路径,是把自省能力开放出来,同时把它留在上下文化、可约束的范围里。[4][6][7] 也正因为这样,这场演讲真正讲清的远远超出六个冷门事实,它实际上给出了一种很稳的系统读法。把 Typst 放回“通过样式、位置与页面语境共同决定文档意义的编译器”里,它会明显清楚得多;把它缩回普通文本格式的想象里,很多行为就会反复显得古怪。[1][2][4]
因此,这支视频很适合作为偏技术用户的入口材料。只看产品演示,Typst 容易显得像一套更清爽的写作界面;把这场演讲与官方文档一起看,更深的一条线会慢慢浮出来。规则可以被编程,计数器带着语境,测量要等排版落位成立之后再发生,位置查询之所以有力量,恰恰因为编译器拒绝假装自己拥有单次自上而下的确定性。这个模型一旦站稳,Typst 那些看似奇怪的边缘地带会逐渐失去怪异感,转而显出另一层含义:它们是让文档拥有真实执行模型所要付出的代价。[1][3][4][5][6][7]
来源
- Typst,《Six Things I Bet You Didn't Know About Typst》:Laurenz Mädje 在 Typst meetup 上的 YouTube 演讲(录制于 2024 年 12 月 14 日,发布于 2024 年 12 月 20 日)。
- Typst,《Open source at Typst》:编译器范围、CLI/库模型,以及输出格式。
- Typst Documentation,《Styling》:
setrules、showrules 与内容变换行为。 - Typst Documentation,《Context》:上下文化表达式,以及依赖位置/样式的求值。
- Typst Documentation,《Counter》:上下文化计数器、更新、显示与最终值。
- Typst Documentation,《State》:持久化文档状态与上下文化更新。
- Typst Documentation,《Locate》:元素位置访问与依赖版面位置的自省能力。