From b557b9ca5dada44c7057d11f738437e3ecd82298 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 19 Apr 2023 18:37:39 -0400 Subject: [PATCH] Accounting for the blank lines at the head of documents and comments plus property drawer at the head of the zeroth section. --- Cargo.toml | 1 - .../property_drawer/zeroth_section.org | 17 ++++++++ src/parser/document.rs | 41 ++++++++++++++++++- toy_language.txt | 9 ++-- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7f42a243..9e11b28b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ name = "toy" version = "0.1.0" edition = "2021" license = "0BSD" -default-run = "toy" [lib] name = "organic" diff --git a/org_mode_samples/property_drawer/zeroth_section.org b/org_mode_samples/property_drawer/zeroth_section.org index ccdae6fa..25380541 100644 --- a/org_mode_samples/property_drawer/zeroth_section.org +++ b/org_mode_samples/property_drawer/zeroth_section.org @@ -6,3 +6,20 @@ :PROPERTIES: :FOO: bar :END: + + + +* Spaces turn property drawers into regular drawers + +:PROPERTIES: +:FOO: bar +:END: +* Comments turn property drawers into regular drawers +# Comment +:PROPERTIES: +:FOO: bar +:END: +* Baseline +:PROPERTIES: +:FOO: bar +:END: diff --git a/src/parser/document.rs b/src/parser/document.rs index f2e4308b..309e2aec 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -1,3 +1,4 @@ +use crate::parser::property_drawer::property_drawer; use nom::branch::alt; use nom::bytes::complete::tag; use nom::character::complete::line_ending; @@ -13,12 +14,14 @@ use nom::multi::many1_count; use nom::multi::many_till; use nom::sequence::tuple; +use crate::parser::comment::comment; use crate::parser::element::element; use crate::parser::exiting::ExitClass; use crate::parser::object::standard_set_object; use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextTree; use crate::parser::parser_context::ExitMatcherNode; +use crate::parser::util::blank_line; use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::element::Element; @@ -92,9 +95,10 @@ pub fn document(input: &str) -> Res<&str, Document> { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let section_matcher = parser_with_context!(section)(&document_context); + let zeroth_section_matcher = parser_with_context!(zeroth_section)(&document_context); let heading_matcher = parser_with_context!(heading)(&document_context); - let (remaining, zeroth_section) = opt(section_matcher)(input)?; + let (remaining, _blank_lines) = many0(blank_line)(input)?; + let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?; let (remaining, children) = many0(heading_matcher)(remaining)?; let source = get_consumed(input, remaining); Ok(( @@ -107,6 +111,39 @@ pub fn document(input: &str) -> Res<&str, Document> { )) } +#[tracing::instrument(ret, level = "debug")] +fn zeroth_section<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Section<'s>> { + // TODO: The zeroth section is specialized so it probably needs its own parser + let parser_context = context + .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) + .with_additional_node(ContextElement::Context("section")) + .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { + class: ExitClass::Document, + exit_matcher: §ion_end, + })); + let element_matcher = parser_with_context!(element)(&parser_context); + let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); + + let (remaining, (comment_element, property_drawer_element)) = tuple(( + opt(parser_with_context!(comment)(&parser_context)), + opt(parser_with_context!(property_drawer)(&parser_context)), + ))(input)?; + + let (remaining, (mut children, _exit_contents)) = verify( + many_till(element_matcher, exit_matcher), + |(children, _exit_contents)| !children.is_empty(), + )(remaining)?; + property_drawer_element.map(Element::PropertyDrawer).map(|ele| children.insert(0, ele)); + comment_element.map(Element::Comment).map(|ele| children.insert(0, ele)); + // children.insert(0, item) + + let (remaining, _trailing_ws) = + maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; + + let source = get_consumed(input, remaining); + Ok((remaining, Section { source, children })) +} + #[tracing::instrument(ret, level = "debug")] fn section<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Section<'s>> { // TODO: The zeroth section is specialized so it probably needs its own parser diff --git a/toy_language.txt b/toy_language.txt index 574a2f2e..ccdae6fa 100644 --- a/toy_language.txt +++ b/toy_language.txt @@ -1,5 +1,8 @@ -foo -:drawername: -:end: + + +# Blank lines and comments can come before property drawers in the zeroth section +:PROPERTIES: +:FOO: bar +:END: