代码围栏里带后缀的反引号为什么不能结束代码块
我在维护单文件 Markdown 发布前检查器“文稿灯塔”时,给它输入了一段带代码示例的文章。代码块中有一行以三个反引号开头,后面紧跟 not-close。这行本来是代码内容,检查器却把它当成结束标记;真正的结束行反而被当成新代码块的开头,最后提示“代码围栏未闭合”。
一个能稳定复现的输入
下面用四个反引号展示测试文本,内层三反引号就是实际粘贴到检查器的内容:
# 标题
```js
```not-close
## 代码里的标题
```
## 正文小节
修复前,页面把这段文稿计为两个代码块,还在第 5 行提示围栏未闭合。问题出在扫描逻辑只检查一行的开头是否有三个以上反引号,没有区分“开头”和“结尾”的条件。
用闭合条件约束状态切换
CommonMark 0.31.2 规范的“Fenced code blocks”一节允许开头的围栏后跟语言等信息;关闭围栏后只允许空格或制表符,且围栏字符须与开头相同、数量不能更少。围栏前的缩进最多三个空格。因此,上例中三个反引号后紧跟 not-close 的那一行只是代码内容,不能关掉代码块。
我把扫描改成两步:先读开头至多三个空格、围栏字符及剩余文本;如果当前已在代码块内,只有字符、长度和行尾空白同时满足才退出。其他行一律作为代码内容跳过。若尚未进入代码块,则按开头规则判断;反引号围栏的信息字符串不能再含反引号。
关键判断是:
if (inFence) {
if (fence && fence[1][0] === fenceMark &&
fence[1].length >= fenceLength && /^[ \t]*$/.test(fence[2])) {
inFence = false;
}
continue;
}
这次只改围栏识别,没有动链接、图片和标题的规则。修复后,同一输入被计为一个代码块、两个正文标题、零条问题。另测了合法的尾随空格关闭行、四空格缩进的普通文本、真正未闭合的围栏,以及工具原有“载入示例”:原示例仍提示原有五项问题。测试是在本地 Edge 页面中输入并读取概览与问题列表完成的。
这个检查器仍然是轻量规则工具,并不声称完整实现 CommonMark。此次修复的是代码围栏状态提前切换这一处可复现问题;复杂容器块和其他 Markdown 方言还需要单独处理。
- 点赞
- 收藏
- 关注作者
评论(0)