inline: impl container attributes

This commit is contained in:
Noah Hellman 2023-01-12 17:28:01 +01:00
parent 73d3e05f0a
commit c0183d4524
2 changed files with 56 additions and 23 deletions

View file

@ -57,6 +57,7 @@ pub enum EventKind {
Atom(Atom), Atom(Atom),
Str, Str,
Attributes, Attributes,
AttributesDummy,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
@ -254,26 +255,46 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
*d == delim || matches!((d, delim), (Delim::Span(..), Delim::Span(..))) *d == delim || matches!((d, delim), (Delim::Span(..), Delim::Span(..)))
}) })
.and_then(|o| { .and_then(|o| {
let (d, e) = self.openers[o];
if matches!(dir, Dir::Close | Dir::Both) { if matches!(dir, Dir::Close | Dir::Both) {
let e = match Container::try_from(d) { let (d, e) = self.openers[o];
let e_attr = e;
let e_opener = e + 1;
let event = match Container::try_from(d) {
Ok(cont) => { Ok(cont) => {
self.events[e].kind = EventKind::Enter(cont); self.events[e_opener].kind = EventKind::Enter(cont);
Some(Event { Some(Event {
kind: EventKind::Exit(cont), kind: EventKind::Exit(cont),
span: self.span, span: self.span,
}) })
} }
Err(ty) => self.post_span(ty, e), Err(ty) => self.post_span(ty, e_opener),
}; };
self.openers.drain(o..); self.openers.drain(o..);
e let mut ahead = self.lexer.inner().clone();
let attr_len = attr::valid(&mut ahead);
dbg!(self.span);
dbg!(attr_len);
if attr_len > 0 {
self.lexer = lex::Lexer::new(ahead);
let span = Span::by_len(self.span.end(), attr_len);
self.events[e_attr] = Event {
kind: EventKind::Attributes,
span,
}
}
event
} else { } else {
None None
} }
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
self.openers.push((delim, self.events.len())); self.openers.push((delim, self.events.len()));
// push dummy attributes in case attributes are encountered after closing
// delimiter
self.events.push_back(Event {
kind: EventKind::AttributesDummy,
span: Span::empty_at(self.span.start()),
});
// use str for now, replace if closed later // use str for now, replace if closed later
Event { Event {
kind: EventKind::Str, kind: EventKind::Str,
@ -448,25 +469,25 @@ impl<I: Iterator<Item = char> + Clone> Iterator for Parser<I> {
} }
} }
self.events.pop_front().map(|e| { self.events.pop_front().and_then(|e| {
if matches!(e.kind, EventKind::Str) { match e.kind {
// merge str events EventKind::Str => {
let mut span = e.span; // merge str events
while self let mut span = e.span;
.events while self.events.front().map_or(false, |e| {
.front() matches!(e.kind, EventKind::Str | EventKind::AttributesDummy)
.map_or(false, |ev| matches!(ev.kind, EventKind::Str)) }) {
{ let ev = self.events.pop_front().unwrap();
let ev = self.events.pop_front().unwrap(); assert_eq!(span.end(), ev.span.start());
assert_eq!(span.end(), ev.span.start()); span = span.union(ev.span);
span = span.union(ev.span); }
Some(Event {
kind: EventKind::Str,
span,
})
} }
Event { EventKind::AttributesDummy => self.next(),
kind: EventKind::Str, _ => Some(e),
span,
}
} else {
e
} }
}) })
} }
@ -744,4 +765,15 @@ mod test {
test_parse!("{_abc", (Str, "{_abc")); test_parse!("{_abc", (Str, "{_abc"));
test_parse!("{_{*{_abc", (Str, "{_{*{_abc")); test_parse!("{_{*{_abc", (Str, "{_{*{_abc"));
} }
#[test]
fn container_attr() {
test_parse!(
"_abc def_{.attr}",
(Attributes, "{.attr}"),
(Enter(Emphasis), "_"),
(Str, "abc def"),
(Exit(Emphasis), "_"),
);
}
} }

View file

@ -438,6 +438,7 @@ impl<'s> Parser<'s> {
}, },
inline::EventKind::Str => Event::Str(self.inlines.src(inline.span)), inline::EventKind::Str => Event::Str(self.inlines.src(inline.span)),
inline::EventKind::Attributes => todo!(), inline::EventKind::Attributes => todo!(),
inline::EventKind::AttributesDummy => panic!(),
} }
} }
} }