Appearance
Typst 入门笔记
最近写课程报告时觉得 LaTeX 的编译速度实在慢的难以忍受,于是粗略体验了一下 Typst,感觉它的设计理念非常现代——把「排版」当成一门编程语言来做。
为什么选择 Typst
| 维度 | LaTeX | Typst |
|---|---|---|
| 编译速度 | 慢(大型文档几十秒) | 快(增量编译,毫秒级) |
| 错误提示 | 宏展开后的 cryptic error | 清晰的源码级报错,带行号 |
| 包管理 | 靠系统包管理器或手动下载 | 内置包管理器,类似 Cargo/NPM |
| 脚本能力 | 宏编程,学习曲线陡峭 | 真正的脚本语言(类 Rust 语法) |
| 实时预览 | 需外部工具(如 Overleaf) | 自带 typst watch,原生支持 |
| 生态系统 | 极其丰富 | 较新,但核心场景已覆盖 |
安装与使用
说到这里不得不吐槽 Latex 的安装实在是太麻烦了一些,1~2G 的安装包,搭配上经常出现的网络问题,对尤其是新手用户相当不友好。
好在这些在 Typst 里面都被妥善解决了,Typst 非常轻量,你甚至只需要安装一个 VSCode 插件就能使用。

当然你也可以选择获取他的二进制文件或在官网提供的 Typst Playground 使用。Typst 支持实时预览,其渲染速度和 Markdown 不相上下,在 Latex 惯用者看来这种体验不亚于古人第一次接触现代科技。
语法模式
Typst 有三种语法模式:Markup、math 和 code。Markup 模式是 Typst 文档的默认模式,math 模式用于编写数学公式,code 模式用于使用 Typst 的脚本功能。
你可以在任何时候通过参考下表切换到特定模式:
| 模式 | 语法 | 示例 |
|---|---|---|
| Code | 以 # 开头 | 数字:#(1 + 2) |
| Math | 用 $..$ | 包裹公式 $-x$ 是 $x$ 的相反数 |
| Markup | 用 [..] | 包裹标记 let name = [*Typst!*] |
一旦你使用 # 进入 code 模式,除非在中间切换回 markup 或 math 模式,否则不需要再使用其他 #。
基本语法
Typst 的标记语法非常直观,和 Markdown 有几分相似:
typ
= 一级标题
== 二级标题
=== 三级标题
这是普通段落,*粗体*、_斜体_、`行内代码` 都很自然。
- 无序列表项
- 另一项
+ 有序列表项
+ 另一项
#figure(
image("diagram.png", width: 80%),
caption: [一个示例图],
)进阶语法
标签与引用
Typst 的标签(label)和引用系统比 LaTeX 更直观:
typ
= 第一章 <ch1-intro>
见第一章 @ch1-intro,或者第 @ch1-intro 页。
#set heading(numbering: "1.1")
= 引言 <intro>
== 背景 <intro-bg>
在 @intro-bg 中我们讨论了相关工作。引用自动带上当前「上下文标题」作为前缀,无需手动维护编号。
图表与浮动体
typ
#figure(
table(
columns: 3,
table.header([Method], [Accuracy], [Time]),
[SGD], [0.82], [1.2s],
[Adam], [0.91], [2.1s],
[AdamW], [0.93], [2.3s],
),
caption: [优化器对比实验结果],
supplement: [表],
)
// supplement 指定浮动体前缀文字(表/图/代码块等)#figure 生成的是「浮动体」,可以指定 placement 控制位置:
typ
#figure(..., placement: auto) // 默认:当前位置或页顶
#figure(..., placement: top) // 强制放在页面顶部
#figure(..., placement: bottom) // 强制放在页面底部
#figure(..., placement: float) // LaTeX 风格的完全浮动脚注
typ
这是正文。#footnote[这是脚注内容。]
脚注会自动编号,上标标记点击可跳转。参考文献
Typst 使用 BibTeX 格式的 .bib 文件,配合 #bibliography() 渲染:
typ
#set text(lang: "zh")
#bibliography("refs.bib", style: "gb-7714-2015")在正文中引用:
typ
Transformer 的提出革新了自然语言处理领域 @vaswani2017attention。布局命令
页面整体布局设置:
typ
#set page(
paper: "a4",
margin: 2.5cm,
header: [My Document],
footer: [Page #counter(page).of()],
)
#set text(lang: "zh", size: 12pt, font: ("Source Han Sans", "Noto Sans"))
#set par(justify: true, first-line-indent: 2em)
= 章节标题
首段不缩进,正文两端对齐,这是中文学术写作的常见格式。多栏布局
typ
#set page(columns: 2, gutter: 1.5em)
= 导论
这里是第一栏的内容。Typst 会自动把内容排入多栏,
直到显式换栏或新页面。
#colbreak()
这里是第二栏的内容。条件与循环
Typst 的脚本语言支持完整的条件与循环:
typ
#let scores = (85, 92, 78, 96, 88)
#for (i, s) in scores.enumerate() {
if s >= 90 {
text("[优] ", weight: "bold", fill: red)
} else if s >= 80 {
text("[良] ", weight: "medium", fill: orange)
} else {
text("[及] ", fill: gray)
}
[学生 #i: #s 分]
}自定义函数
把常用模式封装成可复用函数:
typ
#let info-box(title, body) = {
block(
fill: rgb("#f0f0f0"),
inset: (x: 12pt, y: 8pt),
radius: 6pt,
width: 100%,
)[
#text(weight: "bold")[#title]
#body
]
}
#info-box("注意", [请在提交前仔细检查所有引用。])样式层 #show 规则
#show 可以对特定元素批量应用样式,类似 CSS 的选择器:
typ
// 所有引用链接设为蓝色
#show link: it => text(fill: blue, it)
// 所有一级标题改为居中
#show heading.where(level: 1): it => {
align(center, strong(it))
}
// 特定标签应用特殊样式
#show <warning>: it => {
block(
stroke: (left: 4pt + red),
left-edge: 0pt,
inset: (left: 12pt),
it,
)
}这相当于 Typst 的「伪类选择器」,比 LaTeX 的 \renewcommand 直观得多。
颜色与绘图
Typst 内置向量绘图能力,无需额外工具:
typ
#import "draw@vector*: vector"
#context {
let w = 100pt
let h = 60pt
let arrow = (start: (0pt, 0pt), end: (w, h), stroke: 2pt)
vector.draw(
arrow,
vector-arrow(start: (w, 0pt), end: (0pt, h)),
)
}颜色可以直接用 RGB、CMYK 或命名色:
typ
#rect(fill: rgb("#3B82F6"), width: 2cm)
#rect(fill: cyan, width: 2cm)
#rect(fill: cmyk(0.5, 0, 0, 0), width: 2cm)数学公式
Typst 的数学模式同样用 $ 包裹,但语法做了大量简化:
| 含义 | LaTeX | Typst |
|---|---|---|
| 行内公式 | $x^2$ | $x^2$ |
| 行间公式 | $$\sum_{i=1}^n i$$ | $ sum_(i=1)^n i $ |
| 分数 | \frac{a}{b} | $a / b$ 或 $(a b) / c$ |
| 根号 | \sqrt{x} | $sqrt(x)$ |
| 积分 | \int_0^1 x \,dx | $integral_0^1 x dif x$ |
| 极限 | \lim_{x \to 0} | $lim_(x -> 0)$ |
| 矩阵 | \begin{pmatrix}...\end{pmatrix} | $mat(1, 2; 3, 4)$ |
| 多行对齐 | align* 环境 | 直接写多行,用 & 对齐 |
Typst 的公式语法有几个显著特点:
- 空格敏感:
$x^2$与$ x^2 $的区别在于,后者两侧有空格时表示「显示模式」(display math),类似 LaTeX 的$$...$$。 - 函数式调用:
sqrt(x)、mat(...)等采用统一的函数语法。 - 变量处理:单独的字母被视为变量如
a、b、c;多字符则被视为函数或其他符号,如alpha被解析为 ;如果你想使用多字符作为变量名可以使用引号包裹,如"signal"。 - 隐式乘法:
2x会被正确解析为 ,不需要写成2*x。
一个更复杂的例子:
typ
$f(a,b) = integral_0^1 (a x^2 + b) dif x
= a / 3 + b.$编译后得到一个居中的行间公式,等号处的自动对齐非常优雅。
脚本与自动化
Typst 内嵌了一套完整的脚本语言,这让动态生成内容变得异常简单。例如,自动计算表格行的平均值:
typ
#let data = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
#table(
columns: 4,
table.header([A], [B], [C], [Avg]),
..data.map(row => {
let avg = row.sum() / row.len()
row.map(str).concat((str(avg),))
}).flatten()
)这种程度的脚本能力在 LaTeX 里需要借助 pgfplotstable 或外部 Python 脚本才能实现,而在 Typst 中是原生支持。
一个完整的最小示例
typ
#set page(margin: 2.5cm)
#set text(font: "Linux Libertine", size: 12pt)
#set heading(numbering: "1.1")
= 引言
本文档由 Typst 生成。
= 方法
我们考虑如下优化问题:
$ min_x f(x) quad "s.t." quad g(x) <= 0. $
= 结论
确实挺不错的。
#bibliography("refs.bib")仅十几行就完成了一篇带编号标题、数学公式和参考文献的小型论文框架。
不足
目前 Typst 仍是一个较为年轻的项目,还是不如 Latex 成熟和完整。语法快速迭代,稳定性可能相对不足,社区与生态也尚在建立之中。另外,体验下来我个人觉得对中文的支持还有待提高,有些英文和中文的书写习惯上的差异未完全解决。
总结
总体来说,Typst 虽然好用但目前尚不够完整。我认为它目前的定位是处于 Latex 与 Word 之间的一个东西:比起 Latex 更加轻量易用,比 Word 排版更加稳定。
如果你和我一样,用来写课程报告、技术文档或简历,一方面不想被 Word 的排版折磨,另一方面又觉得使用 Latex 有些「割鸡焉用牛刀」,那么 Typst 确实值得一试。但如果你是要投稿期刊论文,现阶段可能许多期刊不会提供 Typst 模板和相关支持,还是建议选择 Latex 作为工具。
不过我仍然非常欣赏这门新兴的排版语言,简单高效且好玩,希望它能够快速发展到完全替代 Latex 的地步。