Add a minimum stars figure to heading parser to reduce re-parses.

This commit is contained in:
Tom Alexander 2023-08-29 13:48:10 -04:00
parent bfc88c1d1b
commit 1d06d95bb1
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -139,7 +139,7 @@ fn _document<'r, 's>(
input: OrgSource<'s>, input: OrgSource<'s>,
) -> Res<OrgSource<'s>, Document<'s>> { ) -> Res<OrgSource<'s>, Document<'s>> {
let zeroth_section_matcher = parser_with_context!(zeroth_section)(context); let zeroth_section_matcher = parser_with_context!(zeroth_section)(context);
let heading_matcher = parser_with_context!(heading)(context); let heading_matcher = parser_with_context!(heading(0))(context);
let (remaining, _blank_lines) = many0(blank_line)(input)?; let (remaining, _blank_lines) = many0(blank_line)(input)?;
let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?; let (remaining, zeroth_section) = opt(zeroth_section_matcher)(remaining)?;
let (remaining, children) = many0(heading_matcher)(remaining)?; let (remaining, children) = many0(heading_matcher)(remaining)?;
@ -266,21 +266,25 @@ fn section_end<'r, 's>(
recognize(detect_headline)(input) recognize(detect_headline)(input)
} }
const fn heading(
parent_stars: usize,
) -> impl for<'r, 's> Fn(Context<'r, 's>, OrgSource<'s>) -> Res<OrgSource<'s>, Heading<'s>> {
move |context: Context, input: OrgSource<'_>| _heading(context, input, parent_stars)
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn heading<'r, 's>( fn _heading<'r, 's>(
context: Context<'r, 's>, context: Context<'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
parent_stars: usize,
) -> Res<OrgSource<'s>, Heading<'s>> { ) -> Res<OrgSource<'s>, Heading<'s>> {
not(|i| context.check_exit_matcher(i))(input)?; not(|i| context.check_exit_matcher(i))(input)?;
let (remaining, (star_count, _ws, maybe_todo_keyword, title, heading_tags)) = let (remaining, (star_count, _ws, maybe_todo_keyword, title, heading_tags)) =
headline(context, input)?; headline(context, input, parent_stars)?;
let section_matcher = parser_with_context!(section)(context); let section_matcher = parser_with_context!(section)(context);
let heading_matcher = parser_with_context!(heading)(context); let heading_matcher = parser_with_context!(heading(star_count))(context);
let (remaining, children) = many0(alt(( let (remaining, children) = many0(alt((
map( map(heading_matcher, DocumentElement::Heading),
verify(heading_matcher, |h| h.stars > star_count),
DocumentElement::Heading,
),
map(section_matcher, DocumentElement::Section), map(section_matcher, DocumentElement::Section),
)))(remaining)?; )))(remaining)?;
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);
@ -308,6 +312,7 @@ fn detect_headline<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ()> {
fn headline<'r, 's>( fn headline<'r, 's>(
context: Context<'r, 's>, context: Context<'r, 's>,
input: OrgSource<'s>, input: OrgSource<'s>,
parent_stars: usize,
) -> Res< ) -> Res<
OrgSource<'s>, OrgSource<'s>,
( (
@ -330,7 +335,9 @@ fn headline<'r, 's>(
(_sol, star_count, ws, maybe_todo_keyword, title, maybe_tags, _ws, _line_ending), (_sol, star_count, ws, maybe_todo_keyword, title, maybe_tags, _ws, _line_ending),
) = tuple(( ) = tuple((
start_of_line, start_of_line,
many1_count(tag("*")), verify(many1_count(tag("*")), |star_count| {
*star_count > parent_stars
}),
space1, space1,
opt(tuple((heading_keyword, space1))), opt(tuple((heading_keyword, space1))),
many1(standard_set_object_matcher), many1(standard_set_object_matcher),