From 7cc68b512ed095ebc158bcfa6c47e3ddcd0fa24e Mon Sep 17 00:00:00 2001 From: postscriptum Date: Sun, 13 Jul 2025 16:04:14 +0300 Subject: [PATCH] implement snac markdown filter with tests --- src/nex/template.rs | 103 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/src/nex/template.rs b/src/nex/template.rs index 4e3c16c..16c8f38 100644 --- a/src/nex/template.rs +++ b/src/nex/template.rs @@ -27,17 +27,7 @@ impl Template { ) -> String { let mut c = String::with_capacity(content.len() + 128); for l in content.lines() { - if (l.starts_with("http://") - || l.starts_with("https://") - || l.starts_with("nex://") - || l.starts_with("gopher://") - || l.starts_with("gemini://")) - && !l.contains(' ') - && !matches!(self.format, Format::Plain) - { - c.push_str("=> ") - } - c.push_str(l); + format_line(&mut c, l, &self.format); c.push('\n') } self.pattern @@ -110,3 +100,94 @@ impl Template { ) } } + +/// Filter snac markdown +/// https://comam.es/snac-doc/snac.5.html +fn format_line(b: &mut String, l: &str, f: &Format) { + if l.starts_with('*') && l.ends_with('*') { + b.push_str(l.trim_matches('*').trim()) + } else if l.starts_with('~') && l.ends_with('~') { + b.push_str(l.trim_matches('~').trim()) + } else if l.starts_with('_') && l.ends_with('_') { + b.push_str(l.trim_matches('_').trim()) + } else if l.starts_with('#') && !matches!(f, Format::Gemtext) { + b.push_str(l.trim_matches('#').trim()) + } else if l.starts_with('>') && !matches!(f, Format::Gemtext) { + b.push_str(l.trim_matches('>').trim()) + } else if (l.starts_with("http://") + || l.starts_with("https://") + || l.starts_with("nex://") + || l.starts_with("gopher://") + || l.starts_with("gemini://")) + && !l.contains(' ') + && matches!(f, Format::Gemtext | Format::Dir) + { + b.push_str("=> "); + b.push_str(l) + } else { + b.push_str(l) + } +} + +#[test] +fn test() { + fn test(a: &str, b: &str, f: &Format) { + let mut s = String::new(); + format_line(&mut s, a, f); + assert_eq!(s, b); + } + + let f = Format::Dir; + + test("*t*", "t", &f); + test("**t**", "t", &f); + test("~~t~~", "t", &f); + test("__t__", "t", &f); + + test("> t", "t", &f); + test("# t", "t", &f); + test("## t", "t", &f); + test("### t", "t", &f); + + test("gemini://t", "=> gemini://t", &f); + test("gopher://t", "=> gopher://t", &f); + test("http://t", "=> http://t", &f); + test("https://t", "=> https://t", &f); + test("nex://t", "=> nex://t", &f); + + let f = Format::Gemtext; + + test("*t*", "t", &f); + test("**t**", "t", &f); + test("~~t~~", "t", &f); + test("__t__", "t", &f); + + test("> t", "> t", &f); + test("# t", "# t", &f); + test("## t", "## t", &f); + test("### t", "### t", &f); + + test("gemini://t", "=> gemini://t", &f); + test("gopher://t", "=> gopher://t", &f); + test("http://t", "=> http://t", &f); + test("https://t", "=> https://t", &f); + test("nex://t", "=> nex://t", &f); + + let f = Format::Plain; + + test("*t*", "t", &f); + test("**t**", "t", &f); + test("~~t~~", "t", &f); + test("__t__", "t", &f); + + test("> t", "t", &f); + test("# t", "t", &f); + test("## t", "t", &f); + test("### t", "t", &f); + + test("gemini://t", "gemini://t", &f); + test("gopher://t", "gopher://t", &f); + test("http://t", "http://t", &f); + test("https://t", "https://t", &f); + test("nex://t", "nex://t", &f); +}