fix(title): expect space after priority (#20)

This commit is contained in:
PoiScript 2020-05-09 16:55:17 +08:00
parent 2128e86b81
commit a99702a4da

View file

@ -5,9 +5,10 @@ use std::collections::HashMap;
use memchr::memrchr2; use memchr::memrchr2;
use nom::{ use nom::{
branch::alt,
bytes::complete::{tag, take_until, take_while}, bytes::complete::{tag, take_until, take_while},
character::complete::{anychar, space1}, character::complete::{anychar, line_ending, space1},
combinator::{map, map_parser, opt, verify}, combinator::{map, opt, verify},
error::{make_error, ErrorKind}, error::{make_error, ErrorKind},
multi::fold_many0, multi::fold_many0,
sequence::{delimited, preceded}, sequence::{delimited, preceded},
@ -122,8 +123,15 @@ impl Default for Title<'_> {
} }
} }
fn white_spaces_or_eol(input: &str) -> IResult<&str, &str, ()> {
alt((space1, line_ending))(input)
}
#[inline] #[inline]
fn parse_title<'a>(input: &'a str, config: &ParseConfig) -> IResult<&'a str, (Title<'a>, &'a str), ()> { fn parse_title<'a>(
input: &'a str,
config: &ParseConfig,
) -> IResult<&'a str, (Title<'a>, &'a str), ()> {
let (input, level) = map(take_while(|c: char| c == '*'), |s: &str| s.len())(input)?; let (input, level) = map(take_while(|c: char| c == '*'), |s: &str| s.len())(input)?;
debug_assert!(level > 0); debug_assert!(level > 0);
@ -136,16 +144,14 @@ fn parse_title<'a>(input: &'a str, config: &ParseConfig) -> IResult<&'a str, (Ti
}), }),
))(input)?; ))(input)?;
let (input, priority) = opt(preceded( let (input, priority) = opt(delimited(
space1, space1,
map_parser( delimited(
one_word, tag("[#"),
delimited( verify(anychar, |c: &char| c.is_ascii_uppercase()),
tag("[#"), tag("]"),
verify(anychar, |c: &char| c.is_ascii_uppercase()),
tag("]"),
),
), ),
white_spaces_or_eol,
))(input)?; ))(input)?;
let (input, tail) = line(input)?; let (input, tail) = line(input)?;
let tail = tail.trim(); let tail = tail.trim();
@ -323,6 +329,28 @@ fn parse_title_() {
) )
)) ))
); );
// https://github.com/PoiScript/orgize/issues/20
assert_eq!(
parse_title("** DONE [#B]::", &DEFAULT_CONFIG),
Ok((
"",
(
Title {
level: 2,
keyword: Some("DONE".into()),
priority: None,
raw: "[#B]::".into(),
tags: vec![],
planning: None,
properties: HashMap::new(),
post_blank: 0,
},
"[#B]::"
)
))
);
assert_eq!( assert_eq!(
parse_title("**** Title :tag:a2%", &DEFAULT_CONFIG), parse_title("**** Title :tag:a2%", &DEFAULT_CONFIG),
Ok(( Ok((