From 5e73ca74d56b4d02bc6d0af78f3a8e4fd1098602 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Tue, 18 Jul 2023 23:27:48 -0400 Subject: [PATCH] Fix embedding text that coincidentally matches org-mode object syntax inside a LaTeX environment. I was using the plain_text matcher before which adds its own exit condition that does not apply to LaTeX environments. --- src/parser/latex_environment.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/parser/latex_environment.rs b/src/parser/latex_environment.rs index a1353f7..7b6e653 100644 --- a/src/parser/latex_environment.rs +++ b/src/parser/latex_environment.rs @@ -2,10 +2,13 @@ use nom::branch::alt; use nom::bytes::complete::tag; use nom::bytes::complete::tag_no_case; use nom::bytes::complete::take_while1; +use nom::character::complete::anychar; use nom::character::complete::line_ending; use nom::character::complete::space0; use nom::combinator::eof; -use nom::combinator::map; +use nom::combinator::peek; +use nom::combinator::recognize; +use nom::multi::many_till; use nom::sequence::tuple; use super::util::get_consumed; @@ -15,7 +18,7 @@ use crate::parser::exiting::ExitClass; use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ExitMatcherNode; use crate::parser::parser_with_context::parser_with_context; -use crate::parser::plain_text::plain_text; +use crate::parser::util::exit_matcher_parser; use crate::parser::util::start_of_line; use crate::parser::LatexEnvironment; @@ -41,9 +44,7 @@ pub fn latex_environment<'r, 's>( exit_matcher: &latex_environment_end_specialized, })); - let (remaining, _contents) = map(parser_with_context!(plain_text)(&parser_context), |obj| { - obj.source - })(remaining)?; + let (remaining, _contents) = contents(&latex_environment_end_specialized, context, remaining)?; let (remaining, _end) = latex_environment_end_specialized(&parser_context, remaining)?; let source = get_consumed(input, remaining); @@ -55,6 +56,23 @@ fn name<'s>(input: &'s str) -> Res<&'s str, &'s str> { take_while1(|c: char| c.is_alphanumeric() || c == '*')(input) } +#[tracing::instrument(ret, level = "debug", skip(end_matcher))] +pub fn contents<'r, 's, F: Fn(Context<'r, 's>, &'s str) -> Res<&'s str, &'s str>>( + end_matcher: F, + context: Context<'r, 's>, + input: &'s str, +) -> Res<&'s str, &'s str> { + let (remaining, source) = recognize(many_till( + anychar, + peek(alt(( + parser_with_context!(exit_matcher_parser)(context), + parser_with_context!(end_matcher)(context), + ))), + ))(input)?; + + Ok((remaining, source)) +} + fn latex_environment_end( current_name: &str, ) -> impl for<'r, 's> Fn(Context<'r, 's>, &'s str) -> Res<&'s str, &'s str> {