From 444d6758aaf6a855a2c4bb4e61a2bda7823b041c Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 15 Sep 2023 17:51:45 -0400 Subject: [PATCH] Handle leading blank lines in greater blocks. --- src/parser/greater_block.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index 1721163..b6b8785 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -4,11 +4,14 @@ use nom::bytes::complete::tag_no_case; use nom::character::complete::line_ending; use nom::character::complete::space0; use nom::character::complete::space1; +use nom::combinator::consumed; use nom::combinator::eof; use nom::combinator::not; use nom::combinator::opt; use nom::combinator::verify; +use nom::multi::many0; use nom::multi::many_till; +use nom::sequence::preceded; use nom::sequence::tuple; use super::org_source::OrgSource; @@ -80,25 +83,23 @@ pub(crate) fn greater_block<'b, 'g, 'r, 's>( let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); - // Check for a completely empty block - let (remaining, children) = match tuple(( - not(exit_matcher), + not(exit_matcher)(remaining)?; + let (remaining, leading_blank_lines) = opt(consumed(tuple(( blank_line, - many_till(blank_line, exit_matcher), - ))(remaining) - { - Ok((remain, (_not_immediate_exit, first_line, (_trailing_whitespace, _exit_contents)))) => { + many0(preceded(not(exit_matcher), blank_line)), + ))))(remaining)?; + let leading_blank_lines = + leading_blank_lines.map(|(source, (first_line, _remaining_lines))| { let mut element = Element::Paragraph(Paragraph::of_text(first_line.into())); - let source = get_consumed(remaining, remain); element.set_source(source.into()); - (remain, vec![element]) - } - Err(_) => { - let (remaining, (children, _exit_contents)) = - many_till(element_matcher, exit_matcher)(remaining)?; - (remaining, children) - } - }; + element + }); + let (remaining, (mut children, _exit_contents)) = + many_till(element_matcher, exit_matcher)(remaining)?; + if let Some(lines) = leading_blank_lines { + children.insert(0, lines); + } + let (remaining, _end) = exit_with_name(&parser_context, remaining)?; // Not checking if parent exit matcher is causing exit because the greater_block_end matcher asserts we matched a full greater block