Implement generic function for balanced brackets text.
This commit is contained in:
parent
efac73798f
commit
885fefd060
@ -15,10 +15,14 @@ use nom::sequence::tuple;
|
|||||||
use nom::InputTake;
|
use nom::InputTake;
|
||||||
|
|
||||||
use super::keyword::affiliated_keyword;
|
use super::keyword::affiliated_keyword;
|
||||||
|
use super::org_source::BracketDepth;
|
||||||
use super::util::get_name;
|
use super::util::get_name;
|
||||||
use super::util::start_of_line;
|
use super::util::start_of_line;
|
||||||
use super::OrgSource;
|
use super::OrgSource;
|
||||||
|
use crate::context::Matcher;
|
||||||
use crate::context::RefContext;
|
use crate::context::RefContext;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
use crate::parser::util::get_consumed;
|
use crate::parser::util::get_consumed;
|
||||||
use crate::parser::util::org_line_ending;
|
use crate::parser::util::org_line_ending;
|
||||||
@ -125,20 +129,37 @@ fn inside_header<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>>
|
|||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
fn arguments<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
fn arguments<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||||
let (remaining, _) = tag("(")(input)?;
|
balanced_bracket(
|
||||||
|
|i| tag("(")(i),
|
||||||
|
|i| peek(tag(")"))(i),
|
||||||
|
|i| recognize(tuple((space0, org_line_ending)))(i),
|
||||||
|
|i| tag(")")(i),
|
||||||
|
|s| s.get_parenthesis_depth(),
|
||||||
|
)(input)
|
||||||
|
|
||||||
let (remaining, contents) = opt(verify(
|
// impl_balanced_bracket(
|
||||||
recognize(many_till(
|
// input,
|
||||||
anychar,
|
// |i| tag("(")(i),
|
||||||
alt((
|
// |i| peek(tag(")"))(i),
|
||||||
peek(recognize(one_of(")"))),
|
// |i| recognize(tuple((space0, org_line_ending)))(i),
|
||||||
recognize(tuple((space0, org_line_ending))),
|
// |i| tag(")")(i),
|
||||||
)),
|
// |s| s.get_parenthesis_depth(),
|
||||||
)),
|
// )
|
||||||
|s| s.len() > 0,
|
|
||||||
))(remaining)?;
|
// let (remaining, _) = tag("(")(input)?;
|
||||||
let (remaining, _) = tag(")")(remaining)?;
|
|
||||||
Ok((remaining, contents))
|
// let (remaining, contents) = opt(verify(
|
||||||
|
// recognize(many_till(
|
||||||
|
// anychar,
|
||||||
|
// alt((
|
||||||
|
// peek(recognize(one_of(")"))),
|
||||||
|
// recognize(tuple((space0, org_line_ending))),
|
||||||
|
// )),
|
||||||
|
// )),
|
||||||
|
// |s| s.len() > 0,
|
||||||
|
// ))(remaining)?;
|
||||||
|
// let (remaining, _) = tag(")")(remaining)?;
|
||||||
|
// Ok((remaining, contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
@ -150,6 +171,80 @@ fn end_header<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
|||||||
)(remaining)
|
)(remaining)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn balanced_bracket<
|
||||||
|
O: Matcher,
|
||||||
|
S: Matcher,
|
||||||
|
F: Matcher,
|
||||||
|
E: Matcher,
|
||||||
|
D: for<'ss> Fn(OrgSource<'ss>) -> BracketDepth,
|
||||||
|
>(
|
||||||
|
opening_parser: O,
|
||||||
|
stop_parser: S,
|
||||||
|
fail_parser: F,
|
||||||
|
end_parser: E,
|
||||||
|
depth_function: D,
|
||||||
|
) -> impl for<'s> Fn(OrgSource<'s>) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||||
|
move |input| {
|
||||||
|
impl_balanced_bracket::<&O, &S, &F, &E, &D>(
|
||||||
|
input,
|
||||||
|
&opening_parser,
|
||||||
|
&stop_parser,
|
||||||
|
&fail_parser,
|
||||||
|
&end_parser,
|
||||||
|
&depth_function,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn impl_balanced_bracket<
|
||||||
|
's,
|
||||||
|
O: Matcher,
|
||||||
|
S: Matcher,
|
||||||
|
F: Matcher,
|
||||||
|
E: Matcher,
|
||||||
|
D: for<'ss> Fn(OrgSource<'ss>) -> BracketDepth,
|
||||||
|
>(
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
opening_parser: O,
|
||||||
|
stop_parser: S,
|
||||||
|
fail_parser: F,
|
||||||
|
end_parser: E,
|
||||||
|
depth_function: D,
|
||||||
|
) -> Res<OrgSource<'s>, Option<OrgSource<'s>>> {
|
||||||
|
let (mut remaining, _) = opening_parser(input)?;
|
||||||
|
let contents_start = remaining;
|
||||||
|
let original_depth = depth_function(remaining);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let bracket_depth = depth_function(remaining);
|
||||||
|
if bracket_depth == original_depth {
|
||||||
|
let (remain, stop_result) = opt(&stop_parser)(remaining)?;
|
||||||
|
remaining = remain;
|
||||||
|
if stop_result.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fail_parser(remaining).is_ok() {
|
||||||
|
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||||
|
"Fail parser matched.",
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (remain, _) = anychar(remaining)?;
|
||||||
|
remaining = remain;
|
||||||
|
}
|
||||||
|
let contents_end = remaining;
|
||||||
|
|
||||||
|
let (remaining, _) = end_parser(remaining)?;
|
||||||
|
let contents = if contents_start != contents_end {
|
||||||
|
Some(contents_start.get_until(contents_end))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok((remaining, contents))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user