Pass context into fail matchers.
This commit is contained in:
		
							parent
							
								
									23e567ca93
								
							
						
					
					
						commit
						b27be8eab1
					
				| @ -8,8 +8,12 @@ use nom::IResult; | ||||
| use super::list::List; | ||||
| use super::list::Node; | ||||
| use super::token::Token; | ||||
| use super::Context; | ||||
| 
 | ||||
| type Matcher = dyn for<'s> Fn(&'s str) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; | ||||
| type Matcher = dyn for<'r, 's> Fn( | ||||
|     Context<'r, 's>, | ||||
|     &'s str, | ||||
| ) -> IResult<&'s str, &'s str, VerboseError<&'s str>>; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct ContextTree<'r, 's> { | ||||
| @ -39,10 +43,10 @@ impl<'r, 's> ContextTree<'r, 's> { | ||||
|         self.tree.iter() | ||||
|     } | ||||
| 
 | ||||
|     pub fn check_fail_matcher<'b>( | ||||
|     pub fn check_fail_matcher( | ||||
|         &'r self, | ||||
|         i: &'b str, | ||||
|     ) -> IResult<&'b str, &'b str, VerboseError<&'b str>> { | ||||
|         i: &'s str, | ||||
|     ) -> IResult<&'s str, &'s str, VerboseError<&'s str>> { | ||||
|         // TODO: Can I do this without incrementing reference counters? Perhaps via implementing an iterator over the list?
 | ||||
|         let mut current_node = self.tree.clone(); | ||||
|         while !current_node.is_empty() { | ||||
| @ -53,14 +57,14 @@ impl<'r, 's> ContextTree<'r, 's> { | ||||
|                 ContextElement::FailMatcherNode(fail_matcher) => { | ||||
|                     match fail_matcher.fail_matcher { | ||||
|                         ChainBehavior::AndParent(Some(matcher)) => { | ||||
|                             let local_result = matcher(i); | ||||
|                             let local_result = matcher(self, i); | ||||
|                             if local_result.is_ok() { | ||||
|                                 return local_result; | ||||
|                             } | ||||
|                         } | ||||
|                         ChainBehavior::AndParent(None) => {} | ||||
|                         ChainBehavior::IgnoreParent(Some(matcher)) => { | ||||
|                             let local_result = matcher(i); | ||||
|                             let local_result = matcher(self, i); | ||||
|                             if local_result.is_ok() { | ||||
|                                 return local_result; | ||||
|                             } | ||||
|  | ||||
| @ -127,7 +127,7 @@ fn can_start_bold<'s, 'r>(context: Context<'r, 's>) -> bool { | ||||
|     loop { | ||||
|         if let Some((i, ctx)) = context_iterator.next() { | ||||
|             match ctx.get_data() { | ||||
|                 ContextElement::FailMatcherNode(_) => {}, | ||||
|                 ContextElement::FailMatcherNode(_) => {} | ||||
|                 ContextElement::PreviousElementNode(previous_element_node) => { | ||||
|                     match &previous_element_node.element { | ||||
|                         Token::TextElement(text_element) => { | ||||
| @ -139,12 +139,12 @@ fn can_start_bold<'s, 'r>(context: Context<'r, 's>) -> bool { | ||||
|                                 TextElement::Bold(_) => return false, | ||||
|                                 TextElement::Link(_) => return false, | ||||
|                             }; | ||||
|                         }, | ||||
|                         } | ||||
|                     }; | ||||
|                 }, | ||||
|                 } | ||||
|                 ContextElement::StartOfParagraph => { | ||||
|                     return true; | ||||
|                 }, | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             break; | ||||
| @ -173,7 +173,7 @@ pub fn context_bold_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res | ||||
|         tag(" "), | ||||
|         tag("\t"), | ||||
|         tag("\n"), | ||||
|         |i| context.check_fail_matcher(i) | ||||
|         |i| context.check_fail_matcher(i), | ||||
|     )))(remaining)?; | ||||
| 
 | ||||
|     Ok((remaining, actual_match)) | ||||
| @ -188,7 +188,7 @@ pub fn paragraph<'s, 'r>( | ||||
|     let paragraph_context = context | ||||
|         .with_additional_node(ContextElement::StartOfParagraph) | ||||
|         .with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { | ||||
|             fail_matcher: ChainBehavior::AndParent(Some(¶graph_end)), | ||||
|             fail_matcher: ChainBehavior::AndParent(Some(&context_paragraph_end)), | ||||
|         })); | ||||
|     let (remaining, (many, till)) = | ||||
|         context_many_till(¶graph_context, flat_text_element, context_paragraph_end)(i)?; | ||||
| @ -222,13 +222,12 @@ fn flat_text_element<'s, 'r>( | ||||
|     ))(i) | ||||
| } | ||||
| 
 | ||||
| fn recognize_bold_end(input: &str) -> Res<&str, &str> { | ||||
| fn recognize_bold_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     recognize(bold_end)(input) | ||||
| } | ||||
| 
 | ||||
| fn flat_bold<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Bold<'s>> { | ||||
|     let bold_start = parser_with_context!(context_bold_start)(&context); | ||||
|     // TODO: I need to make the fail matchers take in context so I can use context_bold_end. Otherwise this is ending bolds early just because it hits an asterisk.
 | ||||
|     let nom_context = | ||||
|         context.with_additional_node(ContextElement::FailMatcherNode(FailMatcherNode { | ||||
|             fail_matcher: ChainBehavior::AndParent(Some(&recognize_bold_end)), | ||||
| @ -240,7 +239,7 @@ fn flat_bold<'s, 'r>(context: Context<'r, 's>, i: &'s str) -> Res<&'s str, Bold< | ||||
|     Ok((remaining, ret)) | ||||
| } | ||||
| 
 | ||||
| fn recognize_link_end(input: &str) -> Res<&str, &str> { | ||||
| fn recognize_link_end<'s, 'r>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, &'s str> { | ||||
|     recognize(link_end)(input) | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander