From 80f7098f9b42f8ea6c2d1f5bf649d0cc5eee673f Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 8 Sep 2023 23:05:04 -0400 Subject: [PATCH] Compare table formulas. --- src/compare/diff.rs | 41 +++++++++++++++++++++++++++++++++--- src/parser/table.rs | 3 ++- src/types/greater_element.rs | 2 ++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 7e59baf..c7289d1 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeSet; use std::collections::HashSet; use super::util::assert_bounds; @@ -491,7 +492,7 @@ fn compare_heading<'s>( if rust.stars.to_string() != level { this_status = DiffStatus::Bad; message = Some(format!( - "Headline level do not much (emacs != rust): {} != {}", + "Headline level do not match (emacs != rust): {} != {}", level, rust.stars )) } @@ -1075,9 +1076,43 @@ fn compare_table<'s>( Ok(_) => {} }; - // TODO: Compare :type :tblfm :value + // Compare formulas // - // :tblfm is a list () filled with quoted strings containing the value for any tblfm keywords at the end of the table. + // :tblfm is either nil or a list () filled with quoted strings containing the value for any tblfm keywords at the end of the table. + let emacs_formulas = get_property(emacs, ":tblfm")?; + if let Some(emacs_formulas) = emacs_formulas { + let emacs_formulas = emacs_formulas.as_list()?; + if emacs_formulas.len() != rust.formulas.len() { + this_status = DiffStatus::Bad; + message = Some(format!( + "Formulas do not match (emacs != rust): {:?} != {:?}", + emacs_formulas, rust.formulas + )) + } else { + let atoms = emacs_formulas + .into_iter() + .map(Token::as_atom) + .collect::, _>>()?; + let unquoted = atoms + .into_iter() + .map(unquote) + .collect::, _>>()?; + for kw in &rust.formulas { + if !unquoted.contains(kw.value) { + this_status = DiffStatus::Bad; + message = Some(format!("Could not find formula in emacs: {}", kw.value)) + } + } + } + } else { + if !rust.formulas.is_empty() { + this_status = DiffStatus::Bad; + message = Some(format!( + "Formulas do not match (emacs != rust): {:?} != {:?}", + emacs_formulas, rust.formulas + )) + } + } for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_table_row(source, emacs_child, rust_child)?); diff --git a/src/parser/table.rs b/src/parser/table.rs index 69c829e..e5fd7ea 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -58,7 +58,7 @@ pub fn org_mode_table<'b, 'g, 'r, 's>( let (remaining, (children, _exit_contents)) = many_till(org_mode_table_row_matcher, exit_matcher)(input)?; - let (remaining, _formulas) = + let (remaining, formulas) = many0(parser_with_context!(table_formula_keyword)(context))(remaining)?; // TODO: Consume trailing formulas @@ -68,6 +68,7 @@ pub fn org_mode_table<'b, 'g, 'r, 's>( remaining, Table { source: source.into(), + formulas, children, }, )) diff --git a/src/types/greater_element.rs b/src/types/greater_element.rs index 9a12900..e897945 100644 --- a/src/types/greater_element.rs +++ b/src/types/greater_element.rs @@ -1,5 +1,6 @@ use super::element::Element; use super::lesser_element::TableCell; +use super::Keyword; use super::Object; use super::Source; @@ -63,6 +64,7 @@ pub struct NodeProperty<'s> { #[derive(Debug)] pub struct Table<'s> { pub source: &'s str, + pub formulas: Vec>, pub children: Vec>, }