【mdBook】7.1 预处理器

预处理器是在书籍加载后、渲染前立即运行的一段代码,允许您更新和修改书籍。可能的用例包括:

  • 创建自定义助手,如 {``{#include /path/to/file.md}}
  • 将 LaTeX 风格的表达式($$ \frac{1}{3} $$)替换为它们的 MathJax 等效形式

有关使用预处理器的更多信息,请参阅"配置预处理器"章节。

集成到 MDBook

MDBook 使用相当简单的机制来发现第三方插件。在 book.toml 中添加一个新表(例如,对于 foo 预处理器使用 [preprocessor.foo]),然后 mdbook 将尝试调用 mdbook-foo 程序作为构建过程的一部分。

执行流程

一旦定义了预处理器并且构建过程开始,mdBook 会执行 preprocessor.foo.command 键中定义的命令两次:

第一次调用:检查渲染器支持

bash 复制代码
mdbook-foo supports [渲染器名称]
  • 预处理器应以状态码 0 退出(如果支持给定的渲染器)
  • 或以非零退出代码返回(如果不支持)

第二次调用:实际处理

bash 复制代码
mdbook-foo
  • mdbook 将 JSON 数据传入 stdin
  • JSON 格式为 [context, book] 数组
    • context 是序列化的 PreprocessorContext 对象
    • book 是包含书籍内容的 Book 对象
  • 预处理器应将修改后的 Book 对象的 JSON 格式返回到 stdout

实现预处理器

Rust 实现方式

最简单的方法是创建自己的 Preprocessor trait 实现,然后创建一个 shell 二进制文件来将输入转换为正确的 Preprocessor 方法。

便利工具

  • examples/ 目录中有一个无操作预处理器示例
  • 可轻松适配用于其他预处理器

实现提示

通过将 mdbook 作为库引入,预处理器可以访问处理书籍的现有基础设施。

基本流程

  1. 使用 CmdPreprocessor::parse_input() 反序列化写入 stdin 的 JSON
  2. 通过 Book::for_each_mut() 原地修改每个章节
  3. 使用 serde_json crate 将结果写入 stdout

章节访问方式

  • 直接访问(通过递归迭代章节)
  • 使用便利方法 Book::for_each_mut()

Markdown 处理

chapter.content 只是一个恰好是 Markdown 的字符串。虽然完全可以使用正则表达式或手动查找替换,但您可能希望将输入处理为更计算机友好的格式。

推荐工具

  • pulldown-cmark:生产级的事件驱动 Markdown 解析器
  • pulldown-cmark-to-cmark:将事件转换回 Markdown 文本

示例代码:从 Markdown 中移除所有强调,同时避免意外破坏文档

rust 复制代码
fn remove_emphasis(num_removed_items: &mut usize, chapter: &mut Chapter) -> Result<String, Error> {
    let mut buf = String::with_capacity(chapter.content.len());

    let events = Parser::new(&chapter.content).filter(|e| match e {
        Event::Start(Tag::Emphasis) | Event::Start(Tag::Strong) => {
            *num_removed_items += 1;
            false
        }
        Event::End(TagEnd::Emphasis) | Event::End(TagEnd::Strong) => false,
        _ => true,
    });

    Ok(pulldown_cmark_to_cmark::cmark(events, &mut buf).map(|_| buf)?)
}

使用其他语言实现预处理器

mdBook 使用 stdin 和 stdout 与预处理器通信的事实使得用 Rust 以外的语言实现它们变得容易。

Python 示例:修改第一章内容的简单预处理器

python 复制代码
import json
import sys

if __name__ == '__main__':
    if len(sys.argv) > 1:  # 检查是否收到任何参数
        if sys.argv[1] == "supports": 
            # 返回退出状态码 0,因为另一个参数只是渲染器的名称
            sys.exit(0)

    # 从 stdin 加载上下文和书籍表示
    context, book = json.load(sys.stdin)
    # 现在,我们可以修改第一章的内容
    book['sections'][0]['Chapter']['content'] = '# Hello'
    # 完成书籍修改后,只需将其打印到 stdout
    print(json.dumps(book))

配置对应

toml 复制代码
[preprocessor.foo]
command = "python preprocessor.py"
相关推荐
Source.Liu1 天前
【mdBook】5.2.3 渲染器配置详解
markdown
Source.Liu3 天前
【mdBook】5.2 配置
markdown
Source.Liu3 天前
【mdBook】1 安装
笔记·rust·markdown
qq7422349843 天前
免费版Markdown 编辑器:Typora
大模型·编辑器·markdown
Georgewu4 天前
【鸿蒙开源技术共建】用@luvi/lv-markdown-in在HarmonyOS上打造高性能Markdown编辑体验
harmonyos·markdown
Source.Liu4 天前
mdBook 开源笔记
笔记·rust·markdown
支付宝体验科技5 天前
支付宝开源移动端流式 Markdown 渲染引擎 FluidMarkdown
markdown
Simon_He14 天前
这次来点狠的:用 Vue 3 把 AI 的“碎片 Markdown”渲染得又快又稳(Monaco 实时更新 + Mermaid 渐进绘图)
前端·vue.js·markdown
Simon_He16 天前
一款适用于 Vue 的高性能流式 Markdown 渲染器,源自我们的 AI 聊天机器人
前端·vue.js·markdown