links-notation 0.23.0 → 0.25.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 CHANGED
@@ -147,6 +147,85 @@ const group = new LinksGroup(parsed);
147
147
  console.log(group.format());
148
148
  ```
149
149
 
150
+ ### Indented Text Documents
151
+
152
+ Use `parseIndentedDocument` and `formatIndentedDocument` for text parents and
153
+ their answers or options:
154
+
155
+ ```javascript
156
+ import { parseIndentedDocument, formatIndentedDocument } from 'links-notation';
157
+
158
+ const input = `What is your experience?
159
+ I have worked with JavaScript
160
+ 'Question with "quotes": and colon'
161
+ Answer
162
+ Skills
163
+ JavaScript
164
+ Python
165
+ `;
166
+ const answers = parseIndentedDocument(input);
167
+ console.log(answers.get('What is your experience?'));
168
+ // I have worked with JavaScript
169
+ console.log(answers.get('Skills')); // ['JavaScript', 'Python']
170
+ console.log(formatIndentedDocument(answers));
171
+ ```
172
+
173
+ A parent with no children maps to `[]`, one child maps to a string, and multiple
174
+ children map to an array. Repeated parent lines accumulate children in order.
175
+ To read multiple child lines as multiline text, pass
176
+ `{ multipleValues: 'join' }`. These helpers accept the same parsing options as
177
+ `Parser`, including `comments`, `maxInputSize`, and `maxDepth`.
178
+
179
+ The formatter uses two spaces of indentation and adds a final newline to a
180
+ nonempty document. Ordinary single-space prose stays unquoted. Quotes are
181
+ escaped by doubling the enclosing delimiter. Structural characters, comment
182
+ starts, reserved literal prefixes, and significant whitespace are quoted.
183
+ Empty strings and control characters use the versioned reference literals
184
+ introduced in 0.24.0. A multiline string is encoded as one reference with its
185
+ exact line endings; an array is written as separate child references. Parsed
186
+ IDs are already unescaped.
187
+
188
+ The text format does not distinguish a one-element array from a single string;
189
+ both read back as a string. Use a multiline string to distinguish one
190
+ multiline answer from several options. The helpers reject grandchildren and
191
+ named links with values instead of discarding their structure.
192
+
193
+ For arbitrary indentation trees, `Parser.parseGroups(input)` returns existing
194
+ `LinksGroup` instances. Each group's `element` is the `Link` on that line, and
195
+ `children` contains its immediately indented groups. Parenthesized values retain
196
+ their usual `Link` structure:
197
+
198
+ ```javascript
199
+ import { Parser } from 'links-notation';
200
+
201
+ const [group] = new Parser().parseGroups('Question\n Answer\n Detail');
202
+ console.log(group.element.getValuesString()); // Question
203
+ console.log(group.children[0].element.getValuesString()); // Answer
204
+ console.log(group.children[0].children[0].element.getValuesString()); // Detail
205
+ ```
206
+
207
+ `Parser.parse()` continues to return the existing list of links and expanded
208
+ paths. `parseGroups()` preserves indentation even for the `name:` syntax.
209
+
210
+ `escapeReference` and `unescapeReference` are exported functions and static
211
+ methods on `Link`. Use minimal mode only for whole text lines; default escaping
212
+ still quotes spaces so references can be used inside tuples:
213
+
214
+ ```javascript
215
+ import { Link, escapeReference, unescapeReference } from 'links-notation';
216
+
217
+ Link.escapeReference('plain text'); // "'plain text'"
218
+ escapeReference('plain text', { minimal: true }); // 'plain text'
219
+ unescapeReference("'it''s ready'"); // "it's ready"
220
+ ```
221
+
222
+ `unescapeReference` decodes a complete serialized reference, including n-quote
223
+ delimiters, doubled escapes, and versioned literals. It rejects incomplete
224
+ quoted input and malformed literals, and preserves literal backslashes. Do not
225
+ call it on already decoded `Link.id` values.
226
+
227
+ See the [Q&A document example](../examples/js_indented_document.js).
228
+
150
229
  ### Streaming Parser (for Large Messages)
151
230
 
152
231
  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:
@@ -341,6 +420,7 @@ Main parser class for converting strings to links.
341
420
  recursed into until the stack runs out
342
421
  - `initialize()` - Initialize the parser (async)
343
422
  - `parse(input)` - Parse a Lino string and return links
423
+ - `parseGroups(input)` - Read an indentation tree as `LinksGroup` instances
344
424
 
345
425
  #### `Link`
346
426
 
@@ -350,6 +430,9 @@ Represents a single link with ID and values.
350
430
  - `toString()` - Convert link to string format
351
431
  - `id` - Link identifier
352
432
  - `values` - Array of child values/links
433
+ - `escapeReference(reference, options)` - Quote a reference; `minimal: true`
434
+ allows ordinary prose on a text document line
435
+ - `unescapeReference(reference)` - Decode a complete serialized reference
353
436
 
354
437
  #### `LinksGroup`
355
438
 
@@ -481,3 +564,6 @@ fail the format check.
481
564
 
482
565
  - Package: `links-notation`
483
566
  - License: Unlicense (see [LICENSE](../LICENSE))
567
+
568
+ Exact Unicode identifiers and values round-trip with the [reference literal contract](../docs/protocol/reference-literals.md)
569
+ introduced in 0.24.0, including mixed quotes, empty strings, controls and multiline text.
package/README.ru.md CHANGED
@@ -3,6 +3,54 @@
3
3
  Реализация парсера протокола Lino для JavaScript с использованием Bun и
4
4
  генератора парсеров Peggy.js.
5
5
 
6
+ ## Документы с отступами
7
+
8
+ `parseIndentedDocument()` и `formatIndentedDocument()` преобразуют текстовые
9
+ родительские строки и их дочерние строки в `Map<string, string | string[]>`:
10
+
11
+ ```javascript
12
+ import { parseIndentedDocument, formatIndentedDocument } from 'links-notation';
13
+
14
+ const answers = parseIndentedDocument(`Ваш опыт?
15
+ JavaScript
16
+ Навыки
17
+ JavaScript
18
+ Python
19
+ `);
20
+ console.log(answers.get('Ваш опыт?')); // 'JavaScript'
21
+ console.log(answers.get('Навыки')); // ['JavaScript', 'Python']
22
+ console.log(formatIndentedDocument(answers));
23
+ ```
24
+
25
+ Без дочерних строк значение равно `[]`, с одной строкой — строке, с несколькими
26
+ — массиву. Повторяющиеся родительские строки объединяют дочерние значения в
27
+ порядке документа. Опция `{ multipleValues: 'join' }` объединяет несколько
28
+ значений через перевод строки. Поддерживаются опции `Parser`: `comments`,
29
+ `maxInputSize` и `maxDepth`. Вложенность глубже одного дочернего уровня и
30
+ именованные ссылки со значениями отклоняются.
31
+
32
+ Форматирование использует два пробела для отступа и завершающий перевод строки.
33
+ Обычный текст с одиночными пробелами остаётся без кавычек; специальные символы,
34
+ значимые пробелы и зарезервированные префиксы литералов заключаются в кавычки.
35
+ Кавычки экранируются удвоением. Пустые строки и управляющие символы используют
36
+ версионированные литералы, введённые в 0.24.0. Массив из одного элемента при
37
+ чтении становится строкой. Многострочная строка сохраняется одной ссылкой с
38
+ точными переводами строк, а элементы массива записываются отдельными дочерними
39
+ строками.
40
+
41
+ `Parser.parseGroups()` возвращает дерево существующих объектов `LinksGroup`:
42
+ `element` содержит ссылку текущей строки, а `children` — группы непосредственно
43
+ вложенных строк. Поведение `Parser.parse()` сохраняется.
44
+
45
+ Функции `escapeReference()` и `unescapeReference()` экспортируются из пакета и
46
+ доступны как статические методы `Link`. Опция `{ minimal: true }` разрешает
47
+ обычные пробелы при экранировании целой текстовой строки. По умолчанию пробелы
48
+ по-прежнему заключаются в кавычки. `unescapeReference()` принимает целую
49
+ сериализованную ссылку, включая версионированные литералы; значения `Link.id`
50
+ уже декодированы.
51
+
52
+ См. [пример базы вопросов и ответов](../examples/js_indented_document.js).
53
+
6
54
  ## Установка
7
55
 
8
56
  ### Использование Bun (рекомендуется)