use mdbook::BookItem;
use mdbook::book::Book;
use mdbook::errors::Error;
use mdbook::preprocess::{Preprocessor, PreprocessorContext};
use regex::Regex;
use std::path::Path;
use std::path::PathBuf;
#[derive(Default)]
pub struct SelfPathPreprocessor;
impl SelfPathPreprocessor {
pub fn new() -> SelfPathPreprocessor {
SelfPathPreprocessor
}
}
impl Preprocessor for SelfPathPreprocessor {
fn name(&self) -> &str {
"selfpath"
}
fn run(&self, ctx: &PreprocessorContext, mut book: Book) -> Result<Book, Error> {
let include_ext = ctx
.config
.get_preprocessor(self.name())
.and_then(|table| table.get("include-file-ext"))
.and_then(|val| val.as_bool())
.unwrap_or(true);
let src_dir_name = &ctx.config.book.src;
let selfpath_re = Regex::new(r"\{\{\s*selfpath\s*\}\}").unwrap();
let selftitle_re = Regex::new(r"\{\{\s*selftitle\s*\}\}").unwrap();
book.for_each_mut(|item: &mut BookItem| {
if let BookItem::Chapter(chapter) = item {
if let Some(ref source_path) = chapter.source_path {
let mut rel_path = PathBuf::new();
if src_dir_name.as_path() != Path::new(".") {
rel_path.push(&src_dir_name)
}
rel_path.push(source_path);
if !include_ext {
rel_path.set_extension("");
}
let rel_path_str = rel_path.to_string_lossy().replace('\\', "/");
chapter.content = selfpath_re.replace_all(&chapter.content, rel_path_str.as_str()).to_string();
let filename = source_path.file_name().and_then(|s| s.to_str()).unwrap_or("noname");
let without_ext = filename
.strip_suffix(".md")
.unwrap_or(filename);
chapter.content = selftitle_re.replace_all(&chapter.content, without_ext).to_string();
}
}
});
Ok(book)
}
fn supports_renderer(&self, _renderer: &str) -> bool {
true
}
}