1use log::debug;
2use mdbook::preprocess::{Preprocessor, PreprocessorContext, CmdPreprocessor};
3use mdbook::book::Book;
4use mdbook::errors::Error;
5use clap::ArgMatches;
6use std::{process, io};
7use mdbook::BookItem;
8use regex::Regex;
9
10#[macro_use]
11extern crate lazy_static;
12
13lazy_static! {
14 static ref RE : Regex= Regex::new(r"==(?P<c>\S+?)==[^>]").unwrap();
16}
17
18pub fn replace_all(s: &str) -> String {
19 RE.replace_all(s, "<mark>$c</mark>").into_owned()
20}
21
22pub fn handle_each_item(book_item: &mut BookItem) {
23 match book_item {
24 BookItem::Chapter(chapter) => {
25 chapter.content = replace_all(&chapter.content);
26 for item in &mut chapter.sub_items {
27 handle_each_item(item);
28 }
29 }
30 _ => {}
31 }
32}
33
34pub struct MarkPreprocessor {}
35
36impl Preprocessor for MarkPreprocessor {
37
38 fn name(&self) -> &str {
39 "mark"
40 }
41
42 fn run(&self, _: &PreprocessorContext, mut book: Book) -> Result<Book, Error> {
43 let ii = &mut book.sections;
44 for section in ii {
45 handle_each_item(section);
46 }
47 Ok(book)
48 }
49
50 fn supports_renderer(&self, _renderer: &str) -> bool {
51 _renderer == "html"
52 }
53}
54
55pub fn handle_preprocessor(pre: &dyn Preprocessor) -> Result<(), Error> {
56 debug!("mark start");
57 let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?;
58
59 if ctx.mdbook_version != mdbook::MDBOOK_VERSION {
60 eprintln!(
63 "Warning: The {} plugin was built against version {} of mdbook, \
64 but we're being called from version {}",
65 pre.name(),
66 mdbook::MDBOOK_VERSION,
67 ctx.mdbook_version
68 );
69 }
70
71 let processed_book = pre.run(&ctx, book)?;
72
73 serde_json::to_writer(io::stdout(), &processed_book)?;
74
75 Ok(())
76}
77
78pub fn handle_supports(pre: &dyn Preprocessor, sub_args: &ArgMatches) -> ! {
79 let renderer = sub_args.value_of("renderer").expect("Required argument");
80 let supported = pre.supports_renderer(&renderer);
81
82 if supported {
84 process::exit(0);
85 } else {
86 process::exit(1);
87 }
88}