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
12pub 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 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}