snapper_fmt/parser/
plaintext.rs1use crate::parser::{FormatParser, Region, flush_prose};
2
3pub 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 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}