diff --git a/src/parser/document.rs b/src/parser/document.rs index ebfb4814..bec0cab0 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -99,6 +99,29 @@ fn headline<'r, 's>( context: Context<'r, 's>, input: &'s str, ) -> Res<&'s str, (usize, &'s str, Vec>, &'s str)> { + let parser_context = + context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { + exit_matcher: ChainBehavior::AndParent(Some(&headline_end)), + })); + let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context); + let start_of_line_matcher = parser_with_context!(start_of_line)(&parser_context); + + let (remaining, (_sol, star_count, ws, title, ws2)) = tuple(( + start_of_line_matcher, + many1_count(tag("*")), + space1, + many1(standard_set_object_matcher), + alt((line_ending, eof)), + ))(input)?; + Ok((remaining, (star_count, ws, title, ws2))) +} + +fn headline_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { + line_ending(input) +} + +/// Check that we are at the start of a line +fn start_of_line<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, ()> { let document_root = context.get_document_root().unwrap(); let preceding_character = get_one_before(document_root, input) .map(|slice| slice.chars().next()) @@ -108,32 +131,16 @@ fn headline<'r, 's>( Some(_) => { // Not at start of line, cannot be a heading return Err(nom::Err::Error(CustomError::MyError(MyError( - "Heading not at start of line", + "Not at start of line", )))); } // If None, we are at the start of the file which allows for headings None => {} }; - - let parser_context = - context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { - exit_matcher: ChainBehavior::AndParent(Some(&headline_end)), - })); - let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context); - - let ret = tuple(( - many1_count(tag("*")), - space1, - many1(standard_set_object_matcher), - alt((line_ending, eof)), - ))(input); - ret -} - -fn headline_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { - line_ending(input) + Ok((input, ())) } +/// Get one character from before the current position. fn get_one_before<'s>(document: &'s str, current_position: &'s str) -> Option<&'s str> { assert!(is_slice_of(document, current_position)); if document.as_ptr() as usize == current_position.as_ptr() as usize { @@ -144,6 +151,7 @@ fn get_one_before<'s>(document: &'s str, current_position: &'s str) -> Option<&' Some(&document[previous_character_offset..offset]) } +/// Check if the child string slice is a slice of the parent string slice. fn is_slice_of(parent: &str, child: &str) -> bool { let parent_start = parent.as_ptr() as usize; let parent_end = parent_start + parent.len();