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 --fragmentResult. 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.
@table |caption Corpus splits| |rows [[Group, A, B], [Teens, 8, 6.5]]|
| Group | A | B |
|---|---|---|
| Teens | 8 | 6.5 |
Schema plus rows
Supply the header separately, then feed a defined collection of records as the body.
#corpus: [ { split - Train, docs - 40k, tokens - 12.4M } { split - Dev, docs - 5k, tokens - 1.5M } ] !! @table |schema [split, docs, tokens]| |rows @corpus| table@
| split | docs | tokens |
|---|---|---|
| Train | 40k | 12.4M |
| Dev | 5k | 1.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
@tableso|rows @downloads|is looked up. - Commas still split records. A cell like
12.4Mis fine, butAttention, Perceptioninside a{ }record reads as two fields.
See also
A report with live datashows the full data flow; Core vocabulary lists the table nodes.