mdbook_trunk/
preprocessor.rs1use std::{env, str};
2
3use anyhow::Result;
4use cargo::{GlobalContext, core::Workspace, util::important_paths::find_root_manifest_for_wd};
5use mdbook_preprocessor::{
6 Preprocessor, PreprocessorContext,
7 book::{Book, BookItem},
8};
9
10use crate::{parser::definition::parse_definitions, trunk::trunk};
11
12pub struct TrunkPreprocessor;
13
14impl TrunkPreprocessor {
15 pub fn new() -> Self {
16 Self
17 }
18}
19
20impl Default for TrunkPreprocessor {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl Preprocessor for TrunkPreprocessor {
27 fn name(&self) -> &str {
28 "trunk"
29 }
30
31 fn run(&self, _ctx: &PreprocessorContext, book: Book) -> Result<Book> {
32 let mut book = book.clone();
33
34 let gctx = GlobalContext::default()?;
35 let workspace = Workspace::new(&find_root_manifest_for_wd(&env::current_dir()?)?, &gctx)?;
36
37 process_items(&workspace, &mut book.items)?;
38
39 Ok(book)
40 }
41
42 fn supports_renderer(&self, _renderer: &str) -> Result<bool> {
43 Ok(true)
44 }
45}
46
47fn process_items(workspace: &Workspace, items: &mut Vec<BookItem>) -> Result<()> {
48 for section in items {
49 if let BookItem::Chapter(chapter) = section {
50 let blocks = parse_definitions(chapter)?;
51
52 let mut offset: usize = 0;
53
54 for (span, config) in blocks {
55 let replacement = trunk(workspace, &config)?;
56
57 chapter
58 .content
59 .replace_range((span.start + offset)..(span.end + offset), &replacement);
60
61 offset += replacement.len() - span.len();
62 }
63
64 process_items(workspace, &mut chapter.sub_items)?;
65 }
66 }
67
68 Ok(())
69}