From efa372a9e92a82c13cb0aff50d10485143b1d273 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 25 Aug 2023 04:39:58 -0400 Subject: [PATCH 1/4] Add a test case that breaks the current parser. --- .../greater_element/plain_list/content_on_next_line.org | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 org_mode_samples/greater_element/plain_list/content_on_next_line.org diff --git a/org_mode_samples/greater_element/plain_list/content_on_next_line.org b/org_mode_samples/greater_element/plain_list/content_on_next_line.org new file mode 100644 index 0000000..ee3eddd --- /dev/null +++ b/org_mode_samples/greater_element/plain_list/content_on_next_line.org @@ -0,0 +1,7 @@ +1. foo +2. + bar + 1. + #+begin_center +Still in the list + #+end_center From bc5745a95fef8a615ce19b7b135ea8601105f11c Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 25 Aug 2023 05:15:49 -0400 Subject: [PATCH 2/4] Add support for list items with a line break before their contents. --- src/compare/util.rs | 4 +--- src/parser/plain_list.rs | 14 +++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/compare/util.rs b/src/compare/util.rs index 1e0cd85..25174f6 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -47,9 +47,7 @@ pub fn assert_bounds<'s, S: Source<'s>>( standard_properties .begin .ok_or("Token should have a begin.")?, - standard_properties - .end - .ok_or("Token should have a begin.")?, + standard_properties.end.ok_or("Token should have an end.")?, ); let (rust_begin, rust_end) = get_offsets(source, rust); if (rust_begin + 1) != begin || (rust_end + 1) != end { diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index d39b8f7..3c70cd6 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -135,8 +135,7 @@ pub fn plain_list_item<'r, 's>( })(remaining)?; // TODO: This isn't taking into account items that immediately line break and then have contents - let maybe_contentless_item: Res, OrgSource<'_>> = - alt((eof, line_ending))(remaining); + let maybe_contentless_item: Res, OrgSource<'_>> = eof(remaining); match maybe_contentless_item { Ok((rem, _ws)) => { let source = get_consumed(input, rem); @@ -153,7 +152,7 @@ pub fn plain_list_item<'r, 's>( Err(_) => {} }; - let (remaining, _ws) = space1(remaining)?; + let (remaining, _ws) = alt((space1, line_ending))(remaining)?; let exit_matcher = plain_list_item_end(indent_level); let parser_context = context .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) @@ -162,12 +161,9 @@ pub fn plain_list_item<'r, 's>( exit_matcher: &exit_matcher, })); - let (remaining, (children, _exit_contents)) = verify( - many_till( - parser_with_context!(element(true))(&parser_context), - parser_with_context!(exit_matcher_parser)(&parser_context), - ), - |(children, _exit_contents)| !children.is_empty(), + let (remaining, (children, _exit_contents)) = many_till( + parser_with_context!(element(true))(&parser_context), + parser_with_context!(exit_matcher_parser)(&parser_context), )(remaining)?; let (remaining, _trailing_ws) = From bfea828e6259a54415b1f79afc0f4738df480f83 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 25 Aug 2023 05:20:13 -0400 Subject: [PATCH 3/4] Update detect_plain_list to support line breaks. --- src/parser/plain_list.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 3c70cd6..8d8ba36 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -37,9 +37,13 @@ pub fn detect_plain_list<'r, 's>( _context: Context<'r, 's>, input: OrgSource<'s>, ) -> Res, ()> { - // TODO: Add support for plain list items that do not have content on the first line. if verify( - tuple((start_of_line, space0, bullet, space1)), + tuple(( + start_of_line, + space0, + bullet, + alt((space1, line_ending, eof)), + )), |(_start, indent, bull, _after_whitespace)| { Into::<&str>::into(bull) != "*" || indent.len() > 0 }, From 1b678fe81f81ad76b199a3ed1451c178ff0ee47e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 25 Aug 2023 05:25:41 -0400 Subject: [PATCH 4/4] Add tests for detect_plain_list. --- src/parser/plain_list.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 8d8ba36..41c64f4 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -419,4 +419,40 @@ dolar"#, "# ); } + + #[test] + fn detect_line_break() { + let input = OrgSource::new( + r#"+ +"#, + ); + let initial_context: ContextTree<'_, '_> = ContextTree::new(); + let result = detect_plain_list(&initial_context, input); + assert!(result.is_ok()); + } + + #[test] + fn detect_eof() { + let input = OrgSource::new(r#"+"#); + let initial_context: ContextTree<'_, '_> = ContextTree::new(); + let result = detect_plain_list(&initial_context, input); + assert!(result.is_ok()); + } + + #[test] + fn detect_no_gap() { + let input = OrgSource::new(r#"+foo"#); + let initial_context: ContextTree<'_, '_> = ContextTree::new(); + let result = detect_plain_list(&initial_context, input); + // Since there is no whitespace after the '+' this is a paragraph, not a plain list. + assert!(result.is_err()); + } + + #[test] + fn detect_with_gap() { + let input = OrgSource::new(r#"+ foo"#); + let initial_context: ContextTree<'_, '_> = ContextTree::new(); + let result = detect_plain_list(&initial_context, input); + assert!(result.is_ok()); + } }