From 353ff07420020b5c464dc00419ec195afbee9ee7 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 18 Oct 2023 12:32:48 -0400 Subject: [PATCH] Handle bullshitium for broken dynamic blocks. --- src/parser/bullshitium.rs | 53 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/parser/bullshitium.rs b/src/parser/bullshitium.rs index 3a7afc06..ca6dda93 100644 --- a/src/parser/bullshitium.rs +++ b/src/parser/bullshitium.rs @@ -1,5 +1,8 @@ +use nom::branch::alt; use nom::bytes::complete::tag_no_case; +use nom::character::complete::anychar; use nom::character::complete::space0; +use nom::multi::many_till; use nom::sequence::tuple; use super::paragraph::paragraph; @@ -7,6 +10,7 @@ use super::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::util::org_line_ending; use super::util::start_of_line; use super::OrgSource; +use crate::context::bind_context; use crate::context::RefContext; use crate::error::Res; use crate::types::AffiliatedKeywords; @@ -22,7 +26,10 @@ pub(crate) fn bullshitium<'b, 'g, 'r, 's>( context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, ) -> Res, Paragraph<'s>> { - broken_end(context, input) + alt(( + bind_context!(broken_end, context), + bind_context!(broken_dynamic_block, context), + ))(input) } #[cfg_attr( @@ -80,3 +87,47 @@ pub(crate) fn broken_end<'b, 'g, 'r, 's>( )) } } + +#[cfg_attr( + feature = "tracing", + tracing::instrument(ret, level = "debug", skip(context)) +)] +pub(crate) fn broken_dynamic_block<'b, 'g, 'r, 's>( + context: RefContext<'b, 'g, 'r, 's>, + input: OrgSource<'s>, +) -> Res, Paragraph<'s>> { + start_of_line(input)?; + let (remaining, _) = space0(input)?; + let (remaining, _) = tag_no_case("#+BEGIN:")(remaining)?; + let (lead_in_remaining, _) = many_till(anychar, org_line_ending)(remaining)?; + if let Ok((remaining, mut paragraph)) = + paragraph(std::iter::empty(), lead_in_remaining, context, input) + { + match paragraph.children.first_mut() { + Some(Object::PlainText(plain_text)) => { + plain_text.source = input.get_until_end_of_str(plain_text.source).into(); + } + Some(obj) => { + panic!("Unhandled first object type inside bullshitium {:?}", obj); + } + None => { + unreachable!("Paragraph must have children."); + } + }; + Ok((remaining, paragraph)) + } else { + let (remaining, _trailing_ws) = + maybe_consume_trailing_whitespace_if_not_exiting(context, lead_in_remaining)?; + + Ok(( + remaining, + Paragraph { + source: input.get_until(remaining).into(), + affiliated_keywords: AffiliatedKeywords::default(), + children: vec![Object::PlainText(PlainText { + source: input.get_until(lead_in_remaining).into(), + })], + }, + )) + } +}