资讯动态

解读 MarkText 的 CommonMark 标题测试夹具:Setext、ATX 与水平分割线的完整规则

发布时间:2026/9/5 23:18:43 来源:尧图企业网站定制
解读 MarkText 的 CommonMark 标题测试夹具Setext、ATX 与水平分割线的完整规则【免费下载链接】marktextA simple and elegant markdown editor, available for Linux, macOS and Windows.项目地址: https://gitcode.com/gh_mirrors/ma/marktext本篇以 MarkText 仓库中的 CommonMark 标题测试夹具 Headings.md 为主体完整剖析 CommonMark 规范中 Setext 与 ATX 两种标题语法的书写规则、边界陷阱如 7 个#、#5、#This不是标题以及---在 Setext 下划线与水平分割线之间的歧义判定。读完后你既能准确书写符合规范的 Markdown 标题也能理解这套夹具如何在 MarkText 的 muya 编辑器测试链路中被加载和验证。一、夹具定位CommonMark 标题语法的标准答案文件Headings.md 位于packages/desktop/test/unit/data/common/目录下与 BasicTextFormatting.md、Blockquotes.md、CodeBlocks.md、Lists.md 等文件共同构成 CommonMark 基础语法的测试数据组。它由 markdown.ts 中的HeadingsTemplate统一导出const loadMarkdownContent (pathname: string): string { // Load file and ensure LF line endings. return fs .readFileSync(path.resolve(test/unit/data, pathname), utf-8) .replace(/(?:\r\n|\n)/g, \n) } export const HeadingsTemplate () { return loadMarkdownContent(common/Headings.md) }注意加载器会先把 CRLF 归一化为 LF 再返回——这对标题类语法尤其重要Setext 标题的下划线/---必须位于文字所在行的紧邻下一行若行尾混入\r会直接改变块级结构的解析结果。夹具本身是一份规则演示文档覆盖三大块内容Setext 标题、ATX 标题、水平分割线Horizontal Rule。下面逐块对照 CommonMark 规范拆解。二、Setext 标题仅支持一级和二级夹具开头的 Setext 部分原文如下## Setext heading This is a huge header this is a smaller header --- header --- This is a huge header this is a smaller header ------------------其要点可以归纳为下划线决定级别紧跟段落行的一个或多个构成一级标题-一个或多个构成二级标题。与效果完全一致---与------------------效果完全一致——下划线长度无关紧要因此 Setext 只能表达 H1/H2 两个级别。下划线行允许缩进第二个示例中下划线前带有缩进空白仍然成立符合 CommonMark 对 Setext 下划线行最多 3 个前导空格的宽容处理。header---是合法二级标题这与后文水平分割线一节看似矛盾判定规则取决于---之前是否有空行——Setext 下划线要求与上文紧邻无空行而水平分割线独立成块时上下通常留空行。这一紧邻 vs 空行的上下文敏感正是 Setext 语法最易出错的地方也是夹具特意安排两段相同内容Setext heading节与Horizontal Rule节的原因同一条header---序列上下文不同解析结果不同。三、ATX 标题1~6 个井号且必须后跟空格夹具的 ATX 部分原文如下## Atx heading ## ATX Headings # foo bar ## foo bar ### foo bar #### foo bar ##### foo bar ###### foo bar ####### This isnt a heading bar #5 This isnt a heading #This isnt a heading规则拆解级别由井号数量决定#至######依次对应 H1 至 H6且每条示例后面都跟了正文bar说明标题与后续段落之间需要空行分隔否则bar会被视为标题内容的一部分CommonMark 中 ATX 标题是单行构造标题行之后的行不构成标题。三个反例是规范的经典陷阱夹具将它们逐条列出####### This isnt a heading7 个及以上井号不识别为标题CommonMark 只定义 1~6 级#5 This isnt a heading井号后紧跟非空白字符这里是5不构成标题#This isnt a heading井号后无空格CommonMark 也接受制表符但不接受中文全角空格之外的任意字符粘连不构成标题。这三行是 ATX 标题校验正则的关键约束来源^(#{1,6})(?:\s|$)中1~6 个# 必须后随空白或行尾两条缺一不可。四、水平分割线---的另一种身份夹具结尾的 Horizontal Rule 部分## Horizontal Rule --- foo --- bar ## Horizontal Rule - - - - -- --- --- ----独立成行、且不与上文紧贴的---解析为hrthematic break而非 Setext 下划线——与第二节紧邻即 Setext、独立即分割线的判定互为镜像。最后一行- - - - -- --- --- ----展示了分割线的另一组写法由-、*、_三种字符中任一种重复至少 3 次构成字符之间允许任意数量的空白。- - -带空格同样合法。CommonMark 中分割线字符集为*、-、_夹具选用-演示恰好能同时凸显它与 Setext 下划线的符号冲突是理解歧义判定的最佳样本。五、源码印证muya 编辑器如何落块标题与分割线夹具验证的语法最终由 muya 编辑器的块级模型承载。源码中可以确认三类块的独立实现ATX 标题atxHeading/index.ts 中AtxHeading的构造函数依据meta.level动态决定标签constructor(muya: Muya, { meta }: IAtxHeadingState) { super(muya); this.tagName h${meta.level}; this.meta meta; this.classList [mu-atx-heading]; this.createDomNode(); }这与夹具井号数量决定级别的规则一一对应级别合法域为 1~6正对应 1~6 个#。static create中还挂接了heading-copy-link附件块为标题提供复制锚点链接能力。Setext 标题setextHeading/index.ts 的SetextHeading与 ATX 结构同构同样按h${meta.level}渲染但使用独立的mu-setext-headingclass 与setextheading.content内容块。两种语法在渲染层被统一为同级标题标签差异只保留在块名atx-heading/setext-heading与回写 Markdown 的格式上。水平分割线thematicBreak/index.ts 中ThematicBreak以p classmu-thematic-break承载this.tagName p即分割线在 muya 中是独立的块级单元而非依附于相邻标题块——这与夹具中空行隔开才是分割线的独立性语义一致。六、如何复现与验证查看夹具原文packages/desktop/test/unit/data/common/Headings.md。查看加载链路packages/desktop/test/unit/markdown.ts 中的HeadingsTemplate注意其中的 LF 归一化逻辑。对照块级实现packages/muya/src/block/commonMark/atxHeading/index.ts、packages/muya/src/block/commonMark/setextHeading/index.ts、packages/muya/src/block/commonMark/thematicBreak/index.ts。同目录的 gfm/ 数据组提供 GFM 扩展语法夹具可与本 CommonMark 基础组对照阅读。小结这份仅 68 行的夹具是 CommonMark 标题与分割线规则的浓缩版Setext 只产出 H1/H2 且依赖紧邻下划线判定ATX 严格限制为 1~6 个井号加空白而---在有无空行的上下文中分别扮演二级标题下划线与水平分割线两个角色。结合 muya 编辑器中atx-heading、setext-heading、thematic-break三个块级实现可以完整理解 MarkText 从 Markdown 文本到 DOM 标题块h1~h6、mu-*class的解析映射关系。【免费下载链接】marktextA simple and elegant markdown editor, available for Linux, macOS and Windows.项目地址: https://gitcode.com/gh_mirrors/ma/marktext创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价