@gmb/bitmark-parser 7.3.0 → 7.4.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
@@ -276,7 +276,15 @@ survives in a lesser form (its value cleared, or one of its segments dropped).
276
276
  Both arrive on the conversion's warnings, like every other issue. In practice
277
277
  they are rare — a `href` holding a line terminator, a mark kind the grammar has
278
278
  no tag for — so treat either as a signal that the JSON holds something bitmark
279
- cannot express, not as routine noise.
279
+ cannot express, not as routine noise. Likewise `list-number-invalid`: a list
280
+ `start` or item `value` that is not a valid number for its list (`4000` on a
281
+ Roman list), or a `value` on a bullet or task item, is ignored and reported.
282
+
283
+ Reading bitmark, an inline property list (`==text==|link:…|?hint|`) reports two
284
+ things (PLAN-217): `text-tag-cardinality-exceeded` when a child is given more
285
+ often than it may be (`|?a|?b|` — the later value wins), and
286
+ `text-tag-value-invalid` when a value does not fit its format but is kept
287
+ (`|symbol:…|width:wide|`).
280
288
 
281
289
  #### canonicalize(input: string, options?: CanonicalizeOptions): string
282
290
 
@@ -66,6 +66,14 @@ model BitmarkJson {
66
66
  /** Resource-group registry by key (sorted). Here the member list is
67
67
  * authoritative. */
68
68
  resourceGroups: Record<ResourceGroup>;
69
+
70
+ /** Text tags by JSON type (sorted): the heads of inline property lists
71
+ * (`==text==|head:value|child:value|…|`) and the JSON-only marks
72
+ * (PLAN-217). Group references are expanded. */
73
+ textTags: Record<TextTag>;
74
+
75
+ /** ProseMirror nodes that are not text tags (sorted): mappings only. */
76
+ textNodes: Record<TextNode>;
69
77
  }
70
78
 
71
79
  model Locale {
@@ -318,6 +326,107 @@ model BitGroup {
318
326
  allowEmpty?: true;
319
327
  }
320
328
 
329
+ /** A value format of a text tag or child. `none`: no value. `duration`: `P`
330
+ * followed by anything (the 8.41.1 grammar rule). */
331
+ union TextFormat {
332
+ "none",
333
+ "string",
334
+ "bitmark+",
335
+ "boolean",
336
+ "number",
337
+ "enum",
338
+ "duration",
339
+ }
340
+
341
+ /** What an invalid value or a missing required child does: `warn` keeps it
342
+ * and reports; `invalid` rejects the segment and ends the chain. */
343
+ union OnInvalid {
344
+ "warn",
345
+ "invalid",
346
+ }
347
+
348
+ /** A text tag (PLAN-217). */
349
+ model TextTag {
350
+ description: string;
351
+
352
+ /** `mark` decorates the text run; `node` replaces it. */
353
+ kind: "mark" | "node";
354
+
355
+ /** Source spelling of the head; omitted → no bitmark form. An identifier
356
+ * (letters, digits and `*`, starting with a letter) followed by `:value`,
357
+ * or a sigil — one non-letter BMP character outside the chain syntax
358
+ * (`|:^@=*`) — that runs straight into its value (`#`, `►`, `?`). */
359
+ key?: string;
360
+
361
+ format: TextFormat;
362
+
363
+ /** Enum vocabulary; emitted only for `enum`. */
364
+ values?: string[];
365
+
366
+ /** `null` = omit (absence is its own state); always `null` for `none`. */
367
+ default: string | null;
368
+
369
+ /** Flag boolean (PLAN-152). */
370
+ alwaysEmit?: true;
371
+
372
+ /** Always emitted: `invalid` for `none`, else `warn` unless authored. */
373
+ onInvalid: OnInvalid;
374
+
375
+ /** `first`: valid only as the first segment; omitted = any position. */
376
+ headPosition?: "first";
377
+
378
+ /** Text tags that may start after this head's chain; omitted = any. */
379
+ followingHeads?: string[];
380
+
381
+ /** A named value transform applied on read. */
382
+ transform?: "lowercase";
383
+
384
+ /** JSON input of this (legacy) type is read as the named text tag. */
385
+ migrateTo?: string;
386
+
387
+ /** `json`: `{"type": <name>, …fields}` — a field value is `"$"` (the
388
+ * head's value), `"$text"` (the text between `==`) or a constant. A head
389
+ * with a value places it exactly once (`"$"`); a `none` head places none;
390
+ * no two fields of the head and its chain write the same path. */
391
+ mappingKeys?: MappingKeys;
392
+
393
+ /** Children in canonical order (D16); omitted when empty. */
394
+ chain?: TextChild[];
395
+ }
396
+
397
+ /** A child of a text tag. */
398
+ model TextChild {
399
+ /** Source spelling (`?`, `►`, `provider`, …); same rules as
400
+ * `TextTag.key`. */
401
+ tag: string;
402
+ description: string;
403
+
404
+ /** Never `none`: a child always takes a value. */
405
+ format: TextFormat;
406
+ values?: string[];
407
+ min: int64;
408
+
409
+ /** `-1` = unlimited. */
410
+ max: int64;
411
+ default: string | null;
412
+ alwaysEmit?: true;
413
+
414
+ /** Emitted only when `min >= 1`. Always `invalid` for now: `warn` needs
415
+ * the `text-tag-missing` warning, added with its first use (D13). */
416
+ onMissing?: OnInvalid;
417
+ onInvalid: OnInvalid;
418
+
419
+ /** Always has `json`: one field — `"$"` or `["$"]` (append) under
420
+ * `attrs` or at the top level. */
421
+ mappingKeys: MappingKeys;
422
+ }
423
+
424
+ /** A ProseMirror node that is not a text tag. */
425
+ model TextNode {
426
+ description: string;
427
+ mappingKeys?: MappingKeys;
428
+ }
429
+
321
430
  /** A search/filter category over resource types. The member list is the
322
431
  * single home of that fact. */
323
432
  model ResourceGroup {