首页
/ Typst 完全指南:从标记排版语言、CLI 实战到增量编译设计原理

Typst 完全指南:从标记排版语言、CLI 实战到增量编译设计原理

2026-09-05 23:25:00作者:牧宁李

本文基于 Typst 官方仓库的 README 及其配套源码展开,系统讲解 Typst 作为标记式排版系统的核心特性、一个可运行的完整文档示例、五种安装途径、typst 命令行的常用子命令与关键参数,以及"简单、可组合、增量"三大设计原则在编译器架构中的落地方式。读完后你将能够独立完成 Typst 文档的编译、监听与字体配置,并理解其快速编译速度背后的增量编译机制。

一、Typst 是什么:定位与核心特性

Typst 是一个全新的标记式(markup-based)排版系统,其设计目标是达到 LaTeX 级别的排版能力,同时大幅降低学习与使用门槛。根据仓库 README 的官方描述,它具备以下六大特性:

  • 为最常见的排版任务提供内置标记语法;
  • 其余功能通过灵活的函数系统覆盖;
  • 与排版深度集成的脚本系统;
  • 数学公式排版、参考文献(bibliography)管理等能力;
  • 得益于增量编译(incremental compilation)而实现的快速编译;
  • 出错时提供友好、可读性强的错误信息。

需要说明的是,本仓库包含的是 Typst 编译器及其 CLI,也就是在本地编译 Typst 文档所需的一切。从 Cargo.toml 的 workspace 定义可以看到,这是一个由十余个 Rust crate 组成的工作区,当前版本为 0.15.1,要求 Rust 工具链版本不低于 1.92rust-version = "1.92"),默认构建目标 default-members 指向 crates/typst-cli,即命令行工具。

docs/dev/architecture.md 的目录说明与仓库实际结构可以印证各 crate 的职责划分:

Crate 职责
crates/typst 主编译器 crate,定义完整语言与库
crates/typst-cli 命令行界面,编译器与导出器之上的薄层
crates/typst-eval Typst 语言的解释器
crates/typst-syntax 解析器与语法树定义
crates/typst-layout 排版(布局)引擎
crates/typst-library 标准库
crates/typst-realize 实现(realization)子系统
crates/typst-pdf / typst-svg / typst-html / typst-render PDF、SVG、HTML 导出器与像素渲染器
crates/typst-ide IDE 功能(补全、跳转等)
crates/typst-kit / typst-macros / typst-utils / typst-timing 默认实现、过程宏、工具与性能计时

此外,根目录下的 docs/ 用于从 Typst 文件与 Rust 内联文档生成官方文档内容,tests/ 是覆盖解析、求值、排版与渲染的集成测试套件,tools/ 是开发工具。

二、一个例子看懂 Typst:Fibonacci 序列文档

README 用一个"一张图浓缩全部能力"的示例展示了 Typst 的完整面貌。该示例定义了页面大小与标题编号、写入标题、嵌入两个数学公式,并用脚本计算斐波那契数列前 8 项、以居中对齐的表格展示。完整代码如下:

#set page(width: 10cm, height: auto)
#set heading(numbering: "1.")

= Fibonacci sequence
The Fibonacci sequence is defined through the
recurrence relation $F_n = F_(n-1) + F_(n-2)$.
It can also be expressed in _closed form:_

$ F_n = round(1 / sqrt(5) phi.alt^n), quad
  phi.alt = (1 + sqrt(5)) / 2 $

#let count = 8
#let nums = range(1, count + 1)
#let fib(n) = (
  if n <= 2 { 1 }
  else { fib(n - 1) + fib(n - 2) }
)

The first #count numbers of the sequence are:

#align(center, table(
  columns: count,
  ..nums.map(n => $F_#n$),
  ..nums.map(n => str(fib(n))),
))

这个短文档恰好覆盖了 Typst 的四个核心机制,逐一拆解:

1. 配置元素属性用 set rules(set 规则)。 前两行 #set page(width: 10cm, height: auto)#set heading(numbering: "1.") 分别把页面宽度设为 10cm、高度设为 auto(页面高度随内容自适应伸缩),并为标题启用 "1." 形式的编号。set 规则覆盖了绝大多数常见配置需求;若需要完全掌控某个元素的外观,还可以使用 show rules 重新定义元素的渲染方式。

2. 标题与轻量标记语法。 = Heading 中的单个等号创建顶级标题,两个等号创建子标题,依此类推。Typst 还有更多类似的轻量标记语法(如 _closed form:_ 表示强调、#let 定义变量等),构成了一套与函数调用等价的"语法糖"。

3. 数学公式排版。 公式包裹在美元符号内。公式内容前后各加一个空格(如 $ F_n = ... $)会把公式放入独立的块级区域。两个值得注意的设计:

  • 多字母标识符(如 floorsqrt)会被直接解释为 Typst 的定义与函数,无需 LaTeX 式的反斜杠命令;若希望按普通文本处理则加引号。
  • phi.alt 是对 phi 符号应用 alt 修饰符(modifier),用于选取特定的符号变体。

4. 脚本系统。# 开头即可在文档中嵌入代码表达式。示例中定义了两个变量 countnums 和一个递归函数 fib(n) 计算第 n 个斐波那契数,然后通过 #align(center, table(...)) 将结果展示在居中对齐的表格里。table 函数按行接收单元格:先传入公式 $F_1$$F_8$,再传入计算出的斐波那契数。由于两者都是数组,table 参数前使用了展开运算符(spreading operator)..,把数组的每一项作为独立参数传入。

三、安装:五种途径

Typst 的 CLI 可从多种来源获取(以下命令以当前仓库 README 为准):

1. 官方发布页的预构建二进制。 从发布页下载对应平台的压缩包,将其放入 PATH 中的目录即可。之后可通过 typst update 保持版本更新。

2. 各平台包管理器。 注意包管理器中的版本可能落后于最新发布。

  • Linux:可通过 Repology 查询各发行版软件源中的 Typst,或使用 Snap 包;
  • macOS:brew install typst
  • Windows:winget install --id Typst.Typst

3. Rust 工具链安装(从源码构建安装)。 若已安装 Rust 工具链:

# 安装最新已发布版本
cargo install --locked typst-cli

# 安装开发版本
cargo install --git https://github.com/typst/typst --locked typst-cli

4. Nix。

# 使用 typst 包
nix-shell -p typst

# 构建并运行 Typst flake
nix run github:typst/typst-flake -- --version

5. Docker 预构建镜像。

docker run ghcr.io/typst/typst:latest --help

四、CLI 实战:compile、watch、fonts 与更多

安装完成后,README 给出的基础用法如下:

# 在当前工作目录生成 file.pdf
typst compile file.typ

# 在指定路径生成 PDF
typst compile path/to/source.typ path/to/output.pdf

4.1 监听模式:typst watch

# 监听源文件变化并自动重新编译
typst watch file.typ

监听模式的价值在于:每次修改后的重编译比从头编译更快,因为 Typst 具备增量编译(原理见第六节)。值得注意的是,watch 命令复用了与 compile 完全相同的 CompileArgs 参数结构(见 crates/typst-cli/src/args.rsWatchCommandCompileArgsflatten 引入),因此 compile 的所有选项在 watch 下同样有效。

4.2 自定义字体路径:--font-path 与 TYPST_FONT_PATHS

# 添加额外的字体搜索目录
typst compile --font-path path/to/fonts file.typ

# 列出系统中及指定目录中发现的所有字体
typst fonts --font-path path/to/fonts

# 或者通过环境变量(Linux 语法)
TYPST_FONT_PATHS=path/to/fonts typst fonts

这一行为在源码中有直接对应。crates/typst-cli/src/args.rs 中定义了 FontArgs 结构体:

  • --font-path(对应环境变量 TYPST_FONT_PATHS):追加若干被递归搜索的字体目录;多个路径用系统路径分隔符连接——Unix 系用 :、Windows 用 ;(源码中以 ENV_PATH_SEP 常量根据平台选择);
  • --ignore-system-fonts(环境变量 TYPST_IGNORE_SYSTEM_FONTS):确保不搜索系统字体,除非被显式通过 --font-path 包含;
  • --ignore-embedded-fonts(环境变量 TYPST_IGNORE_EMBEDDED_FONTS):忽略嵌入 Typst 的字体。

typst fonts 命令还有一个 --variants 选项,可额外列出每个字体家族的风格变体。

4.3 查看帮助与其他子命令

# 打印可用子命令与选项
typst help

# 打印某个子命令的详细用法
typst help watch

除 README 列出的命令外,从 args.rsCommand 枚举的完整定义可以确认 CLI 的全部子命令集合(compile 别名 cwatch 别名 w):

  • typst compile:把输入文件编译为受支持的输出格式;输出格式默认按扩展名推断,也支持 PDF、PNG、SVG、HTML。多页文档导出 PNG/SVG 时,输出路径需包含页码模板(如 page-{0p}-of-{t}.png);
  • typst watch:监听输入文件并在变化时重新编译,且 compile 的输出参数(如 --format--pages--pretty)在此同样适用;
  • typst init:从模板初始化新项目,模板可写成 @preview/charged-ieee 这样的包引用并追加 :0.1.0 指定版本;
  • typst eval:求值一段 Typst 代码,可选 --in 在某个文档的上下文中求值(用于检查文档);
  • typst fonts:列出系统字体路径与自定义字体路径中发现的字体;
  • typst update:用预构建二进制自更新 CLI,支持 --revert 回滚到上次更新前的版本(需要之前的备份文件)与 --force 允许降级;
  • typst completions:为 shell 生成补全脚本;
  • typst info:显示 Typst 使用的环境变量与默认值等调试信息。

输入端支持 - 表示从标准输入读取,输出端支持 - 表示写入标准输出;全局层面还有 --color 控制彩色输出(默认 auto)、--cert(环境变量 TYPST_CERT)指定自定义 CA 证书。

若偏好带自动补全与即时预览的 IDE 式体验,可使用官方的免费在线编辑器,或使用社区创建的 Tinymist 语言服务器(已集成到多种编辑器扩展中)。

4.4 从源码构建 Typst

README 给出的自构建流程:

git clone https://github.com/typst/typst
cd typst
cargo build --release

优化后的二进制将存放在 target/release/ 目录中。适用前提来自 Cargo.toml:需要"最新的稳定版 Rust"(当前 workspace 声明最低版本 1.92)。release profile 启用了 lto = "thin"codegen-units = 1 以获得优化产物,并对 typst-cli 做了 strip = true。若对构建产物有疑问,可运行 typst info 查看构建信息与默认值。

五、设计原则:简单、可组合、增量

README 明确阐述了 Typst 的全部设计围绕三个目标展开:Power(能力)、Simplicity(简单)、Performance(性能)——一个能力匹配 LaTeX、易于学习使用、且快到足以实现即时预览的系统。对应三条核心设计原则:

1. 以一致性实现简单(Simplicity through Consistency)。 如果在 Typst 中会做一件事,就应该能把这种知识迁移到其他事情上。若存在完成同一任务的多种方式,其中一种应当是另一种在不同抽象层级的封装。例如 = Introduction#heading[Introduction] 做的是同一件事,前者只是后者的语法糖。

2. 以可组合性实现能力(Power through Composability)。 让系统灵活有两条路:为一切提供"旋钮",或提供少量可以互相组合的旋钮。Typst 走的是第二条路——提供可被以连开发者都未曾设想的方式组合的系统。TeX 同属第二类但过于底层,所以人们转而使用 LaTeX,而 LaTeX 的可组合性其实有限,更多靠"什么功能都有一个包"(\usepackage{knob})来堆叠。

3. 以增量性实现性能(Performance through Incrementality)。 Typst 的所有语言特性都必须兼容增量编译。这依赖 comemo 这一专为 Typst 编写的增量编译框架(workspace 中锁定 comemo = "0.5.1"),它把大部分繁重工作放到幕后完成。

六、增量编译如何落地:四阶段编译管线

docs/dev/architecture.md 给出了编译器架构的权威描述,可作为上面第三条原则的具体展开。Typst 文件从源码到 PDF 的编译过程分为四个阶段:

  1. Parsing(解析):把源字符串变为语法树,位于 crates/typst-syntax。解析是纯函数 &str -> SyntaxNode,永不失败,语法错误以错误节点形式保留在树中——这让同一套解析器可同时服务于编译与 IDE 的高亮/分析。解析后的语法树带有 span 编号,用于把后续阶段的错误回溯到具体语法;Typst 还具备增量解析器,可只重解析被编辑的片段,且尽量保持远离编辑位置的 span 编号稳定,这对作为记忆化函数输入的 span 至关重要。
  2. Evaluation(求值):位于 crates/typst-eval,把解析后的 Source 求值为 Module(文档 Content + 绑定 Scope)。解释器是树遍历(tree-walking)解释器,闭包在定义时捕获外部变量,调用时以新 Vm 求值。系统依赖(导入文件、图像、数据文件)通过统一的 World 接口解析,使同一编译器能部署在 CLI、Web 应用等不同环境。此阶段的增量粒度是"模块 + 闭包调用":源码文件求值结果跨编译记忆化,同一闭包在相同参数下的调用结果也可复用——前提是函数纯度,Typst 在语言层面保证了这一点。
  3. Layout(排版):把 Content 变为每页一个 Frame。排版前先执行 realization(应用所有相关 show 规则,而 show 规则可以是 Typst 闭包,因此会触发新的求值,递归地再 realization)。此阶段存在"内省循环"(introspection loop):页码、计数器等内容可能依赖自身排版结果,布局循环运行直到结果稳定,绝大多数情况一两次迭代即可收敛,最多尝试五次。布局缓存的粒度是元素级,因为布局是代价最高的阶段。
  4. Export(导出):各导出器在独立 crate 中,把布局好的 Frame 转为 PDF、SVG、HTML 或像素缓冲。

"从源码结构看",增量编译的痕迹遍布布局引擎:例如 crates/typst-layout/src/flow/mod.rs 中的布局入口函数标注了 #[comemo::memoize]crates/typst-layout/src/flow/collect.rs 中也有多处 #[comemo::memoize]Tracked/TrackedMut 追踪类型——这正是 architecture.md 所说"大部分脏活由 comemo 完成、编译器代码仍需以增量性为前提书写"的实证。

测试方面,tests/ 目录包含大量集成测试,覆盖解析、求值、realization、布局与渲染各阶段,并按 foundationslayoutmathmodeltext 等模块组织 .typ 用例,配合 tests/README.md 说明运行方式。

七、社区与贡献

Typst 社区的主要聚集地是官方论坛(提问、互助、分享作品的合适场所)与 Discord 服务器(更适合快速问答、贡献讨论与闲聊)。Typst Universe 是社区共享模板与包的场所;若想分享自己的创作,可以向官方包仓库提交。

贡献方面:遇到 bug 可以直接开 issue;实现新特性或修复请遵循 CONTRIBUTING.md 中列出的步骤(本地构建流程见上文 4.4 节)。README 也指出,分享自己编写的包是另一条很好的参与路径。

最后补充两个小事实:Typst 的发音为 IPA /taɪpst/("Ty" 如 Typesetting,"pst" 如 Hipster);在文字中书写时应作为专有名词大写 T。

小结

  • Typst 以"内置标记 + 函数 + 脚本"三层结构覆盖从页面配置到数学公式的排版需求,#set page(width: 10cm, height: auto) 这类 set 规则即可完成大部分配置;
  • CLI 覆盖 compile/watch/fonts/eval/init/update/info 等完整工作流,--font-pathTYPST_FONT_PATHS 解决字体发现问题,- 可作 stdin/stdout;
  • 性能来自贯穿四阶段(解析、求值、排版、导出)的增量编译,框架是 comemo,缓存粒度从模块与闭包调用细化到布局元素;
  • 仓库内 docs/dev/architecture.mdtests/ 目录是进一步深入编译器原理与验证行为的最佳入口。
登录后查看全文
热门项目推荐
相关项目推荐