Skip to content

Commit

Permalink
inline: add ControlFlow enum
Browse files Browse the repository at this point in the history
  • Loading branch information
hellux committed Mar 4, 2023
1 parent 165be8c commit aea082b
Showing 1 changed file with 39 additions and 29 deletions.
68 changes: 39 additions & 29 deletions src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use lex::Symbol;

use Atom::*;
use Container::*;
use ControlFlow::*;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Atom {
Expand Down Expand Up @@ -228,6 +229,15 @@ pub struct Parser<'s> {
verbatim: Option<VerbatimState>,
}

pub enum ControlFlow {
/// At least one event has been emitted, continue parsing the line.
Continue,
/// More lines are needed to emit an event.
More,
/// Parsing of the line is completed.
Done,
}

impl<'s> Parser<'s> {
pub fn new(src: &'s str) -> Self {
Self {
Expand All @@ -250,32 +260,34 @@ impl<'s> Parser<'s> {
debug_assert!(self.verbatim.is_none());
}

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))
.or_else(|| self.parse_symbol(&first))
.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 {
More
}
}

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,
Expand Down Expand Up @@ -332,15 +344,15 @@ impl<'s> Parser<'s> {
)
})
{
return Some(()); // skip whitespace
return Some(Continue); // skip whitespace
}
} else {
*non_whitespace_encountered = true;
*non_whitespace_last = Some((first.kind, self.events.len() + 1));
}
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 => {
Expand All @@ -365,7 +377,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));
Expand All @@ -391,14 +403,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;
Expand Down Expand Up @@ -430,7 +442,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;
Expand All @@ -451,13 +463,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(),
Expand Down Expand Up @@ -494,13 +506,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))
Expand Down Expand Up @@ -584,7 +596,7 @@ impl<'s> Parser<'s> {
span: span_spec,
};
self.events.drain(e_opener..);
Some(())
Some(Continue)
}
};

Expand Down Expand Up @@ -655,7 +667,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,
Expand Down Expand Up @@ -689,7 +701,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,
Expand Down Expand Up @@ -924,12 +936,10 @@ 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 {
return None;
}
match self.parse_event() {
Continue => {}
Done => break,
More => return None,
}
}

Expand Down

0 comments on commit aea082b

Please sign in to comment.