Markdown 的优势是简单,劣势也是简单。写技术文章时,我经常需要「提示」「步骤」「对照代码」这些结构,而标准语法里没有。
解决方案不是换一个富文本编辑器,而是在 Markdown 解析管线上做扩展。
从文本到 HTML 的旅程
flowchart LR A[Markdown 源文件] --> B[remark 解析与转换] B --> C[rehype 生成 HTML 节点] C --> D[自定义组件节点] D --> E[Astro 渲染输出]
remark 负责理解 Markdown 结构,rehype 负责把结构变成 HTML。自定义语法就插在这两层之间:先识别作者写的指令,再把它转换成对应的组件节点。
一个容器语法长什么样
下面是本站提示框的写法:
:::tip[部署前检查]确认构建通过,再推送生产环境。:::渲染后就是带图标和强调色的提示块。它不需要在 frontmatter 里开启开关,也不需要额外配置——只要文章里出现这个语法,对应样式和运行时就会被收集。
扩展不是越多越好
每加一种语法,就多一份解析逻辑、一套样式和一组测试。真正需要控制的不是「支持多少种」,而是「哪些语法值得长期维护」。
| 语法 | 用途 | 运行时成本 |
|---|---|---|
| 提示框 | 强调注意事项 | 纯 CSS |
| 步骤流 | 教程与流程 | 纯 CSS |
| 选项卡 | 对照不同方案 | 少量客户端脚本 |
| Mermaid | 流程图与关系图 | 按需加载渲染器 |
| 代码树 | 展示多文件结构 | 纯 CSS + 少量交互 |
只在实际写作中反复用到的语法,才值得进入长期清单。
按需加载是怎么做到的
构建时会扫描文章内容,判断出现了哪些语法,再只把这些语法的样式和脚本注入当前页面。结果是:
- 一篇纯文字文章不会带上 Mermaid 渲染器;
- 没有选项卡的页面不会加载选项卡脚本;
- 语法清单集中在 manifest 里,新增语法时只需要登记一次。
// 页面只加载实际用到的语法资源const usedSyntaxes = detectSyntaxes(articleMarkdown);const assets = resolveAssets(usedSyntaxes, manifest);写作与渲染的分工
理想状态下,作者只需要关心「我想表达什么结构」,而不是「这个结构对应哪个 HTML 标签」。提示框、步骤、选项卡这些语法,本质上都是在降低表达成本。
如果语法失效了怎么办?
管线对非法输入保留原文,所以最坏情况是读者看到原始的 :::tip 文本,而不是整段内容消失。这比「渲染失败导致空白」安全得多。
小结
Markdown 扩展管线的价值,不是把文章变成网页应用,而是让文字拥有更清晰的层次。只要守住「按需加载」和「非法回退」两条底线,扩展就可以成为写作的助力,而不是维护负担。
本站技术手记
连载中分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 8 天
部分内容可能已过时