Skip to main content

snapper_fmt/parser/
plaintext.rs

1use crate::parser::{FormatParser, Region, flush_prose};
2
3/// Trivial parser: everything is prose, blank lines are preserved.
4pub struct PlaintextParser;
5
6impl FormatParser for PlaintextParser {
7    fn parse(&self, input: &str) -> Vec<Region> {
8        let mut regions = Vec::new();
9        let mut current_prose = String::new();
10        let mut pragma_off = false;
11
12        for line in input.lines() {
13            // Check for snapper:off/on pragmas
14            if let Some(on) = super::check_pragma(line) {
15                flush_prose(&mut current_prose, &mut regions);
16                pragma_off = !on;
17                regions.push(Region::Structure(format!("{line}\n")));
18                continue;
19            }
20
21            if pragma_off {
22                flush_prose(&mut current_prose, &mut regions);
23                regions.push(Region::Structure(format!("{line}\n")));
24                continue;
25            }
26
27            if line.trim().is_empty() {
28                flush_prose(&mut current_prose, &mut regions);
29                regions.push(Region::BlankLines(format!("{line}\n")));
30            } else {
31                if !current_prose.is_empty() {
32                    current_prose.push(' ');
33                }
34                current_prose.push_str(line.trim());
35            }
36        }
37
38        flush_prose(&mut current_prose, &mut regions);
39        regions
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn simple_paragraph() {
49        let input = "Hello world. This is a test.\nAnother line here.";
50        let regions = PlaintextParser.parse(input);
51        assert_eq!(
52            regions,
53            vec![Region::Prose(
54                "Hello world. This is a test. Another line here.".to_string()
55            )]
56        );
57    }
58
59    #[test]
60    fn two_paragraphs() {
61        let input = "First paragraph.\n\nSecond paragraph.";
62        let regions = PlaintextParser.parse(input);
63        assert_eq!(
64            regions,
65            vec![
66                Region::Prose("First paragraph.".to_string()),
67                Region::BlankLines("\n".to_string()),
68                Region::Prose("Second paragraph.".to_string()),
69            ]
70        );
71    }
72
73    #[test]
74    fn empty_input() {
75        let regions = PlaintextParser.parse("");
76        assert!(regions.is_empty());
77    }
78}