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"))]