. 写作风格指引

本站的中文写作、文章结构、术语与数学记号,以及 Typst/Typsite 源码约定.

写作风格关乎读者怎样理解一篇文章:先看见问题,得到直觉再沿着定义、例子与论证核对细节. 本站用 Typst 写作,用 Typsite 组织和发布页面; 本文约定中文表达与源码写法,主要面向编程、数学与技术文章. 随笔可以保留个人口吻,不必套用概念条目的结构.

这些约定参考香蕉空间的《风格指引》,并按本站的工具与内容组织方式调整. 基本原则是:直观的解释要易读,精确的陈述要可核对,源码要便于维护. 这不是要求每篇文章都写成论文,也不是用排版代替论证.

1 写给正在学习的人

读者可能第一次接触这个概念,也可能熟悉相邻领域,却不熟悉这里的术语. 开头应交代讨论什么、它解决什么问题,以及读到哪里能找到准确陈述. 不要先堆满缩写、历史与技术条件,再让读者猜主题.

介绍概念时,先给简短的直观解释,再用定义或命题说明它的准确含义. 例如,介绍类型安全,可以先说: “类型规则与运行规则配合,使通过检查的程序不会遇到某类未规定的操作.” 随后必须说明使用哪套规则、“未规定的操作”指什么,以及保证成立的条件. 不能把这个直觉扩写成“通过类型检查的程序绝不会出错”: 逻辑错误、资源耗尽等问题未必在所述定理的范围内.

比喻可以帮助理解,但要指出它对应什么,在哪些地方不再适用. 例子说明某种行为,反例否定某个断言; 除非讨论的情形已经穷尽,若干例子或测试不能代替一般证明.

讲解与个人判断也应分开. “由这些规则可推出……”需要论证; “我更喜欢这种设计……”可以表达偏好,但不能因此声称其他设计错误. 有尚未核实的解释,就保留“可能”“在这个模型下”等必要限定.

2 文章的结构
2.1 引言

引言通常回答三个问题:主题是什么,为什么值得讨论,最简单的例子是什么. 概念文章可以从“在某个领域中,某概念是……”开始, 但不必把所有文章的第一句写成同一模样. 工程文章也可以从具体问题或失败的尝试开始.

主题首次出现在正文中时用粗体. 短概念的引言可以只有一句话;复杂主题则先交代阅读所需的背景, 把不影响理解的旁支留给补充说明或延伸阅读. 引言末尾可以简短指出它与相邻概念的联系.

2.2 定义或陈述

介绍概念的文章通常有“定义”一节;介绍定理时, 可以改成“陈述”或“陈述与证明”. 定义应准确、简洁,解释每个对象、记号、参数及其取值范围. 多个相关子概念可以分小节,不要塞进一个过长的句子.

命题要把假设和结论写全. 例如,“规约是确定的”应说明针对哪套规约规则, 以及“确定”表示下一步唯一,还是最终结果唯一. 不能把这类条件只放在引言里,再要求单独阅读命题的读者自行找回.

2.3 例子、性质与证明

例子从简单或边界情形开始,再到典型、有趣的情形. 数学文章可以先考察空集、零对象或一维情形; 程序语言文章可以先考察常量、单步计算、最小的错误项, 再展示嵌套构造与多步推导.

每个例子都应写清它使用的假设与记号. 即使几个例子采用同一套条件,必要时也应重复说明, 而不是为了少写一句话牺牲清晰度. 性质与命题同样如此.

证明先说明方法,再展开关键步骤. 使用归纳法时,交代归纳对象、归纳假设和覆盖的情形; 使用已有结论时,给出引用,并检查其前提在当前情形下成立. “显然”“容易验证”不能替代读者真正需要的推理.

工程文章可以采用“问题—约束—方案—实现—验证—局限”的顺序. 写清代码的输入、输出、失败行为和运行条件; 性能结论还应交代测量环境与比较对象. 没有做过的实验不要写成已经验证的结果.

2.4 讲解文章与独立条目

本站把可复用的定义、定理、例子及补充说明放在 root/statements/ root/statements/ , 讲解文章通过 statement statement 嵌入,通过 refer refer 引用. 不要为另一篇文章复制一份相同的定义或证明,再让两份内容逐渐分叉. 下面是一份使用现有条目的概念文章骨架:

#import "/lib/lib.typ": *
#import "/lib/statements.typ": statement, refer

#show: schema.with("page")

#title[理解类型判断]
#metacontent("description")[从具体例子理解类型规则怎样描述词项的类型.]
#date[2026-10-14]
#author[Glomzzz]
#parent("/how/index.typ")

在程序语言理论中,*类型判断*描述词项与类型之间的关系.
下面以布尔值与自然数构成的算术语言为例.

= 定义

#statement("definition/types-and-typing-judgments")

= 例子

#statement("example/well-typed-and-ill-typed-terms")

= 性质

#statement("theorem/progress")

根据 #refer("theorem/progress"),在所述规则下,
良类型的项要么已经是值,要么还能规约一步.
#import "/lib/lib.typ": *
#import "/lib/statements.typ": statement, refer

#show: schema.with("page")

#title[理解类型判断]
#metacontent("description")[从具体例子理解类型规则怎样描述词项的类型.]
#date[2026-10-14]
#author[Glomzzz]
#parent("/how/index.typ")

在程序语言理论中,*类型判断*描述词项与类型之间的关系.
下面以布尔值与自然数构成的算术语言为例.

= 定义

#statement("definition/types-and-typing-judgments")

= 例子

#statement("example/well-typed-and-ill-typed-terms")

= 性质

#statement("theorem/progress")

根据 #refer("theorem/progress"),在所述规则下,
良类型的项要么已经是值,要么还能规约一步.

独立条目应当能从自己的网址开始阅读. 不使用指向原讲解文章的“上文”“下一节”“这门语言”等含混指代; 需要哪个定义或哪套规则,就明确引用它. parent parent 只提供返回页面的关系,不能代替正文中的依赖说明.

条目的单文件结构、分类与命名详见仓库中的 root/statements/README.md root/statements/README.md ; 实际用法也可参见 形式化入门 .

3 中文表达与排版
3.1 简洁、精确、自然

少用没有作用的量词和被动句,避免逐字搬运外文句式. 例如:

  • 写“设 𝑌 是集合 𝑋 的子集”,不写“设 𝑌 是一个集合 𝑋 的子集”.
  • 写“此时称 𝑋 为光滑流形”,不写“此时 𝑋 被称为光滑流形”.
  • 写“该映射定义为……”,通常不必写“该映射被定义为……”.
  • 写“域是带有加减乘除四则运算的集合, 这些运算满足实数、有理数的四则运算那样的性质”, 比反复使用“一个……是一个……其上……”更自然.

这不是禁用“一”“被”或长句. 需要强调数量、施事者不明,或必须保留原文语气时,可以照常使用. 删改句子时尤其要保留否定、范围、条件与确定程度: “可能减少开销”不能润色成“减少开销”.

一个段落尽量围绕一个问题. 列举并列内容时用列表,表达推理关系时用连贯的句子; 不要把所有论证拆成口号,也不要反复预告“接下来我们将深入探讨”.

3.2 标点、空格与强调

中文正文使用全角标点 ,.;:?! ,.;:?! :句号统一用全角西文句点 . . ,不用空心句号 。 。 . 并列的词语或公式之间用顿号,例如“定义、例子与性质”、 “设 𝑎、𝑏、𝑐 是复数”. 引号用“”,嵌套时内层用‘’;书名用《》. 代码、网址和公式内部保留各自语法需要的半角标点.

中文与拉丁字母、数字之间通常留一个半角空格, 例如“用 Typst 写作”“共有 3 个分支”. 中文标点前后不额外加空格;行内公式不要靠连续空格调整位置.

强调中文用粗体,不用斜体. 粗体应帮助读者定位术语或关键条件,而不是给整段文字染上重点.

*粗体强调*,不要写成 Markdown 的双星号形式.
_斜体_适合确实需要斜体的外文,不用于强调中文.

变量写成 $x$,函数名写成 `type_of`.
代码中的关键字可以写成 `if`,公式中的关键字可以写成 $"if"$.
*粗体强调*,不要写成 Markdown 的双星号形式.
_斜体_适合确实需要斜体的外文,不用于强调中文.

变量写成 $x$,函数名写成 `type_of`.
代码中的关键字可以写成 `if`,公式中的关键字可以写成 $"if"$.

数学对象用数学模式,代码标识符用行内代码. 不要把数学变量写成代码,也不要用数学斜体拼出程序中的多字母函数名.

4 术语与名称
4.1 选取与统一

所有术语优先遵循香蕉空间的译名, 并在 术语对照 内标注英文与中文译名. 已有通用中文术语时,采用通用术语. 没有稳定译名时,优先考虑准确、易懂、符合汉语习惯的译法; 拿不准就先讨论,不要只为避开外文而创造难懂的新词. 同一概念在本站应尽量使用同一译名,以介绍它的条目为准. 本站将 effect 统一译作“作用”,algebraic effect 译作“代数作用”, 派生术语也统一使用“作用”.

尽量写完整术语. 例如,跨领域的文章应写“代数曲线”,而不是让读者猜“曲线”指哪一种. 某术语在一句话或一段话中反复出现,且不会引起歧义时,可以适当简称. 有意采用不同译名时,应解释对应关系与选择理由.

正文以中文术语为主,不用外文缩写代替已经清楚的中文名称. 行文时不要突然在术语后插入括号标英文; 除了在 术语对照 集中收录英文与中文译名外, 单篇文章也可将外文对照放在“术语对照”或“延伸阅读”一节, 直接使用 Typst 的描述列表:

= 术语对照

/ 类型判断: typing judgment
/ 结构归纳法: structural induction
/ 小步操作语义: small-step operational semantics
= 术语对照

/ 类型判断: typing judgment
/ 结构归纳法: structural induction
/ 小步操作语义: small-step operational semantics

编程文章还需要保留读者检索文档、运行代码时使用的名字. Typst、Typsite、API 名称、命令、包名与代码标识符不强行翻译. 必要的缩写在首次使用时解释,后续不要在中文名称与多种简称之间随意切换.

4.2 人名、连接号与连字符

数学术语中的中文人名写成汉字;其他人名采用通用的拉丁字母拼写, 保留原有的变音符号与扩充字母,例如 Poincaré 群、Gauß 绝妙定理. 非拉丁文字的人名采用通用的拉丁字母转写; 国名、地名仍使用通用中文译名. 外文形容词式的人名后缀通常还原为人名, 例如 Abel 群、Riemann 几何.

连接两个人名用连接号“–”,例如陈–Weil 理论; 一个人名或单词内部用连字符“-”,例如 Levi-Civita 联络. 这些符号与中文破折号“——”用途不同,不要混用.

术语后半部分是完整术语、前半部分是补充条件时,通常加连字符, 例如 𝑅-模、𝑛-范畴、𝜎-有限. 同位关系不用连字符,例如 𝜁 函数; “𝑛 维空间”“𝑝 进数”也不用. 不要机械复制英文术语中的每个连字符.

4.3 书名与文献

外文书首次出现时给出原语言书名,再给中文译名; 再次出现时可以只用中文书名. 引用书籍、论文或技术文档时,尽量给出作者、标题和稳定链接; 讨论具体结论时补充章节、命题编号或版本. 转述与直接引语应区分,自己的译文也应注明.

5 数学记号

优先使用通用记号. 不常见的记号在每一节首次使用时解释,同一对象尽量保留同一种主要记号. 不能因为读者可以点开链接,就省略当前推导所需的变量范围与假设. 有领域惯例或必须区分的语义时,应说明例外,不能为了统一字形改变含义.

  • 映射与集合. 映射冒号应具有关系符号的间距; 集合的条件分隔符用竖线,不用冒号. 空集写作 ∅.

    $f class("relation", colon) X -> Y$
    ${ x in RR mid(|) x > 0 }$
    $emptyset$
    $f class("relation", colon) X -> Y$
    ${ x in RR mid(|) x > 0 }$
    $emptyset$
  • 希腊字母与常数. 采用 𝜀、𝜑 这两种字形, 对应 Typst 的 epsilon epsilon 、 phi phi ,不要随意切换为 .alt .alt 变体. 数学常数 e、 i 用正体, 变量 𝑒、𝑖 则仍按变量排版. 微分中的 𝑑 用斜体; Typst 的 dif dif 默认用正体,不能不加说明地视为同一写法.

    $epsilon, phi$
    $upright(e), upright(i)$
    $d x$
    $epsilon, phi$
    $upright(e), upright(i)$
    $d x$
  • 包含与同构. 用 subset subset 表示允许相等的包含, 用 subset.neq subset.neq 明确表示真包含,并在首次使用时说明. 若当前领域用 subset.eq subset.eq 表示允许相等的包含,则明确约定并保持一致. 同构一般写作 𝑋≃𝑌,但要说明是哪类对象之间的同构.

    $A subset X$
    $A subset.neq X$
    $X tilde.eq Y$
    $A subset X$
    $A subset.neq X$
    $X tilde.eq Y$
  • 区间与序列. 开区间可采用反向方括号; Typst 中使用转义与 lr lr 配对,不照搬 LaTeX 的括号命令. 一族对象要给出指标范围,不只写孤立的 𝑎 𝑛.

    $lr(\]a, b\[)$
    $(a_n)_(n >= 0)$
    $(X_i)_(i in I)$
    $lr(\]a, b\[)$
    $(a_n)_(n >= 0)$
    $(X_i)_(i in I)$
  • 算子与字体. 算子名用 op op ,而不是只把字母改成正体. 具体范畴一般用无衬线字体,一般范畴用花体; 线性群名、导出函子及来自单词的上下标用正体, 对称群、交错群可用哥特体.

    $op("coker") f$
    $sans("Set"), A "-" sans("Mod"), cal(C)$
    $upright("U")(n), upright("GL")_n, upright("R") f_*$
    $bb(G)_upright("m"), H^upright("BM")$
    $frak(S)_n, frak(A)_n$
    $op("coker") f$
    $sans("Set"), A "-" sans("Mod"), cal(C)$
    $upright("U")(n), upright("GL")_n, upright("R") f_*$
    $bb(G)_upright("m"), H^upright("BM")$
    $frak(S)_n, frak(A)_n$

行内公式尽量紧凑,避免高大的分式影响行距. 注意,Typst 的 a / b a / b 会生成上下堆叠的分式; 若要写成斜线形式,应写 $a slash b$ $a slash b$ ,而不是照抄 LaTeX 的源码习惯. 独立展示的公式可以使用 frac(a, b) frac(a, b) 或 a / b a / b .

行内映射通常用短箭头 -> -> ,行间映射可用 arrow.r.long arrow.r.long . 规约、蕴涵、等价等箭头各有含义,应先确定语义, 再决定字形与长度,不能把所有箭头统一替换.

6 Typst 与 Typsite 源码
6.1 页面入口与元数据

本站的内容根目录是 root/ root/ . 仓库文件 root/how/style.typ root/how/style.typ 在 Typsite 中的页面路径是 /how/style.typ /how/style.typ ; 导入 "/lib/lib.typ" "/lib/lib.typ" 也从内容根目录解析,不是操作系统的根目录. 正文中的页面引用使用源码路径,由 Typsite 处理最终网址, 不要把部署后的 .html .html 路径散写在源码中.

普通文章导入共享库,并用 #show: schema.with("page") #show: schema.with("page") 应用本站页面模板. title title 设置文章标题;标题含复杂公式或代码时, 用 page-title page-title 补充适合浏览器标签页的纯文字标题. description description 简短说明内容, date date 与 author author 如实填写, parent parent 指向适当的上级页面.

这些是本站共享库与 Typsite 的接口,不是 Typst 内置的文档元数据语法. 正文的小节使用 = = 、 == == 、 === === ,不要为重复页面标题再加一个正文标题.

6.2 链接、嵌入与注脚
  • 外部资源用 link link ,链接文字写资源名称,不只写“这里”.
  • 站内文章用共享库的 cite cite ;标题交给目标元数据维护时,可以用 cite-title cite-title .
  • 普通页面内容用 embed embed 复用;定义、命题等独立条目用 statement statement 与 refer refer .
  • 当前页面内的目标用有意义且唯一的标签,避免手工写容易变动的章节编号.
  • 不影响主线的出处或补充可以放进 footnote footnote ,关键假设不能藏进注脚.
#link("https://typst.app/docs/")[Typst 官方文档]
#cite("/how/plt/formal/index.typ")[形式化入门]
#cite-title("/how/plt/formal/index.typ")

= 记号约定 <notation-conventions>

记号的含义见 #link(<notation-conventions>)[记号约定].
一段补充说明.#footnote[这里给出出处或不影响主线的细节.]
#link("https://typst.app/docs/")[Typst 官方文档]
#cite("/how/plt/formal/index.typ")[形式化入门]
#cite-title("/how/plt/formal/index.typ")

= 记号约定 <notation-conventions>

记号的含义见 #link(<notation-conventions>)[记号约定].
一段补充说明.#footnote[这里给出出处或不影响主线的细节.]

嵌入目标仍是一篇独立页面,不应依赖父文章刚刚定义的局部变量或叙述位置. 引用显示文字也不要写死成“定理 2.1”: 同一条目在不同父页面中的编号可能不同.

6.3 可读的源码

源码同样是给人读的. 正文在标点或语义边界换行,每行尽量不超过 80 个字符; 长网址、代码字符串等不适合拆开时可以例外. 段落之间留空行;段内的普通换行不表示另起一段, 不要为编辑器中的视觉折行插入强制换行.

公式的运算符两侧适当留空格,例如 1 + 1 = 2 1 + 1 = 2 、 f(x, y) f(x, y) . 块级公式的起止 $ $ 各占一行,长表达式按结构展开; 函数参数和代码块使用 2 个空格缩进. 例如,下面的写法比把矩阵挤进一行更便于检查:

$
A = mat(
  a_11, a_12;
  a_21, a_22
)
$
$
A = mat(
  a_11, a_12;
  a_21, a_22
)
$

Typst 数学模式中的单个字母直接表示数学字母, 多字母名字通常作为变量或函数解析. 需要原样显示多个字母时用引号,如 $"Bool"$ $"Bool"$ ; 需要算子语义时则用 op("size") op("size") . 不要用零散的空格或字体设置补救本来就写错的数学语法.

代码块标明语言.本站的 Typst 高亮可用 typ typ , Rust 用 rust rust ,普通输出用 text text . 可运行的示例与伪代码要明确区分,省略的部分也要标明. 重复使用的记号或组件放进共享库,避免每篇文章维护一套近似的宏.

6.4 面向网页阅读

优先使用段落、标题、列表、链接与代码块等有语义的结构. 字体、颜色、间距等公共样式交给共享库和 .typsite/ .typsite/ 配置, 不要为了局部效果把正文包装成整张图片,或在每页复制一段样式. 复杂图形需要内联时再使用本站的相关组件.

本站的公式渲染会尝试转换为 MathML,无法转换时退回内联 SVG; 因此,Typst 编译通过不等于网页阅读效果已经合格. 重要公式应在附近用文字解释,图像应提供替代文本, 长代码与宽公式需要检查窄屏表现. 不要只靠颜色区别条件、分支或证明步骤.

7 发布前检查
  • 引言是否说明主题与读者需要的背景?直觉是否有准确陈述支撑?
  • 定义、例子、命题等定理环境能否单独阅读?变量、假设与适用范围是否完整?
  • 证明是否覆盖所需情形?引用结论时是否检查了前提?
  • 中文术语、数学记号是否一致?外文缩写是否确有必要?
  • 标点、粗体、代码与公式是否采用各自正确的 Typst 写法?
  • 链接、标签、注脚和嵌入是否有效?来源是否能追溯?
  • 源码是否清楚?可复用内容是否已经集中维护?
  • 页面在浏览器和窄屏上是否可读?公式、图像与代码是否遗漏信息?

在仓库根目录运行 typsite c --p packages typsite c --p packages 构建站点,再检查生成的页面. 命令成功只是第一步,还需要通读文字并核对链接和显示效果. 本文不是完整的语法手册;进一步的用法可查阅 Typst 语法参考、 数学公式参考,以及 Typsite 项目文档.

8 致谢

本文的写作原则、概念文章结构、中文术语、人名与数学记号约定, 主要参考了香蕉空间的 《风格指引》. 文中的 Typst 写法、Typsite 页面接口与本站独立条目规范是针对本项目的改写, 并非原站对这些工具的说明. 感谢香蕉空间及其编者提供这份清晰、细致的指南.