Wit

Load a CSV into a table

Render a real .csv file as a table without hand-typing a single row — the header line becomes the columns automatically. This is a focused excerpt of A report with live data.

Step 1 — Point a source at the file

Any program that emits CSV to standard output works; cat is the simplest. Wire it in wit.sources.json.

{
  "sources": {
    "downloads": { "run": ["cat", "data/downloads.csv"], "format": "csv" }
  }
}

Step 2 — Load and render it

@load downloads load@

@table |rows @downloads|

Step 3 — Build

wit build report.wit --sources wit.sources.json --allow-exec --fragment
Result.

The header row — say platform,downloads,change— becomes three th columns, and each remaining line becomes one tr. The verified output starts: <thead><tr><th>platform</th>….

When you don't have a file

Two forms cover the tables you type by hand, and both build green.

Inline rows

The first inner array is the header.

source
@table |caption Corpus splits| |rows [[Group, A, B], [Teens, 8, 6.5]]|
result
Corpus splits
GroupAB
Teens86.5

Schema plus rows

Supply the header separately, then feed a defined collection of records as the body.

source
#corpus: [
  { split - Train, docs - 40k, tokens - 12.4M }
  { split - Dev, docs - 5k, tokens - 1.5M }
] !!

@table
  |schema [split, docs, tokens]|
  |rows @corpus|
table@
result
splitdocstokens
Train40k12.4M
Dev5k1.5M

This renders a header of split, docs, tokensand one row per record.

Pitfalls

  • Don't freeze the table. A frozen table written with a double fence does not resolve reference rows — use a plain @table so |rows @downloads| is looked up.
  • Commas still split records. A cell like 12.4M is fine, but Attention, Perception inside a { } record reads as two fields.

See also

A report with live data

shows the full data flow; Core vocabulary lists the table nodes.