Markdown 约定
统一 Markdown 风格、标题结构、代码围栏声明、内部链接格式、作者署名头以及校验器的强制执行。
所有已编写的
.md和.mdx工件中 Markdown 形态与格式的规范参考。CLAUDE.md中 Conventions 一节的摘要是内联声明;本页是下游贡献者所引用的独立参考。
1. 风格
GitHub 风格 Markdown(GFM)是宿主风格。每个工件在 GitHub 的网页 UI、Fumadocs 文档站点以及支持 Markdown 的标准编辑器中都能正确渲染。
2. 标题层级
每个文件只有一个 H1。后续标题单调递降(H2 → H3 → H4),不跳级。标题采用句首大写;不使用全大写(ALL-CAPS),不使用 Title Case Across Every Word。H1 承载文档的主标题。在文档站点页面上,frontmatter 的 title 渲染为 H1,并且是该页面在文档站点导航中的锚点,因此页面正文从 H2 开始。
3. 代码块
围栏代码块声明其语言(```python、```bash、```yaml、```json、```mermaid)。未加标签的代码块会抑制语法高亮,并表明编写出现了漂移;在 .markdownlint.json 中配置的 markdownlint MD040 规则强制要求语言标签。
4. 内部链接
内部交叉引用使用站点根路径(例如 [Authorship header](/docs/reference/authorship-header))。站内链接避免使用带 .md/.mdx 扩展名的裸仓库相对路径(/docs/foo.md)以及指向同一仓库的完整 URL(https://github.com/ahmed-g-gad/apothem/blob/main/...),因为它们经不起页面重命名和章节重组。
这些 /docs/... 站点根路径——以及集合中非默认语言区域所用的 /<locale>/docs/... 形式——由 link-check 校验器对照 site/content/docs/ 下磁盘上的页面集合进行解析:/docs/a/b 映射到 site/content/docs/a/b.mdx 或文件夹索引 site/content/docs/a/b/index.mdx,而语言区域形式映射到 site/content/docs/<locale>/ 子树之下。指向已被移除或已被重命名的路由的链接,不会解析到这两个文件中的任何一个,并由 link-check——一个不会使运行失败的建议性匹配器(见 §6)——报告为死路由(面向用户的 404)。
指向可变引用(main、master、latest、HEAD)的外部链接,只要所链接内容的稳定性很重要,就会被固定到提交 SHA 或发布标签;易变的引用会以相邻的 {/* volatile */} 注释标明其易变性质。
5. 作者署名头
每个 Markdown 工件(src/apothem/schemas/header-exceptions.txt 中列举的例外除外)都带有规范的作者署名头——即单独一行 SPDX-License-Identifier: MIT——并按照作者署名头采用其文件类型对应的注释变体:.md 文件使用 HTML 注释,.mdx 文件使用 {/* ... */} 注释。没有 frontmatter 时,头部行是第 1 行。有 YAML frontmatter 时,frontmatter 保持在字节 0 处,头部行紧随结束的 --- 之后。
6. 校验器
.pre-commit-config.yaml 中的 pre-commit markdownlint 钩子使用 .markdownlint.json 中的规则策略运行 markdownlint-cli,并强制执行 §§1–4 中的大部分规则。Markdown Lint 工作流会在每次向 main 推送时以及每个触及 Markdown 的拉取请求中,在 CI 里运行同一个钩子,因此 CI 使用该钩子所固定的版本进行检查。该策略关闭了 MD013(行长度)、MD033(内联 HTML)和 MD041(首行标题)。它还关闭了 MD038,因为规范的选项标签后缀 (Recommended) 在代码跨度内保留其前导空格;并关闭了 MD060,因为没有任何表格列样式能接受语料库所使用的、带有紧凑 |---| 分隔行的紧凑单元格表格。MD024 只检查同级标题,因此每个发布在 CHANGELOG.md 中重复出现的 Added、Changed、Fixed 和 Security 标题都能通过。每项选择的理由都写在该钩子旁边。该钩子会跳过测试夹具目录树 tests/fixtures/、tests/conformity/、tests/conformity-scenarios/fixtures/ 和 tests/scripts/inject-header/fixtures/,这些目录树的字节由测试设定。它还会跳过 plugins/claude-code/,该目录由 python scripts/dev/assemble_plugin_tree.py 从 src/apothem/ 生成:一个命令的每个编号步骤都会成为单独的文件,所以步骤文件中的列表从该步骤的编号开始。src/apothem/ 中的源文件会接受检查,因此插件内容中的发现项要在那里修复,然后重新生成插件树。
位于 src/apothem/conformity/file_header_grep.py 的 file-header-grep 检查 §5。位于 src/apothem/conformity/link_check.py 的 link-check 校验器检查 §4 的链接解析纪律——它针对源文件所在的目录解析相对链接,并针对 site/content/docs/ 页面集合解析 /docs/...(以及 /<locale>/docs/...)站点路由,标记任何无法解析到磁盘上页面的链接。两者都是建议性的逐次写入匹配器。它们在 pre-commit 的 conformity-corpus-perwrite 钩子中运行,也在 .github/workflows/conformity.yml 中 Conformity 工作流的 corpus-perwrite-gate 作业中运行,并且在这两个地方都只报告发现项,而不会使运行失败。.github/workflows/ci.yml 中 CI 质量作业的 python -m apothem.conformity.gate --all . --strict 只覆盖独立校验器,因此这两者它都不会运行。