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"),
|
EmacsField::Required(":search-option"),
|
||||||
|r| r.search_option,
|
|r| r.get_search_option(),
|
||||||
compare_property_quoted_string
|
compare_property_quoted_string
|
||||||
)
|
)
|
||||||
)? {
|
)? {
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
|
use nom::bytes::complete::take;
|
||||||
use nom::bytes::complete::take_until;
|
use nom::bytes::complete::take_until;
|
||||||
use nom::combinator::consumed;
|
use nom::combinator::consumed;
|
||||||
|
use nom::combinator::flat_map;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::combinator::map_parser;
|
use nom::combinator::map_parser;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::combinator::peek;
|
use nom::combinator::peek;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::combinator::rest;
|
use nom::combinator::rest;
|
||||||
|
use nom::combinator::verify;
|
||||||
|
use nom::multi::many1_count;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
@ -114,6 +118,10 @@ fn parse_file_angle_link<'b, 'g, 'r, 's>(
|
|||||||
)),
|
)),
|
||||||
|(_, application, _)| application,
|
|(_, application, _)| application,
|
||||||
)(input)?;
|
)(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, path) = alt((take_until("::"), rest))(remaining)?;
|
||||||
let (remaining, search_option) = opt(map(tuple((tag("::"), rest)), |(_, search_option)| {
|
let (remaining, search_option) = opt(map(tuple((tag("::"), rest)), |(_, search_option)| {
|
||||||
search_option
|
search_option
|
||||||
|
@ -738,6 +738,12 @@ enum PathState {
|
|||||||
HasLineBreak(String),
|
HasLineBreak(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SearchOptionState {
|
||||||
|
Normal,
|
||||||
|
HasWhitespace(usize),
|
||||||
|
HasLineBreak(String),
|
||||||
|
}
|
||||||
|
|
||||||
impl<'s> AngleLink<'s> {
|
impl<'s> AngleLink<'s> {
|
||||||
/// Remove line breaks but preserve multiple consecutive spaces.
|
/// Remove line breaks but preserve multiple consecutive spaces.
|
||||||
pub fn get_path(&self) -> Cow<'s, str> {
|
pub fn get_path(&self) -> Cow<'s, str> {
|
||||||
@ -761,4 +767,44 @@ impl<'s> AngleLink<'s> {
|
|||||||
PathState::HasLineBreak(ret) => Cow::Owned(ret),
|
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…
Reference in New Issue
Block a user