How to programatically set the first row in a table as table.header?

Hi, I would like to set the first row in my tables as the table header. This is particularly useful when importing tables from csv files, for example.

1 Like

Hi and welcome to the forum!

This should achieve what you’re looking for:

#show table: it => {
  let fields = it.fields()
  let children = fields.remove("children")
  if children.at(0, default: none).func() == table.header {
    // already has a header
    return it
  }
  
  let cols = it.columns.len()
  let firstrow = children.slice(0, cols)
  let rest = children.slice(cols)
  table(
    ..fields,
    table.header(..firstrow),
    ..rest
  )
}

(Inspiration taken from here)

4 Likes

See this issue error type none has no method `func` with zero · Issue #41 · Mc-Zen/zero · GitHub

It may be safe to protect the access to the first child, which could be empty, with this:

if children.len() == 0 or children.at(0, default: none).func() == table.header

Which gives the full solution:

#show table: it => {
  let fields = it.fields()
  let children = fields.remove("children")
  if children.len() == 0 or children.at(0, default: none).func() == table.header {
    // already has a header
    return it
  }
  
  let cols = it.columns.len()
  let firstrow = children.slice(0, cols)
  let rest = children.slice(cols)
  table(
    ..fields,
    table.header(..firstrow),
    ..rest
  )
}

Thanks to @Mc-Zen for this addendum!

1 Like