diff --git a/org_mode_samples/greater_element/plain_list/mixed_types.org b/org_mode_samples/greater_element/plain_list/mixed_types.org new file mode 100644 index 00000000..5143152d --- /dev/null +++ b/org_mode_samples/greater_element/plain_list/mixed_types.org @@ -0,0 +1,3 @@ +1. foo +- bar +- lorem :: ipsum diff --git a/org_mode_samples/greater_element/plain_list/ordered_list_with_fake_tag.org b/org_mode_samples/greater_element/plain_list/ordered_list_with_fake_tag.org new file mode 100644 index 00000000..00035139 --- /dev/null +++ b/org_mode_samples/greater_element/plain_list/ordered_list_with_fake_tag.org @@ -0,0 +1,2 @@ +# Since this is an ordered list, the text before the " :: " is NOT parsed as a tag. +1. foo :: bar diff --git a/src/compare/diff.rs b/src/compare/diff.rs index c1416036..ac5b4eed 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -732,6 +732,10 @@ fn compare_plain_list<'s>( Ok(_) => {} }; + // TODO compare :type + // + // :type is an unquoted atom of either descriptive, ordered, or unordered + for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_plain_list_item(source, emacs_child, rust_child)?); } diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 3fbf6434..3f73f4c5 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -57,7 +57,7 @@ pub(crate) fn detect_plain_list<'b, 'g, 'r, 's>( parser_with_context!(bullet)(context), alt((space1, line_ending, eof)), )), - |(_start, indent, bull, _after_whitespace)| { + |(_start, indent, (_bullet_type, bull), _after_whitespace)| { Into::<&str>::into(bull) != "*" || indent.len() > 0 }, )(input) @@ -151,9 +151,9 @@ fn plain_list_item<'b, 'g, 'r, 's>( ) -> Res, PlainListItem<'s>> { start_of_line(input)?; let (remaining, (indent_level, _leading_whitespace)) = indentation_level(context, input)?; - let (remaining, bull) = verify( + let (remaining, (bullet_type, bull)) = verify( parser_with_context!(bullet)(context), - |bull: &OrgSource<'_>| Into::<&str>::into(bull) != "*" || indent_level > 0, + |(_bullet_type, bull)| Into::<&str>::into(bull) != "*" || indent_level > 0, )(remaining)?; let (remaining, _maybe_counter_set) = opt(tuple(( @@ -165,8 +165,11 @@ fn plain_list_item<'b, 'g, 'r, 's>( let (remaining, maybe_checkbox) = opt(tuple((space1, item_checkbox)))(remaining)?; - let (remaining, maybe_tag) = - opt(tuple((space1, parser_with_context!(item_tag)(context))))(remaining)?; + let (remaining, maybe_tag) = if let BulletType::Unordered = bullet_type { + opt(tuple((space1, parser_with_context!(item_tag)(context))))(remaining)? + } else { + (remaining, None) + }; let exit_matcher = plain_list_item_end(indent_level); let contexts = [ @@ -242,19 +245,27 @@ fn plain_list_item<'b, 'g, 'r, 's>( )); } +enum BulletType { + Ordered, + Unordered, +} + #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn bullet<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, OrgSource<'s>> { +) -> Res, (BulletType, OrgSource<'s>)> { alt(( - tag("*"), - tag("-"), - tag("+"), - recognize(tuple(( - parser_with_context!(counter)(context), - alt((tag("."), tag(")"))), - ))), + map(tag("*"), |bull| (BulletType::Unordered, bull)), + map(tag("-"), |bull| (BulletType::Unordered, bull)), + map(tag("+"), |bull| (BulletType::Unordered, bull)), + map( + recognize(tuple(( + parser_with_context!(counter)(context), + alt((tag("."), tag(")"))), + ))), + |bull| (BulletType::Ordered, bull), + ), ))(input) }