Skip to main content

snapper_fmt/parser/
mod.rs

1pub mod latex;
2pub mod markdown;
3pub mod org;
4pub mod plaintext;
5
6/// A region of text classified by a format parser.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum Region {
9    /// Prose text that should be reflowed with semantic line breaks.
10    Prose(String),
11    /// Structural content that must pass through unchanged.
12    Structure(String),
13    /// Blank line(s) preserved as paragraph separators.
14    BlankLines(String),
15}
16
17/// Trait for format-specific parsers that classify text into regions.
18pub trait FormatParser {
19    fn parse(&self, input: &str) -> Vec<Region>;
20}
21
22/// Check if a line contains a snapper pragma.
23/// Returns Some(false) for "snapper:off", Some(true) for "snapper:on", None otherwise.
24pub fn check_pragma(line: &str) -> Option<bool> {
25    let trimmed = line.trim();
26    // Strip format-specific comment markers
27    let content = trimmed
28        .strip_prefix("# ") // Org comment
29        .or_else(|| trimmed.strip_prefix("% ")) // LaTeX comment
30        .or_else(|| {
31            // HTML/Markdown comment
32            trimmed
33                .strip_prefix("<!-- ")
34                .and_then(|s| s.strip_suffix(" -->"))
35        })
36        .unwrap_or(trimmed); // Plaintext: bare pragma
37    let content = content.trim();
38    if content == "snapper:off" {
39        Some(false)
40    } else if content == "snapper:on" {
41        Some(true)
42    } else {
43        None
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn pragma_org_comment() {
53        assert_eq!(check_pragma("# snapper:off"), Some(false));
54        assert_eq!(check_pragma("# snapper:on"), Some(true));
55    }
56
57    #[test]
58    fn pragma_latex_comment() {
59        assert_eq!(check_pragma("% snapper:off"), Some(false));
60        assert_eq!(check_pragma("% snapper:on"), Some(true));
61    }
62
63    #[test]
64    fn pragma_html_comment() {
65        assert_eq!(check_pragma("<!-- snapper:off -->"), Some(false));
66        assert_eq!(check_pragma("<!-- snapper:on -->"), Some(true));
67    }
68
69    #[test]
70    fn pragma_bare() {
71        assert_eq!(check_pragma("snapper:off"), Some(false));
72        assert_eq!(check_pragma("snapper:on"), Some(true));
73    }
74
75    #[test]
76    fn pragma_none() {
77        assert_eq!(check_pragma("regular text"), None);
78        assert_eq!(check_pragma("# a comment"), None);
79        assert_eq!(check_pragma(""), None);
80    }
81}