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