From 6e2fc362ea3bdff01805d7082b324087398f1c83 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 6 Sep 2023 18:04:53 -0400 Subject: [PATCH] Add support for babel-call keywords. --- .../lesser_element/keyword/babel_call.org | 1 + src/compare/diff.rs | 47 +++++++++++++++++++ src/parser/element_parser.rs | 3 ++ src/parser/keyword.rs | 13 +++++ src/parser/token.rs | 1 + src/types/element.rs | 3 ++ 6 files changed, 68 insertions(+) create mode 100644 org_mode_samples/lesser_element/keyword/babel_call.org diff --git a/org_mode_samples/lesser_element/keyword/babel_call.org b/org_mode_samples/lesser_element/keyword/babel_call.org new file mode 100644 index 0000000..281b00c --- /dev/null +++ b/org_mode_samples/lesser_element/keyword/babel_call.org @@ -0,0 +1 @@ +#+call: foo(bar="baz") diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 4b24dc4..26946b8 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -306,6 +306,7 @@ fn compare_element<'s>( Element::FixedWidthArea(obj) => compare_fixed_width_area(source, emacs, obj), Element::HorizontalRule(obj) => compare_horizontal_rule(source, emacs, obj), Element::Keyword(obj) => compare_keyword(source, emacs, obj), + Element::BabelCall(obj) => compare_babel_call(source, emacs, obj), Element::LatexEnvironment(obj) => compare_latex_environment(source, emacs, obj), }; match compare_result { @@ -1447,6 +1448,52 @@ fn compare_keyword<'s>( .into()) } +fn compare_babel_call<'s>( + source: &'s str, + emacs: &'s Token<'s>, + rust: &'s Keyword<'s>, +) -> Result, Box> { + let child_status = Vec::new(); + let mut this_status = DiffStatus::Good; + let mut message = None; + let emacs_name = "babel-call"; + if assert_name(emacs, emacs_name).is_err() { + this_status = DiffStatus::Bad; + } + + match assert_bounds(source, emacs, rust) { + Err(err) => { + this_status = DiffStatus::Bad; + message = Some(err.to_string()) + } + Ok(_) => {} + }; + + // TODO: compare :call :inside-header :arguments :end-header + let value = unquote( + get_property(emacs, ":value")? + .ok_or("Emacs keywords should have a :value")? + .as_atom()?, + )?; + if value != rust.value { + this_status = DiffStatus::Bad; + message = Some(format!( + "Mismatchs keyword values (emacs != rust) {:?} != {:?}", + value, rust.value + )) + } + + Ok(DiffResult { + status: this_status, + name: emacs_name.to_owned(), + message, + children: child_status, + rust_source: rust.get_source(), + emacs_token: emacs, + } + .into()) +} + fn compare_latex_environment<'s>( source: &'s str, emacs: &'s Token<'s>, diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index fe20fa1..9dabf33 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -12,6 +12,7 @@ use super::footnote_definition::footnote_definition; use super::greater_block::greater_block; use super::horizontal_rule::horizontal_rule; use super::keyword::affiliated_keyword; +use super::keyword::babel_call_keyword; use super::keyword::keyword; use super::latex_environment::latex_environment; use super::lesser_block::comment_block; @@ -67,6 +68,7 @@ fn _element<'b, 'g, 'r, 's>( let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context); let keyword_matcher = parser_with_context!(keyword)(context); let affiliated_keyword_matcher = parser_with_context!(affiliated_keyword)(context); + let babel_keyword_matcher = parser_with_context!(babel_call_keyword)(context); let paragraph_matcher = parser_with_context!(paragraph)(context); let latex_environment_matcher = parser_with_context!(latex_environment)(context); @@ -90,6 +92,7 @@ fn _element<'b, 'g, 'r, 's>( map(fixed_width_area_matcher, Element::FixedWidthArea), map(horizontal_rule_matcher, Element::HorizontalRule), map(latex_environment_matcher, Element::LatexEnvironment), + map(babel_keyword_matcher, Element::BabelCall), map(keyword_matcher, Element::Keyword), ))(remaining) { diff --git a/src/parser/keyword.rs b/src/parser/keyword.rs index 466633c..200670a 100644 --- a/src/parser/keyword.rs +++ b/src/parser/keyword.rs @@ -98,6 +98,19 @@ pub fn affiliated_keyword<'b, 'g, 'r, 's>( filtered_keyword(affiliated_key)(input) } +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +pub fn babel_call_keyword<'b, 'g, 'r, 's>( + _context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, Keyword<'s>> { + filtered_keyword(babel_call_key)(input) +} + +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +fn babel_call_key<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { + tag_no_case("call")(input) +} + #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn regular_keyword_key<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { recognize(tuple(( diff --git a/src/parser/token.rs b/src/parser/token.rs index ea9ea8f..2649fac 100644 --- a/src/parser/token.rs +++ b/src/parser/token.rs @@ -94,6 +94,7 @@ impl<'r, 's> Token<'r, 's> { Element::FixedWidthArea(_) => Box::new(std::iter::empty()), Element::HorizontalRule(_) => Box::new(std::iter::empty()), Element::Keyword(_) => Box::new(std::iter::empty()), + Element::BabelCall(_) => Box::new(std::iter::empty()), Element::LatexEnvironment(_) => Box::new(std::iter::empty()), }, Token::PlainListItem(elem) => Box::new(elem.children.iter().map(Token::Element)), diff --git a/src/types/element.rs b/src/types/element.rs index c279657..f29dee1 100644 --- a/src/types/element.rs +++ b/src/types/element.rs @@ -44,6 +44,7 @@ pub enum Element<'s> { FixedWidthArea(FixedWidthArea<'s>), HorizontalRule(HorizontalRule<'s>), Keyword(Keyword<'s>), + BabelCall(Keyword<'s>), LatexEnvironment(LatexEnvironment<'s>), } @@ -70,6 +71,7 @@ impl<'s> Source<'s> for Element<'s> { Element::FixedWidthArea(obj) => obj.source, Element::HorizontalRule(obj) => obj.source, Element::Keyword(obj) => obj.source, + Element::BabelCall(obj) => obj.source, Element::LatexEnvironment(obj) => obj.source, } } @@ -99,6 +101,7 @@ impl<'s> SetSource<'s> for Element<'s> { Element::FixedWidthArea(obj) => obj.source = source, Element::HorizontalRule(obj) => obj.source = source, Element::Keyword(obj) => obj.source = source, + Element::BabelCall(obj) => obj.source = source, Element::LatexEnvironment(obj) => obj.source = source, } }