ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Biome 的 useTopLevelHeading 规则:强制 Markdown 文档以一级标题开头(nursery 组)

Biome 的 useTopLevelHeading 规则:强制 Markdown 文档以一级标题开头(nursery 组) Biome 的 useTopLevelHeading 规则强制 Markdown 文档以一级标题开头nursery 组【免费下载链接】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导读useTopLevelHeading是 Biome 为 Markdown 提供的一条 lint 规则当前位于nursery组版本门槛 2.5.8它要求每个 Markdown 文档的第一个块级元素必须是一级标题h1无论是 ATX 语法# Heading还是 setext 语法Heading后跟。本文以仓库中的官方测试用例为骨架从规则行为、判定逻辑、测试矩阵到配置启用方式做一次完整拆解读完你将能精确理解该规则在哪些场景触发诊断、哪些场景被放行并掌握在biome.json中启用它的正确姿势。一、从一条测试用例说起文档第一块是段落会怎样仓库中用于验证文档以普通段落开头这一非法场景的测试输入位于 paragraph.md全文如下!-- should generate diagnostics -- Some text # Top-level heading这个文件的第一个非空块是普通段落Some text虽然后面出现了# Top-level heading但因为它不在文档开头useTopLevelHeading依然会报错。对应的快照 paragraph.md.snap 记录了完整诊断输出paragraph.md:2:1 lint/nursery/useTopLevelHeading i Missing top-level heading. 1 │ !-- should generate diagnostics -- 2 │ Some text │ ^^^^^^^^^ 3 │ 4 │ # Top-level heading i The document should start with a top-level heading (h1) so readers and tools can identify its title. Add a # Heading (or a level-1 setext heading) at the start of the document.诊断定位在2:1段落的起始位置错误消息为Missing top-level heading.并附带修复建议在文档开头添加# Heading或一级 setext 标题。二、规则声明与出处对齐 markdownlint 的 md041规则的完整定义位于 use_top_level_heading.rs其声明信息如下pub UseTopLevelHeading { version: 2.5.8, name: useTopLevelHeading, language: md, recommended: false, sources: [RuleSource::MarkdownLint(md041, first-line-heading).same()], }几个关键点recommended: false该规则默认不随推荐组启用需要用户显式配置。language: md规则只作用于 Markdown 文件。sources规则语义对齐 markdownlint 的md041 / first-line-heading规则采用同一语义.same()而非等效标注便于用户从其他工具迁移时理解行为一致性。nursery组规则尚未稳定接口与行为在未来可能调整。从 rules.rs 可以看到nursery作为独立配置组存在于 linter 配置结构中。三、判定逻辑源码级拆解什么算合格的第一块规则的核心逻辑在run方法中查询类型为AstMdRoot即整个文档的语法树根节点。算法分三步1. 找到第一个不可忽略的块let first_block root .value() .iter() .find(|block| !is_ignorable_leading_block(block))?;is_ignorable_leading_block会跳过三类前置内容HTML 注释块含段落形式的!-- ... --注释见is_html_comment_block换行块block.is_newline()延续缩进块block.is_continuation_indent()。这就是为什么测试输入paragraph.md中第一行!-- should generate diagnostics --被忽略真正的判定对象是后面的段落。2. 按首块类型分类处理match first_block { AnyMdBlock::AnyMdLeafBlock(AnyMdLeafBlock::MdHeader(header)) { if header.level() 1 { None } else { Some(header.range()) } } AnyMdBlock::AnyMdLeafBlock(AnyMdLeafBlock::MdSetextHeader(header)) { if header.is_level_1() { None } else { Some(header.range()) } } AnyMdBlock::AnyMdLeafBlock( AnyMdLeafBlock::MdThematicBreakBlock(_) | AnyMdLeafBlock::MdHtmlBlock(_), ) None, _ Some(first_block.range()), }分四种情况首块类型判定结果ATX 标题MdHeader且 level 1通过不报错ATX 标题但 level 1报错定位到该标题setext 标题MdSetextHeader且为一级通过不报错setext 标题但非一级报错主题分隔线MdThematicBreakBlock放行HTML 块MdHtmlBlock放行其他任何块段落、列表、引用等报错定位到该块3. 生成诊断诊断统一为Missing top-level heading.并附一条 note 解释原因与修法添加# Heading或一级 setext 标题。需要特别强调的是HTML 块和主题分隔线被明确放行。规则文档注释给出的理由是一些项目尤其是 README会用 HTML 标记来书写标题因此 HTML 块开头的文档不报错同时规则文档还给出以 YAML front matter 开头的合法示例。这两类放行都体现在测试套件中。四、测试矩阵valid 与 invalid 全量对照仓库通过一组规格化测试覆盖规则的全部行为测试位于 useTopLevelHeading 测试目录分为valid/不应产生诊断与invalid/应产生诊断两类valid以下文档均不应触发诊断测试文件文档开头形态放行原因heading-1.md# Top-level heading首块即 ATX 一级标题setext-heading-1.mdTop-level heading首块即 setext 一级标题html.mddivHTML content/div后跟## Second level heading首块是 HTML 块被放行yaml.md---front matter 后跟## Second level headingfront matter 可视为文件前置信息放行其中 yaml.md 的内容是--- path: /post date: 2012-06-21T10:14:00.00002:00 title: First level heading --- ## Second level heading这说明文档从 YAML front matter 开始是允许的——这是博客、文档站等场景的常见写法。invalid以下文档均应触发诊断测试文件文档开头形态触发原因paragraph.md普通段落Some text后跟# Top-level heading首块是段落heading-2.md## Second level heading首块是二级 ATX 标题setext-heading-2.mdSecond level heading----首块是二级 setext 标题这些用例覆盖了非一级标题ATX 与 setext 两种写法以及非标题块段落两类非法形态与规则源码中的match分支一一对应。所有测试均由 spec_tests.rs 驱动执行快照文件与输入文件成对出现用于锁定诊断输出。五、选项与配置如何在项目中启用规则接受空的选项类型UseTopLevelHeadingOptions见 use_top_level_heading.rs 选项定义即当前不提供任何可调参数行为是固定的。要启用它需要显式配置nursery组。在项目的biome.json中{ linter: { enabled: true, rules: { nursery: { useTopLevelHeading: warn } } } }nursery组的规则均可通过SeverityOrGroup配置为error/warn/info/off或按规则粒度单独覆盖具体解析逻辑见 rules.rs。由于该规则recommended: false即使开启了推荐规则集也不会自动生效必须如上显式声明。启用后执行biome lint或针对单个文件biome lint README.md即可看到形如快照中的Missing top-level heading.诊断。六、为什么需要这条规则文档结构与可读性收益从规则自带的 note 可以看出设计动机文档应以一级标题h1开头以便读者与工具识别其标题。具体收益包括文档导航与目录生成渲染器GitHub、文档站依据首个 h1 生成页面标题缺失时标题会退化为文件名或为空工具链一致性与 markdownlintmd041对齐后从 ESLint markdownlint 迁移到 Biome 的团队可保持相同规范强制内容结构以标题开头的文档强制作者先给出主题避免无题文档。同时规则对 README 场景做了务实让步——HTML 块如div包裹的标题、主题分隔线、YAML front matter 均不触发诊断避免误伤常见工程实践。七、注意事项与稳定性说明nursery 稳定性规则仍处于nursery阶段未来可能调整判定边界或默认行为升级 Biome 后应关注 CHANGELOG 中对该规则的变更记录HTML 放行是整体性的只要首块是 HTML 块无论内容是否真的是标题都不会报错从 html.md 可见注释放行开头的 HTML 注释文件级 preamble 注释会被跳过不会因注释在前而误报这在 paragraph.md 与 heading-1.md 中均有体现空文档不报错若文档没有任何块find返回Nonerun直接返回None不产生诊断。延伸阅读规则完整实现use_top_level_heading.rs全部测试用例useTopLevelHeading 测试目录诊断快照示例paragraph.md.snap测试驱动入口spec_tests.rslinter 配置结构nursery 组解析rules.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),仅供参考
返回列表