Biome Markdown 格式化器如何原样保留 fenced code block:以 mdn-background-4 测试用例为例

发布时间:2026/9/20 18:02:47
Biome Markdown 格式化器如何原样保留 fenced code block:以 mdn-background-4 测试用例为例 Biome Markdown 格式化器如何原样保留 fenced code block以 mdn-background-4 测试用例为例【免费下载链接】biomeA toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.项目地址: https://gitcode.com/gh_mirrors/bi/biome本篇文章以 Biome 仓库中的 Markdown 格式化测试用例 mdn-background-4.md 为切入点剖析 Biome 的 Markdown 格式化器biome_markdown_formatter对**代码围栏块fenced code block**的独特处理策略格式化器只负责规整 Markdown 语法层面的围栏与段落而对代码块内部的代码内容如 CSS逐字保留、不做任何重排。读完本文你将掌握该行为的源码级原理、测试验证方法以及如何通过 CLI 与配置文件实际体验与使用这一特性。一、测试用例全貌一段故意写乱的 CSS 代码块测试输入文件 mdn-background-4.md 全文如下注意其中的空白与缩进混乱.multi-bg-example { width: 100%; height: 400px; background-image: url(firefox.png), url(bubbles.png), linear-gradient(to right, rgb(30 75 115 / 100%), rgb(255 255 255 / 0%)); background-repeat: no-repeat, no-repeat, no-repeat; background-position: bottom right, left, right; }这段内容源自 MDN 文档中background多背景示例仓库中同目录还有mdn-background-1.md至mdn-background-9.md、mdn-filter-*.md、mdn-font-face-*.md等同系列用例均取自 MDN 文档的真实代码片段。它刻意包含多种不整洁特征开围栏后紧跟着两个空行同一行内width: 100%; height: 400px;用两个空格分隔两条声明background-image值跨两行第二行缩进 10 个空格background-repeat前有 4 个空格缩进background-position完全没有缩进其属性值却缩进 4 个空格属性值内部存在rgb(30\n 75 115 / 100%)这样的换行写法。二、期望输出输入即输出代码块内容被逐字保留与输入文件同名的期望快照 mdn-background-4.md.prettier-snap 中输出内容与输入逐字完全一致.multi-bg-example { width: 100%; height: 400px; background-image: url(firefox.png), url(bubbles.png), linear-gradient(to right, rgb(30 75 115 / 100%), rgb(255 255 255 / 0%)); background-repeat: no-repeat, no-repeat, no-repeat; background-position: bottom right, left, right; }也就是说上面列出的所有混乱——多余空行、多个连续空格、不统一的缩进、跨行属性值——全部被原样保留。这正是 Biome Markdown 格式化器与 CSS 格式化器的关键分工Biome 不会在格式化 Markdown 时顺手重排嵌入的代码因为 Markdown 格式化器的工作边界是 Markdown 语法本身而不是围栏内代码的语法。如果你希望这段 CSS 被重新格式化应单独对.css文件运行 Biome 的 CSS 格式化能力而不是指望 Markdown 格式化器代劳。三、源码原理格式化器只管围栏、不动内容上述行为可以在实现源码中得到直接印证核心实现位于 fenced_code_block.rs。3.1 围栏归一化依据 CommonMark §4.5 计算围栏长度格式化器对开围栏l_fence与闭围栏r_fence做的是长度归一化而非内容处理。其逻辑见 fenced_code_block.rs L26-L33为调用longest_fence_char_sequence(node, ) 扫描代码块内容找出其中最长的连续反引号序列长度围栏长度取max(最长内部序列 1, 3)即严格长于内容中任何同字符序列否则内部序列会被解析为闭围栏这正是 CommonMark 规范 §4.5 的要求用计算出的长度生成归一化围栏normalized_fence替换开/闭围栏。辅助函数longest_fence_char_sequencefenced_code_block.rs L137-L165遍历代码块内容节点对MdTextual与MdCodeContent的 token 逐字符统计连续反引号的最大长度。对mdn-background-4.md而言内容中没有反引号因此围栏长度保持 3 个反引号不变。3.2 内容输出仅作文本打印不做语法级格式化围栏之后的内容部分格式化器只做两类处理见 fenced_code_block.rs L64-L92若存在MdCodeContent节点则按行逐个打印仅配合opening_fence_indent处理缩进上下文否则按TextPrintMode列表内用Fill普通场景用Clean输出文本。无论哪种路径内容 token 的文本本身都不会被裁剪、合并空格或重排——mdn-background-4.md中空行、多个空格、混合缩进因此得以逐字保留。此外开围栏前的缩进 token 与闭围栏前的缩进 token 会被移除并标记为已检查的抑制mark_suppression_checked说明格式化器会规整的是围栏块外围的缩进而不是块内的代码。3.3 其他 Markdown 节点同样语法化处理从 lib.rs 的模块划分bullet_list、gfm、markdown/auxiliary下的inline_code、indent_code_block、fenced_code_block等可以看出Biome 对 Markdown 的格式化是基于biome_markdown_syntax解析出的 AST 逐节点执行的标题、列表、引用块、表格等 Markdown 语法元素会被规整而代码围栏块是语法外壳被规整、内部代码被原样保留的特殊节点。四、测试验证prettier 兼容快照机制这个用例归属于 Biome 为 Markdown 格式化器搭建的prettier 兼容测试套件保证输出行为与 prettier 对齐。4.1 测试入口与快照机制prettier_tests.rs 中通过宏声明tests_macros::gen_tests! {tests/specs/prettier/markdown/**/*.{md}, crate::test_snapshot, }即遍历tests/specs/prettier/markdown/下所有.md文件含code/mdn-background-4.md每个输入文件配合一个*.prettier-snap期望文件进行快照比对。测试中使用的格式化选项为IndentStyle::Space 默认IndentWidth2 空格语言上下文为 GFMlanguage::MarkdownTestFormatLanguage::gfm()解析器开启 GFM 扩展见 language.rs 中parse_markdown_with_cache与MarkdownParserOptions::default().with_gfm(true)的调用。4.2 与 prettier 的对齐目标PrettierSnapshot的意义在于prettier 对 Markdown 中 fenced code block 的处理同样是保留内部内容因此这份快照同时约束了两点——Biome 的输出与 prettier 一致且不会随着格式化器的演化而意外开始重排代码块内容。同目录下mdn-background-1.md至mdn-background-9.md、mdn-grid-auto-columns.md、mdn-transform.md等大量mdn-*用例共同构成了对 MDN 真实代码片段的行为回归测试。4.3 另一套 specs 测试除 prettier 兼容套件外仓库还维护了 spec_tests.rs 定义的tests/specs/markdown/**/*.md常规规格测试通过 spec_test.rs 中显式启用的markdown.formatter.enabled配置运行验证在真实配置解析路径下的格式化结果。五、相关配置proseWrap 与代码块的关系mdn-background-4.md这类用例还牵出一个配置要点Markdown 格式化器的段落换行策略proseWrap不会影响代码块内部。在 context.rs 中MdFormatOptions包含indent_style、indent_width、line_ending、line_width、trailing_newline、prose_wrap六项context.rs L19-L27其中ProseWrap枚举context.rs L33-L71定义为取值语义preserve默认按源文件保留段落中的换行always按配置的lineWidth对段落重新换行never移除段落换行使每个段落位于一行其文档注释明确写着Manual line breaks are always kept且所有换行策略都作用于段落paragraph与代码围栏块的内容无关——代码块内的换行与空格始终原样保留。这与本文用例展示的行为互相印证。六、实战验证如何亲自观察这一行为你可以在本地仓库中实际复现该测试验证输入即输出# 运行 prettier 兼容测试套件mdn-background-4 用例即在其内 cargo test -p biome_markdown_formatter --test prettier_tests # 运行常规规格测试 cargo test -p biome_markdown_formatter --test spec_tests若在项目中使用 CLI 格式化 Markdown也可以直接构造一个包含类似混乱 CSS 代码块的.md文件然后执行biome format --write path/to/file.md观察输出即可发现标题、列表等 Markdown 语法会被规整而 css 围栏内部的全部内容保持逐字不变。若你确实需要规整围栏内的 CSS则应将其抽出为独立.css文件交给 Biome 的 CSS 格式化器处理——这正体现了 Biome 一门语言一套格式化器、职责互不越界的设计。七、小结通过mdn-background-4.md这一个测试用例可以清晰看到 Biome Markdown 格式化器三条可验证的行为准则围栏归格式化器管开闭围栏会按 CommonMark §4.5 归一化长度防止内容中的反引号序列被误判为闭围栏内容归作者管围栏内的代码以文本形式逐字输出空行、多空格、混合缩进全部保留与 prettier 行为对齐配置有边界proseWrap、lineWidth等段落级选项不会渗透进代码块。这些行为全部有测试快照锁定mdn-background-4.md.prettier-snap与源码实现佐证fenced_code_block.rs对任何希望在文档中嵌入不可被格式化器破坏的代码片段的开发者而言都是值得依赖的稳定契约。【免费下载链接】biomeA toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.项目地址: https://gitcode.com/gh_mirrors/bi/biome创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询