mirror of
https://github.com/typst/typst
synced 2025-08-15 07:28:32 +08:00
create RowGroupData struct
This commit is contained in:
parent
9da25616a9
commit
2d4a81ec24
@ -908,6 +908,26 @@ struct CellGridResolver<'a, 'b, 'x> {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
enum RowGroupKind {
|
||||
Header,
|
||||
Footer,
|
||||
}
|
||||
|
||||
struct RowGroupData {
|
||||
/// The range of rows of cells inside this grid row group. The
|
||||
/// first and last rows are guaranteed to have cells (an exception
|
||||
/// is made when there is gutter, in which case the group range may
|
||||
/// be expanded to include an additional gutter row when there is a
|
||||
/// repeatable header or footer). This is `None` until the first
|
||||
/// cell of the row group is placed, then it is continually adjusted
|
||||
/// to fit the cells inside the row group.
|
||||
///
|
||||
/// This stays as `None` for fully empty headers and footers.
|
||||
range: Option<Range<usize>>,
|
||||
span: Span,
|
||||
kind: RowGroupKind,
|
||||
}
|
||||
|
||||
impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
fn resolve<T, C, I>(mut self, children: C) -> SourceResult<CellGrid<'x>>
|
||||
where
|
||||
@ -1209,11 +1229,12 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
T: ResolvableCell + Default,
|
||||
I: Iterator<Item = ResolvableGridItem<T>>,
|
||||
{
|
||||
let mut is_header = false;
|
||||
let mut is_footer = false;
|
||||
|
||||
// This is true for any header or footer.
|
||||
let mut is_row_group = false;
|
||||
// Data for the row group in this iteration.
|
||||
//
|
||||
// Note that cells outside headers and footers are grid children
|
||||
// with a single cell inside, and thus not considered row groups,
|
||||
// in which case this variable remains 'None'.
|
||||
let mut row_group_data: Option<RowGroupData> = None;
|
||||
|
||||
// The normal auto index should only be stepped (upon placing an
|
||||
// automatically-positioned cell, to indicate the position of the
|
||||
@ -1227,20 +1248,6 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
// instead, and use a separate counter outside them.
|
||||
let mut local_auto_index = *auto_index;
|
||||
|
||||
// The range of rows of cells inside this grid row group. The
|
||||
// first and last rows are guaranteed to have cells (an exception
|
||||
// is made when there is gutter, in which case the group range may
|
||||
// be expanded to include an additional gutter row when there is a
|
||||
// repeatable header or footer). This is 'None' until the first
|
||||
// cell of the row group is placed, then it is continually adjusted
|
||||
// to fit the cells inside the row group.
|
||||
//
|
||||
// Note that cells outside headers and footers are grid children
|
||||
// with a single cell inside, and thus not considered row groups,
|
||||
// in which case this variable remains 'None'.
|
||||
let mut group_range: Option<Range<usize>> = None;
|
||||
let mut group_span = Span::detached();
|
||||
|
||||
// The first row in which this table group can fit.
|
||||
//
|
||||
// Within headers and footers, this will correspond to the first
|
||||
@ -1255,9 +1262,9 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
bail!(span, "cannot have more than one header");
|
||||
}
|
||||
|
||||
is_header = true;
|
||||
is_row_group = true;
|
||||
group_span = span;
|
||||
row_group_data =
|
||||
Some(RowGroupData { range: None, span, kind: RowGroupKind::Header });
|
||||
|
||||
*repeat_header = repeat;
|
||||
|
||||
first_available_row =
|
||||
@ -1281,9 +1288,9 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
bail!(span, "cannot have more than one footer");
|
||||
}
|
||||
|
||||
is_footer = true;
|
||||
is_row_group = true;
|
||||
group_span = span;
|
||||
row_group_data =
|
||||
Some(RowGroupData { range: None, span, kind: RowGroupKind::Footer });
|
||||
|
||||
*repeat_footer = repeat;
|
||||
|
||||
first_available_row =
|
||||
@ -1418,7 +1425,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
&mut local_auto_index,
|
||||
first_available_row,
|
||||
c,
|
||||
is_row_group,
|
||||
row_group_data.is_some(),
|
||||
)
|
||||
.at(cell_span)?
|
||||
};
|
||||
@ -1449,10 +1456,10 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
|
||||
// Cell's header or footer must expand to include the cell's
|
||||
// occupied positions, if possible.
|
||||
if is_row_group {
|
||||
group_range = Some(
|
||||
if let Some(RowGroupData { range: group_range, .. }) = &mut row_group_data {
|
||||
*group_range = Some(
|
||||
expand_row_group(
|
||||
&*resolved_cells,
|
||||
resolved_cells,
|
||||
group_range.as_ref(),
|
||||
first_available_row,
|
||||
y,
|
||||
@ -1534,8 +1541,9 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_row_group {
|
||||
let group_range = match group_range {
|
||||
|
||||
if let Some(row_group) = row_group_data {
|
||||
let group_range = match row_group.range {
|
||||
Some(group_range) => group_range,
|
||||
|
||||
None => {
|
||||
@ -1572,10 +1580,11 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
}
|
||||
};
|
||||
|
||||
if is_header {
|
||||
match row_group.kind {
|
||||
RowGroupKind::Header => {
|
||||
if group_range.start != 0 {
|
||||
bail!(
|
||||
group_span,
|
||||
row_group.span,
|
||||
"header must start at the first row";
|
||||
hint: "remove any rows before the header"
|
||||
);
|
||||
@ -1590,12 +1599,12 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
});
|
||||
}
|
||||
|
||||
if is_footer {
|
||||
RowGroupKind::Footer => {
|
||||
// Only check if the footer is at the end later, once we know
|
||||
// the final amount of rows.
|
||||
*footer = Some((
|
||||
group_range.end,
|
||||
group_span,
|
||||
row_group.span,
|
||||
Footer {
|
||||
// Later on, we have to correct this number in case there
|
||||
// is gutter, but only once all cells have been analyzed
|
||||
@ -1607,6 +1616,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The child was a single cell outside headers or footers.
|
||||
// Therefore, 'local_auto_index' for this table child was
|
||||
@ -1848,7 +1858,7 @@ fn resolve_cell_position(
|
||||
auto_index: &mut usize,
|
||||
first_available_row: usize,
|
||||
columns: usize,
|
||||
is_row_group: bool,
|
||||
in_row_group: bool,
|
||||
) -> HintedStrResult<usize> {
|
||||
// Translates a (x, y) position to the equivalent index in the final cell vector.
|
||||
// Errors if the position would be too large.
|
||||
@ -1925,7 +1935,7 @@ fn resolve_cell_position(
|
||||
// Ensure it doesn't conflict with an existing header or
|
||||
// footer (but only if it isn't already in one, otherwise there
|
||||
// will already be a separate check).
|
||||
if !is_row_group {
|
||||
if !in_row_group {
|
||||
check_for_conflicting_cell_row(header, footer, cell_y, rowspan)?;
|
||||
}
|
||||
|
||||
@ -1987,7 +1997,7 @@ fn resolve_cell_position(
|
||||
// Ensure it doesn't conflict with an existing header or
|
||||
// footer (but only if it isn't already in one, otherwise there
|
||||
// will already be a separate check).
|
||||
if !is_row_group {
|
||||
if !in_row_group {
|
||||
check_for_conflicting_cell_row(header, footer, cell_y, rowspan)?;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user