A first stab at a final item whitespace cut-off exit matcher.
This commit is contained in:
parent
bd187ebfe7
commit
47408763e5
@ -3,6 +3,7 @@ use nom::bytes::complete::tag;
|
|||||||
use nom::character::complete::anychar;
|
use nom::character::complete::anychar;
|
||||||
use nom::character::complete::digit1;
|
use nom::character::complete::digit1;
|
||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
|
use nom::character::complete::multispace1;
|
||||||
use nom::character::complete::one_of;
|
use nom::character::complete::one_of;
|
||||||
use nom::character::complete::space0;
|
use nom::character::complete::space0;
|
||||||
use nom::character::complete::space1;
|
use nom::character::complete::space1;
|
||||||
@ -17,6 +18,7 @@ use nom::multi::many0;
|
|||||||
use nom::multi::many1;
|
use nom::multi::many1;
|
||||||
use nom::multi::many_till;
|
use nom::multi::many_till;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
use nom::InputTake;
|
||||||
|
|
||||||
use super::affiliated_keyword::parse_affiliated_keywords;
|
use super::affiliated_keyword::parse_affiliated_keywords;
|
||||||
use super::element_parser::element;
|
use super::element_parser::element;
|
||||||
@ -81,6 +83,28 @@ where
|
|||||||
return Err(nom::Err::Error(CustomError::Static("No element detected.")));
|
return Err(nom::Err::Error(CustomError::Static("No element detected.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
|
)]
|
||||||
|
pub(crate) fn detect_not_plain_list_item_indent<'b, 'g, 'r, 's>(
|
||||||
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
) -> Res<OrgSource<'s>, (u16, OrgSource<'s>)> {
|
||||||
|
if let Ok((_remaining, (_, indent, _))) = tuple((
|
||||||
|
start_of_line,
|
||||||
|
parser_with_context!(indentation_level)(context),
|
||||||
|
not(tuple((
|
||||||
|
parser_with_context!(bullet)(context),
|
||||||
|
alt((space1, line_ending, eof)),
|
||||||
|
))),
|
||||||
|
))(input)
|
||||||
|
{
|
||||||
|
return Ok((input, indent));
|
||||||
|
}
|
||||||
|
return Err(nom::Err::Error(CustomError::Static("No element detected.")));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords))
|
tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords))
|
||||||
@ -204,15 +228,21 @@ fn plain_list_item<'b, 'g, 'r, 's>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let exit_matcher = plain_list_item_end(indent_level);
|
let exit_matcher = plain_list_item_end(indent_level);
|
||||||
|
let final_item_whitespace_cutoff = final_item_whitespace_cutoff(indent_level);
|
||||||
let contexts = [
|
let contexts = [
|
||||||
ContextElement::ConsumeTrailingWhitespace(true),
|
ContextElement::ConsumeTrailingWhitespace(true),
|
||||||
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
class: ExitClass::Beta,
|
class: ExitClass::Beta,
|
||||||
exit_matcher: &exit_matcher,
|
exit_matcher: &exit_matcher,
|
||||||
}),
|
}),
|
||||||
|
ContextElement::ExitMatcherNode(ExitMatcherNode {
|
||||||
|
class: ExitClass::Beta,
|
||||||
|
exit_matcher: &final_item_whitespace_cutoff,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
let parser_context = context.with_additional_node(&contexts[0]);
|
let parser_context = context.with_additional_node(&contexts[0]);
|
||||||
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
let parser_context = parser_context.with_additional_node(&contexts[1]);
|
||||||
|
let parser_context = parser_context.with_additional_node(&contexts[2]);
|
||||||
|
|
||||||
let maybe_contentless_item: Res<OrgSource<'_>, ()> =
|
let maybe_contentless_item: Res<OrgSource<'_>, ()> =
|
||||||
detect_contentless_item_contents(&parser_context, remaining);
|
detect_contentless_item_contents(&parser_context, remaining);
|
||||||
@ -356,6 +386,52 @@ fn counter_set_value<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, PlainListIt
|
|||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn final_item_whitespace_cutoff(indent_level: IndentationLevel) -> impl ContextMatcher {
|
||||||
|
move |context, input: OrgSource<'_>| {
|
||||||
|
impl_final_item_whitespace_cutoff(context, input, indent_level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "tracing",
|
||||||
|
tracing::instrument(ret, level = "debug", skip(context))
|
||||||
|
)]
|
||||||
|
fn impl_final_item_whitespace_cutoff<'b, 'g, 'r, 's>(
|
||||||
|
context: RefContext<'b, 'g, 'r, 's>,
|
||||||
|
input: OrgSource<'s>,
|
||||||
|
indent_level: IndentationLevel,
|
||||||
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
|
start_of_line(input)?;
|
||||||
|
// element!(plain_list_end, context, input);
|
||||||
|
|
||||||
|
if let Ok((_remaining, _)) = verify(
|
||||||
|
tuple((
|
||||||
|
opt(blank_line),
|
||||||
|
bind_context!(indentation_level, context),
|
||||||
|
not(multispace1),
|
||||||
|
)),
|
||||||
|
|(_, (depth, _stars), _not_whitespace)| *depth < indent_level,
|
||||||
|
)(input)
|
||||||
|
{
|
||||||
|
return Ok((input, input.take(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok((_remaining, _)) = tuple((
|
||||||
|
opt(blank_line),
|
||||||
|
verify(
|
||||||
|
bind_context!(detect_not_plain_list_item_indent, context),
|
||||||
|
|(depth, _)| *depth == indent_level,
|
||||||
|
),
|
||||||
|
))(input)
|
||||||
|
{
|
||||||
|
return Ok((input, input.take(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(nom::Err::Error(CustomError::Static(
|
||||||
|
"No whitespace cut-off.",
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "tracing",
|
feature = "tracing",
|
||||||
tracing::instrument(ret, level = "debug", skip(_context))
|
tracing::instrument(ret, level = "debug", skip(_context))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user