diff --git a/org_mode_samples/lesser_element/lesser_block/example/affiliated_keyword_dual_value.org b/org_mode_samples/lesser_element/lesser_block/example/affiliated_keyword_dual_value.org index f6c72d4a..6982f69e 100644 --- a/org_mode_samples/lesser_element/lesser_block/example/affiliated_keyword_dual_value.org +++ b/org_mode_samples/lesser_element/lesser_block/example/affiliated_keyword_dual_value.org @@ -3,4 +3,14 @@ #+begin_example baz #+end_example + #+caption[lorem]: ipsum +#+caption[foo]: bar +#+begin_example +baz +#+end_example + +#+header[foo]: bar +#+begin_example +baz +#+end_example diff --git a/src/parser/diary_sexp.rs b/src/parser/diary_sexp.rs index 348c2e3b..5f11a67a 100644 --- a/src/parser/diary_sexp.rs +++ b/src/parser/diary_sexp.rs @@ -9,6 +9,7 @@ use super::keyword::affiliated_keyword; use super::org_source::OrgSource; use super::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::util::org_line_ending; +use crate::context::parser_with_context; use crate::context::RefContext; use crate::error::Res; use crate::parser::util::get_consumed; @@ -50,8 +51,11 @@ where } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_diary_sexp<'s>(input: OrgSource<'s>) -> Res, ()> { - let (input, _) = many0(affiliated_keyword)(input)?; +pub(crate) fn detect_diary_sexp<'b, 'g, 'r, '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)?; Ok((input, ())) } diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 48cf5431..ac4403c8 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -56,7 +56,8 @@ fn _element<'b, 'g, 'r, 's>( input: OrgSource<'s>, can_be_paragraph: bool, ) -> Res, Element<'s>> { - let (post_affiliated_keywords_input, affiliated_keywords) = many0(affiliated_keyword)(input)?; + let (post_affiliated_keywords_input, affiliated_keywords) = + many0(parser_with_context!(affiliated_keyword)(context))(input)?; let mut affiliated_keywords = affiliated_keywords.into_iter(); @@ -272,13 +273,14 @@ 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), - detect_footnote_definition, - detect_diary_sexp, + parser_with_context!(detect_footnote_definition)(context), + parser_with_context!(detect_diary_sexp)(context), detect_comment, - detect_fixed_width_area, - detect_table, + parser_with_context!(detect_fixed_width_area)(context), + parser_with_context!(detect_table)(context), ))(input) .is_ok() { diff --git a/src/parser/fixed_width_area.rs b/src/parser/fixed_width_area.rs index 2f94e908..f3efb222 100644 --- a/src/parser/fixed_width_area.rs +++ b/src/parser/fixed_width_area.rs @@ -90,8 +90,11 @@ fn fixed_width_area_line<'b, 'g, 'r, 's>( } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_fixed_width_area<'s>(input: OrgSource<'s>) -> Res, ()> { - let (input, _) = many0(affiliated_keyword)(input)?; +pub(crate) fn detect_fixed_width_area<'b, 'g, 'r, '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, diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index 611a674e..2f2cb1a7 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), - detect_footnote_definition, + parser_with_context!(detect_footnote_definition)(context), ))), recognize(tuple(( start_of_line, @@ -139,8 +139,11 @@ fn footnote_definition_end<'b, 'g, 'r, 's>( } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_footnote_definition<'s>(input: OrgSource<'s>) -> Res, ()> { - let (input, _) = many0(affiliated_keyword)(input)?; +pub(crate) fn detect_footnote_definition<'b, 'g, 'r, '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)?; Ok((input, ())) } diff --git a/src/parser/keyword.rs b/src/parser/keyword.rs index 73055956..858b59b9 100644 --- a/src/parser/keyword.rs +++ b/src/parser/keyword.rs @@ -21,6 +21,7 @@ use super::org_source::BracketDepth; use super::org_source::OrgSource; use super::util::get_consumed; use super::util::maybe_consume_trailing_whitespace_if_not_exiting; +use crate::context::parser_with_context; use crate::context::Matcher; use crate::context::RefContext; use crate::error::CustomError; @@ -30,15 +31,9 @@ use crate::parser::util::start_of_line; use crate::types::AffiliatedKeywords; use crate::types::Keyword; -const ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [ - "caption", "data", "headers", "header", "label", "name", "plot", "resname", "results", - "result", "source", "srcname", "tblname", -]; -const ORG_ELEMENT_DUAL_KEYWORDS: [&'static str; 2] = ["caption", "results"]; - -pub(crate) fn filtered_keyword( +pub(crate) fn filtered_keyword<'s, F: Fn(OrgSource<'s>) -> Res, OrgSource<'s>>>( key_parser: F, -) -> impl for<'s> Fn(OrgSource<'s>) -> Res, Keyword<'s>> { +) -> impl Fn(OrgSource<'s>) -> Res, Keyword<'s>> { move |input| _filtered_keyword(&key_parser, input) } @@ -46,7 +41,7 @@ pub(crate) fn filtered_keyword( feature = "tracing", tracing::instrument(ret, level = "debug", skip(key_parser)) )] -fn _filtered_keyword<'s, F: Matcher>( +fn _filtered_keyword<'s, F: Fn(OrgSource<'s>) -> Res, OrgSource<'s>>>( key_parser: F, input: OrgSource<'s>, ) -> Res, Keyword<'s>> { @@ -113,8 +108,11 @@ where } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn affiliated_keyword<'s>(input: OrgSource<'s>) -> Res, Keyword<'s>> { - filtered_keyword(affiliated_key)(input) +pub(crate) fn affiliated_keyword<'b, 'g, 'r, 's>( + context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, Keyword<'s>> { + filtered_keyword(parser_with_context!(affiliated_key)(context))(input) } #[cfg_attr( @@ -149,18 +147,29 @@ fn regular_keyword_key<'s>(input: OrgSource<'s>) -> Res, OrgSource } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn affiliated_key<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { +fn affiliated_key<'b, 'g, 'r, 's>( + context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, OrgSource<'s>> { alt(( - recognize(tuple((dual_affiliated_key, tag("["), optval, tag("]")))), - plain_affiliated_key, + recognize(tuple(( + parser_with_context!(dual_affiliated_key)(context), + tag("["), + optval, + tag("]"), + ))), + parser_with_context!(plain_affiliated_key)(context), export_keyword, ))(input) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn plain_affiliated_key<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { - for keyword in ORG_ELEMENT_AFFILIATED_KEYWORDS { - let result = tag_no_case::<_, _, CustomError<_>>(keyword)(input); +fn plain_affiliated_key<'b, 'g, 'r, 's>( + context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, OrgSource<'s>> { + for keyword in context.get_global_settings().element_affiliated_keywords { + let result = tag_no_case::<_, _, CustomError<_>>(*keyword)(input); match result { Ok((remaining, ent)) => { return Ok((remaining, ent)); @@ -175,9 +184,12 @@ fn plain_affiliated_key<'s>(input: OrgSource<'s>) -> Res, OrgSourc } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -fn dual_affiliated_key<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { - for keyword in ORG_ELEMENT_DUAL_KEYWORDS { - let result = tag_no_case::<_, _, CustomError<_>>(keyword)(input); +fn dual_affiliated_key<'b, 'g, 'r, 's>( + context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, OrgSource<'s>> { + for keyword in context.get_global_settings().element_dual_keywords { + let result = tag_no_case::<_, _, CustomError<_>>(*keyword)(input); match result { Ok((remaining, ent)) => { return Ok((remaining, ent)); diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index e2807bd5..ef70911a 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -59,7 +59,7 @@ pub(crate) fn detect_plain_list<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, ) -> Res, ()> { - let (input, _) = many0(affiliated_keyword)(input)?; + let (input, _) = many0(parser_with_context!(affiliated_keyword)(context))(input)?; if verify( tuple(( start_of_line, diff --git a/src/parser/table.rs b/src/parser/table.rs index b3fdd90e..88387564 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -93,8 +93,11 @@ where } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] -pub(crate) fn detect_table<'s>(input: OrgSource<'s>) -> Res, ()> { - let (input, _) = many0(affiliated_keyword)(input)?; +pub(crate) fn detect_table<'b, 'g, 'r, '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)?; Ok((input, ())) }