From 517cabe8ec54d0bf5f5f9cc9089d76a1fad7bb6a Mon Sep 17 00:00:00 2001 From: Minijackson Date: Sun, 7 Nov 2021 23:09:34 +0100 Subject: initial commit with PoC --- src/utils.rs | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/utils.rs (limited to 'src/utils.rs') diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..8928cfb --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,116 @@ +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; -- cgit v1.2.3