- name
- typst-writing-conventions
- description
- 当编辑/创建 .typ 文件时,必须使用本技能以确保符合 Typst 语法规范(如 subset→subset.eq, \sigma→sigma, integral→integral 等)、符号映射规则、文档层级结构和写作风格约定。尤其适用于新增数学公式较多的笔记时。
- user_invocable
- false
## 1. 文档结构
### 层级体系
| 语法 | 层级 | 含义 |
|------|------|------|
| `#part("...")` | Part | 大知识模块分组 |
| `= ...` | Chapter(一级标题) | 完整知识单元 |
| `== ...` | Section(二级标题) | 章内主要知识点 |
| `=== ...` | Subsection(三级标题) | 节内细分 |
### 标题规则
- 标题标记 `=` 后必须有空格:`= Title`(正确)vs `=Title`(错误)
- 不要跳级使用标题(如从 `=` 直接到 `===`)
---
## 2. 文本格式
| 效果 | 语法 |
|------|------|
| 加粗 | `*text*` |
| 斜体 | `_text_` |
| 行内代码 | `` `code` `` |
| 脚注 | `#footnote[...]` |
| 垂直间距 | `#v(1cm)` |
| 行内高亮 | `#highlight[text]` |
### 列表
- 无序列表:`- item`
- 有序列表:`1. item` / `2. item`
- 嵌套:使用缩进(Tab 或两空格)
---
## 3. 数学公式
### 基本用法
- 行内公式:`$ ... $`(与文本同行)
- 行间公式(display math):`$ ... $`(单独成段,前后有空行或换行)
### 符号映射(LaTeX → Typst)
| LaTeX | Typst |
|-------|-------|
| `\mathbb{R}` | `bb(R)` |
| `\mathcal{F}` | `cal(F)` |
| `\mathscr{M}` | `scr(M)` |
| `\to`, `\rightarrow` | `->` |
| `\Rightarrow` | `=>` |
| `\Leftrightarrow` | `<=>` |
| `\infty` | `oo` |
| `\subseteq` | `subset` |
| `\cup` | `union` |
| `\cap` | `inter` |
| `\notin` | `in.not` |
| `\neq` | `!=` |
| `\land` | `and` |
| `\lor` | `or` |
| `\lnot` | `not` |
| `\circ`(复合) | `compose` |
| `\preceq` | `prec.eq` |
| `\oplus`(对称差) | `plus.o` |
| `\forall` | `forall` |
| `\exists` | `exists` |
| `\partial` | `partial` |
| `\mathrm{d}x` | `dif x` |
| `\liminf` | `liminf` |
| `\limsup` | `limsup` |
| `\sup` | `sup` |
| `\inf` | `inf` |
| `\overline{X}` | `overline(X)` |
| `\chi_A`(特征函数) | `chi_A` |
| `\backslash` | `backslash` |
| `\int` | `integral` |
| `\iint`, `\iiint` | `integral.double`, `integral.triple` |
| `\oint` | `integral.cont`(闭合环路线积分) |
| `\cdot` | `dot` |
| `\sim` | `~` 或 `approx` |
| `\text{...}` | `text("...")`(**必须用字符串引号**) |
| `\left(`, `\right)` | 无对应命令,Typst 自动缩放括号 |
| `\left[`, `\right]` | 无对应命令,Typst 自动缩放方括号 |
### 硬规则(必须遵守)
1. **不属于符号**:写 `$in.not$`,不要写 `$notin$`
2. **子集**:统一写 `$subset$`
3. **箭头**:`$->$`、`$<=>$`,不保留 LaTeX 宏名
4. **不等于**:`$!=$`(注意空格:`$!= $` 或 `$a != b$`)
5. **函数复合**:`$compose$`
6. **微分符号**:使用正体 `dif x`、`dif t`
7. **导数点记号**:`dot(x)`、`dot.double(x)`、`dot.triple(x)`
8. **积分号**:用 `integral`,不是 `int`。二重/三重:`integral.double`、`integral.triple`
9. **`text()` 必须用字符串参数**:写 `text("something")`,不是 `text(something)`
10. **点乘**:写 `a dot b`,不用 `a cdot b`(`cdot` 不存在)
11. **下标后紧接括号,下标必须用 `{}` 包裹,否则括号会被吞进下标**:写 `mu_(X)(B)`,**绝对禁止** `mu_X(B)`。判定用正则 `_([a-zA-Z])\(` → `_($1)(`(见下方专门小节)。这是全仓库出现频率最高、AI 最易再犯的 Typst 语法错误,每次写完公式必须逐条自查。
12. **`\left(`/`\right)` 不存在**:Typst 自动缩放括号,不需要 `\left`/`\right`
### 常见陷阱
#### 裸下标问题
Typst 不支持 `$_x$`,下标 `_` 前必须有主体。
```typst
// 错误
$_x$
// 正确:空主体下标
$""_x$
```
#### ⚠️⚠️⚠️ 绝对禁止:下标后紧接括号必须用 `{}` 包裹下标(三维基准) ⚠️⚠️⚠️
> 🔴🔴🔴 **这是全仓库最高频、AI 反复再犯、被用户在 Review 中当场抓出的错误。每次写完任何带下标 + 括号的数学公式,必须立刻用正则 `_([a-zA-Z])\(` 自查,不做这一步禁止提交。** 🔴🔴🔴
**任何"下标是一个符号、后面紧跟一个括号作为函数参数"的写法,都必须把下标用 `{}` 裹起来**,否则 Typst 会把整个 `下标+括号+括号内容` 全部归入下标,渲染成叠成小字的错误结果。
#### 单字母下标后接括号(`GL_n(F)` 问题)
**单字母下标后直接跟一个括号时,括号及其中内容会被 Typst 一并归入下标**,而不是作为括号表达式紧跟在右侧:
```typst
// 错误 — 整个 "n(F)" 都被当作下标,渲染成 G L 的下标下标小字
$"GL"_n(F)$ // 实际渲染:GL_{n(F)},且 F 被错误地放进下标
$f_n(A)$ // f_{n(A)},括号 (A) 被吞进下标
$mu_P(x, y)$ // mu_{P(x,y)}
$mu_X(B)$ // mu_{X(B)} —— 本次 Probabilités 实际踩中的坑!
$"Syl"_p(G)$ // Syl_{p(G)}
$C_G(H)$ // C_{G(H)}
// 正确 — 括号作为独立的函数参数贴在右侧
$"GL"_(n)(F)$ // GL_n (F) —— n 是下标,(F) 是独立的参数
$f_(n)(A)$ // f_n (A)
$mu_(P)(x, y)$ // mu_P (x, y)
$mu_(X)(B)$ // mu_X (B) —— X 是下标,(B) 是独立参数
$"Syl"_(p)(G)$ // Syl_p (G)
$C_(G)(H)$ // C_G (H)
```
**判定规则**:只要遇到形如 `_<单个字母>` 且后面紧跟 `(` 的模式(`"GL"_n(F)`、`f_n(A)`、`C_G(H)`、`mu_P(x,y)`、`"Syl"_p(G)`、`N_G(H)`、`phi_g(x)` 等),一律改写为 `_<字母>(` + `)(` 形式,即 `"GL"_(n)(F)`。批量替换时注意两点:
- 括号里的多字母(如 `"GL"_(n)(F)`)用 `{...}` 包裹下标;**真正作为函数参数的括号要写在 `)` 之后**,不与下标粘连;
- 若下标本身是普通变量而非"名字 + 参数",如 $x_i^2$ 或 $n_k$,则无需改动——只处理**下标后紧跟 `(`** 的情形(此时 `(` 是想作为独立参数而非下标)。
**批量排查**:在全仓库 `.typ` 文件中搜索正则 `_([a-zA-Z])\(`,逐个改为 `_($1)(`。这与你之前修的 `f_n(A)` 是同一种错误,务必全局替换,不限于举例处。
#### 多字母变量问题
Typst 将连续字母识别为内置函数名(如 `sin`、`exp`),或把相邻的单字母变量合并为一个未知多字母变量,导致编译错误。
```typst
// 正体多字母变量:用引号包裹
$"ext"$, $"const"$, $"max"$
// 斜体多字母变量:用空格分开
$e x t$
// 示例
$bold(F)_i^("ext")$ // 外力
```
**相邻单字母变量之间必须用空格分隔**,否则整体被识别为一个未知变量(报 `unknown variable: xy` 等):
```typst
// 错误 — 字母连写被合并为单个未知变量
$xy$ // → unknown variable: xy
$2xy$ // → unknown variable: xy
$2 x y z$ 若写成 $2xyz$
// 正确 — 变量与变量之间留空格
$x y$
$2 x y$
```
数字紧跟单个变量(如 `$2x$`)本身合法,但建议统一写成 `$2 x$` 保持风格一致。
**排查指南**:遇到 `unknown variable` 错误时,优先排查两类根因——多字母连写(如 `xy`、`2xy`)与 LaTeX 宏残留(如 `cdot`、`int`、`infty`)。
#### 组件参数中的引号嵌套
组件的 `name:` / `title:` 等字符串参数内部**不能直接嵌套双引号**,否则字符串提前终止,报 `unclosed delimiter` / `expected comma`:
```typst
// 错误 — 内层双引号截断了外层字符串
#note(title: "On the Usage of "Holomorphic" and "Analytic")[...]
// 正确 — 内层改用单引号
#note(title: "On the Usage of 'Holomorphic' and 'Analytic'")[...]
```
#### 组件 name/title 参数中的数学公式
`name:` / `title:` 参数可以传字符串(`"..."`)或 content(`[...]`),两种形式都能正确渲染其中的 `$...$` 数学公式。模板已通过 `eval(name, mode: "markup")` 自动解析字符串中的 markup 语法。
```typst
// 两种写法都正确,数学正常渲染
#definition(name: "$L^p$ Space")[...]
#definition(name: [$L^p$ Space])[...]
// 推荐:字符串形式更简洁
#theorem(name: "Properties of $sin$ and $cos$")[...]
```
**注意**:使用字符串形式时,`$...$` 内的 Typst 数学符号必须正确(如 `!=` 而非 `neq`),否则 `eval` 解析时会报 `unknown variable` 错误。
#### 分数的分子/分母非单因子时必须加括号
`/` 只把紧邻的**单个因子**作为分子和分母。分母(或分子)含多字符结构或运算时必须加括号,否则解析错误。
**绝对值的特殊处理**:使用 `abs()` 函数形式后无需再加外层括号(`abs()` 自身作为一个完整因子)。但若使用 `|...|` 形式则必须加外层括号(见下方「绝对值用 abs(xxx),不用 |xxx|」陷阱):
```typst
// 错误 — 分母只解析出单个因子,多字符结构被截断
$z^5 / |z|^4$ // 分母只取到 "|",剩余 "z|^4" 并排在分数旁
$x + y / 2$ // 实际是 x 加上分数 y/2
// 正确 — abs() 形式(推荐,无需额外括号)
$z^5 / abs(z)^4$
$z / abs(z)$
$x / abs(z)$
$abs(f(z)) / abs(g(z))$
// 正确 — 普通非单因子加括号
$(x + y) / 2$ // 想要 (x+y)/2 必须加括号
$z^5 / (w^4)$ // 含运算的幂次也加括号保险
```
**判定规则**:分子/分母只要不是单个字母或数字(可带上下标,如 `x_i`、`z^2`),就必须加括号。**但 `abs(...)` 作为一个整体函数调用,可以视为单个因子**——这就是统一使用 `abs()` 形式的另一优势。
#### 绝对值用 abs(xxx),不用 |xxx|
Typst 数学模式中的 `|...|` **不会自动调整大小**,且在分式、根号、嵌套结构中容易被解析为独立竖线元素(见上文"分数的分子/分母非单因子时必须加括号"陷阱)。**统一使用函数形式 `abs(xxx)`**,自动缩放并避免歧义:
```typst
// 错误 — |xxx| 不会自动缩放,且容易被误解为单字符
$|z - z_0|$
$|f(z)| / |g(z)|$
$root(n, |a_n|)$
// 正确 — abs() 自动缩放,且作为整体单元参与解析
$abs(z - z_0)$
$abs(f(z)) / abs(g(z))$
$root(n, abs(a_n))$
```
عرض على GitHub