Thanks for all your help, I’ve converged now on this #show table solution that seems to work pretty well. The vertical height might not always be minimal but that’s not important, at least no input I’ve tested so far looks unreasonable.
// an empty table cell that stores its own layout space as metadata
#let measurement-cell(table-id, x) = table.cell(
inset: 0pt,
stroke: none,
x: x, // set x explicitly to be robust against dangling cells in the table definition
layout(s => [#metadata(s)#label(table-id)]),
)
#let measurement-cells(table-id, n) = range(n).map(i => measurement-cell(table-id, i))
#let full-width-table(tbl) = {
let f = tbl.fields()
let columns = f.remove("columns")
let children = f.remove("children")
context {
// use a counter to generate the unique ID needed to store the metadata
let table-id = counter("table-id")
table-id.step()
let table-id = "table" + str(table-id.get().first())
// retrieve the resolved cell sizes from the first layout
// iteration and give each column a proportional fr size,
// this will expand all columns such that the table now has
// full page width
let computed-sizes = query(label(table-id))
let columns-sizes = columns
if computed-sizes.len() != 0 {
columns-sizes = computed-sizes.map(md => calc.round(md.value.width.pt()) * 1fr)
}
table(
columns: columns-sizes,
..f,
..children,
// insert the invisible measurement cells in the last row
..measurement-cells(table-id, columns.len()),
)
}
}
#show table: it => {
// this is a bit hacky, determine if the table was already modified
// by a zero inset measurement cell that was appended, the assumption
// being that normal cells wouldn't have zero inset
let is-processed = it.children.last().at("inset", default: none) == 0pt
if is-processed {
it
} else {
full-width-table(it)
}
}