Typst 完全指南:从标记排版语言、CLI 实战到增量编译设计原理
本文基于 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.92(rust-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 = ... $)会把公式放入独立的块级区域。两个值得注意的设计:
- 多字母标识符(如
floor、sqrt)会被直接解释为 Typst 的定义与函数,无需 LaTeX 式的反斜杠命令;若希望按普通文本处理则加引号。 phi.alt是对phi符号应用alt修饰符(modifier),用于选取特定的符号变体。
4. 脚本系统。
以 # 开头即可在文档中嵌入代码表达式。示例中定义了两个变量 count、nums 和一个递归函数 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.rs 中 WatchCommand 对 CompileArgs 的 flatten 引入),因此 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.rs 中 Command 枚举的完整定义可以确认 CLI 的全部子命令集合(compile 别名 c,watch 别名 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 的编译过程分为四个阶段:
- Parsing(解析):把源字符串变为语法树,位于
crates/typst-syntax。解析是纯函数&str -> SyntaxNode,永不失败,语法错误以错误节点形式保留在树中——这让同一套解析器可同时服务于编译与 IDE 的高亮/分析。解析后的语法树带有 span 编号,用于把后续阶段的错误回溯到具体语法;Typst 还具备增量解析器,可只重解析被编辑的片段,且尽量保持远离编辑位置的 span 编号稳定,这对作为记忆化函数输入的 span 至关重要。 - Evaluation(求值):位于
crates/typst-eval,把解析后的Source求值为Module(文档Content+ 绑定Scope)。解释器是树遍历(tree-walking)解释器,闭包在定义时捕获外部变量,调用时以新Vm求值。系统依赖(导入文件、图像、数据文件)通过统一的World接口解析,使同一编译器能部署在 CLI、Web 应用等不同环境。此阶段的增量粒度是"模块 + 闭包调用":源码文件求值结果跨编译记忆化,同一闭包在相同参数下的调用结果也可复用——前提是函数纯度,Typst 在语言层面保证了这一点。 - Layout(排版):把
Content变为每页一个Frame。排版前先执行 realization(应用所有相关 show 规则,而 show 规则可以是 Typst 闭包,因此会触发新的求值,递归地再 realization)。此阶段存在"内省循环"(introspection loop):页码、计数器等内容可能依赖自身排版结果,布局循环运行直到结果稳定,绝大多数情况一两次迭代即可收敛,最多尝试五次。布局缓存的粒度是元素级,因为布局是代价最高的阶段。 - 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、布局与渲染各阶段,并按 foundations、layout、math、model、text 等模块组织 .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-path与TYPST_FONT_PATHS解决字体发现问题,-可作 stdin/stdout; - 性能来自贯穿四阶段(解析、求值、排版、导出)的增量编译,框架是 comemo,缓存粒度从模块与闭包调用细化到布局元素;
- 仓库内 docs/dev/architecture.md 与
tests/目录是进一步深入编译器原理与验证行为的最佳入口。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00