Remove all whitespace from search option if it contains any line breaks and handle triple+ slashes for file links.
This commit is contained in:
		
							parent
							
								
									d987b9b75b
								
							
						
					
					
						commit
						ba55e0df4f
					
				| @ -3044,7 +3044,7 @@ fn compare_angle_link<'b, 's>( | ||||
|         ), | ||||
|         ( | ||||
|             EmacsField::Required(":search-option"), | ||||
|             |r| r.search_option, | ||||
|             |r| r.get_search_option(), | ||||
|             compare_property_quoted_string | ||||
|         ) | ||||
|     )? { | ||||
|  | ||||
| @ -1,13 +1,17 @@ | ||||
| use nom::branch::alt; | ||||
| use nom::bytes::complete::tag; | ||||
| use nom::bytes::complete::take; | ||||
| use nom::bytes::complete::take_until; | ||||
| use nom::combinator::consumed; | ||||
| use nom::combinator::flat_map; | ||||
| use nom::combinator::map; | ||||
| use nom::combinator::map_parser; | ||||
| use nom::combinator::opt; | ||||
| use nom::combinator::peek; | ||||
| use nom::combinator::recognize; | ||||
| use nom::combinator::rest; | ||||
| use nom::combinator::verify; | ||||
| use nom::multi::many1_count; | ||||
| use nom::sequence::tuple; | ||||
| 
 | ||||
| use super::org_source::OrgSource; | ||||
| @ -114,6 +118,10 @@ fn parse_file_angle_link<'b, 'g, 'r, 's>( | ||||
|         )), | ||||
|         |(_, application, _)| application, | ||||
|     )(input)?; | ||||
|     let (remaining, _) = opt(flat_map( | ||||
|         peek(map(verify(many1_count(tag("/")), |c| *c >= 3), |c| c - 1)), | ||||
|         take, | ||||
|     ))(remaining)?; | ||||
|     let (remaining, path) = alt((take_until("::"), rest))(remaining)?; | ||||
|     let (remaining, search_option) = opt(map(tuple((tag("::"), rest)), |(_, search_option)| { | ||||
|         search_option | ||||
|  | ||||
| @ -738,6 +738,12 @@ enum PathState { | ||||
|     HasLineBreak(String), | ||||
| } | ||||
| 
 | ||||
| enum SearchOptionState { | ||||
|     Normal, | ||||
|     HasWhitespace(usize), | ||||
|     HasLineBreak(String), | ||||
| } | ||||
| 
 | ||||
| impl<'s> AngleLink<'s> { | ||||
|     /// Remove line breaks but preserve multiple consecutive spaces.
 | ||||
|     pub fn get_path(&self) -> Cow<'s, str> { | ||||
| @ -761,4 +767,44 @@ impl<'s> AngleLink<'s> { | ||||
|             PathState::HasLineBreak(ret) => Cow::Owned(ret), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Remove all whitespace but only if search_option contains a line break.
 | ||||
|     pub fn get_search_option(&self) -> Option<Cow<'s, str>> { | ||||
|         self.search_option.map(|search_option| { | ||||
|             let mut state = SearchOptionState::Normal; | ||||
|             for (offset, c) in search_option.char_indices() { | ||||
|                 match (&mut state, c) { | ||||
|                     (SearchOptionState::Normal, '\n') => { | ||||
|                         let mut ret = String::with_capacity(search_option.len()); | ||||
|                         ret.push_str(&search_option[..offset]); | ||||
|                         state = SearchOptionState::HasLineBreak(ret); | ||||
|                     } | ||||
|                     (SearchOptionState::Normal, ' ' | '\t') => { | ||||
|                         state = SearchOptionState::HasWhitespace(offset); | ||||
|                     } | ||||
|                     (SearchOptionState::Normal, _) => {} | ||||
|                     (SearchOptionState::HasWhitespace(first_whitespace_offset), '\n') => { | ||||
|                         let mut ret = String::with_capacity(search_option.len()); | ||||
|                         ret.push_str(&search_option[..*first_whitespace_offset]); | ||||
|                         for c in search_option[*first_whitespace_offset..offset].chars() { | ||||
|                             if !c.is_ascii_whitespace() { | ||||
|                                 ret.push(c); | ||||
|                             } | ||||
|                         } | ||||
|                         state = SearchOptionState::HasLineBreak(ret); | ||||
|                     } | ||||
|                     (SearchOptionState::HasWhitespace(_), _) => {} | ||||
|                     (SearchOptionState::HasLineBreak(_), ' ' | '\t' | '\r' | '\n') => {} | ||||
|                     (SearchOptionState::HasLineBreak(ret), _) => { | ||||
|                         ret.push(c); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             match state { | ||||
|                 SearchOptionState::Normal => Cow::Borrowed(search_option), | ||||
|                 SearchOptionState::HasWhitespace(_) => Cow::Borrowed(search_option), | ||||
|                 SearchOptionState::HasLineBreak(ret) => Cow::Owned(ret), | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander