From 728a79f9a41d1f88562527d04aa1ac4aa6592b4d Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 6 Sep 2023 13:56:27 -0400 Subject: [PATCH] Handle zero-width space in text markup. --- .../text_markup/verbatim_with_equals_inside.org | 3 +++ src/parser/text_markup.rs | 3 ++- src/parser/util.rs | 17 ++++++++--------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/org_mode_samples/object/text_markup/verbatim_with_equals_inside.org b/org_mode_samples/object/text_markup/verbatim_with_equals_inside.org index 1a1b513..173377b 100644 --- a/org_mode_samples/object/text_markup/verbatim_with_equals_inside.org +++ b/org_mode_samples/object/text_markup/verbatim_with_equals_inside.org @@ -1 +1,4 @@ foo ==>bar=. + +# This uses a zero-width space to escape the equals signs to make the verbatim not end. +=lorem =​= ipsum= diff --git a/src/parser/text_markup.rs b/src/parser/text_markup.rs index f339fdd..48f6eea 100644 --- a/src/parser/text_markup.rs +++ b/src/parser/text_markup.rs @@ -231,7 +231,8 @@ fn _text_markup_string<'b, 'g, 'r, 's, 'c>( ) -> Res, OrgSource<'s>> { let (remaining, _) = pre(context, input)?; let (remaining, open) = tag(marker_symbol)(remaining)?; - let (remaining, _peek_not_whitespace) = peek(not(multispace1))(remaining)?; + let (remaining, _peek_not_whitespace) = + peek(verify(anychar, |c| !c.is_whitespace() && *c != '\u{200B}'))(remaining)?; let text_markup_end_specialized = text_markup_end(open.into()); let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode { class: ExitClass::Gamma, diff --git a/src/parser/util.rs b/src/parser/util.rs index ba84ae1..67fccbd 100644 --- a/src/parser/util.rs +++ b/src/parser/util.rs @@ -127,15 +127,14 @@ pub fn start_of_line<'s>(input: OrgSource<'s>) -> Res, ()> { #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] pub fn preceded_by_whitespace<'s>(input: OrgSource<'s>) -> Res, ()> { let preceding_character = input.get_preceding_character(); - match preceding_character { - Some('\n') | Some('\r') | Some(' ') | Some('\t') => {} - // If None, we are at the start of the file which is not allowed - None | Some(_) => { - return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not preceded by whitespace.".into(), - )))); - } - }; + if !preceding_character + .map(|c| c.is_whitespace() || c == '\u{200B}') // 200B = Zero-width space + .unwrap_or(false) + { + return Err(nom::Err::Error(CustomError::MyError(MyError( + "Not preceded by whitespace.".into(), + )))); + } Ok((input, ())) }