Add a DocumentRoot context element storing the original full document.

This might be used for look-behind instead of storing previous element nodes in the context tree.
This commit is contained in:
Tom Alexander 2023-03-23 16:40:39 -04:00
parent 7402de6a7c
commit 36210c2d7f
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 24 additions and 14 deletions

View File

@ -96,6 +96,9 @@ fn _preceded_by_whitespace<'r, 's>(context: Context<'r, 's>) -> bool {
}
ContextElement::Context(_) => {}
ContextElement::ListItem(_) => {}
ContextElement::DocumentRoot(_) => {
return true;
}
}
} else {
break;

View File

@ -43,10 +43,7 @@ where
.into_iter_until(context)
.filter_map(|context_element| match context_element {
ContextElement::PreviousElementNode(elem) => Some(elem.element),
ContextElement::ExitMatcherNode(_) => None,
ContextElement::Context(_) => None,
ContextElement::StartOfParagraph => None,
ContextElement::ListItem(_) => None,
_ => None,
})
.collect();
if elements.is_empty() {
@ -86,15 +83,12 @@ where
let context_element = context_element.expect("We only pop off context elements created in this function, so they are all Some()");
current_context = next_context;
match context_element {
ContextElement::ExitMatcherNode(_) => {}
ContextElement::StartOfParagraph => {}
ContextElement::Context(_) => {}
ContextElement::PreviousElementNode(PreviousElementNode {
element: token,
}) => {
ret.push(token);
}
ContextElement::ListItem(_) => {}
_ => {}
};
}
ret.reverse();

View File

@ -2,6 +2,7 @@
use super::combinator::context_many1;
use super::error::Res;
use super::paragraph::paragraph;
use super::parser_context::ContextElement;
use super::parser_context::ContextTree;
use super::token::Paragraph;
use super::token::Token;
@ -14,7 +15,9 @@ type UnboundMatcher<'r, 's, I, O, E> = dyn Fn(Context<'r, 's>, I) -> IResult<I,
pub fn document(input: &str) -> Res<&str, Vec<Paragraph>> {
let initial_context: ContextTree<'_, '_> = ContextTree::new();
let (remaining, tokens) = context_many1(&initial_context, paragraph)(input)?;
let document_context =
initial_context.with_additional_node(ContextElement::DocumentRoot(input));
let (remaining, tokens) = context_many1(&document_context, paragraph)(input)?;
let paragraphs = tokens
.into_iter()
.map(|token| match token {

View File

@ -94,6 +94,7 @@ impl<'r, 's> ContextTree<'r, 's> {
#[derive(Debug)]
pub enum ContextElement<'r, 's> {
DocumentRoot(&'s str),
ExitMatcherNode(ExitMatcherNode<'r>),
PreviousElementNode(PreviousElementNode<'s>),
Context(&'r str),

View File

@ -1,15 +1,24 @@
use super::parser_context::ContextElement;
use super::Context;
/// Check if we are below a section of the given section type regardless of depth
pub fn in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name: &'x str) -> bool {
for thing in context.iter() {
match thing.get_data() {
ContextElement::ExitMatcherNode(_) => {}
ContextElement::PreviousElementNode(_) => {}
ContextElement::Context(name) if *name == section_name => return true,
ContextElement::Context(_) => {}
ContextElement::StartOfParagraph => {} // TODO: If we specialize this to bold then this would be a good spot to stop scanning
ContextElement::ListItem(_) => {}
_ => {}
}
}
false
}
/// Checks if we are currently an immediate child of the given section type
pub fn immediate_in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name: &'x str) -> bool {
for thing in context.iter() {
match thing.get_data() {
ContextElement::Context(name) if *name == section_name => return true,
ContextElement::Context(name) if *name != section_name => return false,
_ => {}
}
}
false