use anyhow::{Result, anyhow};
use itertools::Itertools;
use mdbook_preprocessor::{Preprocessor, PreprocessorContext, book::Book};
use config::{BibliographyLocation, Config};
mod bib;
mod config;
#[cfg(test)]
mod tests;
pub struct BibtexPreprocessor;
impl Preprocessor for BibtexPreprocessor {
fn name(&self) -> &str {
"bibtex-preprocessor"
}
fn run(&self, ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {
let config: Config = (&ctx.config).try_into()?;
match config.biblio_location {
BibliographyLocation::Footnotes | BibliographyLocation::Chapter => {
let mut errs = vec![];
book.for_each_chapter_mut(|chapter| {
let mut f = || -> Result<()> {
let mut pass = bib::BibPass::new(&config)?;
pass.collect_citations(chapter)?;
let pass = pass.render()?;
pass.replace_citations(chapter);
pass.add_chapter_bib(chapter);
Ok(())
};
if let Err(e) = f() {
errs.push(e);
}
});
if !errs.is_empty() {
Err(anyhow!(errs.into_iter().map(|e| e.to_string()).join("\n")))?;
}
}
BibliographyLocation::Global => {
let mut pass = bib::BibPass::new(&config)?;
let mut errs = vec![];
book.chapters().for_each(|chapter| {
if let Err(e) = pass.collect_citations(chapter) {
errs.push(e);
}
});
if !errs.is_empty() {
Err(anyhow!(errs.into_iter().map(|e| e.to_string()).join("\n")))?;
}
let pass = pass.render()?;
book.for_each_chapter_mut(|chapter| {
pass.replace_citations(chapter);
});
pass.add_global_bib(&mut book);
}
}
Ok(book)
}
fn supports_renderer(&self, renderer: &str) -> Result<bool> {
Ok(renderer != "not-supported")
}
}