mdbook/guide/guide-helper/src/lib.rs
Eric Huss 3629e2c051 Add an iterator over chapters
This adds the `Book::chapters` iterator (and `for_each_chapter_mut`) to
iterate over non-draft chapters. This is a common pattern I keep
encountering, and I figure it might simplify things. It runs a little
risk that callers may not be properly handling every item type, but I
think it should be ok.
2025-09-15 07:11:19 -07:00

61 lines
1.8 KiB
Rust

//! Preprocessor for the mdBook guide.
use mdbook_preprocessor::book::Book;
use mdbook_preprocessor::errors::Result;
use mdbook_preprocessor::{Preprocessor, PreprocessorContext};
use semver::{Version, VersionReq};
use std::io;
/// Preprocessing entry point.
pub fn handle_preprocessing() -> Result<()> {
let pre = GuideHelper;
let (ctx, book) = mdbook_preprocessor::parse_input(io::stdin())?;
let book_version = Version::parse(&ctx.mdbook_version)?;
let version_req = VersionReq::parse(mdbook_preprocessor::MDBOOK_VERSION)?;
if !version_req.matches(&book_version) {
eprintln!(
"warning: The {} plugin was built against version {} of mdbook, \
but we're being called from version {}",
pre.name(),
mdbook_preprocessor::MDBOOK_VERSION,
ctx.mdbook_version
);
}
let processed_book = pre.run(&ctx, book)?;
serde_json::to_writer(io::stdout(), &processed_book)?;
Ok(())
}
struct GuideHelper;
impl Preprocessor for GuideHelper {
fn name(&self) -> &str {
"guide-helper"
}
fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {
insert_version(&mut book);
Ok(book)
}
}
fn insert_version(book: &mut Book) {
let path = std::env::current_dir()
.unwrap()
.parent()
.unwrap()
.join("Cargo.toml");
let manifest_contents = std::fs::read_to_string(&path).unwrap();
let manifest: toml::Value = toml::from_str(&manifest_contents).unwrap();
let version = manifest["package"]["version"].as_str().unwrap();
const MARKER: &str = "{{ mdbook-version }}";
book.for_each_chapter_mut(|ch| {
if ch.content.contains(MARKER) {
ch.content = ch.content.replace(MARKER, version);
}
});
}