libyay 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +868 -0
- package/package.json +23 -0
- package/yay.js +2113 -0
package/README.md
ADDED
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
# libyay
|
|
2
|
+
|
|
3
|
+
A parser for the [YAY](https://github.com/kriskowal/yay) data format, implemented in JavaScript (ES2024+).
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js 22+ (for `Uint8Array.fromHex`)
|
|
8
|
+
- Or any JavaScript runtime with ES2024 support
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install libyay
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import { parseYay } from 'libyay';
|
|
20
|
+
|
|
21
|
+
// Parse a YAY document
|
|
22
|
+
const result = parseYay('key: "value"');
|
|
23
|
+
// => { key: "value" }
|
|
24
|
+
|
|
25
|
+
// Parse with filename for error messages
|
|
26
|
+
const data = parseYay(source, 'config.yay');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
### `parseYay(source, filename?)`
|
|
32
|
+
|
|
33
|
+
Parses a YAY document string and returns the corresponding JavaScript value.
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
|
|
37
|
+
- `source` - A string containing the YAY document (UTF-8)
|
|
38
|
+
- `filename` - Optional filename for error messages
|
|
39
|
+
|
|
40
|
+
**Returns:** A JavaScript value representing the parsed document.
|
|
41
|
+
|
|
42
|
+
**Throws:** `Error` with line:column location if parsing fails.
|
|
43
|
+
|
|
44
|
+
## Type Mapping
|
|
45
|
+
|
|
46
|
+
| YAY Type | JavaScript Type |
|
|
47
|
+
|----------|-----------------|
|
|
48
|
+
| `null` | `null` |
|
|
49
|
+
| big integer | `bigint` |
|
|
50
|
+
| float64 | `number` |
|
|
51
|
+
| boolean | `boolean` |
|
|
52
|
+
| string | `string` |
|
|
53
|
+
| array | `Array` |
|
|
54
|
+
| object | `Object` |
|
|
55
|
+
| bytes | `Uint8Array` |
|
|
56
|
+
|
|
57
|
+
# YAY Format
|
|
58
|
+
|
|
59
|
+
## Null
|
|
60
|
+
|
|
61
|
+
The keyword `null` denotes a null value.
|
|
62
|
+
|
|
63
|
+
[null-literal.yay](https://github.com/kriskowal/yay/blob/main/test/yay/null-literal.yay)
|
|
64
|
+
```yay
|
|
65
|
+
null
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
[null-literal.js](https://github.com/kriskowal/yay/blob/main/test/js/null-literal.js)
|
|
69
|
+
```js
|
|
70
|
+
null
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Booleans
|
|
74
|
+
|
|
75
|
+
The literals `true` and `false` denote booleans.
|
|
76
|
+
|
|
77
|
+
A true boolean value.
|
|
78
|
+
|
|
79
|
+
[boolean-true.yay](https://github.com/kriskowal/yay/blob/main/test/yay/boolean-true.yay)
|
|
80
|
+
```yay
|
|
81
|
+
true
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
[boolean-true.js](https://github.com/kriskowal/yay/blob/main/test/js/boolean-true.js)
|
|
85
|
+
```js
|
|
86
|
+
true
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
A false boolean value.
|
|
90
|
+
|
|
91
|
+
[boolean-false.yay](https://github.com/kriskowal/yay/blob/main/test/yay/boolean-false.yay)
|
|
92
|
+
```yay
|
|
93
|
+
false
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
[boolean-false.js](https://github.com/kriskowal/yay/blob/main/test/js/boolean-false.js)
|
|
97
|
+
```js
|
|
98
|
+
false
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Big Integers
|
|
102
|
+
|
|
103
|
+
Unquoted decimal digit sequences are big integers (arbitrary precision).
|
|
104
|
+
A leading minus sign denotes a negative big integer; the minus must not be followed by a space.
|
|
105
|
+
Spaces may be used to group digits for readability; they do not change the value.
|
|
106
|
+
|
|
107
|
+
A basic positive integer.
|
|
108
|
+
|
|
109
|
+
[integer-big-basic.yay](https://github.com/kriskowal/yay/blob/main/test/yay/integer-big-basic.yay)
|
|
110
|
+
```yay
|
|
111
|
+
42
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
[integer-big-basic.js](https://github.com/kriskowal/yay/blob/main/test/js/integer-big-basic.js)
|
|
115
|
+
```js
|
|
116
|
+
42n
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
A negative integer.
|
|
120
|
+
|
|
121
|
+
[integer-big-negative.yay](https://github.com/kriskowal/yay/blob/main/test/yay/integer-big-negative.yay)
|
|
122
|
+
```yay
|
|
123
|
+
-42
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
[integer-big-negative.js](https://github.com/kriskowal/yay/blob/main/test/js/integer-big-negative.js)
|
|
127
|
+
```js
|
|
128
|
+
-42n
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Spaces group digits for readability without changing the value.
|
|
132
|
+
|
|
133
|
+
[integer-big.yay](https://github.com/kriskowal/yay/blob/main/test/yay/integer-big.yay)
|
|
134
|
+
```yay
|
|
135
|
+
867 5309
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
[integer-big.js](https://github.com/kriskowal/yay/blob/main/test/js/integer-big.js)
|
|
139
|
+
```js
|
|
140
|
+
8675309n
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Floating-Point (Float64)
|
|
144
|
+
|
|
145
|
+
A decimal point must be present to distinguish a float from a big integer.
|
|
146
|
+
Decimal literals with a decimal point, or the keywords `infinity`, `-infinity`, and `nan`, denote 64-bit floats.
|
|
147
|
+
A leading minus must not be followed by a space.
|
|
148
|
+
Spaces may group digits.
|
|
149
|
+
|
|
150
|
+
A basic floating-point number.
|
|
151
|
+
|
|
152
|
+
[number-float.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float.yay)
|
|
153
|
+
```yay
|
|
154
|
+
6.283185307179586
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
[number-float.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float.js)
|
|
158
|
+
```js
|
|
159
|
+
6.283185307179586
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
A float with a leading decimal point (no integer part).
|
|
163
|
+
|
|
164
|
+
[number-float-leading-dot.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-leading-dot.yay)
|
|
165
|
+
```yay
|
|
166
|
+
.5
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
[number-float-leading-dot.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-leading-dot.js)
|
|
170
|
+
```js
|
|
171
|
+
0.5
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
A float with a trailing decimal point (no fractional part).
|
|
175
|
+
|
|
176
|
+
[number-float-trailing-dot.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-trailing-dot.yay)
|
|
177
|
+
```yay
|
|
178
|
+
1.
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
[number-float-trailing-dot.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-trailing-dot.js)
|
|
182
|
+
```js
|
|
183
|
+
1
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Negative zero is distinct from positive zero.
|
|
187
|
+
|
|
188
|
+
[number-float-negative-zero.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-negative-zero.yay)
|
|
189
|
+
```yay
|
|
190
|
+
-0.0
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
[number-float-negative-zero.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-negative-zero.js)
|
|
194
|
+
```js
|
|
195
|
+
-0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Positive infinity.
|
|
199
|
+
|
|
200
|
+
[number-float-infinity.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-infinity.yay)
|
|
201
|
+
```yay
|
|
202
|
+
infinity
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
[number-float-infinity.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-infinity.js)
|
|
206
|
+
```js
|
|
207
|
+
Infinity
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Negative infinity.
|
|
211
|
+
|
|
212
|
+
[number-float-negative-infinity.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-negative-infinity.yay)
|
|
213
|
+
```yay
|
|
214
|
+
-infinity
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
[number-float-negative-infinity.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-negative-infinity.js)
|
|
218
|
+
```js
|
|
219
|
+
-Infinity
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Not-a-number (canonical NaN).
|
|
223
|
+
|
|
224
|
+
[number-float-nan.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-nan.yay)
|
|
225
|
+
```yay
|
|
226
|
+
nan
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
[number-float-nan.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-nan.js)
|
|
230
|
+
```js
|
|
231
|
+
NaN
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Spaces group digits for readability in floats.
|
|
235
|
+
|
|
236
|
+
[number-float-grouped.yay](https://github.com/kriskowal/yay/blob/main/test/yay/number-float-grouped.yay)
|
|
237
|
+
```yay
|
|
238
|
+
6.283 185 307 179 586
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
[number-float-grouped.js](https://github.com/kriskowal/yay/blob/main/test/js/number-float-grouped.js)
|
|
242
|
+
```js
|
|
243
|
+
6.283185307179586
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Block Strings
|
|
247
|
+
|
|
248
|
+
Block strings use the backtick (`` ` ``) introducer.
|
|
249
|
+
The body continues until the next line that is indented the same or less.
|
|
250
|
+
The first two spaces of each content line are stripped; any further indentation is preserved.
|
|
251
|
+
Empty lines are interpreted as newlines.
|
|
252
|
+
Trailing empty lines collapse to a single trailing newline.
|
|
253
|
+
Block strings do not support escape sequences—a backslash is just a backslash.
|
|
254
|
+
Comments are also not recognized inside block strings; `#` is literal content.
|
|
255
|
+
|
|
256
|
+
### At Root Level
|
|
257
|
+
|
|
258
|
+
At root level or as an array item, content may appear on the same line after `` ` `` (backtick + space + content).
|
|
259
|
+
When the backtick is alone on a line, the result has an implicit leading newline.
|
|
260
|
+
|
|
261
|
+
Content on the same line as the backtick starts the string without a leading newline.
|
|
262
|
+
|
|
263
|
+
[string-block-root-same-line.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-root-same-line.yay)
|
|
264
|
+
```yay
|
|
265
|
+
` I think you ought to know I'm feeling very depressed.
|
|
266
|
+
This will all end in tears.
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
[string-block-root-same-line.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-root-same-line.js)
|
|
270
|
+
```js
|
|
271
|
+
"I think you ought to know I'm feeling very depressed.\nThis will all end in tears.\n"
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Backtick alone on its line produces a leading newline because content starts on the following line.
|
|
275
|
+
|
|
276
|
+
[string-block-root-next-line.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-root-next-line.yay)
|
|
277
|
+
```yay
|
|
278
|
+
`
|
|
279
|
+
I've calculated your chance of survival,
|
|
280
|
+
but I don't think you'll like it.
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
[string-block-root-next-line.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-root-next-line.js)
|
|
284
|
+
```js
|
|
285
|
+
"\nI've calculated your chance of survival,\nbut I don't think you'll like it.\n"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
An empty line in the middle of a block string is preserved as a newline.
|
|
289
|
+
|
|
290
|
+
[string-block-empty-middle.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-empty-middle.yay)
|
|
291
|
+
```yay
|
|
292
|
+
`
|
|
293
|
+
I'm getting better!
|
|
294
|
+
|
|
295
|
+
No you're not.
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
[string-block-empty-middle.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-empty-middle.js)
|
|
299
|
+
```js
|
|
300
|
+
"\nI'm getting better!\n\nNo you're not.\n"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The `#` character inside a block string is literal content, not a comment.
|
|
304
|
+
|
|
305
|
+
[string-block-root-hash.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-root-hash.yay)
|
|
306
|
+
```yay
|
|
307
|
+
` # this is not a comment
|
|
308
|
+
it is content
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
[string-block-root-hash.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-root-hash.js)
|
|
312
|
+
```js
|
|
313
|
+
"# this is not a comment\nit is content\n"
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
A block string may be deeply nested and the indentation prefix will be absent
|
|
317
|
+
in the value.
|
|
318
|
+
The string will end with a single newline regardless of any subsequent newlines
|
|
319
|
+
in the YAY text.
|
|
320
|
+
|
|
321
|
+
[string-block-nested-in-object-and-array.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-nested-in-object-and-array.yay)
|
|
322
|
+
```yay
|
|
323
|
+
parrot:
|
|
324
|
+
condition: `
|
|
325
|
+
No, no, it's just resting!
|
|
326
|
+
|
|
327
|
+
remarks:
|
|
328
|
+
- ` Remarkable bird, the Norwegian Blue.
|
|
329
|
+
Beautiful plumage, innit?
|
|
330
|
+
|
|
331
|
+
- ` It's probably pining for the fjords.
|
|
332
|
+
Lovely plumage.
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
[string-block-nested-in-object-and-array.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-nested-in-object-and-array.js)
|
|
336
|
+
```js
|
|
337
|
+
({
|
|
338
|
+
"parrot": {
|
|
339
|
+
"condition": "No, no, it's just resting!\n",
|
|
340
|
+
"remarks": [
|
|
341
|
+
"Remarkable bird, the Norwegian Blue.\nBeautiful plumage, innit?\n",
|
|
342
|
+
"It's probably pining for the fjords.\nLovely plumage.\n",
|
|
343
|
+
],
|
|
344
|
+
},
|
|
345
|
+
})
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### As Object Property
|
|
349
|
+
|
|
350
|
+
In property context, the backtick must be alone on the line (no content after it).
|
|
351
|
+
There is no implicit leading newline.
|
|
352
|
+
The first content line becomes the start of the string.
|
|
353
|
+
|
|
354
|
+
[string-block-property.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-property.yay)
|
|
355
|
+
```yay
|
|
356
|
+
message: `
|
|
357
|
+
By Grabthar's hammer, we live to tell the tale.
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
[string-block-property.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-property.js)
|
|
361
|
+
```js
|
|
362
|
+
({
|
|
363
|
+
"message": "By Grabthar's hammer, we live to tell the tale.\n",
|
|
364
|
+
})
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
An empty line in the middle of a block string property is preserved.
|
|
368
|
+
|
|
369
|
+
[string-block-property-empty-middle.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-property-empty-middle.yay)
|
|
370
|
+
```yay
|
|
371
|
+
message: `
|
|
372
|
+
It's not pining!
|
|
373
|
+
|
|
374
|
+
It's passed on! This parrot is no more!
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
[string-block-property-empty-middle.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-property-empty-middle.js)
|
|
378
|
+
```js
|
|
379
|
+
({
|
|
380
|
+
"message": "It's not pining!\n\nIt's passed on! This parrot is no more!\n",
|
|
381
|
+
})
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
A block string property followed by another property: the block ends when a line at the same or lesser indent appears.
|
|
385
|
+
Trailing empty lines collapse to a single trailing newline.
|
|
386
|
+
|
|
387
|
+
[string-block-property-trailing-empty.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-block-property-trailing-empty.yay)
|
|
388
|
+
```yay
|
|
389
|
+
message: `
|
|
390
|
+
By Grabthar's hammer... what a savings.
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
next: 1
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
[string-block-property-trailing-empty.js](https://github.com/kriskowal/yay/blob/main/test/js/string-block-property-trailing-empty.js)
|
|
397
|
+
```js
|
|
398
|
+
({
|
|
399
|
+
"message": "By Grabthar's hammer... what a savings.\n",
|
|
400
|
+
"next": 1n,
|
|
401
|
+
})
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## Inline Strings
|
|
405
|
+
|
|
406
|
+
Strings may be quoted with double or single quotes.
|
|
407
|
+
Double-quoted strings support escape sequences: `\"`, `\\`, `\/`, `\b`, `\f`, `\n`, `\r`, `\t`, and `\u{XXXXXX}` for Unicode code points.
|
|
408
|
+
Single-quoted strings are literal (no escape sequences).
|
|
409
|
+
|
|
410
|
+
A double-quoted string.
|
|
411
|
+
|
|
412
|
+
[string-inline-doublequote-basic.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-inline-doublequote-basic.yay)
|
|
413
|
+
```yay
|
|
414
|
+
"This will all end in tears."
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
[string-inline-doublequote-basic.js](https://github.com/kriskowal/yay/blob/main/test/js/string-inline-doublequote-basic.js)
|
|
418
|
+
```js
|
|
419
|
+
"This will all end in tears."
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
A single-quoted string (literal, no escapes).
|
|
423
|
+
|
|
424
|
+
[string-inline-singlequote-basic.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-inline-singlequote-basic.yay)
|
|
425
|
+
```yay
|
|
426
|
+
'Are you suggesting coconuts migrate?'
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
[string-inline-singlequote-basic.js](https://github.com/kriskowal/yay/blob/main/test/js/string-inline-singlequote-basic.js)
|
|
430
|
+
```js
|
|
431
|
+
"Are you suggesting coconuts migrate?"
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
A double-quoted string with escape sequences.
|
|
435
|
+
|
|
436
|
+
[string-inline-doublequote-escapes.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-inline-doublequote-escapes.yay)
|
|
437
|
+
```yay
|
|
438
|
+
"\"\\\/\b\f\n\r\t\u{263A}"
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
[string-inline-doublequote-escapes.js](https://github.com/kriskowal/yay/blob/main/test/js/string-inline-doublequote-escapes.js)
|
|
442
|
+
```js
|
|
443
|
+
'"\\/\b\f\n\r\t☺'
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
A double-quoted string with a Unicode emoji (literal UTF-8).
|
|
447
|
+
|
|
448
|
+
[string-inline-doublequote-unicode-emoji.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-inline-doublequote-unicode-emoji.yay)
|
|
449
|
+
```yay
|
|
450
|
+
"😀"
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
[string-inline-doublequote-unicode-emoji.js](https://github.com/kriskowal/yay/blob/main/test/js/string-inline-doublequote-unicode-emoji.js)
|
|
454
|
+
```js
|
|
455
|
+
"😀"
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
A Unicode code point escape for a character outside the BMP (U+1F600), which requires a surrogate pair in UTF-16.
|
|
459
|
+
The `\u{...}` escape accepts 1 to 6 hexadecimal digits representing a Unicode code point (e.g. `\u{41}` for "A", `\u{1F600}` for "😀").
|
|
460
|
+
Surrogate code points (U+D800 through U+DFFF) are forbidden in `\u{...}` escapes.
|
|
461
|
+
Unlike JSON, the four-digit `\uXXXX` form is not supported; use `\u{XXXX}` instead.
|
|
462
|
+
|
|
463
|
+
[string-inline-doublequote-unicode-surrogate-pair.yay](https://github.com/kriskowal/yay/blob/main/test/yay/string-inline-doublequote-unicode-surrogate-pair.yay)
|
|
464
|
+
```yay
|
|
465
|
+
"\u{1F600}"
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
[string-inline-doublequote-unicode-surrogate-pair.js](https://github.com/kriskowal/yay/blob/main/test/js/string-inline-doublequote-unicode-surrogate-pair.js)
|
|
469
|
+
```js
|
|
470
|
+
"😀"
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Block Arrays
|
|
474
|
+
|
|
475
|
+
Arrays are written as a sequence of items, each introduced by `- ` (dash and space).
|
|
476
|
+
The two-character `- ` prefix is the list marker; the value follows immediately.
|
|
477
|
+
Items may be nested: a bullet line whose content starts with `- ` begins an inner list.
|
|
478
|
+
An array may be given a name as a key followed by `:`.
|
|
479
|
+
|
|
480
|
+
A basic block array with three integer items.
|
|
481
|
+
|
|
482
|
+
[array-multiline.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-multiline.yay)
|
|
483
|
+
```yay
|
|
484
|
+
- 5
|
|
485
|
+
- 3
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
[array-multiline.js](https://github.com/kriskowal/yay/blob/main/test/js/array-multiline.js)
|
|
489
|
+
```js
|
|
490
|
+
[5n, 3n]
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Nested arrays where each top-level item contains an inner array.
|
|
494
|
+
|
|
495
|
+
[array-multiline-nested.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-multiline-nested.yay)
|
|
496
|
+
```yay
|
|
497
|
+
- - "a"
|
|
498
|
+
- "b"
|
|
499
|
+
- - 1
|
|
500
|
+
- 2
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
[array-multiline-nested.js](https://github.com/kriskowal/yay/blob/main/test/js/array-multiline-nested.js)
|
|
504
|
+
```js
|
|
505
|
+
[["a", "b"], [1n, 2n]]
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
An array as the value of an object property.
|
|
509
|
+
|
|
510
|
+
[array-multiline-named.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-multiline-named.yay)
|
|
511
|
+
```yay
|
|
512
|
+
complaints:
|
|
513
|
+
- "I didn't vote for you."
|
|
514
|
+
- "Help, help, I'm being repressed!"
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
[array-multiline-named.js](https://github.com/kriskowal/yay/blob/main/test/js/array-multiline-named.js)
|
|
518
|
+
```js
|
|
519
|
+
({
|
|
520
|
+
"complaints": [
|
|
521
|
+
"I didn't vote for you.",
|
|
522
|
+
"Help, help, I'm being repressed!",
|
|
523
|
+
],
|
|
524
|
+
})
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Inline Arrays
|
|
528
|
+
|
|
529
|
+
Inline arrays use JSON-style bracket syntax with strict spacing rules: no space after `[`, no space before `]`, exactly one space after each `,`.
|
|
530
|
+
|
|
531
|
+
A simple inline array with string values.
|
|
532
|
+
|
|
533
|
+
[array-inline-doublequote.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-inline-doublequote.yay)
|
|
534
|
+
```yay
|
|
535
|
+
["And there was much rejoicing.", "yay."]
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
[array-inline-doublequote.js](https://github.com/kriskowal/yay/blob/main/test/js/array-inline-doublequote.js)
|
|
539
|
+
```js
|
|
540
|
+
["And there was much rejoicing.", "yay."]
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
An inline array containing big integers.
|
|
544
|
+
|
|
545
|
+
[array-inline-integers.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-inline-integers.yay)
|
|
546
|
+
```yay
|
|
547
|
+
[42, 404, 418]
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
[array-inline-integers.js](https://github.com/kriskowal/yay/blob/main/test/js/array-inline-integers.js)
|
|
551
|
+
```js
|
|
552
|
+
[42n, 404n, 418n]
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
An inline array containing byte array literals.
|
|
556
|
+
|
|
557
|
+
[array-inline-bytearray.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-inline-bytearray.yay)
|
|
558
|
+
```yay
|
|
559
|
+
[<b0b5>, <cafe>]
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
[array-inline-bytearray.js](https://github.com/kriskowal/yay/blob/main/test/js/array-inline-bytearray.js)
|
|
563
|
+
```js
|
|
564
|
+
[
|
|
565
|
+
Uint8Array.from([0xb0, 0xb5]),
|
|
566
|
+
Uint8Array.from([0xca, 0xfe]),
|
|
567
|
+
]
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
Inline arrays nested within an inline array.
|
|
571
|
+
|
|
572
|
+
[array-inline-nested.yay](https://github.com/kriskowal/yay/blob/main/test/yay/array-inline-nested.yay)
|
|
573
|
+
```yay
|
|
574
|
+
[["I feel happy!", "yay."], ["And there was much rejoicing.", "yay."]]
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
[array-inline-nested.js](https://github.com/kriskowal/yay/blob/main/test/js/array-inline-nested.js)
|
|
578
|
+
```js
|
|
579
|
+
[
|
|
580
|
+
["I feel happy!", "yay."],
|
|
581
|
+
["And there was much rejoicing.", "yay."],
|
|
582
|
+
]
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
## Block Objects
|
|
586
|
+
|
|
587
|
+
Objects are key–value pairs.
|
|
588
|
+
A key is followed by `:` and then the value.
|
|
589
|
+
Object keys must be either alphanumeric (letters and digits) or quoted (double or single quotes, same rules as string values).
|
|
590
|
+
Nested objects are indented by two spaces.
|
|
591
|
+
Empty objects are written as `key: {}`.
|
|
592
|
+
|
|
593
|
+
A simple object with two key-value pairs at the root level.
|
|
594
|
+
|
|
595
|
+
[object-multiline.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-multiline.yay)
|
|
596
|
+
```yay
|
|
597
|
+
answer: 42
|
|
598
|
+
error: 404
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
[object-multiline.js](https://github.com/kriskowal/yay/blob/main/test/js/object-multiline.js)
|
|
602
|
+
```js
|
|
603
|
+
({ "answer": 42n, "error": 404n })
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
An object nested within another object, demonstrating indentation.
|
|
607
|
+
|
|
608
|
+
[object-multiline-nested.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-multiline-nested.yay)
|
|
609
|
+
```yay
|
|
610
|
+
parrot:
|
|
611
|
+
status: "pining for the fjords"
|
|
612
|
+
plumage: "beautiful"
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
[object-multiline-nested.js](https://github.com/kriskowal/yay/blob/main/test/js/object-multiline-nested.js)
|
|
616
|
+
```js
|
|
617
|
+
({
|
|
618
|
+
"parrot": { "plumage": "beautiful", "status": "pining for the fjords" },
|
|
619
|
+
})
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
Object keys containing spaces or special characters must be quoted.
|
|
623
|
+
|
|
624
|
+
[object-multiline-doublequote-key.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-multiline-doublequote-key.yay)
|
|
625
|
+
```yay
|
|
626
|
+
"key name": 1
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
[object-multiline-doublequote-key.js](https://github.com/kriskowal/yay/blob/main/test/js/object-multiline-doublequote-key.js)
|
|
630
|
+
```js
|
|
631
|
+
({ "key name": 1n })
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
An empty object as a property value.
|
|
635
|
+
|
|
636
|
+
[object-inline-empty.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-inline-empty.yay)
|
|
637
|
+
```yay
|
|
638
|
+
empty: {}
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
[object-inline-empty.js](https://github.com/kriskowal/yay/blob/main/test/js/object-inline-empty.js)
|
|
642
|
+
```js
|
|
643
|
+
({ "empty": {} })
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
## Inline Objects
|
|
647
|
+
|
|
648
|
+
Inline objects use JSON-style brace syntax with strict spacing rules: no space after `{`, no space before `}`, exactly one space after each `,`.
|
|
649
|
+
|
|
650
|
+
A simple inline object with integer values.
|
|
651
|
+
|
|
652
|
+
[object-inline-integers.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-inline-integers.yay)
|
|
653
|
+
```yay
|
|
654
|
+
{answer: 42, error: 404}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
[object-inline-integers.js](https://github.com/kriskowal/yay/blob/main/test/js/object-inline-integers.js)
|
|
658
|
+
```js
|
|
659
|
+
({ "answer": 42n, "error": 404n })
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
An inline object with string and integer values.
|
|
663
|
+
|
|
664
|
+
[object-inline-mixed.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-inline-mixed.yay)
|
|
665
|
+
```yay
|
|
666
|
+
{name: 'Marvin', mood: 'depressed'}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
[object-inline-mixed.js](https://github.com/kriskowal/yay/blob/main/test/js/object-inline-mixed.js)
|
|
670
|
+
```js
|
|
671
|
+
({ "mood": "depressed", "name": "Marvin" })
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
An inline object containing both a nested object and an array.
|
|
675
|
+
|
|
676
|
+
[object-inline-nested.yay](https://github.com/kriskowal/yay/blob/main/test/yay/object-inline-nested.yay)
|
|
677
|
+
```yay
|
|
678
|
+
{luggage: {combination: 12345}, air: ["canned", "Perri-Air"]}
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
[object-inline-nested.js](https://github.com/kriskowal/yay/blob/main/test/js/object-inline-nested.js)
|
|
682
|
+
```js
|
|
683
|
+
({
|
|
684
|
+
"air": ["canned", "Perri-Air"],
|
|
685
|
+
"luggage": { "combination": 12345n },
|
|
686
|
+
})
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
## Block Byte Arrays
|
|
690
|
+
|
|
691
|
+
Block byte arrays use the `>` introducer (as opposed to `<...>` for inline).
|
|
692
|
+
Each line may hold hex chunks and comments (comments start with `#`).
|
|
693
|
+
Spaces within hex content are ignored.
|
|
694
|
+
|
|
695
|
+
### At Root Level
|
|
696
|
+
|
|
697
|
+
At root level or as an array item, hex may appear on the same line after `> `.
|
|
698
|
+
The `> ` leader must have hex digits or a comment on the line—`>` alone is invalid.
|
|
699
|
+
|
|
700
|
+
A block byte array at root level with hex on the same line as the `>` introducer.
|
|
701
|
+
|
|
702
|
+
[bytearray-block-basic.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-block-basic.yay)
|
|
703
|
+
```yay
|
|
704
|
+
> b0b5
|
|
705
|
+
c0ff
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
[bytearray-block-basic.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-block-basic.js)
|
|
709
|
+
```js
|
|
710
|
+
Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff])
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
A block byte array with a comment on the first line instead of hex.
|
|
714
|
+
|
|
715
|
+
[bytearray-block-comment-only.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-block-comment-only.yay)
|
|
716
|
+
```yay
|
|
717
|
+
> # header comment
|
|
718
|
+
b0b5 c0ff
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
[bytearray-block-comment-only.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-block-comment-only.js)
|
|
722
|
+
```js
|
|
723
|
+
Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff])
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
Hex and comments on the same lines for inline documentation of byte sequences.
|
|
727
|
+
|
|
728
|
+
[bytearray-block-hex-and-comment.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-block-hex-and-comment.yay)
|
|
729
|
+
```yay
|
|
730
|
+
> b0b5 # first chunk
|
|
731
|
+
c0ff # second chunk
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
[bytearray-block-hex-and-comment.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-block-hex-and-comment.js)
|
|
735
|
+
```js
|
|
736
|
+
Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff])
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
### As Object Property
|
|
740
|
+
|
|
741
|
+
In property context, the `>` must be alone on the line (optionally followed by a comment).
|
|
742
|
+
Hex content starts on the following lines, preserving column alignment.
|
|
743
|
+
|
|
744
|
+
[bytearray-block-property.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-block-property.yay)
|
|
745
|
+
```yay
|
|
746
|
+
data: >
|
|
747
|
+
b0b5 c0ff
|
|
748
|
+
eefa cade
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
[bytearray-block-property.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-block-property.js)
|
|
752
|
+
```js
|
|
753
|
+
({
|
|
754
|
+
"data": Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff, 0xee, 0xfa, 0xca, 0xde]),
|
|
755
|
+
})
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
A block byte array property with a comment on the leader line.
|
|
759
|
+
|
|
760
|
+
[bytearray-block-property-comment.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-block-property-comment.yay)
|
|
761
|
+
```yay
|
|
762
|
+
data: > # raw bytes
|
|
763
|
+
b0b5 c0ff
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
[bytearray-block-property-comment.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-block-property-comment.js)
|
|
767
|
+
```js
|
|
768
|
+
({ "data": Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff]) })
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
## Inline Byte Arrays
|
|
772
|
+
|
|
773
|
+
Binary data is written as hexadecimal inside angle brackets.
|
|
774
|
+
Hexadecimal must be lowercase.
|
|
775
|
+
An odd number of hex digits is forbidden.
|
|
776
|
+
`<>` denotes an empty byte array.
|
|
777
|
+
Spaces inside the brackets are allowed for readability.
|
|
778
|
+
|
|
779
|
+
An empty byte array.
|
|
780
|
+
|
|
781
|
+
[bytearray-inline-empty.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-inline-empty.yay)
|
|
782
|
+
```yay
|
|
783
|
+
<>
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
[bytearray-inline-empty.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-inline-empty.js)
|
|
787
|
+
```js
|
|
788
|
+
new Uint8Array(0)
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
An inline byte array with hex content.
|
|
792
|
+
|
|
793
|
+
[bytearray-inline-even.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-inline-even.yay)
|
|
794
|
+
```yay
|
|
795
|
+
<b0b5c0ffeefacade>
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
[bytearray-inline-even.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-inline-even.js)
|
|
799
|
+
```js
|
|
800
|
+
Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff, 0xee, 0xfa, 0xca, 0xde])
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
An inline byte array as an object property value.
|
|
804
|
+
|
|
805
|
+
[bytearray-inline-named.yay](https://github.com/kriskowal/yay/blob/main/test/yay/bytearray-inline-named.yay)
|
|
806
|
+
```yay
|
|
807
|
+
data: <b0b5c0ffeefacade>
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
[bytearray-inline-named.js](https://github.com/kriskowal/yay/blob/main/test/js/bytearray-inline-named.js)
|
|
811
|
+
```js
|
|
812
|
+
({
|
|
813
|
+
"data": Uint8Array.from([0xb0, 0xb5, 0xc0, 0xff, 0xee, 0xfa, 0xca, 0xde]),
|
|
814
|
+
})
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
## Error Handling
|
|
818
|
+
|
|
819
|
+
Errors include line and column numbers for debugging:
|
|
820
|
+
|
|
821
|
+
```js
|
|
822
|
+
try {
|
|
823
|
+
parseYay('invalid: [', 'config.yay');
|
|
824
|
+
} catch (e) {
|
|
825
|
+
console.error(e.message);
|
|
826
|
+
// "Unexpected newline in inline array at 1:11 of <config.yay>"
|
|
827
|
+
}
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
## Whitespace Rules
|
|
831
|
+
|
|
832
|
+
YAY has strict whitespace rules that the parser enforces:
|
|
833
|
+
|
|
834
|
+
- Two spaces for indentation (tabs are illegal)
|
|
835
|
+
- No trailing spaces on lines
|
|
836
|
+
- Exactly one space after `:` in key-value pairs
|
|
837
|
+
- Exactly one space after `,` in inline arrays/objects
|
|
838
|
+
- No spaces after `[` or `{`, or before `]` or `}`
|
|
839
|
+
- No space before `:` in keys
|
|
840
|
+
|
|
841
|
+
## Running Tests
|
|
842
|
+
|
|
843
|
+
```bash
|
|
844
|
+
cd js
|
|
845
|
+
node --test yay.test.js
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
The test runner uses fixture files from `../test/`.
|
|
849
|
+
Files with `.yay` extension contain YAY input.
|
|
850
|
+
Files with `.js` extension contain expected JavaScript output.
|
|
851
|
+
|
|
852
|
+
## References
|
|
853
|
+
|
|
854
|
+
Examples in this document pay homage to:
|
|
855
|
+
|
|
856
|
+
- The Hitchhiker's Guide to the Galaxy (Douglas Adams)
|
|
857
|
+
- Monty Python and the Holy Grail
|
|
858
|
+
- Monty Python's Flying Circus ("Dead Parrot" sketch)
|
|
859
|
+
- Galaxy Quest
|
|
860
|
+
- Spaceballs
|
|
861
|
+
- Tommy Tutone ("867-5309/Jenny")
|
|
862
|
+
- The Tau Manifesto
|
|
863
|
+
|
|
864
|
+
## License
|
|
865
|
+
|
|
866
|
+
Apache 2.0
|
|
867
|
+
|
|
868
|
+
Copyright (C) 2026 Kris Kowal
|