panache_parser/parser/inlines/
mark.rs1use super::core::parse_inline_text;
13use crate::options::ParserOptions;
14use crate::syntax::SyntaxKind;
15use rowan::GreenNodeBuilder;
16
17pub fn try_parse_mark(text: &str) -> Option<(usize, &str)> {
20 let bytes = text.as_bytes();
21
22 if bytes.len() < 4 || bytes[0] != b'=' || bytes[1] != b'=' {
24 return None;
25 }
26
27 let mut pos = 2;
29 let mut found_close = false;
30 while pos + 1 < bytes.len() {
31 if bytes[pos] == b'=' && bytes[pos + 1] == b'=' {
32 found_close = true;
33 break;
34 }
35 pos += 1;
36 }
37
38 if !found_close {
39 return None;
40 }
41
42 let content = &text[2..pos];
43
44 if content.trim().is_empty() {
46 return None;
47 }
48
49 if content.starts_with(char::is_whitespace) || content.ends_with(char::is_whitespace) {
51 return None;
52 }
53
54 let total_len = pos + 2; Some((total_len, content))
56}
57
58pub fn emit_mark(
60 builder: &mut GreenNodeBuilder,
61 inner_text: &str,
62 config: &ParserOptions,
63 suppress_footnote_refs: bool,
64) {
65 builder.start_node(SyntaxKind::MARK.into());
66
67 builder.start_node(SyntaxKind::MARK_MARKER.into());
68 builder.token(SyntaxKind::MARK_MARKER.into(), "==");
69 builder.finish_node();
70
71 parse_inline_text(builder, inner_text, config, false, suppress_footnote_refs);
72
73 builder.start_node(SyntaxKind::MARK_MARKER.into());
74 builder.token(SyntaxKind::MARK_MARKER.into(), "==");
75 builder.finish_node();
76
77 builder.finish_node();
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_simple_mark() {
86 assert_eq!(try_parse_mark("==hi=="), Some((6, "hi")));
87 }
88
89 #[test]
90 fn test_mark_with_spaces_inside_content() {
91 assert_eq!(try_parse_mark("==hello world=="), Some((15, "hello world")));
92 }
93
94 #[test]
95 fn test_mark_requires_non_whitespace_content() {
96 assert_eq!(try_parse_mark("===="), None);
97 assert_eq!(try_parse_mark("== =="), None);
98 }
99
100 #[test]
101 fn test_mark_disallows_whitespace_just_inside_delimiters() {
102 assert_eq!(try_parse_mark("== hi=="), None);
103 assert_eq!(try_parse_mark("==hi =="), None);
104 assert_eq!(try_parse_mark("== hi =="), None);
105 }
106
107 #[test]
108 fn test_mark_allows_neighboring_extra_equals_like_pandoc() {
109 assert_eq!(try_parse_mark("===a==="), Some((6, "=a")));
110 assert_eq!(try_parse_mark("==a==="), Some((5, "a")));
111 assert_eq!(try_parse_mark("====a=="), None);
112 assert_eq!(try_parse_mark("==a===="), Some((5, "a")));
113 }
114}