diff --git a/src/parser/parser_context.rs b/src/parser/parser_context.rs index f3fc1708..db7312f2 100644 --- a/src/parser/parser_context.rs +++ b/src/parser/parser_context.rs @@ -149,18 +149,6 @@ pub enum ContextElement<'r, 's> { /// unbalanced brackets can be detected in the middle of an /// object. InlineSourceBlockBracket(InlineSourceBlockBracket<'s>), - - /// Stores the current bracket or parenthesis depth inside a - /// superscript or superscript. - /// - /// Inside the braces of a subscript or superscript there must be - /// balanced braces {}, so this stores the amount of opening - /// braces subtracted by the amount of closing braces within the - /// definition must equal zero. - /// - /// A reference to the position in the string is also included so - /// unbalanced braces can be detected in the middle of an object. - SubscriptSuperscriptBrace(SubscriptSuperscriptBrace<'s>), } pub struct ExitMatcherNode<'r> { @@ -180,12 +168,6 @@ pub struct InlineSourceBlockBracket<'s> { pub depth: usize, } -#[derive(Debug)] -pub struct SubscriptSuperscriptBrace<'s> { - pub position: OrgSource<'s>, - pub depth: usize, -} - impl<'r> std::fmt::Debug for ExitMatcherNode<'r> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut formatter = f.debug_struct("ExitMatcherNode"); diff --git a/src/parser/subscript_and_superscript.rs b/src/parser/subscript_and_superscript.rs index 43978da3..cbc3f482 100644 --- a/src/parser/subscript_and_superscript.rs +++ b/src/parser/subscript_and_superscript.rs @@ -21,7 +21,6 @@ use crate::parser::exiting::ExitClass; use crate::parser::object_parser::standard_set_object; use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ExitMatcherNode; -use crate::parser::parser_context::SubscriptSuperscriptBrace; use crate::parser::parser_with_context::parser_with_context; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; @@ -154,16 +153,11 @@ fn script_with_braces<'r, 's>( input: OrgSource<'s>, ) -> Res, Vec>> { let (remaining, _) = tag("{")(input)?; - let parser_context = context - .with_additional_node(ContextElement::SubscriptSuperscriptBrace( - SubscriptSuperscriptBrace { - position: remaining.into(), - depth: 0, - }, - )) - .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { + let exit_with_depth = script_with_braces_end(remaining.get_brace_depth()); + let parser_context = + context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { class: ExitClass::Gamma, - exit_matcher: &script_with_braces_end, + exit_matcher: &exit_with_depth, })); let (remaining, (children, _exit_contents)) = many_till( @@ -175,49 +169,30 @@ fn script_with_braces<'r, 's>( Ok((remaining, children)) } -#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn script_with_braces_end<'r, 's>( - context: Context<'r, 's>, - input: OrgSource<'s>, -) -> Res, OrgSource<'s>> { - let context_depth = get_bracket_depth(context) - .expect("This function should only be called from inside a subscript or superscript."); - let text_since_context_entry = get_consumed(context_depth.position, input); - let mut current_depth = context_depth.depth; - for c in Into::<&str>::into(text_since_context_entry).chars() { - match c { - '{' => { - current_depth += 1; - } - '}' if current_depth == 0 => { - panic!("Exceeded subscript or superscript brace depth.") - } - '}' if current_depth > 0 => { - current_depth -= 1; - } - _ => {} - } +fn script_with_braces_end( + starting_brace_depth: isize, +) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res, OrgSource<'s>> { + move |context: Context, input: OrgSource<'_>| { + _script_with_braces_end(context, input, starting_brace_depth) } - if current_depth == 0 { - let close_bracket = tag::<&str, OrgSource<'_>, CustomError>>("}")(input); - if close_bracket.is_ok() { - return close_bracket; - } - } - return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not a valid end for subscript or superscript.".into(), - )))); } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn get_bracket_depth<'r, 's>( - context: Context<'r, 's>, -) -> Option<&'r SubscriptSuperscriptBrace<'s>> { - for node in context.iter() { - match node.get_data() { - ContextElement::SubscriptSuperscriptBrace(depth) => return Some(depth), - _ => {} - } +fn _script_with_braces_end<'r, 's>( + _context: Context<'r, 's>, + input: OrgSource<'s>, + starting_brace_depth: isize, +) -> Res, OrgSource<'s>> { + let current_depth = input.get_brace_depth() - starting_brace_depth; + if current_depth > 0 { + // Its impossible for the next character to end the subscript or superscript if we're any amount of braces deep + return Err(nom::Err::Error(CustomError::MyError(MyError( + "Not a valid end for subscript or superscript.".into(), + )))); } - None + if current_depth < 0 { + // This shouldn't be possible because if depth is 0 then a closing brace should end the subscript or superscript. + unreachable!("Exceeded subscript or superscript brace depth.") + } + tag("}")(input) }