inline: add ControlFlow enum
needed to indicate that more input is needed this is needed only for multiline attributes that require backtracking
This commit is contained in:
parent
7133de94bb
commit
3d42820001
1 changed files with 44 additions and 30 deletions
|
@ -9,6 +9,7 @@ use lex::Symbol;
|
|||
|
||||
use Atom::*;
|
||||
use Container::*;
|
||||
use ControlFlow::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Atom {
|
||||
|
@ -224,6 +225,15 @@ pub struct Parser<'s> {
|
|||
pub(crate) store_cowstrs: Vec<CowStr<'s>>,
|
||||
}
|
||||
|
||||
enum ControlFlow {
|
||||
/// At least one event has been emitted, continue parsing the line.
|
||||
Continue,
|
||||
/// Next line is needed to emit an event.
|
||||
Next,
|
||||
/// Parsing of the line is completed.
|
||||
Done,
|
||||
}
|
||||
|
||||
impl<'s> Parser<'s> {
|
||||
pub fn new(src: &'s str) -> Self {
|
||||
Self {
|
||||
|
@ -248,18 +258,18 @@ impl<'s> Parser<'s> {
|
|||
self.store_cowstrs.clear();
|
||||
}
|
||||
|
||||
fn push_sp(&mut self, kind: EventKind, span: Span) -> Option<()> {
|
||||
fn push_sp(&mut self, kind: EventKind, span: Span) -> Option<ControlFlow> {
|
||||
self.events.push_back(Event { kind, span });
|
||||
Some(())
|
||||
Some(Continue)
|
||||
}
|
||||
|
||||
fn push(&mut self, kind: EventKind) -> Option<()> {
|
||||
fn push(&mut self, kind: EventKind) -> Option<ControlFlow> {
|
||||
self.push_sp(kind, self.input.span)
|
||||
}
|
||||
|
||||
fn parse_event(&mut self) -> Option<()> {
|
||||
fn parse_event(&mut self) -> ControlFlow {
|
||||
self.input.reset_span();
|
||||
self.input.eat().map(|first| {
|
||||
if let Some(first) = self.input.eat() {
|
||||
self.parse_verbatim(&first)
|
||||
.or_else(|| self.parse_attributes(&first))
|
||||
.or_else(|| self.parse_autolink(&first))
|
||||
|
@ -267,13 +277,15 @@ impl<'s> Parser<'s> {
|
|||
.or_else(|| self.parse_footnote_reference(&first))
|
||||
.or_else(|| self.parse_container(&first))
|
||||
.or_else(|| self.parse_atom(&first))
|
||||
.unwrap_or_else(|| {
|
||||
self.push(EventKind::Str);
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| self.push(EventKind::Str).unwrap())
|
||||
} else if self.input.last() {
|
||||
Done
|
||||
} else {
|
||||
Next
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_verbatim(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_verbatim(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
if let Some(VerbatimState {
|
||||
event_opener,
|
||||
len_opener,
|
||||
|
@ -335,7 +347,7 @@ impl<'s> Parser<'s> {
|
|||
)
|
||||
})
|
||||
{
|
||||
return Some(()); // skip whitespace
|
||||
return Some(Continue); // skip whitespace
|
||||
}
|
||||
} else {
|
||||
*non_whitespace_encountered = true;
|
||||
|
@ -343,7 +355,7 @@ impl<'s> Parser<'s> {
|
|||
}
|
||||
self.push(EventKind::Str);
|
||||
};
|
||||
Some(())
|
||||
Some(Continue)
|
||||
} else {
|
||||
let (ty, len_opener) = match first.kind {
|
||||
lex::Kind::DollarBacktick(l) if first.len - l as usize == 1 => {
|
||||
|
@ -368,7 +380,7 @@ impl<'s> Parser<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_attributes(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_attributes(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
if first.kind == lex::Kind::Open(Delimiter::Brace) {
|
||||
let mut ahead = self.input.lexer.ahead().chars();
|
||||
let (mut attr_len, mut has_attr) = attr::valid(std::iter::once('{').chain(&mut ahead));
|
||||
|
@ -394,14 +406,14 @@ impl<'s> Parser<'s> {
|
|||
} else {
|
||||
self.push_sp(EventKind::Placeholder, self.input.span.empty_before());
|
||||
}
|
||||
return Some(());
|
||||
return Some(Continue);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn parse_autolink(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_autolink(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
if first.kind == lex::Kind::Sym(Symbol::Lt) {
|
||||
let mut ahead = self.input.lexer.ahead().chars();
|
||||
let mut end = false;
|
||||
|
@ -433,7 +445,7 @@ impl<'s> Parser<'s> {
|
|||
None
|
||||
}
|
||||
|
||||
fn parse_symbol(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_symbol(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
if first.kind == lex::Kind::Sym(Symbol::Colon) {
|
||||
let mut ahead = self.input.lexer.ahead().chars();
|
||||
let mut end = false;
|
||||
|
@ -454,13 +466,13 @@ impl<'s> Parser<'s> {
|
|||
self.input.span = self.input.span.after(len);
|
||||
self.push(EventKind::Atom(Symbol));
|
||||
self.input.span = self.input.span.after(1);
|
||||
return Some(());
|
||||
return Some(Continue);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
if first.kind == lex::Kind::Open(Delimiter::Bracket)
|
||||
&& matches!(
|
||||
self.input.peek(),
|
||||
|
@ -497,13 +509,13 @@ impl<'s> Parser<'s> {
|
|||
self.input.span = self.input.span.after(len);
|
||||
self.push(EventKind::Atom(FootnoteReference));
|
||||
self.input.span = self.input.span.after(1);
|
||||
return Some(());
|
||||
return Some(Continue);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn parse_container(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_container(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
self.openers
|
||||
.iter()
|
||||
.rposition(|(o, _)| o.closed_by(first.kind))
|
||||
|
@ -642,7 +654,7 @@ impl<'s> Parser<'s> {
|
|||
),
|
||||
};
|
||||
self.events.drain(e_opener..);
|
||||
Some(())
|
||||
Some(Continue)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -713,7 +725,7 @@ impl<'s> Parser<'s> {
|
|||
})
|
||||
}
|
||||
|
||||
fn parse_atom(&mut self, first: &lex::Token) -> Option<()> {
|
||||
fn parse_atom(&mut self, first: &lex::Token) -> Option<ControlFlow> {
|
||||
let atom = match first.kind {
|
||||
lex::Kind::Newline => Softbreak,
|
||||
lex::Kind::Hardbreak => Hardbreak,
|
||||
|
@ -747,7 +759,7 @@ impl<'s> Parser<'s> {
|
|||
self.push_sp(EventKind::Atom(atom), self.input.span.with_len(l));
|
||||
self.input.span = self.input.span.skip(l);
|
||||
});
|
||||
return Some(());
|
||||
return Some(Continue);
|
||||
}
|
||||
lex::Kind::Open(Delimiter::BraceQuote1) => Quote {
|
||||
ty: QuoteType::Single,
|
||||
|
@ -981,16 +993,18 @@ impl<'s> Iterator for Parser<'s> {
|
|||
.back()
|
||||
.map_or(false, |ev| matches!(ev.kind, EventKind::Str))
|
||||
{
|
||||
if self.parse_event().is_none() {
|
||||
if self.input.last() {
|
||||
break;
|
||||
} else if let Some(l) = self.input.ahead.pop_front() {
|
||||
match self.parse_event() {
|
||||
Continue => {}
|
||||
Done => break,
|
||||
Next => {
|
||||
if let Some(l) = self.input.ahead.pop_front() {
|
||||
self.input.set_current_line(l);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// automatically close unclosed verbatim
|
||||
if let Some(VerbatimState { event_opener, .. }) = self.verbatim.take() {
|
||||
|
|
Loading…
Reference in a new issue