mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Small fixes for table line priority in headers/footers (#3602)
This commit is contained in:
parent
c29db5f27e
commit
288f7da4d0
@ -1731,21 +1731,44 @@ impl<'a> GridLayouter<'a> {
|
|||||||
})
|
})
|
||||||
.unwrap_or(LinePosition::Before);
|
.unwrap_or(LinePosition::Before);
|
||||||
|
|
||||||
|
// FIXME: In the future, directly specify in 'self.rrows' when
|
||||||
|
// we place a repeated header rather than its original rows.
|
||||||
|
// That would let us remove most of those verbose checks, both
|
||||||
|
// in 'lines.rs' and here. Those checks also aren't fully
|
||||||
|
// accurate either, since they will also trigger when some rows
|
||||||
|
// have been removed between the header and what's below it.
|
||||||
|
let is_under_repeated_header = self
|
||||||
|
.grid
|
||||||
|
.header
|
||||||
|
.as_ref()
|
||||||
|
.and_then(Repeatable::as_repeated)
|
||||||
|
.zip(prev_y)
|
||||||
|
.is_some_and(|(header, prev_y)| {
|
||||||
|
// Note: 'y == header.end' would mean we're right below
|
||||||
|
// the NON-REPEATED header, so that case should return
|
||||||
|
// false.
|
||||||
|
prev_y < header.end && y > header.end
|
||||||
|
});
|
||||||
|
|
||||||
// If some grid rows were omitted between the previous resolved
|
// If some grid rows were omitted between the previous resolved
|
||||||
// row and the current one, we ensure lines below the previous
|
// row and the current one, we ensure lines below the previous
|
||||||
// row don't "disappear" and are considered, albeit with less
|
// row don't "disappear" and are considered, albeit with less
|
||||||
// priority. However, don't do this when we're below a header,
|
// priority. However, don't do this when we're below a header,
|
||||||
// as it must have more priority instead of less, so it is
|
// as it must have more priority instead of less, so it is
|
||||||
// chained later instead of before.
|
// chained later instead of before. The exception is when the
|
||||||
|
// last row in the header is removed, in which case we append
|
||||||
|
// both the lines under the row above us and also (later) the
|
||||||
|
// lines under the header's (removed) last row.
|
||||||
let prev_lines = prev_y
|
let prev_lines = prev_y
|
||||||
.filter(|prev_y| {
|
.filter(|prev_y| {
|
||||||
prev_y + 1 != y
|
prev_y + 1 != y
|
||||||
&& !self
|
&& (!is_under_repeated_header
|
||||||
.grid
|
|| self
|
||||||
.header
|
.grid
|
||||||
.as_ref()
|
.header
|
||||||
.and_then(Repeatable::as_repeated)
|
.as_ref()
|
||||||
.is_some_and(|header| prev_y + 1 == header.end)
|
.and_then(Repeatable::as_repeated)
|
||||||
|
.is_some_and(|header| prev_y + 1 != header.end))
|
||||||
})
|
})
|
||||||
.map(|prev_y| get_hlines_at(prev_y + 1))
|
.map(|prev_y| get_hlines_at(prev_y + 1))
|
||||||
.unwrap_or(&[]);
|
.unwrap_or(&[]);
|
||||||
@ -1765,15 +1788,16 @@ impl<'a> GridLayouter<'a> {
|
|||||||
&[]
|
&[]
|
||||||
};
|
};
|
||||||
|
|
||||||
// The header lines, if any, will correspond to the lines under
|
let mut expected_header_line_position = LinePosition::Before;
|
||||||
// the previous row, so they function similarly to 'prev_lines'.
|
|
||||||
let expected_header_line_position = expected_prev_line_position;
|
|
||||||
let header_hlines = if let Some((Repeatable::Repeated(header), prev_y)) =
|
let header_hlines = if let Some((Repeatable::Repeated(header), prev_y)) =
|
||||||
self.grid.header.as_ref().zip(prev_y)
|
self.grid.header.as_ref().zip(prev_y)
|
||||||
{
|
{
|
||||||
if prev_y + 1 != y
|
if is_under_repeated_header
|
||||||
&& prev_y + 1 == header.end
|
&& (!self.grid.has_gutter
|
||||||
&& !self.grid.has_gutter
|
|| matches!(
|
||||||
|
self.grid.rows[prev_y],
|
||||||
|
Sizing::Rel(length) if length.is_zero()
|
||||||
|
))
|
||||||
{
|
{
|
||||||
// For lines below a header, give priority to the
|
// For lines below a header, give priority to the
|
||||||
// lines originally below the header rather than
|
// lines originally below the header rather than
|
||||||
@ -1783,10 +1807,18 @@ impl<'a> GridLayouter<'a> {
|
|||||||
// lines being normally laid out then will be
|
// lines being normally laid out then will be
|
||||||
// precisely the lines below the header.
|
// precisely the lines below the header.
|
||||||
//
|
//
|
||||||
// Additionally, we don't append header lines when
|
// Additionally, we don't repeat lines above the row
|
||||||
// gutter is enabled, since, in that case, there will
|
// below the header when gutter is enabled, since, in
|
||||||
// be a gutter row between header and content, so no
|
// that case, there will be a gutter row between header
|
||||||
// lines should overlap.
|
// and content, so no lines should overlap. The
|
||||||
|
// exception is when the gutter at the end of the
|
||||||
|
// header has a size of zero, which happens when only
|
||||||
|
// column-gutter is specified, for example. In that
|
||||||
|
// case, we still repeat the line under the gutter.
|
||||||
|
expected_header_line_position = expected_line_position(
|
||||||
|
header.end,
|
||||||
|
header.end == self.grid.rows.len(),
|
||||||
|
);
|
||||||
get_hlines_at(header.end)
|
get_hlines_at(header.end)
|
||||||
} else {
|
} else {
|
||||||
&[]
|
&[]
|
||||||
|
@ -547,7 +547,7 @@ pub(super) fn hline_stroke_at_column(
|
|||||||
// Ensure the row above us is a repeated header.
|
// Ensure the row above us is a repeated header.
|
||||||
// FIXME: Make this check more robust when headers at arbitrary
|
// FIXME: Make this check more robust when headers at arbitrary
|
||||||
// positions are added.
|
// positions are added.
|
||||||
local_top_y + 1 == header.end && y != header.end
|
local_top_y < header.end && y > header.end
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prioritize the footer's top stroke as well where applicable.
|
// Prioritize the footer's top stroke as well where applicable.
|
||||||
@ -559,7 +559,7 @@ pub(super) fn hline_stroke_at_column(
|
|||||||
// Ensure the row below us is a repeated footer.
|
// Ensure the row below us is a repeated footer.
|
||||||
// FIXME: Make this check more robust when footers at arbitrary
|
// FIXME: Make this check more robust when footers at arbitrary
|
||||||
// positions are added.
|
// positions are added.
|
||||||
local_top_y.unwrap_or(0) + 1 != footer.start && y == footer.start
|
local_top_y.unwrap_or(0) + 1 < footer.start && y >= footer.start
|
||||||
});
|
});
|
||||||
|
|
||||||
let (prioritized_cell_stroke, deprioritized_cell_stroke) =
|
let (prioritized_cell_stroke, deprioritized_cell_stroke) =
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 41 KiB |
@ -26,3 +26,16 @@
|
|||||||
gutter: 3pt,
|
gutter: 3pt,
|
||||||
table.footer[a][b][c]
|
table.footer[a][b][c]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Test footer stroke priority edge case
|
||||||
|
#set page(height: 10em)
|
||||||
|
#table(
|
||||||
|
columns: 2,
|
||||||
|
stroke: black,
|
||||||
|
..(table.cell(stroke: aqua)[d],) * 8,
|
||||||
|
table.footer(
|
||||||
|
table.cell(rowspan: 2, colspan: 2)[a],
|
||||||
|
[c], [d]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -56,3 +56,44 @@
|
|||||||
),
|
),
|
||||||
[a\ b]
|
[a\ b]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Test header stroke priority edge case (last header row removed)
|
||||||
|
#set page(height: 8em)
|
||||||
|
#table(
|
||||||
|
columns: 2,
|
||||||
|
stroke: black,
|
||||||
|
gutter: (auto, 3pt),
|
||||||
|
table.header(
|
||||||
|
[c], [d],
|
||||||
|
),
|
||||||
|
..(table.cell(stroke: aqua)[d],) * 8,
|
||||||
|
)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Yellow line should be kept here
|
||||||
|
#set text(6pt)
|
||||||
|
#table(
|
||||||
|
column-gutter: 3pt,
|
||||||
|
inset: 1pt,
|
||||||
|
table.header(
|
||||||
|
[a],
|
||||||
|
table.hline(stroke: yellow),
|
||||||
|
),
|
||||||
|
table.cell(rowspan: 2)[b]
|
||||||
|
)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Red line should be kept here
|
||||||
|
#set page(height: 6em)
|
||||||
|
#set text(6pt)
|
||||||
|
#table(
|
||||||
|
column-gutter: 3pt,
|
||||||
|
inset: 1pt,
|
||||||
|
table.header(
|
||||||
|
table.hline(stroke: red, position: bottom),
|
||||||
|
[a],
|
||||||
|
),
|
||||||
|
[a],
|
||||||
|
table.cell(stroke: aqua)[b]
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user