Add support for parsing tags in headlines.

This commit is contained in:
Tom Alexander 2023-08-25 06:13:29 -04:00
parent d5ea650b96
commit 2d4e54845b
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 32 additions and 6 deletions

View File

@ -14,10 +14,12 @@
|-------+------+----------+------------------------------|
| Baz | | B | :thisisatag: |
| Lorem | | B | :thisshouldinheritfromabove: |
| Ipsum | | B | |
| Ipsum | | B | :multiple:tags: |
#+END:
* Foo
* TODO Bar
* Baz :thisisatag:
** Lorem :thisshouldinheritfromabove:
*** Ipsum
*** Ipsum :multiple:tags:
* Dolar ::
* cat :dog: bat

View File

@ -348,6 +348,8 @@ fn compare_heading<'s>(
child_status.push(compare_object(source, emacs_child, rust_child)?);
}
// TODO: Compare tags, todo-keyword, level, priority
for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) {
match rust_child {
DocumentElement::Heading(rust_heading) => {

View File

@ -1,6 +1,8 @@
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::anychar;
use nom::character::complete::line_ending;
use nom::character::complete::space0;
use nom::character::complete::space1;
use nom::combinator::eof;
use nom::combinator::map;
@ -12,6 +14,7 @@ use nom::multi::many0;
use nom::multi::many1;
use nom::multi::many1_count;
use nom::multi::many_till;
use nom::multi::separated_list1;
use nom::sequence::tuple;
use super::element::Element;
@ -297,26 +300,45 @@ fn headline<'r, 's>(
let parser_context =
context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode {
class: ExitClass::Document,
exit_matcher: &headline_end,
exit_matcher: &headline_title_end,
}));
let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context);
let (remaining, (_sol, star_count, ws, title, _line_ending)) = tuple((
let (remaining, (_sol, star_count, ws, title, maybe_tags, _ws, _line_ending)) = tuple((
start_of_line,
many1_count(tag("*")),
space1,
many1(standard_set_object_matcher),
opt(tuple((space0, tags))),
space0,
alt((line_ending, eof)),
))(input)?;
Ok((remaining, (star_count, ws, title)))
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn headline_end<'r, 's>(
fn headline_title_end<'r, 's>(
_context: Context<'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
line_ending(input)
recognize(tuple((
opt(tuple((space0, tags, space0))),
alt((line_ending, eof)),
)))(input)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn tags<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Vec<OrgSource<'s>>> {
let (remaining, (_open, tags, _close)) =
tuple((tag(":"), separated_list1(tag(":"), single_tag), tag(":")))(input)?;
Ok((remaining, tags))
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn single_tag<'r, 's>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
recognize(many1(verify(anychar, |c| {
c.is_alphanumeric() || "_@#%".contains(*c)
})))(input)
}
impl<'s> Document<'s> {