Switch greater blocks to using name provided when building exit matcher instead of from context.

This commit is contained in:
Tom Alexander 2023-08-27 22:35:37 -04:00
parent b35d785e73
commit 20c17c40be
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 17 additions and 22 deletions

View File

@ -58,15 +58,15 @@ pub fn greater_block<'r, 's>(
"Cannot nest objects of the same element".into(), "Cannot nest objects of the same element".into(),
)))); ))));
} }
let exit_with_name = greater_block_end(name.into());
let (remaining, parameters) = opt(tuple((space1, parameters)))(remaining)?; let (remaining, parameters) = opt(tuple((space1, parameters)))(remaining)?;
let (remaining, _nl) = line_ending(remaining)?; let (remaining, _nl) = line_ending(remaining)?;
let parser_context = context let parser_context = context
.with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true))
.with_additional_node(ContextElement::Context(context_name)) .with_additional_node(ContextElement::Context(context_name))
.with_additional_node(ContextElement::GreaterBlock(name.into()))
.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
class: ExitClass::Alpha, class: ExitClass::Alpha,
exit_matcher: &greater_block_end, exit_matcher: &exit_with_name,
})); }));
let parameters = match parameters { let parameters = match parameters {
Some((_ws, parameters)) => Some(parameters), Some((_ws, parameters)) => Some(parameters),
@ -94,7 +94,7 @@ pub fn greater_block<'r, 's>(
(remaining, children) (remaining, children)
} }
}; };
let (remaining, _end) = greater_block_end(&parser_context, remaining)?; let (remaining, _end) = exit_with_name(&parser_context, remaining)?;
// Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block // Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block
@ -120,31 +120,27 @@ fn parameters<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
is_not("\r\n")(input) is_not("\r\n")(input)
} }
fn greater_block_end<'x>(
name: &'x str,
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
// TODO: Can this be done without making an owned copy?
let name = name.to_owned();
move |context: Context, input: OrgSource<'_>| _greater_block_end(context, input, name.as_str())
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn greater_block_end<'r, 's>( fn _greater_block_end<'r, 's, 'x>(
context: Context<'r, 's>, _context: Context<'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
name: &'x str,
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, OrgSource<'s>> {
start_of_line(input)?; start_of_line(input)?;
let current_name: &str = get_context_greater_block_name(context).ok_or(nom::Err::Error(
CustomError::MyError(MyError("Not inside a greater block".into())),
))?;
let (remaining, _leading_whitespace) = space0(input)?; let (remaining, _leading_whitespace) = space0(input)?;
let (remaining, (_begin, _name, _ws)) = tuple(( let (remaining, (_begin, _name, _ws)) = tuple((
tag_no_case("#+end_"), tag_no_case("#+end_"),
tag_no_case(current_name), tag_no_case(name),
alt((eof, line_ending)), alt((eof, line_ending)),
))(remaining)?; ))(remaining)?;
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);
Ok((remaining, source)) Ok((remaining, source))
} }
fn get_context_greater_block_name<'r, 's>(context: Context<'r, 's>) -> Option<&'s str> {
for thing in context.iter() {
match thing.get_data() {
ContextElement::GreaterBlock(name) => return Some(name),
_ => {}
};
}
None
}

View File

@ -110,10 +110,9 @@ impl<'r, 's> ContextTree<'r, 's> {
pub enum ContextElement<'r, 's> { pub enum ContextElement<'r, 's> {
/// Stores a parser that indicates that children should exit upon matching an exit matcher. /// Stores a parser that indicates that children should exit upon matching an exit matcher.
ExitMatcherNode(ExitMatcherNode<'r>), ExitMatcherNode(ExitMatcherNode<'r>),
Context(&'r str),
/// Stores the name of the greater block. /// Stores the name of the current element to prevent directly nesting elements of the same type.
GreaterBlock(&'s str), Context(&'r str),
/// Indicates if elements should consume the whitespace after them. /// Indicates if elements should consume the whitespace after them.
ConsumeTrailingWhitespace(bool), ConsumeTrailingWhitespace(bool),