Keeping table rows together at page boundaries

I wanted to write a longish table with groups of rows (separated by hlines) that should be kept together when the table flows over to the next page. The trick with an empty block and a negative v() space didn’t work well as it needs to know the resulting height of the row group beforehand which is hard to get at (with context and measure()).

Eventually I found a simpler solution that worked for me. I’d like to share it – not only for the benefit of anyone who might need it but also in the hope for improvement if there are better and/or easier ways to achieve the same effect.

So here is a short demo:

#let data = ("a", "b", "c", "d", "e", "f", "g", "h", "i",)

// regular table, will have pagebreaks somewhere

#table(
  columns: 2,
  stroke: none,
  table.header([*left*], [*right*]),
  ..for d in data {
    (
      table.hline(),
      [This is a left entry for #d;.],
      [This is a right entry for #d;.],
      [A second left entry], [A second right entry],
      [A third left entry], [A third right entry],
      [A fourth left entry], [A fourth right entry],
      [A fifth left entry], [A fifth right entry],
    )
  },
  table.hline(),
)

// the following table will be broken only at the `hline` block boundaries

#table(
  columns: (auto, auto, 0mm),
  column-gutter: (0pt, 0pt), // with non-zero gutter, leave last one at 0pt!
  stroke: none,
  table.header([*left*], [*right*]),  // no header for the dummy column
  ..for d in data {
    (
      table.hline(),
      [This is a left entry for #d;.],
      [This is a right entry for #d;.],
      table.cell(rowspan: 5, breakable: false, ""),  // ← insert this per block
      [A second left entry], [A second right entry],
      [A third left entry], [A third right entry],
      [A fourth left entry], [A fourth right entry],
      [A fifth left entry], [A fifth right entry],
    )
  },
  table.hline(),
)

The number of lines in each block has to be known and inserted into the rowspan. For generated content this shouldn’t be hard; for hand-written content it’s unwieldy, though.

2 Likes