136 lines
6.7 KiB
Rust
136 lines
6.7 KiB
Rust
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)
|
|
}
|
|
}
|