Skip to main content

mdbook_plotly/preprocessor/
bookdata.rs

1use super::config::{PREPROCESSOR_CONFIG_KEY, PreprocessorConfig, SUPPORTED_MDBOOK_VERSION};
2use crate::fatal;
3use log::warn;
4use mdbook_preprocessor::{
5    PreprocessorContext,
6    book::{Book, BookItem, Chapter},
7};
8#[cfg(feature = "sync")]
9use rayon::prelude::*;
10
11pub struct BookData {
12    ctx: PreprocessorContext,
13    book: Book,
14    config: PreprocessorConfig,
15}
16
17impl BookData {
18    fn new(ctx: PreprocessorContext, book: Book, config: PreprocessorConfig) -> Self {
19        Self { ctx, book, config }
20    }
21
22    pub fn version(&self) -> &str {
23        &self.ctx.mdbook_version
24    }
25
26    pub fn is_compatible_version(&self) -> bool {
27        self.version() == SUPPORTED_MDBOOK_VERSION
28    }
29
30    pub fn emit_compatibility_warning(&self) {
31        if !self.is_compatible_version() {
32            warn!(
33                "This preprocessor was developed for mdbook v{}, but found v{}. May not work as expected.",
34                SUPPORTED_MDBOOK_VERSION,
35                self.version()
36            );
37        }
38    }
39
40    /// NOTE: This interface returns a cloned internal `PreprocessorConfig`.
41    pub fn get_config(&self) -> PreprocessorConfig {
42        self.config.clone()
43    }
44
45    /// NOTE: This interface returns a cloned internal `PathBuf`.
46    pub fn get_book_path(&self) -> std::path::PathBuf {
47        self.ctx.root.clone()
48    }
49
50    #[allow(unused)]
51    pub fn for_each_chapter_mut<F>(&mut self, mut f: F)
52    where
53        F: FnMut(&mut Chapter),
54    {
55        fn walk<F: FnMut(&mut Chapter)>(items: &mut [BookItem], f: &mut F) {
56            for item in items.iter_mut() {
57                if let BookItem::Chapter(ch) = item {
58                    f(ch);
59                    walk(&mut ch.sub_items, f);
60                }
61            }
62        }
63        walk(&mut self.book.items, &mut f);
64    }
65
66    #[cfg(feature = "sync")]
67    pub fn for_each_chapter_par<F>(&mut self, f: F)
68    where
69        F: Fn(&mut Chapter) + Sync + Send,
70    {
71        fn walk_par<F: Fn(&mut Chapter) + Sync + Send>(items: &mut [BookItem], f: &F) {
72            items.par_iter_mut().for_each(|item| {
73                if let BookItem::Chapter(ch) = item {
74                    f(ch);
75                    walk_par(&mut ch.sub_items, f);
76                }
77            });
78        }
79        walk_par(&mut self.book.items, &f);
80    }
81
82    pub fn into_book(self) -> Book {
83        self.book
84    }
85}
86
87pub fn get_book_data() -> BookData {
88    let (ctx, book) = match mdbook_preprocessor::parse_input(std::io::stdin()) {
89        Ok(parsed) => parsed,
90        Err(e) => fatal!("Input parsing failed.\nInterError: {:#?}", e),
91    };
92
93    let config = match ctx.config.get("preprocessor.plotly") {
94        Ok(Some(value)) => PreprocessorConfig::from_toml(&value),
95        Ok(None) => {
96            warn!("Custom config not found; using default configuration.");
97            PreprocessorConfig::default()
98        }
99        Err(e) => {
100            warn!(
101                "Illegal config format for '{}': {}; using default configuration.",
102                PREPROCESSOR_CONFIG_KEY,
103                e.root_cause()
104            );
105            PreprocessorConfig::default()
106        }
107    };
108
109    BookData::new(ctx, book, config)
110}