inline: hide empty attributes from output

allow comments
This commit is contained in:
Noah Hellman 2023-01-16 18:41:13 +01:00
parent e6eb02ad03
commit f80991d07a

View file

@ -239,41 +239,52 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
.map_or(false, |e| e.kind == EventKind::Str) .map_or(false, |e| e.kind == EventKind::Str)
{ {
let mut ahead = self.lexer.inner().clone(); let mut ahead = self.lexer.inner().clone();
let mut attr_len = attr::valid(std::iter::once('{').chain(&mut ahead)).0 - 1; let (mut attr_len, mut has_attr) = attr::valid(std::iter::once('{').chain(&mut ahead));
attr_len -= 1; // rm {
if attr_len > 0 { if attr_len > 0 {
while attr_len > 0 { while attr_len > 0 {
self.lexer = lex::Lexer::new(ahead.clone());
self.span = self.span.extend(attr_len); self.span = self.span.extend(attr_len);
attr_len = attr::valid(&mut ahead).0; self.lexer = lex::Lexer::new(ahead.clone());
let (l, non_empty) = attr::valid(&mut ahead);
attr_len = l;
has_attr |= non_empty;
} }
let i = self Some(if has_attr {
.events let i = self
.iter() .events
.rposition(|e| e.kind != EventKind::Str) .iter()
.map_or(0, |i| i + 1); .rposition(|e| e.kind != EventKind::Str)
let span_str = Span::new( .map_or(0, |i| i + 1);
self.events[i].span.start(), let span_str = Span::new(
self.events[self.events.len() - 1].span.end(), self.events[i].span.start(),
); self.events[self.events.len() - 1].span.end(),
self.events.drain(i..); );
self.events.drain(i..);
self.events.push_back(Event { self.events.push_back(Event {
kind: EventKind::Attributes, kind: EventKind::Attributes,
span: self.span, span: self.span,
}); });
self.events.push_back(Event { self.events.push_back(Event {
kind: EventKind::Enter(Container::Span), kind: EventKind::Enter(Container::Span),
span: Span::empty_at(span_str.start()), span: Span::empty_at(span_str.start()),
}); });
self.events.push_back(Event { self.events.push_back(Event {
kind: EventKind::Str, kind: EventKind::Str,
span: span_str, span: span_str,
}); });
Some(Event { Event {
kind: EventKind::Exit(Container::Span), kind: EventKind::Exit(Container::Span),
span: Span::empty_at(span_str.end()), span: Span::empty_at(span_str.end()),
}
} else {
Event {
kind: EventKind::Placeholder,
span: Span::empty_at(self.span.start()),
}
}) })
} else { } else {
None None
@ -345,22 +356,36 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
}; };
self.openers.drain(o..); self.openers.drain(o..);
let mut ahead = self.lexer.inner().clone(); let mut ahead = self.lexer.inner().clone();
let mut attr_len = attr::valid(&mut ahead).0; let (mut attr_len, mut has_attr) = attr::valid(&mut ahead);
if attr_len > 0 { if attr_len > 0 {
let span_closer = self.span; let span_closer = self.span;
self.events[e_attr].span = Span::empty_at(self.span.end()); self.span = Span::empty_at(self.span.end());
self.events[e_attr].kind = EventKind::Attributes;
while attr_len > 0 { while attr_len > 0 {
self.span = self.span.extend(attr_len);
self.lexer = lex::Lexer::new(ahead.clone()); self.lexer = lex::Lexer::new(ahead.clone());
self.span = self.events[e_attr].span.extend(attr_len);
self.events[e_attr].span = self.span; let (l, non_empty) = attr::valid(&mut ahead);
attr_len = attr::valid(&mut ahead).0; has_attr |= non_empty;
attr_len = l;
}
if has_attr {
self.events[e_attr] = Event {
kind: EventKind::Attributes,
span: self.span,
};
} }
if event.is_none() { if event.is_none() {
self.events[e_opener].kind = EventKind::Enter(Container::Span); if has_attr {
self.events[e_opener].kind = EventKind::Enter(Container::Span);
}
event = Some(Event { event = Some(Event {
kind: EventKind::Exit(Container::Span), kind: if has_attr {
EventKind::Exit(Container::Span)
} else {
EventKind::Str
},
span: span_closer, span: span_closer,
}); });
} }
@ -915,6 +940,23 @@ mod test {
); );
} }
#[test]
fn container_attr_empty() {
test_parse!(
"_abc def_{}",
(Enter(Emphasis), "_"),
(Str, "abc def"),
(Exit(Emphasis), "_"),
);
test_parse!(
"_abc def_{ % comment % } ghi",
(Enter(Emphasis), "_"),
(Str, "abc def"),
(Exit(Emphasis), "_"),
(Str, " ghi"),
);
}
#[test] #[test]
fn container_attr_multiple() { fn container_attr_multiple() {
test_parse!( test_parse!(
@ -946,4 +988,10 @@ mod test {
(Str, " with attrs"), (Str, " with attrs"),
); );
} }
#[test]
fn attr_empty() {
test_parse!("word{}", (Str, "word"));
test_parse!("word{ % comment % } trail", (Str, "word"), (Str, " trail"));
}
} }