feat(config): add done_keywords field
This commit is contained in:
parent
3e82172dfe
commit
b429e4f54a
6 changed files with 51 additions and 56 deletions
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
/// Parse configuration
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ParseConfig<'a> {
|
||||
/// Default headline todo keywords, it shouldn't be changed.
|
||||
pub default_todo_keywords: &'a [&'a str],
|
||||
/// Custom headline todo keywords
|
||||
pub todo_keywords: &'a [&'a str],
|
||||
pub struct ParseConfig {
|
||||
/// Headline's TODO keywords, todo type
|
||||
pub todo_keywords: Vec<String>,
|
||||
/// Headline's TODO keywords, done type
|
||||
pub done_keywords: Vec<String>,
|
||||
}
|
||||
|
||||
impl Default for ParseConfig<'_> {
|
||||
impl Default for ParseConfig {
|
||||
fn default() -> Self {
|
||||
ParseConfig {
|
||||
default_todo_keywords: &["TODO", "DONE", "NEXT", "WAITING", "LATER", "CANCELLED"],
|
||||
todo_keywords: &[],
|
||||
todo_keywords: vec![String::from("TODO")],
|
||||
done_keywords: vec![String::from("DONE")],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ pub struct Headline<'a> {
|
|||
impl Headline<'_> {
|
||||
pub(crate) fn parse<'a>(
|
||||
text: &'a str,
|
||||
config: &ParseConfig<'_>,
|
||||
config: &ParseConfig,
|
||||
) -> (&'a str, Headline<'a>, &'a str) {
|
||||
let level = memchr2(b'\n', b' ', text.as_bytes()).unwrap_or_else(|| text.len());
|
||||
|
||||
|
|
@ -67,7 +67,8 @@ impl Headline<'_> {
|
|||
let (word, off) = memchr(b' ', tail.as_bytes())
|
||||
.map(|i| (&tail[0..i], i + 1))
|
||||
.unwrap_or_else(|| (tail, tail.len()));
|
||||
if config.todo_keywords.contains(&word) || config.default_todo_keywords.contains(&word)
|
||||
if config.todo_keywords.iter().any(|x| x == word)
|
||||
|| config.done_keywords.iter().any(|x| x == word)
|
||||
{
|
||||
(Some(word), &tail[off..])
|
||||
} else {
|
||||
|
|
@ -151,7 +152,7 @@ impl Headline<'_> {
|
|||
|
||||
#[cfg(test)]
|
||||
lazy_static::lazy_static! {
|
||||
static ref CONFIG: ParseConfig<'static> = ParseConfig::default();
|
||||
static ref CONFIG: ParseConfig = ParseConfig::default();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -276,7 +277,7 @@ fn parse_todo_keywords() {
|
|||
Headline::parse(
|
||||
"**** DONE [#A] COMMENT Title :tag:a2%:",
|
||||
&ParseConfig {
|
||||
default_todo_keywords: &[],
|
||||
done_keywords: vec![],
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
|
|
@ -296,7 +297,7 @@ fn parse_todo_keywords() {
|
|||
Headline::parse(
|
||||
"**** TASK [#A] COMMENT Title :tag:a2%:",
|
||||
&ParseConfig {
|
||||
todo_keywords: &["TASK"],
|
||||
todo_keywords: vec!["TASK".to_string()],
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
|
|
|
|||
32
src/lib.rs
32
src/lib.rs
|
|
@ -21,9 +21,9 @@
|
|||
//!
|
||||
//! Org::parse_with_config(
|
||||
//! "* TASK Title 1",
|
||||
//! ParseConfig {
|
||||
//! &ParseConfig {
|
||||
//! // custom todo keywords
|
||||
//! todo_keywords: &["TASK"],
|
||||
//! todo_keywords: vec!["TASK".to_string()],
|
||||
//! ..Default::default()
|
||||
//! },
|
||||
//! );
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
//! );
|
||||
//! ```
|
||||
//!
|
||||
//! # Render html with custom HtmlHandler
|
||||
//! # Render html with custom `HtmlHandler`
|
||||
//!
|
||||
//! To customize html rendering, simply implementing [`HtmlHandler`] trait and passing
|
||||
//! it to the [`Org::html_with_handler`] function.
|
||||
|
|
@ -112,28 +112,26 @@
|
|||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! struct MyHtmlHandler;
|
||||
//! struct MyHtmlHandler(DefaultHtmlHandler);
|
||||
//!
|
||||
//! impl HtmlHandler<MyError> for MyHtmlHandler {
|
||||
//! fn start<W: Write>(&mut self, mut w: W, element: &Element<'_>) -> Result<(), MyError> {
|
||||
//! let mut default_handler = DefaultHtmlHandler;
|
||||
//! match element {
|
||||
//! Element::Headline(headline) => {
|
||||
//! if headline.level > 6 {
|
||||
//! return Err(MyError::Heading);
|
||||
//! } else {
|
||||
//! let slugify = slugify!(headline.title);
|
||||
//! write!(
|
||||
//! w,
|
||||
//! "<h{0}><a id=\"{1}\" href=\"#{1}\">{2}</a></h{0}>",
|
||||
//! headline.level,
|
||||
//! slugify,
|
||||
//! slugify!(headline.title),
|
||||
//! Escape(headline.title),
|
||||
//! )?;
|
||||
//! }
|
||||
//! }
|
||||
//! // fallthrough to default handler
|
||||
//! _ => default_handler.start(w, element)?,
|
||||
//! _ => self.0.start(w, element)?,
|
||||
//! }
|
||||
//! Ok(())
|
||||
//! }
|
||||
|
|
@ -141,7 +139,7 @@
|
|||
//!
|
||||
//! fn main() -> Result<(), MyError> {
|
||||
//! let mut writer = Vec::new();
|
||||
//! Org::parse("* title\n*section*").html_with_handler(&mut writer, MyHtmlHandler)?;
|
||||
//! Org::parse("* title\n*section*").html_with_handler(&mut writer, MyHtmlHandler(DefaultHtmlHandler))?;
|
||||
//!
|
||||
//! assert_eq!(
|
||||
//! String::from_utf8(writer)?,
|
||||
|
|
@ -156,13 +154,13 @@
|
|||
//! **Note**: as I mentioned above, each element will appears two times while iterating.
|
||||
//! And handler will silently ignores all end events from non-container elements.
|
||||
//!
|
||||
//! So if you want to change how a non-container element renders, just redefine the start
|
||||
//! function and leave the end function untouched.
|
||||
//! So if you want to change how a non-container element renders, just redefine the `start`
|
||||
//! function and leave the `end` function unchanged.
|
||||
//!
|
||||
//! # Serde
|
||||
//!
|
||||
//! `Org` struct have already implemented serde's `Serialize` trait. It means you can
|
||||
//! freely serialize it into any format that serde supports such as json:
|
||||
//! serialize it into any format supported by serde, such as json:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use orgize::Org;
|
||||
|
|
@ -197,11 +195,11 @@
|
|||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! By now, orgize provides three features:
|
||||
//! By now, orgize provides two features:
|
||||
//!
|
||||
//! + `serde`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default.
|
||||
//!
|
||||
//! + `chrono`: adds the ability to convert `Datetime` into `chrono` struct, disabled by default.
|
||||
//! + `chrono`: adds the ability to convert `Datetime` into `chrono` structs, disabled by default.
|
||||
//!
|
||||
//! # License
|
||||
//!
|
||||
|
|
@ -209,11 +207,11 @@
|
|||
|
||||
#![allow(clippy::range_plus_one)]
|
||||
|
||||
pub mod config;
|
||||
mod config;
|
||||
pub mod elements;
|
||||
pub mod export;
|
||||
pub mod iter;
|
||||
pub mod org;
|
||||
mod iter;
|
||||
mod org;
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ enum Container<'a> {
|
|||
|
||||
impl<'a> Org<'a> {
|
||||
pub fn parse(text: &'a str) -> Self {
|
||||
Org::parse_with_config(text, ParseConfig::default())
|
||||
Org::parse_with_config(text, &ParseConfig::default())
|
||||
}
|
||||
|
||||
pub fn parse_with_config(content: &'a str, config: ParseConfig<'_>) -> Self {
|
||||
pub fn parse_with_config(content: &'a str, config: &ParseConfig) -> Self {
|
||||
let mut arena = Arena::new();
|
||||
let document = arena.new_node(Element::Document);
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ fn parse_element<'a>(
|
|||
}
|
||||
|
||||
if tail.starts_with(':') {
|
||||
if let Some((tail, drawer, content)) = Drawer::parse(tail) {
|
||||
if let Some((tail, drawer, _content)) = Drawer::parse(tail) {
|
||||
return Some((tail, arena.new_node(drawer)));
|
||||
}
|
||||
}
|
||||
|
|
@ -404,7 +404,7 @@ fn parse_object<'a>(
|
|||
.ok()
|
||||
.map(|(tail, element)| (tail, arena.new_node(element))),
|
||||
b'<' => RadioTarget::parse(contents)
|
||||
.map(|(tail, (radio, content))| (tail, radio))
|
||||
.map(|(tail, (radio, _content))| (tail, radio))
|
||||
.or_else(|_| Target::parse(contents))
|
||||
.or_else(|_| {
|
||||
Timestamp::parse_active(contents).map(|(tail, timestamp)| (tail, timestamp.into()))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue