diff --git a/src/parser/document.rs b/src/parser/document.rs index 352ddc8..81f1a68 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -29,6 +29,7 @@ use super::parser_with_context::parser_with_context; use super::source::Source; use super::util::get_consumed; use super::util::get_one_before; +use super::util::trailing_whitespace; use super::Context; #[derive(Debug)] @@ -151,7 +152,7 @@ fn headline<'r, 's>( many1_count(tag("*")), space1, many1(standard_set_object_matcher), - alt((line_ending, eof)), + trailing_whitespace, ))(input)?; Ok((remaining, (star_count, ws, title, ws2))) } diff --git a/src/parser/element.rs b/src/parser/element.rs index 88d44cc..3ae3d1a 100644 --- a/src/parser/element.rs +++ b/src/parser/element.rs @@ -19,7 +19,9 @@ use super::error::Res; use super::greater_element::PlainList; use super::lesser_element::Paragraph; use super::source::Source; +use super::util::blank_line; use super::util::get_consumed; +use super::util::trailing_whitespace; use super::Context; #[derive(Debug)] @@ -54,8 +56,7 @@ fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, P let (remaining, children) = many1(standard_set_object_matcher)(input)?; - let (remaining, _trailing_whitespace) = - alt((eof, recognize(tuple((line_ending, many0(blank_line))))))(remaining)?; + let (remaining, _trailing_whitespace) = trailing_whitespace(remaining)?; let source = get_consumed(input, remaining); @@ -66,11 +67,3 @@ fn paragraph_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st // TODO: Other elements should also end paragraphs alt((recognize(tuple((line_ending, many1(blank_line)))), eof))(input) } - -/// A line containing only whitespace and then a line break -/// -/// It is up to the caller to ensure this is called at the start of a line. -fn blank_line(input: &str) -> Res<&str, &str> { - not(eof)(input)?; - recognize(tuple((space0, alt((line_ending, eof)))))(input) -} diff --git a/src/parser/util.rs b/src/parser/util.rs index cf4b3f7..9962dc7 100644 --- a/src/parser/util.rs +++ b/src/parser/util.rs @@ -1,3 +1,13 @@ +use nom::branch::alt; +use nom::character::complete::line_ending; +use nom::character::complete::space0; +use nom::combinator::eof; +use nom::combinator::not; +use nom::combinator::recognize; +use nom::multi::many0; +use nom::sequence::tuple; + +use super::error::Res; use super::parser_context::ContextElement; use super::Context; @@ -54,6 +64,18 @@ pub fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str { source } +/// A line containing only whitespace and then a line break +/// +/// It is up to the caller to ensure this is called at the start of a line. +pub fn blank_line(input: &str) -> Res<&str, &str> { + not(eof)(input)?; + recognize(tuple((space0, alt((line_ending, eof)))))(input) +} + +pub fn trailing_whitespace(input: &str) -> Res<&str, &str> { + alt((eof, recognize(tuple((line_ending, many0(blank_line))))))(input) +} + #[cfg(test)] mod tests { use super::*; diff --git a/toy_language.txt b/toy_language.txt index 2f8aa33..614291f 100644 --- a/toy_language.txt +++ b/toy_language.txt @@ -11,3 +11,7 @@ text* *nesting *bold entrances* and* exits + +* Heading + +body of heading