Add a parser for the todo keyword's value.
This commit is contained in:
parent
b0392ad6fb
commit
bdba495f69
@ -25,5 +25,19 @@ pub fn scan_for_in_buffer_settings<'s>(
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn in_buffer_settings_key<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
alt((tag_no_case("todo"), tag_no_case("setupfile")))(input)
|
||||
alt((
|
||||
tag_no_case("archive"),
|
||||
tag_no_case("category"),
|
||||
tag_no_case("columns"),
|
||||
tag_no_case("filetags"),
|
||||
tag_no_case("link"),
|
||||
tag_no_case("priorities"),
|
||||
tag_no_case("property"),
|
||||
tag_no_case("seq_todo"),
|
||||
tag_no_case("setupfile"),
|
||||
tag_no_case("startup"),
|
||||
tag_no_case("tags"),
|
||||
tag_no_case("todo"),
|
||||
tag_no_case("typ_todo"),
|
||||
))(input)
|
||||
}
|
||||
|
90
src/parser/keyword_todo.rs
Normal file
90
src/parser/keyword_todo.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take_till;
|
||||
use nom::character::complete::line_ending;
|
||||
use nom::character::complete::space0;
|
||||
use nom::character::complete::space1;
|
||||
use nom::combinator::eof;
|
||||
use nom::combinator::opt;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::separated_list0;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use crate::error::Res;
|
||||
|
||||
/// Parses the text in the value of a #+TODO keyword.
|
||||
///
|
||||
/// Example input: "foo bar baz | lorem ipsum"
|
||||
pub fn keyword_todo<'s>(input: &'s str) -> Res<&'s str, (Vec<&'s str>, Vec<&'s str>)> {
|
||||
let (remaining, mut before_pipe_words) = separated_list0(space1, keyword_word)(input)?;
|
||||
let (remaining, after_pipe_words) = opt(tuple((
|
||||
tuple((space0, tag("|"), space0)),
|
||||
separated_list0(space1, keyword_word),
|
||||
)))(remaining)?;
|
||||
let (remaining, _eol) = alt((line_ending, eof))(remaining)?;
|
||||
if let Some((_pipe, after_pipe_words)) = after_pipe_words {
|
||||
Ok((remaining, (before_pipe_words, after_pipe_words)))
|
||||
} else if !before_pipe_words.is_empty() {
|
||||
// If there was no pipe, then the last word becomes a completion state instead.
|
||||
let mut after_pipe_words = Vec::with_capacity(1);
|
||||
after_pipe_words.push(
|
||||
before_pipe_words
|
||||
.pop()
|
||||
.expect("If-statement proves this is Some."),
|
||||
);
|
||||
Ok((remaining, (before_pipe_words, after_pipe_words)))
|
||||
} else {
|
||||
// No words founds
|
||||
Ok((remaining, (Vec::new(), Vec::new())))
|
||||
}
|
||||
}
|
||||
|
||||
fn keyword_word<'s>(input: &'s str) -> Res<&'s str, &'s str> {
|
||||
verify(take_till(|c| " \t\r\n|".contains(c)), |result: &str| {
|
||||
!result.is_empty()
|
||||
})(input)
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn before_and_after() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = "foo bar baz | lorem ipsum";
|
||||
let (remaining, (before_pipe_words, after_pipe_words)) = keyword_todo(input)?;
|
||||
assert_eq!(remaining, "");
|
||||
assert_eq!(before_pipe_words, vec!["foo", "bar", "baz"]);
|
||||
assert_eq!(after_pipe_words, vec!["lorem", "ipsum"]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_pipe() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = "foo bar baz";
|
||||
let (remaining, (before_pipe_words, after_pipe_words)) = keyword_todo(input)?;
|
||||
assert_eq!(remaining, "");
|
||||
assert_eq!(before_pipe_words, vec!["foo", "bar"]);
|
||||
assert_eq!(after_pipe_words, vec!["baz"]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn early_pipe() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = "| foo bar baz";
|
||||
let (remaining, (before_pipe_words, after_pipe_words)) = keyword_todo(input)?;
|
||||
assert_eq!(remaining, "");
|
||||
assert_eq!(before_pipe_words, Vec::<&str>::new());
|
||||
assert_eq!(after_pipe_words, vec!["foo", "bar", "baz"]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn late_pipe() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = "foo bar baz |";
|
||||
let (remaining, (before_pipe_words, after_pipe_words)) = keyword_todo(input)?;
|
||||
assert_eq!(remaining, "");
|
||||
assert_eq!(before_pipe_words, vec!["foo", "bar", "baz"]);
|
||||
assert_eq!(after_pipe_words, Vec::<&str>::new());
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ mod in_buffer_settings;
|
||||
mod inline_babel_call;
|
||||
mod inline_source_block;
|
||||
mod keyword;
|
||||
mod keyword_todo;
|
||||
mod latex_environment;
|
||||
mod latex_fragment;
|
||||
mod lesser_block;
|
||||
|
Loading…
Reference in New Issue
Block a user