1//! Book preprocessing.
2
3pub use self::cmd::CmdPreprocessor;
4pub use self::index::IndexPreprocessor;
5pub use self::links::LinkPreprocessor;
6
7mod cmd;
8mod index;
9mod links;
10
11use crate::book::Book;
12use crate::config::Config;
13use crate::errors::*;
14
15use serde::{Deserialize, Serialize};
16use std::cell::RefCell;
17use std::collections::HashMap;
18use std::path::PathBuf;
19
20/// Extra information for a `Preprocessor` to give them more context when
21/// processing a book.
22#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
23pub struct PreprocessorContext {
24 /// The location of the book directory on disk.
25 pub root: PathBuf,
26 /// The book configuration (`book.toml`).
27 pub config: Config,
28 /// The `Renderer` this preprocessor is being used with.
29 pub renderer: String,
30 /// The calling `mdbook` version.
31 pub mdbook_version: String,
32 #[serde(skip)]
33 pub(crate) chapter_titles: RefCell<HashMap<PathBuf, String>>,
34 #[serde(skip)]
35 __non_exhaustive: (),
36}
37
38impl PreprocessorContext {
39 /// Create a new `PreprocessorContext`.
40 pub(crate) fn new(root: PathBuf, config: Config, renderer: String) -> Self {
41 PreprocessorContext {
42 root,
43 config,
44 renderer,
45 mdbook_version: crate::MDBOOK_VERSION.to_string(),
46 chapter_titles: RefCell::new(HashMap::new()),
47 __non_exhaustive: (),
48 }
49 }
50}
51
52/// An operation which is run immediately after loading a book into memory and
53/// before it gets rendered.
54pub trait Preprocessor {
55 /// Get the `Preprocessor`'s name.
56 fn name(&self) -> &str;
57
58 /// Run this `Preprocessor`, allowing it to update the book before it is
59 /// given to a renderer.
60 fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result<Book>;
61
62 /// A hint to `MDBook` whether this preprocessor is compatible with a
63 /// particular renderer.
64 ///
65 /// By default, always returns `true`.
66 fn supports_renderer(&self, _renderer: &str) -> bool {
67 true
68 }
69}
70