统计Markdown标题数量时容易忽略的三个细节:围栏代码块、行首空格与Setext标题
用脚本统计Markdown各级标题数量时,最简单的办法是逐行匹配“行首的#号”。这个办法在干净的文档里没问题,但在真实文档里很容易数错。下面三个细节,是我在写这类脚本时实际踩到、也最容易被忽略的。
一、围栏代码块里的“#”不是标题
代码示例里经常出现以#开头的行,例如Shell注释、Python注释、配置文件里的注释行。如果脚本不区分代码块,就会把这些行全部算成标题。正确做法是先维护一个“是否在围栏代码块内”的状态:遇到以```或~~~开头的行就切换状态,处于代码块内时跳过标题统计,遇到闭合围栏再恢复。只看单行正则、不看上下文,是这类统计最常见的错误来源。
二、行首最多三个空格仍是标题,四个空格就变了
按照CommonMark的规则,ATX标题行首最多可以有三个空格,超过三个空格后该行会被解析为缩进代码块,而不是标题。写正则时如果只写“行首必须是#”,就会漏掉带一到三个空格缩进的标题;如果写成“任意空白后接#”,又会把四个空格的缩进代码误算进去。稳妥的写法是允许0到3个空格,再匹配1到6个#号,后面还要有空格或行尾。
三、Setext标题没有#号,容易被漏数
除了#号标题,Markdown还有Setext风格:一行普通文本,下一行是连续的=号表示一级标题,连续的-号表示二级标题。例如“项目简介”下一行写“========”,渲染后就是一级标题。只统计#号的脚本会把这类标题全部漏掉。处理办法是按行配对判断:当前行是非空文本、下一行全部由=或-组成时,把当前行计为一级或二级标题,同时注意不要把列表项、分隔线和Setext下划线混淆。
一个可直接复用的检查清单
1、先处理围栏代码块,块内内容一律不计标题。
2、ATX标题只接受行首0到3个空格、1到6个#号、#号后有空格或行尾的形式,结尾多余的#号不影响级别。
3、再补一遍Setext配对判断,避免漏数无#号的标题。
4、最后用一小段已知样例验证:样例里应同时包含代码块里的#号、带缩进的标题、Setext标题和分隔线,确认每一项的计数都符合预期,再用脚本跑真实文档。
把这三点处理好,统计结果才和渲染后的文档结构一致;否则数字看起来精确,实际上从第一步就数错了对象。
- 点赞
- 收藏
- 关注作者
评论(0)