From 7df393f31d1eb8f365317ee8110627566384a830 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Tue, 15 Aug 2023 02:02:15 -0400 Subject: [PATCH] Make a new naive implementation of plain_list_item. Still need to update plain_list_item_end and handle the whitespace ownership issues, but starting from a simplified state will help. --- src/parser/plain_list.rs | 71 ++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 62fb7e0..08b7e89 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -85,29 +85,12 @@ pub fn plain_list_item<'r, 's>( let (remaining, leading_whitespace) = space0(input)?; // It is fine that we get the indent level using the number of bytes rather than the number of characters because nom's space0 only matches space and tab (0x20 and 0x09) let indent_level = leading_whitespace.len(); - let with_consume_context = context - .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) - .with_additional_node(ContextElement::ListItem(indent_level)) - .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { - class: ExitClass::Beta, - exit_matcher: &plain_list_item_end, - })); - let without_consume_context = context - .with_additional_node(ContextElement::ListItem(indent_level)) - .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { - class: ExitClass::Beta, - exit_matcher: &plain_list_item_end, - })); - - let with_consume_matcher = parser_with_context!(element(true))(&with_consume_context); - let without_consume_matcher = parser_with_context!(element(true))(&without_consume_context); - let exit_matcher = parser_with_context!(exit_matcher_parser)(&with_consume_context); let (remaining, bull) = verify(bullet, |bull: &str| bull != "*" || indent_level > 0)(remaining)?; + let maybe_contentless_item: Res<&str, &str> = alt((eof, line_ending))(remaining); match maybe_contentless_item { Ok((rem, _ws)) => { - // TODO: do we need to consume if this isn't the last item? let source = get_consumed(input, rem); return Ok(( rem, @@ -119,31 +102,35 @@ pub fn plain_list_item<'r, 's>( }, )); } - Err(_) => { - let (remaining, _ws) = space1(remaining)?; - let (remaining, (mut contents, final_element)) = many_till( - &with_consume_matcher, - alt(( - terminated(&without_consume_matcher, exit_matcher), - preceded( - peek(tuple((&with_consume_matcher, exit_matcher))), - &without_consume_matcher, - ), - )), - )(remaining)?; - contents.push(final_element); - let source = get_consumed(input, remaining); - return Ok(( - remaining, - PlainListItem { - source, - indentation: indent_level, - bullet: bull, - children: contents, - }, - )); - } + Err(_) => {} }; + + let (remaining, _ws) = space1(remaining)?; + let parser_context = context + .with_additional_node(ContextElement::ListItem(indent_level)) + .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { + class: ExitClass::Beta, + exit_matcher: &plain_list_item_end, + })); + + 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(), + )(remaining)?; + + let source = get_consumed(input, remaining); + return Ok(( + remaining, + PlainListItem { + source, + indentation: indent_level, + bullet: bull, + children, + }, + )); } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]