Parse priority cookie and COMMENT from headlines.

This commit is contained in:
Tom Alexander 2023-09-08 15:43:13 -04:00
parent b32c21eb1d
commit c7c0deed74
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 48 additions and 7 deletions

View File

@ -39,7 +39,7 @@ tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-fil
walkdir = "2.3.3" walkdir = "2.3.3"
[features] [features]
default = [] default = ["compare"]
compare = [] compare = []
tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"]

View File

@ -33,6 +33,7 @@ use crate::parser::util::blank_line;
use crate::types::DocumentElement; use crate::types::DocumentElement;
use crate::types::Heading; use crate::types::Heading;
use crate::types::Object; use crate::types::Object;
use crate::types::PriorityCookie;
use crate::types::TodoKeywordType; use crate::types::TodoKeywordType;
pub const fn heading( pub const fn heading(
@ -51,8 +52,10 @@ fn _heading<'b, 'g, 'r, 's>(
parent_stars: usize, parent_stars: usize,
) -> Res<OrgSource<'s>, Heading<'s>> { ) -> Res<OrgSource<'s>, Heading<'s>> {
not(|i| context.check_exit_matcher(i))(input)?; not(|i| context.check_exit_matcher(i))(input)?;
let (remaining, (star_count, _ws, maybe_todo_keyword, title, heading_tags)) = let (
headline(context, input, parent_stars)?; remaining,
(star_count, maybe_todo_keyword, maybe_priority, maybe_comment, title, heading_tags),
) = headline(context, input, parent_stars)?;
let section_matcher = parser_with_context!(section)(context); let section_matcher = parser_with_context!(section)(context);
let heading_matcher = parser_with_context!(heading(star_count))(context); let heading_matcher = parser_with_context!(heading(star_count))(context);
let (remaining, maybe_section) = let (remaining, maybe_section) =
@ -70,6 +73,7 @@ fn _heading<'b, 'g, 'r, 's>(
} else { } else {
remaining remaining
}; };
let is_archived = heading_tags.contains(&"ARCHIVE");
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);
Ok(( Ok((
@ -80,9 +84,12 @@ fn _heading<'b, 'g, 'r, 's>(
todo_keyword: maybe_todo_keyword.map(|((todo_keyword_type, todo_keyword), _ws)| { todo_keyword: maybe_todo_keyword.map(|((todo_keyword_type, todo_keyword), _ws)| {
(todo_keyword_type, Into::<&str>::into(todo_keyword)) (todo_keyword_type, Into::<&str>::into(todo_keyword))
}), }),
priority_cookie: maybe_priority.map(|(priority, _)| priority),
title, title,
tags: heading_tags, tags: heading_tags,
children, children,
is_comment: maybe_comment.is_some(),
is_archived,
}, },
)) ))
} }
@ -102,8 +109,9 @@ fn headline<'b, 'g, 'r, 's>(
OrgSource<'s>, OrgSource<'s>,
( (
usize, usize,
OrgSource<'s>,
Option<((TodoKeywordType, OrgSource<'s>), OrgSource<'s>)>, Option<((TodoKeywordType, OrgSource<'s>), OrgSource<'s>)>,
Option<(PriorityCookie, OrgSource<'s>)>,
Option<(OrgSource<'s>, OrgSource<'s>)>,
Vec<Object<'s>>, Vec<Object<'s>>,
Vec<&'s str>, Vec<&'s str>,
), ),
@ -116,7 +124,18 @@ fn headline<'b, 'g, 'r, 's>(
let ( let (
remaining, remaining,
(_sol, star_count, ws, maybe_todo_keyword, title, maybe_tags, _ws, _line_ending), (
_,
star_count,
_,
maybe_todo_keyword,
maybe_priority,
maybe_comment,
title,
maybe_tags,
_,
_,
),
) = tuple(( ) = tuple((
start_of_line, start_of_line,
verify(many1_count(tag("*")), |star_count| { verify(many1_count(tag("*")), |star_count| {
@ -127,6 +146,8 @@ fn headline<'b, 'g, 'r, 's>(
parser_with_context!(heading_keyword)(&parser_context), parser_with_context!(heading_keyword)(&parser_context),
space1, space1,
))), ))),
opt(tuple((priority_cookie, space1))),
opt(tuple((tag("COMMENT"), space1))),
many1(parser_with_context!(standard_set_object)(&parser_context)), many1(parser_with_context!(standard_set_object)(&parser_context)),
opt(tuple((space0, tags))), opt(tuple((space0, tags))),
space0, space0,
@ -136,8 +157,9 @@ fn headline<'b, 'g, 'r, 's>(
remaining, remaining,
( (
star_count, star_count,
ws,
maybe_todo_keyword, maybe_todo_keyword,
maybe_priority,
maybe_comment,
title, title,
maybe_tags maybe_tags
.map(|(_ws, tags)| { .map(|(_ws, tags)| {
@ -220,3 +242,17 @@ fn heading_keyword<'b, 'g, 'r, 's>(
)))) ))))
} }
} }
fn priority_cookie<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PriorityCookie> {
let (remaining, (_, priority_character, _)) = tuple((
tag("[#"),
verify(anychar, |c| c.is_alphanumeric()),
tag("]"),
))(input)?;
let cookie = PriorityCookie::try_from(priority_character).map_err(|_| {
nom::Err::Error(CustomError::MyError(MyError(
"Failed to cast priority cookie to number.".into(),
)))
})?;
Ok((remaining, cookie))
}

View File

@ -2,6 +2,8 @@ use super::Element;
use super::Object; use super::Object;
use super::Source; use super::Source;
pub type PriorityCookie = u8;
#[derive(Debug)] #[derive(Debug)]
pub struct Document<'s> { pub struct Document<'s> {
pub source: &'s str, pub source: &'s str,
@ -14,10 +16,12 @@ pub struct Heading<'s> {
pub source: &'s str, pub source: &'s str,
pub stars: usize, pub stars: usize,
pub todo_keyword: Option<(TodoKeywordType, &'s str)>, pub todo_keyword: Option<(TodoKeywordType, &'s str)>,
// TODO: add todo-type enum pub priority_cookie: Option<PriorityCookie>,
pub title: Vec<Object<'s>>, pub title: Vec<Object<'s>>,
pub tags: Vec<&'s str>, pub tags: Vec<&'s str>,
pub children: Vec<DocumentElement<'s>>, pub children: Vec<DocumentElement<'s>>,
pub is_comment: bool,
pub is_archived: bool,
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -7,6 +7,7 @@ mod source;
pub use document::Document; pub use document::Document;
pub use document::DocumentElement; pub use document::DocumentElement;
pub use document::Heading; pub use document::Heading;
pub use document::PriorityCookie;
pub use document::Section; pub use document::Section;
pub use document::TodoKeywordType; pub use document::TodoKeywordType;
pub use element::Element; pub use element::Element;