From 9d534aa627afa8f6c6c2f3818d6e38a1351d3f69 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 15 Oct 2022 14:16:52 -0400 Subject: [PATCH] Add paragraph parser. --- src/parser/nom_context.rs | 12 ++++++------ src/parser/parser_with_context.rs | 2 +- src/parser/text.rs | 5 +++-- src/parser/text_element_parser.rs | 13 +++++++++---- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/parser/nom_context.rs b/src/parser/nom_context.rs index 94fa26a2..52c86d59 100644 --- a/src/parser/nom_context.rs +++ b/src/parser/nom_context.rs @@ -9,10 +9,10 @@ use nom::Parser; type MatcherRef = Rc IResult<&str, &str, VerboseError<&str>>>>; -struct FailChecker<'a>(&'a NomContext<'a>); +struct FailChecker<'r>(&'r NomContext<'r>); -impl<'a> FailChecker<'a> { - fn new(func: &'a NomContext<'a>) -> Self { +impl<'r> FailChecker<'r> { + fn new(func: &'r NomContext<'r>) -> Self { Self(func) } } @@ -22,15 +22,15 @@ enum ChainBehavior { IgnoreParent(Option), } -pub struct NomContext<'a> { - parent: Option<&'a Self>, +pub struct NomContext<'r> { + parent: Option<&'r Self>, fail_matcher: ChainBehavior, /// You can't have nested bolds or links in org-mode can_match_bold: bool, can_match_link: bool, } -impl<'a> NomContext<'a> { +impl<'r> NomContext<'r> { pub fn new(fail_matcher: MatcherRef) -> Self { NomContext { parent: None, diff --git a/src/parser/parser_with_context.rs b/src/parser/parser_with_context.rs index bb4a1059..9b6063f2 100644 --- a/src/parser/parser_with_context.rs +++ b/src/parser/parser_with_context.rs @@ -1,6 +1,6 @@ macro_rules! parser_with_context { ($target:ident) => { - move |mut context| move |i| $target(i, &mut context) + move |context| move |i| $target(i, context) }; } pub(crate) use parser_with_context; diff --git a/src/parser/text.rs b/src/parser/text.rs index a15cccdf..fb9d7edb 100644 --- a/src/parser/text.rs +++ b/src/parser/text.rs @@ -28,6 +28,7 @@ use nom::IResult; use super::nom_context::NomContext; use super::parser_with_context::parser_with_context; +use super::text_element_parser::paragraph; pub type Res = IResult>; @@ -137,6 +138,6 @@ pub fn paragraph_end(input: &str) -> Res<&str, &str> { pub fn document(input: &str) -> Res<&str, Vec<(Vec, &str)>> { let initial_context = NomContext::new(Rc::new(RefCell::new(paragraph_end))); - todo!() - // many1(parser_with_context!(paragraph)(initial_context))(input) + let ret = many1(parser_with_context!(paragraph)(&initial_context))(input); + ret } diff --git a/src/parser/text_element_parser.rs b/src/parser/text_element_parser.rs index d31ab201..23765261 100644 --- a/src/parser/text_element_parser.rs +++ b/src/parser/text_element_parser.rs @@ -21,10 +21,7 @@ use nom::multi::many_till; use nom::sequence::tuple; use nom::IResult; -fn flat_text_element<'s, 'r>( - i: &'s str, - context: &'r mut NomContext, -) -> Res<&'s str, TextElement<'s>> { +fn flat_text_element<'s, 'r>(i: &'s str, context: &'r NomContext) -> Res<&'s str, TextElement<'s>> { context.not_matching_fail(i)?; alt(( @@ -36,3 +33,11 @@ fn flat_text_element<'s, 'r>( map(line_break, TextElement::LineBreak), ))(i) } + +pub fn paragraph<'s, 'r>( + i: &'s str, + context: &'r NomContext, +) -> Res<&'s str, (Vec>, &'s str)> { + let text_element_parser = parser_with_context!(flat_text_element)(context); + many_till(text_element_parser, paragraph_end)(i) +}