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