From 76a81b73ac4de8772da2d7e305e1e9cc3246e0c4 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Thu, 7 Sep 2023 02:59:08 -0400 Subject: [PATCH] Add a detect object function similar to the detect element function. --- src/parser/object_parser.rs | 20 ++++++++++++++++++++ src/parser/plain_text.rs | 6 ++++-- src/parser/subscript_and_superscript.rs | 13 +++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/parser/object_parser.rs b/src/parser/object_parser.rs index e3db553..b65f525 100644 --- a/src/parser/object_parser.rs +++ b/src/parser/object_parser.rs @@ -4,8 +4,11 @@ use nom::combinator::map; use super::org_source::OrgSource; use super::plain_text::plain_text; use super::regular_link::regular_link; +use super::subscript_and_superscript::detect_subscript_or_superscript; use crate::context::parser_with_context; use crate::context::RefContext; +use crate::error::CustomError; +use crate::error::MyError; use crate::error::Res; use crate::parser::angle_link::angle_link; use crate::parser::citation::citation; @@ -165,6 +168,23 @@ pub fn any_object_except_plain_text<'b, 'g, 'r, 's>( Ok((remaining, object)) } +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +pub fn detect_any_object_except_plain_text<'b, 'g, 'r, 's>( + context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, ()> { + if detect_subscript_or_superscript(input).is_ok() { + return Ok((input, ())); + } + if any_object_except_plain_text(context, input).is_ok() { + return Ok((input, ())); + } + + return Err(nom::Err::Error(CustomError::MyError(MyError( + "No object detected.".into(), + )))); +} + #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] pub fn regular_link_description_object_set<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, diff --git a/src/parser/plain_text.rs b/src/parser/plain_text.rs index 1dbc295..e57f4d1 100644 --- a/src/parser/plain_text.rs +++ b/src/parser/plain_text.rs @@ -7,7 +7,7 @@ use nom::combinator::recognize; use nom::combinator::verify; use nom::multi::many_till; -use super::object_parser::any_object_except_plain_text; +use super::object_parser::detect_any_object_except_plain_text; use super::org_source::OrgSource; use super::radio_link::RematchObject; use super::util::exit_matcher_parser; @@ -46,7 +46,9 @@ fn plain_text_end<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, ) -> Res, OrgSource<'s>> { - recognize(parser_with_context!(any_object_except_plain_text)(context))(input) + recognize(parser_with_context!(detect_any_object_except_plain_text)( + context, + ))(input) } impl<'x> RematchObject<'x> for PlainText<'x> { diff --git a/src/parser/subscript_and_superscript.rs b/src/parser/subscript_and_superscript.rs index 00a76cd..e2025e7 100644 --- a/src/parser/subscript_and_superscript.rs +++ b/src/parser/subscript_and_superscript.rs @@ -30,6 +30,19 @@ use crate::types::Object; use crate::types::Subscript; use crate::types::Superscript; +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +pub fn detect_subscript_or_superscript<'s>(input: OrgSource<'s>) -> Res, ()> { + // This does not have to detect all valid subscript/superscript but all that it detects must be valid. + let (remaining, _) = one_of("_^")(input)?; + pre(input)?; + if tag::<_, _, CustomError<_>>("*")(remaining).is_ok() { + return Ok((input, ())); + } + let (remaining, _) = opt(one_of("+-"))(remaining)?; + let (_remaining, _) = verify(anychar, |c| c.is_alphanumeric())(remaining)?; + Ok((input, ())) +} + #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] pub fn subscript<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>,