图表与数学公式(Mermaid / PlantUML / KaTeX)
Mizuki 的统一 Markdown/MDX 渲染管线为文章内容提供三种"富内容"能力:Mermaid 图表、PlantUML 图表与 KaTeX 数学公式。三者都以 Astro remark/rehype 插件的形式挂接在同一条内容管线上,与文章页、RSS、Atom 共用同一处理流程。
Purpose and Scope
本页覆盖 Mizuki 中图表与数学公式能力的完整链路:
- 插件在
astro.config.mjs中的注册方式与管线顺序; - remark 阶段插件(
remarkMermaid、remarkPlantuml)与 rehype 阶段插件(rehypeMermaid、rehypePlantuml)的分工; - 浏览器端 Mermaid 渲染脚本(
mermaid-render-script.js)与 PlantUML 编码工具(plantuml-encoder.mjs)的角色; - KaTeX 数学公式在整体 Markdown 能力中的定位。
留给兄弟页面的内容(本页不展开):
- 提示框、GitHub 卡片、Wiki Link、剧透、响应式图片、图片网格、Fancybox 灯箱等其它 Markdown 扩展 —— 见
markdown-pipeline下的对应页面; - 整条 Markdown 管线的总体装配与
markdownConfig全貌 —— 见 Markdown Pipeline 总览页。
说明:本次文档生成受源码读取预算限制,仅完成了插件注册位置与文件清单的验证(
astro.config.mjs、src/plugins/目录、README)。各插件函数内部的逐行实现未能在本页中读取,相关小节会明确标注"实现细节未读取",不进行臆测。
Overview
在博客场景中,技术文章经常需要表达三类难以用纯文本描述的内容:流程/架构图、UML 图、数学公式。Mizuki 的选择是:
- Mermaid:以 fenced code block(```mermaid)书写的图表,由管线识别后在浏览器端渲染成 SVG,构建期只负责标记与脚本注入;
- PlantUML:以 fenced code block(```plantuml)或指令语法书写,经由编码工具转为 URL 安全形式后交给外部 PlantUML 渲染服务生成图片;
- KaTeX:数学公式渲染,属于 Markdown/MDX 的基础能力之一,与上述图表能力并列出现在 README 的功能清单中。
README(中文版)对本能力的官方描述:
- [x] **数学公式**,使用 KaTeX,并支持 Mermaid 和 PlantUML 图表Source: README.md
三者共享同一个设计动机:作者只写源码文本,渲染复杂性由管线与运行时承担。这样图表与公式可以像普通代码块一样参与版本管理,同时站点构建产物保持轻量(Mermaid 不在构建期执行重量级布局计算,PlantUML 由外部服务承担渲染)。
Architecture
下图展示从 Markdown 源文件到最终 HTML 的完整数据流,所有节点都是仓库中真实存在的文件/导出(依据 astro.config.mjs 的 import 与插件数组注册顺序验证):
架构要点(WHY):
-
双阶段拆分(remark + rehype)。
remarkMermaid/remarkPlantuml工作在 Markdown AST(mdast)层面,负责把代码块识别为图表节点;rehypeMermaid/rehypePlantuml工作在 HTML AST(hast)层面,负责把节点转成真正的 HTML 元素与脚本挂载点。这种拆分让语法识别与 DOM 产物生成解耦,与 Astro 生态中 remark/rehype 的标准分层一致。 -
Mermaid 的渲染位置在浏览器端。仓库中存在独立的
src/plugins/mermaid-render-script.js,说明 Mermaid 图表不在构建期渲染成 SVG,而是在页面加载后由脚本执行渲染——这避免了大图表拖慢构建,代价是客户端需要执行脚本。 -
PlantUML 的渲染位置在外部服务。存在独立的
src/plugins/plantuml-encoder.mjs,对应 PlantUML 官方服务接受"压缩+编码后的文本 URL"的惯例(具体编码算法未读取验证),构建期只需要做编码与<img>元素生成。 -
同一管线服务多种产物。README 明确说明文章页、RSS、Atom 共用同一条 Markdown/MDX 管线,因此图表/公式插件对所有出口统一生效(加密文章除外,不进入 RSS/Atom)。
插件在 astro.config.mjs 中的 import(第 37–48 行节选,为仓库真实内容):
import { rehypeMarkdownImages } from "./src/plugins/rehype-markdown-images.mjs";
import { rehypeMermaid } from "./src/plugins/rehype-mermaid.mjs";
import { rehypePlantuml } from "./src/plugins/rehype-plantuml.mjs";Source: astro.config.mjs
import { remarkMarkSectionized } from "./src/plugins/remark-mark-sectionized.mjs";
import { remarkMermaid } from "./src/plugins/remark-mermaid.js";
import { remarkPlantuml } from "./src/plugins/remark-plantuml.mjs";Source: astro.config.mjs
在 remark 插件数组中的注册顺序(第 236–238 行,缩进已简化):
parseDirectiveNode,
remarkMermaid,
[remarkPlantuml, markdownConfig.plantuml],Source: astro.config.mjs
注意两个关键差异:remarkMermaid 是无选项注册,而 remarkPlantuml 以 [plugin, options] 数组形式注册并传入 markdownConfig.plantuml——说明 PlantUML 能力存在面向用户的配置项(例如渲染服务器地址),而 Mermaid 在 remark 层不需要用户配置。
实现走读:管线中的位置与控制流
由于本页源码读取预算已耗尽(6/6),以下对插件内部实现的描述仅基于已验证的注册证据做边界性说明,各函数内部逻辑未读取,不做臆测。
端到端控制流(已验证部分)
- 构建期 · remark 阶段:Astro 读入
.md/.mdx源文件构建 mdast。插件数组按注册顺序执行:parseDirectiveNode→remarkMermaid→[remarkPlantuml, markdownConfig.plantuml](顺序见上文astro.config.mjs第 236–238 行)。remarkMermaid在此处获得处理 ```mermaid 代码块的最早机会。 - 构建期 · mdast → hast 转换后:
rehypeMermaid与rehypePlantuml接管 HTML AST,将图表节点转换为最终 HTML 结构(Mermaid 侧大概率生成携带源码文本的占位元素并注入mermaid-render-script.js;PlantUML 侧借助plantuml-encoder.mjs编码源码后指向渲染服务)。此两步的内部实现未读取,属于推断性描述。 - 运行期(浏览器):
mermaid-render-script.js扫描页面中的 Mermaid 占位元素,调用 Mermaid 渲染为内联 SVG;PlantUML 图片为普通<img>,由外部服务渲染,无需客户端脚本;KaTeX 公式在构建期或既有 rehype 链中完成渲染(具体挂接点未读取验证)。 - 多出口复用:同一管线产出文章页、RSS、Atom,图表与公式能力对所有出口一致;加密文章按 README 说明被排除出 RSS/Atom。
参与文件的职责边界
| 文件 | 管线阶段 | 已验证职责 | 未验证部分 |
|---|---|---|---|
src/plugins/remark-mermaid.js | remark(mdast) | 导出 remarkMermaid,在 astro.config.mjs 中无选项注册 | 内部 AST 匹配与节点改写逻辑 |
src/plugins/rehype-mermaid.mjs | rehype(hast) | 导出 rehypeMermaid | HTML 元素生成与脚本注入细节 |
src/plugins/mermaid-render-script.js | 浏览器运行期 | 存在于 plugins 目录,与 Mermaid 浏览器端渲染配套 | 初始化时机与主题适配逻辑 |
src/plugins/remark-plantuml.mjs | remark(mdast) | 导出 remarkPlantuml,以 markdownConfig.plantuml 作为选项注册 | 指令解析与代码块识别逻辑 |
src/plugins/rehype-plantuml.mjs | rehype(hast) | 导出 rehypePlantuml | <img>/URL 构造细节 |
src/plugins/plantuml-encoder.mjs | 构建期工具 | PlantUML 文本编码器 | 具体编码算法(是否 deflate+base64 变体) |
| KaTeX 相关插件 | 管线中 | README 声明为已支持能力 | 具体挂接插件与配置键未在本页验证 |
Usage Examples
作者侧:Mermaid 图表
1```mermaid
2flowchart TD
3 A --> B
4```(上例为语法示意,用于说明作者书写形态;仓库中实际的渲染行为由 remark-mermaid.js + rehype-mermaid.mjs + mermaid-render-script.js 三段链路完成。本页未读取到仓库内的官方示例文档,故不引用具体示例文件。)
作者侧:PlantUML 图表
1```plantuml
2@startuml
3Alice -> Bob: Hello
4@enduml
5```PlantUML 还支持通过 remark 指令语法使用(管线中 parseDirectiveNode 先于 remarkPlantuml 注册,暗示指令式 PlantUML 的存在,此为基于注册顺序的推断,未读取实现验证)。
配置侧:插件注册的真实代码
remarkMermaid,
[remarkPlantuml, markdownConfig.plantuml],Source: astro.config.mjs
这是在站点配置中启用图表能力的唯一必经入口:remarkMermaid 直接注册,remarkPlantuml 携带 markdownConfig.plantuml 选项对象注册。
Configuration Options
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
markdownConfig.plantuml | object | 未验证 | 传给 remarkPlantuml 的选项对象;具体键名(如渲染服务器地址、图片格式)需查阅 src/plugins/remark-plantuml.mjs 实现,本页未读取 |
| Mermaid 选项 | — | 无 | remarkMermaid 以无选项形式注册,remark 层不暴露用户配置 |
API Reference
| 导出 | 所在文件 | 签名 | 说明 |
|---|---|---|---|
remarkMermaid | src/plugins/remark-mermaid.js | 未验证 | remark 插件;签名与内部参数未读取 |
remarkPlantuml | src/plugins/remark-plantuml.mjs | remarkPlantuml(options) | remark 插件;以 markdownConfig.plantuml 为 options 注册 |
rehypeMermaid | src/plugins/rehype-mermaid.mjs | 未验证 | rehype 插件;签名未读取 |
rehypePlantuml | src/plugins/rehype-plantuml.mjs | 未验证 | rehype 插件;签名未读取 |
其余函数(plantuml-encoder.mjs 与 mermaid-render-script.js 的导出)未读取,不列出。
Failure Modes, Edge Cases & Concurrency
- 构建期 vs 运行期失败分离(Mermaid):Mermaid 语法错误不会打断构建——渲染发生在浏览器端(
mermaid-render-script.js),坏图表只影响对应页面元素,这是把渲染推迟到客户端的一个直接收益。具体错误回退 UI 未读取验证。 - 外部依赖(PlantUML):PlantUML 依赖外部渲染服务,服务不可用时构建可能仍成功但图片加载失败;
markdownConfig.plantuml选项的存在暗示服务器地址可配置以缓解此风险。 - 共享管线出口:由于 RSS/Atom 复用同一条管线,图表/公式处理异常会同时影响多个出口,而非仅文章页;加密文章是已知例外(不进入 RSS/Atom)。
- 插件顺序敏感:
remarkMermaid与remarkPlantuml在parseDirectiveNode之后注册,若调整顺序可能影响指令式语法的解析;改动注册顺序需谨慎。
Performance / Operational Notes & Extension Points
- 性能:Mermaid 构建期零渲染成本、客户端承担渲染;PlantUML 成本转嫁给外部服务。图片/图表在 RSS/Atom 中同样由该管线处理,需注意订阅源中的图表展示效果。
- 扩展点:
- 新增图表语言 = 新增一对 remark/rehype 插件并在
astro.config.mjs的两个插件数组中注册(参照 Mermaid/PlantUML 的四文件模式:remark 插件 + rehype 插件 + 运行期脚本或编码器)。 - PlantUML 行为定制通过
markdownConfig.plantuml选项对象。 - 修改 Mermaid 主题/初始化行为的天然位置是
src/plugins/mermaid-render-script.js。
- 新增图表语言 = 新增一对 remark/rehype 插件并在
Tests
未在本页的证据收集中发现针对图表/数学公式插件的测试文件(预算耗尽前未检索到 *.test.* / *.spec.* 相关结果)。此为信息缺口,不代表测试不存在。
Related Links
- Markdown 管线总览(插件装配与
markdownConfig全貌):见同目录下的markdown-pipeline页面 - 其它 Markdown 扩展(提示框、GitHub 卡片、图片网格等):见同目录对应子页
- 源文件入口:
- 功能声明:README.md(数学公式与图表能力)