2025-07-21 11:07:57 -07:00
|
|
|
//! Library to assist implementing an mdbook preprocessor.
|
2025-07-23 16:31:21 -07:00
|
|
|
//!
|
|
|
|
|
//! This library is used to implement a
|
|
|
|
|
//! [preprocessor](https://rust-lang.github.io/mdBook/for_developers/preprocessors.html)
|
|
|
|
|
//! for [mdBook](https://rust-lang.github.io/mdBook/). See the linked chapter
|
|
|
|
|
//! for more information on how to implement a preprocessor.
|
2025-07-21 11:07:57 -07:00
|
|
|
|
2025-07-21 15:19:18 -07:00
|
|
|
use anyhow::Context;
|
|
|
|
|
use mdbook_core::book::Book;
|
|
|
|
|
use mdbook_core::config::Config;
|
|
|
|
|
use mdbook_core::errors::Result;
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use std::cell::RefCell;
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::io::Read;
|
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
2025-07-21 11:07:57 -07:00
|
|
|
pub use mdbook_core::MDBOOK_VERSION;
|
2025-07-21 15:19:18 -07:00
|
|
|
pub use mdbook_core::book;
|
|
|
|
|
pub use mdbook_core::config;
|
|
|
|
|
pub use mdbook_core::errors;
|
|
|
|
|
|
|
|
|
|
/// An operation which is run immediately after loading a book into memory and
|
|
|
|
|
/// before it gets rendered.
|
2025-07-23 16:31:21 -07:00
|
|
|
///
|
|
|
|
|
/// Types that implement the `Preprocessor` trait can be used with
|
|
|
|
|
/// [`MDBook::with_preprocessor`] to programmatically add preprocessors.
|
|
|
|
|
///
|
|
|
|
|
/// [`MDBook::with_preprocessor`]: https://docs.rs/mdbook-driver/latest/mdbook_driver/struct.MDBook.html#method.with_preprocessor
|
2025-07-21 15:19:18 -07:00
|
|
|
pub trait Preprocessor {
|
|
|
|
|
/// Get the `Preprocessor`'s name.
|
|
|
|
|
fn name(&self) -> &str;
|
|
|
|
|
|
|
|
|
|
/// Run this `Preprocessor`, allowing it to update the book before it is
|
|
|
|
|
/// given to a renderer.
|
|
|
|
|
fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result<Book>;
|
|
|
|
|
|
|
|
|
|
/// A hint to `MDBook` whether this preprocessor is compatible with a
|
|
|
|
|
/// particular renderer.
|
|
|
|
|
///
|
|
|
|
|
/// By default, always returns `true`.
|
|
|
|
|
fn supports_renderer(&self, _renderer: &str) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Extra information for a `Preprocessor` to give them more context when
|
|
|
|
|
/// processing a book.
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
2025-08-09 16:38:22 -07:00
|
|
|
#[non_exhaustive]
|
2025-07-21 15:19:18 -07:00
|
|
|
pub struct PreprocessorContext {
|
|
|
|
|
/// The location of the book directory on disk.
|
|
|
|
|
pub root: PathBuf,
|
|
|
|
|
/// The book configuration (`book.toml`).
|
|
|
|
|
pub config: Config,
|
|
|
|
|
/// The `Renderer` this preprocessor is being used with.
|
|
|
|
|
pub renderer: String,
|
|
|
|
|
/// The calling `mdbook` version.
|
|
|
|
|
pub mdbook_version: String,
|
|
|
|
|
/// Internal mapping of chapter titles.
|
|
|
|
|
///
|
|
|
|
|
/// This is used internally by mdbook to compute custom chapter titles.
|
|
|
|
|
/// This should not be used outside of mdbook's internals.
|
|
|
|
|
#[serde(skip)]
|
|
|
|
|
pub chapter_titles: RefCell<HashMap<PathBuf, String>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PreprocessorContext {
|
|
|
|
|
/// Create a new `PreprocessorContext`.
|
|
|
|
|
pub fn new(root: PathBuf, config: Config, renderer: String) -> Self {
|
|
|
|
|
PreprocessorContext {
|
|
|
|
|
root,
|
|
|
|
|
config,
|
|
|
|
|
renderer,
|
|
|
|
|
mdbook_version: crate::MDBOOK_VERSION.to_string(),
|
|
|
|
|
chapter_titles: RefCell::new(HashMap::new()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Parses the input given to a preprocessor.
|
|
|
|
|
pub fn parse_input<R: Read>(reader: R) -> Result<(PreprocessorContext, Book)> {
|
|
|
|
|
serde_json::from_reader(reader).with_context(|| "Unable to parse the input")
|
|
|
|
|
}
|