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;
|
||||||
use nom::bytes::complete::tag_no_case;
|
use nom::bytes::complete::tag_no_case;
|
||||||
use nom::bytes::complete::take;
|
use nom::bytes::complete::take;
|
||||||
|
use nom::bytes::complete::take_until;
|
||||||
use nom::character::complete::anychar;
|
use nom::character::complete::anychar;
|
||||||
use nom::character::complete::none_of;
|
use nom::character::complete::none_of;
|
||||||
use nom::character::complete::one_of;
|
use nom::character::complete::one_of;
|
||||||
|
use nom::combinator::all_consuming;
|
||||||
use nom::combinator::consumed;
|
use nom::combinator::consumed;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::flat_map;
|
use nom::combinator::flat_map;
|
||||||
@ -127,6 +129,44 @@ pub(crate) fn parse_file_and_application<'s>(
|
|||||||
Ok((remaining, application))
|
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"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn file_path_plain<'b, 'g, 'r, 's>(
|
fn file_path_plain<'b, 'g, 'r, 's>(
|
||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
@ -138,7 +178,8 @@ fn file_path_plain<'b, 'g, 'r, 's>(
|
|||||||
exit_matcher: &path_plain_end,
|
exit_matcher: &path_plain_end,
|
||||||
});
|
});
|
||||||
let parser_context = context.with_additional_node(&parser_context);
|
let parser_context = context.with_additional_node(&parser_context);
|
||||||
let (remaining, (raw_link, (_, application, _, _, path, search_option))) = consumed(tuple((
|
let (remaining, (raw_link, (_, application, _, _, (path, search_option)))) =
|
||||||
|
consumed(tuple((
|
||||||
peek(tag("file")),
|
peek(tag("file")),
|
||||||
map_parser(
|
map_parser(
|
||||||
parser_with_context!(protocol)(&parser_context),
|
parser_with_context!(protocol)(&parser_context),
|
||||||
@ -149,18 +190,10 @@ fn file_path_plain<'b, 'g, 'r, 's>(
|
|||||||
peek(map(verify(many1_count(tag("/")), |c| *c >= 3), |c| c - 1)),
|
peek(map(verify(many1_count(tag("/")), |c| *c >= 3), |c| c - 1)),
|
||||||
take,
|
take,
|
||||||
)),
|
)),
|
||||||
|
map_parser(
|
||||||
parser_with_context!(path_plain)(&parser_context),
|
parser_with_context!(path_plain)(&parser_context),
|
||||||
opt(map(
|
parse_path_and_search_option,
|
||||||
tuple((
|
),
|
||||||
tag("::"),
|
|
||||||
verify(is_not(" \t\r\n"), |search_option| {
|
|
||||||
Into::<&str>::into(search_option)
|
|
||||||
.chars()
|
|
||||||
.any(char::is_alphanumeric)
|
|
||||||
}),
|
|
||||||
)),
|
|
||||||
|(_, search_option)| search_option,
|
|
||||||
)),
|
|
||||||
)))(input)?;
|
)))(input)?;
|
||||||
Ok((
|
Ok((
|
||||||
remaining,
|
remaining,
|
||||||
@ -256,15 +289,9 @@ fn impl_path_plain_end<'b, 'g, 'r, 's>(
|
|||||||
context: RefContext<'b, 'g, 'r, 's>,
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
starting_parenthesis_depth: BracketDepth,
|
starting_parenthesis_depth: BracketDepth,
|
||||||
enable_search_option: bool,
|
_enable_search_option: bool,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
let current_depth = input.get_parenthesis_depth() - starting_parenthesis_depth;
|
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| {
|
let (remaining, _leading_punctuation) = many0(verify(anychar, |c| {
|
||||||
!" \t\r\n[]<>()/".contains(*c) && c.is_ascii_punctuation()
|
!" \t\r\n[]<>()/".contains(*c) && c.is_ascii_punctuation()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user