diff --git a/src/compare/diff.rs b/src/compare/diff.rs index dd444021..42a3d9b6 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -86,6 +86,7 @@ use crate::types::Superscript; use crate::types::Table; use crate::types::TableCell; use crate::types::TableRow; +use crate::types::TableRowType; use crate::types::Target; use crate::types::Time; use crate::types::TimeUnit; @@ -1388,7 +1389,23 @@ fn compare_table<'b, 's>( } } - // TODO: Compare :type :value + // Compare type + let table_type = get_property_unquoted_atom(emacs, ":type")?.expect("Table should have a type"); + if table_type != "org" { + this_status = DiffStatus::Bad; + message = Some(format!( + "Table type mismatch (emacs != rust) {:?} != {:?}", + table_type, "org" + )); + } + + // Compare value + let value = get_property(emacs, ":value")?; + if value.is_some() { + // I don't know what :value is for, but it seems to always be nil. This is here to alert me to value being non-nil so I can investigate. + this_status = DiffStatus::Bad; + message = Some(format!("Non-nil value {:?}", value)) + } for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); @@ -1412,12 +1429,23 @@ fn compare_table_row<'b, 's>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let this_status = DiffStatus::Good; - let message = None; + let mut this_status = DiffStatus::Good; + let mut message = None; - // TODO: Compare :type - // - // :type is an unquoted atom of either standard or rule + // Compare type + let row_type = get_property_unquoted_atom(emacs, ":type")?; + let rust_row_type = rust.get_type(); + match (row_type, &rust_row_type) { + (Some("standard"), TableRowType::Standard) => {} + (Some("rule"), TableRowType::Rule) => {} + _ => { + this_status = DiffStatus::Bad; + message = Some(format!( + "Type mismatch (emacs != rust) {:?} != {:?}", + row_type, rust_row_type + )); + } + } for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); diff --git a/src/parser/table.rs b/src/parser/table.rs index e9ad98f8..1d27ed6d 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -3,8 +3,8 @@ use nom::bytes::complete::is_not; use nom::bytes::complete::tag; use nom::character::complete::line_ending; use nom::character::complete::space0; -use nom::combinator::eof; use nom::combinator::not; +use nom::combinator::opt; use nom::combinator::peek; use nom::combinator::recognize; use nom::combinator::verify; @@ -17,6 +17,7 @@ use super::keyword::table_formula_keyword; use super::object_parser::table_cell_set_object; use super::org_source::OrgSource; use super::util::exit_matcher_parser; +use super::util::org_line_ending; use crate::context::parser_with_context; use crate::context::ContextElement; use crate::context::ExitClass; @@ -105,7 +106,7 @@ fn org_mode_table_row_rule<'b, 'g, 'r, 's>( input: OrgSource<'s>, ) -> Res, TableRow<'s>> { start_of_line(input)?; - let (remaining, _) = tuple((space0, tag("|-"), is_not("\r\n"), line_ending))(input)?; + let (remaining, _) = tuple((space0, tag("|-"), opt(is_not("\r\n")), org_line_ending))(input)?; let source = get_consumed(input, remaining); Ok(( remaining, @@ -125,7 +126,7 @@ fn org_mode_table_row_regular<'b, 'g, 'r, 's>( let (remaining, _) = tuple((space0, tag("|")))(input)?; let (remaining, children) = many1(parser_with_context!(org_mode_table_cell)(context))(remaining)?; - let (remaining, _tail) = recognize(tuple((space0, alt((line_ending, eof)))))(remaining)?; + let (remaining, _tail) = recognize(tuple((space0, org_line_ending)))(remaining)?; let source = get_consumed(input, remaining); Ok(( remaining, diff --git a/src/types/greater_element.rs b/src/types/greater_element.rs index bbf88f70..17d7cd2e 100644 --- a/src/types/greater_element.rs +++ b/src/types/greater_element.rs @@ -111,6 +111,12 @@ pub struct TableRow<'s> { pub children: Vec>, } +#[derive(Debug)] +pub enum TableRowType { + Standard, + Rule, +} + impl<'s> StandardProperties<'s> for PlainList<'s> { fn get_source<'b>(&'b self) -> &'s str { self.source @@ -194,3 +200,13 @@ impl<'s> PlainListItem<'s> { .map(|(checkbox_type, _)| checkbox_type) } } + +impl<'s> TableRow<'s> { + pub fn get_type(&self) -> TableRowType { + if self.children.is_empty() { + TableRowType::Rule + } else { + TableRowType::Standard + } + } +} diff --git a/src/types/mod.rs b/src/types/mod.rs index d95adcbd..d0b9b977 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -35,6 +35,7 @@ pub use greater_element::QuoteBlock; pub use greater_element::SpecialBlock; pub use greater_element::Table; pub use greater_element::TableRow; +pub use greater_element::TableRowType; pub use lesser_element::BabelCall; pub use lesser_element::Clock; pub use lesser_element::Comment;