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