mdbook_plotly/preprocessor/
bookdata.rs1use 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 pub fn get_config(&self) -> PreprocessorConfig {
42 self.config.clone()
43 }
44
45 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}