Merge branch 'reduce_heap_iter'
This commit is contained in:
commit
a5b4eb40f6
102
src/iter/all_ast_node_iter.rs
Normal file
102
src/iter/all_ast_node_iter.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use super::ast_node::AstNode;
|
||||
use super::ast_node_iter::AstNodeIter;
|
||||
|
||||
pub struct AllAstNodeIter<'r, 's> {
|
||||
root: Option<AstNode<'r, 's>>,
|
||||
queue: VecDeque<AstNodeIter<'r, 's>>,
|
||||
}
|
||||
|
||||
impl<'r, 's> Iterator for AllAstNodeIter<'r, 's> {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(root) = self.root.take() {
|
||||
self.queue.push_back(AstNodeIter::from_ast_node(&root));
|
||||
return Some(root);
|
||||
}
|
||||
while let Some(child) = self.queue.front_mut() {
|
||||
let next_elem_this_iter = match child {
|
||||
AstNodeIter::Document(ref mut i) => i.next(),
|
||||
AstNodeIter::Heading(ref mut i) => i.next(),
|
||||
AstNodeIter::Section(ref mut i) => i.next(),
|
||||
AstNodeIter::Paragraph(ref mut i) => i.next(),
|
||||
AstNodeIter::PlainList(ref mut i) => i.next(),
|
||||
AstNodeIter::PlainListItem(ref mut i) => i.next(),
|
||||
AstNodeIter::GreaterBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::DynamicBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::FootnoteDefinition(ref mut i) => i.next(),
|
||||
AstNodeIter::Comment(ref mut i) => i.next(),
|
||||
AstNodeIter::Drawer(ref mut i) => i.next(),
|
||||
AstNodeIter::PropertyDrawer(ref mut i) => i.next(),
|
||||
AstNodeIter::NodeProperty(ref mut i) => i.next(),
|
||||
AstNodeIter::Table(ref mut i) => i.next(),
|
||||
AstNodeIter::TableRow(ref mut i) => i.next(),
|
||||
AstNodeIter::VerseBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::CommentBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::ExampleBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::ExportBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::SrcBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::Clock(ref mut i) => i.next(),
|
||||
AstNodeIter::DiarySexp(ref mut i) => i.next(),
|
||||
AstNodeIter::Planning(ref mut i) => i.next(),
|
||||
AstNodeIter::FixedWidthArea(ref mut i) => i.next(),
|
||||
AstNodeIter::HorizontalRule(ref mut i) => i.next(),
|
||||
AstNodeIter::Keyword(ref mut i) => i.next(),
|
||||
AstNodeIter::BabelCall(ref mut i) => i.next(),
|
||||
AstNodeIter::LatexEnvironment(ref mut i) => i.next(),
|
||||
AstNodeIter::Bold(ref mut i) => i.next(),
|
||||
AstNodeIter::Italic(ref mut i) => i.next(),
|
||||
AstNodeIter::Underline(ref mut i) => i.next(),
|
||||
AstNodeIter::StrikeThrough(ref mut i) => i.next(),
|
||||
AstNodeIter::Code(ref mut i) => i.next(),
|
||||
AstNodeIter::Verbatim(ref mut i) => i.next(),
|
||||
AstNodeIter::PlainText(ref mut i) => i.next(),
|
||||
AstNodeIter::RegularLink(ref mut i) => i.next(),
|
||||
AstNodeIter::RadioLink(ref mut i) => i.next(),
|
||||
AstNodeIter::RadioTarget(ref mut i) => i.next(),
|
||||
AstNodeIter::PlainLink(ref mut i) => i.next(),
|
||||
AstNodeIter::AngleLink(ref mut i) => i.next(),
|
||||
AstNodeIter::OrgMacro(ref mut i) => i.next(),
|
||||
AstNodeIter::Entity(ref mut i) => i.next(),
|
||||
AstNodeIter::LatexFragment(ref mut i) => i.next(),
|
||||
AstNodeIter::ExportSnippet(ref mut i) => i.next(),
|
||||
AstNodeIter::FootnoteReference(ref mut i) => i.next(),
|
||||
AstNodeIter::Citation(ref mut i) => i.next(),
|
||||
AstNodeIter::CitationReference(ref mut i) => i.next(),
|
||||
AstNodeIter::InlineBabelCall(ref mut i) => i.next(),
|
||||
AstNodeIter::InlineSourceBlock(ref mut i) => i.next(),
|
||||
AstNodeIter::LineBreak(ref mut i) => i.next(),
|
||||
AstNodeIter::Target(ref mut i) => i.next(),
|
||||
AstNodeIter::StatisticsCookie(ref mut i) => i.next(),
|
||||
AstNodeIter::Subscript(ref mut i) => i.next(),
|
||||
AstNodeIter::Superscript(ref mut i) => i.next(),
|
||||
AstNodeIter::TableCell(ref mut i) => i.next(),
|
||||
AstNodeIter::Timestamp(ref mut i) => i.next(),
|
||||
};
|
||||
if let Some(next_elem_this_iter) = next_elem_this_iter {
|
||||
self.queue
|
||||
.push_back(AstNodeIter::from_ast_node(&next_elem_this_iter));
|
||||
return Some(next_elem_this_iter);
|
||||
} else {
|
||||
self.queue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> IntoIterator for AstNode<'r, 's> {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
type IntoIter = AllAstNodeIter<'r, 's>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
AllAstNodeIter {
|
||||
root: Some(self),
|
||||
queue: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
}
|
251
src/iter/ast_node.rs
Normal file
251
src/iter/ast_node.rs
Normal file
@ -0,0 +1,251 @@
|
||||
use super::macros::to_ast_node;
|
||||
use crate::types::AngleLink;
|
||||
use crate::types::BabelCall;
|
||||
use crate::types::Bold;
|
||||
use crate::types::Citation;
|
||||
use crate::types::CitationReference;
|
||||
use crate::types::Clock;
|
||||
use crate::types::Code;
|
||||
use crate::types::Comment;
|
||||
use crate::types::CommentBlock;
|
||||
use crate::types::DiarySexp;
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Drawer;
|
||||
use crate::types::DynamicBlock;
|
||||
use crate::types::Element;
|
||||
use crate::types::Entity;
|
||||
use crate::types::ExampleBlock;
|
||||
use crate::types::ExportBlock;
|
||||
use crate::types::ExportSnippet;
|
||||
use crate::types::FixedWidthArea;
|
||||
use crate::types::FootnoteDefinition;
|
||||
use crate::types::FootnoteReference;
|
||||
use crate::types::GreaterBlock;
|
||||
use crate::types::Heading;
|
||||
use crate::types::HorizontalRule;
|
||||
use crate::types::InlineBabelCall;
|
||||
use crate::types::InlineSourceBlock;
|
||||
use crate::types::Italic;
|
||||
use crate::types::Keyword;
|
||||
use crate::types::LatexEnvironment;
|
||||
use crate::types::LatexFragment;
|
||||
use crate::types::LineBreak;
|
||||
use crate::types::NodeProperty;
|
||||
use crate::types::Object;
|
||||
use crate::types::OrgMacro;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::PlainLink;
|
||||
use crate::types::PlainList;
|
||||
use crate::types::PlainListItem;
|
||||
use crate::types::PlainText;
|
||||
use crate::types::Planning;
|
||||
use crate::types::PropertyDrawer;
|
||||
use crate::types::RadioLink;
|
||||
use crate::types::RadioTarget;
|
||||
use crate::types::RegularLink;
|
||||
use crate::types::Section;
|
||||
use crate::types::SrcBlock;
|
||||
use crate::types::StatisticsCookie;
|
||||
use crate::types::StrikeThrough;
|
||||
use crate::types::Subscript;
|
||||
use crate::types::Superscript;
|
||||
use crate::types::Table;
|
||||
use crate::types::TableCell;
|
||||
use crate::types::TableRow;
|
||||
use crate::types::Target;
|
||||
use crate::types::Timestamp;
|
||||
use crate::types::Underline;
|
||||
use crate::types::Verbatim;
|
||||
use crate::types::VerseBlock;
|
||||
|
||||
pub enum AstNode<'r, 's> {
|
||||
// Document Nodes
|
||||
Document(&'r Document<'s>),
|
||||
Heading(&'r Heading<'s>),
|
||||
Section(&'r Section<'s>),
|
||||
// Elements
|
||||
Paragraph(&'r Paragraph<'s>),
|
||||
PlainList(&'r PlainList<'s>),
|
||||
PlainListItem(&'r PlainListItem<'s>),
|
||||
GreaterBlock(&'r GreaterBlock<'s>),
|
||||
DynamicBlock(&'r DynamicBlock<'s>),
|
||||
FootnoteDefinition(&'r FootnoteDefinition<'s>),
|
||||
Comment(&'r Comment<'s>),
|
||||
Drawer(&'r Drawer<'s>),
|
||||
PropertyDrawer(&'r PropertyDrawer<'s>),
|
||||
NodeProperty(&'r NodeProperty<'s>),
|
||||
Table(&'r Table<'s>),
|
||||
TableRow(&'r TableRow<'s>),
|
||||
VerseBlock(&'r VerseBlock<'s>),
|
||||
CommentBlock(&'r CommentBlock<'s>),
|
||||
ExampleBlock(&'r ExampleBlock<'s>),
|
||||
ExportBlock(&'r ExportBlock<'s>),
|
||||
SrcBlock(&'r SrcBlock<'s>),
|
||||
Clock(&'r Clock<'s>),
|
||||
DiarySexp(&'r DiarySexp<'s>),
|
||||
Planning(&'r Planning<'s>),
|
||||
FixedWidthArea(&'r FixedWidthArea<'s>),
|
||||
HorizontalRule(&'r HorizontalRule<'s>),
|
||||
Keyword(&'r Keyword<'s>),
|
||||
BabelCall(&'r BabelCall<'s>),
|
||||
LatexEnvironment(&'r LatexEnvironment<'s>),
|
||||
// Objects
|
||||
Bold(&'r Bold<'s>),
|
||||
Italic(&'r Italic<'s>),
|
||||
Underline(&'r Underline<'s>),
|
||||
StrikeThrough(&'r StrikeThrough<'s>),
|
||||
Code(&'r Code<'s>),
|
||||
Verbatim(&'r Verbatim<'s>),
|
||||
PlainText(&'r PlainText<'s>),
|
||||
RegularLink(&'r RegularLink<'s>),
|
||||
RadioLink(&'r RadioLink<'s>),
|
||||
RadioTarget(&'r RadioTarget<'s>),
|
||||
PlainLink(&'r PlainLink<'s>),
|
||||
AngleLink(&'r AngleLink<'s>),
|
||||
OrgMacro(&'r OrgMacro<'s>),
|
||||
Entity(&'r Entity<'s>),
|
||||
LatexFragment(&'r LatexFragment<'s>),
|
||||
ExportSnippet(&'r ExportSnippet<'s>),
|
||||
FootnoteReference(&'r FootnoteReference<'s>),
|
||||
Citation(&'r Citation<'s>),
|
||||
CitationReference(&'r CitationReference<'s>),
|
||||
InlineBabelCall(&'r InlineBabelCall<'s>),
|
||||
InlineSourceBlock(&'r InlineSourceBlock<'s>),
|
||||
LineBreak(&'r LineBreak<'s>),
|
||||
Target(&'r Target<'s>),
|
||||
StatisticsCookie(&'r StatisticsCookie<'s>),
|
||||
Subscript(&'r Subscript<'s>),
|
||||
Superscript(&'r Superscript<'s>),
|
||||
TableCell(&'r TableCell<'s>),
|
||||
Timestamp(&'r Timestamp<'s>),
|
||||
}
|
||||
|
||||
impl<'r, 's> From<&'r DocumentElement<'s>> for AstNode<'r, 's> {
|
||||
fn from(value: &'r DocumentElement<'s>) -> Self {
|
||||
match value {
|
||||
DocumentElement::Heading(inner) => inner.into(),
|
||||
DocumentElement::Section(inner) => inner.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> From<&'r Element<'s>> for AstNode<'r, 's> {
|
||||
fn from(value: &'r Element<'s>) -> Self {
|
||||
match value {
|
||||
Element::Paragraph(inner) => inner.into(),
|
||||
Element::PlainList(inner) => inner.into(),
|
||||
Element::GreaterBlock(inner) => inner.into(),
|
||||
Element::DynamicBlock(inner) => inner.into(),
|
||||
Element::FootnoteDefinition(inner) => inner.into(),
|
||||
Element::Comment(inner) => inner.into(),
|
||||
Element::Drawer(inner) => inner.into(),
|
||||
Element::PropertyDrawer(inner) => inner.into(),
|
||||
Element::Table(inner) => inner.into(),
|
||||
Element::VerseBlock(inner) => inner.into(),
|
||||
Element::CommentBlock(inner) => inner.into(),
|
||||
Element::ExampleBlock(inner) => inner.into(),
|
||||
Element::ExportBlock(inner) => inner.into(),
|
||||
Element::SrcBlock(inner) => inner.into(),
|
||||
Element::Clock(inner) => inner.into(),
|
||||
Element::DiarySexp(inner) => inner.into(),
|
||||
Element::Planning(inner) => inner.into(),
|
||||
Element::FixedWidthArea(inner) => inner.into(),
|
||||
Element::HorizontalRule(inner) => inner.into(),
|
||||
Element::Keyword(inner) => inner.into(),
|
||||
Element::BabelCall(inner) => inner.into(),
|
||||
Element::LatexEnvironment(inner) => inner.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> From<&'r Object<'s>> for AstNode<'r, 's> {
|
||||
fn from(value: &'r Object<'s>) -> Self {
|
||||
match value {
|
||||
Object::Bold(inner) => inner.into(),
|
||||
Object::Italic(inner) => inner.into(),
|
||||
Object::Underline(inner) => inner.into(),
|
||||
Object::StrikeThrough(inner) => inner.into(),
|
||||
Object::Code(inner) => inner.into(),
|
||||
Object::Verbatim(inner) => inner.into(),
|
||||
Object::PlainText(inner) => inner.into(),
|
||||
Object::RegularLink(inner) => inner.into(),
|
||||
Object::RadioLink(inner) => inner.into(),
|
||||
Object::RadioTarget(inner) => inner.into(),
|
||||
Object::PlainLink(inner) => inner.into(),
|
||||
Object::AngleLink(inner) => inner.into(),
|
||||
Object::OrgMacro(inner) => inner.into(),
|
||||
Object::Entity(inner) => inner.into(),
|
||||
Object::LatexFragment(inner) => inner.into(),
|
||||
Object::ExportSnippet(inner) => inner.into(),
|
||||
Object::FootnoteReference(inner) => inner.into(),
|
||||
Object::Citation(inner) => inner.into(),
|
||||
Object::CitationReference(inner) => inner.into(),
|
||||
Object::InlineBabelCall(inner) => inner.into(),
|
||||
Object::InlineSourceBlock(inner) => inner.into(),
|
||||
Object::LineBreak(inner) => inner.into(),
|
||||
Object::Target(inner) => inner.into(),
|
||||
Object::StatisticsCookie(inner) => inner.into(),
|
||||
Object::Subscript(inner) => inner.into(),
|
||||
Object::Superscript(inner) => inner.into(),
|
||||
Object::Timestamp(inner) => inner.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
to_ast_node!(&'r Document<'s>, AstNode::Document);
|
||||
to_ast_node!(&'r Heading<'s>, AstNode::Heading);
|
||||
to_ast_node!(&'r Section<'s>, AstNode::Section);
|
||||
to_ast_node!(&'r Paragraph<'s>, AstNode::Paragraph);
|
||||
to_ast_node!(&'r PlainList<'s>, AstNode::PlainList);
|
||||
to_ast_node!(&'r PlainListItem<'s>, AstNode::PlainListItem);
|
||||
to_ast_node!(&'r GreaterBlock<'s>, AstNode::GreaterBlock);
|
||||
to_ast_node!(&'r DynamicBlock<'s>, AstNode::DynamicBlock);
|
||||
to_ast_node!(&'r FootnoteDefinition<'s>, AstNode::FootnoteDefinition);
|
||||
to_ast_node!(&'r Comment<'s>, AstNode::Comment);
|
||||
to_ast_node!(&'r Drawer<'s>, AstNode::Drawer);
|
||||
to_ast_node!(&'r PropertyDrawer<'s>, AstNode::PropertyDrawer);
|
||||
to_ast_node!(&'r NodeProperty<'s>, AstNode::NodeProperty);
|
||||
to_ast_node!(&'r Table<'s>, AstNode::Table);
|
||||
to_ast_node!(&'r TableRow<'s>, AstNode::TableRow);
|
||||
to_ast_node!(&'r VerseBlock<'s>, AstNode::VerseBlock);
|
||||
to_ast_node!(&'r CommentBlock<'s>, AstNode::CommentBlock);
|
||||
to_ast_node!(&'r ExampleBlock<'s>, AstNode::ExampleBlock);
|
||||
to_ast_node!(&'r ExportBlock<'s>, AstNode::ExportBlock);
|
||||
to_ast_node!(&'r SrcBlock<'s>, AstNode::SrcBlock);
|
||||
to_ast_node!(&'r Clock<'s>, AstNode::Clock);
|
||||
to_ast_node!(&'r DiarySexp<'s>, AstNode::DiarySexp);
|
||||
to_ast_node!(&'r Planning<'s>, AstNode::Planning);
|
||||
to_ast_node!(&'r FixedWidthArea<'s>, AstNode::FixedWidthArea);
|
||||
to_ast_node!(&'r HorizontalRule<'s>, AstNode::HorizontalRule);
|
||||
to_ast_node!(&'r Keyword<'s>, AstNode::Keyword);
|
||||
to_ast_node!(&'r BabelCall<'s>, AstNode::BabelCall);
|
||||
to_ast_node!(&'r LatexEnvironment<'s>, AstNode::LatexEnvironment);
|
||||
to_ast_node!(&'r Bold<'s>, AstNode::Bold);
|
||||
to_ast_node!(&'r Italic<'s>, AstNode::Italic);
|
||||
to_ast_node!(&'r Underline<'s>, AstNode::Underline);
|
||||
to_ast_node!(&'r StrikeThrough<'s>, AstNode::StrikeThrough);
|
||||
to_ast_node!(&'r Code<'s>, AstNode::Code);
|
||||
to_ast_node!(&'r Verbatim<'s>, AstNode::Verbatim);
|
||||
to_ast_node!(&'r PlainText<'s>, AstNode::PlainText);
|
||||
to_ast_node!(&'r RegularLink<'s>, AstNode::RegularLink);
|
||||
to_ast_node!(&'r RadioLink<'s>, AstNode::RadioLink);
|
||||
to_ast_node!(&'r RadioTarget<'s>, AstNode::RadioTarget);
|
||||
to_ast_node!(&'r PlainLink<'s>, AstNode::PlainLink);
|
||||
to_ast_node!(&'r AngleLink<'s>, AstNode::AngleLink);
|
||||
to_ast_node!(&'r OrgMacro<'s>, AstNode::OrgMacro);
|
||||
to_ast_node!(&'r Entity<'s>, AstNode::Entity);
|
||||
to_ast_node!(&'r LatexFragment<'s>, AstNode::LatexFragment);
|
||||
to_ast_node!(&'r ExportSnippet<'s>, AstNode::ExportSnippet);
|
||||
to_ast_node!(&'r FootnoteReference<'s>, AstNode::FootnoteReference);
|
||||
to_ast_node!(&'r Citation<'s>, AstNode::Citation);
|
||||
to_ast_node!(&'r CitationReference<'s>, AstNode::CitationReference);
|
||||
to_ast_node!(&'r InlineBabelCall<'s>, AstNode::InlineBabelCall);
|
||||
to_ast_node!(&'r InlineSourceBlock<'s>, AstNode::InlineSourceBlock);
|
||||
to_ast_node!(&'r LineBreak<'s>, AstNode::LineBreak);
|
||||
to_ast_node!(&'r Target<'s>, AstNode::Target);
|
||||
to_ast_node!(&'r StatisticsCookie<'s>, AstNode::StatisticsCookie);
|
||||
to_ast_node!(&'r Subscript<'s>, AstNode::Subscript);
|
||||
to_ast_node!(&'r Superscript<'s>, AstNode::Superscript);
|
||||
to_ast_node!(&'r TableCell<'s>, AstNode::TableCell);
|
||||
to_ast_node!(&'r Timestamp<'s>, AstNode::Timestamp);
|
332
src/iter/ast_node_iter.rs
Normal file
332
src/iter/ast_node_iter.rs
Normal file
@ -0,0 +1,332 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use super::ast_node::AstNode;
|
||||
use super::macros::children_iter;
|
||||
use super::macros::empty_iter;
|
||||
use super::macros::multi_field_iter;
|
||||
use crate::types::AngleLink;
|
||||
use crate::types::BabelCall;
|
||||
use crate::types::Bold;
|
||||
use crate::types::Citation;
|
||||
use crate::types::CitationReference;
|
||||
use crate::types::Clock;
|
||||
use crate::types::Code;
|
||||
use crate::types::Comment;
|
||||
use crate::types::CommentBlock;
|
||||
use crate::types::DiarySexp;
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Drawer;
|
||||
use crate::types::DynamicBlock;
|
||||
use crate::types::Element;
|
||||
use crate::types::Entity;
|
||||
use crate::types::ExampleBlock;
|
||||
use crate::types::ExportBlock;
|
||||
use crate::types::ExportSnippet;
|
||||
use crate::types::FixedWidthArea;
|
||||
use crate::types::FootnoteDefinition;
|
||||
use crate::types::FootnoteReference;
|
||||
use crate::types::GreaterBlock;
|
||||
use crate::types::Heading;
|
||||
use crate::types::HorizontalRule;
|
||||
use crate::types::InlineBabelCall;
|
||||
use crate::types::InlineSourceBlock;
|
||||
use crate::types::Italic;
|
||||
use crate::types::Keyword;
|
||||
use crate::types::LatexEnvironment;
|
||||
use crate::types::LatexFragment;
|
||||
use crate::types::LineBreak;
|
||||
use crate::types::NodeProperty;
|
||||
use crate::types::Object;
|
||||
use crate::types::OrgMacro;
|
||||
use crate::types::Paragraph;
|
||||
use crate::types::PlainLink;
|
||||
use crate::types::PlainList;
|
||||
use crate::types::PlainListItem;
|
||||
use crate::types::PlainText;
|
||||
use crate::types::Planning;
|
||||
use crate::types::PropertyDrawer;
|
||||
use crate::types::RadioLink;
|
||||
use crate::types::RadioTarget;
|
||||
use crate::types::RegularLink;
|
||||
use crate::types::Section;
|
||||
use crate::types::SrcBlock;
|
||||
use crate::types::StatisticsCookie;
|
||||
use crate::types::StrikeThrough;
|
||||
use crate::types::Subscript;
|
||||
use crate::types::Superscript;
|
||||
use crate::types::Table;
|
||||
use crate::types::TableCell;
|
||||
use crate::types::TableRow;
|
||||
use crate::types::Target;
|
||||
use crate::types::Timestamp;
|
||||
use crate::types::Underline;
|
||||
use crate::types::Verbatim;
|
||||
use crate::types::VerseBlock;
|
||||
|
||||
/// Iterator over the AST nodes contained within the starting node.
|
||||
///
|
||||
/// This only iterates over the children, not the starting node itself. So an AstNodeIter::PlainList would only return PlainListItems, not the PlainList.
|
||||
///
|
||||
/// This only iterates over AST nodes, so an AstNodeIter::Heading would iterate over both the title and section contents, but it would not iterate over simple strings like the TODO keyword or priority.
|
||||
pub(crate) enum AstNodeIter<'r, 's> {
|
||||
// Document Nodes
|
||||
Document(DocumentIter<'r, 's>),
|
||||
Heading(HeadingIter<'r, 's>),
|
||||
Section(SectionIter<'r, 's>),
|
||||
// Elements
|
||||
Paragraph(ParagraphIter<'r, 's>),
|
||||
PlainList(PlainListIter<'r, 's>),
|
||||
PlainListItem(PlainListItemIter<'r, 's>),
|
||||
GreaterBlock(GreaterBlockIter<'r, 's>),
|
||||
DynamicBlock(DynamicBlockIter<'r, 's>),
|
||||
FootnoteDefinition(FootnoteDefinitionIter<'r, 's>),
|
||||
Comment(CommentIter<'r, 's>),
|
||||
Drawer(DrawerIter<'r, 's>),
|
||||
PropertyDrawer(PropertyDrawerIter<'r, 's>),
|
||||
NodeProperty(NodePropertyIter<'r, 's>),
|
||||
Table(TableIter<'r, 's>),
|
||||
TableRow(TableRowIter<'r, 's>),
|
||||
VerseBlock(VerseBlockIter<'r, 's>),
|
||||
CommentBlock(CommentBlockIter<'r, 's>),
|
||||
ExampleBlock(ExampleBlockIter<'r, 's>),
|
||||
ExportBlock(ExportBlockIter<'r, 's>),
|
||||
SrcBlock(SrcBlockIter<'r, 's>),
|
||||
Clock(ClockIter<'r, 's>),
|
||||
DiarySexp(DiarySexpIter<'r, 's>),
|
||||
Planning(PlanningIter<'r, 's>),
|
||||
FixedWidthArea(FixedWidthAreaIter<'r, 's>),
|
||||
HorizontalRule(HorizontalRuleIter<'r, 's>),
|
||||
Keyword(KeywordIter<'r, 's>),
|
||||
BabelCall(BabelCallIter<'r, 's>),
|
||||
LatexEnvironment(LatexEnvironmentIter<'r, 's>),
|
||||
// Objects
|
||||
Bold(BoldIter<'r, 's>),
|
||||
Italic(ItalicIter<'r, 's>),
|
||||
Underline(UnderlineIter<'r, 's>),
|
||||
StrikeThrough(StrikeThroughIter<'r, 's>),
|
||||
Code(CodeIter<'r, 's>),
|
||||
Verbatim(VerbatimIter<'r, 's>),
|
||||
PlainText(PlainTextIter<'r, 's>),
|
||||
RegularLink(RegularLinkIter<'r, 's>),
|
||||
RadioLink(RadioLinkIter<'r, 's>),
|
||||
RadioTarget(RadioTargetIter<'r, 's>),
|
||||
PlainLink(PlainLinkIter<'r, 's>),
|
||||
AngleLink(AngleLinkIter<'r, 's>),
|
||||
OrgMacro(OrgMacroIter<'r, 's>),
|
||||
Entity(EntityIter<'r, 's>),
|
||||
LatexFragment(LatexFragmentIter<'r, 's>),
|
||||
ExportSnippet(ExportSnippetIter<'r, 's>),
|
||||
FootnoteReference(FootnoteReferenceIter<'r, 's>),
|
||||
Citation(CitationIter<'r, 's>),
|
||||
CitationReference(CitationReferenceIter<'r, 's>),
|
||||
InlineBabelCall(InlineBabelCallIter<'r, 's>),
|
||||
InlineSourceBlock(InlineSourceBlockIter<'r, 's>),
|
||||
LineBreak(LineBreakIter<'r, 's>),
|
||||
Target(TargetIter<'r, 's>),
|
||||
StatisticsCookie(StatisticsCookieIter<'r, 's>),
|
||||
Subscript(SubscriptIter<'r, 's>),
|
||||
Superscript(SuperscriptIter<'r, 's>),
|
||||
TableCell(TableCellIter<'r, 's>),
|
||||
Timestamp(TimestampIter<'r, 's>),
|
||||
}
|
||||
|
||||
impl<'r, 's> AstNodeIter<'r, 's> {
|
||||
pub(crate) fn from_ast_node(node: &AstNode<'r, 's>) -> AstNodeIter<'r, 's> {
|
||||
match node {
|
||||
AstNode::Document(inner) => AstNodeIter::Document(inner.into_iter()),
|
||||
AstNode::Heading(inner) => AstNodeIter::Heading(inner.into_iter()),
|
||||
AstNode::Section(inner) => AstNodeIter::Section(inner.into_iter()),
|
||||
AstNode::Paragraph(inner) => AstNodeIter::Paragraph(inner.into_iter()),
|
||||
AstNode::PlainList(inner) => AstNodeIter::PlainList(inner.into_iter()),
|
||||
AstNode::PlainListItem(inner) => AstNodeIter::PlainListItem(inner.into_iter()),
|
||||
AstNode::GreaterBlock(inner) => AstNodeIter::GreaterBlock(inner.into_iter()),
|
||||
AstNode::DynamicBlock(inner) => AstNodeIter::DynamicBlock(inner.into_iter()),
|
||||
AstNode::FootnoteDefinition(inner) => {
|
||||
AstNodeIter::FootnoteDefinition(inner.into_iter())
|
||||
}
|
||||
AstNode::Comment(inner) => AstNodeIter::Comment(inner.into_iter()),
|
||||
AstNode::Drawer(inner) => AstNodeIter::Drawer(inner.into_iter()),
|
||||
AstNode::PropertyDrawer(inner) => AstNodeIter::PropertyDrawer(inner.into_iter()),
|
||||
AstNode::NodeProperty(inner) => AstNodeIter::NodeProperty(inner.into_iter()),
|
||||
AstNode::Table(inner) => AstNodeIter::Table(inner.into_iter()),
|
||||
AstNode::TableRow(inner) => AstNodeIter::TableRow(inner.into_iter()),
|
||||
AstNode::VerseBlock(inner) => AstNodeIter::VerseBlock(inner.into_iter()),
|
||||
AstNode::CommentBlock(inner) => AstNodeIter::CommentBlock(inner.into_iter()),
|
||||
AstNode::ExampleBlock(inner) => AstNodeIter::ExampleBlock(inner.into_iter()),
|
||||
AstNode::ExportBlock(inner) => AstNodeIter::ExportBlock(inner.into_iter()),
|
||||
AstNode::SrcBlock(inner) => AstNodeIter::SrcBlock(inner.into_iter()),
|
||||
AstNode::Clock(inner) => AstNodeIter::Clock(inner.into_iter()),
|
||||
AstNode::DiarySexp(inner) => AstNodeIter::DiarySexp(inner.into_iter()),
|
||||
AstNode::Planning(inner) => AstNodeIter::Planning(inner.into_iter()),
|
||||
AstNode::FixedWidthArea(inner) => AstNodeIter::FixedWidthArea(inner.into_iter()),
|
||||
AstNode::HorizontalRule(inner) => AstNodeIter::HorizontalRule(inner.into_iter()),
|
||||
AstNode::Keyword(inner) => AstNodeIter::Keyword(inner.into_iter()),
|
||||
AstNode::BabelCall(inner) => AstNodeIter::BabelCall(inner.into_iter()),
|
||||
AstNode::LatexEnvironment(inner) => AstNodeIter::LatexEnvironment(inner.into_iter()),
|
||||
AstNode::Bold(inner) => AstNodeIter::Bold(inner.into_iter()),
|
||||
AstNode::Italic(inner) => AstNodeIter::Italic(inner.into_iter()),
|
||||
AstNode::Underline(inner) => AstNodeIter::Underline(inner.into_iter()),
|
||||
AstNode::StrikeThrough(inner) => AstNodeIter::StrikeThrough(inner.into_iter()),
|
||||
AstNode::Code(inner) => AstNodeIter::Code(inner.into_iter()),
|
||||
AstNode::Verbatim(inner) => AstNodeIter::Verbatim(inner.into_iter()),
|
||||
AstNode::PlainText(inner) => AstNodeIter::PlainText(inner.into_iter()),
|
||||
AstNode::RegularLink(inner) => AstNodeIter::RegularLink(inner.into_iter()),
|
||||
AstNode::RadioLink(inner) => AstNodeIter::RadioLink(inner.into_iter()),
|
||||
AstNode::RadioTarget(inner) => AstNodeIter::RadioTarget(inner.into_iter()),
|
||||
AstNode::PlainLink(inner) => AstNodeIter::PlainLink(inner.into_iter()),
|
||||
AstNode::AngleLink(inner) => AstNodeIter::AngleLink(inner.into_iter()),
|
||||
AstNode::OrgMacro(inner) => AstNodeIter::OrgMacro(inner.into_iter()),
|
||||
AstNode::Entity(inner) => AstNodeIter::Entity(inner.into_iter()),
|
||||
AstNode::LatexFragment(inner) => AstNodeIter::LatexFragment(inner.into_iter()),
|
||||
AstNode::ExportSnippet(inner) => AstNodeIter::ExportSnippet(inner.into_iter()),
|
||||
AstNode::FootnoteReference(inner) => AstNodeIter::FootnoteReference(inner.into_iter()),
|
||||
AstNode::Citation(inner) => AstNodeIter::Citation(inner.into_iter()),
|
||||
AstNode::CitationReference(inner) => AstNodeIter::CitationReference(inner.into_iter()),
|
||||
AstNode::InlineBabelCall(inner) => AstNodeIter::InlineBabelCall(inner.into_iter()),
|
||||
AstNode::InlineSourceBlock(inner) => AstNodeIter::InlineSourceBlock(inner.into_iter()),
|
||||
AstNode::LineBreak(inner) => AstNodeIter::LineBreak(inner.into_iter()),
|
||||
AstNode::Target(inner) => AstNodeIter::Target(inner.into_iter()),
|
||||
AstNode::StatisticsCookie(inner) => AstNodeIter::StatisticsCookie(inner.into_iter()),
|
||||
AstNode::Subscript(inner) => AstNodeIter::Subscript(inner.into_iter()),
|
||||
AstNode::Superscript(inner) => AstNodeIter::Superscript(inner.into_iter()),
|
||||
AstNode::TableCell(inner) => AstNodeIter::TableCell(inner.into_iter()),
|
||||
AstNode::Timestamp(inner) => AstNodeIter::Timestamp(inner.into_iter()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
multi_field_iter!(
|
||||
Document<'s>,
|
||||
DocumentIter,
|
||||
zeroth_section,
|
||||
std::option::Iter<'r, Section<'s>>,
|
||||
children,
|
||||
std::slice::Iter<'r, Heading<'s>>
|
||||
);
|
||||
multi_field_iter!(
|
||||
Heading<'s>,
|
||||
HeadingIter,
|
||||
title,
|
||||
std::slice::Iter<'r, Object<'s>>,
|
||||
children,
|
||||
std::slice::Iter<'r, DocumentElement<'s>>
|
||||
);
|
||||
children_iter!(Section<'s>, SectionIter, std::slice::Iter<'r, Element<'s>>);
|
||||
children_iter!(
|
||||
Paragraph<'s>,
|
||||
ParagraphIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
PlainList<'s>,
|
||||
PlainListIter,
|
||||
std::slice::Iter<'r, PlainListItem<'s>>
|
||||
);
|
||||
multi_field_iter!(
|
||||
PlainListItem<'s>,
|
||||
PlainListItemIter,
|
||||
tag,
|
||||
std::slice::Iter<'r, Object<'s>>,
|
||||
children,
|
||||
std::slice::Iter<'r, Element<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
GreaterBlock<'s>,
|
||||
GreaterBlockIter,
|
||||
std::slice::Iter<'r, Element<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
DynamicBlock<'s>,
|
||||
DynamicBlockIter,
|
||||
std::slice::Iter<'r, Element<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
FootnoteDefinition<'s>,
|
||||
FootnoteDefinitionIter,
|
||||
std::slice::Iter<'r, Element<'s>>
|
||||
);
|
||||
empty_iter!(Comment<'s>, CommentIter);
|
||||
children_iter!(Drawer<'s>, DrawerIter, std::slice::Iter<'r, Element<'s>>);
|
||||
children_iter!(
|
||||
PropertyDrawer<'s>,
|
||||
PropertyDrawerIter,
|
||||
std::slice::Iter<'r, NodeProperty<'s>>
|
||||
);
|
||||
empty_iter!(NodeProperty<'s>, NodePropertyIter);
|
||||
children_iter!(Table<'s>, TableIter, std::slice::Iter<'r, TableRow<'s>>);
|
||||
children_iter!(
|
||||
TableRow<'s>,
|
||||
TableRowIter,
|
||||
std::slice::Iter<'r, TableCell<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
VerseBlock<'s>,
|
||||
VerseBlockIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
empty_iter!(CommentBlock<'s>, CommentBlockIter);
|
||||
empty_iter!(ExampleBlock<'s>, ExampleBlockIter);
|
||||
empty_iter!(ExportBlock<'s>, ExportBlockIter);
|
||||
empty_iter!(SrcBlock<'s>, SrcBlockIter);
|
||||
empty_iter!(Clock<'s>, ClockIter);
|
||||
empty_iter!(DiarySexp<'s>, DiarySexpIter);
|
||||
empty_iter!(Planning<'s>, PlanningIter);
|
||||
empty_iter!(FixedWidthArea<'s>, FixedWidthAreaIter);
|
||||
empty_iter!(HorizontalRule<'s>, HorizontalRuleIter);
|
||||
empty_iter!(Keyword<'s>, KeywordIter);
|
||||
empty_iter!(BabelCall<'s>, BabelCallIter);
|
||||
empty_iter!(LatexEnvironment<'s>, LatexEnvironmentIter);
|
||||
children_iter!(Bold<'s>, BoldIter, std::slice::Iter<'r, Object<'s>>);
|
||||
children_iter!(Italic<'s>, ItalicIter, std::slice::Iter<'r, Object<'s>>);
|
||||
children_iter!(
|
||||
Underline<'s>,
|
||||
UnderlineIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
StrikeThrough<'s>,
|
||||
StrikeThroughIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
empty_iter!(Code<'s>, CodeIter);
|
||||
empty_iter!(Verbatim<'s>, VerbatimIter);
|
||||
empty_iter!(PlainText<'s>, PlainTextIter);
|
||||
empty_iter!(RegularLink<'s>, RegularLinkIter);
|
||||
children_iter!(
|
||||
RadioLink<'s>,
|
||||
RadioLinkIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
children_iter!(
|
||||
RadioTarget<'s>,
|
||||
RadioTargetIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
empty_iter!(PlainLink<'s>, PlainLinkIter);
|
||||
empty_iter!(AngleLink<'s>, AngleLinkIter);
|
||||
empty_iter!(OrgMacro<'s>, OrgMacroIter);
|
||||
empty_iter!(Entity<'s>, EntityIter);
|
||||
empty_iter!(LatexFragment<'s>, LatexFragmentIter);
|
||||
empty_iter!(ExportSnippet<'s>, ExportSnippetIter);
|
||||
multi_field_iter!(
|
||||
FootnoteReference<'s>,
|
||||
FootnoteReferenceIter,
|
||||
definition,
|
||||
std::slice::Iter<'r, Object<'s>>,
|
||||
);
|
||||
empty_iter!(Citation<'s>, CitationIter);
|
||||
empty_iter!(CitationReference<'s>, CitationReferenceIter);
|
||||
empty_iter!(InlineBabelCall<'s>, InlineBabelCallIter);
|
||||
empty_iter!(InlineSourceBlock<'s>, InlineSourceBlockIter);
|
||||
empty_iter!(LineBreak<'s>, LineBreakIter);
|
||||
empty_iter!(Target<'s>, TargetIter);
|
||||
empty_iter!(StatisticsCookie<'s>, StatisticsCookieIter);
|
||||
empty_iter!(Subscript<'s>, SubscriptIter);
|
||||
empty_iter!(Superscript<'s>, SuperscriptIter);
|
||||
children_iter!(
|
||||
TableCell<'s>,
|
||||
TableCellIter,
|
||||
std::slice::Iter<'r, Object<'s>>
|
||||
);
|
||||
empty_iter!(Timestamp<'s>, TimestampIter);
|
114
src/iter/macros.rs
Normal file
114
src/iter/macros.rs
Normal file
@ -0,0 +1,114 @@
|
||||
/// Write the implementation of From<> to convert a borrow of the type to an AstNode
|
||||
macro_rules! to_ast_node {
|
||||
($inp:ty, $enum:expr) => {
|
||||
impl<'r, 's> From<$inp> for AstNode<'r, 's> {
|
||||
fn from(value: $inp) -> Self {
|
||||
$enum(value)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use to_ast_node;
|
||||
|
||||
/// Create iterators for ast nodes where it only has to iterate over children
|
||||
macro_rules! children_iter {
|
||||
($astnodetype:ty, $itertype:ident, $innertype:ty) => {
|
||||
pub struct $itertype<'r, 's> {
|
||||
next: $innertype,
|
||||
}
|
||||
|
||||
impl<'r, 's> Iterator for $itertype<'r, 's> {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.next.next().map(Into::<AstNode>::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
type IntoIter = $itertype<'r, 's>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
$itertype {
|
||||
next: self.children.iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use children_iter;
|
||||
|
||||
/// Create iterators for ast nodes that do not contain any ast node children.
|
||||
macro_rules! empty_iter {
|
||||
($astnodetype:ty, $itertype:ident) => {
|
||||
pub struct $itertype<'r, 's> {
|
||||
phantom: PhantomData<&'r $astnodetype>,
|
||||
}
|
||||
|
||||
impl<'r, 's> Iterator for $itertype<'r, 's> {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
type IntoIter = $itertype<'r, 's>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
$itertype {
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use empty_iter;
|
||||
|
||||
/// Create iterators for ast nodes where it has to iterate over multiple child lists.
|
||||
macro_rules! multi_field_iter {
|
||||
($astnodetype:ty, $itertype:ident, $firstfieldname: ident, $firstinnertype:ty, $($fieldname: ident, $innertype:ty),*) => {
|
||||
pub struct $itertype<'r, 's> {
|
||||
$firstfieldname: $firstinnertype,
|
||||
$(
|
||||
$fieldname: $innertype,
|
||||
),*
|
||||
}
|
||||
|
||||
impl<'r, 's> Iterator for $itertype<'r, 's> {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.$firstfieldname.next().map(Into::<AstNode>::into)
|
||||
$(
|
||||
.or_else(|| self.$fieldname.next().map(Into::<AstNode>::into))
|
||||
),*
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
type IntoIter = $itertype<'r, 's>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
$itertype {
|
||||
$firstfieldname: self.$firstfieldname.iter(),
|
||||
$(
|
||||
$fieldname: self.$fieldname.iter(),
|
||||
),*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use multi_field_iter;
|
5
src/iter/mod.rs
Normal file
5
src/iter/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
mod all_ast_node_iter;
|
||||
mod ast_node;
|
||||
mod ast_node_iter;
|
||||
mod macros;
|
||||
pub(crate) use ast_node::AstNode;
|
@ -8,6 +8,7 @@ pub mod compare;
|
||||
|
||||
mod context;
|
||||
mod error;
|
||||
mod iter;
|
||||
pub mod parser;
|
||||
pub mod types;
|
||||
|
||||
|
@ -7,8 +7,6 @@ use super::in_buffer_settings::apply_in_buffer_settings;
|
||||
use super::in_buffer_settings::scan_for_in_buffer_settings;
|
||||
use super::org_source::OrgSource;
|
||||
use super::section::zeroth_section;
|
||||
use super::token::AllTokensIterator;
|
||||
use super::token::Token;
|
||||
use super::util::get_consumed;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::Context;
|
||||
@ -19,6 +17,7 @@ use crate::context::RefContext;
|
||||
use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::iter::AstNode;
|
||||
use crate::parser::org_source::convert_error;
|
||||
use crate::parser::util::blank_line;
|
||||
use crate::types::Document;
|
||||
@ -111,15 +110,14 @@ fn document_org_source<'b, 'g, 'r, 's>(
|
||||
_document(context, input).map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
||||
{
|
||||
// If there are radio targets in this document then we need to parse the entire document again with the knowledge of the radio targets.
|
||||
let all_radio_targets: Vec<&Vec<Object<'_>>> = document
|
||||
.iter_tokens()
|
||||
.filter_map(|tkn| match tkn {
|
||||
Token::Object(obj) => Some(obj),
|
||||
_ => None,
|
||||
})
|
||||
.filter_map(|obj| match obj {
|
||||
Object::RadioTarget(rt) => Some(rt),
|
||||
_ => None,
|
||||
let all_radio_targets: Vec<&Vec<Object<'_>>> = Into::<AstNode>::into(&document)
|
||||
.into_iter()
|
||||
.filter_map(|ast_node| {
|
||||
if let AstNode::RadioTarget(ast_node) = ast_node {
|
||||
Some(ast_node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|rt| &rt.children)
|
||||
.collect();
|
||||
@ -155,9 +153,3 @@ fn _document<'b, 'g, 'r, 's>(
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
impl<'s> Document<'s> {
|
||||
fn iter_tokens<'r>(&'r self) -> impl Iterator<Item = Token<'r, 's>> {
|
||||
AllTokensIterator::new(Token::Document(self))
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ mod table;
|
||||
mod target;
|
||||
mod text_markup;
|
||||
mod timestamp;
|
||||
mod token;
|
||||
mod util;
|
||||
pub use document::parse;
|
||||
pub use document::parse_with_settings;
|
||||
|
@ -1,135 +0,0 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::types::Document;
|
||||
use crate::types::DocumentElement;
|
||||
use crate::types::Element;
|
||||
use crate::types::Heading;
|
||||
use crate::types::NodeProperty;
|
||||
use crate::types::Object;
|
||||
use crate::types::PlainListItem;
|
||||
use crate::types::Section;
|
||||
use crate::types::TableCell;
|
||||
use crate::types::TableRow;
|
||||
|
||||
pub(crate) enum Token<'r, 's> {
|
||||
Document(&'r Document<'s>),
|
||||
Heading(&'r Heading<'s>),
|
||||
Section(&'r Section<'s>),
|
||||
Object(&'r Object<'s>),
|
||||
Element(&'r Element<'s>),
|
||||
PlainListItem(&'r PlainListItem<'s>),
|
||||
TableRow(&'r TableRow<'s>),
|
||||
TableCell(&'r TableCell<'s>),
|
||||
NodeProperty(&'r NodeProperty<'s>),
|
||||
}
|
||||
|
||||
impl<'r, 's> Token<'r, 's> {
|
||||
fn iter_tokens(&self) -> Box<dyn Iterator<Item = Token<'r, 's>> + '_> {
|
||||
match self {
|
||||
Token::Document(document) => Box::new(
|
||||
document
|
||||
.zeroth_section
|
||||
.iter()
|
||||
.map(Token::Section)
|
||||
.chain(document.children.iter().map(Token::Heading)),
|
||||
),
|
||||
Token::Heading(heading) => Box::new(heading.title.iter().map(Token::Object).chain(
|
||||
heading.children.iter().map(|de| match de {
|
||||
DocumentElement::Heading(ref obj) => Token::Heading(obj),
|
||||
DocumentElement::Section(ref obj) => Token::Section(obj),
|
||||
}),
|
||||
)),
|
||||
Token::Section(section) => Box::new(section.children.iter().map(Token::Element)),
|
||||
Token::Object(obj) => match obj {
|
||||
Object::Bold(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Object::Italic(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Object::Underline(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Object::StrikeThrough(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Object::Code(_) => Box::new(std::iter::empty()),
|
||||
Object::Verbatim(_) => Box::new(std::iter::empty()),
|
||||
Object::PlainText(_) => Box::new(std::iter::empty()),
|
||||
Object::RegularLink(_) => Box::new(std::iter::empty()),
|
||||
Object::RadioLink(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Object::RadioTarget(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Object::PlainLink(_) => Box::new(std::iter::empty()),
|
||||
Object::AngleLink(_) => Box::new(std::iter::empty()),
|
||||
Object::OrgMacro(_) => Box::new(std::iter::empty()),
|
||||
Object::Entity(_) => Box::new(std::iter::empty()),
|
||||
Object::LatexFragment(_) => Box::new(std::iter::empty()),
|
||||
Object::ExportSnippet(_) => Box::new(std::iter::empty()),
|
||||
Object::FootnoteReference(inner) => {
|
||||
Box::new(inner.definition.iter().map(Token::Object))
|
||||
}
|
||||
Object::Citation(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
||||
Object::CitationReference(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
||||
Object::InlineBabelCall(_) => Box::new(std::iter::empty()),
|
||||
Object::InlineSourceBlock(_) => Box::new(std::iter::empty()),
|
||||
Object::LineBreak(_) => Box::new(std::iter::empty()),
|
||||
Object::Target(_) => Box::new(std::iter::empty()),
|
||||
Object::StatisticsCookie(_) => Box::new(std::iter::empty()),
|
||||
Object::Subscript(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
||||
Object::Superscript(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
||||
Object::Timestamp(_) => Box::new(std::iter::empty()),
|
||||
},
|
||||
Token::Element(elem) => match elem {
|
||||
Element::Paragraph(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Element::PlainList(inner) => {
|
||||
Box::new(inner.children.iter().map(Token::PlainListItem))
|
||||
}
|
||||
Element::GreaterBlock(inner) => Box::new(inner.children.iter().map(Token::Element)),
|
||||
Element::DynamicBlock(inner) => Box::new(inner.children.iter().map(Token::Element)),
|
||||
Element::FootnoteDefinition(inner) => {
|
||||
Box::new(inner.children.iter().map(Token::Element))
|
||||
}
|
||||
Element::Comment(_) => Box::new(std::iter::empty()),
|
||||
Element::Drawer(inner) => Box::new(inner.children.iter().map(Token::Element)),
|
||||
Element::PropertyDrawer(inner) => {
|
||||
Box::new(inner.children.iter().map(Token::NodeProperty))
|
||||
}
|
||||
Element::Table(inner) => Box::new(inner.children.iter().map(Token::TableRow)),
|
||||
Element::VerseBlock(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
||||
Element::CommentBlock(_) => Box::new(std::iter::empty()),
|
||||
Element::ExampleBlock(_) => Box::new(std::iter::empty()),
|
||||
Element::ExportBlock(_) => Box::new(std::iter::empty()),
|
||||
Element::SrcBlock(_) => Box::new(std::iter::empty()),
|
||||
Element::Clock(_) => Box::new(std::iter::empty()),
|
||||
Element::DiarySexp(_) => Box::new(std::iter::empty()),
|
||||
Element::Planning(_) => Box::new(std::iter::empty()),
|
||||
Element::FixedWidthArea(_) => Box::new(std::iter::empty()),
|
||||
Element::HorizontalRule(_) => Box::new(std::iter::empty()),
|
||||
Element::Keyword(_) => Box::new(std::iter::empty()),
|
||||
Element::BabelCall(_) => Box::new(std::iter::empty()),
|
||||
Element::LatexEnvironment(_) => Box::new(std::iter::empty()),
|
||||
},
|
||||
Token::PlainListItem(elem) => Box::new(elem.children.iter().map(Token::Element)),
|
||||
Token::TableRow(elem) => Box::new(elem.children.iter().map(Token::TableCell)),
|
||||
Token::TableCell(elem) => Box::new(elem.children.iter().map(Token::Object)),
|
||||
Token::NodeProperty(_) => Box::new(std::iter::empty()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct AllTokensIterator<'r, 's> {
|
||||
queued_tokens: VecDeque<Token<'r, 's>>,
|
||||
}
|
||||
|
||||
impl<'r, 's> AllTokensIterator<'r, 's> {
|
||||
pub(crate) fn new(tkn: Token<'r, 's>) -> Self {
|
||||
let mut queued_tokens = VecDeque::new();
|
||||
queued_tokens.push_back(tkn);
|
||||
AllTokensIterator { queued_tokens }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> Iterator for AllTokensIterator<'r, 's> {
|
||||
type Item = Token<'r, 's>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next_token = match self.queued_tokens.pop_front() {
|
||||
Some(tkn) => tkn,
|
||||
None => return None,
|
||||
};
|
||||
self.queued_tokens.extend(next_token.iter_tokens());
|
||||
Some(next_token)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user