]> git.proxmox.com Git - rustc.git/blame - vendor/mdbook/examples/nop-preprocessor.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / vendor / mdbook / examples / nop-preprocessor.rs
CommitLineData
dc9dc135 1use crate::nop_lib::Nop;
9c376795 2use clap::{Arg, ArgMatches, Command};
9fa01778
XL
3use mdbook::book::Book;
4use mdbook::errors::Error;
5use mdbook::preprocess::{CmdPreprocessor, Preprocessor, PreprocessorContext};
94222f64 6use semver::{Version, VersionReq};
9fa01778
XL
7use std::io;
8use std::process;
9
9c376795
FG
10pub fn make_app() -> Command {
11 Command::new("nop-preprocessor")
9fa01778
XL
12 .about("A mdbook preprocessor which does precisely nothing")
13 .subcommand(
9c376795 14 Command::new("supports")
04454e1e 15 .arg(Arg::new("renderer").required(true))
9fa01778
XL
16 .about("Check whether a renderer is supported by this preprocessor"),
17 )
18}
19
20fn main() {
21 let matches = make_app().get_matches();
22
23 // Users will want to construct their own preprocessor here
24 let preprocessor = Nop::new();
25
26 if let Some(sub_args) = matches.subcommand_matches("supports") {
27 handle_supports(&preprocessor, sub_args);
dc9dc135
XL
28 } else if let Err(e) = handle_preprocessing(&preprocessor) {
29 eprintln!("{}", e);
30 process::exit(1);
9fa01778
XL
31 }
32}
33
34fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<(), Error> {
35 let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?;
36
94222f64
XL
37 let book_version = Version::parse(&ctx.mdbook_version)?;
38 let version_req = VersionReq::parse(mdbook::MDBOOK_VERSION)?;
39
a2a8927a 40 if !version_req.matches(&book_version) {
9fa01778
XL
41 eprintln!(
42 "Warning: The {} plugin was built against version {} of mdbook, \
43 but we're being called from version {}",
44 pre.name(),
45 mdbook::MDBOOK_VERSION,
46 ctx.mdbook_version
47 );
48 }
49
50 let processed_book = pre.run(&ctx, book)?;
51 serde_json::to_writer(io::stdout(), &processed_book)?;
52
53 Ok(())
54}
55
56fn handle_supports(pre: &dyn Preprocessor, sub_args: &ArgMatches) -> ! {
9c376795
FG
57 let renderer = sub_args
58 .get_one::<String>("renderer")
59 .expect("Required argument");
a2a8927a 60 let supported = pre.supports_renderer(renderer);
9fa01778
XL
61
62 // Signal whether the renderer is supported by exiting with 1 or 0.
63 if supported {
64 process::exit(0);
65 } else {
66 process::exit(1);
67 }
68}
69
70/// The actual implementation of the `Nop` preprocessor. This would usually go
71/// in your main `lib.rs` file.
72mod nop_lib {
73 use super::*;
74
75 /// A no-op preprocessor.
76 pub struct Nop;
77
78 impl Nop {
79 pub fn new() -> Nop {
80 Nop
81 }
82 }
83
84 impl Preprocessor for Nop {
85 fn name(&self) -> &str {
86 "nop-preprocessor"
87 }
88
89 fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result<Book, Error> {
90 // In testing we want to tell the preprocessor to blow up by setting a
91 // particular config value
92 if let Some(nop_cfg) = ctx.config.get_preprocessor(self.name()) {
93 if nop_cfg.contains_key("blow-up") {
f035d41b 94 anyhow::bail!("Boom!!1!");
9fa01778
XL
95 }
96 }
97
98 // we *are* a no-op preprocessor after all
99 Ok(book)
100 }
101
102 fn supports_renderer(&self, renderer: &str) -> bool {
103 renderer != "not-supported"
104 }
105 }
9c376795
FG
106
107 #[cfg(test)]
108 mod test {
109 use super::*;
110
111 #[test]
112 fn nop_preprocessor_run() {
113 let input_json = r##"[
114 {
115 "root": "/path/to/book",
116 "config": {
117 "book": {
118 "authors": ["AUTHOR"],
119 "language": "en",
120 "multilingual": false,
121 "src": "src",
122 "title": "TITLE"
123 },
124 "preprocessor": {
125 "nop": {}
126 }
127 },
128 "renderer": "html",
129 "mdbook_version": "0.4.21"
130 },
131 {
132 "sections": [
133 {
134 "Chapter": {
135 "name": "Chapter 1",
136 "content": "# Chapter 1\n",
137 "number": [1],
138 "sub_items": [],
139 "path": "chapter_1.md",
140 "source_path": "chapter_1.md",
141 "parent_names": []
142 }
143 }
144 ],
145 "__non_exhaustive": null
146 }
147 ]"##;
148 let input_json = input_json.as_bytes();
149
150 let (ctx, book) = mdbook::preprocess::CmdPreprocessor::parse_input(input_json).unwrap();
151 let expected_book = book.clone();
152 let result = Nop::new().run(&ctx, book);
153 assert!(result.is_ok());
154
155 // The nop-preprocessor should not have made any changes to the book content.
156 let actual_book = result.unwrap();
157 assert_eq!(actual_book, expected_book);
158 }
159 }
9fa01778 160}