Implement check_exit_matcher.
This commit is contained in:
		
							parent
							
								
									8502a8830d
								
							
						
					
					
						commit
						15e8d1ab77
					
				| @ -1,10 +1,13 @@ | ||||
| use nom::combinator::eof; | ||||
| use nom::IResult; | ||||
| 
 | ||||
| use super::exiting::ExitClass; | ||||
| use super::global_settings::GlobalSettings; | ||||
| use super::list::List; | ||||
| use super::DynContextMatcher; | ||||
| use super::RefContext; | ||||
| use crate::error::CustomError; | ||||
| use crate::error::MyError; | ||||
| use crate::error::Res; | ||||
| use crate::parser::OrgSource; | ||||
| use crate::types::Object; | ||||
| @ -169,6 +172,56 @@ impl<'r, 's> Context<'r, 's> { | ||||
|             tree: parent_tree.clone(), | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_data(&self) -> &ContextElement<'r, 's> { | ||||
|         self.tree.get_data() | ||||
|     } | ||||
| 
 | ||||
|     #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
|     pub fn check_exit_matcher( | ||||
|         &'r self, | ||||
|         i: OrgSource<'s>, | ||||
|     ) -> IResult<OrgSource<'s>, OrgSource<'s>, CustomError<OrgSource<'s>>> { | ||||
|         let mut current_class_filter = ExitClass::Gamma; | ||||
|         for current_node in self.iter_context() { | ||||
|             let context_element = current_node.get_data(); | ||||
|             match context_element { | ||||
|                 ContextElement::ExitMatcherNode(exit_matcher) => { | ||||
|                     if exit_matcher.class as u32 <= current_class_filter as u32 { | ||||
|                         current_class_filter = exit_matcher.class; | ||||
|                         let local_result = (exit_matcher.exit_matcher)(¤t_node, i); | ||||
|                         if local_result.is_ok() { | ||||
|                             return local_result; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 _ => {} | ||||
|             }; | ||||
|         } | ||||
|         // TODO: Make this a specific error instead of just a generic MyError
 | ||||
|         return Err(nom::Err::Error(CustomError::MyError(MyError( | ||||
|             "NoExit".into(), | ||||
|         )))); | ||||
|     } | ||||
| 
 | ||||
|     /// Indicates if elements should consume the whitespace after them.
 | ||||
|     ///
 | ||||
|     /// Defaults to true.
 | ||||
|     pub fn should_consume_trailing_whitespace(&self) -> bool { | ||||
|         self._should_consume_trailing_whitespace().unwrap_or(true) | ||||
|     } | ||||
| 
 | ||||
|     fn _should_consume_trailing_whitespace(&self) -> Option<bool> { | ||||
|         for current_node in self.iter() { | ||||
|             match current_node { | ||||
|                 ContextElement::ConsumeTrailingWhitespace(should) => { | ||||
|                     return Some(*should); | ||||
|                 } | ||||
|                 _ => {} | ||||
|             } | ||||
|         } | ||||
|         None | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
|  | ||||
| @ -17,8 +17,6 @@ use nom::multi::many_till; | ||||
| use nom::multi::separated_list1; | ||||
| use nom::sequence::tuple; | ||||
| 
 | ||||
| use super::element::Element; | ||||
| use super::object::Object; | ||||
| use super::org_source::convert_error; | ||||
| use super::org_source::OrgSource; | ||||
| use super::token::AllTokensIterator; | ||||
| @ -26,6 +24,14 @@ use super::token::Token; | ||||
| use super::util::exit_matcher_parser; | ||||
| use super::util::get_consumed; | ||||
| use super::util::start_of_line; | ||||
| use crate::context::parser_with_context; | ||||
| use crate::context::Context; | ||||
| use crate::context::ContextElement; | ||||
| use crate::context::ExitClass; | ||||
| use crate::context::ExitMatcherNode; | ||||
| use crate::context::GlobalSettings; | ||||
| use crate::context::List; | ||||
| use crate::context::RefContext; | ||||
| use crate::error::Res; | ||||
| use crate::parser::comment::comment; | ||||
| use crate::parser::element_parser::element; | ||||
| @ -34,11 +40,19 @@ use crate::parser::planning::planning; | ||||
| use crate::parser::property_drawer::property_drawer; | ||||
| use crate::parser::util::blank_line; | ||||
| use crate::parser::util::maybe_consume_trailing_whitespace_if_not_exiting; | ||||
| use crate::types::Document; | ||||
| use crate::types::DocumentElement; | ||||
| use crate::types::Element; | ||||
| use crate::types::Heading; | ||||
| use crate::types::Object; | ||||
| use crate::types::Section; | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| #[allow(dead_code)] | ||||
| pub fn document(input: &str) -> Res<&str, Document> { | ||||
|     let initial_context = Context::default(); | ||||
|     let global_settings = GlobalSettings::default(); | ||||
|     let initial_context = ContextElement::document_context(); | ||||
|     let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|     let wrapped_input = OrgSource::new(input); | ||||
|     let (remaining, document) = _document(&initial_context, wrapped_input) | ||||
|         .map(|(rem, out)| (Into::<&str>::into(rem), out)) | ||||
| @ -58,9 +72,9 @@ pub fn document(input: &str) -> Res<&str, Document> { | ||||
|             .map(|rt| &rt.children) | ||||
|             .collect(); | ||||
|         if !all_radio_targets.is_empty() { | ||||
|             let initial_context = initial_context | ||||
|                 .with_additional_node(ContextElement::RadioTarget(all_radio_targets)); | ||||
|             let (remaining, document) = _document(&initial_context, wrapped_input) | ||||
|             let parser_context = ContextElement::RadioTarget(all_radio_targets); | ||||
|             let parser_context = initial_context.with_additional_node(&parser_context); | ||||
|             let (remaining, document) = _document(&parser_context, wrapped_input) | ||||
|                 .map(|(rem, out)| (Into::<&str>::into(rem), out)) | ||||
|                 .map_err(convert_error)?; | ||||
|             return Ok((remaining.into(), document)); | ||||
| @ -96,15 +110,21 @@ fn zeroth_section<'r, 's>( | ||||
|     input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, 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 { | ||||
|     let contexts = [ | ||||
|         ContextElement::ConsumeTrailingWhitespace(true), | ||||
|         ContextElement::Context("section"), | ||||
|         ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Document, | ||||
|             exit_matcher: §ion_end, | ||||
|         })); | ||||
|         }), | ||||
|     ]; | ||||
|     let parser_context = context | ||||
|         .with_additional_node(&contexts[0]) | ||||
|         .with_additional_node(&contexts[1]) | ||||
|         .with_additional_node(&contexts[2]); | ||||
|     let without_consuming_whitespace_context = ContextElement::ConsumeTrailingWhitespace(false); | ||||
|     let without_consuming_whitespace_context = | ||||
|         parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false)); | ||||
|         parser_context.with_additional_node(&without_consuming_whitespace_context); | ||||
| 
 | ||||
|     let element_matcher = parser_with_context!(element(true))(&parser_context); | ||||
|     let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); | ||||
| @ -150,13 +170,18 @@ fn section<'r, 's>( | ||||
|     mut input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, 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 { | ||||
|     let contexts = [ | ||||
|         ContextElement::ConsumeTrailingWhitespace(true), | ||||
|         ContextElement::Context("section"), | ||||
|         ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Document, | ||||
|             exit_matcher: §ion_end, | ||||
|         })); | ||||
|         }), | ||||
|     ]; | ||||
|     let parser_context = context | ||||
|         .with_additional_node(&contexts[0]) | ||||
|         .with_additional_node(&contexts[1]) | ||||
|         .with_additional_node(&contexts[2]); | ||||
|     let element_matcher = parser_with_context!(element(true))(&parser_context); | ||||
|     let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); | ||||
|     let (mut remaining, (planning_element, property_drawer_element)) = tuple(( | ||||
| @ -204,8 +229,9 @@ fn section_end<'r, 's>( | ||||
| 
 | ||||
| const fn heading( | ||||
|     parent_stars: usize, | ||||
| ) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Heading<'s>> { | ||||
|     move |context: Context, input: OrgSource<'_>| _heading(context, input, parent_stars) | ||||
| ) -> impl for<'b, 'r, 's> Fn(RefContext<'b, 'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Heading<'s>> | ||||
| { | ||||
|     move |context, input: OrgSource<'_>| _heading(context, input, parent_stars) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| @ -270,11 +296,11 @@ fn headline<'r, 's>( | ||||
|         Vec<&'s str>, | ||||
|     ), | ||||
| > { | ||||
|     let parser_context = | ||||
|         context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Document, | ||||
|             exit_matcher: &headline_title_end, | ||||
|         })); | ||||
|     let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|         class: ExitClass::Document, | ||||
|         exit_matcher: &headline_title_end, | ||||
|     }); | ||||
|     let parser_context = context.with_additional_node(&parser_context); | ||||
|     let standard_set_object_matcher = parser_with_context!(standard_set_object)(&parser_context); | ||||
| 
 | ||||
|     let ( | ||||
|  | ||||
| @ -16,21 +16,26 @@ use nom::multi::many1; | ||||
| use nom::multi::many_till; | ||||
| use nom::sequence::tuple; | ||||
| 
 | ||||
| use super::greater_element::PlainList; | ||||
| use super::greater_element::PlainListItem; | ||||
| use super::element_parser::element; | ||||
| use super::object_parser::standard_set_object; | ||||
| use super::org_source::OrgSource; | ||||
| use super::util::non_whitespace_character; | ||||
| use super::Context; | ||||
| use super::Object; | ||||
| use crate::context::parser_with_context; | ||||
| use crate::context::ContextElement; | ||||
| use crate::context::ExitClass; | ||||
| use crate::context::ExitMatcherNode; | ||||
| use crate::context::RefContext; | ||||
| use crate::error::CustomError; | ||||
| use crate::error::MyError; | ||||
| use crate::error::Res; | ||||
| use crate::parser::element_parser::element; | ||||
| 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; | ||||
| use crate::types::Object; | ||||
| use crate::types::PlainList; | ||||
| use crate::types::PlainListItem; | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| pub fn detect_plain_list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> { | ||||
| @ -59,13 +64,19 @@ pub fn plain_list<'r, 's>( | ||||
|     context: RefContext<'_, 'r, 's>, | ||||
|     input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, PlainList<'s>> { | ||||
|     let parser_context = context | ||||
|         .with_additional_node(ContextElement::Context("plain list")) | ||||
|         .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) | ||||
|         .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|     let contexts = [ | ||||
|         ContextElement::Context("plain list"), | ||||
|         ContextElement::ConsumeTrailingWhitespace(true), | ||||
|         ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Beta, | ||||
|             exit_matcher: &plain_list_end, | ||||
|         })); | ||||
|         }), | ||||
|     ]; | ||||
| 
 | ||||
|     let parser_context = context | ||||
|         .with_additional_node(&contexts[0]) | ||||
|         .with_additional_node(&contexts[1]) | ||||
|         .with_additional_node(&contexts[2]); | ||||
|     // children stores tuple of (input string, parsed object) so we can re-parse the final item
 | ||||
|     let mut children = Vec::new(); | ||||
|     let mut first_item_indentation: Option<usize> = None; | ||||
| @ -107,8 +118,8 @@ pub fn plain_list<'r, 's>( | ||||
|             )))); | ||||
|         } | ||||
|     }; | ||||
|     let final_item_context = | ||||
|         parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false)); | ||||
|     let final_item_context = ContextElement::ConsumeTrailingWhitespace(false); | ||||
|     let final_item_context = parser_context.with_additional_node(&final_item_context); | ||||
|     let (remaining, reparsed_final_item) = | ||||
|         parser_with_context!(plain_list_item)(&final_item_context)(final_child_start)?; | ||||
|     children.push((final_child_start, reparsed_final_item)); | ||||
| @ -164,12 +175,16 @@ pub fn plain_list_item<'r, 's>( | ||||
|     }; | ||||
|     let (remaining, _ws) = item_tag_post_gap(context, remaining)?; | ||||
|     let exit_matcher = plain_list_item_end(indent_level); | ||||
|     let parser_context = context | ||||
|         .with_additional_node(ContextElement::ConsumeTrailingWhitespace(true)) | ||||
|         .with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|     let contexts = [ | ||||
|         ContextElement::ConsumeTrailingWhitespace(true), | ||||
|         ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Beta, | ||||
|             exit_matcher: &exit_matcher, | ||||
|         })); | ||||
|         }), | ||||
|     ]; | ||||
|     let parser_context = context | ||||
|         .with_additional_node(&contexts[0]) | ||||
|         .with_additional_node(&contexts[1]); | ||||
| 
 | ||||
|     let (mut remaining, (mut children, _exit_contents)) = many_till( | ||||
|         include_input(parser_with_context!(element(true))(&parser_context)), | ||||
| @ -177,8 +192,8 @@ pub fn plain_list_item<'r, 's>( | ||||
|     )(remaining)?; | ||||
| 
 | ||||
|     if !children.is_empty() && !context.should_consume_trailing_whitespace() { | ||||
|         let final_item_context = | ||||
|             parser_context.with_additional_node(ContextElement::ConsumeTrailingWhitespace(false)); | ||||
|         let final_item_context = ContextElement::ConsumeTrailingWhitespace(false); | ||||
|         let final_item_context = parser_context.with_additional_node(&final_item_context); | ||||
|         let (final_child_start, _original_final_child) = children | ||||
|             .pop() | ||||
|             .expect("if-statement already checked that children was non-empty."); | ||||
| @ -249,9 +264,10 @@ fn plain_list_end<'r, 's>( | ||||
| 
 | ||||
| const fn plain_list_item_end( | ||||
|     indent_level: usize, | ||||
| ) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> { | ||||
| ) -> impl for<'b, 'r, 's> Fn(RefContext<'b, 'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> | ||||
| { | ||||
|     let line_indented_lte_matcher = line_indented_lte(indent_level); | ||||
|     move |context: Context, input: OrgSource<'_>| { | ||||
|     move |context, input: OrgSource<'_>| { | ||||
|         _plain_list_item_end(context, input, &line_indented_lte_matcher) | ||||
|     } | ||||
| } | ||||
| @ -263,8 +279,8 @@ const fn plain_list_item_end( | ||||
| fn _plain_list_item_end<'r, 's>( | ||||
|     context: RefContext<'_, 'r, 's>, | ||||
|     input: OrgSource<'s>, | ||||
|     line_indented_lte_matcher: impl for<'rr, 'ss> Fn( | ||||
|         Context<'rr, 'ss>, | ||||
|     line_indented_lte_matcher: impl for<'bb, 'rr, 'ss> Fn( | ||||
|         RefContext<'bb, 'rr, 'ss>, | ||||
|         OrgSource<'ss>, | ||||
|     ) -> Res<OrgSource<'ss>, OrgSource<'ss>>, | ||||
| ) -> Res<OrgSource<'s>, OrgSource<'s>> { | ||||
| @ -277,8 +293,9 @@ fn _plain_list_item_end<'r, 's>( | ||||
| 
 | ||||
| const fn line_indented_lte( | ||||
|     indent_level: usize, | ||||
| ) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> { | ||||
|     move |context: Context, input: OrgSource<'_>| _line_indented_lte(context, input, indent_level) | ||||
| ) -> impl for<'b, 'r, 's> Fn(RefContext<'b, 'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> | ||||
| { | ||||
|     move |context, input: OrgSource<'_>| _line_indented_lte(context, input, indent_level) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| @ -301,11 +318,11 @@ fn item_tag<'r, 's>( | ||||
|     context: RefContext<'_, 'r, 's>, | ||||
|     input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, Vec<Object<'s>>> { | ||||
|     let parser_context = | ||||
|         context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Gamma, | ||||
|             exit_matcher: &item_tag_end, | ||||
|         })); | ||||
|     let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|         class: ExitClass::Gamma, | ||||
|         exit_matcher: &item_tag_end, | ||||
|     }); | ||||
|     let parser_context = context.with_additional_node(&parser_context); | ||||
|     let (remaining, (children, _exit_contents)) = verify( | ||||
|         many_till( | ||||
|             // TODO: Should this be using a different set like the minimal set?
 | ||||
| @ -353,14 +370,16 @@ fn item_tag_post_gap<'r, 's>( | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|     use crate::parser::parser_context::ContextTree; | ||||
|     use crate::parser::parser_with_context::parser_with_context; | ||||
|     use crate::parser::Source; | ||||
|     use crate::context::Context; | ||||
|     use crate::context::GlobalSettings; | ||||
|     use crate::context::List; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn plain_list_item_empty() { | ||||
|         let input = OrgSource::new("1."); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_item_matcher = parser_with_context!(plain_list_item)(&initial_context); | ||||
|         let (remaining, result) = plain_list_item_matcher(input).unwrap(); | ||||
|         assert_eq!(Into::<&str>::into(remaining), ""); | ||||
| @ -370,7 +389,9 @@ mod tests { | ||||
|     #[test] | ||||
|     fn plain_list_item_simple() { | ||||
|         let input = OrgSource::new("1. foo"); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_item_matcher = parser_with_context!(plain_list_item)(&initial_context); | ||||
|         let (remaining, result) = plain_list_item_matcher(input).unwrap(); | ||||
|         assert_eq!(Into::<&str>::into(remaining), ""); | ||||
| @ -380,7 +401,9 @@ mod tests { | ||||
|     #[test] | ||||
|     fn plain_list_empty() { | ||||
|         let input = OrgSource::new("1."); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(plain_list)(&initial_context); | ||||
|         let (remaining, result) = plain_list_matcher(input).unwrap(); | ||||
|         assert_eq!(Into::<&str>::into(remaining), ""); | ||||
| @ -390,7 +413,9 @@ mod tests { | ||||
|     #[test] | ||||
|     fn plain_list_simple() { | ||||
|         let input = OrgSource::new("1. foo"); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(plain_list)(&initial_context); | ||||
|         let (remaining, result) = plain_list_matcher(input).unwrap(); | ||||
|         assert_eq!(Into::<&str>::into(remaining), ""); | ||||
| @ -401,7 +426,9 @@ mod tests { | ||||
|     fn plain_list_cant_start_line_with_asterisk() { | ||||
|         // Plain lists with an asterisk bullet must be indented or else they would be a headline
 | ||||
|         let input = OrgSource::new("* foo"); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(plain_list)(&initial_context); | ||||
|         let result = plain_list_matcher(input); | ||||
|         assert!(result.is_err()); | ||||
| @ -411,7 +438,9 @@ mod tests { | ||||
|     fn indented_can_start_line_with_asterisk() { | ||||
|         // Plain lists with an asterisk bullet must be indented or else they would be a headline
 | ||||
|         let input = OrgSource::new(" * foo"); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(plain_list)(&initial_context); | ||||
|         let result = plain_list_matcher(input); | ||||
|         assert!(result.is_ok()); | ||||
| @ -429,7 +458,9 @@ mod tests { | ||||
|    ipsum | ||||
| "#,
 | ||||
|         ); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(element(true))(&initial_context); | ||||
|         let (remaining, result) = | ||||
|             plain_list_matcher(input).expect("Should parse the plain list successfully."); | ||||
| @ -455,7 +486,9 @@ mod tests { | ||||
| 
 | ||||
| baz"#,
 | ||||
|         ); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(element(true))(&initial_context); | ||||
|         let (remaining, result) = | ||||
|             plain_list_matcher(input).expect("Should parse the plain list successfully."); | ||||
| @ -486,7 +519,9 @@ baz"#, | ||||
| 
 | ||||
| dolar"#,
 | ||||
|         ); | ||||
|         let initial_context: ContextTree<'_, '_> = ContextTree::new(); | ||||
|         let global_settings = GlobalSettings::default(); | ||||
|         let initial_context = ContextElement::document_context(); | ||||
|         let initial_context = Context::new(&global_settings, List::new(&initial_context)); | ||||
|         let plain_list_matcher = parser_with_context!(element(true))(&initial_context); | ||||
|         let (remaining, result) = | ||||
|             plain_list_matcher(input).expect("Should parse the plain list successfully."); | ||||
|  | ||||
| @ -7,13 +7,18 @@ use nom::combinator::verify; | ||||
| use nom::multi::many_till; | ||||
| 
 | ||||
| use super::org_source::OrgSource; | ||||
| use super::util::exit_matcher_parser; | ||||
| use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting; | ||||
| use super::Context; | ||||
| use crate::context::parser_with_context; | ||||
| use crate::context::ContextElement; | ||||
| use crate::context::ExitClass; | ||||
| use crate::context::ExitMatcherNode; | ||||
| use crate::context::RefContext; | ||||
| use crate::error::CustomError; | ||||
| use crate::error::MyError; | ||||
| use crate::error::Res; | ||||
| use crate::parser::util::get_consumed; | ||||
| use crate::parser::Target; | ||||
| use crate::types::Target; | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| pub fn target<'r, 's>( | ||||
| @ -25,11 +30,11 @@ pub fn target<'r, 's>( | ||||
|         !c.is_whitespace() && !"<>\n".contains(*c) | ||||
|     }))(remaining)?; | ||||
| 
 | ||||
|     let parser_context = | ||||
|         context.with_additional_node(ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Beta, | ||||
|             exit_matcher: &target_end, | ||||
|         })); | ||||
|     let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|         class: ExitClass::Beta, | ||||
|         exit_matcher: &target_end, | ||||
|     }); | ||||
|     let parser_context = context.with_additional_node(&parser_context); | ||||
|     let (remaining, _body) = recognize(many_till( | ||||
|         anychar, | ||||
|         parser_with_context!(exit_matcher_parser)(&parser_context), | ||||
|  | ||||
| @ -20,7 +20,6 @@ use super::org_source::OrgSource; | ||||
| use super::radio_link::RematchObject; | ||||
| use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting; | ||||
| use crate::context::parser_with_context; | ||||
| use crate::context::Context; | ||||
| use crate::context::ContextElement; | ||||
| use crate::context::ExitClass; | ||||
| use crate::context::ExitMatcherNode; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander