From 7df899e3a78c1c9d97dd4f23740c74776788d887 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 21 Apr 2023 23:36:38 -0400 Subject: [PATCH 01/14] Read affiliated keywords. --- src/parser/element_parser.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index e2ccc9b..04b7466 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -16,24 +16,32 @@ use super::lesser_block::src_block; use super::lesser_block::verse_block; use super::paragraph::paragraph; use super::plain_list::plain_list; +use super::util::start_of_line; use super::Context; use crate::error::Res; use crate::parser::parser_with_context::parser_with_context; use crate::parser::table::org_mode_table; use nom::branch::alt; use nom::combinator::map; +use nom::multi::many0; #[tracing::instrument(ret, level = "debug")] pub fn element<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Element<'s>> { let non_paragraph_matcher = parser_with_context!(non_paragraph_element)(context); - let paragraph_matcher = parser_with_context!(paragraph)(context); + let paragraph_matcher = parser_with_context!(paragraph_element)(context); - alt(( - non_paragraph_matcher, - map(paragraph_matcher, Element::Paragraph), - ))(input) + alt((non_paragraph_matcher, paragraph_matcher))(input) } +pub fn paragraph_element<'r, 's>( + context: Context<'r, 's>, + input: &'s str, +) -> Res<&'s str, Element<'s>> { + let paragraph_matcher = parser_with_context!(paragraph)(context); + let keyword_matcher = parser_with_context!(keyword)(context); + let (remaining, affiliated_keywords) = many0(keyword_matcher)(input)?; + map(paragraph_matcher, Element::Paragraph)(remaining) +} pub fn non_paragraph_element<'r, 's>( context: Context<'r, 's>, input: &'s str, @@ -55,7 +63,8 @@ pub fn non_paragraph_element<'r, 's>( let fixed_width_area_matcher = parser_with_context!(fixed_width_area)(context); let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context); let keyword_matcher = parser_with_context!(keyword)(context); - alt(( + let (remaining, mut affiliated_keywords) = many0(keyword_matcher)(input)?; + let (remaining, element) = match alt(( map(plain_list_matcher, Element::PlainList), map(greater_block_matcher, Element::GreaterBlock), map(dynamic_block_matcher, Element::DynamicBlock), @@ -72,6 +81,13 @@ pub fn non_paragraph_element<'r, 's>( map(diary_sexp_matcher, Element::DiarySexp), map(fixed_width_area_matcher, Element::FixedWidthArea), map(horizontal_rule_matcher, Element::HorizontalRule), - map(keyword_matcher, Element::Keyword), - ))(input) + ))(remaining) + { + the_ok @ Ok(_) => the_ok, + Err(_) => { + affiliated_keywords.clear(); + map(keyword_matcher, Element::Keyword)(input) + } + }?; + Ok((remaining, element)) } From e97cf6630f18fefa7032af2e6b4cab481d848194 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 21 Apr 2023 23:54:54 -0400 Subject: [PATCH 02/14] Move consuming the trailing whitespace up to the element matchers. --- src/parser/clock.rs | 3 --- src/parser/comment.rs | 3 --- src/parser/diary_sexp.rs | 3 --- src/parser/drawer.rs | 2 -- src/parser/dynamic_block.rs | 3 --- src/parser/element_parser.rs | 17 ++++++++++++++++- src/parser/fixed_width_area.rs | 3 --- src/parser/footnote_definition.rs | 3 --- src/parser/greater_block.rs | 5 +---- src/parser/lesser_block.rs | 15 --------------- src/parser/paragraph.rs | 3 --- src/parser/plain_list.rs | 3 --- src/parser/table.rs | 2 -- 13 files changed, 17 insertions(+), 48 deletions(-) diff --git a/src/parser/clock.rs b/src/parser/clock.rs index d15e69a..3043c8b 100644 --- a/src/parser/clock.rs +++ b/src/parser/clock.rs @@ -31,9 +31,6 @@ pub fn clock<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, C parser_with_context!(inactive_timestamp)(context), ))(remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok((remaining, Clock { source })) } diff --git a/src/parser/comment.rs b/src/parser/comment.rs index 80d5651..9dd5328 100644 --- a/src/parser/comment.rs +++ b/src/parser/comment.rs @@ -38,9 +38,6 @@ pub fn comment<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, let (remaining, _remaining_lines) = many0(preceded(not(exit_matcher), comment_line_matcher))(remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok((remaining, Comment { source })) } diff --git a/src/parser/diary_sexp.rs b/src/parser/diary_sexp.rs index 3cf0c43..bb4abd7 100644 --- a/src/parser/diary_sexp.rs +++ b/src/parser/diary_sexp.rs @@ -24,9 +24,6 @@ pub fn diary_sexp<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s let (remaining, _trailing_whitespace) = recognize(tuple((space0, alt((line_ending, eof)))))(remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok((remaining, DiarySexp { source })) } diff --git a/src/parser/drawer.rs b/src/parser/drawer.rs index fa5db04..4e6765a 100644 --- a/src/parser/drawer.rs +++ b/src/parser/drawer.rs @@ -69,8 +69,6 @@ pub fn drawer<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, }; let (remaining, _end) = drawer_end(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; let source = get_consumed(input, remaining); Ok(( diff --git a/src/parser/dynamic_block.rs b/src/parser/dynamic_block.rs index 1cbe4b4..71a401d 100644 --- a/src/parser/dynamic_block.rs +++ b/src/parser/dynamic_block.rs @@ -74,9 +74,6 @@ pub fn dynamic_block<'r, 's>( }; let (remaining, _end) = dynamic_block_end(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 04b7466..7a09aff 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -16,6 +16,8 @@ use super::lesser_block::src_block; use super::lesser_block::verse_block; use super::paragraph::paragraph; use super::plain_list::plain_list; +use super::util::get_consumed; +use super::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::util::start_of_line; use super::Context; use crate::error::Res; @@ -40,7 +42,14 @@ pub fn paragraph_element<'r, 's>( let paragraph_matcher = parser_with_context!(paragraph)(context); let keyword_matcher = parser_with_context!(keyword)(context); let (remaining, affiliated_keywords) = many0(keyword_matcher)(input)?; - map(paragraph_matcher, Element::Paragraph)(remaining) + let (remaining, element) = map(paragraph_matcher, Element::Paragraph)(remaining)?; + + let (remaining, _trailing_ws) = + maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; + + let source = get_consumed(input, remaining); + + Ok((remaining, element)) } pub fn non_paragraph_element<'r, 's>( context: Context<'r, 's>, @@ -89,5 +98,11 @@ pub fn non_paragraph_element<'r, 's>( map(keyword_matcher, Element::Keyword)(input) } }?; + + let (remaining, _trailing_ws) = + maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; + + let source = get_consumed(input, remaining); + Ok((remaining, element)) } diff --git a/src/parser/fixed_width_area.rs b/src/parser/fixed_width_area.rs index 3a4f28c..ed8853e 100644 --- a/src/parser/fixed_width_area.rs +++ b/src/parser/fixed_width_area.rs @@ -31,9 +31,6 @@ pub fn fixed_width_area<'r, 's>( let (remaining, _remaining_lines) = many0(preceded(not(exit_matcher), fixed_width_area_line_matcher))(remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok((remaining, FixedWidthArea { source })) } diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index c401b40..faaad70 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -55,9 +55,6 @@ pub fn footnote_definition<'r, 's>( let (remaining, (children, _exit_contents)) = many_till(element_matcher, exit_matcher)(remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index 4a8f896..7727247 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -1,7 +1,7 @@ +use super::Context; use crate::error::CustomError; use crate::error::MyError; use crate::error::Res; -use super::Context; use crate::parser::element_parser::element; use crate::parser::exiting::ExitClass; use crate::parser::greater_element::GreaterBlock; @@ -87,9 +87,6 @@ pub fn greater_block<'r, 's>( // 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) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, diff --git a/src/parser/lesser_block.rs b/src/parser/lesser_block.rs index 7bbdacc..9844286 100644 --- a/src/parser/lesser_block.rs +++ b/src/parser/lesser_block.rs @@ -70,9 +70,6 @@ pub fn verse_block<'r, 's>( }; let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, @@ -111,9 +108,6 @@ pub fn comment_block<'r, 's>( })(remaining)?; let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, @@ -152,9 +146,6 @@ pub fn example_block<'r, 's>( })(remaining)?; let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, @@ -194,9 +185,6 @@ pub fn export_block<'r, 's>( })(remaining)?; let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, @@ -233,9 +221,6 @@ pub fn src_block<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st })(remaining)?; let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?; - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok(( remaining, diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index b722856..e1b30f4 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -39,9 +39,6 @@ pub fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st // Not checking parent exit matcher because if there are any children matched then we have a valid paragraph. - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok((remaining, Paragraph { source, children })) diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 9f15933..d5af25c 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -134,9 +134,6 @@ pub fn plain_list<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s )))); } - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); Ok((remaining, PlainList { source, children })) } diff --git a/src/parser/table.rs b/src/parser/table.rs index 0ac55f3..e8924ef 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -51,8 +51,6 @@ pub fn org_mode_table<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<& many_till(org_mode_table_row_matcher, exit_matcher)(input)?; // TODO: Consume trailing formulas - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; let source = get_consumed(input, remaining); Ok((remaining, Table { source, children })) From 0b989b53a65b2a30aadd0e4de31c7355b05f2edb Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 21 Apr 2023 23:55:18 -0400 Subject: [PATCH 03/14] Fix warnings. --- src/parser/clock.rs | 2 +- src/parser/comment.rs | 2 +- src/parser/diary_sexp.rs | 2 +- src/parser/drawer.rs | 2 +- src/parser/dynamic_block.rs | 2 +- src/parser/element_parser.rs | 8 ++++---- src/parser/fixed_width_area.rs | 2 +- src/parser/footnote_definition.rs | 2 +- src/parser/greater_block.rs | 2 +- src/parser/lesser_block.rs | 2 +- src/parser/paragraph.rs | 2 +- src/parser/plain_list.rs | 2 +- src/parser/table.rs | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/parser/clock.rs b/src/parser/clock.rs index 3043c8b..22d2e2c 100644 --- a/src/parser/clock.rs +++ b/src/parser/clock.rs @@ -15,7 +15,7 @@ use super::Context; use crate::error::Res; use crate::parser::parser_with_context::parser_with_context; use crate::parser::util::get_consumed; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::Clock; diff --git a/src/parser/comment.rs b/src/parser/comment.rs index 9dd5328..15a5abc 100644 --- a/src/parser/comment.rs +++ b/src/parser/comment.rs @@ -20,7 +20,7 @@ use crate::parser::parser_context::ContextElement; use crate::parser::parser_with_context::parser_with_context; use crate::parser::util::exit_matcher_parser; use crate::parser::util::immediate_in_section; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::Comment; diff --git a/src/parser/diary_sexp.rs b/src/parser/diary_sexp.rs index bb4abd7..856648b 100644 --- a/src/parser/diary_sexp.rs +++ b/src/parser/diary_sexp.rs @@ -10,7 +10,7 @@ use super::sexp::sexp; use super::Context; use crate::error::Res; use crate::parser::util::get_consumed; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::DiarySexp; diff --git a/src/parser/drawer.rs b/src/parser/drawer.rs index 4e6765a..e6e0fe0 100644 --- a/src/parser/drawer.rs +++ b/src/parser/drawer.rs @@ -23,7 +23,7 @@ use crate::parser::util::blank_line; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; use crate::parser::util::immediate_in_section; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::util::WORD_CONSTITUENT_CHARACTERS; use crate::parser::Drawer; diff --git a/src/parser/dynamic_block.rs b/src/parser/dynamic_block.rs index 71a401d..5d6e156 100644 --- a/src/parser/dynamic_block.rs +++ b/src/parser/dynamic_block.rs @@ -13,7 +13,7 @@ use crate::parser::util::blank_line; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; use crate::parser::util::immediate_in_section; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::Element; use nom::branch::alt; diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 7a09aff..35aa79d 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -18,7 +18,7 @@ use super::paragraph::paragraph; use super::plain_list::plain_list; use super::util::get_consumed; use super::util::maybe_consume_trailing_whitespace_if_not_exiting; -use super::util::start_of_line; + use super::Context; use crate::error::Res; use crate::parser::parser_with_context::parser_with_context; @@ -41,13 +41,13 @@ pub fn paragraph_element<'r, 's>( ) -> Res<&'s str, Element<'s>> { let paragraph_matcher = parser_with_context!(paragraph)(context); let keyword_matcher = parser_with_context!(keyword)(context); - let (remaining, affiliated_keywords) = many0(keyword_matcher)(input)?; + let (remaining, _affiliated_keywords) = many0(keyword_matcher)(input)?; let (remaining, element) = map(paragraph_matcher, Element::Paragraph)(remaining)?; let (remaining, _trailing_ws) = maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); + let _source = get_consumed(input, remaining); Ok((remaining, element)) } @@ -102,7 +102,7 @@ pub fn non_paragraph_element<'r, 's>( let (remaining, _trailing_ws) = maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let source = get_consumed(input, remaining); + let _source = get_consumed(input, remaining); Ok((remaining, element)) } diff --git a/src/parser/fixed_width_area.rs b/src/parser/fixed_width_area.rs index ed8853e..147ef87 100644 --- a/src/parser/fixed_width_area.rs +++ b/src/parser/fixed_width_area.rs @@ -16,7 +16,7 @@ use crate::error::Res; use crate::parser::parser_with_context::parser_with_context; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::FixedWidthArea; diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index faaad70..b4e5f29 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -14,7 +14,7 @@ use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; use crate::parser::util::immediate_in_section; use crate::parser::util::maybe_consume_trailing_whitespace; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use nom::branch::alt; use nom::bytes::complete::tag; diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index 7727247..7855a2c 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -12,7 +12,7 @@ use crate::parser::util::blank_line; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; use crate::parser::util::immediate_in_section; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::Element; use crate::parser::Paragraph; diff --git a/src/parser/lesser_block.rs b/src/parser/lesser_block.rs index 9844286..764a556 100644 --- a/src/parser/lesser_block.rs +++ b/src/parser/lesser_block.rs @@ -30,7 +30,7 @@ use crate::parser::plain_text::plain_text; use crate::parser::util::blank_line; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; #[tracing::instrument(ret, level = "debug")] diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index e1b30f4..94ccf75 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -13,7 +13,7 @@ use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ExitMatcherNode; use crate::parser::parser_with_context::parser_with_context; use crate::parser::util::exit_matcher_parser; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use super::element_parser::non_paragraph_element; diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index d5af25c..73c4c86 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -1,7 +1,7 @@ use super::greater_element::PlainList; use super::greater_element::PlainListItem; use super::parser_with_context::parser_with_context; -use super::util::maybe_consume_trailing_whitespace_if_not_exiting; + use super::util::non_whitespace_character; use super::Context; use crate::error::CustomError; diff --git a/src/parser/table.rs b/src/parser/table.rs index e8924ef..275e754 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -24,7 +24,7 @@ use crate::parser::parser_context::ExitMatcherNode; use crate::parser::parser_with_context::parser_with_context; use crate::parser::util::exit_matcher_parser; use crate::parser::util::get_consumed; -use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; + use crate::parser::util::start_of_line; use crate::parser::Table; From 7b7779ee7ead1fee2912ceed36f80e47709bffb3 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 00:09:14 -0400 Subject: [PATCH 04/14] Set the source using the full range of affiliated keywords to trailing whitespace. --- src/parser/element.rs | 29 +++++++++++++++++++++++++++++ src/parser/element_parser.rs | 11 +++++++---- src/parser/source.rs | 3 +++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/parser/element.rs b/src/parser/element.rs index f245744..233068e 100644 --- a/src/parser/element.rs +++ b/src/parser/element.rs @@ -17,6 +17,7 @@ use super::lesser_element::Paragraph; use super::lesser_element::Planning; use super::lesser_element::SrcBlock; use super::lesser_element::VerseBlock; +use super::source::SetSource; use super::source::Source; use super::Drawer; @@ -70,3 +71,31 @@ impl<'s> Source<'s> for Element<'s> { } } } + +impl<'s> SetSource<'s> for Element<'s> { + #[tracing::instrument(ret, level = "debug")] + fn set_source(&mut self, source: &'s str) { + match self { + Element::Paragraph(obj) => obj.source = source, + Element::PlainList(obj) => obj.source = source, + Element::GreaterBlock(obj) => obj.source = source, + Element::DynamicBlock(obj) => obj.source = source, + Element::FootnoteDefinition(obj) => obj.source = source, + Element::Comment(obj) => obj.source = source, + Element::Drawer(obj) => obj.source = source, + Element::PropertyDrawer(obj) => obj.source = source, + Element::Table(obj) => obj.source = source, + Element::VerseBlock(obj) => obj.source = source, + Element::CommentBlock(obj) => obj.source = source, + Element::ExampleBlock(obj) => obj.source = source, + Element::ExportBlock(obj) => obj.source = source, + Element::SrcBlock(obj) => obj.source = source, + Element::Clock(obj) => obj.source = source, + Element::DiarySexp(obj) => obj.source = source, + Element::Planning(obj) => obj.source = source, + Element::FixedWidthArea(obj) => obj.source = source, + Element::HorizontalRule(obj) => obj.source = source, + Element::Keyword(obj) => obj.source = source, + } + } +} diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 35aa79d..1f21cbb 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -16,6 +16,7 @@ use super::lesser_block::src_block; use super::lesser_block::verse_block; use super::paragraph::paragraph; use super::plain_list::plain_list; +use super::source::SetSource; use super::util::get_consumed; use super::util::maybe_consume_trailing_whitespace_if_not_exiting; @@ -42,12 +43,13 @@ pub fn paragraph_element<'r, 's>( let paragraph_matcher = parser_with_context!(paragraph)(context); let keyword_matcher = parser_with_context!(keyword)(context); let (remaining, _affiliated_keywords) = many0(keyword_matcher)(input)?; - let (remaining, element) = map(paragraph_matcher, Element::Paragraph)(remaining)?; + let (remaining, mut element) = map(paragraph_matcher, Element::Paragraph)(remaining)?; let (remaining, _trailing_ws) = maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let _source = get_consumed(input, remaining); + let source = get_consumed(input, remaining); + element.set_source(source); Ok((remaining, element)) } @@ -73,7 +75,7 @@ pub fn non_paragraph_element<'r, 's>( let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context); let keyword_matcher = parser_with_context!(keyword)(context); let (remaining, mut affiliated_keywords) = many0(keyword_matcher)(input)?; - let (remaining, element) = match alt(( + let (remaining, mut element) = match alt(( map(plain_list_matcher, Element::PlainList), map(greater_block_matcher, Element::GreaterBlock), map(dynamic_block_matcher, Element::DynamicBlock), @@ -102,7 +104,8 @@ pub fn non_paragraph_element<'r, 's>( let (remaining, _trailing_ws) = maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - let _source = get_consumed(input, remaining); + let source = get_consumed(input, remaining); + element.set_source(source); Ok((remaining, element)) } diff --git a/src/parser/source.rs b/src/parser/source.rs index c8e5417..5e0b8c4 100644 --- a/src/parser/source.rs +++ b/src/parser/source.rs @@ -1,3 +1,6 @@ pub trait Source<'s> { fn get_source(&'s self) -> &'s str; } +pub trait SetSource<'s> { + fn set_source(&mut self, source: &'s str); +} From 9b66929c14ee5219a95c94286edbb651f15f6029 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 00:14:41 -0400 Subject: [PATCH 05/14] Update test to use elements to capture the trailing whitespace. --- src/main.rs | 3 ++- src/parser/paragraph.rs | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0916f22..29423dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,8 @@ use crate::init_tracing::shutdown_telemetry; use ::organic::parser::document; mod init_tracing; -const TEST_DOC: &'static str = include_str!("../toy_language.txt"); +// const TEST_DOC: &'static str = include_str!("../toy_language.txt"); +const TEST_DOC: &'static str = "foo bar baz\n\nlorem ipsum"; fn main() -> Result<(), Box> { init_telemetry()?; diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index 94ccf75..c0deadb 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -57,9 +57,11 @@ fn paragraph_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st #[cfg(test)] mod tests { + use crate::parser::element_parser::paragraph_element; use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextTree; use crate::parser::parser_with_context::parser_with_context; + use crate::parser::source::Source; use super::*; @@ -69,12 +71,12 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let paragraph_matcher = parser_with_context!(paragraph)(&document_context); + let paragraph_matcher = parser_with_context!(paragraph_element)(&document_context); let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph"); let (remaining, second_paragraph) = paragraph_matcher(remaining).expect("Parse second paragraph."); assert_eq!(remaining, ""); - assert_eq!(first_paragraph.source, "foo bar baz\n\n"); - assert_eq!(second_paragraph.source, "lorem ipsum"); + assert_eq!(first_paragraph.get_source(), "foo bar baz\n\n"); + assert_eq!(second_paragraph.get_source(), "lorem ipsum"); } } From fbdf40fed0abfb14ba9a311028193486c615e942 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 00:19:01 -0400 Subject: [PATCH 06/14] Fix failing tests that were relying on the captured trailing whitespace. --- src/parser/footnote_definition.rs | 13 ++++++------- src/parser/plain_list.rs | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index b4e5f29..ffc4c52 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -110,6 +110,7 @@ mod tests { use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextTree; use crate::parser::parser_with_context::parser_with_context; + use crate::parser::Source; use super::*; @@ -123,21 +124,20 @@ line footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let footnote_definition_matcher = - parser_with_context!(footnote_definition)(&document_context); + let footnote_definition_matcher = parser_with_context!(element)(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); let (remaining, second_footnote_definition) = footnote_definition_matcher(remaining).expect("Parse second footnote_definition."); assert_eq!(remaining, ""); assert_eq!( - first_footnote_definition.source, + first_footnote_definition.get_source(), "[fn:1] A footnote. " ); assert_eq!( - second_footnote_definition.source, + second_footnote_definition.get_source(), "[fn:2] A multi- line footnote." @@ -155,13 +155,12 @@ not in the footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let footnote_definition_matcher = - parser_with_context!(footnote_definition)(&document_context); + let footnote_definition_matcher = parser_with_context!(element)(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); assert_eq!(remaining, "not in the footnote."); assert_eq!( - first_footnote_definition.source, + first_footnote_definition.get_source(), "[fn:2] A multi- line footnote. diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 73c4c86..4e5704f 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -370,7 +370,7 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(plain_list)(&document_context); + let plain_list_matcher = parser_with_context!(element)(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, " ipsum\n"); @@ -396,7 +396,7 @@ baz"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(plain_list)(&document_context); + let plain_list_matcher = parser_with_context!(element)(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "baz"); @@ -427,7 +427,7 @@ dolar"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(plain_list)(&document_context); + let plain_list_matcher = parser_with_context!(element)(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "dolar"); From fef58417136b6e86178220cd0376c6286f05f343 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 00:23:16 -0400 Subject: [PATCH 07/14] Identify a problem. --- build.rs | 1 - src/main.rs | 3 +-- src/parser/element_parser.rs | 3 +++ toy_language.txt | 9 ++++++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/build.rs b/build.rs index 012312e..615d8a7 100644 --- a/build.rs +++ b/build.rs @@ -72,7 +72,6 @@ fn is_expect_fail(name: &str) -> Option<&str> { match name { "drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."), "element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."), - "keyword_affiliated_keyword" => Some("Affiliated keywords would have to be implemented first."), _ => None, } } diff --git a/src/main.rs b/src/main.rs index 29423dc..0916f22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,7 @@ use crate::init_tracing::shutdown_telemetry; use ::organic::parser::document; mod init_tracing; -// const TEST_DOC: &'static str = include_str!("../toy_language.txt"); -const TEST_DOC: &'static str = "foo bar baz\n\nlorem ipsum"; +const TEST_DOC: &'static str = include_str!("../toy_language.txt"); fn main() -> Result<(), Box> { init_telemetry()?; diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 1f21cbb..7ae672b 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -36,6 +36,7 @@ pub fn element<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, alt((non_paragraph_matcher, paragraph_matcher))(input) } +#[tracing::instrument(ret, level = "debug")] pub fn paragraph_element<'r, 's>( context: Context<'r, 's>, input: &'s str, @@ -53,6 +54,8 @@ pub fn paragraph_element<'r, 's>( Ok((remaining, element)) } + +#[tracing::instrument(ret, level = "debug")] pub fn non_paragraph_element<'r, 's>( context: Context<'r, 's>, input: &'s str, diff --git a/toy_language.txt b/toy_language.txt index 7de30a5..2323b99 100644 --- a/toy_language.txt +++ b/toy_language.txt @@ -1 +1,8 @@ -%%(foo) +#+name: foo +#+caption: bar +#+caption: baz +[[file:lorem/ipsum.png]] + +#+name: cat +#+caption: dog +[[file:lorem/ipsum.png]] From 4ac6d89311513bb31db05eded048a0c7caf58356 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 00:55:31 -0400 Subject: [PATCH 08/14] Moving towards unifying into a single parameterized element matcher. This is to give paragraph priority over keyword in parsing so that affiliated keywords for paragraphs will be parsed as such. --- src/parser/document.rs | 4 +- src/parser/drawer.rs | 2 +- src/parser/dynamic_block.rs | 2 +- src/parser/element_parser.rs | 146 +++++++++++++----------------- src/parser/footnote_definition.rs | 6 +- src/parser/greater_block.rs | 2 +- src/parser/paragraph.rs | 7 +- src/parser/plain_list.rs | 11 ++- 8 files changed, 81 insertions(+), 99 deletions(-) diff --git a/src/parser/document.rs b/src/parser/document.rs index 9020903..6e202f5 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -124,7 +124,7 @@ fn zeroth_section<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s let without_consuming_whitespace_context = parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false)); - let element_matcher = parser_with_context!(element)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, comment_and_property_drawer_element) = opt(tuple(( @@ -166,7 +166,7 @@ fn section<'r, 's>(context: Context<'r, 's>, mut input: &'s str) -> Res<&'s str, class: ExitClass::Document, exit_matcher: §ion_end, })); - let element_matcher = parser_with_context!(element)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); // TODO: Match whatever a planning is. let (mut remaining, (planning_element, property_drawer_element)) = tuple(( diff --git a/src/parser/drawer.rs b/src/parser/drawer.rs index e6e0fe0..9c93a94 100644 --- a/src/parser/drawer.rs +++ b/src/parser/drawer.rs @@ -54,7 +54,7 @@ pub fn drawer<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, exit_matcher: &drawer_end, })); - let element_matcher = parser_with_context!(element)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( diff --git a/src/parser/dynamic_block.rs b/src/parser/dynamic_block.rs index 5d6e156..d523920 100644 --- a/src/parser/dynamic_block.rs +++ b/src/parser/dynamic_block.rs @@ -59,7 +59,7 @@ pub fn dynamic_block<'r, 's>( Some((_ws, parameters)) => Some(parameters), None => None, }; - let element_matcher = parser_with_context!(element)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 7ae672b..640ebcc 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -21,94 +21,76 @@ use super::util::get_consumed; use super::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::Context; +use crate::error::CustomError; +use crate::error::MyError; use crate::error::Res; use crate::parser::parser_with_context::parser_with_context; use crate::parser::table::org_mode_table; use nom::branch::alt; +use nom::combinator::cond; use nom::combinator::map; +use nom::combinator::verify; use nom::multi::many0; -#[tracing::instrument(ret, level = "debug")] -pub fn element<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, Element<'s>> { - let non_paragraph_matcher = parser_with_context!(non_paragraph_element)(context); - let paragraph_matcher = parser_with_context!(paragraph_element)(context); +pub fn element( + can_be_paragraph: bool, +) -> impl for<'r, 's> Fn(Context<'r, 's>, &'s str) -> Res<&'s str, Element<'s>> { + move |context: Context, input: &str| { + let plain_list_matcher = parser_with_context!(plain_list)(context); + let greater_block_matcher = parser_with_context!(greater_block)(context); + let dynamic_block_matcher = parser_with_context!(dynamic_block)(context); + let footnote_definition_matcher = parser_with_context!(footnote_definition)(context); + let comment_matcher = parser_with_context!(comment)(context); + let drawer_matcher = parser_with_context!(drawer)(context); + let table_matcher = parser_with_context!(org_mode_table)(context); + let verse_block_matcher = parser_with_context!(verse_block)(context); + let comment_block_matcher = parser_with_context!(comment_block)(context); + let example_block_matcher = parser_with_context!(example_block)(context); + let export_block_matcher = parser_with_context!(export_block)(context); + let src_block_matcher = parser_with_context!(src_block)(context); + let clock_matcher = parser_with_context!(clock)(context); + let diary_sexp_matcher = parser_with_context!(diary_sexp)(context); + let fixed_width_area_matcher = parser_with_context!(fixed_width_area)(context); + let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context); + let keyword_matcher = parser_with_context!(keyword)(context); + let paragraph_matcher = parser_with_context!(paragraph)(context); + let (remaining, mut affiliated_keywords) = many0(keyword_matcher)(input)?; + let (remaining, mut element) = match alt(( + map(plain_list_matcher, Element::PlainList), + map(greater_block_matcher, Element::GreaterBlock), + map(dynamic_block_matcher, Element::DynamicBlock), + map(footnote_definition_matcher, Element::FootnoteDefinition), + map(comment_matcher, Element::Comment), + map(drawer_matcher, Element::Drawer), + map(table_matcher, Element::Table), + map(verse_block_matcher, Element::VerseBlock), + map(comment_block_matcher, Element::CommentBlock), + map(example_block_matcher, Element::ExampleBlock), + map(export_block_matcher, Element::ExportBlock), + map(src_block_matcher, Element::SrcBlock), + map(clock_matcher, Element::Clock), + map(diary_sexp_matcher, Element::DiarySexp), + map(fixed_width_area_matcher, Element::FixedWidthArea), + map(horizontal_rule_matcher, Element::HorizontalRule), + map( + verify(paragraph_matcher, |_p| can_be_paragraph), + Element::Paragraph, + ), + ))(remaining) + { + the_ok @ Ok(_) => the_ok, + Err(_) => { + affiliated_keywords.clear(); + map(keyword_matcher, Element::Keyword)(input) + } + }?; - alt((non_paragraph_matcher, paragraph_matcher))(input) -} - -#[tracing::instrument(ret, level = "debug")] -pub fn paragraph_element<'r, 's>( - context: Context<'r, 's>, - input: &'s str, -) -> Res<&'s str, Element<'s>> { - let paragraph_matcher = parser_with_context!(paragraph)(context); - let keyword_matcher = parser_with_context!(keyword)(context); - let (remaining, _affiliated_keywords) = many0(keyword_matcher)(input)?; - let (remaining, mut element) = map(paragraph_matcher, Element::Paragraph)(remaining)?; - - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - - let source = get_consumed(input, remaining); - element.set_source(source); - - Ok((remaining, element)) -} - -#[tracing::instrument(ret, level = "debug")] -pub fn non_paragraph_element<'r, 's>( - context: Context<'r, 's>, - input: &'s str, -) -> Res<&'s str, Element<'s>> { - let plain_list_matcher = parser_with_context!(plain_list)(context); - let greater_block_matcher = parser_with_context!(greater_block)(context); - let dynamic_block_matcher = parser_with_context!(dynamic_block)(context); - let footnote_definition_matcher = parser_with_context!(footnote_definition)(context); - let comment_matcher = parser_with_context!(comment)(context); - let drawer_matcher = parser_with_context!(drawer)(context); - let table_matcher = parser_with_context!(org_mode_table)(context); - let verse_block_matcher = parser_with_context!(verse_block)(context); - let comment_block_matcher = parser_with_context!(comment_block)(context); - let example_block_matcher = parser_with_context!(example_block)(context); - let export_block_matcher = parser_with_context!(export_block)(context); - let src_block_matcher = parser_with_context!(src_block)(context); - let clock_matcher = parser_with_context!(clock)(context); - let diary_sexp_matcher = parser_with_context!(diary_sexp)(context); - let fixed_width_area_matcher = parser_with_context!(fixed_width_area)(context); - let horizontal_rule_matcher = parser_with_context!(horizontal_rule)(context); - let keyword_matcher = parser_with_context!(keyword)(context); - let (remaining, mut affiliated_keywords) = many0(keyword_matcher)(input)?; - let (remaining, mut element) = match alt(( - map(plain_list_matcher, Element::PlainList), - map(greater_block_matcher, Element::GreaterBlock), - map(dynamic_block_matcher, Element::DynamicBlock), - map(footnote_definition_matcher, Element::FootnoteDefinition), - map(comment_matcher, Element::Comment), - map(drawer_matcher, Element::Drawer), - map(table_matcher, Element::Table), - map(verse_block_matcher, Element::VerseBlock), - map(comment_block_matcher, Element::CommentBlock), - map(example_block_matcher, Element::ExampleBlock), - map(export_block_matcher, Element::ExportBlock), - map(src_block_matcher, Element::SrcBlock), - map(clock_matcher, Element::Clock), - map(diary_sexp_matcher, Element::DiarySexp), - map(fixed_width_area_matcher, Element::FixedWidthArea), - map(horizontal_rule_matcher, Element::HorizontalRule), - ))(remaining) - { - the_ok @ Ok(_) => the_ok, - Err(_) => { - affiliated_keywords.clear(); - map(keyword_matcher, Element::Keyword)(input) - } - }?; - - let (remaining, _trailing_ws) = - maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; - - let source = get_consumed(input, remaining); - element.set_source(source); - - Ok((remaining, element)) + let (remaining, _trailing_ws) = + maybe_consume_trailing_whitespace_if_not_exiting(context, remaining)?; + + let source = get_consumed(input, remaining); + element.set_source(source); + + Ok((remaining, element)) + } } diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index ffc4c52..00f1077 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -50,7 +50,7 @@ pub fn footnote_definition<'r, 's>( exit_matcher: &footnote_definition_end, })); // TODO: The problem is we are not accounting for trailing whitespace like we do in section. Maybe it would be easier if we passed down whether or not to parse trailing whitespace into the element matcher similar to how tag takes in parameters. - let element_matcher = parser_with_context!(element)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, (children, _exit_contents)) = many_till(element_matcher, exit_matcher)(remaining)?; @@ -124,7 +124,7 @@ line footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let footnote_definition_matcher = parser_with_context!(element)(&document_context); + let footnote_definition_matcher = parser_with_context!(element(true))(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); let (remaining, second_footnote_definition) = @@ -155,7 +155,7 @@ not in the footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let footnote_definition_matcher = parser_with_context!(element)(&document_context); + let footnote_definition_matcher = parser_with_context!(element(true))(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); assert_eq!(remaining, "not in the footnote."); diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index 7855a2c..8ca1fe1 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -69,7 +69,7 @@ pub fn greater_block<'r, 's>( None => None, }; - let element_matcher = parser_with_context!(element)(&parser_context); + 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 consumed(many_till(blank_line, exit_matcher))(remaining) { diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index c0deadb..1bf3c41 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -16,7 +16,6 @@ use crate::parser::util::exit_matcher_parser; use crate::parser::util::start_of_line; -use super::element_parser::non_paragraph_element; use super::lesser_element::Paragraph; use super::util::blank_line; use super::util::get_consumed; @@ -46,7 +45,7 @@ pub fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st #[tracing::instrument(ret, level = "debug")] fn paragraph_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { - let non_paragraph_element_matcher = parser_with_context!(non_paragraph_element)(context); + let non_paragraph_element_matcher = parser_with_context!(element(false))(context); let start_of_line_matcher = parser_with_context!(start_of_line)(&context); alt(( recognize(tuple((start_of_line_matcher, many1(blank_line)))), @@ -57,7 +56,7 @@ fn paragraph_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st #[cfg(test)] mod tests { - use crate::parser::element_parser::paragraph_element; + use crate::parser::element_parser::element; use crate::parser::parser_context::ContextElement; use crate::parser::parser_context::ContextTree; use crate::parser::parser_with_context::parser_with_context; @@ -71,7 +70,7 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let paragraph_matcher = parser_with_context!(paragraph_element)(&document_context); + let paragraph_matcher = parser_with_context!(element(true))(&document_context); let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph"); let (remaining, second_paragraph) = paragraph_matcher(remaining).expect("Parse second paragraph."); diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 4e5704f..436208d 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -161,8 +161,8 @@ pub fn plain_list_item<'r, 's>( exit_matcher: &plain_list_item_end, })); - let with_consume_matcher = parser_with_context!(element)(&with_consume_context); - let without_consume_matcher = parser_with_context!(element)(&without_consume_context); + let with_consume_matcher = parser_with_context!(element(true))(&with_consume_context); + let without_consume_matcher = parser_with_context!(element(true))(&without_consume_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&with_consume_context); let (remaining, bull) = verify(bullet, |bull: &str| bull != "*" || indent_level > 0)(remaining)?; @@ -370,7 +370,7 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(element)(&document_context); + let plain_list_matcher = parser_with_context!(element(true))(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, " ipsum\n"); @@ -396,7 +396,7 @@ baz"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(element)(&document_context); + let plain_list_matcher = parser_with_context!(element(true))(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "baz"); @@ -427,7 +427,8 @@ dolar"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(element)(&document_context); + let element_matcher = element(true); + let plain_list_matcher = parser_with_context!(element_matcher)(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "dolar"); From ba74bb58bbef43be47646441525399709d5559e1 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 01:08:45 -0400 Subject: [PATCH 09/14] Separate out calls to build element parser. --- src/parser/document.rs | 6 ++++-- src/parser/drawer.rs | 3 ++- src/parser/dynamic_block.rs | 3 ++- src/parser/footnote_definition.rs | 9 ++++++--- src/parser/greater_block.rs | 3 ++- src/parser/paragraph.rs | 7 +++++-- src/parser/plain_list.rs | 11 +++++++---- 7 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/parser/document.rs b/src/parser/document.rs index 6e202f5..26c844a 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -124,7 +124,8 @@ fn zeroth_section<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s let without_consuming_whitespace_context = parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false)); - let element_matcher = parser_with_context!(element(true))(&parser_context); + let element_matcher = element(true); + let element_matcher = parser_with_context!(element_matcher)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, comment_and_property_drawer_element) = opt(tuple(( @@ -166,7 +167,8 @@ fn section<'r, 's>(context: Context<'r, 's>, mut input: &'s str) -> Res<&'s str, class: ExitClass::Document, exit_matcher: §ion_end, })); - let element_matcher = parser_with_context!(element(true))(&parser_context); + let element_matcher = element(true); + let element_matcher = parser_with_context!(element_matcher)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); // TODO: Match whatever a planning is. let (mut remaining, (planning_element, property_drawer_element)) = tuple(( diff --git a/src/parser/drawer.rs b/src/parser/drawer.rs index 9c93a94..d0c7d7b 100644 --- a/src/parser/drawer.rs +++ b/src/parser/drawer.rs @@ -54,7 +54,8 @@ pub fn drawer<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, exit_matcher: &drawer_end, })); - let element_matcher = parser_with_context!(element(true))(&parser_context); + let element_matcher = element(true); + let element_matcher = parser_with_context!(element_matcher)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( diff --git a/src/parser/dynamic_block.rs b/src/parser/dynamic_block.rs index d523920..005cd0d 100644 --- a/src/parser/dynamic_block.rs +++ b/src/parser/dynamic_block.rs @@ -59,7 +59,8 @@ pub fn dynamic_block<'r, 's>( Some((_ws, parameters)) => Some(parameters), None => None, }; - let element_matcher = parser_with_context!(element(true))(&parser_context); + let element_matcher = element(true); + let element_matcher = parser_with_context!(element_matcher)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index 00f1077..89704b5 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -50,7 +50,8 @@ pub fn footnote_definition<'r, 's>( exit_matcher: &footnote_definition_end, })); // TODO: The problem is we are not accounting for trailing whitespace like we do in section. Maybe it would be easier if we passed down whether or not to parse trailing whitespace into the element matcher similar to how tag takes in parameters. - let element_matcher = parser_with_context!(element(true))(&parser_context); + let element_matcher = element(true); + let element_matcher = parser_with_context!(element_matcher)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, (children, _exit_contents)) = many_till(element_matcher, exit_matcher)(remaining)?; @@ -124,7 +125,8 @@ line footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let footnote_definition_matcher = parser_with_context!(element(true))(&document_context); + let element_matcher = element(true); + let footnote_definition_matcher = parser_with_context!(element_matcher)(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); let (remaining, second_footnote_definition) = @@ -155,7 +157,8 @@ not in the footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let footnote_definition_matcher = parser_with_context!(element(true))(&document_context); + let element_matcher = element(true); + let footnote_definition_matcher = parser_with_context!(element_matcher)(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); assert_eq!(remaining, "not in the footnote."); diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index 8ca1fe1..1878915 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -69,7 +69,8 @@ pub fn greater_block<'r, 's>( None => None, }; - let element_matcher = parser_with_context!(element(true))(&parser_context); + let element_matcher = element(true); + let element_matcher = parser_with_context!(element_matcher)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); // Check for a completely empty block let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index 1bf3c41..55947ed 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -1,4 +1,5 @@ use crate::error::Res; +use crate::parser::element_parser::element; use nom::branch::alt; use nom::combinator::eof; use nom::combinator::recognize; @@ -45,7 +46,8 @@ pub fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st #[tracing::instrument(ret, level = "debug")] fn paragraph_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { - let non_paragraph_element_matcher = parser_with_context!(element(false))(context); + let element_matcher = element(false); + let non_paragraph_element_matcher = parser_with_context!(element_matcher)(context); let start_of_line_matcher = parser_with_context!(start_of_line)(&context); alt(( recognize(tuple((start_of_line_matcher, many1(blank_line)))), @@ -70,7 +72,8 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let paragraph_matcher = parser_with_context!(element(true))(&document_context); + let element_matcher = element(true); + let paragraph_matcher = parser_with_context!(element_matcher)(&document_context); let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph"); let (remaining, second_paragraph) = paragraph_matcher(remaining).expect("Parse second paragraph."); diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 436208d..484020c 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -161,8 +161,9 @@ pub fn plain_list_item<'r, 's>( exit_matcher: &plain_list_item_end, })); - let with_consume_matcher = parser_with_context!(element(true))(&with_consume_context); - let without_consume_matcher = parser_with_context!(element(true))(&without_consume_context); + let element_matcher = element(true); + let with_consume_matcher = parser_with_context!(element_matcher)(&with_consume_context); + let without_consume_matcher = parser_with_context!(element_matcher)(&without_consume_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&with_consume_context); let (remaining, bull) = verify(bullet, |bull: &str| bull != "*" || indent_level > 0)(remaining)?; @@ -370,7 +371,8 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(element(true))(&document_context); + let element_matcher = element(true); + let plain_list_matcher = parser_with_context!(element_matcher)(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, " ipsum\n"); @@ -396,7 +398,8 @@ baz"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let plain_list_matcher = parser_with_context!(element(true))(&document_context); + let element_matcher = element(true); + let plain_list_matcher = parser_with_context!(element_matcher)(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "baz"); From 785502092738c3f68585bd154a303074f82f2c4e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 01:13:05 -0400 Subject: [PATCH 10/14] Fix some errors. --- src/parser/element_parser.rs | 3 --- src/parser/plain_list.rs | 9 +++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 640ebcc..03a26d3 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -21,13 +21,10 @@ use super::util::get_consumed; use super::util::maybe_consume_trailing_whitespace_if_not_exiting; use super::Context; -use crate::error::CustomError; -use crate::error::MyError; use crate::error::Res; use crate::parser::parser_with_context::parser_with_context; use crate::parser::table::org_mode_table; use nom::branch::alt; -use nom::combinator::cond; use nom::combinator::map; use nom::combinator::verify; use nom::multi::many0; diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 484020c..5c15235 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -162,6 +162,7 @@ pub fn plain_list_item<'r, 's>( })); let element_matcher = element(true); + let element_matcher = &element_matcher; let with_consume_matcher = parser_with_context!(element_matcher)(&with_consume_context); let without_consume_matcher = parser_with_context!(element_matcher)(&without_consume_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&with_consume_context); @@ -185,12 +186,12 @@ pub fn plain_list_item<'r, 's>( Err(_) => { let (remaining, _ws) = space1(remaining)?; let (remaining, (mut contents, final_element)) = many_till( - with_consume_matcher, + &with_consume_matcher, alt(( - terminated(without_consume_matcher, exit_matcher), + terminated(&without_consume_matcher, exit_matcher), preceded( - peek(tuple((with_consume_matcher, exit_matcher))), - without_consume_matcher, + peek(tuple((&with_consume_matcher, exit_matcher))), + &without_consume_matcher, ), )), )(remaining)?; From af90ea6dfd4c32d6d9ce0e95e405f8aab9cb28e2 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 01:34:34 -0400 Subject: [PATCH 11/14] Fix infinite loop by only checking paragraph matcher when boolean is true. Before I was checking afterwards with a verify, which was causing an infinite loop. --- src/parser/element_parser.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 03a26d3..3ddc1f5 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -69,16 +69,22 @@ pub fn element( map(diary_sexp_matcher, Element::DiarySexp), map(fixed_width_area_matcher, Element::FixedWidthArea), map(horizontal_rule_matcher, Element::HorizontalRule), - map( - verify(paragraph_matcher, |_p| can_be_paragraph), - Element::Paragraph, - ), ))(remaining) { the_ok @ Ok(_) => the_ok, Err(_) => { - affiliated_keywords.clear(); - map(keyword_matcher, Element::Keyword)(input) + if can_be_paragraph { + match map(paragraph_matcher, Element::Paragraph)(remaining) { + the_ok @ Ok(_) => the_ok, + Err(_) => { + affiliated_keywords.clear(); + map(keyword_matcher, Element::Keyword)(input) + } + } + } else { + affiliated_keywords.clear(); + map(keyword_matcher, Element::Keyword)(input) + } } }?; From 92ee59558bdad92d74ce8ac463e5bdb79c990ee3 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 01:36:43 -0400 Subject: [PATCH 12/14] Remove unused import. --- src/parser/element_parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/element_parser.rs b/src/parser/element_parser.rs index 3ddc1f5..e435dae 100644 --- a/src/parser/element_parser.rs +++ b/src/parser/element_parser.rs @@ -26,7 +26,7 @@ use crate::parser::parser_with_context::parser_with_context; use crate::parser::table::org_mode_table; use nom::branch::alt; use nom::combinator::map; -use nom::combinator::verify; + use nom::multi::many0; pub fn element( From 9861084afe6c8edc115a83f1add75c563fae5631 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 01:45:38 -0400 Subject: [PATCH 13/14] Cleanup. --- src/parser/document.rs | 6 ++---- src/parser/drawer.rs | 3 +-- src/parser/dynamic_block.rs | 3 +-- src/parser/footnote_definition.rs | 9 +++------ src/parser/greater_block.rs | 3 +-- src/parser/paragraph.rs | 8 ++------ src/parser/parser_with_context.rs | 2 +- src/parser/plain_list.rs | 15 +++++---------- 8 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/parser/document.rs b/src/parser/document.rs index 26c844a..6e202f5 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -124,8 +124,7 @@ fn zeroth_section<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s s let without_consuming_whitespace_context = parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false)); - let element_matcher = element(true); - let element_matcher = parser_with_context!(element_matcher)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, comment_and_property_drawer_element) = opt(tuple(( @@ -167,8 +166,7 @@ fn section<'r, 's>(context: Context<'r, 's>, mut input: &'s str) -> Res<&'s str, class: ExitClass::Document, exit_matcher: §ion_end, })); - let element_matcher = element(true); - let element_matcher = parser_with_context!(element_matcher)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); // TODO: Match whatever a planning is. let (mut remaining, (planning_element, property_drawer_element)) = tuple(( diff --git a/src/parser/drawer.rs b/src/parser/drawer.rs index d0c7d7b..9c93a94 100644 --- a/src/parser/drawer.rs +++ b/src/parser/drawer.rs @@ -54,8 +54,7 @@ pub fn drawer<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, exit_matcher: &drawer_end, })); - let element_matcher = element(true); - let element_matcher = parser_with_context!(element_matcher)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( diff --git a/src/parser/dynamic_block.rs b/src/parser/dynamic_block.rs index 005cd0d..d523920 100644 --- a/src/parser/dynamic_block.rs +++ b/src/parser/dynamic_block.rs @@ -59,8 +59,7 @@ pub fn dynamic_block<'r, 's>( Some((_ws, parameters)) => Some(parameters), None => None, }; - let element_matcher = element(true); - let element_matcher = parser_with_context!(element_matcher)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, children) = match consumed(many_till(blank_line, exit_matcher))(remaining) { Ok((remaining, (whitespace, (_children, _exit_contents)))) => ( diff --git a/src/parser/footnote_definition.rs b/src/parser/footnote_definition.rs index 89704b5..00f1077 100644 --- a/src/parser/footnote_definition.rs +++ b/src/parser/footnote_definition.rs @@ -50,8 +50,7 @@ pub fn footnote_definition<'r, 's>( exit_matcher: &footnote_definition_end, })); // TODO: The problem is we are not accounting for trailing whitespace like we do in section. Maybe it would be easier if we passed down whether or not to parse trailing whitespace into the element matcher similar to how tag takes in parameters. - let element_matcher = element(true); - let element_matcher = parser_with_context!(element_matcher)(&parser_context); + let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); let (remaining, (children, _exit_contents)) = many_till(element_matcher, exit_matcher)(remaining)?; @@ -125,8 +124,7 @@ line footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let element_matcher = element(true); - let footnote_definition_matcher = parser_with_context!(element_matcher)(&document_context); + let footnote_definition_matcher = parser_with_context!(element(true))(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); let (remaining, second_footnote_definition) = @@ -157,8 +155,7 @@ not in the footnote."; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let element_matcher = element(true); - let footnote_definition_matcher = parser_with_context!(element_matcher)(&document_context); + let footnote_definition_matcher = parser_with_context!(element(true))(&document_context); let (remaining, first_footnote_definition) = footnote_definition_matcher(input).expect("Parse first footnote_definition"); assert_eq!(remaining, "not in the footnote."); diff --git a/src/parser/greater_block.rs b/src/parser/greater_block.rs index 1878915..8ca1fe1 100644 --- a/src/parser/greater_block.rs +++ b/src/parser/greater_block.rs @@ -69,8 +69,7 @@ pub fn greater_block<'r, 's>( None => None, }; - let element_matcher = element(true); - let element_matcher = parser_with_context!(element_matcher)(&parser_context); + 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 consumed(many_till(blank_line, exit_matcher))(remaining) { diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index 55947ed..ba9c557 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -46,8 +46,7 @@ pub fn paragraph<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s st #[tracing::instrument(ret, level = "debug")] fn paragraph_end<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { - let element_matcher = element(false); - let non_paragraph_element_matcher = parser_with_context!(element_matcher)(context); + let non_paragraph_element_matcher = parser_with_context!(element(false))(context); let start_of_line_matcher = parser_with_context!(start_of_line)(&context); alt(( recognize(tuple((start_of_line_matcher, many1(blank_line)))), @@ -64,16 +63,13 @@ mod tests { use crate::parser::parser_with_context::parser_with_context; use crate::parser::source::Source; - use super::*; - #[test] fn two_paragraphs() { let input = "foo bar baz\n\nlorem ipsum"; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let element_matcher = element(true); - let paragraph_matcher = parser_with_context!(element_matcher)(&document_context); + let paragraph_matcher = parser_with_context!(element(true))(&document_context); let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph"); let (remaining, second_paragraph) = paragraph_matcher(remaining).expect("Parse second paragraph."); diff --git a/src/parser/parser_with_context.rs b/src/parser/parser_with_context.rs index e5d6086..6705d47 100644 --- a/src/parser/parser_with_context.rs +++ b/src/parser/parser_with_context.rs @@ -1,5 +1,5 @@ macro_rules! parser_with_context { - ($target:ident) => { + ($target:expr) => { move |context| move |i| $target(context, i) }; } diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index 5c15235..d84b04a 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -161,10 +161,8 @@ pub fn plain_list_item<'r, 's>( exit_matcher: &plain_list_item_end, })); - let element_matcher = element(true); - let element_matcher = &element_matcher; - let with_consume_matcher = parser_with_context!(element_matcher)(&with_consume_context); - let without_consume_matcher = parser_with_context!(element_matcher)(&without_consume_context); + let with_consume_matcher = parser_with_context!(element(true))(&with_consume_context); + let without_consume_matcher = parser_with_context!(element(true))(&without_consume_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&with_consume_context); let (remaining, bull) = verify(bullet, |bull: &str| bull != "*" || indent_level > 0)(remaining)?; @@ -372,8 +370,7 @@ mod tests { let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let element_matcher = element(true); - let plain_list_matcher = parser_with_context!(element_matcher)(&document_context); + let plain_list_matcher = parser_with_context!(element(true))(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, " ipsum\n"); @@ -399,8 +396,7 @@ baz"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let element_matcher = element(true); - let plain_list_matcher = parser_with_context!(element_matcher)(&document_context); + let plain_list_matcher = parser_with_context!(element(true))(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "baz"); @@ -431,8 +427,7 @@ dolar"#; let initial_context: ContextTree<'_, '_> = ContextTree::new(); let document_context = initial_context.with_additional_node(ContextElement::DocumentRoot(input)); - let element_matcher = element(true); - let plain_list_matcher = parser_with_context!(element_matcher)(&document_context); + let plain_list_matcher = parser_with_context!(element(true))(&document_context); let (remaining, result) = plain_list_matcher(input).expect("Should parse the plain list successfully."); assert_eq!(remaining, "dolar"); From fee9166741d3beda82afcd233b04d63464a728fe Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 22 Apr 2023 01:45:54 -0400 Subject: [PATCH 14/14] Remove a TODO. --- src/parser/document.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parser/document.rs b/src/parser/document.rs index 6e202f5..853db11 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -168,7 +168,6 @@ fn section<'r, 's>(context: Context<'r, 's>, mut input: &'s str) -> Res<&'s str, })); let element_matcher = parser_with_context!(element(true))(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); - // TODO: Match whatever a planning is. let (mut remaining, (planning_element, property_drawer_element)) = tuple(( opt(parser_with_context!(planning)(&parser_context)), opt(parser_with_context!(property_drawer)(&parser_context)),