From 240f238eee4d6dfce7e3c4cabb9315ad052ca230 Mon Sep 17 00:00:00 2001
From: PgBiel <9021226+PgBiel@users.noreply.github.com>
Date: Sun, 23 Feb 2025 08:26:14 -0300
Subject: [PATCH] Fix HTML export of table with gutter (#5920)
---
.../typst-library/src/layout/grid/resolve.rs | 21 +++++++++++----
crates/typst-library/src/model/table.rs | 2 +-
tests/ref/html/col-gutter-table.html | 26 ++++++++++++++++++
tests/ref/html/col-row-gutter-table.html | 26 ++++++++++++++++++
tests/ref/html/row-gutter-table.html | 26 ++++++++++++++++++
tests/suite/layout/grid/html.typ | 27 +++++++++++++++++++
6 files changed, 122 insertions(+), 6 deletions(-)
create mode 100644 tests/ref/html/col-gutter-table.html
create mode 100644 tests/ref/html/col-row-gutter-table.html
create mode 100644 tests/ref/html/row-gutter-table.html
diff --git a/crates/typst-library/src/layout/grid/resolve.rs b/crates/typst-library/src/layout/grid/resolve.rs
index f6df57a37..762f94ed0 100644
--- a/crates/typst-library/src/layout/grid/resolve.rs
+++ b/crates/typst-library/src/layout/grid/resolve.rs
@@ -1526,11 +1526,7 @@ impl<'a> CellGrid<'a> {
self.entry(x, y).map(|entry| match entry {
Entry::Cell(_) => Axes::new(x, y),
Entry::Merged { parent } => {
- let c = if self.has_gutter {
- 1 + self.cols.len() / 2
- } else {
- self.cols.len()
- };
+ let c = self.non_gutter_column_count();
let factor = if self.has_gutter { 2 } else { 1 };
Axes::new(factor * (*parent % c), factor * (*parent / c))
}
@@ -1602,6 +1598,21 @@ impl<'a> CellGrid<'a> {
cell.rowspan.get()
}
}
+
+ #[inline]
+ pub fn non_gutter_column_count(&self) -> usize {
+ if self.has_gutter {
+ // Calculation: With gutters, we have
+ // 'cols = 2 * (non-gutter cols) - 1', since there is a gutter
+ // column between each regular column. Therefore,
+ // 'floor(cols / 2)' will be equal to
+ // 'floor(non-gutter cols - 1/2) = non-gutter-cols - 1',
+ // so 'non-gutter cols = 1 + floor(cols / 2)'.
+ 1 + self.cols.len() / 2
+ } else {
+ self.cols.len()
+ }
+ }
}
/// Given a cell's requested x and y, the vector with the resolved cell
diff --git a/crates/typst-library/src/model/table.rs b/crates/typst-library/src/model/table.rs
index 82c1cc08b..6f4461bd4 100644
--- a/crates/typst-library/src/model/table.rs
+++ b/crates/typst-library/src/model/table.rs
@@ -282,7 +282,7 @@ fn show_cell_html(tag: HtmlTag, cell: &Cell, styles: StyleChain) -> Content {
fn show_cellgrid_html(grid: CellGrid, styles: StyleChain) -> Content {
let elem = |tag, body| HtmlElem::new(tag).with_body(Some(body)).pack();
- let mut rows: Vec<_> = grid.entries.chunks(grid.cols.len()).collect();
+ let mut rows: Vec<_> = grid.entries.chunks(grid.non_gutter_column_count()).collect();
let tr = |tag, row: &[Entry]| {
let row = row
diff --git a/tests/ref/html/col-gutter-table.html b/tests/ref/html/col-gutter-table.html
new file mode 100644
index 000000000..54170f534
--- /dev/null
+++ b/tests/ref/html/col-gutter-table.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+ a |
+ b |
+ c |
+
+
+ d |
+ e |
+ f |
+
+
+ g |
+ h |
+ i |
+
+
+
+
diff --git a/tests/ref/html/col-row-gutter-table.html b/tests/ref/html/col-row-gutter-table.html
new file mode 100644
index 000000000..54170f534
--- /dev/null
+++ b/tests/ref/html/col-row-gutter-table.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+ a |
+ b |
+ c |
+
+
+ d |
+ e |
+ f |
+
+
+ g |
+ h |
+ i |
+
+
+
+
diff --git a/tests/ref/html/row-gutter-table.html b/tests/ref/html/row-gutter-table.html
new file mode 100644
index 000000000..54170f534
--- /dev/null
+++ b/tests/ref/html/row-gutter-table.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+ a |
+ b |
+ c |
+
+
+ d |
+ e |
+ f |
+
+
+ g |
+ h |
+ i |
+
+
+
+
diff --git a/tests/suite/layout/grid/html.typ b/tests/suite/layout/grid/html.typ
index 2a7dfc2ce..10345cb06 100644
--- a/tests/suite/layout/grid/html.typ
+++ b/tests/suite/layout/grid/html.typ
@@ -30,3 +30,30 @@
[row],
),
)
+
+--- col-gutter-table html ---
+#table(
+ columns: 3,
+ column-gutter: 3pt,
+ [a], [b], [c],
+ [d], [e], [f],
+ [g], [h], [i]
+)
+
+--- row-gutter-table html ---
+#table(
+ columns: 3,
+ row-gutter: 3pt,
+ [a], [b], [c],
+ [d], [e], [f],
+ [g], [h], [i]
+)
+
+--- col-row-gutter-table html ---
+#table(
+ columns: 3,
+ gutter: 3pt,
+ [a], [b], [c],
+ [d], [e], [f],
+ [g], [h], [i]
+)