diff options
Diffstat (limited to 'src/utils.rs')
-rw-r--r-- | src/utils.rs | 116 |
1 files changed, 116 insertions, 0 deletions
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 @@ | |||
1 | use std::path::PathBuf; | ||
2 | |||
3 | pub fn pandoc_stringify(inlines: &[pandoc_ast::Inline]) -> String { | ||
4 | fn pandoc_stringify_(result: &mut String, inlines: &[pandoc_ast::Inline]) { | ||
5 | for inline in inlines { | ||
6 | match inline { | ||
7 | pandoc_ast::Inline::Str(s) | ||
8 | | pandoc_ast::Inline::Code(_, s) | ||
9 | | pandoc_ast::Inline::Math(_, s) => result.push_str(s), | ||
10 | pandoc_ast::Inline::Emph(inner) | ||
11 | | pandoc_ast::Inline::Underline(inner) | ||
12 | | pandoc_ast::Inline::Strong(inner) | ||
13 | | pandoc_ast::Inline::Strikeout(inner) | ||
14 | | pandoc_ast::Inline::Superscript(inner) | ||
15 | | pandoc_ast::Inline::Subscript(inner) | ||
16 | | pandoc_ast::Inline::SmallCaps(inner) | ||
17 | | pandoc_ast::Inline::Quoted(_, inner) | ||
18 | | pandoc_ast::Inline::Cite(_, inner) | ||
19 | | pandoc_ast::Inline::Link(_, inner, _) | ||
20 | | pandoc_ast::Inline::Image(_, inner, _) | ||
21 | | pandoc_ast::Inline::Span(_, inner) => pandoc_stringify_(result, inner), | ||
22 | pandoc_ast::Inline::Space => result.push(' '), | ||
23 | pandoc_ast::Inline::SoftBreak => todo!(), | ||
24 | pandoc_ast::Inline::LineBreak => todo!(), | ||
25 | pandoc_ast::Inline::RawInline(_, _) => todo!(), | ||
26 | pandoc_ast::Inline::Note(_) => todo!(), | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | |||
31 | let mut result = String::new(); | ||
32 | pandoc_stringify_(&mut result, inlines); | ||
33 | result | ||
34 | } | ||
35 | |||
36 | /// Follows the algorithm specified in the Pandoc manual[1] | ||
37 | /// | ||
38 | /// [1]: <https://pandoc.org/MANUAL.html#extension-auto_identifiers> | ||
39 | #[derive(Debug)] | ||
40 | pub struct AutoIdentifier(pub String); | ||
41 | |||
42 | impl std::ops::Deref for AutoIdentifier { | ||
43 | type Target = String; | ||
44 | |||
45 | fn deref(&self) -> &Self::Target { | ||
46 | &self.0 | ||
47 | } | ||
48 | } | ||
49 | |||
50 | impl From<AutoIdentifier> for String { | ||
51 | fn from(id: AutoIdentifier) -> Self { | ||
52 | id.0 | ||
53 | } | ||
54 | } | ||
55 | |||
56 | impl From<&[pandoc_ast::Inline]> for AutoIdentifier { | ||
57 | fn from(inlines: &[pandoc_ast::Inline]) -> Self { | ||
58 | let text = pandoc_stringify(inlines); | ||
59 | AutoIdentifier::from(text.as_str()) | ||
60 | } | ||
61 | } | ||
62 | |||
63 | impl From<&str> for AutoIdentifier { | ||
64 | fn from(text: &str) -> Self { | ||
65 | let id = text | ||
66 | .chars() | ||
67 | .skip_while(|ch| !ch.is_alphabetic()) | ||
68 | .filter_map(|ch| { | ||
69 | if !ch.is_ascii_alphanumeric() | ||
70 | && !ch.is_whitespace() | ||
71 | && ch != '_' | ||
72 | && ch != '-' | ||
73 | && ch != '.' | ||
74 | { | ||
75 | return None; | ||
76 | } | ||
77 | |||
78 | if ch.is_whitespace() { | ||
79 | return Some('-'); | ||
80 | } | ||
81 | |||
82 | Some(ch.to_ascii_lowercase()) | ||
83 | }) | ||
84 | .collect(); | ||
85 | |||
86 | AutoIdentifier(id) | ||
87 | } | ||
88 | } | ||
89 | |||
90 | pub trait PandocOutputExt { | ||
91 | fn buffer(self) -> String; | ||
92 | fn file(self) -> PathBuf; | ||
93 | } | ||
94 | |||
95 | impl PandocOutputExt for pandoc::PandocOutput { | ||
96 | fn buffer(self) -> String { | ||
97 | match self { | ||
98 | pandoc::PandocOutput::ToBuffer(buffer) => buffer, | ||
99 | pandoc::PandocOutput::ToBufferRaw(_) => { | ||
100 | panic!("Expected text pandoc output, found binary format") | ||
101 | } | ||
102 | pandoc::PandocOutput::ToFile(_) => { | ||
103 | panic!("Expected buffered pandoc output, found file") | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | |||
108 | fn file(self) -> PathBuf { | ||
109 | match self { | ||
110 | pandoc::PandocOutput::ToFile(file) => file, | ||
111 | _ => panic!("Expected file pandoc output, found buffer"), | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | pub type PandocMeta = pandoc_ast::Map<String, pandoc_ast::MetaValue>; | ||