Skip to content

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(必需,全书唯一的"结构定义")

markdown
# 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 特有语法:

markdown
{{#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) ​

维度mdBookVitePress
元数据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 ​

  1. 多语言书怎么做? → [book].language 只影响 <html lang>;真正 i18n 用 mdbook-i18n-helpers(gettext PO 流程)或每语言一个独立 book。
  2. 要输出 EPUB/PDF? → 第三方 renderer:mdbook-epub、mdbook-pandoc;或直接拿 print.html 打印。
  3. 自动检查坏链? → mdbook-linkcheck preprocessor。
  4. CI 部署? → mdbook build 后把 book/ 推给静态托管(GitHub Pages 官方有 mdbook action)。

一句话:mdBook 的"标准"= book.toml(配置)+ src/SUMMARY.md(结构)+ Markdown 章节(内容),三者分离,产物进 book/。需要的话,我可以帮你把现有 VitePress 项目改造成 mdBook 的迁移清单。