Repository Wiki
LyraVoid/Mizuki

图表与数学公式(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(中文版)对本能力的官方描述:

text
- [x] **数学公式**,使用 KaTeX,并支持 Mermaid 和 PlantUML 图表

Source: README.md

三者共享同一个设计动机:作者只写源码文本,渲染复杂性由管线与运行时承担。这样图表与公式可以像普通代码块一样参与版本管理,同时站点构建产物保持轻量(Mermaid 不在构建期执行重量级布局计算,PlantUML 由外部服务承担渲染)。

Architecture

下图展示从 Markdown 源文件到最终 HTML 的完整数据流,所有节点都是仓库中真实存在的文件/导出(依据 astro.config.mjs 的 import 与插件数组注册顺序验证):

Loading diagram...

架构要点(WHY):

  1. 双阶段拆分(remark + rehype)。remarkMermaid/remarkPlantuml 工作在 Markdown AST(mdast)层面,负责把代码块识别为图表节点;rehypeMermaid/rehypePlantuml 工作在 HTML AST(hast)层面,负责把节点转成真正的 HTML 元素与脚本挂载点。这种拆分让语法识别与 DOM 产物生成解耦,与 Astro 生态中 remark/rehype 的标准分层一致。

  2. Mermaid 的渲染位置在浏览器端。仓库中存在独立的 src/plugins/mermaid-render-script.js,说明 Mermaid 图表不在构建期渲染成 SVG,而是在页面加载后由脚本执行渲染——这避免了大图表拖慢构建,代价是客户端需要执行脚本。

  3. PlantUML 的渲染位置在外部服务。存在独立的 src/plugins/plantuml-encoder.mjs,对应 PlantUML 官方服务接受"压缩+编码后的文本 URL"的惯例(具体编码算法未读取验证),构建期只需要做编码与 <img> 元素生成。

  4. 同一管线服务多种产物。README 明确说明文章页、RSS、Atom 共用同一条 Markdown/MDX 管线,因此图表/公式插件对所有出口统一生效(加密文章除外,不进入 RSS/Atom)。

插件在 astro.config.mjs 中的 import(第 37–48 行节选,为仓库真实内容):

js
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

js
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 行,缩进已简化):

js
parseDirectiveNode, remarkMermaid, [remarkPlantuml, markdownConfig.plantuml],

Source: astro.config.mjs

注意两个关键差异:remarkMermaid 是无选项注册,而 remarkPlantuml 以 [plugin, options] 数组形式注册并传入 markdownConfig.plantuml——说明 PlantUML 能力存在面向用户的配置项(例如渲染服务器地址),而 Mermaid 在 remark 层不需要用户配置。

实现走读:管线中的位置与控制流

由于本页源码读取预算已耗尽(6/6),以下对插件内部实现的描述仅基于已验证的注册证据做边界性说明,各函数内部逻辑未读取,不做臆测。

端到端控制流(已验证部分)

  1. 构建期 · remark 阶段:Astro 读入 .md/.mdx 源文件构建 mdast。插件数组按注册顺序执行:parseDirectiveNode → remarkMermaid → [remarkPlantuml, markdownConfig.plantuml](顺序见上文 astro.config.mjs 第 236–238 行)。remarkMermaid 在此处获得处理 ```mermaid 代码块的最早机会。
  2. 构建期 · mdast → hast 转换后:rehypeMermaid 与 rehypePlantuml 接管 HTML AST,将图表节点转换为最终 HTML 结构(Mermaid 侧大概率生成携带源码文本的占位元素并注入 mermaid-render-script.js;PlantUML 侧借助 plantuml-encoder.mjs 编码源码后指向渲染服务)。此两步的内部实现未读取,属于推断性描述。
  3. 运行期(浏览器):mermaid-render-script.js 扫描页面中的 Mermaid 占位元素,调用 Mermaid 渲染为内联 SVG;PlantUML 图片为普通 <img>,由外部服务渲染,无需客户端脚本;KaTeX 公式在构建期或既有 rehype 链中完成渲染(具体挂接点未读取验证)。
  4. 多出口复用:同一管线产出文章页、RSS、Atom,图表与公式能力对所有出口一致;加密文章按 README 说明被排除出 RSS/Atom。

参与文件的职责边界

文件管线阶段已验证职责未验证部分
src/plugins/remark-mermaid.jsremark(mdast)导出 remarkMermaid,在 astro.config.mjs 中无选项注册内部 AST 匹配与节点改写逻辑
src/plugins/rehype-mermaid.mjsrehype(hast)导出 rehypeMermaidHTML 元素生成与脚本注入细节
src/plugins/mermaid-render-script.js浏览器运行期存在于 plugins 目录,与 Mermaid 浏览器端渲染配套初始化时机与主题适配逻辑
src/plugins/remark-plantuml.mjsremark(mdast)导出 remarkPlantuml,以 markdownConfig.plantuml 作为选项注册指令解析与代码块识别逻辑
src/plugins/rehype-plantuml.mjsrehype(hast)导出 rehypePlantuml<img>/URL 构造细节
src/plugins/plantuml-encoder.mjs构建期工具PlantUML 文本编码器具体编码算法(是否 deflate+base64 变体)
KaTeX 相关插件管线中README 声明为已支持能力具体挂接插件与配置键未在本页验证

Usage Examples

作者侧:Mermaid 图表

text
1​```mermaid 2flowchart TD 3 A --> B 4​```

(上例为语法示意,用于说明作者书写形态;仓库中实际的渲染行为由 remark-mermaid.js + rehype-mermaid.mjs + mermaid-render-script.js 三段链路完成。本页未读取到仓库内的官方示例文档,故不引用具体示例文件。)

作者侧:PlantUML 图表

text
1​```plantuml 2@startuml 3Alice -> Bob: Hello 4@enduml 5​```

PlantUML 还支持通过 remark 指令语法使用(管线中 parseDirectiveNode 先于 remarkPlantuml 注册,暗示指令式 PlantUML 的存在,此为基于注册顺序的推断,未读取实现验证)。

配置侧:插件注册的真实代码

js
remarkMermaid, [remarkPlantuml, markdownConfig.plantuml],

Source: astro.config.mjs

这是在站点配置中启用图表能力的唯一必经入口:remarkMermaid 直接注册,remarkPlantuml 携带 markdownConfig.plantuml 选项对象注册。

Configuration Options

选项类型默认值说明
markdownConfig.plantumlobject未验证传给 remarkPlantuml 的选项对象;具体键名(如渲染服务器地址、图片格式)需查阅 src/plugins/remark-plantuml.mjs 实现,本页未读取
Mermaid 选项—无remarkMermaid 以无选项形式注册,remark 层不暴露用户配置

API Reference

导出所在文件签名说明
remarkMermaidsrc/plugins/remark-mermaid.js未验证remark 插件;签名与内部参数未读取
remarkPlantumlsrc/plugins/remark-plantuml.mjsremarkPlantuml(options)remark 插件;以 markdownConfig.plantuml 为 options 注册
rehypeMermaidsrc/plugins/rehype-mermaid.mjs未验证rehype 插件;签名未读取
rehypePlantumlsrc/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。

Tests

未在本页的证据收集中发现针对图表/数学公式插件的测试文件(预算耗尽前未检索到 *.test.* / *.spec.* 相关结果)。此为信息缺口,不代表测试不存在。