mdbook_djot/
lib.rs

1use std::ffi::OsStr;
2
3use anyhow::Error;
4use jotdown::{
5    Parser, Render,
6    html::{Indentation, Renderer},
7};
8use log::debug;
9
10use mdbook_preprocessor::{Preprocessor, PreprocessorContext, book::Book};
11
12/// A Djot preprocessor.
13pub struct Djot {
14    renderer: Renderer,
15}
16
17impl Djot {
18    #[must_use]
19    pub fn new() -> Djot {
20        let renderer = Renderer::indented(Indentation {
21            string: " ".repeat(4),
22            initial_level: 6,
23        });
24        Self { renderer }
25    }
26}
27
28impl Default for Djot {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl Preprocessor for Djot {
35    fn name(&self) -> &'static str {
36        "djot-preprocessor"
37    }
38
39    fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book, Error> {
40        /* Fixme:
41        if let Ok(cfg) = ctx.config.get(self.name()) {
42            //
43        }
44        */
45
46        book.for_each_chapter_mut(|chapter| {
47            let Some(path) = chapter.source_path.as_ref() else {
48                return;
49            };
50
51            let Some(extension) = path.extension() else {
52                return;
53            };
54
55            if OsStr::new("dj") == extension {
56                debug!("Preprocessing {chapter}");
57                let events = Parser::new(&chapter.content);
58                let mut content = String::new();
59                self.renderer.push(events, &mut content).unwrap();
60                let content_stripped = content.trim().to_string();
61                chapter.content = content_stripped;
62            }
63        });
64
65        Ok(book)
66    }
67
68    fn supports_renderer(&self, renderer: &str) -> anyhow::Result<bool> {
69        Ok(renderer != "markdown")
70    }
71}