From 31c782499e9c8dc9e790314a561a34504b27a347 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Thu, 21 Sep 2023 23:00:28 -0400 Subject: [PATCH] Do not match text markup end with empty contents. --- src/parser/org_source.rs | 4 ++++ src/parser/text_markup.rs | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/parser/org_source.rs b/src/parser/org_source.rs index 41348124..f38b85da 100644 --- a/src/parser/org_source.rs +++ b/src/parser/org_source.rs @@ -59,6 +59,10 @@ impl<'s> OrgSource<'s> { self.end - self.start } + pub(crate) fn get_byte_offset(&self) -> usize { + self.start + } + pub(crate) fn get_preceding_character(&self) -> Option { self.preceding_character } diff --git a/src/parser/text_markup.rs b/src/parser/text_markup.rs index 5cae3f69..a32c4c11 100644 --- a/src/parser/text_markup.rs +++ b/src/parser/text_markup.rs @@ -182,7 +182,7 @@ fn _text_markup_object<'b, 'g, 'r, 's, 'c>( let (remaining, open) = tag(marker_symbol)(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 text_markup_end_specialized = text_markup_end(open.into(), remaining.get_byte_offset()); let contexts = [ ContextElement::ContextObject(marker_symbol), ContextElement::ExitMatcherNode(ExitMatcherNode { @@ -244,7 +244,7 @@ fn _text_markup_string<'b, 'g, 'r, 's, 'c>( let (remaining, open) = tag(marker_symbol)(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 text_markup_end_specialized = text_markup_end(open.into(), remaining.get_byte_offset()); let contexts = [ ContextElement::ContextObject(marker_symbol), ContextElement::ExitMatcherNode(ExitMatcherNode { @@ -315,8 +315,13 @@ fn post<'b, 'g, 'r, 's>( Ok((remaining, ())) } -fn text_markup_end<'c>(marker_symbol: &'c str) -> impl ContextMatcher + 'c { - move |context, input: OrgSource<'_>| _text_markup_end(context, input, marker_symbol) +fn text_markup_end<'c>( + marker_symbol: &'c str, + contents_start_offset: usize, +) -> impl ContextMatcher + 'c { + move |context, input: OrgSource<'_>| { + _text_markup_end(context, input, marker_symbol, contents_start_offset) + } } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] @@ -324,7 +329,13 @@ fn _text_markup_end<'b, 'g, 'r, 's, 'c>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, marker_symbol: &'c str, + contents_start_offset: usize, ) -> Res, OrgSource<'s>> { + if input.get_byte_offset() == contents_start_offset { + return Err(nom::Err::Error(CustomError::MyError(MyError( + "Text markup cannot be empty".into(), + )))); + } not(preceded_by_whitespace(false))(input)?; let (remaining, _marker) = terminated( tag(marker_symbol), @@ -424,7 +435,7 @@ fn _rematch_text_markup_object<'b, 'g, 'r, 's, 'x>( let (remaining, _) = pre(context, input)?; let (remaining, open) = tag(marker_symbol)(remaining)?; let (remaining, _peek_not_whitespace) = peek(not(multispace1))(remaining)?; - let text_markup_end_specialized = text_markup_end(open.into()); + let text_markup_end_specialized = text_markup_end(open.into(), remaining.get_byte_offset()); let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode { class: ExitClass::Gamma, exit_matcher: &text_markup_end_specialized,