2022-11-12 12:45:17 -05:00
|
|
|
mod block;
|
2022-11-16 16:11:55 -05:00
|
|
|
mod inline;
|
2022-11-20 13:13:48 -05:00
|
|
|
mod lex;
|
2022-11-12 12:45:17 -05:00
|
|
|
mod span;
|
|
|
|
mod tree;
|
|
|
|
|
2022-11-20 13:13:48 -05:00
|
|
|
pub struct Block;
|
2022-11-12 12:45:17 -05:00
|
|
|
|
|
|
|
const EOF: char = '\0';
|
|
|
|
|
|
|
|
use span::Span;
|
2022-11-20 13:13:48 -05:00
|
|
|
|
|
|
|
pub struct Parser<'s> {
|
|
|
|
src: &'s str,
|
|
|
|
tree: block::Tree,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'s> Parser<'s> {
|
2022-11-22 13:19:21 -05:00
|
|
|
#[must_use]
|
2022-11-20 13:13:48 -05:00
|
|
|
pub fn new(src: &'s str) -> Self {
|
|
|
|
Self {
|
|
|
|
src,
|
|
|
|
tree: block::parse(src),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-22 13:19:21 -05:00
|
|
|
#[must_use]
|
2022-11-20 13:13:48 -05:00
|
|
|
pub fn iter(&self) -> Iter {
|
|
|
|
Iter {
|
|
|
|
src: self.src,
|
2022-11-22 13:19:21 -05:00
|
|
|
tree: self.tree.iter(),
|
|
|
|
parser: None,
|
2022-11-26 19:12:56 -05:00
|
|
|
inline_start: 0,
|
2022-11-20 13:13:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-22 13:19:21 -05:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum Event {
|
|
|
|
Start(block::Block),
|
|
|
|
End,
|
|
|
|
Inline(inline::Event),
|
|
|
|
Blankline,
|
|
|
|
}
|
|
|
|
|
2022-11-20 13:13:48 -05:00
|
|
|
pub struct Iter<'s> {
|
|
|
|
src: &'s str,
|
2022-11-22 13:19:21 -05:00
|
|
|
tree: block::TreeIter<'s>,
|
|
|
|
parser: Option<inline::Parser<'s>>,
|
2022-11-26 19:12:56 -05:00
|
|
|
inline_start: usize,
|
2022-11-20 13:13:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'s> Iterator for Iter<'s> {
|
2022-11-22 13:19:21 -05:00
|
|
|
type Item = Event;
|
2022-11-20 13:13:48 -05:00
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
2022-11-22 13:19:21 -05:00
|
|
|
while let Some(parser) = &mut self.parser {
|
|
|
|
// inside leaf block, with inline content
|
2022-11-26 19:12:56 -05:00
|
|
|
if let Some(mut inline) = parser.next() {
|
|
|
|
if let inline::Event::Node(inline::Node { span, .. }) = &mut inline {
|
|
|
|
*span = span.translate(self.inline_start);
|
|
|
|
}
|
2022-11-22 13:19:21 -05:00
|
|
|
return Some(Event::Inline(inline));
|
|
|
|
} else if let Some(ev) = self.tree.next() {
|
|
|
|
match ev {
|
|
|
|
tree::Event::Element(atom, sp) => {
|
|
|
|
assert_eq!(*atom, block::Atom::Inline);
|
|
|
|
parser.parse(sp.of(self.src));
|
2022-11-26 19:12:56 -05:00
|
|
|
self.inline_start = sp.start();
|
2022-11-22 13:19:21 -05:00
|
|
|
}
|
|
|
|
tree::Event::Exit => {
|
|
|
|
self.parser = None;
|
|
|
|
return Some(Event::End);
|
2022-11-20 13:13:48 -05:00
|
|
|
}
|
2022-11-22 13:19:21 -05:00
|
|
|
tree::Event::Enter(..) => unreachable!(),
|
|
|
|
}
|
2022-11-20 13:13:48 -05:00
|
|
|
}
|
2022-11-22 13:19:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
self.tree.next().map(|ev| match ev {
|
2022-11-20 13:13:48 -05:00
|
|
|
tree::Event::Element(atom, _sp) => {
|
2022-11-22 13:19:21 -05:00
|
|
|
assert_eq!(*atom, block::Atom::Blankline);
|
|
|
|
Event::Blankline
|
|
|
|
}
|
2022-11-26 19:12:56 -05:00
|
|
|
tree::Event::Enter(block, ..) => {
|
|
|
|
if matches!(block, block::Block::Leaf(..)) {
|
|
|
|
self.parser = Some(inline::Parser::new());
|
|
|
|
}
|
2022-11-22 13:19:21 -05:00
|
|
|
Event::Start(block.clone())
|
|
|
|
}
|
|
|
|
tree::Event::Exit => Event::End,
|
2022-11-20 13:13:48 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2022-11-22 13:19:21 -05:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::Event::*;
|
|
|
|
use crate::block::Block::*;
|
|
|
|
use crate::block::Container::*;
|
|
|
|
use crate::block::Leaf::*;
|
|
|
|
use crate::inline::Atom::*;
|
|
|
|
use crate::inline::Event::*;
|
2022-11-26 19:12:56 -05:00
|
|
|
use crate::inline::NodeKind::*;
|
2022-11-22 13:19:21 -05:00
|
|
|
|
2022-11-22 13:48:17 -05:00
|
|
|
macro_rules! test_parse {
|
|
|
|
($($st:ident,)? $src:expr $(,$($token:expr),* $(,)?)?) => {
|
|
|
|
#[allow(unused)]
|
|
|
|
let actual = super::Parser::new($src).iter().collect::<Vec<_>>();
|
|
|
|
let expected = &[$($($token),*,)?];
|
|
|
|
assert_eq!(actual, expected, "\n\n{}\n\n", $src);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-22 13:19:21 -05:00
|
|
|
#[test]
|
2022-11-22 13:48:17 -05:00
|
|
|
fn para() {
|
|
|
|
test_parse!(
|
2022-11-26 19:12:56 -05:00
|
|
|
"para",
|
|
|
|
Start(Leaf(Paragraph)),
|
|
|
|
Inline(Node(Str.span(0, 4))),
|
|
|
|
End
|
|
|
|
);
|
|
|
|
test_parse!(
|
|
|
|
"pa ra",
|
|
|
|
Start(Leaf(Paragraph)),
|
|
|
|
Inline(Node(Str.span(0, 9))),
|
|
|
|
End
|
|
|
|
);
|
|
|
|
test_parse!(
|
|
|
|
"para0\n\npara1",
|
2022-11-22 13:48:17 -05:00
|
|
|
Start(Leaf(Paragraph)),
|
2022-11-26 19:12:56 -05:00
|
|
|
Inline(Node(Str.span(0, 6))),
|
2022-11-22 13:48:17 -05:00
|
|
|
End,
|
2022-11-26 19:12:56 -05:00
|
|
|
Blankline,
|
2022-11-22 13:48:17 -05:00
|
|
|
Start(Leaf(Paragraph)),
|
2022-11-26 19:12:56 -05:00
|
|
|
Inline(Node(Str.span(7, 12))),
|
2022-11-22 13:48:17 -05:00
|
|
|
End,
|
2022-11-22 13:19:21 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|