From c36009db461aba73253ae7fb027eb50a14fc94b8 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Fri, 2 Jun 2023 11:09:39 -0400 Subject: [PATCH] Handle leaving quote mode properly; --- src/message/parser.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/message/parser.rs b/src/message/parser.rs index 1a3ba0f..98e531e 100644 --- a/src/message/parser.rs +++ b/src/message/parser.rs @@ -26,7 +26,7 @@ pub enum GemtextNode { Heading3(String), ListItem(String), Quote(String), - Preformatted(String), + Preformatted(Option, String), Link(Link), } @@ -42,7 +42,10 @@ impl fmt::Display for GemtextNode { Self::Heading3(h) => writeln!(f, "### {h}"), Self::ListItem(l) => writeln!(f, "* {l}"), Self::Quote(q) => writeln!(f, "> {q}"), - Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"), + Self::Preformatted(a, p) => match a { + None => writeln!(f, "```\n{}\n```", p), + Some(alt) => writeln!(f, "```{alt}\n{}\n```", p), + }, Self::Link(l) => writeln!(f, "=> {l}"), } } @@ -155,13 +158,25 @@ impl<'a> Parser<'a> { self.lines.push(GemtextNode::parse_list_item(line)); } - fn quote(&mut self, line: &'a str) { + fn enter_quote(&mut self, line: &'a str) { match line.split_once(char::is_whitespace) { Some((prefix, suffix)) if prefix == ">" => self.state = State::Quote(vec![suffix]), _ => self.lines.push(GemtextNode::Text(line.to_string())), } } + fn leave_quote(&mut self, line: &'a str) { + match &mut self.state { + State::Quote(q) => { + let quote = q.join("\n").to_string(); + self.lines.push(GemtextNode::Quote(quote)); + } + _ => panic!("Attempt to parse as quote when not in quote mode"), + } + self.state = State::Normal; + self.lines.push(GemtextNode::Text(line.to_string())); + } + fn enter_preformatted(&mut self, line: &'a str) { let alt = if line.len() > 3 { Some(line[3..].trim()) @@ -196,7 +211,7 @@ impl<'a> Parser<'a> { s if s.starts_with("=>") => self.link(s), s if s.starts_with('#') => self.heading(s), s if s.starts_with('*') => self.list_item(s), - s if s.starts_with('>') => self.quote(s), + s if s.starts_with('>') => self.enter_quote(s), s if s.starts_with("```") => self.enter_preformatted(s), s if s.starts_with('<') => self.senders(s), s if s.starts_with(':') => self.recipients(s), @@ -217,6 +232,13 @@ impl<'a> Parser<'a> { } fn parse_quote(&mut self, line: &'a str) { - todo!() + if let Some(suffix) = line.strip_prefix('>') { + match &mut self.state { + State::Quote(q) => q.push(suffix.trim()), + _ => panic!("Attempt to parse as quote when not in quote mode"), + } + } else { + self.leave_quote(line); + } } }