mdBook 的"标准"其实只有两条硬约束——book.toml 和 src/SUMMARY.md,其余都是内容或可选定制。先给结论图:
mdBook 项目约定:两个必需 + 一个产物
■ 必需:book.toml、src/SUMMARY.md
■ 可选:theme/、自定义 preprocessor/renderer
■ 产物:mdbook build 生成的 book/
📁 my-book/
book.toml 必需·配置 书名/作者/构建目录/输出选项
📁 src/ 必需·源目录 (目录名可在 [book].src 改)
SUMMARY.md 必需·骨架 定义章节与顺序,唯一结构入口
chapter_1.md · 章节内容(须被 SUMMARY 引用)
chapter_2.md · 支持子目录嵌套
images/… · 非 md 文件会被原样复制到产物
📁 theme/ 可选·定制 index.hbs / head.hbs / css / js
📁 book/ 构建产物 index.html / print.html / searchindex.js / css/
.gitignore · mdbook init 自动生成,含 /book
关键文件逐个说
① book.toml(必需,文件名固定,TOML 格式)
| 段 | 常用键 | 说明 |
|---|---|---|
[book] | title / authors / description / language / src | 元数据;src 默认 "src" |
[build] | build-dir(默认 book)/ create-missing | 输出目录与缺失文件补建 |
[output.html] | default-theme / additional-css / additional-js / mathjax-support / search / print / theme / git-repository-url | 渲染层配置 |
[rust] | edition | {{#playpen}} 代码的 Rust 版本 |
[preprocessor.xxx] / [output.xxx] | command / 自定义参数 | 扩展点:预处理与渲染器插拔 |
② src/SUMMARY.md(必需,全书唯一的"结构定义")
# Summary ← # 开头的非链接行 = 分组标题(part title)
- [第一章](chapter_1.md) ← 第一个链接 = 首页(惯用 README.md)
- [1.1 小节](ch1/section.md) ← 缩进嵌套 = 子章节
- [第二章](chapter_2.md)
- [外部链接](https://example.com) ← 也支持外部 URL要点:SUMMARY.md 没列出的 .md 文件不会生成页面;章节可以放子目录,路径相对 src/。
③ 章节文件(内容层)——普通 Markdown + mdBook 特有语法:
{{#include code/snippet.md}} <!-- 插入另一文件 -->
{{#include code/main.rs:10:20}} <!-- 按行范围截取 -->
{{#include ch1.md#anchor}} <!-- 按锚点截取片段 -->
{{#playpen examples/hello.rs}} <!-- Rust 可编辑运行 -->
{{#rust examples/hello.rs}} <!-- 仅高亮 -->
行内公式 \(E=mc^2\) 与块级公式 \[...\] <!-- 需 mathjax-support = true -->④ theme/(可选)——整站模板 index.hbs、head.hbs、css/、js/,在 [output.html].theme 指定路径。
⑤ book/(产物)——mdbook build 输出:每章一个 HTML、print.html(全书合并打印版)、searchindex.js、css/;mdbook clean 清空。
与 VitePress 的对比(你刚问过 frontmatter)
| 维度 | mdBook | VitePress |
|---|---|---|
| 元数据 | book.toml(全局) | 每页 frontmatter |
| 结构 | SUMMARY.md 显式清单 | 文件系统即路由,隐式 |
| 章节顺序 | SUMMARY.md 排定 | 依赖配置/插件 |
| 特有语法 | {{#include}} / {{#playpen}} | 无 |
迁移注意:VitePress 的 frontmatter 里 title、排序信息,到 mdBook 要改写进 book.toml 和 SUMMARY.md——两者模型不同,不能机械搬运。
避坑指南
- SUMMARY.md 漏引用 = 页面消失:文件还在
src/里,但不会渲染;图片等非 md 文件则会被原样复制。 {{#include}}是 mdBook 私有语法:换到别的渲染器会原样显示{{#include ...}}文本。- 锚点规则与 GitHub 不一致:章节内标题 id 由 mdBook 的 slugger 生成,跨章节链接
file.md#id要以实际渲染结果为准。 mdbook serve默认 3000 端口:改book.toml的结构类配置(如build-dir)建议重启,避免 watch 状态不一致。- 中文没问题,但路径别带空格:跨平台脚本/CI 里引号处理是高频翻车点。
Follow-up Chain
- 多语言书怎么做? →
[book].language只影响<html lang>;真正 i18n 用mdbook-i18n-helpers(gettext PO 流程)或每语言一个独立 book。 - 要输出 EPUB/PDF? → 第三方 renderer:
mdbook-epub、mdbook-pandoc;或直接拿print.html打印。 - 自动检查坏链? →
mdbook-linkcheckpreprocessor。 - CI 部署? →
mdbook build后把book/推给静态托管(GitHub Pages 官方有 mdbook action)。
一句话:mdBook 的"标准"= book.toml(配置)+ src/SUMMARY.md(结构)+ Markdown 章节(内容),三者分离,产物进 book/。需要的话,我可以帮你把现有 VitePress 项目改造成 mdBook 的迁移清单。
