From 05c9ec86b8964fb9b1eed79792a19fdd5cdfbb2f Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 12 Apr 2023 14:07:33 -0400 Subject: [PATCH] Compare plain list items inside plain lists. --- src/compare/diff.rs | 50 ++++++++++++++++++++++++++++++++++++++++++- src/parser/element.rs | 7 ++++++ src/parser/mod.rs | 1 + 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index bf4fd59..5197ba5 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -8,6 +8,7 @@ use crate::parser::GreaterBlock; use crate::parser::Heading; use crate::parser::Paragraph; use crate::parser::PlainList; +use crate::parser::PlainListItem; use crate::parser::Section; #[derive(Debug)] @@ -288,7 +289,9 @@ fn compare_plain_list<'s>( this_status = DiffStatus::Bad; } - for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) {} + for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { + child_status.push(compare_plain_list_item(source, emacs_child, rust_child)?); + } Ok(DiffResult { status: this_status, @@ -297,6 +300,51 @@ fn compare_plain_list<'s>( }) } +fn compare_plain_list_item<'s>( + source: &'s str, + emacs: &'s Token<'s>, + rust: &'s PlainListItem<'s>, +) -> Result> { + let children = emacs.as_list()?; + let first_child = children + .first() + .ok_or("Should have at least one child.")? + .as_atom()?; + if first_child != "item" { + return Err("PlainListItem should correspond to an item cell.".into()); + } + let mut child_status = Vec::new(); + let mut this_status = DiffStatus::Good; + + let attributes_child = children + .iter() + .nth(1) + .ok_or("Should have an attributes child.")?; + let attributes_map = attributes_child.as_map()?; + let begin = attributes_map + .get(":begin") + .ok_or("Missing :begin attribute.")? + .as_atom()?; + let end = attributes_map + .get(":end") + .ok_or("Missing :end attribute.")? + .as_atom()?; + let (rust_begin, rust_end) = get_offsets(source, rust); + if (rust_begin + 1).to_string() != begin || (rust_end + 1).to_string() != end { + this_status = DiffStatus::Bad; + } + + for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { + child_status.push(compare_element(source, emacs_child, rust_child)?); + } + + Ok(DiffResult { + status: this_status, + name: "plain-list-item".to_owned(), + children: child_status, + }) +} + fn compare_greater_block<'s>( source: &'s str, emacs: &'s Token<'s>, diff --git a/src/parser/element.rs b/src/parser/element.rs index a6f009d..9d2778b 100644 --- a/src/parser/element.rs +++ b/src/parser/element.rs @@ -1,3 +1,4 @@ +use super::PlainListItem; use super::error::Res; use super::footnote_definition::footnote_definition; use super::greater_block::greater_block; @@ -44,6 +45,12 @@ impl<'s> Source<'s> for PlainList<'s> { } } +impl<'s> Source<'s> for PlainListItem<'s> { + fn get_source(&'s self) -> &'s str { + self.source + } +} + impl<'s> Source<'s> for GreaterBlock<'s> { fn get_source(&'s self) -> &'s str { self.source diff --git a/src/parser/mod.rs b/src/parser/mod.rs index d4fd960..169d5ea 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -23,6 +23,7 @@ pub use element::Element; pub use greater_element::FootnoteDefinition; pub use greater_element::GreaterBlock; pub use greater_element::PlainList; +pub use greater_element::PlainListItem; pub use lesser_element::Paragraph; pub use source::Source; type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;