ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

TOP004 课程标题结构规范:curriculum 仓库如何用 markdownlint 强制统一课程文档骨架

2026/9/15 21:38:44 拓冰建站 浏览量
TOP004 课程标题结构规范:curriculum 仓库如何用 markdownlint 强制统一课程文档骨架 TOP004 课程标题结构规范curriculum 仓库如何用 markdownlint 强制统一课程文档骨架【免费下载链接】curriculumThe open curriculum for learning web development项目地址: https://gitcode.com/GitHub_Trending/cu/curriculum本篇技术指南围绕cu/curriculum仓库中 markdownlint 自定义规则TOP004lesson-headings展开以该规则的一组测试样例文档如 valid_no_additional_resources.md为切入点系统讲解课程、项目、指南三类文档必须遵循的标题结构模板、通配符语义、例外文件清单以及规则在 TOP004_lessonHeadings.js 中的逐段匹配实现。读完本文你将掌握在该开源课程仓库中编写任意新课程文档时标题怎么排、哪些小节必填、Additional resources 何时该省略的完整规范并能独立读懂 TOP004 的测试与报错信息。一、背景为什么需要强制标题结构cu/curriculum是一个用于学习 Web 开发的开源课程仓库其根目录 package.json 中声明了三个脚本lintmarkdownlint-cli2、fix自动修复与testnode 原生测试。全部课程文档以 Markdown 编写分布在foundations/、javascript/、ruby/、react/、ruby_on_rails/等目录下文档类型包括课程lesson、项目project与指南guide。当课程数量达到数百篇时如果没有统一规范各文档会出现标题层级混乱、必备小节缺失、Additional resources 空置等问题。TOP004 规则的官方说明 markdownlint/docs/TOP004.md 明确给出了其设计动机强制一致的标题结构可以提高可读性、组织性与导航性。通过规定必需的标题结构作者可以确保文档遵循标准化格式包含所有必要的小节从而方便读者定位具体信息。因此 TOP004 的定位是基于上下文不可自动修复的结构校验规则TOP004.md 中标注 Not fixable due to being context-based它只负责报错不负责改错——标题语义只能由作者人工判断。二、三种文档类型的三套标题模板规则实现 TOP004_lessonHeadings.js 中定义了三套命名常量分别对应课程、项目、指南const HEADINGS { lesson: [ ### Introduction, ### Lesson overview, *, ### Assignment, *, ### Knowledge check, ?, ], project: [### Introduction, *, ### Assignment, *], guide: [### Guide: *, *], };选择哪一套模板取决于目标文件的文件名与所在路径TOP004_lessonHeadings.js文件名以project_开头 → 使用project模板注意projections.md这类以project开头的普通词汇不会被误判路径中包含_guides/目录段 → 使用guide模板其余全部 → 使用lesson模板。2.1 课程lesson模板五段必填 一段可选依据 TOP004.md 的官方说明课程文档的标题骨架为### Introduction ### Lesson overview ### A custom heading * (Wildcard: Any heading at any level) ### Assignment * (Wildcard: Any heading at any level) ### Knowledge check ### Additional resources (optional)逐项解读### Introduction课程开场交代本课目标与背景### Lesson overview课程总览通常以列表形式给出本课将学到的知识点第一个*允许出现任意数量、任意层级的自定义小节标题如### Custom section、#### Subsection只要位置在 Lesson overview 与 Assignment 之间即可### Assignment作业区规定必须用div classlesson-content__panel markdown1包裹正文第二个*Assignment 之后、Knowledge check 之前同样允许任意自定义标题如#### Extra credit### Knowledge check知识自测区?可选的### Additional resources——只有当确有资源时该小节才应存在若为空则整节不得出现。在代码中模板末尾的?被注释为 Allow single wildcard headingTOP004_lessonHeadings.js当匹配到?时直接放行即该位置之后是否还有标题都不再追究。2.2 项目project模板两段必填 两处通配### Introduction * (Wildcard: Any heading at any level) ### Assignment * (Wildcard: Any heading at any level)项目文档没有 Lesson overview 与 Knowledge check因为项目的重点是从头实现一个完整应用。### Assignment同样是必填的且按惯例同样以lesson-content__panel包裹。仓库中 project_valid.md 展示了合法项目文档的写法——在 Assignment 的 panel 内还可以嵌套#### Extra credit子节。2.3 指南guide模板首标题必须带前缀### Guide: * (Any descriptive title) * (Wildcard: Any heading at any level)位于*_guides/目录例如foundations/installations/installation_guides/、nodeJS/express/installation_guides/下的参考文档自动使用 guide 模板第一个标题必须以### Guide:开头后接任意描述性标题此后任意标题结构均合法。合法样例见 guide_valid.md首行### Guide: Virtual Machine installation其后自由展开### Step 1、#### Step 1.1等若首标题写成### Installation Guide之类的其他形式会被报错Expected: heading starting with ### Guide: ; Actual: ### Installation Guide。三、通配符*的精确语义三套模板中都出现了*其行为由两个正则决定TOP004_lessonHeadings.js// 匹配整体通配项如模板中的 * const wildcardRegex new RegExp(/^(#*\s)?\*$/); // 匹配前缀通配项如模板中的 ### Guide: * const prefixWildcardRegex new RegExp(/^(###\s)(.):\s\*$/);wildcardRegex对应任意标题文本、任意标题级别prefixWildcardRegex则要求### 前缀:之后跟任意描述。匹配逻辑的关键在 TOP004_lessonHeadings.js当期望值是通配符时规则进入matchAny状态——随后的每一个标题都会被消费直到命中下一个具体期望标题如### Assignment为止若一直未命中则通过i--让游标回退继续消费更多标题。这意味着通配区域可以有零个、一个或多个标题通配区域内的标题级别不限##、####均可模板中的具体标题Introduction、Assignment、Knowledge check必须逐字逐级匹配区分大小写例如把### Introduction写成## Introduction或### introduction都会报错。forEachHeading辅助函数TOP004_lessonHeadings.js遍历 markdown-it 解析出的 token 流在每个heading_open与inline配对处取出标题文本与行号从而获得第几行出现哪个级别的什么标题这一完整信息供逐段比对使用。四、本篇主角无 Additional resources 的合法课程文档valid_no_additional_resources.md 是 TOP004 的合法测试样例之一它完整展示了没有附加资源时课程文档的标准骨架### Introduction # 必填 ### Lesson overview # 必填总览 LO 列表 ### Custom section # 通配区任意自定义小节 ### Assignment # 必填且正文须包在 panel div 中 #### Assignment subsection # 通配区panel 内可嵌套子节 ### Knowledge check # 必填自测问题列表几个值得注意的细节标题均为###H3级别——课程文档不使用#/##作为章节标题整篇文档以小节为单位平铺Assignment 内容被div classlesson-content__panel markdown1包裹valid_no_additional_resources.mdmarkdown1确保 div 内的 Markdown 语法仍被解析这一约定在该规则的其他样例如 valid_with_additional_resources.md中保持一致文件末尾没有 Additional resources 小节——这正是本样例与 valid_with_additional_resources.md 的唯一结构差异后者在 Knowledge check 之后补上了### Additional resources及- AR item列表。两份文件都通过 TOP004 校验说明 Additional resources 是可选节其取舍依据是内容而非格式Knowledge check 的引导语是固定文案The following questions are an opportunity to reflect on key topics in this lesson...配合- KC item列表形成规范的自测区形态。五、错误路径哪些写法会被 TOP004 拦截规则与测试共同勾勒出三条典型的失败路径便于在编写文档时反向规避。5.1 必填小节缺失missing_heading.md 在 Introduction 之后直接写了### Custom section跳过了### Lesson overview。测试 TOP004.test.js 断言其报错为path:5 error TOP004/lesson-headings Required heading structure [Expected: ### Lesson overview; Actual: ### Custom section]即期望下一个标题是### Lesson overview实际遇到的是### Custom section。这是逐段比对在第一个失配点立即停止的结果。5.2 文件末尾缺少关键小节project_invalid.md 只有 Introduction 和两个自定义小节始终没有出现### Assignment。规则在文件读完后的收尾校验阶段TOP004_lessonHeadings.js计算missingExpectedHeadingCount requiredHeadings.length - i发现游标停留在### Assignment上于是报出[Missing heading (case sensitive): ### Assignment] [Context: ### Assignment]注意这里的判断条件missingExpectedHeadingCount 1 || isLastRequiredHeadingSpecific隐含了一个行为如果文档在 Assignment 的期望位置之前就结束且剩余缺失的恰好只有通配项例如只缺末尾的*规则并不会报错——因为通配项允许零个标题。因此对于 lesson 模板### Knowledge check是必须的它是具体标题且是最后一个必填项而### Additional resources缺失完全合法。5.3 匹配到第一个错误即停止实现中hasError标志TOP004_lessonHeadings.js确保规则只报告每个文件的第一处结构错误。注释给出了原因一处标题错位如多写、漏写一个标题会连带导致后续所有标题整体错位产生噪声式报错。因此调试时应优先修复第一条 TOP004 错误再重新 lint。5.4 例外文件完全不校验TOP004_lessonHeadings.js 硬编码了五个豁免文件名const exceptedLessons [ how_this_course_will_work.md, conclusion.md, conclusion_full_stack_javascript.md, conclusion_ruby_on_rails.md, actioncable_lesson.md, ];这些文件对应课程开篇说明How This Course Will Work、课程结语Conclusion以及特殊专题ActionCable其内容形态不适合套用统一标题骨架。判断逻辑在 TOP004_lessonHeadings.jsif (exceptedLessons.includes(fileName)) return;直接跳过。测试 TOP004.test.js 用 conclusion.md 与 how_this_course_will_work.md 验证了豁免生效。六、测试与运行方式规则如何被验证6.1 测试组织TOP004 的测试位于 TOP004_lessonHeadings/tests/TOP004.test.js使用 Node 内置的node:test与node:assert/strict不需要额外测试框架。测试共覆盖五个维度规则元数据names为[TOP004, lesson-headings]、description为Required heading structure、information指向官方文档地址TOP004.test.js合法课程文档带/不带 Additional resources 两份均不报错非法课程文档missing_heading 精确报错项目文档project_invalid 报缺失 Assignmentproject_valid 不报错例外文档与指南文档conclusion / how_this_course_will_work 豁免guide_invalid 报前缀错误guide_valid 放行。6.2 测试如何驱动真实 lint测试工具 lint.js 并不直接调用规则函数而是通过子进程真实执行npm run lint -- file即markdownlint-cli2然后解析 stderr 输出退出码为 0 → 返回空数组无错误退出码非 0 → 将 stderr 按行拆分作为错误列表。这意味着每条测试断言都是对完整 markdownlint 管道的端到端验证而非对单个函数的单元测试从而保证规则在真实 lint 环境中的行为与断言一致。6.3 本地复现与运行在仓库根目录可执行# 对单个测试文件运行 lint观察 TOP004 是否报错 npm run lint -- markdownlint/TOP004_lessonHeadings/tests/valid_no_additional_resources.md npm run lint -- markdownlint/TOP004_lessonHeadings/tests/missing_heading.md # 运行全部 markdownlint 规则的测试含 TOP004 npm test对valid_no_additional_resources.md执行 lint 不会产生任何 TOP004 报错对missing_heading.md执行则会得到与测试断言一致的[Expected: ### Lesson overview; Actual: ### Custom section]输出。需要说明的是运行前提是仓库已安装依赖npm install依赖清单见 package.json 中的markdownlint-cli2。七、编写课程文档的实操清单综合上述规范在cu/curriculum仓库中新增一篇课程文档时可按以下清单自检以最常见的 lesson 类型为例标题全部使用###级别第一个小节必须是### Introduction第二个小节必须是### Lesson overview其后以- LO item.列表给出学习目标在总览与作业之间可自由添加任意数量的自定义小节任意标题级别必须出现### Assignment且内容包裹于div classlesson-content__panel markdown1内panel 中允许嵌套####子节作业之后必须出现### Knowledge check搭配固定引导语与- KC item列表### Additional resources仅在确有补充链接时保留否则整节省略模板中它为可选?避免把文件命名为how_this_course_will_work.md、conclusion.md等豁免清单之外的敏感名——这些名字会跳过校验属于刻意为之的例外若文件位于_guides/目录首标题必须写成### Guide: 描述性标题的形式若文件名以project_开头只需### Introduction 自定义小节 ### Assignment 自定义小节无需 Lesson overview 与 Knowledge check。遵循这份骨架既能让读者在任意课程文档中获得一致的信息查找路径Introduction → 总览 → 正文 → 作业 → 自测也能让 TOP004 在持续集成中保持零告警。【免费下载链接】curriculumThe open curriculum for learning web development项目地址: https://gitcode.com/GitHub_Trending/cu/curriculum创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考