diff --git a/org_mode_samples/lesser_element/comment/indented.org b/org_mode_samples/lesser_element/comment/indented.org index b98916d..ed61a36 100644 --- a/org_mode_samples/lesser_element/comment/indented.org +++ b/org_mode_samples/lesser_element/comment/indented.org @@ -1,4 +1,5 @@ # Comment +# # indented line # At the top of the file diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 8d99fd8..3cc9671 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -1208,9 +1208,20 @@ fn compare_comment<'b, 's>( rust: &'b Comment<'s>, ) -> Result, Box> { let child_status = Vec::new(); - let this_status = DiffStatus::Good; - let message = None; - // TODO: Compare :value + let mut this_status = DiffStatus::Good; + let mut message = None; + + // Compare value + let value = + get_property_quoted_string(emacs, ":value")?.ok_or("Comments should have a value.")?; + let rust_value = rust.get_value(); + if value != rust_value { + this_status = DiffStatus::Bad; + message = Some(format!( + "Value mismatch (emacs != rust) {:?} != {:?}", + value, rust_value + )); + } Ok(DiffResult { status: this_status, diff --git a/src/parser/comment.rs b/src/parser/comment.rs index c2f761d..a6ded5d 100644 --- a/src/parser/comment.rs +++ b/src/parser/comment.rs @@ -1,18 +1,19 @@ use nom::branch::alt; -use nom::bytes::complete::is_not; use nom::bytes::complete::tag; +use nom::character::complete::anychar; use nom::character::complete::line_ending; use nom::character::complete::space0; -use nom::character::complete::space1; use nom::combinator::eof; use nom::combinator::not; -use nom::combinator::opt; +use nom::combinator::recognize; use nom::multi::many0; +use nom::multi::many_till; use nom::sequence::preceded; use nom::sequence::tuple; use super::org_source::OrgSource; use super::util::get_consumed; +use super::util::org_line_ending; use crate::context::parser_with_context; use crate::context::ContextElement; use crate::context::RefContext; @@ -38,15 +39,29 @@ pub(crate) fn comment<'b, 'g, 'r, 's>( let parser_context = context.with_additional_node(&parser_context); let comment_line_matcher = parser_with_context!(comment_line)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); - let (remaining, _first_line) = comment_line_matcher(input)?; - let (remaining, _remaining_lines) = + let (remaining, first_line) = comment_line_matcher(input)?; + let (remaining, mut remaining_lines) = many0(preceded(not(exit_matcher), comment_line_matcher))(remaining)?; let source = get_consumed(input, remaining); + let mut value = Vec::with_capacity(remaining_lines.len() + 1); + let last_line = remaining_lines.pop(); + if let Some(last_line) = last_line { + value.push(Into::<&str>::into(first_line)); + value.extend(remaining_lines.into_iter().map(Into::<&str>::into)); + let last_line = Into::<&str>::into(last_line); + // Trim the line ending from the final line. + value.push(&last_line[..(last_line.len() - 1)]) + } else { + // Trim the line ending from the only line. + let only_line = Into::<&str>::into(first_line); + value.push(&only_line[..(only_line.len() - 1)]) + } Ok(( remaining, Comment { source: source.into(), + value, }, )) } @@ -57,14 +72,13 @@ fn comment_line<'b, 'g, 'r, 's>( input: OrgSource<'s>, ) -> Res, OrgSource<'s>> { start_of_line(input)?; - let (remaining, _indent) = space0(input)?; - let (remaining, (_hash, _leading_whitespace_and_content, _line_ending)) = tuple(( - tag("#"), - opt(tuple((space1, is_not("\r\n")))), - alt((line_ending, eof)), - ))(remaining)?; - let source = get_consumed(input, remaining); - Ok((remaining, source)) + let (remaining, _) = tuple((space0, tag("#")))(input)?; + if let Ok((remaining, line_break)) = org_line_ending(remaining) { + return Ok((remaining, line_break)); + } + let (remaining, _) = tag(" ")(remaining)?; + let (remaining, value) = recognize(many_till(anychar, org_line_ending))(remaining)?; + Ok((remaining, value)) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] diff --git a/src/types/lesser_element.rs b/src/types/lesser_element.rs index e0e9762..77964cf 100644 --- a/src/types/lesser_element.rs +++ b/src/types/lesser_element.rs @@ -12,6 +12,7 @@ pub struct Paragraph<'s> { #[derive(Debug)] pub struct Comment<'s> { pub source: &'s str, + pub value: Vec<&'s str>, } #[derive(Debug)] @@ -209,3 +210,16 @@ impl<'s> StandardProperties<'s> for LatexEnvironment<'s> { self.source } } + +impl<'s> Comment<'s> { + pub fn get_value(&self) -> String { + // TODO: maybe we should handle parsing here instead of storing the parsing result in the AST since I imagine getting the value of comments won't be a common operation. + let final_size = self.value.iter().map(|line| line.len()).sum(); + let mut ret = String::with_capacity(final_size); + for line in &self.value { + ret.push_str(line); + } + + ret + } +}