From 683c523eceb5dcdcd92523a3f06a60d88e1b3154 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 15 Dec 2023 16:15:22 -0500 Subject: [PATCH] Implement the new fields for greater block. --- src/parser/greater_block.rs | 52 +++++++++++++++++++++++++++--------- src/types/greater_element.rs | 30 ++++++++++++++++----- 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index c8b8d772..d8b6d8c7 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -102,7 +102,7 @@ fn center_block<'b, 'g, 'r, 's, AK>( where AK: IntoIterator>, { - let (remaining, (source, children)) = greater_block_body( + let (remaining, body) = greater_block_body( context, input, pre_affiliated_keywords_input, @@ -112,12 +112,14 @@ where Ok(( remaining, Element::CenterBlock(CenterBlock { - source, + source: body.source, affiliated_keywords: parse_affiliated_keywords( context.get_global_settings(), affiliated_keywords, ), - children, + children: body.children, + contents: body.contents, + post_blank: body.post_blank, }), )) } @@ -135,7 +137,7 @@ fn quote_block<'b, 'g, 'r, 's, AK>( where AK: IntoIterator>, { - let (remaining, (source, children)) = greater_block_body( + let (remaining, body) = greater_block_body( context, input, pre_affiliated_keywords_input, @@ -145,12 +147,14 @@ where Ok(( remaining, Element::QuoteBlock(QuoteBlock { - source, + source: body.source, affiliated_keywords: parse_affiliated_keywords( context.get_global_settings(), affiliated_keywords, ), - children, + children: body.children, + contents: body.contents, + post_blank: body.post_blank, }), )) } @@ -196,7 +200,7 @@ where AK: IntoIterator>, { let (remaining, parameters) = opt(tuple((space1, parameters)))(input)?; - let (remaining, (source, children)) = greater_block_body( + let (remaining, body) = greater_block_body( context, remaining, pre_affiliated_keywords_input, @@ -206,18 +210,28 @@ where Ok(( remaining, Element::SpecialBlock(SpecialBlock { - source, + source: body.source, affiliated_keywords: parse_affiliated_keywords( context.get_global_settings(), affiliated_keywords, ), - children, + children: body.children, block_type: name, parameters: parameters.map(|(_, parameters)| Into::<&str>::into(parameters)), + contents: body.contents, + post_blank: body.post_blank, }), )) } +#[derive(Debug)] +struct GreaterBlockBody<'s> { + source: &'s str, + children: Vec>, + contents: Option<&'s str>, + post_blank: Option<&'s str>, +} + #[cfg_attr( feature = "tracing", tracing::instrument(ret, level = "debug", skip(context)) @@ -228,7 +242,7 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>( pre_affiliated_keywords_input: OrgSource<'s>, name: &'c str, context_name: &'c str, -) -> Res, (&'s str, Vec>)> { +) -> Res, GreaterBlockBody<'s>> { if in_section(context, context_name) { return Err(nom::Err::Error(CustomError::Static( "Cannot nest objects of the same element", @@ -250,6 +264,7 @@ fn greater_block_body<'c, '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); not(exit_matcher)(remaining)?; + let contents_begin = remaining; let (remaining, leading_blank_lines) = opt(consumed(tuple(( blank_line, many0(preceded(not(exit_matcher), blank_line)), @@ -263,15 +278,28 @@ fn greater_block_body<'c, 'b, 'g, 'r, 's>( if let Some(lines) = leading_blank_lines { children.insert(0, lines); } + let contents = get_consumed(contents_begin, remaining); 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 - let (remaining, _trailing_ws) = + let (remaining, post_blank) = maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; let source = get_consumed(pre_affiliated_keywords_input, remaining); - Ok((remaining, (Into::<&str>::into(source), children))) + Ok(( + remaining, + GreaterBlockBody { + source: Into::<&str>::into(source), + children, + contents: if contents.len() > 0 { + Some(Into::<&str>::into(contents)) + } else { + None + }, + post_blank: post_blank.map(Into::<&str>::into), + }, + )) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] diff --git a/src/types/greater_element.rs b/src/types/greater_element.rs index f43cf13a..bb848d97 100644 --- a/src/types/greater_element.rs +++ b/src/types/greater_element.rs @@ -56,6 +56,8 @@ pub struct CenterBlock<'s> { pub source: &'s str, pub affiliated_keywords: AffiliatedKeywords<'s>, pub children: Vec>, + pub contents: Option<&'s str>, + pub post_blank: Option<&'s str>, } #[derive(Debug)] @@ -63,6 +65,8 @@ pub struct QuoteBlock<'s> { pub source: &'s str, pub affiliated_keywords: AffiliatedKeywords<'s>, pub children: Vec>, + pub contents: Option<&'s str>, + pub post_blank: Option<&'s str>, } #[derive(Debug)] @@ -72,6 +76,8 @@ pub struct SpecialBlock<'s> { pub block_type: &'s str, pub parameters: Option<&'s str>, pub children: Vec>, + pub contents: Option<&'s str>, + pub post_blank: Option<&'s str>, } #[derive(Debug)] @@ -180,11 +186,15 @@ impl<'s> StandardProperties<'s> for CenterBlock<'s> { } fn get_contents<'b>(&'b self) -> Option<&'s str> { - todo!() + self.contents } fn get_post_blank(&self) -> PostBlank { - todo!() + self.post_blank + .map(|text| text.lines().count()) + .unwrap_or(0) + .try_into() + .expect("Too much post-blank to fit into a PostBlank.") } } @@ -194,11 +204,15 @@ impl<'s> StandardProperties<'s> for QuoteBlock<'s> { } fn get_contents<'b>(&'b self) -> Option<&'s str> { - todo!() + self.contents } fn get_post_blank(&self) -> PostBlank { - todo!() + self.post_blank + .map(|text| text.lines().count()) + .unwrap_or(0) + .try_into() + .expect("Too much post-blank to fit into a PostBlank.") } } @@ -208,11 +222,15 @@ impl<'s> StandardProperties<'s> for SpecialBlock<'s> { } fn get_contents<'b>(&'b self) -> Option<&'s str> { - todo!() + self.contents } fn get_post_blank(&self) -> PostBlank { - todo!() + self.post_blank + .map(|text| text.lines().count()) + .unwrap_or(0) + .try_into() + .expect("Too much post-blank to fit into a PostBlank.") } }