From c7c0deed74613c648ae34e3ff42ecdd5148dc936 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 8 Sep 2023 15:43:13 -0400 Subject: [PATCH] Parse priority cookie and COMMENT from headlines. --- Cargo.toml | 2 +- src/parser/headline.rs | 46 +++++++++++++++++++++++++++++++++++++----- src/types/document.rs | 6 +++++- src/types/mod.rs | 1 + 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b233792..e8981ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-fil walkdir = "2.3.3" [features] -default = [] +default = ["compare"] compare = [] tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"] diff --git a/src/parser/headline.rs b/src/parser/headline.rs index c0b6702..6be9159 100644 --- a/src/parser/headline.rs +++ b/src/parser/headline.rs @@ -33,6 +33,7 @@ use crate::parser::util::blank_line; use crate::types::DocumentElement; use crate::types::Heading; use crate::types::Object; +use crate::types::PriorityCookie; use crate::types::TodoKeywordType; pub const fn heading( @@ -51,8 +52,10 @@ fn _heading<'b, 'g, 'r, 's>( parent_stars: usize, ) -> Res, Heading<'s>> { not(|i| context.check_exit_matcher(i))(input)?; - let (remaining, (star_count, _ws, maybe_todo_keyword, title, heading_tags)) = - headline(context, input, parent_stars)?; + let ( + 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 heading_matcher = parser_with_context!(heading(star_count))(context); let (remaining, maybe_section) = @@ -70,6 +73,7 @@ fn _heading<'b, 'g, 'r, 's>( } else { remaining }; + let is_archived = heading_tags.contains(&"ARCHIVE"); let source = get_consumed(input, remaining); 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_type, Into::<&str>::into(todo_keyword)) }), + priority_cookie: maybe_priority.map(|(priority, _)| priority), title, tags: heading_tags, children, + is_comment: maybe_comment.is_some(), + is_archived, }, )) } @@ -102,8 +109,9 @@ fn headline<'b, 'g, 'r, 's>( OrgSource<'s>, ( usize, - OrgSource<'s>, Option<((TodoKeywordType, OrgSource<'s>), OrgSource<'s>)>, + Option<(PriorityCookie, OrgSource<'s>)>, + Option<(OrgSource<'s>, OrgSource<'s>)>, Vec>, Vec<&'s str>, ), @@ -116,7 +124,18 @@ fn headline<'b, 'g, 'r, 's>( let ( 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(( start_of_line, verify(many1_count(tag("*")), |star_count| { @@ -127,6 +146,8 @@ fn headline<'b, 'g, 'r, 's>( parser_with_context!(heading_keyword)(&parser_context), space1, ))), + opt(tuple((priority_cookie, space1))), + opt(tuple((tag("COMMENT"), space1))), many1(parser_with_context!(standard_set_object)(&parser_context)), opt(tuple((space0, tags))), space0, @@ -136,8 +157,9 @@ fn headline<'b, 'g, 'r, 's>( remaining, ( star_count, - ws, maybe_todo_keyword, + maybe_priority, + maybe_comment, title, maybe_tags .map(|(_ws, tags)| { @@ -220,3 +242,17 @@ fn heading_keyword<'b, 'g, 'r, 's>( )))) } } + +fn priority_cookie<'s>(input: OrgSource<'s>) -> Res, 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)) +} diff --git a/src/types/document.rs b/src/types/document.rs index 654377a..142762d 100644 --- a/src/types/document.rs +++ b/src/types/document.rs @@ -2,6 +2,8 @@ use super::Element; use super::Object; use super::Source; +pub type PriorityCookie = u8; + #[derive(Debug)] pub struct Document<'s> { pub source: &'s str, @@ -14,10 +16,12 @@ pub struct Heading<'s> { pub source: &'s str, pub stars: usize, pub todo_keyword: Option<(TodoKeywordType, &'s str)>, - // TODO: add todo-type enum + pub priority_cookie: Option, pub title: Vec>, pub tags: Vec<&'s str>, pub children: Vec>, + pub is_comment: bool, + pub is_archived: bool, } #[derive(Debug)] diff --git a/src/types/mod.rs b/src/types/mod.rs index efd1b04..9cf5b59 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -7,6 +7,7 @@ mod source; pub use document::Document; pub use document::DocumentElement; pub use document::Heading; +pub use document::PriorityCookie; pub use document::Section; pub use document::TodoKeywordType; pub use element::Element;