Skip to content

Commit b071a78

Browse files
docs(examples): refresh key folding docs and samples
1 parent 9950fe8 commit b071a78

9 files changed

Lines changed: 142 additions & 57 deletions

examples/README.md

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,65 +11,70 @@ Complete, valid TOON files demonstrating core features:
1111
- [`valid/objects.toon`](valid/objects.toon) - Simple flat object with primitive values
1212
- Demonstrates basic key-value pairs
1313
- Shows multiple data types: string, number, boolean, null
14-
- Spec: §6 Objects
14+
- Spec: §8 Objects
1515

1616
- [`valid/nested-objects.toon`](valid/nested-objects.toon) - Multi-level nested objects
1717
- Demonstrates indentation-based nesting (2 spaces per level)
1818
- Shows how objects can contain other objects
19-
- Spec: §6 Objects, §4 Indentation
19+
- Spec: §8 Objects, §12 Indentation
2020

2121
### Arrays
2222

2323
- [`valid/primitive-arrays.toon`](valid/primitive-arrays.toon) - Inline primitive arrays
2424
- Demonstrates compact inline format `[N]: item1,item2,item3`
2525
- Shows empty arrays `[0]:`
2626
- Multiple arrays in one document
27-
- Spec: §7.1 Primitive Arrays
27+
- Spec: §9.1 Primitive Arrays
2828

2929
- [`valid/tabular-array.toon`](valid/tabular-array.toon) - Tabular array format (comma delimiter)
3030
- Demonstrates the most token-efficient format for uniform data
3131
- Header declares fields once: `{field1,field2,...}`
3232
- Rows contain only data values
33-
- Spec: §7.2 Tabular Arrays
33+
- Spec: §9.3 Tabular Arrays
3434

3535
- [`valid/mixed-array.toon`](valid/mixed-array.toon) - Mixed-type array (list format)
3636
- Demonstrates list format with `-` prefix
3737
- Shows arrays containing different types (number, object, string)
3838
- Useful when items don't have uniform structure
39-
- Spec: §7.3 Mixed Arrays
39+
- Spec: §9.4 Mixed Arrays
4040

4141
### Delimiters
4242

4343
- [`valid/pipe-delimiter.toon`](valid/pipe-delimiter.toon) - Pipe delimiter (`|`)
4444
- Shows alternative delimiter for tabular arrays
4545
- Delimiter marker appears in both header `[N|]` and field list `{field|...}`
4646
- Useful when data contains commas
47-
- Spec: §8 Delimiters
47+
- Spec: §11 Delimiters
4848

4949
- [`valid/tab-delimiter.toon`](valid/tab-delimiter.toon) - Tab delimiter (`\t`)
5050
- Demonstrates tab-separated tabular format
5151
- Tab character appears in both header and between fields
5252
- Useful for TSV-like data
53-
- Spec: §8 Delimiters
53+
- Spec: §11 Delimiters
5454

5555
### Key Folding and Path Expansion (v1.5+)
5656

57+
> Regenerate any of these examples via the reference CLI, e.g. `npx @toon-format/cli --encode --keyFolding safe examples/valid/key-folding-basic.json --output examples/valid/key-folding-basic.toon`.
58+
5759
- [`valid/key-folding-basic.toon`](valid/key-folding-basic.toon) - Basic dotted-key notation
58-
- Demonstrates collapsing nested objects: `server.host: localhost` instead of 3 indentation levels
59-
- Significant token savings for deeply nested configuration data
60-
- Requires encoder option `keyFolding="safe"` to produce; decoder expands with `expandPaths="safe"`
60+
- Demonstrates how `keyFolding="safe"` only folds chains of single-key objects (e.g. `server.host: localhost`)
61+
- Notes that siblings such as `database.connection.username` need their own wrapper objects in the JSON source
62+
- Generated directly from [`valid/key-folding-basic.json`](valid/key-folding-basic.json) using the CLI encoder
63+
- **Decode tip:** use `expandPaths="safe"` to reconstruct the nested JSON structure
6164
- Spec: §13.4 Key Folding and Path Expansion
6265

6366
- [`valid/key-folding-with-array.toon`](valid/key-folding-with-array.toon) - Dotted keys with arrays
64-
- Shows folding combined with inline arrays: `data.meta.items[3]: x,y,z`
65-
- Demonstrates that folding stops at array boundaries (arrays terminate chains)
66-
- Useful for API responses and structured data with nested metadata
67+
- Shows folding combined with inline arrays: `data.meta.items[3]: widget,gadget,tool`
68+
- Adds folded scalar `stats.meta.count: 3` plus folded array `user.preferences.tags[2]: …`
69+
- Shows that arrays stop the folding chain yet remain inline when the parent chain qualifies
70+
- **Decode tip:** use `expandPaths="safe"` to reconstruct the nested JSON structure
6771
- Spec: §13.4 Key Folding
6872

6973
- [`valid/key-folding-mixed.toon`](valid/key-folding-mixed.toon) - Mixed folding strategies
70-
- Shows both folded (`app.name: MyApp`) and regular nested keys in same document
71-
- Demonstrates `flattenDepth` control for partial folding
72-
- Allows selective use of dotted notation where most beneficial
74+
- Combines standard nested objects (`app`, `server`) with folded keys (`database.connection.url`, `feature.flags.beta`)
75+
- Shows the encoder mixing folded and non-folded sections within the same document
76+
- Useful when only some branches meet the single-key-chain requirement
77+
- **Decode tip:** use `expandPaths="safe"` to reconstruct the nested JSON structure
7378
- Spec: §13.4 Key Folding
7479

7580
- [`valid/path-expansion-merge.toon`](valid/path-expansion-merge.toon) - Deep merge behavior
@@ -85,12 +90,12 @@ Examples that intentionally violate TOON syntax rules:
8590
- **[`invalid/length-mismatch.toon`](invalid/length-mismatch.toon)** - Array length mismatch
8691
- Declares `[3]` but provides only 2 items
8792
- Should fail validation in strict mode
88-
- Spec: §9 Validation
93+
- Spec: §14.1 Strict Mode (Array Count & Width)
8994

9095
- **[`invalid/missing-colon.toon`](invalid/missing-colon.toon)** - Missing colon after key
91-
- Keys must be followed by `: ` (colon + space)
96+
- Keys must be followed by `:`; when a value appears on the same line, the format MUST be `: ` (colon + single space)
9297
- Demonstrates common syntax error
93-
- Spec: §6 Objects
98+
- Spec: §8 Objects, §14.2 Syntax Errors
9499

95100
- **[`invalid/path-expansion-conflict-strict.toon`](invalid/path-expansion-conflict-strict.toon)** - Path expansion conflict (v1.5+)
96101
- First line creates nested path `user.profile.name`, second line tries to assign primitive to `user.profile`
@@ -102,7 +107,7 @@ Examples that intentionally violate TOON syntax rules:
102107
- Contains keys like `first-name` with hyphens (not valid IdentifierSegments)
103108
- These remain as literal dotted keys when `expandPaths="safe"` is used
104109
- Demonstrates safe mode validation: only expands keys with valid identifier segments
105-
- Note: This is NOT an errorit's valid TOON, but shows when expansion doesn't occur
110+
- Note: This is NOT an errorit's valid TOON, but shows when expansion doesn't occur
106111
- Spec: §13.4 Safe Mode Requirements, §1.9 IdentifierSegment
107112

108113
## Conversions
@@ -116,15 +121,15 @@ Side-by-side JSON ↔ TOON examples showing equivalent representations:
116121

117122
- **[`conversions/config.json`](conversions/config.json)** + **[`conversions/config.toon`](conversions/config.toon)** (v1.5+)
118123
- Deeply nested configuration data (server, database, logging settings)
119-
- TOON version uses dotted-key notation (`database.connection.host: localhost`)
120-
- Shows ≈40-50% token reduction for deeply nested structures
121-
- Demonstrates key folding benefits for configuration files
124+
- Regenerated with `keyFolding="safe"`; because most objects are multi-key, folding halts quickly and the output stays primarily nested (the **stop condition**)
125+
- Shows ≈40-50% token reduction versus the JSON source while remaining spec-compliant
126+
- Highlights how safe folding behaves when little or no folding is permitted
122127

123128
- **[`conversions/api-response.json`](conversions/api-response.json)** + **[`conversions/api-response.toon`](conversions/api-response.toon)** (v1.5+)
124129
- API response with nested data and metadata
125-
- TOON version collapses nested paths (`data.attributes.name: Ada Lovelace`)
126-
- Shows practical use case for serializing API responses
127-
- Demonstrates how key folding maintains readability while reducing tokens
130+
- Regenerated with `keyFolding="safe"`; multi-sibling branches like `data` and `meta` stay fully nested instead of becoming dotted keys (stop condition on display)
131+
- Shows practical use case for serializing API responses while preserving deterministic structure
132+
- `expandPaths="safe"` is not required for this file (no folded keys)
128133

129134
## Using These Examples
130135

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
data.id: 42
2-
data.type: user
3-
data.attributes.name: Ada Lovelace
4-
data.attributes.email: ada@example.com
5-
data.attributes.active: true
6-
meta.request.id: req_abc123
7-
meta.request.timestamp: "2025-01-15T10:30:00Z"
8-
meta.response.duration: 42
9-
meta.response.cached: false
1+
data:
2+
id: 42
3+
type: user
4+
attributes:
5+
name: Ada Lovelace
6+
email: ada@example.com
7+
active: true
8+
meta:
9+
request:
10+
id: req_abc123
11+
timestamp: "2025-01-15T10:30:00Z"
12+
response:
13+
duration: 42
14+
cached: false

examples/conversions/config.toon

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
server.host: localhost
2-
server.port: 8080
3-
server.timeout: 30000
4-
database.connection.host: db.example.com
5-
database.connection.port: 5432
6-
database.connection.username: admin
7-
database.connection.database: myapp_prod
8-
database.pool.min: 2
9-
database.pool.max: 10
10-
logging.level: info
11-
logging.format: json
1+
server:
2+
host: localhost
3+
port: 8080
4+
timeout: 30000
5+
database:
6+
connection:
7+
host: db.example.com
8+
port: 5432
9+
username: admin
10+
database: myapp_prod
11+
pool:
12+
min: 2
13+
max: 10
14+
logging:
15+
level: info
16+
format: json
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"server": {
3+
"host": "localhost"
4+
},
5+
"database": {
6+
"connection": {
7+
"username": "admin"
8+
}
9+
},
10+
"app": {
11+
"info": {
12+
"name": "MyApp"
13+
}
14+
},
15+
"release": {
16+
"meta": {
17+
"version": "1.0.0"
18+
}
19+
},
20+
"cache": {
21+
"layer": {
22+
"ttlSeconds": 300
23+
}
24+
}
25+
}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
server.host: localhost
2-
server.port: 8080
3-
database.connection.host: db.example.com
4-
database.connection.port: 5432
52
database.connection.username: admin
6-
app.name: MyApp
7-
app.version: 1.0.0
3+
app.info.name: MyApp
4+
release.meta.version: 1.0.0
5+
cache.layer.ttlSeconds: 300
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"app": {
3+
"name": "MyApp",
4+
"version": "2.1.0"
5+
},
6+
"server": {
7+
"host": "localhost",
8+
"port": 8080,
9+
"ssl": {
10+
"enabled": true,
11+
"cert": "/path/to/cert.pem"
12+
}
13+
},
14+
"database": {
15+
"connection": {
16+
"url": "postgresql://localhost:5432/mydb"
17+
}
18+
},
19+
"feature": {
20+
"flags": {
21+
"beta": true
22+
}
23+
}
24+
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
app.name: MyApp
2-
app.version: 2.1.0
1+
app:
2+
name: MyApp
3+
version: 2.1.0
34
server:
45
host: localhost
56
port: 8080
67
ssl:
78
enabled: true
89
cert: /path/to/cert.pem
9-
database.connection.url: "postgresql://localhost:5432/mydb"
10+
database.connection.url: "postgresql://localhost:5432/mydb"
11+
feature.flags.beta: true
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"api": {
3+
"endpoint": {
4+
"url": "https://api.example.com"
5+
}
6+
},
7+
"data": {
8+
"meta": {
9+
"items": ["widget", "gadget", "tool"]
10+
}
11+
},
12+
"stats": {
13+
"meta": {
14+
"count": 3
15+
}
16+
},
17+
"user": {
18+
"preferences": {
19+
"tags": ["productivity", "development"]
20+
}
21+
}
22+
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
api.endpoint: "https://api.example.com"
2-
api.timeout: 5000
1+
api.endpoint.url: "https://api.example.com"
32
data.meta.items[3]: widget,gadget,tool
4-
data.meta.count: 3
3+
stats.meta.count: 3
54
user.preferences.tags[2]: productivity,development

0 commit comments

Comments
 (0)