资讯动态

Example 1 (compact list with code block)

发布时间:2026/9/19 22:20:00 来源:尧图企业网站定制
Example 1 (compact list with code block)【免费下载链接】prettierPrettier is an opinionated code formatter.项目地址: https://gitcode.com/gh_mirrors/pr/prettierSibling item beforeA bullet point with bare text (not in ap), followed by a code block that includes an empty lineconst foo bar; console.log(foo);Sibling item after要点 - 列表为“紧凑列表”compact list即列表项之间没有空行分隔 - 第二项中文字后面直接跟一个缩进 2 个空格的围栏代码块fenced code block - 代码块内部包含一个空行且代码块结尾的 之后没有多余空行 - 第三项是“Sibling item after”用于验证前置列表项的处理不影响后续兄弟项。 **Example 2嵌套紧凑列表 含空行的围栏代码块** markdown # Example 2 (compact nested list with code block) - Parent bullet point which is not wrapped in p - Sibling item before - Item containing a code block that includes an empty line javascript const foo bar; console.log(foo); - Sibling item after要点代码块位于二级嵌套列表项内缩进 4 个空格-前缀加 2 格缩进后再对齐代码块同样包含空行。Example 3对照用例不触发 bug 的形态# Example 3 (like example 2, but doesnt trigger the bug) - It works as expected - If the code block - Does not have a line break javascript const foo bar; console.log(foo); - It doesnt affect other items要点结构上与 Example 2 几乎一致唯一区别是代码块内部没有空行。它作为对照组用来证明只有“列表项内代码块包含空行”这一特定形态才是历史 bug 的触发条件。期望输出快照断言揭示了什么快照文件 format.test.js.snap 中记录了本用例输入与输出的完整对照。输出结果可归纳为以下几点列表项文字被按 80 列折行因proseWrap: always输入中的长句A bullet point with bare text (not in a \), followed by a code block that includes an empty line 被输出为- A bullet point with bare text (not in a \p\), followed by a code block that includes an empty line代码块整体结构与缩进保持不变三个示例中的围栏代码块其语言标记javascript、缩进级别、内部空行均原样保留没有被“压平”或重新排版。空行被保留代码块内部的空行Example 1、Example 2 中的空行在输出中依然存在Example 3 中代码块本无空行输出也保持无空行。兄弟列表项不受影响每个示例中“before/after”兄弟项的输出与输入一致说明代码块的处理没有污染同一列表中的其他项。也就是说该用例期望的格式结果是除段落文字按 proseWrap 折行外列表与代码块的结构、缩进和空行全部原样输出。这验证了 Prettier 对 Markdown 的格式化策略——代码块是“格式化边界”内部内容属于原样保留区域。源码佐证Prettier 如何实现这一行为1. 代码块走独立的打印路径在 src/language-markdown/print/code.js 中printCode()区分两种代码块function printCode(path, options) { const { node } path; if (node.isIndented) { // 缩进代码块固定 4 空格对齐内容原样输出 const alignment .repeat(4); return align(alignment, [ alignment, replaceEndOfLine(node.value, hardline), ]); } return printFencedCodeBlock(path, options); }围栏代码块fenced code block走printFencedCodeBlock()function printFencedCodeBlock(path, options) { const { node } path; const value ...node.value; const style printCodeFences(value, options); return [ style, node.lang || , node.meta ? node.meta : , hardline, replaceEndOfLine(value, hardline), hardline, style, ]; }关键点在于replaceEndOfLine(value, hardline)代码块的原始文本内容被原样输出其中原有的空行会转换成 doc 结构中的hardline从而在最终渲染时得到保留。这就是快照中“代码块内空行原样保留”的底层机制。而printCodeFences()则负责根据代码内容中连续反引号的个数动态决定围栏需要多少个反引号Math.max(3, 连续个数 1)避免围栏与内容冲突。2. 列表打印中的对齐与缩进处理在 src/language-markdown/print/list.js 的printListItem()中对列表项子节点的缩进处理是“分情况讨论”的processor({ node, isFirst }) { if ((isFirst node.type ! list) || node.type html) { return align( .repeat(prefix.length), print()); } if (node.type code node.isIndented) { return print(); } const alignment .repeat( clamp(options.tabWidth - listPrefix.length, 0, 3), // 4 will cause indented code block ); return [alignment, align(alignment, print())]; }这里有一处贯穿 Markdown 打印器的核心约束注释反复出现“4 will cause indented code block”缩进超过 4 个空格会让内容被解析成缩进代码块。因此 Prettier 在列表项内做对齐时额外缩进被clamp(..., 0, 3)限制在 3 个空格以内防止子内容被 CommonMark 解析器误判为代码块。对围栏代码块而言它并不是isIndented的缩进代码块因此走print()原样打印其结构代码块自身的缩进由外层align/doc 结构负责这与快照中代码块保持原缩进的表现一致。3. 代码块列表前缀的“安全间距”处理printList()中的getPrefix()和requiredIndent()还处理了另一种边界当列表项后跟缩进代码块时列表前缀必须有足够的缩进保证。requiredIndent()的计算逻辑为return ( 4 // base indent of the code block [...leadingSpaces].reduce( (count, char) count (char \t ? 4 : 1), 0, ) 1 // at least one space more than the code block );即列表前缀的缩进必须比后续缩进代码块至少多 1 个空格否则代码块会被错误地并入列表项。虽然 issue-10063 使用的是围栏代码块而非缩进代码块但这段代码展示了 Prettier 对“列表 代码块”组合的整体防御性设计。4. 更多相关测试列表与代码块的其他组合tests/format/markdown/list/codeblock.md验证带空行的围栏代码块位于列表项内的通用场景有序/无序列表、代码块内含多个空行tests/format/markdown/list/followed-by-indented-things.md覆盖列表后跟缩进代码块、引用的各种对齐形态同目录 parser-regression 下的其他用例则覆盖了有序列表超大编号issue-17778.md、tab 与空格混用issue-19146.md、issue-19152.md等解析器边界问题。这些测试共同构成了 Markdown 列表打印器的回归防线。如何运行与验证该用例在仓库根目录执行 Jest 即可运行全部 Markdown 格式测试并针对本用例进行验证# 运行 parser-regression 目录下的全部用例含 issue-10063 yarn jest tests/format/markdown/list/parser-regression # 更精确地只跑本用例对应的快照 yarn jest tests/format/markdown/list/parser-regression/format.test.js -t issue-10063若测试通过说明当前解析与打印逻辑与快照一致若失败可在 CI 中通过更新快照文件定位解析行为的变化。命令行方式亦可直接观察格式化结果# 用 proseWrap: always 格式化该用例文件并打印到终端 yarn prettier --parser markdown --prose-wrap always tests/format/markdown/list/parser-regression/issue-10063.md【免费下载链接】prettierPrettier is an opinionated code formatter.项目地址: https://gitcode.com/gh_mirrors/pr/prettier创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价