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.
61 lines
1.8 KiB
Rust
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);
|
|
}
|
|
});
|
|
}
|