How can I iterate over all cells of a table in a show rule?

Dear all,

as the title says, I would like to iterate over all cells of a table in a show rule. That is:

#show table: it => {
  for child in it.children {
    if (WHAT DO I NEED TO WRITE HERE TO CHECK IF CHILD IS A CELL?) {
      /* Read the text from the body of the cell and do something with it. */
    }
  }
}

#table(
  columns: (auto, auto, 1fr, auto, auto),
  align: horizon,
  table.header(
    repeat: true
  )[Head 1][Head 2][Head 3][Head 4][Head 5]
)[1][2][3][4][5]


What if condition should I use to check whether the child is a cell?

A few additional remarks:

  • I am aware that I actually need to go recursively through all children to iterate over all cells. But that’s not my problem. My problem is that for the life of me I can’t find out how to check whether or not a child is a cell. Once I know that, implementing the recursion should be easy.
  • Of course, I would be open to other solutions. For example, I tried to select all cells with a selector, but without avail. Either that’s not possible, or I have been too silly to find out the correct way. With other selectors, I had no problems, though. I’ll be happy with every method that enables me to iterate over all cells of a table in a #show rule. It doesn’t need to be a recursive scan through all children.
  • There are some questions (along with answers) in this forum and elsewhere about how to automatically fill table cells with content (for example, from a CSV file). But I’d like to have it the other way around. I’d like to read the content of the cells.

Thank you very much in advance!

You were pretty close ;)

The table.cell values can be accessed via table.fields().children

Just try this and look at the output:

#table(
  columns: (auto, auto, 1fr, auto, auto),
  align: horizon,
  table.header(repeat: true,)[Head 1][Head 2][Head 3][Head 4][Head 5],
)[1][2][3][4][5].fields().children

There are a few examples on this forum, like Is it possible to have a function in set rule that are inside a show rule? - #16 by bluss

For your case, probably something like this:

#show table: it => {
  // Prevent infinite recursion
  if (it.has("label") and it.label == <table-style-done>) {
    it
  } else {
    let fields = it.fields()
    let children = fields.remove("children")
    let new-children = ()

    for child in children {
      if child.func() == table.cell {
        // Table cell
        new-children.push([_Modified_ #child])
      } else {
        // Table headers (array)
        new-children.push(child)
      }
    }
    // Recreate and return the table
    [#table(..fields, ..new-children)<table-style-done>]
  }
}

I see. child.func() was the key to solving the problem.

Now I have to find out how I can determine in which column a cell is. If I get stuck again, I’ll open a new question.

Thank you very much!

1 Like

Your use case has been very vague so far, but you may want to look at

#show table.cell.where(x: 1, y: 0): strong

Otherwise knowing the number of columns, you can keep a counter when iterating on the cells.