代码围栏里带后缀的反引号为什么不能结束代码块

举报
yd_298688312 发表于 2026/11/03 10:05:07 2026/11/03
【摘要】 复现并修复 Markdown 检查器误将代码块中的 ```not-close 当成闭合围栏的问题。按 CommonMark 的闭合条件调整状态判断,并在 Edge 验证五组输入。

我在维护单文件 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 方言还需要单独处理。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。