diff --git a/src/parser/nom_context.rs b/src/parser/nom_context.rs index 7c61641..7b302af 100644 --- a/src/parser/nom_context.rs +++ b/src/parser/nom_context.rs @@ -19,6 +19,7 @@ where impl NomContext where F: for<'a> FnMut(&'a str) -> IResult<&'a str, &'a str, VerboseError<&'a str>>, + F: Clone, { pub fn new(fail_matcher: F) -> Self { NomContext { @@ -27,4 +28,12 @@ where can_match_link: true, } } + + pub fn without_bold(&self) -> Self { + NomContext { + fail_matcher: self.fail_matcher.clone(), + can_match_bold: true, + can_match_link: true, + } + } } diff --git a/src/parser/text_element_parser.rs b/src/parser/text_element_parser.rs index 3d2bf2b..e2c4540 100644 --- a/src/parser/text_element_parser.rs +++ b/src/parser/text_element_parser.rs @@ -3,17 +3,22 @@ use crate::parser::parser_with_context::parser_with_context; use crate::parser::text::paragraph_end; use super::nom_context::NomContext; +use super::text::bold_end; +use super::text::bold_start; use super::text::line_break; use super::text::space; use super::text::span; use super::text::symbol; +use super::text::Bold; use super::text::Res; use super::text::TextElement; use nom::branch::alt; use nom::combinator::map; use nom::combinator::not; +use nom::combinator::recognize; use nom::error::VerboseError; use nom::multi::many_till; +use nom::sequence::tuple; use nom::IResult; pub fn flat_text_element<'a, F>( @@ -24,6 +29,12 @@ where F: for<'b> FnMut(&'b str) -> IResult<&'b str, &'b str, VerboseError<&'b str>>, { not(&mut context.fail_matcher)(i)?; + if context.can_match_bold { + // todo + } + if context.can_match_link { + // todo + } alt(( // map( // BoldParser::new(slf.context.fail_matcher.clone()), @@ -42,6 +53,24 @@ where ))(i) } +pub fn flat_bold<'a, F>(i: &'a str, context: &mut NomContext) -> Res<&'a str, TextElement<'a>> +where + F: for<'b> FnMut(&'b str) -> IResult<&'b str, &'b str, VerboseError<&'b str>>, + F: Clone, +{ + not(&mut context.fail_matcher)(i)?; + let new_context = context.without_bold(); + let text_element_parser = parser_with_context!(flat_text_element)(new_context); + map( + recognize(tuple(( + bold_start, + many_till(text_element_parser, bold_end), + bold_end, + ))), + |body| TextElement::Bold(Bold { contents: body }), + )(i) +} + pub fn paragraph(input: &str) -> Res<&str, (Vec, &str)> { let initial_context = NomContext::new(¶graph_end); let text_element_parser = parser_with_context!(flat_text_element)(initial_context);