inline event span

This commit is contained in:
Noah Hellman 2022-11-28 00:10:28 +01:00
parent fb1950233a
commit 82ad0dc93c
2 changed files with 87 additions and 73 deletions

View file

@ -6,7 +6,7 @@ use lex::Symbol;
use Atom::*; use Atom::*;
use Container::*; use Container::*;
use NodeKind::*; use Node::*;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Atom { pub enum Atom {
@ -26,13 +26,7 @@ pub enum Atom {
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Node { pub enum Node {
pub kind: NodeKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NodeKind {
Str, Str,
// link // link
Url, Url,
@ -64,13 +58,19 @@ pub enum Container {
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum Event { pub enum EventKind {
Enter(Container, OpenerState), Enter(Container, OpenerState),
Exit(Container), Exit(Container),
Atom(Atom), Atom(Atom),
Node(Node), Node(Node),
} }
#[derive(Debug, PartialEq, Eq)]
pub struct Event {
pub kind: EventKind,
pub span: Span,
}
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum OpenerState { pub enum OpenerState {
Unclosed, Unclosed,
@ -123,11 +123,11 @@ impl<'s> Parser<'s> {
self.span = Span::empty_at(self.span.end()); self.span = Span::empty_at(self.span.end());
} }
fn node(&self, kind: NodeKind) -> Event { fn node(&self, kind: Node) -> Event {
Event::Node(Node { Event {
kind: EventKind::Node(kind),
span: self.span, span: self.span,
kind, }
})
} }
fn parse_event(&mut self) -> Option<Event> { fn parse_event(&mut self) -> Option<Event> {
@ -141,14 +141,19 @@ impl<'s> Parser<'s> {
} }
fn parse_atom(&mut self, first: &lex::Token) -> Option<Event> { fn parse_atom(&mut self, first: &lex::Token) -> Option<Event> {
match first.kind { let atom = match first.kind {
lex::Kind::Escape => Some(Event::Atom(Escape)), lex::Kind::Escape => Escape,
lex::Kind::Nbsp => Some(Event::Atom(Nbsp)), lex::Kind::Nbsp => Nbsp,
lex::Kind::Sym(lex::Symbol::Lt) => Some(Event::Atom(Lt)), lex::Kind::Sym(lex::Symbol::Lt) => Lt,
lex::Kind::Sym(lex::Symbol::Gt) => Some(Event::Atom(Gt)), lex::Kind::Sym(lex::Symbol::Gt) => Gt,
lex::Kind::Sym(lex::Symbol::Quote2) => Some(Event::Atom(Quote)), lex::Kind::Sym(lex::Symbol::Quote2) => Quote,
_ => None, _ => return None,
} };
Some(Event {
kind: EventKind::Atom(atom),
span: self.span,
})
} }
fn parse_verbatim(&mut self, first: &lex::Token) -> Option<Event> { fn parse_verbatim(&mut self, first: &lex::Token) -> Option<Event> {
@ -192,7 +197,10 @@ impl<'s> Parser<'s> {
} }
span = span.extend(tok.len); span = span.extend(tok.len);
} }
Event::Node(Node { kind, span }) Event {
kind: EventKind::Node(kind),
span,
}
}) })
} }
@ -229,10 +237,10 @@ impl<'s> Parser<'s> {
.and_then(|o| { .and_then(|o| {
matches!(dir, Dir::Close | Dir::Both).then(|| { matches!(dir, Dir::Close | Dir::Both).then(|| {
let (_, e) = &mut self.openers[o]; let (_, e) = &mut self.openers[o];
if let Event::Enter(_, state_ev) = &mut self.events[*e] { if let EventKind::Enter(_, state_ev) = &mut self.events[*e].kind {
*state_ev = OpenerState::Closed; *state_ev = OpenerState::Closed;
self.openers.drain(o..); self.openers.drain(o..);
Event::Exit(cont_new) EventKind::Exit(cont_new)
} else { } else {
panic!() panic!()
} }
@ -240,9 +248,13 @@ impl<'s> Parser<'s> {
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
self.openers.push((cont_new, self.events.len())); self.openers.push((cont_new, self.events.len()));
Event::Enter(cont_new, OpenerState::Unclosed) EventKind::Enter(cont_new, OpenerState::Unclosed)
}) })
}) })
.map(|kind| Event {
kind,
span: self.span,
})
} }
} }
@ -269,8 +281,8 @@ mod test {
use super::Atom::*; use super::Atom::*;
use super::Container::*; use super::Container::*;
use super::Event::*; use super::EventKind::*;
use super::NodeKind::*; use super::Node::*;
use super::OpenerState::*; use super::OpenerState::*;
macro_rules! test_parse { macro_rules! test_parse {
@ -284,9 +296,9 @@ mod test {
}; };
} }
impl super::NodeKind { impl super::EventKind {
pub fn span(self, start: usize, end: usize) -> super::Node { pub fn span(self, start: usize, end: usize) -> super::Event {
super::Node { super::Event {
span: Span::new(start, end), span: Span::new(start, end),
kind: self, kind: self,
} }
@ -295,37 +307,37 @@ mod test {
#[test] #[test]
fn str() { fn str() {
test_parse!("abc", Node(Str.span(0, 3))); test_parse!("abc", Node(Str).span(0, 3));
test_parse!("abc def", Node(Str.span(0, 7))); test_parse!("abc def", Node(Str).span(0, 7));
} }
#[test] #[test]
fn verbatim() { fn verbatim() {
test_parse!("`abc`", Node(Verbatim.span(1, 4))); test_parse!("`abc`", Node(Verbatim).span(1, 4));
test_parse!("`abc", Node(Verbatim.span(1, 4))); test_parse!("`abc", Node(Verbatim).span(1, 4));
test_parse!("``abc``", Node(Verbatim.span(2, 5))); test_parse!("``abc``", Node(Verbatim).span(2, 5));
test_parse!("abc `def`", Node(Str.span(0, 4)), Node(Verbatim.span(5, 8))); test_parse!("abc `def`", Node(Str).span(0, 4), Node(Verbatim).span(5, 8));
} }
#[test] #[test]
fn math() { fn math() {
test_parse!("$`abc`", Node(InlineMath.span(2, 5))); test_parse!("$`abc`", Node(InlineMath).span(2, 5));
test_parse!("$$```abc", Node(DisplayMath.span(5, 8))); test_parse!("$$```abc", Node(DisplayMath).span(5, 8));
} }
#[test] #[test]
fn container_basic() { fn container_basic() {
test_parse!( test_parse!(
"_abc_", "_abc_",
Enter(Emphasis, Closed), Enter(Emphasis, Closed).span(0, 1),
Node(Str.span(1, 4)), Node(Str).span(1, 4),
Exit(Emphasis) Exit(Emphasis).span(4, 5),
); );
test_parse!( test_parse!(
"{_abc_}", "{_abc_}",
Enter(Emphasis, Closed), Enter(Emphasis, Closed).span(0, 2),
Node(Str.span(2, 5)), Node(Str).span(2, 5),
Exit(Emphasis) Exit(Emphasis).span(5, 7),
); );
} }
@ -333,47 +345,51 @@ mod test {
fn container_nest() { fn container_nest() {
test_parse!( test_parse!(
"{_{_abc_}_}", "{_{_abc_}_}",
Enter(Emphasis, Closed), Enter(Emphasis, Closed).span(0, 2),
Enter(Emphasis, Closed), Enter(Emphasis, Closed).span(2, 4),
Node(Str.span(4, 7)), Node(Str).span(4, 7),
Exit(Emphasis), Exit(Emphasis).span(7, 9),
Exit(Emphasis) Exit(Emphasis).span(9, 11),
); );
test_parse!( test_parse!(
"*_abc_*", "*_abc_*",
Enter(Strong, Closed), Enter(Strong, Closed).span(0, 1),
Enter(Emphasis, Closed), Enter(Emphasis, Closed).span(1, 2),
Node(Str.span(2, 5)), Node(Str).span(2, 5),
Exit(Emphasis), Exit(Emphasis).span(5, 6),
Exit(Strong) Exit(Strong).span(6, 7),
); );
} }
#[test] #[test]
fn container_unopened() { fn container_unopened() {
test_parse!("*}abc", Node(Str.span(0, 5)),); test_parse!("*}abc", Node(Str).span(0, 5));
} }
#[test] #[test]
fn container_close_parent() { fn container_close_parent() {
test_parse!( test_parse!(
"{*{_abc*}", "{*{_abc*}",
Enter(Strong, Closed), Enter(Strong, Closed).span(0, 2),
Enter(Emphasis, Unclosed), Enter(Emphasis, Unclosed).span(2, 4),
Node(Str.span(4, 7)), Node(Str).span(4, 7),
Exit(Strong), Exit(Strong).span(7, 9),
); );
} }
#[test] #[test]
fn container_close_block() { fn container_close_block() {
test_parse!("{_abc", Enter(Emphasis, Unclosed), Node(Str.span(2, 5))); test_parse!(
"{_abc",
Enter(Emphasis, Unclosed).span(0, 2),
Node(Str).span(2, 5),
);
test_parse!( test_parse!(
"{_{*{_abc", "{_{*{_abc",
Enter(Emphasis, Unclosed), Enter(Emphasis, Unclosed).span(0, 2),
Enter(Strong, Unclosed), Enter(Strong, Unclosed).span(2, 4),
Enter(Emphasis, Unclosed), Enter(Emphasis, Unclosed).span(4, 6),
Node(Str.span(6, 9)), Node(Str).span(6, 9),
); );
} }
} }

View file

@ -80,9 +80,7 @@ impl<'s> Iterator for Iter<'s> {
while let Some(parser) = &mut self.parser { while let Some(parser) = &mut self.parser {
// inside leaf block, with inline content // inside leaf block, with inline content
if let Some(mut inline) = parser.next() { if let Some(mut inline) = parser.next() {
if let inline::Event::Node(inline::Node { span, .. }) = &mut inline { inline.span = inline.span.translate(self.inline_start);
*span = span.translate(self.inline_start);
}
return Some(Event::Inline(inline)); return Some(Event::Inline(inline));
} else if let Some(ev) = self.tree.next() { } else if let Some(ev) = self.tree.next() {
match ev { match ev {
@ -123,8 +121,8 @@ mod test {
use crate::block::Container::*; use crate::block::Container::*;
use crate::block::Leaf::*; use crate::block::Leaf::*;
use crate::inline::Atom::*; use crate::inline::Atom::*;
use crate::inline::Event::*; use crate::inline::EventKind::*;
use crate::inline::NodeKind::*; use crate::inline::Node::*;
macro_rules! test_parse { macro_rules! test_parse {
($($st:ident,)? $src:expr $(,$($token:expr),* $(,)?)?) => { ($($st:ident,)? $src:expr $(,$($token:expr),* $(,)?)?) => {
@ -140,23 +138,23 @@ mod test {
test_parse!( test_parse!(
"para", "para",
Start(Leaf(Paragraph)), Start(Leaf(Paragraph)),
Inline(Node(Str.span(0, 4))), Inline(Node(Str).span(0, 4)),
End End
); );
test_parse!( test_parse!(
"pa ra", "pa ra",
Start(Leaf(Paragraph)), Start(Leaf(Paragraph)),
Inline(Node(Str.span(0, 9))), Inline(Node(Str).span(0, 9)),
End End
); );
test_parse!( test_parse!(
"para0\n\npara1", "para0\n\npara1",
Start(Leaf(Paragraph)), Start(Leaf(Paragraph)),
Inline(Node(Str.span(0, 6))), Inline(Node(Str).span(0, 6)),
End, End,
Blankline, Blankline,
Start(Leaf(Paragraph)), Start(Leaf(Paragraph)),
Inline(Node(Str.span(7, 12))), Inline(Node(Str).span(7, 12)),
End, End,
); );
} }