use crate::nop_lib::NopPost;
use clap::{Arg, ArgMatches, Command};
use mdxbook::errors::Error;
use mdxbook::postprocess::{CmdPostprocessor, Postprocessor, Rendered};
use semver::{Version, VersionReq};
use std::io;
use std::process;
pub fn make_app() -> Command {
Command::new("nop-postprocessor")
.about("A mdxbook postprocessor which does precisely nothing")
.subcommand(
Command::new("supports")
.arg(Arg::new("renderer").required(true))
.about("Check whether a renderer is supported by this postprocessor"),
)
}
fn main() {
let matches = make_app().get_matches();
let preprocessor = NopPost::new();
if let Some(sub_args) = matches.subcommand_matches("supports") {
handle_supports(&preprocessor, sub_args);
} else if let Err(e) = handle_preprocessing(&preprocessor) {
eprintln!("{}", e);
process::exit(1);
}
}
fn handle_preprocessing(pre: &dyn Postprocessor) -> Result<(), Error> {
let (ctx, book) = CmdPostprocessor::parse_input(io::stdin())?;
let book_version = Version::parse(&ctx.mdbook_version)?;
let version_req = VersionReq::parse(mdxbook::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(),
mdxbook::MDBOOK_VERSION,
ctx.mdbook_version
);
}
let processed_book = match book {
Rendered::Book(b) => serde_json::to_writer(io::stdout(), &pre.postprocess_book(&ctx, b)?)?,
Rendered::Document(d) => {
serde_json::to_writer(io::stdout(), &pre.postprocess_document(&ctx, d)?)?
}
};
Ok(processed_book)
}
fn handle_supports(pre: &dyn Postprocessor, sub_args: &ArgMatches) -> ! {
let renderer = sub_args
.get_one::<String>("renderer")
.expect("Required argument");
let supported = pre.supports_renderer(renderer);
if supported {
process::exit(0);
} else {
process::exit(1);
}
}
mod nop_lib {
use super::*;
use mdxbook::postprocess::{
CmdPostprocessor, Postprocessor, PostprocessorContext, RenderedBook, RenderedDocumentOfBook,
};
#[derive(Clone)]
pub struct NopPost;
impl NopPost {
pub fn new() -> NopPost {
NopPost
}
}
impl Postprocessor for NopPost {
fn name(&self) -> &str {
"nop-postprocessor"
}
fn supports_renderer(&self, renderer: &str) -> bool {
renderer != "not-supported"
}
fn postprocess_document(
&self,
context: &PostprocessorContext,
rendered_document: RenderedDocumentOfBook,
) -> Result<RenderedDocumentOfBook, Error> {
if let Some(nop_cfg) = context.config.get_postprocessor(self.name()) {
if nop_cfg.contains_key("blow-up") {
anyhow::bail!("Boom!!1!");
}
}
Ok(rendered_document)
}
fn postprocess_book(
&self,
context: &PostprocessorContext,
rendered_book: RenderedBook,
) -> Result<RenderedBook, Error> {
if let Some(nop_cfg) = context.config.get_postprocessor(self.name()) {
if nop_cfg.contains_key("blow-up") {
anyhow::bail!("Boom!!1!");
}
}
Ok(rendered_book)
}
fn clone_dyn(&self) -> Box<dyn Postprocessor> {
Box::new(self.clone())
}
fn to_cmd_postprocessor(&self) -> Option<CmdPostprocessor> {
Some(CmdPostprocessor::new(
self.name().to_string(),
"cargo run --example nop-postprocessor --".to_string(),
))
}
}
}