We can shell out to the preprocessor

This commit is contained in:
Michael Bryan 2018-09-16 23:23:03 +08:00
parent 304234c122
commit 1aa1194d79
No known key found for this signature in database
GPG Key ID: E9C602B0D9A998DC
3 changed files with 58 additions and 4 deletions

View File

@ -3,8 +3,9 @@ extern crate mdbook;
extern crate clap; extern crate clap;
use clap::{App, Arg, ArgMatches, SubCommand}; use clap::{App, Arg, ArgMatches, SubCommand};
use mdbook::preprocess::{Preprocessor, PreprocessorContext}; use mdbook::preprocess::{Preprocessor, PreprocessorContext, CmdPreprocessor};
use std::process; use std::process;
use std::io;
fn main() { fn main() {
let matches = app().get_matches(); let matches = app().get_matches();
@ -17,7 +18,18 @@ fn main() {
} }
fn handle_preprocessing(args: &ArgMatches) { fn handle_preprocessing(args: &ArgMatches) {
unimplemented!() let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())
.expect("Couldn't parse the input");
// You can tell the preprocessor to blow up by setting a particular
// config value
if let Some(table) = ctx.config.get_preprocessor("nop-preprocessor") {
let should_blow_up = table.get("blow-up").is_some();
if should_blow_up {
panic!("Boom!!!1!");
}
}
} }
fn handle_supports(sub_args: &ArgMatches) { fn handle_supports(sub_args: &ArgMatches) {

View File

@ -39,7 +39,7 @@ impl CmdPreprocessor {
&self, &self,
child: &mut Child, child: &mut Child,
book: Book, book: Book,
ctx: PreprocessorContext, ctx: &PreprocessorContext,
) { ) {
let mut stdin = child.stdin.take().expect("Child has stdin"); let mut stdin = child.stdin.take().expect("Child has stdin");
let input = (ctx, book); let input = (ctx, book);
@ -77,7 +77,25 @@ impl Preprocessor for CmdPreprocessor {
} }
fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result<Book> { fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result<Book> {
unimplemented!() let mut cmd = self.command()?;
let mut child = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.spawn()
.chain_err(|| format!("Unable to start the \"{}\" preprocessor. Is it installed?", self.name()))?;
self.write_input(&mut child, book, ctx);
let output = child
.wait_with_output()
.chain_err(|| "Error waiting for the preprocessor to complete")?;
trace!("{} exited with output: {:?}", self.cmd, output);
ensure!(output.status.success(), "The preprocessor exited unsuccessfully");
serde_json::from_slice(&output.stdout).chain_err(|| "Unable to parse the preprocessed book")
} }
fn supports_renderer(&self, renderer: &str) -> bool { fn supports_renderer(&self, renderer: &str) -> bool {

View File

@ -1,6 +1,8 @@
extern crate mdbook; extern crate mdbook;
use mdbook::preprocess::{CmdPreprocessor, Preprocessor}; use mdbook::preprocess::{CmdPreprocessor, Preprocessor};
use mdbook::MDBook;
use std::path::Path;
fn example() -> CmdPreprocessor { fn example() -> CmdPreprocessor {
CmdPreprocessor::new("nop-preprocessor".to_string(), "cargo run --example nop-preprocessor --".to_string()) CmdPreprocessor::new("nop-preprocessor".to_string(), "cargo run --example nop-preprocessor --".to_string())
@ -23,3 +25,25 @@ fn example_doesnt_support_not_supported() {
assert_eq!(got, false); assert_eq!(got, false);
} }
#[test]
fn ask_the_preprocessor_to_blow_up() {
let dummy_book = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join("dummy_book");
let mut md = MDBook::load(&dummy_book).unwrap();
md.with_preprecessor(example());
md.config.set("preprocess.nop-preprocessor.blow-up", true).unwrap();
let got = md.build();
assert!(got.is_err());
}
#[test]
fn process_the_dummy_book() {
let dummy_book = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join("dummy_book");
let mut md = MDBook::load(&dummy_book).unwrap();
md.with_preprecessor(example());
md.build().unwrap();
}