How can I read this JSON into a (breakable) table(x)

I have a file creds.json

{
    "test1.example.com": [
        {
            "Password": "obfuscated",
            "User": "userA"
        },
        {
            "Password": "############",
            "User": "userB"
        }
    ],
    "test2.example.com": [
        {
            "Password": "obfuscated",
            "User": "UserC"
        },
        {
            "Password": "############",
            "User": "UserD"
        }
    ]
}

and would like to get one breakable typst table(x) with each domain name in a colspan and three columns

  1. Nr (counter starting at 1 incremented for each User (so the last line here would be ‘4’))
  2. User,
  3. Password,

Is that possible? If not can it be done with a YAML file? (edited)

ok this is pretty horrible but it works

#let data = json("data.json")
#let keys = data.values().first().first().keys()
#let i = 1
#table(
  columns: 2 + keys.len(),
  table.header([], "Nr", ..keys),
  ..for (domain, entries) in data {
    (table.cell(rowspan: entries.len(), domain),)
    entries.enumerate().map(((e, entry)) => (str(i + e), ..entry.values()))
    i += entries.len()
  }.flatten()
)

edit: i cannot read

1 Like
#let data = json("data.json")
#let i = 0
#table(
  columns: 3,
  ..for server in data {
    (
      table.cell(colspan: 3, server.at(0)),
      ..for login in server.at(1) {
        i = i + 1
        (
          [#i],
          login.User,
          login.Password,
        )
      },
    )
  }
)

This makes use of the fact that if all iterations of a for-loop produce arrays, then the for-loop itself evaluates to the concatenation of these arrays, which we then can spread using ..

2 Likes

Fantastic. Exactly what I needed.

Thank you so much.