summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bryan <michaelfbryan@gmail.com>2018-09-16 23:23:03 +0800
committerMichael Bryan <michaelfbryan@gmail.com>2018-09-16 23:23:03 +0800
commit1aa1194d798b1e8ab5788bb527f968981e7b9ca2 (patch)
treea3426d97f3cffa78d557b1e276bb38078e395ae1
parent304234c122ec15051a2ed4379bd3a21b2dccb4fa (diff)
We can shell out to the preprocessor
-rw-r--r--examples/nop-preprocessor.rs16
-rw-r--r--src/preprocess/cmd.rs22
-rw-r--r--tests/custom_preprocessors.rs24
3 files changed, 58 insertions, 4 deletions
diff --git a/examples/nop-preprocessor.rs b/examples/nop-preprocessor.rs
index 29b397ee..df8bd757 100644
--- a/examples/nop-preprocessor.rs
+++ b/examples/nop-preprocessor.rs
@@ -3,8 +3,9 @@ extern crate mdbook;
extern crate clap;
use clap::{App, Arg, ArgMatches, SubCommand};
-use mdbook::preprocess::{Preprocessor, PreprocessorContext};
+use mdbook::preprocess::{Preprocessor, PreprocessorContext, CmdPreprocessor};
use std::process;
+use std::io;
fn main() {
let matches = app().get_matches();
@@ -17,7 +18,18 @@ fn main() {
}
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) {
diff --git a/src/preprocess/cmd.rs b/src/preprocess/cmd.rs
index 84a78e29..2fc14ffc 100644
--- a/src/preprocess/cmd.rs
+++ b/src/preprocess/cmd.rs
@@ -39,7 +39,7 @@ impl CmdPreprocessor {
&self,
child: &mut Child,
book: Book,
- ctx: PreprocessorContext,
+ ctx: &PreprocessorContext,
) {
let mut stdin = child.stdin.take().expect("Child has stdin");
let input = (ctx, book);
@@ -77,7 +77,25 @@ impl Preprocessor for CmdPreprocessor {
}
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 {
diff --git a/tests/custom_preprocessors.rs b/tests/custom_preprocessors.rs
index 03d2689a..d0182e7e 100644
--- a/tests/custom_preprocessors.rs
+++ b/tests/custom_preprocessors.rs
@@ -1,6 +1,8 @@
extern crate mdbook;
use mdbook::preprocess::{CmdPreprocessor, Preprocessor};
+use mdbook::MDBook;
+use std::path::Path;
fn example() -> CmdPreprocessor {
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);
}
+
+#[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();
+}