Skip to main content

mdbook_plotly/preprocessor/
bookdata.rs

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