links-notation 0.27.1 → 0.28.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 +47 -0
- package/README.ru.md +38 -0
- package/dist/index.js +303 -95
- package/index.d.ts +84 -0
- package/package.json +1 -1
- package/src/Cst.js +263 -0
- package/src/Link.js +41 -1
- package/src/Parser.js +49 -10
- package/src/grammar.pegjs +15 -4
- package/src/index.js +6 -1
- package/src/parser-generated.js +73 -53
- package/src/references.js +18 -0
- package/tests/Cst.test.js +109 -0
- package/tests/SharedSyntaxParity.test.js +47 -0
- package/tests/SyntaxMetadata.test.js +102 -0
package/README.md
CHANGED
|
@@ -234,6 +234,47 @@ call it on already decoded `Link.id` values.
|
|
|
234
234
|
|
|
235
235
|
See the [Q&A document example](../examples/js_indented_document.js).
|
|
236
236
|
|
|
237
|
+
### How a Document Was Written (CST)
|
|
238
|
+
|
|
239
|
+
Parsing keeps how every ID was written. Quoting never changes a reference:
|
|
240
|
+
`1` and `'1'` are the same reference, so equality, formatting and JSON stay as
|
|
241
|
+
they were. Each parsed link also carries `rawId`, the ID exactly as written,
|
|
242
|
+
and `quote`, the delimiter it was written between:
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
import { Parser } from 'links-notation';
|
|
246
|
+
|
|
247
|
+
const [link] = new Parser().parse("(t 1 '1')");
|
|
248
|
+
const [, bare, quoted] = link.values;
|
|
249
|
+
bare.equals(quoted); // true: the same reference
|
|
250
|
+
[bare.rawId, bare.quote]; // ['1', null]
|
|
251
|
+
[quoted.rawId, quoted.quote]; // ["'1'", "'"]
|
|
252
|
+
link.format(); // '(t 1 1)'
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`rawId` is `null` for links without an ID, links built in code, and links
|
|
256
|
+
made by indentation path combination. Use `new Parser({ syntax: false })` (AST
|
|
257
|
+
mode) to leave it out.
|
|
258
|
+
|
|
259
|
+
`parseCst(input)` returns the lossless concrete syntax tree. Every character,
|
|
260
|
+
including comments, blank lines, indentation, quotes and line endings, belongs
|
|
261
|
+
to exactly one token, so the original text is always recovered:
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
const cst = new Parser().parseCst("(t 1 '1') # note\n");
|
|
265
|
+
cst.toString(); // "(t 1 '1') # note\n"
|
|
266
|
+
cst.tokens().map((token) => [token.kind, token.text]);
|
|
267
|
+
// [['open_paren', '('], ['reference', 't'], ['whitespace', ' '], ...]
|
|
268
|
+
cst.toSExpression();
|
|
269
|
+
// (document (line (group open_paren:"(" (line reference:"t" ...) close_paren:")") whitespace:" " comment:"# note" newline:"\n"))
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
A `document` node holds `line` nodes. A line holds its tokens up to and
|
|
273
|
+
including its line ending. A `group` node holds `(`, the lines inside it, and
|
|
274
|
+
`)`. Reference tokens carry `value` (what the reference means) and `quote`.
|
|
275
|
+
`parseCst` refuses exactly what `parse` refuses. See
|
|
276
|
+
[the issue 364 case study](../docs/case-studies/issue-364/README.md).
|
|
277
|
+
|
|
237
278
|
### Streaming Parser (for Large Messages)
|
|
238
279
|
|
|
239
280
|
The `StreamParser` allows you to parse Links Notation incrementally, processing data as it arrives without loading the entire message into memory. This is ideal for:
|
|
@@ -429,6 +470,9 @@ Main parser class for converting strings to links.
|
|
|
429
470
|
- `initialize()` - Initialize the parser (async)
|
|
430
471
|
- `parse(input)` - Parse a Lino string and return links
|
|
431
472
|
- `parseGroups(input)` - Read an indentation tree as `LinksGroup` instances
|
|
473
|
+
- `parseCst(input)` - Read the lossless concrete syntax tree (`CstNode`)
|
|
474
|
+
- `options.syntax` - If `false` (AST mode), parsed links leave `rawId` null
|
|
475
|
+
(default: `true`)
|
|
432
476
|
|
|
433
477
|
#### `Link`
|
|
434
478
|
|
|
@@ -438,6 +482,9 @@ Represents a single link with ID and values.
|
|
|
438
482
|
- `toString()` - Convert link to string format
|
|
439
483
|
- `id` - Link identifier
|
|
440
484
|
- `values` - Array of child values/links
|
|
485
|
+
- `rawId` - The ID exactly as the parsed document wrote it, or `null`; ignored
|
|
486
|
+
by `equals`, `format` and JSON
|
|
487
|
+
- `quote` - `'`, `"` or `` ` `` when `rawId` is quoted, otherwise `null`
|
|
441
488
|
- `escapeReference(reference, options)` - Quote a reference; `minimal: true`
|
|
442
489
|
allows ordinary prose on a text document line
|
|
443
490
|
- `unescapeReference(reference)` - Decode a complete serialized reference
|
package/README.ru.md
CHANGED
|
@@ -153,6 +153,38 @@ const group = new LinksGroup(parsed);
|
|
|
153
153
|
console.log(group.format());
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
+
### Как документ был записан (CST)
|
|
157
|
+
|
|
158
|
+
Парсер сохраняет, как была записана каждая ссылка. Кавычки не меняют ссылку:
|
|
159
|
+
`1` и `'1'` - одна и та же ссылка, поэтому сравнение, форматирование и JSON
|
|
160
|
+
остаются прежними. Каждая разобранная связь хранит `rawId` - ID в точности
|
|
161
|
+
так, как он записан, и `quote` - кавычку, в которую он заключён:
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
import { Parser } from 'links-notation';
|
|
165
|
+
|
|
166
|
+
const [link] = new Parser().parse("(t 1 '1')");
|
|
167
|
+
const [, bare, quoted] = link.values;
|
|
168
|
+
bare.equals(quoted); // true: это одна ссылка
|
|
169
|
+
[bare.rawId, bare.quote]; // ['1', null]
|
|
170
|
+
[quoted.rawId, quoted.quote]; // ["'1'", "'"]
|
|
171
|
+
link.format(); // '(t 1 1)'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`rawId` равен `null` у связей без ID, у связей, созданных в коде, и у связей,
|
|
175
|
+
построенных объединением путей по отступам. `new Parser({ syntax: false })`
|
|
176
|
+
(режим AST) не сохраняет его.
|
|
177
|
+
|
|
178
|
+
`parseCst(input)` возвращает конкретное синтаксическое дерево без потерь:
|
|
179
|
+
каждый символ, включая комментарии, пустые строки, отступы, кавычки и
|
|
180
|
+
переводы строк, принадлежит ровно одному токену, поэтому исходный текст
|
|
181
|
+
всегда восстанавливается: `new Parser().parseCst(text).toString() === text`.
|
|
182
|
+
Узел `document` содержит узлы `line`; строка содержит свои токены вместе с
|
|
183
|
+
переводом строки; узел `group` содержит `(`, строки внутри и `)`. Токены
|
|
184
|
+
ссылок хранят `value` (что означает ссылка) и `quote`. `parseCst` отклоняет
|
|
185
|
+
ровно то, что отклоняет `parse`. Подробности - в
|
|
186
|
+
[разборе issue 364](../docs/case-studies/issue-364/README.md).
|
|
187
|
+
|
|
156
188
|
### Потоковый парсер
|
|
157
189
|
|
|
158
190
|
`StreamParser` принимает произвольные порции данных и отправляет события только
|
|
@@ -298,6 +330,9 @@ console.log(formatLinks(plain.parse('# a b\n'))); // (# a b)
|
|
|
298
330
|
отклоняется с `ParseError`, а не разбирается рекурсивно, пока не кончится стек
|
|
299
331
|
- `initialize()` - Инициализация парсера (асинхронно)
|
|
300
332
|
- `parse(input)` - Парсинг строки Lino и возвращение связей
|
|
333
|
+
- `parseCst(input)` - Конкретное синтаксическое дерево без потерь (`CstNode`)
|
|
334
|
+
- `options.syntax` - Со значением `false` (режим AST) связи не хранят `rawId`
|
|
335
|
+
(по умолчанию: `true`)
|
|
301
336
|
|
|
302
337
|
#### `Link`
|
|
303
338
|
|
|
@@ -307,6 +342,9 @@ console.log(formatLinks(plain.parse('# a b\n'))); // (# a b)
|
|
|
307
342
|
- `toString()` - Преобразование связи в строковый формат
|
|
308
343
|
- `id` - Идентификатор связи
|
|
309
344
|
- `values` - Массив дочерних значений/связей
|
|
345
|
+
- `rawId` - ID в точности так, как он записан в документе, или `null`;
|
|
346
|
+
`equals`, `format` и JSON его не учитывают
|
|
347
|
+
- `quote` - `'`, `"` или `` ` ``, если `rawId` в кавычках, иначе `null`
|
|
310
348
|
|
|
311
349
|
#### `LinksGroup`
|
|
312
350
|
|