|
|
|
|
@@ -37,9 +37,13 @@ pub fn detect_plain_list<'r, 's>(
|
|
|
|
|
_context: Context<'r, 's>,
|
|
|
|
|
input: OrgSource<'s>,
|
|
|
|
|
) -> Res<OrgSource<'s>, ()> {
|
|
|
|
|
// 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
|
|
|
|
|
},
|
|
|
|
|
@@ -135,8 +139,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<'_>, OrgSource<'_>> =
|
|
|
|
|
alt((eof, line_ending))(remaining);
|
|
|
|
|
let maybe_contentless_item: Res<OrgSource<'_>, OrgSource<'_>> = eof(remaining);
|
|
|
|
|
match maybe_contentless_item {
|
|
|
|
|
Ok((rem, _ws)) => {
|
|
|
|
|
let source = get_consumed(input, rem);
|
|
|
|
|
@@ -153,7 +156,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 +165,9 @@ pub fn plain_list_item<'r, 's>(
|
|
|
|
|
exit_matcher: &exit_matcher,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
let (remaining, (children, _exit_contents)) = verify(
|
|
|
|
|
many_till(
|
|
|
|
|
let (remaining, (children, _exit_contents)) = 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 (remaining, _trailing_ws) =
|
|
|
|
|
@@ -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());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|