Handle leaving quote mode properly;

This commit is contained in:
Nathan Fisher 2023-06-02 11:09:39 -04:00
parent 5113775933
commit c36009db46

View file

@ -26,7 +26,7 @@ pub enum GemtextNode {
Heading3(String), Heading3(String),
ListItem(String), ListItem(String),
Quote(String), Quote(String),
Preformatted(String), Preformatted(Option<String>, String),
Link(Link), Link(Link),
} }
@ -42,7 +42,10 @@ impl fmt::Display for GemtextNode {
Self::Heading3(h) => writeln!(f, "### {h}"), Self::Heading3(h) => writeln!(f, "### {h}"),
Self::ListItem(l) => writeln!(f, "* {l}"), Self::ListItem(l) => writeln!(f, "* {l}"),
Self::Quote(q) => writeln!(f, "> {q}"), 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}"), Self::Link(l) => writeln!(f, "=> {l}"),
} }
} }
@ -155,13 +158,25 @@ impl<'a> Parser<'a> {
self.lines.push(GemtextNode::parse_list_item(line)); 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) { match line.split_once(char::is_whitespace) {
Some((prefix, suffix)) if prefix == ">" => self.state = State::Quote(vec![suffix]), Some((prefix, suffix)) if prefix == ">" => self.state = State::Quote(vec![suffix]),
_ => self.lines.push(GemtextNode::Text(line.to_string())), _ => 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) { fn enter_preformatted(&mut self, line: &'a str) {
let alt = if line.len() > 3 { let alt = if line.len() > 3 {
Some(line[3..].trim()) 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.link(s),
s if s.starts_with('#') => self.heading(s), s if s.starts_with('#') => self.heading(s),
s if s.starts_with('*') => self.list_item(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.enter_preformatted(s),
s if s.starts_with('<') => self.senders(s), s if s.starts_with('<') => self.senders(s),
s if s.starts_with(':') => self.recipients(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) { 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);
}
} }
} }