mdbook_preprocessor_utils/
lib.rs1use std::{
2 env,
3 io::{self, Write},
4 process,
5};
6
7use chrono::Local;
8use clap::{arg, Command, CommandFactory};
9use env_logger::Builder;
10use log::LevelFilter;
11use mdbook::{
12 errors::Error,
13 preprocess::{CmdPreprocessor, Preprocessor},
14};
15use semver::{Version, VersionReq};
16
17mod copy_assets;
18mod html;
19mod processor;
20#[cfg(feature = "testing")]
21pub mod testing;
22
23pub use copy_assets::copy_assets;
24pub use html::HtmlElementBuilder;
25pub use mdbook;
26pub use processor::{Asset, SimplePreprocessor};
27pub use rayon;
28
29fn init_logger() {
32 let mut builder = Builder::new();
33
34 builder.format(|formatter, record| {
35 writeln!(
36 formatter,
37 "{} [{}] ({}): {}",
38 Local::now().format("%Y-%m-%d %H:%M:%S"),
39 record.level(),
40 record.target(),
41 record.args()
42 )
43 });
44
45 if let Ok(var) = env::var("RUST_LOG") {
46 builder.parse_filters(&var);
47 } else {
48 builder.filter(None, LevelFilter::Info);
50 builder.filter(Some("html5ever"), LevelFilter::Error);
52 }
53
54 builder.init();
55}
56
57pub fn main<P: SimplePreprocessor>() {
58 init_logger();
59
60 let args = P::Args::command()
61 .subcommand(Command::new("supports").arg(arg!(<renderer> "Checks if renderer is supported")))
62 .get_matches();
63
64 let preprocessor = processor::SimplePreprocessorDriver::<P>::new();
65
66 match args.subcommand() {
67 Some(("supports", m)) => {
68 let renderer = m.get_one::<String>("renderer").unwrap();
69 handle_supports(&preprocessor, renderer);
70 }
71 _ => {
72 if let Err(e) = handle_preprocessing(&preprocessor) {
73 eprintln!("{}", e);
74 process::exit(1);
75 }
76 }
77 }
78}
79
80fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<(), Error> {
81 let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?;
82
83 let book_version = Version::parse(&ctx.mdbook_version)?;
84 let version_req = VersionReq::parse(mdbook::MDBOOK_VERSION)?;
85
86 if !version_req.matches(&book_version) {
87 eprintln!(
88 "Warning: The {} plugin was built against version {} of mdbook, \
89 but we're being called from version {}",
90 pre.name(),
91 mdbook::MDBOOK_VERSION,
92 ctx.mdbook_version
93 );
94 }
95
96 let processed_book = pre.run(&ctx, book)?;
97 serde_json::to_writer(io::stdout(), &processed_book)?;
98
99 Ok(())
100}
101
102fn handle_supports(pre: &dyn Preprocessor, renderer: &str) -> ! {
103 let supported = pre.supports_renderer(renderer);
104
105 if supported {
107 process::exit(0);
108 } else {
109 process::exit(1);
110 }
111}