How to fill a 2-column-table with key value pairs of an array?

Hi, I want to write a function, which gets an array of key value pairs and these pairs must be displayed in a table. Can anybody give me an example?

I tried this, but it doesnt work:

#let mainline(..moves) = {
  align(center)[
  #table(
  columns: (2.6cm, 2.6cm),
  stroke: none,
  align: (left, right),

// ??????? What to write here ??????????????// 

//  [*1.e2-e4*], [*e7-e5*],
//  [*2.Sg1-f3*], [*f7-f5*],
//  [*3.Sf3xe5*],
  )// table
] 
} // mainline


#mainline(
  (
    ("1.e2-e4", "e7-e5"), 
    ("2.Sg1-f3", "f7-f5"), 
  ),
)

Hi Friedrich, and welcome to the forum!

The table function takes a variable amount of entries as its arguments, which are then laid out row by row. To pass the data as a list of tuples (like you currently do), you can use the flatten method to convert that list to a one-dimensional array, where the tuple structure is removed.

Now, since the table function does not take an array as its argument, but a variable amount of values (as in #table(first, second, third, ...), you can use the spreading operator .., which spreads the contents of the array into the arguments of a function call.

The moves argument of the mainline function is of type arguments, which can contain both named and positional arguments. As we only care about the positional ones, you can use the pos function to get them as an array.

In total, you only need to add a very small piece to what you already have:

#let mainline(..moves) = align(center, table(
  columns: (2.6cm, 2.6cm),
  stroke: none,
  align: (left, right),
  ..moves.pos().flatten()
))

I also removed a bit of nesting to avoid unnecessary swapping between content mode and code mode. This doesn’t mean that there was anything wrong with it, it’s mostly just personal preference.

1 Like

as a minor note, the moves.pos() for the given input results in

(
  (
    ("1.e2-e4", "e7-e5"), 
    ("2.Sg1-f3", "f7-f5"), 
  ),
)

(an array of all parameters: there was only one parameter, and that parameter is an array containing arrays of two moves each) – since flatten() gets rid of arrays recursively, this extra layer made no difference for the table.

I suggest additionally doing one of two changes:

  1. instead of ..moves, write moves so that the single parameter (still an array) is processed directly.
  2. instead of passing an array of arrays, directly pass multiple arrays of moves:
    #mainline(
      ("1.e2-e4", "e7-e5"), 
      ("2.Sg1-f3", "f7-f5"), 
    )
    

In either case, the parameter (moves or moves.pos()) is the following:

(
  ("1.e2-e4", "e7-e5"), 
  ("2.Sg1-f3", "f7-f5"), 
)

Which is probably what you actually wanted to work with

1 Like

To be more clear, I would say it lays them from left to right and then from top to bottom.

Hi @Friedrich_Kirch, don’t forget to tick one of the responses if you got a satisfying answer. The answer you choose should usually be the response that you found most correct/helpful/comprehensive for the question you asked.