Skip to main content

mdbook_typstpdf/config/
renderer.rs

1use std::fs;
2
3use super::Config;
4
5impl Config {
6    pub fn prepare_chapter_dir(&self, ctx: &mdbook_renderer::RenderContext) -> anyhow::Result<()> {
7        let chapter_dir = self.get_chapters_dir(ctx);
8        // create chapter dir
9        fs::create_dir_all(&chapter_dir)?;
10        log::debug!("created chapter dir: {}", chapter_dir.display());
11        Ok(())
12    }
13
14    pub fn prepare_template_images(
15        &self,
16        ctx: &mdbook_renderer::RenderContext,
17    ) -> anyhow::Result<()> {
18        let target_template_dir = self.get_typst_templates_dir(ctx);
19        let source_template_dir = self.get_template_dir(ctx);
20        let images_dir = source_template_dir.join("images");
21        if images_dir.exists() {
22            // copy the folder to the typst_dir
23            fs::create_dir_all(target_template_dir.join("images"))?;
24            let entries = fs::read_dir(&images_dir)?;
25            for entry in entries {
26                let entry = entry?;
27                let path = entry.path();
28                let dest = target_template_dir
29                    .join("images")
30                    .join(path.file_name().unwrap());
31                if path.is_file() {
32                    fs::copy(&path, &dest)?;
33                } else if path.is_dir() {
34                    fs::create_dir_all(&dest)?;
35                    let subentries = fs::read_dir(&path)?;
36                    for subentry in subentries {
37                        let subentry = subentry?;
38                        let subpath = subentry.path();
39                        fs::copy(&subpath, dest.join(subpath.file_name().unwrap()))?;
40                    }
41                }
42            }
43            log::debug!(
44                "copied images folder from {} to {}",
45                images_dir.display(),
46                target_template_dir.join("images").display()
47            );
48        }
49
50        Ok(())
51    }
52
53    pub fn prepare_templates(&self, ctx: &mdbook_renderer::RenderContext) -> anyhow::Result<()> {
54        let target_template_dir = self.get_typst_templates_dir(ctx);
55        // create it if not exists
56        fs::create_dir_all(&target_template_dir)?;
57        let source_template_dir = self.get_template_dir(ctx);
58        log::debug!(
59            "template_dir value:{},template_dir folder: {}",
60            self.template_dir,
61            source_template_dir.display()
62        );
63
64        self.prepare_template_images(ctx)?;
65
66        // check the templates hashmap
67        for (name, file_name) in &self.templates {
68            let template_file = source_template_dir.join(file_name);
69            if !template_file.exists() {
70                return Err(anyhow::anyhow!(
71                    "template file {} not found",
72                    template_file.display()
73                ));
74            }
75            // get the file name from the template_file
76            let file_name = template_file.file_name().unwrap().to_str().unwrap();
77            let dst = target_template_dir.join(file_name);
78            fs::copy(&template_file, &dst)?;
79            log::debug!(
80                "{},copied template file {} to {}",
81                name,
82                template_file.display(),
83                dst.display()
84            );
85        }
86
87        Ok(())
88    }
89
90    pub fn renderer(&self, ctx: &mdbook_renderer::RenderContext) -> anyhow::Result<()> {
91        let book = &ctx.book;
92        log::debug!("book items:{}", book.items.len());
93        // steps
94        // 1. create "typst" folder under the typst_pdf_dir for hosting all typst files
95        // 2. copy all template typst files to the "typst" folder
96        // 3. copy the images folder to support typst template to the "typst" folder
97        // 4. copy code block template to the "typst" folder
98        self.prepare_templates(ctx)?;
99
100        // 5. create chapter folder under the typst_pdf_dir/typst/
101        self.prepare_chapter_dir(ctx)?;
102
103        // 6. convert each chapter to typst file
104        let mut chapter_file_list = Vec::new();
105        self.convert_chapters(&mut chapter_file_list, ctx)?;
106        log::debug!("chapter_file_list: {:?}", chapter_file_list);
107
108        // 7. convert the book to a typst file
109        self.convert_book(&mut chapter_file_list, ctx)?;
110
111        // 8. convert the book to pdf
112        self.convert_book_to_pdf(ctx)?;
113
114        if !self.keep_typst_files {
115            // 9. remove the typst folder
116            let typst_dir = self.get_typst_dir(ctx);
117            if typst_dir.exists() {
118                fs::remove_dir_all(&typst_dir)?;
119                log::info!("removed typst folder: {}", typst_dir.display());
120            }
121        }
122
123        Ok(())
124    }
125}