NautilusTrader Markdown 风格规范:基于 markdownlint 的文档编写与自动化校验指南
2026/9/13 20:32:18 网站建设 项目流程

NautilusTrader Markdown 风格规范:基于 markdownlint 的文档编写与自动化校验指南

【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader

本文是 NautilusTrader 仓库内 Markdown 文档的编写基准(baseline)说明,适用于所有在仓库文档范围内撰写、修改 Markdown 文件的开发者与 AI 协作场景。文章以 docs/developer_guide/markdown_style.md 为骨架,结合仓库根目录的 .markdownlint.jsonc 配置、Makefile 中的check-markdown目标以及 scripts/check-markdown-tables.py 脚本,完整讲解规则层级、语法基线、各类元素的书写要求、自动化强制机制与过渡性采用策略。读完本文,你将能写出既符合 CommonMark/GFM 规范、又能通过本仓库 markdownlint 检查的文档,并理解每一条规则背后的工具实现。

规范定位:一份可复制的共享基线

markdown_style.md是一份"标准修订版(Standard revision: 1)"的共享 Markdown 基线文档,设计目标是被多个采用该文档副本的仓库共同维护。因此它明确要求:

  • 各仓库的副本必须与被维护的源逐字节(byte-for-byte)保持一致
  • 仓库特有的补充内容必须写在单独的本地指南中,而不是混入共享基线。

在 NautilusTrader 中,这份仓库本地补充指南就是 docs/developer_guide/docs.md。docs.md 在开篇即声明:markdown_style.md是 Markdown 语法与格式的共享基线,.markdownlint.jsonc强制执行其机械子集,而 docs.md 只覆盖 NautilusTrader 文档特有的约定(文档类型体系、语气、MDX 组件、支持矩阵表格等),不重复基线内容。这种"共享基线 + 本地指南"的分层结构,既保证了跨仓库风格统一,又为项目保留了定制空间。

规则层级:Required、Preferred 与 Transitional

规范将每一条规则划分为三个层级,理解层级是阅读全部规则的前提:

层级含义判定标志
Required(必需)适用于范围内每个文件,不满足即不合规无条件祈使句("Use"、"Do not")或含 "must" 的表述
Preferred(首选)存在多种合法写法时的默认选择使用 "Prefer" 措辞,不影响合规判定
Transitional(过渡)仅适用于新增或大幅编辑的指定构造明确标注Transitional或描述为 transitional;既有实例可保留至单独迁移

此外,规范对措辞的含义边界做了精确定义:

  • 含 "may" 或 "allowed" 的表述授予有限许可而非义务;任何限制该许可的条件都属于 Required;
  • 仓库可以在其渲染器、生成内容或导入材料确有需要的场景下,记录更窄的本地例外。

语言与扩展:CommonMark 为基,GFM 为扩展

规范对 Markdown 方言的选择非常明确:

  • CommonMark作为基础规范;
  • 使用GitHub Flavored Markdown(GFM)来支持表格、任务列表、删除线和自动链接;
  • 额外的 front matter、Markdown 扩展或渲染器组件,仅当仓库有文档说明并支持时才可使用;
  • 禁止引入依赖未文档化渲染器扩展的语法

规范还特意提醒:文首链接的两个规范是"参考资料"而非"常规前置条件"——只有遇到本地指南、上下文内容和 markdownlint 都无法回答的具体解析器/渲染器歧义时,才需要打开它们查阅。这也意味着绝大多数日常写作不需要翻阅规范原文。

强制机制:从配置文件到命令行

风格规范本身是"意图",而自动化工具是其"机械子集的执行者"。仓库的强制链路由三层构成。

1. 仓库级 markdownlint 配置

仓库根目录的 .markdownlint.jsonc 采用"默认全关("default": false)+ 显式开启"的策略,即只启用仓库确认需要的规则。已启用的规则及其配置覆盖了本规范的所有机械性要求,例如:

  • MD001/heading-increment:标题层级每次只能递增一级;
  • MD003/heading-style:ATX 标题风格(style: "atx");
  • MD004/ul-style:无序列表用-style: "dash");
  • MD009/no-trailing-spaces:禁止行尾空格,br_spaces: 0同时禁止用尾随空格制造硬换行,并启用strict
  • MD012/no-multiple-blanks:连续空行最多 1 行;
  • MD031/MD032:围栏代码块与列表前后必须有空行;
  • MD034/no-bare-urls:禁止裸 URL;
  • MD035/hr-style:分隔线风格固定为---
  • MD046/code-block-style:代码块使用围栏风格(fenced);
  • MD049/MD050:强调与加粗统一使用星号(*italic***bold**);
  • MD055/MD056/MD058:表格必须有首尾竖线、列数一致、表格前后有空行;
  • MD059/descriptive-link-text:链接文本必须具有描述性;
  • MD060/table-column-alignment:表格列对齐风格为aligned

2. make check-markdown 目标

Makefile 中的check-markdown目标把两条检查串联起来:

check-markdown: #-- Lint Markdown with markdownlint-cli2 and check table delimiter padding @$(MARKDOWNLINT) --config .markdownlint.jsonc $(MARKDOWNLINT_FILES) @python3 -B scripts/check-markdown-tables.py $(MARKDOWN_FILES)
  • 第一条命令用markdownlint-cli2配合.markdownlint.jsonc检查全部 Markdown 文件,其版本通过 pre-commit hook 的 rev 固定(Makefile 中从 pre-commit 配置解析MARKDOWNLINT_VERSION);
  • 第二条命令运行 scripts/check-markdown-tables.py,专门规整表格的列宽填充与分隔行内边距。

3. pre-commit 钩子与生成文件

  • normalize markdown table paddingpre-commit 钩子会自动把表格重写为规范要求的填充形式(最宽单元格 + 两侧各一空格),因此手写时无需人工数空格;
  • 规范同时要求:不要手工编辑生成的 Markdown,应修改其源文件后重新运行生成器;生成的、导入的第三方文档与渲染器夹具可使用文档化的仓库排除规则。

4. 配置与规范冲突的处理

规范给出了三条明确准则:

  • 遵循仓库的.markdownlint.jsonc或等价本地配置;
  • 将本规范视为"预期风格",将 markdownlint 视为其机械子集的自动化执行;
  • 规范与本地配置之间存在未文档化冲突时,视为需要解决的漂移(drift),而不是默认的例外;
  • 确保仓库 lint 范围内所有作者编写的 Markdown 都通过配置的 Markdown 检查。

标题:ATX 风格与大小写约定

  • 使用 ATX 标题(######等),对应MD003
  • 每篇文档的第一个 Markdown 标题必须是唯一的 H1,对应MD025/single-title
  • H1 使用 Title Case(每个实词首字母大写);
  • H2 及以下使用 Sentence case(仅首字母与专有名词大写);
  • 保持逻辑层级,不跳级(对应MD001);
  • 每个标题上下各留一个空行(对应MD022lines_above: 1lines_below: 1)。

docs.md 补充了本地约定:无论标题层级,专有名词(产品名、技术名、公司名、缩写)始终大写,这一条优先于大小写规则。

段落与换行

  • 段落之间用一个空行分隔;
  • 不要出现连续空行(对应MD012maximum: 1);
  • 散文行长度目标为100–120 字符(Preferred 级);
  • 优先在自然断点换行,避免一行末尾只留 1–3 个词;
  • 代码块、表格和长链接目标可以超出该目标(Allowed)。

值得注意的是,docs.md 中 NautilusTrader 的源码注释规范要求行宽低于 100 字符,而 Markdown 散文的行宽目标稍宽(100–120),两者适用对象不同,不应混淆。

列表:破折号与"全部写 1."

  • 无序列表项统一使用-(对应MD004dash风格;NautilusTrader 的编码规范同样在 Rust/Python/Shell 注释中坚持用-而非*);
  • 仅当顺序有意义时才使用有序列表;
  • Transitional 规则:有序列表的每个源行都写1.,由渲染器自动编号(对应MD029的行为,但该规则当前仍被禁用,见下文"过渡性采用");
  • 列表的缩进与间距与本地 markdownlint 配置保持一致(MD007配置为 2 空格缩进、首层不缩进、MD030配置列表标记后 1 空格);
  • 列表前后各留一个空行(对应MD032)。

示例(规范原文):

- First item - Second item 1. First step 1. Second step

Admonitions(提示块):GitHub Alert 与可移植回退

Admonition 的使用必须遵循"只使用仓库有文档说明且能渲染的语法"这一总原则,具体分三种情形:

  1. 仓库文档化并支持 GitHub Alerts 时:使用 GitHub blockquote alert 形式,类型限定为NOTETIPIMPORTANTWARNINGCAUTION之一;
  2. 该扩展不存在或未确认支持时:使用可移植的 blockquote + 粗体文本标签形式;
  3. 多段落 admonition:每个内容行和空行续行都要以>开头;一个裸空行即结束该 admonition。

规范还强调两点:类型标签必须在源码和渲染输出中都保留(不能只靠颜色或图标传达含义);在窄幅编辑中要保留已确立且受支持的既有 admonition 语法,不要仅为套用回退形式而转换它。

> [!WARNING] > Back up the database before running the migration.

可移植回退形式:

> **Warning:** Back up the database before running the migration.

需要注意:NautilusTrader 的文档站(fumadocs,见 docs.md)在 MDX 环境中使用的是:::note:::info:::tip:::warning:::danger这组 admonition 语法,并警告"过度使用 admonition 会削弱其影响力"。这两套语法服务于不同场景——markdown_style.md是面向所有采用该基线的仓库的可移植基准,而 docs.md 的 MDX admonition 是本地文档站的既定扩展,写作时需根据目标文件所在的渲染环境选择正确的形式。

表格:GFM 管道表格与对齐规范

表格是 NautilusTrader 文档中出现频率最高的元素之一(能力矩阵、支持表、参数表),规范与工具对它的约束也最细:

  • 使用 GFM 管道表格;
  • 包含首尾竖线(对应MD055leading_and_trailing风格);
  • 竖线垂直对齐
  • 每列填充到最宽单元格宽度 + 两侧各一空格(与 Prettier 的默认表格输出一致)。MD060只检查竖线对齐、不检查单元格内容宽度,因此列可以比内容更宽;
  • 分隔行单元格两侧也要填充空格| ----- |而不是|-----|),MD060同样不检查此项;
  • 文本列默认左对齐,数字列按需右对齐(分隔行右侧冒号----:表示右对齐),分隔行与预期的渲染对齐方式保持一致;
  • 避免使用 HTML 表格,除非 Markdown 无法表达所需结构或仓库有文档说明。

规范原文示例:

| Name | Value | | ----- | ----: | | Alpha | 42 | | Beta | 17 |

表格的自动化规整

scripts/check-markdown-tables.py 提供了比 markdownlint 更进一步的保障,它的实现细节印证了规范中的陈述:

  • 使用正则DELIMITER_RE识别分隔行,并用围栏检测(FENCE_RE)跳过代码块内的表格;
  • 按列宽计算时使用utf16_width(对 BMP 之外的字符(如)按宽度 2 计数),确保-这类支持矩阵符号不会破坏对齐;
  • cell_alignment根据单元格两侧空格数推断左/右/居中对齐,分隔行冒号位置决定渲染对齐;
  • 规整结果为"最宽单元格 + 2"的列宽、MIN_DASHES = 3的最小分隔线长度,与规范"每列填充到最宽单元格加一空格"完全对应;
  • 脚本发现需要规整的文件时返回退出码 1,从而让check-markdown目标失败并提示normalized table column widths

docs.md 还补充了支持矩阵的语义约定:用表示支持、用-表示不支持(而非),不支持的说明用斜体*Not supported*强调,并按原因细化——*Not supported by <venue>*表示交易所能力缺口、*Not currently implemented*表示适配器尚未实现。

代码:围栏、语言标注与行内代码

  • 使用反引号围栏代码块,不用缩进代码块(对应MD046fenced风格;MD048规定围栏符号为反引号);
  • Transitional 规则:每个开围栏都必须标注语言;无更具体语法的纯文本或输出使用text
  • 当文档本身要展示带围栏的 Markdown 时,使用更长的外层围栏(例如四反引号包三反引号);
  • 命令、文件名、函数、类型、环境变量、配置键和标识符使用行内代码。

嵌套围栏示例:

```rust fn main() { println!("Hello"); }
docs.md 对代码引用还有一条实用约定:引用代码位置时使用 `file_path::function_name` 或 `file_path::ClassName` 形式,而**不用行号**——行号会随代码变更而过时。这与本文章前面引用 Makefile 目标、脚本函数的方式一致。 ## 强调、分隔线与链接图片 - 强调用 `*italic*`,强强调用 `**bold**`(对应 `MD049`/`MD050` 的 `asterisk` 风格); - 避免无意义的强调; - 分隔线使用三个连字符 `---`(对应 `MD035` 的 `hr-style`); - 链接使用描述性文本(对应 `MD059`,例如用"账户配置文档"而非"点击这里"); - 优先行内链接;同一目标在文档中出现多次时,优先引用式链接(对应 `MD052`/`MD053` 对引用定义的要求); - 避免裸 URL(对应 `MD034`); - 渲染器支持时保持内部链接为相对路径; - 图片必须有有用的替代文本(alt text),纯装饰图片才允许使用空 alt(对应 `MD045`)。 ## HTML:优先可移植 Markdown - 优先使用可移植的 Markdown 语法,而非原始 HTML; - 仅当 Markdown 无法表达所需结果、或仓库有文档说明该元素/组件时才使用原始 HTML; - 在编辑周边内容时,保留受支持的 front matter、MDX 组件、围栏属性和其他仓库扩展(这些在 NautilusTrader 的 fumadocs 文档站中广泛存在,例如 docs.md 记录的 `Tabs`、`Steps`、`Accordions`、`Files`、`Cards`、`TypeTable` 组件)。 ## 文件级别要求:编码、换行与空白 - 使用 **UTF-8** 编码; - 使用 **LF** 行尾(对应 `check-markdown-tables.py` 写入时显式指定 `newline="\n"`); - 文件以**一个换行符结尾**(对应 `MD047`); - 不遗留行尾空格,也不使用尾随空格制造 Markdown 硬换行(对应 `MD009` 的 `br_spaces: 0`)。 ## 编辑指引:窄幅修改与结构重构的不同策略 规范针对"创建或修改 Markdown"给出了场景化的操作建议: - **窄幅修改(narrow edits)**:保留周边风格,直接用 markdownlint 检查即可,不必通读整份指南——除非两者都留下具体未决问题; - **创建或大幅重构文档之前**:只查阅仓库本地 Markdown 指南的相关章节(对 NautilusTrader 而言是 docs.md 与 markdown_style.md 的对应小节); - **保留既有文档结构**,除非任务本身要求变更; - 格式与周边内容和受支持的渲染器扩展保持一致; - **不要重排无关章节**; - 可用时运行仓库的聚焦 Markdown 检查(即 `make check-markdown`)。 这套指引同样适用于 AI 辅助写作场景:小范围修订交给 linter 把关,大范围创作先对齐本地风格指南,始终把变更面控制在任务范围内。 ## 过渡性采用(Transitional adoption):规则与迁移的平衡 规范最后说明了哪些规则立即生效、哪些处于过渡状态: - **ATX 标题通过 `MD003` 立即强制执行**(非过渡); - **重复的 `1.` 有序列表标记**和**开围栏语言标注**是过渡性规则——它们对应的 `MD029`(有序列表前缀)与 `MD040`(围栏代码语言)**在既有文档完成单独机械迁移之前保持禁用**; - 因此,不要为了迁移那些既有构造而扩大一次窄幅文档修改的范围。 这一设计与 `.markdownlint.jsonc` 的配置完全吻合:`MD003` 处于开启状态,而 `MD029`、`MD040` 未出现在启用清单中。它体现了规范制定的核心理念——**风格演进应当是"新增内容先守新规、存量内容分批迁移",而不是一次性大规模重写**,既保证了向前的一致性,又避免了对既有文档的破坏性变更。 ## 小结:一条从规范到工具的完整链路 NautilusTrader 的 Markdown 风格管理是一套自洽的工程体系: 1. **意图层**:[docs/developer_guide/markdown_style.md](https://link.gitcode.com/i/a180ffb7d2b019812178e043c6647c7e) 定义共享基线(规则层级、语法选择、元素写法); 2. **本地化层**:[docs/developer_guide/docs.md](https://link.gitcode.com/i/f36463b1018f39ae057e7dcf0922efac) 定义 NautilusTrader 文档特有约定(文档类型、语气、MDX 组件、支持矩阵); 3. **机械层**:[.markdownlint.jsonc](https://link.gitcode.com/i/b539fbf43efe8d3462c23ed78c64cfe0) 以"默认关闭 + 显式启用"方式固化规则子集; 4. **执行层**:[Makefile](https://link.gitcode.com/i/fe64e26fff4e32bdd7e81cef055be655#L654-L658) 的 `check-markdown` 串联 markdownlint-cli2 与 [scripts/check-markdown-tables.py](https://link.gitcode.com/i/a2b7cbe199552f293ee9a5e65e9b8769),配合 pre-commit 钩子实现提交前自动规整。 对贡献者而言,日常写作只需遵循两条主线:**新增内容按规范书写(过渡规则对新内容立即生效)**,**提交前运行 `make check-markdown` 并通过**。把握住"共享基线 + 本地指南 + 自动化强制"的分层思想,就能在保持文档风格统一的同时,让每一次文档变更都可验证、可追踪。

【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询