From 7833a58461311245849589f7a1199e3090eeb0cc Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 16 Oct 2023 14:55:40 -0400 Subject: [PATCH] Apply a similar optimization to the detect element parser but also unify detection of affiliated keywords. --- src/parser/diary_sexp.rs | 17 ++++++--- src/parser/element_parser.rs | 63 ++++++++++++++++++++++++------- src/parser/fixed_width_area.rs | 17 ++++++--- src/parser/footnote_definition.rs | 19 +++++++--- src/parser/plain_list.rs | 14 ++++--- src/parser/table.rs | 17 ++++++--- 6 files changed, 108 insertions(+), 39 deletions(-) diff --git a/src/parser/diary_sexp.rs b/src/parser/diary_sexp.rs index 5f11a67a..eb118178 100644 --- a/src/parser/diary_sexp.rs +++ b/src/parser/diary_sexp.rs @@ -50,12 +50,19 @@ where )) } -#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_diary_sexp<'b, 'g, 'r, 's>( +#[cfg_attr( + feature = "tracing", + tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords)) +)] +pub(crate) fn detect_diary_sexp<'b, 'g, 'r, 's, AK>( + affiliated_keywords: AK, + remaining: OrgSource<'s>, context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, ()> { - let (input, _) = many0(parser_with_context!(affiliated_keyword)(context))(input)?; - tuple((start_of_line, tag("%%(")))(input)?; +) -> Res, ()> +where + AK: IntoIterator>, +{ + tuple((start_of_line, tag("%%(")))(remaining)?; Ok((input, ())) } diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index ac4403c8..c5c87a1d 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -273,23 +273,60 @@ fn _detect_element<'b, 'g, 'r, 's>( input: OrgSource<'s>, can_be_paragraph: bool, ) -> Res, ()> { - // TODO: unify parsing of affiliated keywords like we did for the element parser. - if alt(( - parser_with_context!(detect_plain_list)(context), - parser_with_context!(detect_footnote_definition)(context), - parser_with_context!(detect_diary_sexp)(context), - detect_comment, - parser_with_context!(detect_fixed_width_area)(context), - parser_with_context!(detect_table)(context), - ))(input) - .is_ok() - { + let (post_affiliated_keywords_input, affiliated_keywords) = + many0(parser_with_context!(affiliated_keyword)(context))(input)?; + + let mut affiliated_keywords = affiliated_keywords.into_iter(); + + ak_element!( + detect_plain_list, + &mut affiliated_keywords, + post_affiliated_keywords_input, + context, + input + ); + + ak_element!( + detect_footnote_definition, + &mut affiliated_keywords, + post_affiliated_keywords_input, + context, + input + ); + + ak_element!( + detect_diary_sexp, + &mut affiliated_keywords, + post_affiliated_keywords_input, + context, + input + ); + + if let Ok((_, _)) = detect_comment(input) { return Ok((input, ())); } + + ak_element!( + detect_fixed_width_area, + &mut affiliated_keywords, + post_affiliated_keywords_input, + context, + input + ); + + ak_element!( + detect_table, + &mut affiliated_keywords, + post_affiliated_keywords_input, + context, + input + ); + if _element(context, input, can_be_paragraph).is_ok() { return Ok((input, ())); } - return Err(nom::Err::Error(CustomError::MyError(MyError( + + Err(nom::Err::Error(CustomError::MyError(MyError( "No element detected.".into(), - )))); + )))) } diff --git a/src/parser/fixed_width_area.rs b/src/parser/fixed_width_area.rs index f3efb222..2afae7d3 100644 --- a/src/parser/fixed_width_area.rs +++ b/src/parser/fixed_width_area.rs @@ -89,17 +89,24 @@ fn fixed_width_area_line<'b, 'g, 'r, 's>( Ok((remaining, value)) } -#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_fixed_width_area<'b, 'g, 'r, 's>( +#[cfg_attr( + feature = "tracing", + tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords)) +)] +pub(crate) fn detect_fixed_width_area<'b, 'g, 'r, 's, AK>( + affiliated_keywords: AK, + remaining: OrgSource<'s>, context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, ()> { - let (input, _) = many0(parser_with_context!(affiliated_keyword)(context))(input)?; +) -> Res, ()> +where + AK: IntoIterator>, +{ tuple(( start_of_line, space0, tag(":"), alt((tag(" "), org_line_ending)), - ))(input)?; + ))(remaining)?; Ok((input, ())) } diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index 2f2cb1a7..ea1f3c02 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -125,7 +125,7 @@ fn footnote_definition_end<'b, 'g, 'r, 's>( let (remaining, source) = alt(( recognize(tuple(( parser_with_context!(maybe_consume_trailing_whitespace)(context), - parser_with_context!(detect_footnote_definition)(context), + |i| detect_footnote_definition(std::iter::empty(), i, context, i), ))), recognize(tuple(( start_of_line, @@ -138,13 +138,20 @@ fn footnote_definition_end<'b, 'g, 'r, 's>( Ok((remaining, source)) } -#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_footnote_definition<'b, 'g, 'r, 's>( +#[cfg_attr( + feature = "tracing", + tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords)) +)] +pub(crate) fn detect_footnote_definition<'b, 'g, 'r, 's, AK>( + affiliated_keywords: AK, + remaining: OrgSource<'s>, context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, ()> { - let (input, _) = many0(parser_with_context!(affiliated_keyword)(context))(input)?; - tuple((start_of_line, tag_no_case("[fn:"), label, tag("]")))(input)?; +) -> Res, ()> +where + AK: IntoIterator>, +{ + tuple((start_of_line, tag_no_case("[fn:"), label, tag("]")))(remaining)?; Ok((input, ())) } diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index ef70911a..f8d5ec82 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -53,13 +53,17 @@ use crate::types::PlainListType; #[cfg_attr( feature = "tracing", - tracing::instrument(ret, level = "debug", skip(context)) + tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords)) )] -pub(crate) fn detect_plain_list<'b, 'g, 'r, 's>( +pub(crate) fn detect_plain_list<'b, 'g, 'r, 's, AK>( + affiliated_keywords: AK, + remaining: OrgSource<'s>, context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, ()> { - let (input, _) = many0(parser_with_context!(affiliated_keyword)(context))(input)?; +) -> Res, ()> +where + AK: IntoIterator>, +{ if verify( tuple(( start_of_line, @@ -70,7 +74,7 @@ pub(crate) fn detect_plain_list<'b, 'g, 'r, 's>( |(_start, (indent_level, _), (_bullet_type, bull), _after_whitespace)| { !Into::<&str>::into(bull).starts_with("*") || *indent_level > 0 }, - )(input) + )(remaining) .is_ok() { return Ok((input, ())); diff --git a/src/parser/table.rs b/src/parser/table.rs index 88387564..934a30cf 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -92,13 +92,20 @@ where )) } -#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_table<'b, 'g, 'r, 's>( +#[cfg_attr( + feature = "tracing", + tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords)) +)] +pub(crate) fn detect_table<'b, 'g, 'r, 's, AK>( + affiliated_keywords: AK, + remaining: OrgSource<'s>, context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, ()> { - let (input, _) = many0(parser_with_context!(affiliated_keyword)(context))(input)?; - tuple((start_of_line, space0, tag("|")))(input)?; +) -> Res, ()> +where + AK: IntoIterator>, +{ + tuple((start_of_line, space0, tag("|")))(remaining)?; Ok((input, ())) }