#Get all grid cells in a table to be equal width, while also auto-sizing to fit content inside them

3 messages · Page 1 of 1 (latest)

ebon echo
#

Context

Hi! I'm typesetting a table for a reference sheet I'm making where each row represents a probability distribution. For some rows (distributions), I've decided to put multiple formulas to show what they will look like for different parameters of the distribution.

Problem

My problem is... only some distributions have this multiple-interpretations-of-the-same-parameter conundrum, so only those distributions' rows need cells that span multiple columns (essentially, I'm wanting to "split" one cell in a table into multiple).

Attempted solution

Since my input is organised into a dictionary, and every distribution (row) which requires multi-column cell data is fed as an array, I am testing for this using a conditional and currently just using a grid inside the table cell. Observe:

#let distGridCreator(arr) = grid(
  columns: (auto,) * arr.len(),
  stroke: (right: 0.85pt),
  inset: 5pt,
  align: center + horizon,
  [
    #v(1fr)  // So the grid.vline goes all the way to the top
    #arr.first()
    #v(1fr)
  ],
  ..arr.slice(1, -1),
  grid.cell(stroke: (right: 0pt))[#arr.last()]  // So the last item doesn't have a stroke on the right, the table cell's stroke should do
)

My current main dilemma is that if I use auto as my column dimensions (as above), then the grid cells get typeset quite nicely with every equation fitting inside as well, but if one of the equations is shorter than the others, then it gets "less" area, which is not what I want. I want all the cells of the grid to be of equal width, but if I use 1fr as the dimension for the columns, then they all get equal width, but the table cell does not get resized for the entire grid and the equations spill out if they are longer than the space they get allocated as per the division by the fractional length (1fr).
-# See pictures attached for visual of the difference between auto and 1fr.

Summary

Is there any way to make sure all the equations fit inside the grid cells, and to have the grid cells be equal width? One way I can think to do this is to measure the width of every grid cell, pick the largest, and then reassign all grid cell widths to be that maximum width, but I don't really know how to go about doing this. I'm all ears if someone has a more elegant solution!

Link

Typst webapp link: https://typst.app/project/rpe1lw6KKogw0bQUIGZ0vS

summer barn
#

Hummm I think people have already think about that. This is not trivial I think and should require measuring stuff.

In my knowledge this is not possible with standard table and using only the columns argument with standard length, fraction, pourcentage...

ebon echo
#

Ok some development on this... I've tried to implement my own thing using measure and layout to pass in the container table cell's dimensions to the grid function, which then uses that to calculate a new width that every cell should be typeset as. But this is throwing a new error now.

Here's the code:

#let distGridCreator(arr, containerSize) = context [
  #let maxWidth = calc.max(..arr.map(it => measure(it).width))  // Width of the widest content to be typeset in a grid cell
  #let newMaxWidth = maxWidth + ((containerSize.width - arr.len() * maxWidth) / arr.len())  // Also split up the space left after typesetting `arr.len() * maxWidth` grid cells
  // #newMaxWidth  // This is always a finite value, so why do I get the error down below?
  #grid(
      columns: (newMaxWidth,) * arr.len(),  // Using `auto` here is fine, but using `newMaxWidth` give the error
      stroke: (right: 0.85pt),
      inset: 5pt,
      align: center + horizon,
      [
        #v(1fr)  // So the grid.vline goes all the way to the top
        #arr.first()
        #v(1fr)
      ],
      ..arr.slice(1, -1),
      grid.cell(stroke: (right: 0pt))[#arr.last()]  // So the last item doesn't have a stroke on the right, the table cell's stroke should do
    )
]

If I typeset the value of newMaxWidth, it appears to be a finite value (see image 1). However, if I supply newMaxWidth as the width of each cell to the grid's columns argument, then I get the error in image 2: cannot expand into infinite width.

My hunch is that the newMaxWidth value is being calculated after the grid is typeset, which interferes with using that value itself to typeset the grid (😭). Any way I can go about fixing this?