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.
This commit is contained in:
Tom Alexander 2023-08-15 02:02:15 -04:00
parent 72d5f8f35c
commit 7df393f31d
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
1 changed files with 29 additions and 42 deletions

View File

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