Formatting a json key value data in a rectangle grid

Hello all,

I am pretty new with typst and trying to learn typst by generating one existing pdf from json data. I am mainly exploring typst for generating pdf automatically from (json) data. This used to be generated using LaTeX + jinja work flow and I am trying to convert it to typst.

I have gone through the documentation as well as Typst Examples Book, but I have not yet reached a level of proficiency to ask specific questions, thus this question is pretty general.

I have an input data as follows:

{
    "Header": {
        "Name": "John Doe",
        "Branch Name": "New York",
        "Communication Address": "123 Infinite Loop, Acme City, New York",
        "Regd. Mobile Number": "123456789",
        "Address Last Updated On": "14/11/2018",
        "Customer ID": "1294786589"
    }
}

I am trying to format this approximately as the figure below:
screen01

The above image consists of two columns of key value data. Each column consists of a key, flexible space, a : followed by value. All the : are lined up in one column. But contrary to what is displayed here, rows in each column need not align with each other. For example the “Customer ID” need not align itsel with “Address Last Updated On” and can follow immediately after “Regd. Mobile Number” after a fixed gutter.

How can I go about formatting such a grid in Typst?

1 Like

You image is basically a table without strokes, so we can simply use table to arrange contents.

To automatically generate document from json data, we can use json to read data as a dict and get everything provided.

A example:

#let data = json("data.json").at("Header")

#set page(width: 460pt, height: auto, margin: 10pt)

#rect(
  table(
    stroke: none,
    columns: 4,
    rows: auto,
    ..data.keys().map(k => (k, ": " + data.at(k))).flatten()
  ),
)

gives

Thanks a lot, this almost works.
Just a bit of nitpick.

It will be perfect if the full text is rendered along the green line. I understand that my original example too was like the image in the answer.

Also the order of how the items appear in the table is determined by column major arrangement of how the data is structured in the incoming data. If it can be made row major, it will be easy for me to output the json in the way I want it to appear in the output.

Thanks!

Regarding text alignment, we can place : in its own column, like this:

#rect(
  table(
    stroke: none,
    columns: 6,
    column-gutter: (0em, -0.7em) * 2,
    rows: auto,
    ..data.keys().map(k => (k, ":", data.at(k))).flatten()
  ),
)

Note that column-gutter was set because placing : in its own column makes it too far from the text that follows it. We can adjust this by setting column-gutter.

Regarding the order of data arrangement, you can transpose it when exporting the JSON, or you can transpose it in Typst like this:

#set page(width: 460pt, height: auto, margin: 10pt)

#let data = json("data.json").at("Header")

#let data-arr = data.keys().map(k => (k, data.at(k))).chunks(3)
#let data-arr = array.zip(..data-arr)

#rect(
  table(
    stroke: none,
    columns: 6,
    column-gutter: (0em, -0.7em) * 2,
    rows: auto,
    ..data-arr.map(
      r => r.map(
        c => (c.at(0), ":", c.at(1))
      )
    ).flatten()
  ),
)
1 Like

Thanks! This works perfectly!