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: | | Baz | | B | :thisisatag: |
| Lorem | | B | :thisshouldinheritfromabove: | | Lorem | | B | :thisshouldinheritfromabove: |
| Ipsum | | B | | | Ipsum | | B | :multiple:tags: |
#+END: #+END:
* Foo * Foo
* TODO Bar * TODO Bar
* Baz :thisisatag: * Baz :thisisatag:
** Lorem :thisshouldinheritfromabove: ** 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)?); 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()) { for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) {
match rust_child { match rust_child {
DocumentElement::Heading(rust_heading) => { DocumentElement::Heading(rust_heading) => {

View File

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