diff --git a/src/parser/subscript_and_superscript.rs b/src/parser/subscript_and_superscript.rs index 9ad8906..00a76cd 100644 --- a/src/parser/subscript_and_superscript.rs +++ b/src/parser/subscript_and_superscript.rs @@ -15,6 +15,7 @@ use super::org_source::BracketDepth; use super::org_source::OrgSource; use super::util::exit_matcher_parser; use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting; +use super::util::preceded_by_whitespace; use crate::context::parser_with_context; use crate::context::ContextElement; use crate::context::ContextMatcher; @@ -36,7 +37,7 @@ pub fn subscript<'b, 'g, 'r, 's>( ) -> Res, Subscript<'s>> { // We check for the underscore first before checking the pre-character as a minor optimization to avoid walking up the context tree to find the document root unnecessarily. let (remaining, _) = tag("_")(input)?; - pre(context, input)?; + pre(input)?; let (remaining, _body) = script_body(context, remaining)?; let (remaining, _trailing_whitespace) = maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?; @@ -56,7 +57,7 @@ pub fn superscript<'b, 'g, 'r, 's>( ) -> Res, Superscript<'s>> { // We check for the circumflex first before checking the pre-character as a minor optimization to avoid walking up the context tree to find the document root unnecessarily. let (remaining, _) = tag("^")(input)?; - pre(context, input)?; + pre(input)?; let (remaining, _body) = script_body(context, remaining)?; let (remaining, _trailing_whitespace) = maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?; @@ -70,19 +71,8 @@ pub fn superscript<'b, 'g, 'r, 's>( } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn pre<'b, 'g, 'r, 's>( - _context: RefContext<'b, 'g, 'r, 's>, - input: OrgSource<'s>, -) -> Res, ()> { - let preceding_character = input.get_preceding_character(); - match preceding_character { - Some(c) if !c.is_whitespace() => {} - _ => { - return Err(nom::Err::Error(CustomError::MyError(MyError( - "Must be preceded by a non-whitespace character.".into(), - )))); - } - }; +fn pre<'s>(input: OrgSource<'s>) -> Res, ()> { + not(preceded_by_whitespace(true))(input)?; Ok((input, ())) } @@ -120,37 +110,27 @@ fn script_asterisk<'b, 'g, 'r, 's>( #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn script_alphanum<'b, 'g, 'r, 's>( - context: RefContext<'b, 'g, 'r, 's>, + _context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, ) -> Res, OrgSource<'s>> { let (remaining, _sign) = opt(recognize(one_of("+-")))(input)?; - let (remaining, _script) = many_till( - parser_with_context!(script_alphanum_character)(context), - parser_with_context!(end_script_alphanum_character)(context), - )(remaining)?; + let (remaining, _script) = + many_till(script_alphanum_character, end_script_alphanum_character)(remaining)?; let source = get_consumed(input, remaining); Ok((remaining, source)) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn script_alphanum_character<'b, 'g, 'r, 's>( - _context: RefContext<'b, 'g, 'r, 's>, - input: OrgSource<'s>, -) -> Res, OrgSource<'s>> { +fn script_alphanum_character<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { recognize(verify(anychar, |c| { c.is_alphanumeric() || r#",.\"#.contains(*c) }))(input) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn end_script_alphanum_character<'b, 'g, 'r, 's>( - context: RefContext<'b, 'g, 'r, 's>, - input: OrgSource<'s>, -) -> Res, OrgSource<'s>> { +fn end_script_alphanum_character<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { let (remaining, final_char) = recognize(verify(anychar, |c| c.is_alphanumeric()))(input)?; - peek(not(parser_with_context!(script_alphanum_character)( - context, - )))(remaining)?; + peek(not(script_alphanum_character))(remaining)?; Ok((remaining, final_char)) } diff --git a/src/parser/text_markup.rs b/src/parser/text_markup.rs index d131370..e36d179 100644 --- a/src/parser/text_markup.rs +++ b/src/parser/text_markup.rs @@ -325,7 +325,7 @@ fn _text_markup_end<'b, 'g, 'r, 's, 'c>( input: OrgSource<'s>, marker_symbol: &'c str, ) -> Res, OrgSource<'s>> { - not(preceded_by_whitespace)(input)?; + not(preceded_by_whitespace(false))(input)?; let (remaining, _marker) = terminated( tag(marker_symbol), peek(parser_with_context!(post)(context)), diff --git a/src/parser/util.rs b/src/parser/util.rs index c715a50..6464fe8 100644 --- a/src/parser/util.rs +++ b/src/parser/util.rs @@ -135,16 +135,25 @@ pub fn start_of_line<'s>(input: OrgSource<'s>) -> Res, ()> { } } +pub fn preceded_by_whitespace( + allow_start_of_file: bool, +) -> impl for<'s> Fn(OrgSource<'s>) -> Res, ()> { + move |input| _preceded_by_whitespace(allow_start_of_file, input) +} + /// Check that we are at the start of a line #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub fn preceded_by_whitespace<'s>(input: OrgSource<'s>) -> Res, ()> { +fn _preceded_by_whitespace<'s>( + allow_start_of_file: bool, + input: OrgSource<'s>, +) -> Res, ()> { let preceding_character = input.get_preceding_character(); if !preceding_character .map(|c| c.is_whitespace() || c == '\u{200B}') // 200B = Zero-width space - .unwrap_or(false) + .unwrap_or(allow_start_of_file) { return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not preceded by whitespace.".into(), + "Must be preceded by a non-whitespace character.".into(), )))); } Ok((input, ()))