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:
parent
7402de6a7c
commit
36210c2d7f
@ -96,6 +96,9 @@ fn _preceded_by_whitespace<'r, 's>(context: Context<'r, 's>) -> bool {
|
|||||||
}
|
}
|
||||||
ContextElement::Context(_) => {}
|
ContextElement::Context(_) => {}
|
||||||
ContextElement::ListItem(_) => {}
|
ContextElement::ListItem(_) => {}
|
||||||
|
ContextElement::DocumentRoot(_) => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -43,10 +43,7 @@ where
|
|||||||
.into_iter_until(context)
|
.into_iter_until(context)
|
||||||
.filter_map(|context_element| match context_element {
|
.filter_map(|context_element| match context_element {
|
||||||
ContextElement::PreviousElementNode(elem) => Some(elem.element),
|
ContextElement::PreviousElementNode(elem) => Some(elem.element),
|
||||||
ContextElement::ExitMatcherNode(_) => None,
|
_ => None,
|
||||||
ContextElement::Context(_) => None,
|
|
||||||
ContextElement::StartOfParagraph => None,
|
|
||||||
ContextElement::ListItem(_) => None,
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if elements.is_empty() {
|
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()");
|
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;
|
current_context = next_context;
|
||||||
match context_element {
|
match context_element {
|
||||||
ContextElement::ExitMatcherNode(_) => {}
|
|
||||||
ContextElement::StartOfParagraph => {}
|
|
||||||
ContextElement::Context(_) => {}
|
|
||||||
ContextElement::PreviousElementNode(PreviousElementNode {
|
ContextElement::PreviousElementNode(PreviousElementNode {
|
||||||
element: token,
|
element: token,
|
||||||
}) => {
|
}) => {
|
||||||
ret.push(token);
|
ret.push(token);
|
||||||
}
|
}
|
||||||
ContextElement::ListItem(_) => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ret.reverse();
|
ret.reverse();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
use super::combinator::context_many1;
|
use super::combinator::context_many1;
|
||||||
use super::error::Res;
|
use super::error::Res;
|
||||||
use super::paragraph::paragraph;
|
use super::paragraph::paragraph;
|
||||||
|
use super::parser_context::ContextElement;
|
||||||
use super::parser_context::ContextTree;
|
use super::parser_context::ContextTree;
|
||||||
use super::token::Paragraph;
|
use super::token::Paragraph;
|
||||||
use super::token::Token;
|
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>> {
|
pub fn document(input: &str) -> Res<&str, Vec<Paragraph>> {
|
||||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
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
|
let paragraphs = tokens
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|token| match token {
|
.map(|token| match token {
|
||||||
|
@ -94,6 +94,7 @@ impl<'r, 's> ContextTree<'r, 's> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ContextElement<'r, 's> {
|
pub enum ContextElement<'r, 's> {
|
||||||
|
DocumentRoot(&'s str),
|
||||||
ExitMatcherNode(ExitMatcherNode<'r>),
|
ExitMatcherNode(ExitMatcherNode<'r>),
|
||||||
PreviousElementNode(PreviousElementNode<'s>),
|
PreviousElementNode(PreviousElementNode<'s>),
|
||||||
Context(&'r str),
|
Context(&'r str),
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
use super::parser_context::ContextElement;
|
use super::parser_context::ContextElement;
|
||||||
use super::Context;
|
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 {
|
pub fn in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name: &'x str) -> bool {
|
||||||
for thing in context.iter() {
|
for thing in context.iter() {
|
||||||
match thing.get_data() {
|
match thing.get_data() {
|
||||||
ContextElement::ExitMatcherNode(_) => {}
|
|
||||||
ContextElement::PreviousElementNode(_) => {}
|
|
||||||
ContextElement::Context(name) if *name == section_name => return true,
|
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
|
false
|
||||||
|
Loading…
Reference in New Issue
Block a user