Text markup uses confine context.
This commit is contained in:
		
							parent
							
								
									25531cc443
								
							
						
					
					
						commit
						ee1d8ca321
					
				| @ -22,9 +22,6 @@ pub(crate) enum ContextElement<'r, 's> { | ||||
|     /// Stores the name of the current element to prevent directly nesting elements of the same type.
 | ||||
|     Context(&'r str), | ||||
| 
 | ||||
|     /// Stores the name of the current object to prevent directly nesting elements of the same type.
 | ||||
|     ContextObject(&'r str), | ||||
| 
 | ||||
|     /// Indicates if elements should consume the whitespace after them.
 | ||||
|     ConsumeTrailingWhitespace(bool), | ||||
| 
 | ||||
|  | ||||
| @ -4,11 +4,14 @@ use nom::character::complete::anychar; | ||||
| use nom::character::complete::multispace1; | ||||
| use nom::character::complete::one_of; | ||||
| use nom::character::complete::space0; | ||||
| use nom::combinator::all_consuming; | ||||
| use nom::combinator::map; | ||||
| use nom::combinator::map_parser; | ||||
| use nom::combinator::not; | ||||
| use nom::combinator::peek; | ||||
| use nom::combinator::recognize; | ||||
| use nom::combinator::verify; | ||||
| use nom::multi::many1; | ||||
| use nom::multi::many_till; | ||||
| use nom::sequence::terminated; | ||||
| #[cfg(feature = "tracing")] | ||||
| @ -17,15 +20,18 @@ use tracing::span; | ||||
| use super::object_parser::standard_set_object; | ||||
| use super::org_source::OrgSource; | ||||
| use super::radio_link::RematchObject; | ||||
| use super::util::in_object_section; | ||||
| use super::util::confine_context; | ||||
| use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting; | ||||
| use super::util::org_line_ending; | ||||
| use super::util::start_of_line; | ||||
| use super::util::text_until_exit; | ||||
| use crate::context::parser_with_context; | ||||
| use crate::context::Context; | ||||
| use crate::context::ContextElement; | ||||
| use crate::context::ContextMatcher; | ||||
| use crate::context::ExitClass; | ||||
| use crate::context::ExitMatcherNode; | ||||
| use crate::context::List; | ||||
| use crate::context::RefContext; | ||||
| use crate::error::CustomError; | ||||
| use crate::error::MyError; | ||||
| @ -196,33 +202,30 @@ fn _text_markup_object<'b, 'g, 'r, 's, 'c>( | ||||
|     input: OrgSource<'s>, | ||||
|     marker_symbol: &'c str, | ||||
| ) -> Res<OrgSource<'s>, Vec<Object<'s>>> { | ||||
|     if in_object_section(context, marker_symbol) { | ||||
|         return Err(nom::Err::Error(CustomError::MyError(MyError( | ||||
|             "Cannot nest objects of the same type".into(), | ||||
|         )))); | ||||
|     } | ||||
| 
 | ||||
|     let (remaining, _) = pre(context, input)?; | ||||
|     let (remaining, open) = tag(marker_symbol)(remaining)?; | ||||
|     let (remaining, _peek_not_whitespace) = | ||||
|         peek(verify(anychar, |c| !c.is_whitespace() && *c != '\u{200B}'))(remaining)?; | ||||
|     let text_markup_end_specialized = text_markup_end(open.into(), remaining.get_byte_offset()); | ||||
|     let contexts = [ | ||||
|         ContextElement::ContextObject(marker_symbol), | ||||
|         ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Gamma, | ||||
|             exit_matcher: &text_markup_end_specialized, | ||||
|         }), | ||||
|     ]; | ||||
|     let contexts = [ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|         class: ExitClass::Gamma, | ||||
|         exit_matcher: &text_markup_end_specialized, | ||||
|     })]; | ||||
|     let parser_context = context.with_additional_node(&contexts[0]); | ||||
|     let parser_context = parser_context.with_additional_node(&contexts[1]); | ||||
| 
 | ||||
|     let (remaining, (children, _exit_contents)) = verify( | ||||
|         many_till( | ||||
|             parser_with_context!(standard_set_object)(&parser_context), | ||||
|             parser_with_context!(exit_matcher_parser)(&parser_context), | ||||
|     let initial_context = ContextElement::document_context(); | ||||
|     let initial_context = Context::new(context.get_global_settings(), List::new(&initial_context)); | ||||
| 
 | ||||
|     let (remaining, children) = map_parser( | ||||
|         verify( | ||||
|             parser_with_context!(text_until_exit)(&parser_context), | ||||
|             |text| text.len() > 0, | ||||
|         ), | ||||
|         |(children, _exit_contents)| !children.is_empty(), | ||||
|         confine_context(|i| { | ||||
|             all_consuming(many1(parser_with_context!(standard_set_object)( | ||||
|                 &initial_context, | ||||
|             )))(i) | ||||
|         }), | ||||
|     )(remaining)?; | ||||
| 
 | ||||
|     { | ||||
| @ -262,25 +265,16 @@ fn _text_markup_string<'b, 'g, 'r, 's, 'c>( | ||||
|     input: OrgSource<'s>, | ||||
|     marker_symbol: &'c str, | ||||
| ) -> Res<OrgSource<'s>, OrgSource<'s>> { | ||||
|     if in_object_section(context, marker_symbol) { | ||||
|         return Err(nom::Err::Error(CustomError::MyError(MyError( | ||||
|             "Cannot nest objects of the same type".into(), | ||||
|         )))); | ||||
|     } | ||||
|     let (remaining, _) = pre(context, input)?; | ||||
|     let (remaining, open) = tag(marker_symbol)(remaining)?; | ||||
|     let (remaining, _peek_not_whitespace) = | ||||
|         peek(verify(anychar, |c| !c.is_whitespace() && *c != '\u{200B}'))(remaining)?; | ||||
|     let text_markup_end_specialized = text_markup_end(open.into(), remaining.get_byte_offset()); | ||||
|     let contexts = [ | ||||
|         ContextElement::ContextObject(marker_symbol), | ||||
|         ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|             class: ExitClass::Gamma, | ||||
|             exit_matcher: &text_markup_end_specialized, | ||||
|         }), | ||||
|     ]; | ||||
|     let contexts = [ContextElement::ExitMatcherNode(ExitMatcherNode { | ||||
|         class: ExitClass::Gamma, | ||||
|         exit_matcher: &text_markup_end_specialized, | ||||
|     })]; | ||||
|     let parser_context = context.with_additional_node(&contexts[0]); | ||||
|     let parser_context = parser_context.with_additional_node(&contexts[1]); | ||||
| 
 | ||||
|     let (remaining, contents) = recognize(verify( | ||||
|         many_till( | ||||
|  | ||||
| @ -57,20 +57,6 @@ pub(crate) fn immediate_in_section<'b, 'g, 'r, 's, 'x>( | ||||
|     false | ||||
| } | ||||
| 
 | ||||
| /// Check if we are below a section of the given section type regardless of depth
 | ||||
| pub(crate) fn in_object_section<'b, 'g, 'r, 's, 'x>( | ||||
|     context: RefContext<'b, 'g, 'r, 's>, | ||||
|     section_name: &'x str, | ||||
| ) -> bool { | ||||
|     for thing in context.iter() { | ||||
|         match thing { | ||||
|             ContextElement::ContextObject(name) if *name == section_name => return true, | ||||
|             _ => {} | ||||
|         } | ||||
|     } | ||||
|     false | ||||
| } | ||||
| 
 | ||||
| /// Get a slice of the string that was consumed in a parser using the original input to the parser and the remaining input after the parser.
 | ||||
| pub(crate) fn get_consumed<'s>(input: OrgSource<'s>, remaining: OrgSource<'s>) -> OrgSource<'s> { | ||||
|     input.get_until(remaining) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander