use std::path::PathBuf; pub fn pandoc_stringify(inlines: &[pandoc_ast::Inline]) -> String { fn pandoc_stringify_(result: &mut String, inlines: &[pandoc_ast::Inline]) { for inline in inlines { match inline { pandoc_ast::Inline::Str(s) | pandoc_ast::Inline::Code(_, s) | pandoc_ast::Inline::Math(_, s) => result.push_str(s), pandoc_ast::Inline::Emph(inner) | pandoc_ast::Inline::Underline(inner) | pandoc_ast::Inline::Strong(inner) | pandoc_ast::Inline::Strikeout(inner) | pandoc_ast::Inline::Superscript(inner) | pandoc_ast::Inline::Subscript(inner) | pandoc_ast::Inline::SmallCaps(inner) | pandoc_ast::Inline::Quoted(_, inner) | pandoc_ast::Inline::Cite(_, inner) | pandoc_ast::Inline::Link(_, inner, _) | pandoc_ast::Inline::Image(_, inner, _) | pandoc_ast::Inline::Span(_, inner) => pandoc_stringify_(result, inner), pandoc_ast::Inline::Space => result.push(' '), pandoc_ast::Inline::SoftBreak => todo!(), pandoc_ast::Inline::LineBreak => todo!(), pandoc_ast::Inline::RawInline(_, _) => todo!(), pandoc_ast::Inline::Note(_) => todo!(), } } } let mut result = String::new(); pandoc_stringify_(&mut result, inlines); result } /// Follows the algorithm specified in the Pandoc manual[1] /// /// [1]: #[derive(Debug)] pub struct AutoIdentifier(pub String); impl std::ops::Deref for AutoIdentifier { type Target = String; fn deref(&self) -> &Self::Target { &self.0 } } impl From for String { fn from(id: AutoIdentifier) -> Self { id.0 } } impl From<&[pandoc_ast::Inline]> for AutoIdentifier { fn from(inlines: &[pandoc_ast::Inline]) -> Self { let text = pandoc_stringify(inlines); AutoIdentifier::from(text.as_str()) } } impl From<&str> for AutoIdentifier { fn from(text: &str) -> Self { let id = text .chars() .skip_while(|ch| !ch.is_alphabetic()) .filter_map(|ch| { if !ch.is_ascii_alphanumeric() && !ch.is_whitespace() && ch != '_' && ch != '-' && ch != '.' { return None; } if ch.is_whitespace() { return Some('-'); } Some(ch.to_ascii_lowercase()) }) .collect(); AutoIdentifier(id) } } pub trait PandocOutputExt { fn buffer(self) -> String; fn file(self) -> PathBuf; } impl PandocOutputExt for pandoc::PandocOutput { fn buffer(self) -> String { match self { pandoc::PandocOutput::ToBuffer(buffer) => buffer, pandoc::PandocOutput::ToBufferRaw(_) => { panic!("Expected text pandoc output, found binary format") } pandoc::PandocOutput::ToFile(_) => { panic!("Expected buffered pandoc output, found file") } } } fn file(self) -> PathBuf { match self { pandoc::PandocOutput::ToFile(file) => file, _ => panic!("Expected file pandoc output, found buffer"), } } } pub type PandocMeta = pandoc_ast::Map;