mirror of
https://github.com/typst/typst
synced 2025-05-17 02:25:27 +08:00
only match consecutive conflicting headers
This commit is contained in:
parent
8e50df544d
commit
05d4af43b6
@ -219,21 +219,47 @@ impl<'a> GridLayouter<'a> {
|
||||
if first_header.unwrap().range().contains(&y) {
|
||||
consecutive_header_count += 1;
|
||||
|
||||
if self.upcoming_headers.get(consecutive_header_count).is_none_or(
|
||||
|h| {
|
||||
h.unwrap().start > first_header.unwrap().end
|
||||
|| h.unwrap().level <= first_header.unwrap().level
|
||||
},
|
||||
) {
|
||||
// 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(
|
||||
first_header,
|
||||
consecutive_header_count,
|
||||
engine,
|
||||
)?;
|
||||
consecutive_header_count = 0;
|
||||
// TODO: surely there is a better way to do this
|
||||
match self.upcoming_headers.get(consecutive_header_count) {
|
||||
// No more headers, so place the latest headers.
|
||||
None => {
|
||||
self.place_new_headers(
|
||||
consecutive_header_count,
|
||||
None,
|
||||
engine,
|
||||
)?;
|
||||
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;
|
||||
// Skip header rows during normal layout.
|
||||
continue;
|
||||
|
@ -24,28 +24,21 @@ pub enum HeadersToLayout<'a> {
|
||||
impl<'a> GridLayouter<'a> {
|
||||
pub fn place_new_headers(
|
||||
&mut self,
|
||||
first_header: &Repeatable<Header>,
|
||||
consecutive_header_count: usize,
|
||||
conflicting_header: Option<&Repeatable<Header>>,
|
||||
engine: &mut Engine,
|
||||
) -> 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) =
|
||||
self.upcoming_headers.split_at(consecutive_header_count);
|
||||
self.upcoming_headers = new_upcoming_headers;
|
||||
|
||||
let (non_conflicting_headers, conflicting_headers) = match self
|
||||
.upcoming_headers
|
||||
.get(consecutive_header_count)
|
||||
.map(Repeatable::unwrap)
|
||||
{
|
||||
Some(next_header) if next_header.level <= first_header.unwrap().level => {
|
||||
let (non_conflicting_headers, conflicting_headers) = match conflicting_header {
|
||||
Some(conflicting_header) => {
|
||||
// All immediately conflicting headers will
|
||||
// be placed as normal rows.
|
||||
consecutive_headers.split_at(
|
||||
consecutive_headers
|
||||
.partition_point(|h| next_header.level > h.unwrap().level),
|
||||
)
|
||||
consecutive_headers.split_at(consecutive_headers.partition_point(|h| {
|
||||
conflicting_header.unwrap().level > h.unwrap().level
|
||||
}))
|
||||
}
|
||||
_ => (consecutive_headers, Default::default()),
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user