资讯动态

markdownlint 链接与标题空格规则实战:基于 MD011–MD021 测试文件的逐条解析与自动修复

发布时间:2026/10/15 6:56:21 来源:尧图企业网站定制
开发工具代码质量Lint静态分析【免费下载链接】markdownlintA Node.js style checker and lint tool for Markdown/CommonMark files.项目地址https://gitcode.com/gh_mirrors/ma/markdownlint点击查看免费下载导读本文以 markdownlint 仓库中的综合场景测试文件 test/MD011-MD021.md 为骨架逐条剖析其中覆盖的 8 条核心规则——反向链接MD011、连续空行MD012、行长MD013、命令提示符MD014以及 ATX 标题空格系规则MD018–MD021。你将掌握每条规则的触发条件、参数配置、{MD###}行内标记的断言机制以及 markdownlint 通过markdownlint-configure-file内联配置和applyFixes自动修复的完整工作流。测试文件结构用内联标记声明预期结果test/MD011-MD021.md 是一个自描述的 Markdown 文件——它不仅是 lint 的输入样例其内容本身也通过行内注释标明了每条规则期望报告的行号# Top level heading !-- markdownlint-disable MD003 -- A (reversed)[link] example. {MD011} ... {MD012:7} {MD013:8} {MD013:10} !-- markdownlint-configure-file { line-length: { heading_line_length: 40 } } --其中的关键机制来自测试驱动 test/markdownlint-test-scenarios.mjs测试框架用正则/\{(MD\d)(?::([-]?)(\d))?\}/g扫描文件内容将{MD011}解析为第 5 行应报告 MD011将{MD013:8}解析为第 8 行应报告 MD013支持{MD013:2}这类相对行号写法/-前缀表示偏移。随后框架对 lint 返回的ruleNames[0]与实际报告行号做深度比对任何多报或漏报都会导致测试失败这就是test/markdownlint-test-scenarios.mjs.snapshot中快照的来源。值得注意的是该文件第 3 行用!-- markdownlint-disable MD003 --关闭了标题风格一致性检查避免标题用例干扰本文关注的规则文件末尾的markdownlint-configure-file注释则在整文件范围内把line-length规则的heading_line_length调整为 40详见下文 MD013 小节。MD011反向链接语法no-reversed-links触发条件与修复MD011 在文本疑似链接、但方括号与圆括号顺序颠倒时触发例如(reversed)[link]。规则文档 doc/md011.md 给出的正确写法是reversed并特别说明 Markdown Extra 风格的脚注For (example)[^1]不触发该规则。测试文件中第 5 行A (reversed)[link] example. {MD011}与第 26 行*Another* (reversed)[link] example. {MD011}两处命中快照显示二者均被报告为errorDetail: (reversed)[link]、errorRange: [3,16]与[11,16]并携带自动修复信息insertText: reversed。源码级实现原理在 lib/md011.mjs 中核心正则const reversedLinkRe /(^|[^\\])\(([^()])\)\[([^\]^][^\]]*)\](?!\()/g;实现细节包括通过filterByTypesCached([codeFenced, codeIndented, mathFlow])跳过围栏代码块、缩进代码块和数学公式块避免误报代码内容通过filterByTypesCached([codeText, mathText])排除行内代码与行内数学并用hasOverlap做区间重叠判断检测linkText与linkDestination是否以反斜杠结尾避免命中转义场景命中后给出完整fixInfoeditColumn、deleteCount、insertText因此 MD011 位于 lib/constants.mjs 的fixableRuleNames列表中可被applyFixes自动重排为reversed。MD012连续空行no-multiple-blanks触发条件与参数MD012 在文档中出现连续多个空行时触发。测试文件第 7 行附近存在两处连续空行快照报告errorDetail: Expected: 1; Actual: 2且fixInfo.deleteCount: -1表示在上一行末尾删掉一个换行。规则文档 doc/md012.md 给出参数参数类型默认值含义maximuminteger1允许的最大连续空行数代码块内部的连续空行不触发本规则。源码级实现原理lib/md012.mjs 的实现非常精简先用filterByTypesCached([codeFenced, codeIndented])收集代码块行号集合然后逐行扫描count (inCode || line.trim().length 0) ? 0 : count 1——非空行或代码块内重置计数连续空行累计一旦count maximum即报错并附带删除一个换行的修复信息。maximum通过Number(params.config.maximum || 1)读取可直接在配置中调整。MD013行长line-length参数表与三种检查模式MD013 是本文档涉及参数最多的规则完整参数见 doc/md013.md参数类型默认值含义line_lengthinteger80普通行最大字符数heading_line_lengthinteger80标题行最大字符数code_block_line_lengthinteger80代码块行最大字符数headingsbooleantrue是否检查标题code_blocksbooleantrue是否检查代码块tablesbooleantrue是否检查表格strictbooleanfalse严格模式任何超长行都报错sternbooleanfalse严格但允许整行无空格默认行为存在无空格豁免只要超出限制的部分没有空格如长 URL就不报错。strict关闭该豁免stern则只对可换行但未换行的行报错。此外链接/图片的引用定义行、以及仅包含单个链接/图片可带强调的独立行即使在strict模式下也永远豁免因为这类行无法在不破坏 URL 的前提下拆分。测试文件中的应用测试文件第 8 行是 99 个字符的长行Expected: 80; Actual: 99第 10 行是超长的 H2 标题。文件末尾的内联配置把标题行上限收窄!-- markdownlint-configure-file { line-length: { heading_line_length: 40 } } --因此快照中第 10 行报告Expected: 40; Actual: 62——同一规则对普通行与标题行使用了不同阈值这正是heading_line_length独立生效的实证。源码级实现原理lib/md013.mjs 通过filterByTypesCached收集atxHeading/setextHeading、codeFenced/codeIndented、table、autolink/image/link/literalAutolink等 token 的行号区间逐行按inCode → codeLineLength、isHeading → headingLineLength、否则lineLength选取阈值并用line.replace(/\S*$/u, #)实现无空格豁免strict/stern模式下不替换。definitionLineIndices来自getReferenceLinkImageData()实现引用定义豁免linkOnlyLineNumbers实现纯链接独立行豁免。MD013 本身不可自动修复fixInfo: null需要手动换行。MD014命令前的美元符号commands-show-output触发条件MD014 在代码块展示 shell 命令、且所有命令都以$开头、同时没有任何输出行时触发。规则文档 doc/md014.md 强调三个边界若命令后附带了输出$ ls后跟foo bar不触发若只有部分命令有输出不触发只有全部命令带$且全部无输出才触发。测试文件第 12 行缩进代码块$ command with no output {MD014}命中快照给出errorRange: [5,2]即$两字符与fixInfo: { editColumn: 5, deleteCount: 2 }——自动修复会直接删掉美元符号与空格。源码级实现原理lib/md014.mjs 遍历codeFenced/codeIndented代码块取出codeFlowValue子节点用/^(\s*)(\$\s)/匹配行首$。只有dollarMatches.length codeFlowValues.length全部行带$时才报告所有命中行。这意味着只要代码块内出现一行未以$开头的文本典型如命令输出规则即整体放行。MD018–MD021ATX 标题空格四规则这四条规则共同管理 ATX 风格标题#开头中井号与标题文本之间的空格数量按开式不闭合与闭式行尾也加井号分为四组规则别名检查对象判定MD018no-missing-space-atx开式标题井号后缺少空格MD019no-multiple-space-atx开式标题井号后多于一个空格MD020no-missing-space-closed-atx闭式标题井号两侧缺少空格MD021no-multiple-space-closed-atx闭式标题井号两侧多于一个空格测试文件中的四组用例测试文件 14–24 行密集放置了六条用例恰好覆盖四种违规行号原文命中的规则快照报告14##No space A {MD018}MD018errorRange: [1,3]修复为在列 3 插入空格16## Multiple spaces B {MD019}MD019errorRange: [4,1]删除第 4 列一个空格18##No space C {MD020} ##MD020左侧缺空格整行重写为## No space C {MD020} ##20## No space D {MD020}##MD020右侧缺空格同样整行重写22## Multiple spaces E {MD021} ##MD021左侧多空格删除第 4 列一个空格24## Multiple spaces F {MD021} ##MD021右侧多空格删除第 30 列一个空格从快照可见MD018/019 的修复是局部插入/删除而 MD020 因可能同时涉及左右两侧采用editColumn: 1, deleteCount: 行长度, insertText: 规范化整行的重写式修复——这也解释了 lib/md020.mjs 中同时判断leftSpaceLength与rightSpaceLength/rightEscape的原因。源码级实现原理MD018 在 lib/md018.mjs 中用正则/^#[^# \t]/定位井号后紧跟非井号非空格的行同时排除以#结尾的闭式标题、排除#️⃣emoji 序列并跳过codeFenced/codeIndented/htmlFlow区间修复方式是editColumn: hashCount 1, insertText: 。MD019 与 MD021 共用同一辅助函数validateHeadingSpaces实现在 lib/md019-md021.mjs基于 micromark 解析出的atxHeadingtoken通过getHeadingStyle(heading)区分atx与atx_closed两种风格delta 1正向扫描开式/闭式标题的起始空白delta -1仅对闭式标题扫描结尾空白。只有当whitespace.text.length 1多于一个空格时才报告修复为删除多余空格。这从实现层面印证MD019 只检查开头MD021 则开头、结尾都检查闭式标题两侧皆可能违规。综合验证快照与自动修复test/markdownlint-test-scenarios.mjs.snapshot 中MD011-MD021.md条目完整记录了 13 个错误对象2×MD011、1×MD012、2×MD013、1×MD014、1×MD018、1×MD019、2×MD020、2×MD021并给出了applyFixes后的整文件内容# Top level heading !-- markdownlint-disable MD003 -- A reversed example. {MD011} 123456789 ... ## 123456789 ... command with no output {MD014} ## No space A {MD018} ## Multiple spaces B {MD019} ## No space C {MD020} ## ## No space D {MD020} ## ## Multiple spaces E {MD021} ## ## Multiple spaces F {MD021} ##修复后再次 lintmarkdownlint-test-scenarios.mjs会断言可修复的错误均已清零fixableRuleNames中列出的规则必须全部修复完成报错 → 修复 → 复核的闭环。你可以用同样的方式在本地验证运行node test/markdownlint-test-scenarios.mjs或直接node test/harness.mjs test/MD011-MD021.md查看 token 结构与 lint 结果即可复现本文所有结论。实战小结通过这一份测试文件可以提炼出四条可直接迁移到日常 Markdown 写作的准则链接语法始终使用文本避免括号顺序颠倒MD011它可被自动修复空行与行长段落间最多保留一个空行MD012普通行控制在 80 字符内、标题行可通过heading_line_length单独收紧MD013超长行需手动拆分代码块命令要么省略$要么展示命令输出二者缺一不可MD014全无输出的$前缀命令会被自动删除提示符标题空格ATX 标题井号后必须有且仅有一个空格使用闭式标题时两侧同样要求恰好一个空格MD018–MD021除 MD020 采用整行重写修复外其余均为局部空格增删。若需按项目自定义这些阈值除了常规的options.config配置外还可以像本测试文件一样使用!-- markdownlint-configure-file { ... } --内联注释按文件覆盖配置语法见 README.md实现单文件级的精细化规则调优。赞分享开发工具代码质量Lint静态分析【免费下载链接】markdownlintA Node.js style checker and lint tool for Markdown/CommonMark files.项目地址https://gitcode.com/gh_mirrors/ma/markdownlint点击查看免费下载相关推荐markdownlint 规则 MD021no-multiple-space-closed-atx闭合 ATX 标题井号内多余空格的检测与自动修复markdownlint 规则 MD021no multiple space closed atx闭合 ATX 标题井号内多余空格的检测与自动修复 本篇文开发工具代码质量Lint静态分析markdownlint 深入解析 MD011 规则reversed link syntax反转链接语法的检测原理与自动修复markdownlint 深入解析 MD011 规则reversed link syntax反转链接语法的检测原理与自动修复 MD011 别名 no r开发工具代码质量Lint静态分析markdownlint MD039 规则详解识别与自动修复链接文本内部的空格问题markdownlint MD039 规则详解识别与自动修复链接文本内部的空格问题 本文基于 markdownlint 仓库中的 MD039 规则文档 htt开发工具代码质量Lint静态分析上一篇昇腾GE的CMake示例指南下一篇Newsyc终极开源Hacker News iOS客户端完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价 →
↑