From 81a4edb884a0f5e87dc9d6642416849db5165034 Mon Sep 17 00:00:00 2001 From: Noah Hellman Date: Sun, 11 Dec 2022 21:43:22 +0100 Subject: [PATCH] inline: get rid of verbatim state --- src/inline.rs | 177 +++++++++++++++++++++++--------------------------- src/lib.rs | 2 +- 2 files changed, 82 insertions(+), 97 deletions(-) diff --git a/src/inline.rs b/src/inline.rs index 41884a4..030abea 100644 --- a/src/inline.rs +++ b/src/inline.rs @@ -63,8 +63,6 @@ pub struct Parser { lexer: lex::Lexer, /// Span of current event. span: Span, - /// The kind, opener_len and opener_event of the current verbatim container if within one. - verbatim: Option<(Container, usize, usize)>, /// Stack with kind and index of _potential_ openers for typesetting containers. typesets: Vec<(Container, usize)>, /// Stack with index of _potential_ span/link openers. @@ -80,7 +78,6 @@ impl + Clone> Parser { Self { lexer: lex::Lexer::new(chars), span: Span::new(0, 0), - verbatim: None, typesets: Vec::new(), spans: Vec::new(), events: std::collections::VecDeque::new(), @@ -118,18 +115,54 @@ impl + Clone> Parser { } fn parse_verbatim(&mut self, first: &lex::Token) -> Option { - self.verbatim - .map(|(kind, opener_len, opener_event)| { - assert_eq!(self.events[opener_event].kind, EventKind::Enter(kind)); - let kind = if matches!(first.kind, lex::Kind::Seq(lex::Sequence::Backtick)) - && first.len == opener_len + match first.kind { + lex::Kind::Seq(lex::Sequence::Dollar) => { + let math_opt = (first.len <= 2) + .then(|| { + if let Some(lex::Token { + kind: lex::Kind::Seq(lex::Sequence::Backtick), + len, + }) = self.peek() + { + Some(( + if first.len == 2 { + DisplayMath + } else { + InlineMath + }, + *len, + )) + } else { + None + } + }) + .flatten(); + if math_opt.is_some() { + self.eat(); // backticks + } + math_opt + } + lex::Kind::Seq(lex::Sequence::Backtick) => Some((Verbatim, first.len)), + _ => None, + } + .map(|(mut kind, opener_len)| { + let opener_event = self.events.len(); + self.events.push_back(Event { + kind: EventKind::Enter(kind), + span: self.span, + }); + + let mut span_inner = Span::empty_at(self.span.end()); + + while let Some(t) = self.eat() { + if matches!(t.kind, lex::Kind::Seq(lex::Sequence::Backtick)) && t.len == opener_len { - self.verbatim = None; - let kind = if matches!(kind, Verbatim) + if matches!(kind, Verbatim) && matches!( self.lexer.peek().map(|t| &t.kind), Some(lex::Kind::Open(Delimiter::BraceEqual)) - ) { + ) + { let mut ahead = self.lexer.inner().clone(); let mut end = false; let len = (&mut ahead) @@ -146,64 +179,28 @@ impl + Clone> Parser { if len > 0 && end { self.lexer = lex::Lexer::new(ahead); let span_format = Span::by_len(self.span.end() + "{=".len(), len); - self.events[opener_event].kind = EventKind::Enter(RawFormat); + kind = RawFormat; + self.events[opener_event].kind = EventKind::Enter(kind); self.events[opener_event].span = span_format; self.span = span_format; - RawFormat - } else { - Verbatim } - } else { - kind - }; - EventKind::Exit(kind) - } else { - EventKind::Str - }; - Event { - kind, - span: self.span, - } - }) - .or_else(|| { - match first.kind { - lex::Kind::Seq(lex::Sequence::Dollar) => { - let math_opt = (first.len <= 2) - .then(|| { - if let Some(lex::Token { - kind: lex::Kind::Seq(lex::Sequence::Backtick), - len, - }) = self.peek() - { - Some(( - if first.len == 2 { - DisplayMath - } else { - InlineMath - }, - *len, - )) - } else { - None - } - }) - .flatten(); - if math_opt.is_some() { - self.eat(); // backticks - } - math_opt } - lex::Kind::Seq(lex::Sequence::Backtick) => Some((Verbatim, first.len)), - _ => None, + break; } - .map(|(kind, opener_len)| { - self.verbatim = Some((kind, opener_len, self.events.len())); - Event { - kind: EventKind::Enter(kind), - span: self.span, - } - }) - }) + span_inner = span_inner.extend(t.len); + self.reset_span(); + } + + self.events.push_back(Event { + kind: EventKind::Str, + span: span_inner, + }); + + Event { + kind: EventKind::Exit(kind), + span: self.span, + } + }) } fn parse_span(&mut self, first: &lex::Token) -> Option { @@ -339,7 +336,6 @@ impl + Clone> Iterator for Parser { fn next(&mut self) -> Option { while self.events.is_empty() || !self.typesets.is_empty() - || self.verbatim.is_some() // might be raw format || self // for merge .events .back() @@ -352,38 +348,27 @@ impl + Clone> Iterator for Parser { } } - self.events - .pop_front() - .map(|e| { - if matches!(e.kind, EventKind::Str) { - // merge str events - let mut span = e.span; - while self - .events - .front() - .map_or(false, |ev| matches!(ev.kind, EventKind::Str)) - { - let ev = self.events.pop_front().unwrap(); - assert_eq!(span.end(), ev.span.start()); - span = span.union(ev.span); - } - Event { - kind: EventKind::Str, - span, - } - } else { - e + self.events.pop_front().map(|e| { + if matches!(e.kind, EventKind::Str) { + // merge str events + let mut span = e.span; + while self + .events + .front() + .map_or(false, |ev| matches!(ev.kind, EventKind::Str)) + { + let ev = self.events.pop_front().unwrap(); + assert_eq!(span.end(), ev.span.start()); + span = span.union(ev.span); } - }) - .or_else(|| { - self.verbatim.map(|(kind, _, _)| { - self.verbatim = None; - Event { - kind: EventKind::Exit(kind), - span: self.span, - } - }) - }) + Event { + kind: EventKind::Str, + span, + } + } else { + e + } + }) } } diff --git a/src/lib.rs b/src/lib.rs index 5869895..7593769 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -502,7 +502,7 @@ mod test { #[test] fn raw_inline() { test_parse!( - "`raw\nraw`{=format}", + "``raw\nraw``{=format}", Start(Paragraph, Attributes::none()), Start(RawInline { format: "format" }, Attributes::none()), Str("raw\nraw"),