Fix handling of search option for plain links when parenthesis are involved.
This commit is contained in:
		
							parent
							
								
									b64c1c944b
								
							
						
					
					
						commit
						ceb5376b21
					
				| @ -3,9 +3,11 @@ use nom::bytes::complete::is_not; | ||||
| use nom::bytes::complete::tag; | ||||
| use nom::bytes::complete::tag_no_case; | ||||
| use nom::bytes::complete::take; | ||||
| use nom::bytes::complete::take_until; | ||||
| use nom::character::complete::anychar; | ||||
| use nom::character::complete::none_of; | ||||
| use nom::character::complete::one_of; | ||||
| use nom::combinator::all_consuming; | ||||
| use nom::combinator::consumed; | ||||
| use nom::combinator::eof; | ||||
| use nom::combinator::flat_map; | ||||
| @ -127,6 +129,44 @@ pub(crate) fn parse_file_and_application<'s>( | ||||
|     Ok((remaining, application)) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| pub(crate) fn parse_path_and_search_option<'s>( | ||||
|     input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, (OrgSource<'s>, Option<OrgSource<'s>>)> { | ||||
|     alt(( | ||||
|         all_consuming(parse_path_and_search_option_with_search_option), | ||||
|         all_consuming(parse_path_and_search_option_without_search_option), | ||||
|     ))(input) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| pub(crate) fn parse_path_and_search_option_with_search_option<'s>( | ||||
|     input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, (OrgSource<'s>, Option<OrgSource<'s>>)> { | ||||
|     let (remaining, path) = take_until("::")(input)?; | ||||
|     let (remaining, search_option) = opt(map( | ||||
|         tuple(( | ||||
|             tag("::"), | ||||
|             verify(is_not(" \t\r\n"), |search_option| { | ||||
|                 Into::<&str>::into(search_option) | ||||
|                     .chars() | ||||
|                     .any(char::is_alphanumeric) | ||||
|             }), | ||||
|         )), | ||||
|         |(_, search_option)| search_option, | ||||
|     ))(remaining)?; | ||||
|     // Assert we consumed the entire protocol.
 | ||||
|     not(anychar)(remaining)?; | ||||
|     Ok((remaining, (path, search_option))) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| pub(crate) fn parse_path_and_search_option_without_search_option<'s>( | ||||
|     input: OrgSource<'s>, | ||||
| ) -> Res<OrgSource<'s>, (OrgSource<'s>, Option<OrgSource<'s>>)> { | ||||
|     map(rest, |path| (path, None))(input) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] | ||||
| fn file_path_plain<'b, 'g, 'r, 's>( | ||||
|     context: RefContext<'b, 'g, 'r, 's>, | ||||
| @ -138,30 +178,23 @@ fn file_path_plain<'b, 'g, 'r, 's>( | ||||
|         exit_matcher: &path_plain_end, | ||||
|     }); | ||||
|     let parser_context = context.with_additional_node(&parser_context); | ||||
|     let (remaining, (raw_link, (_, application, _, _, path, search_option))) = consumed(tuple(( | ||||
|         peek(tag("file")), | ||||
|         map_parser( | ||||
|             parser_with_context!(protocol)(&parser_context), | ||||
|             parse_file_and_application, | ||||
|         ), | ||||
|         tag(":"), | ||||
|         opt(flat_map( | ||||
|             peek(map(verify(many1_count(tag("/")), |c| *c >= 3), |c| c - 1)), | ||||
|             take, | ||||
|         )), | ||||
|         parser_with_context!(path_plain)(&parser_context), | ||||
|         opt(map( | ||||
|             tuple(( | ||||
|                 tag("::"), | ||||
|                 verify(is_not(" \t\r\n"), |search_option| { | ||||
|                     Into::<&str>::into(search_option) | ||||
|                         .chars() | ||||
|                         .any(char::is_alphanumeric) | ||||
|                 }), | ||||
|     let (remaining, (raw_link, (_, application, _, _, (path, search_option)))) = | ||||
|         consumed(tuple(( | ||||
|             peek(tag("file")), | ||||
|             map_parser( | ||||
|                 parser_with_context!(protocol)(&parser_context), | ||||
|                 parse_file_and_application, | ||||
|             ), | ||||
|             tag(":"), | ||||
|             opt(flat_map( | ||||
|                 peek(map(verify(many1_count(tag("/")), |c| *c >= 3), |c| c - 1)), | ||||
|                 take, | ||||
|             )), | ||||
|             |(_, search_option)| search_option, | ||||
|         )), | ||||
|     )))(input)?; | ||||
|             map_parser( | ||||
|                 parser_with_context!(path_plain)(&parser_context), | ||||
|                 parse_path_and_search_option, | ||||
|             ), | ||||
|         )))(input)?; | ||||
|     Ok(( | ||||
|         remaining, | ||||
|         PathPlain { | ||||
| @ -256,15 +289,9 @@ fn impl_path_plain_end<'b, 'g, 'r, 's>( | ||||
|     context: RefContext<'b, 'g, 'r, 's>, | ||||
|     input: OrgSource<'s>, | ||||
|     starting_parenthesis_depth: BracketDepth, | ||||
|     enable_search_option: bool, | ||||
|     _enable_search_option: bool, | ||||
| ) -> Res<OrgSource<'s>, OrgSource<'s>> { | ||||
|     let current_depth = input.get_parenthesis_depth() - starting_parenthesis_depth; | ||||
|     if enable_search_option { | ||||
|         let search_option = peek(tag("::"))(input); | ||||
|         if search_option.is_ok() { | ||||
|             return search_option; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let (remaining, _leading_punctuation) = many0(verify(anychar, |c| { | ||||
|         !" \t\r\n[]<>()/".contains(*c) && c.is_ascii_punctuation() | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander