Parse application and handle parenthesis in regular links.

This commit is contained in:
Tom Alexander 2023-10-08 09:10:47 -04:00
parent 20a8683894
commit 0030ef4459
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 85 additions and 14 deletions

View File

@ -230,7 +230,7 @@ fn path_plain_end(
enable_search_option: bool, enable_search_option: bool,
) -> impl ContextMatcher { ) -> impl ContextMatcher {
move |context, input: OrgSource<'_>| { move |context, input: OrgSource<'_>| {
_path_plain_end( impl_path_plain_end(
context, context,
input, input,
starting_parenthesis_depth, starting_parenthesis_depth,
@ -240,7 +240,7 @@ fn path_plain_end(
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn _path_plain_end<'b, 'g, 'r, 's>( 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,

View File

@ -21,13 +21,17 @@ use nom::sequence::tuple;
use nom::InputTake; use nom::InputTake;
use super::object_parser::regular_link_description_set_object; use super::object_parser::regular_link_description_set_object;
use super::org_source::BracketDepth;
use super::org_source::OrgSource; use super::org_source::OrgSource;
use super::plain_link::parse_file_and_application;
use super::plain_link::protocol; use super::plain_link::protocol;
use super::util::exit_matcher_parser; use super::util::exit_matcher_parser;
use super::util::get_consumed; use super::util::get_consumed;
use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting; use super::util::maybe_consume_object_trailing_whitespace_if_not_exiting;
use super::util::text_until_exit;
use crate::context::parser_with_context; use crate::context::parser_with_context;
use crate::context::ContextElement; use crate::context::ContextElement;
use crate::context::ContextMatcher;
use crate::context::ExitClass; use crate::context::ExitClass;
use crate::context::ExitMatcherNode; use crate::context::ExitMatcherNode;
use crate::context::RefContext; use crate::context::RefContext;
@ -136,7 +140,7 @@ fn parse_path_reg<'b, 'g, 'r, 's>(
if let Some(replaced_link) = apply_link_templates(context, input) { if let Some(replaced_link) = apply_link_templates(context, input) {
let replaced_input = Into::<OrgSource<'_>>::into(replaced_link.as_str()); let replaced_input = Into::<OrgSource<'_>>::into(replaced_link.as_str());
let (_remaining, link) = alt(( let (_remaining, link) = alt((
file_path_reg, parser_with_context!(file_path_reg)(context),
id_path_reg, id_path_reg,
custom_id_path_reg, custom_id_path_reg,
code_ref_path_reg, code_ref_path_reg,
@ -169,7 +173,7 @@ fn parse_path_reg<'b, 'g, 'r, 's>(
)) ))
} else { } else {
alt(( alt((
file_path_reg, parser_with_context!(file_path_reg)(context),
id_path_reg, id_path_reg,
custom_id_path_reg, custom_id_path_reg,
code_ref_path_reg, code_ref_path_reg,
@ -243,16 +247,47 @@ fn apply_link_templates<'b, 'g, 'r, 's>(
Some(ret) Some(ret)
} }
fn file_path_reg<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PathReg<'s>> { fn file_path_reg<'b, 'g, 'r, 's>(
// TODO: Update this to parse out the application like plain link does. context: RefContext<'b, 'g, 'r, 's>,
// TODO: Handle parenthesis like plain link does. input: OrgSource<'s>,
let (remaining, (raw_link, (_, path, search_option))) = consumed(tuple(( ) -> Res<OrgSource<'s>, PathReg<'s>> {
alt((tag("file:"), peek(tag(".")), peek(tag("/")))), let path_reg_end = path_reg_end(input.get_parenthesis_depth(), true);
recognize(many_till(anychar, alt((peek(tag("::")), eof)))), let parser_context = ContextElement::ExitMatcherNode(ExitMatcherNode {
opt(map(tuple((tag("::"), rest)), |(_, search_option)| { class: ExitClass::Gamma,
search_option exit_matcher: &path_reg_end,
})), });
let parser_context = context.with_additional_node(&parser_context);
let (remaining, (raw_link, (application, path, search_option))) = consumed(tuple((
alt((
map(
tuple((
peek(tag("file")),
map_parser(
parser_with_context!(protocol)(&parser_context),
parse_file_and_application,
),
tag(":"),
)),
|(_, application, _)| application,
),
map(peek(tag(".")), |_| None),
map(peek(tag("/")), |_| None),
)),
parser_with_context!(text_until_exit)(&parser_context),
opt(map(
tuple((
tag("::"),
verify(rest, |search_option| {
Into::<&str>::into(search_option)
.chars()
.any(char::is_alphanumeric)
}),
)),
|(_, search_option)| search_option,
)),
)))(input)?; )))(input)?;
Ok(( Ok((
remaining, remaining,
PathReg { PathReg {
@ -262,7 +297,9 @@ fn file_path_reg<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PathReg<'s>> {
search_option: search_option search_option: search_option
.map(Into::<&str>::into) .map(Into::<&str>::into)
.map(Into::<Cow<str>>::into), .map(Into::<Cow<str>>::into),
application: None, // TODO application: application
.map(Into::<&str>::into)
.map(Into::<Cow<str>>::into),
}, },
)) ))
} }
@ -376,3 +413,37 @@ fn description_end<'b, 'g, 'r, 's>(
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, OrgSource<'s>> {
tag("]]")(input) tag("]]")(input)
} }
fn path_reg_end(
starting_parenthesis_depth: BracketDepth,
enable_search_option: bool,
) -> impl ContextMatcher {
move |context, input: OrgSource<'_>| {
impl_path_reg_end(
context,
input,
starting_parenthesis_depth,
enable_search_option,
)
}
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn impl_path_reg_end<'b, 'g, 'r, 's>(
_context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
starting_parenthesis_depth: BracketDepth,
enable_search_option: bool,
) -> Res<OrgSource<'s>, OrgSource<'s>> {
let current_depth = input.get_parenthesis_depth() - starting_parenthesis_depth;
if enable_search_option && current_depth == 0 {
let search_option = peek(tag("::"))(input);
if search_option.is_ok() {
return search_option;
}
}
Err(nom::Err::Error(CustomError::MyError(MyError(
"No path reg end".into(),
))))
}