Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

简介

mdbook-modern-dot 是一个 mdBook 预处理器,可将 Markdown 中的围栏代码块渲染为 Graphviz 图表。

功能特性

  • 构建时通过 dot 命令处理 modern-dot 代码块
  • 内联 SVG(默认)或 输出到文件 并以图片引用
  • 可选 明暗双主题渲染,与 mdBook HTML 主题(Light/Rust 与 Coal/Navy/Ayu)联动
  • 支持 TOML 主题文件、{{ token }} 占位符与自动 preamble 注入

工作原理

  1. 在 Markdown 中编写 Graphviz dot 代码:

    ```modern-dot
    digraph { a -> b; }
    ```
    
  2. 执行 mdbook build 时,预处理器调用 dot,按需应用主题 token,并将代码块替换为 HTML(内联 SVG)或生成的图片文件。

  3. 启用 themed-output = true 时,会同时生成明、暗两套 SVG,由 CSS 根据当前 mdBook 主题切换显示。

markdownMarkdown```modern-dot```preprocessormdbook-modern-dotmarkdown->preprocessordotGraphviz dotpreprocessor->dothtmlHTML / SVGdot->html
markdownMarkdown```modern-dot```preprocessormdbook-modern-dotmarkdown->preprocessordotGraphviz dotpreprocessor->dothtmlHTML / SVGdot->html

本书本身即由 mdbook-modern-dot 构建——切换 mdBook 主题即可看到图表配色随之变化。

安装

安装预处理器

crates.io 安装:

cargo install mdbook-modern-dot

从源码安装:

cargo install --path .

安装 Graphviz

预处理器在构建时会调用 dot 命令,需单独安装 Graphviz

# macOS
brew install graphviz

# Debian/Ubuntu
sudo apt install graphviz

验证安装:

dot -V

若未找到 dotmdbook build 会失败并提示安装方法。

安装 mdBook

构建书籍还需要 mdBook:

cargo install mdbook

快速开始

book.toml 中添加预处理器:

[preprocessor.modern-dot]
command = "mdbook-modern-dot"

在 Markdown 中编写图表:

```modern-dot
digraph {
    "processed" -> "graph"
}
```

可在 info string 后添加可选标题:

```modern-dot 数据流
digraph { input -> output; }
```

构建:

mdbook build

启用明暗主题

[preprocessor.modern-dot]
command = "mdbook-modern-dot"
themed-output = true
theme-file = "themes/default.toml"

启用 themed-output 后,预处理器会在每个含主题图的章节首张图前自动注入内置 CSS,无需复制 modern-dot-theme.css 或配置 additional-css

若需自定义样式,可设置 inject-theme-css = false 并自行引入 CSS 文件。

本仓库开发

开发本项目时,可指向本地 crate:

[preprocessor.modern-dot]
command = "cargo run -q -p mdbook-modern-dot"
themed-output = true
theme-file = "../themes/default.toml"

配置项

所有选项均写在 book.toml[preprocessor.modern-dot] 下。

选项默认值说明
command(必填)mdbook-modern-dot 可执行文件路径
themed-outputfalse渲染明、暗两套 SVG
inject-theme-csstrue在每个含主题图的章节首张图前自动注入内置主题切换 CSS(themed-output = true 时生效)
theme-filethemes/default.toml主题 TOML 路径(相对书籍根目录)
dark-suffix-dark文件模式下暗色 SVG 文件名后缀
theme-wrapper-classtheme-diagram主题输出外层 CSS 类名
info-stringmodern-dot要处理的围栏代码块标记
output-to-filefalse输出 SVG 文件而非内联 HTML
link-to-filefalse文件模式下用链接包裹图片(仅单主题)
arguments["-Tsvg"]传给 dot 的额外参数
after在其他预处理器之后运行(如 ["links"]

环境变量

mdBook 支持用环境变量覆盖配置:

MDBOOK_preprocessor__modern_dot__themed_output="true" mdbook build
MDBOOK_preprocessor__modern_dot__output_to_file="true" mdbook build

选项名中的连字符 - 变为下划线 _;嵌套键使用双下划线 __

自定义 info string

仅处理与 info-string 匹配的代码块,其他标记(如普通 ```dot)保持不变。

[preprocessor.modern-dot]
info-string = "graphviz"

嵌入外部 dot 文件

配合 mdBook 的 links 预处理器引入 dot 源码:

```dot
{{#include path/to/diagram.dot}}
```

确保 modern-dot 在 links 之后运行:

[preprocessor.modern-dot]
after = ["links"]

文件模式的 .gitignore

使用 output-to-file = true 时,建议添加:

*.modern-dot.svg
*.modern-dot-dark.svg

主题系统

启用 themed-output = true 后,每张图会渲染两次:分别使用主题文件中的 [light][dark] token。

主题文件格式

示例(themes/default.toml):

[light]
text = "#24292f"
node_fill = "#f6f7f9"
edge = "#5c6b7a"

[dark]
text = "#adbac7"
node_fill = "#2d333b"
edge = "#768390"

[preamble]
graph = 'graph [ bgcolor="transparent", fontcolor="{{ text }}" ];'
node = 'node [ style="filled", fillcolor="{{ node_fill }}", color="{{ node_stroke }}", fontcolor="{{ text }}" ];'
edge = 'edge [ color="{{ edge }}", fontcolor="{{ text }}" ];'

dot 代码中的占位符

在图表中使用 {{ token }}

GAABBA->B
GAABBA->B

缺少 token 会导致构建失败,并列出未找到的键名。

自动 preamble 注入

若代码块中 没有 {{ ... }} 占位符,会在图定义开括号 { 之后自动注入主题文件 [preamble] 中的属性。

已使用占位符的代码块不会注入 preamble,样式由你完全控制。

CSS 切换

默认 inject-theme-css = true 时,预处理器在每个含主题图的章节首张图前注入内置 <style>,无需额外文件。

若需自定义,可关闭自动注入并手动引入 assets/modern-dot-theme.css

[preprocessor.modern-dot]
inject-theme-css = false

[output.html]
additional-css = ["modern-dot-theme.css"]

生成的 HTML 结构:

<div class="mdbook-modern-dot-output theme-diagram">
  <div class="diagram-light"><svg>...</svg></div>
  <div class="diagram-dark"><svg>...</svg></div>
</div>

输出模式

内联模式(默认)

output-to-file = false — SVG 直接嵌入章节 HTML。

适合大多数书籍:无额外文件,图表随页面一起发布。

文件模式

[preprocessor.modern-dot]
output-to-file = true

每张图在源章节旁生成 SVG 文件:

  • chapter_name_0.modern-dot.svg(浅色)
  • chapter_name_0.modern-dot-dark.svg(深色,需 themed-output = true

Markdown 中的代码块会被替换为 <img> 标签(主题模式下为双图 HTML)。

链接到文件

单主题文件模式下,可将图片包裹在指向 SVG 的链接中:

[preprocessor.modern-dot]
output-to-file = true
link-to-file = true

启用 themed-output = true 时不使用此选项(主题文件输出使用固定 HTML 结构)。

文件命名规则

生成文件名由以下部分组成:

  1. 规范化后的章节名
  2. info string 中的可选图标题
  3. 章节内代码块序号

示例:章节「Getting Started」、标题「Data Flow」、第一个块 → getting_started_data_flow_0.modern-dot.svg

章节名与图标题中的非字母数字字符会规范化为下划线(仅保留 ASCII 字母数字)。

示例

以下图表由 mdbook-modern-dotthemed-output = true 下实时渲染。 切换 mdBook 主题(Light ↔ Coal/Navy/Ayu)即可看到配色变化。

Graphviz

示例书籍启用了 themed-output,图表会生成明、暗两套 SVG,随 mdBook 主题切换。只需写一个围栏代码块,无需手写 HTML。

显式 token 的主题图

Ginput输入process处理input->processoutput输出process->output
Ginput输入process处理input->processoutput输出process->output

自动 preamble 注入的简单图

不含 {{ token }} 占位符的图表,会从 themes/default.toml 自动注入默认 graph/node/edge 属性。

Gstartstartmiddlemiddlestart->middleendendmiddle->end
Gstartstartmiddlemiddlestart->middleendendmiddle->end

硬编码颜色(不随主题变化)

以下颜色固定不变,除非改为主题 token。

Gcluster_0流程 #1cluster_1流程 #2a0a0a1a1a0->a1a2a2a1->a2b3b3a1->b3a3a3a2->a3a3->a0endenda3->endb0b0b1b1b0->b1b2b2b1->b2b2->a3b2->b3b3->endstartstartstart->a0start->b0
Gcluster_0流程 #1cluster_1流程 #2a0a0a1a1a0->a1a2a2a1->a2b3b3a1->b3a3a3a2->a3a3->a0endenda3->endb0b0b1b1b0->b1b2b2b1->b2b2->a3b2->b3b3->endstartstartstart->a0start->b0

开发指南

环境要求

构建本文档

在仓库根目录执行:

mdbook build book
mdbook serve book

book/ 目录既是项目手册,也是启用 themed-output 的集成示例。

常用命令

cargo test
cargo lint      # clippy + fmt 检查
cargo fmt-check

发布

使用 cargo-release

cargo release patch -x --no-confirm

许可证

AGPL-3.0-or-later — 见 LICENSE