only match consecutive conflicting headers

This commit is contained in:
PgBiel 2025-04-07 21:19:28 -03:00
parent 8e50df544d
commit 05d4af43b6
2 changed files with 46 additions and 27 deletions

View File

@ -219,21 +219,47 @@ impl<'a> GridLayouter<'a> {
if first_header.unwrap().range().contains(&y) { if first_header.unwrap().range().contains(&y) {
consecutive_header_count += 1; consecutive_header_count += 1;
if self.upcoming_headers.get(consecutive_header_count).is_none_or( // TODO: surely there is a better way to do this
|h| { match self.upcoming_headers.get(consecutive_header_count) {
h.unwrap().start > first_header.unwrap().end // No more headers, so place the latest headers.
|| h.unwrap().level <= first_header.unwrap().level None => {
},
) {
// Next row either isn't a header. or is in a
// conflicting one, which is the sign that we need to go.
self.place_new_headers( self.place_new_headers(
first_header,
consecutive_header_count, consecutive_header_count,
None,
engine, engine,
)?; )?;
consecutive_header_count = 0; consecutive_header_count = 0;
} }
// Next header is not consecutive, so place the latest headers.
Some(next_header)
if next_header.unwrap().start > first_header.unwrap().end =>
{
self.place_new_headers(
consecutive_header_count,
None,
engine,
)?;
consecutive_header_count = 0;
}
// Next header is consecutive and conflicts with one or
// more of the latest consecutive headers, so we must
// place them before proceeding.
Some(next_header)
if next_header.unwrap().level
<= first_header.unwrap().level =>
{
self.place_new_headers(
consecutive_header_count,
Some(next_header),
engine,
)?;
consecutive_header_count = 0;
}
// Next header is a non-conflicting consecutive header.
// Keep collecting more headers.
_ => {}
}
y = first_header.unwrap().end; y = first_header.unwrap().end;
// Skip header rows during normal layout. // Skip header rows during normal layout.
continue; continue;

View File

@ -24,28 +24,21 @@ pub enum HeadersToLayout<'a> {
impl<'a> GridLayouter<'a> { impl<'a> GridLayouter<'a> {
pub fn place_new_headers( pub fn place_new_headers(
&mut self, &mut self,
first_header: &Repeatable<Header>,
consecutive_header_count: usize, consecutive_header_count: usize,
conflicting_header: Option<&Repeatable<Header>>,
engine: &mut Engine, engine: &mut Engine,
) -> SourceResult<()> { ) -> SourceResult<()> {
// Next row either isn't a header. or is in a
// conflicting one, which is the sign that we need to go.
let (consecutive_headers, new_upcoming_headers) = let (consecutive_headers, new_upcoming_headers) =
self.upcoming_headers.split_at(consecutive_header_count); self.upcoming_headers.split_at(consecutive_header_count);
self.upcoming_headers = new_upcoming_headers; self.upcoming_headers = new_upcoming_headers;
let (non_conflicting_headers, conflicting_headers) = match self let (non_conflicting_headers, conflicting_headers) = match conflicting_header {
.upcoming_headers Some(conflicting_header) => {
.get(consecutive_header_count)
.map(Repeatable::unwrap)
{
Some(next_header) if next_header.level <= first_header.unwrap().level => {
// All immediately conflicting headers will // All immediately conflicting headers will
// be placed as normal rows. // be placed as normal rows.
consecutive_headers.split_at( consecutive_headers.split_at(consecutive_headers.partition_point(|h| {
consecutive_headers conflicting_header.unwrap().level > h.unwrap().level
.partition_point(|h| next_header.level > h.unwrap().level), }))
)
} }
_ => (consecutive_headers, Default::default()), _ => (consecutive_headers, Default::default()),
}; };