@gmb/bitmark-parser-generator 5.35.0 → 5.37.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/dist/index.js CHANGED
@@ -1351,6 +1351,7 @@ var propertyKeys = {
1351
1351
  property_dateEnd: "@dateEnd",
1352
1352
  property_decimalPlaces: "@decimalPlaces",
1353
1353
  property_deeplink: "@deeplink",
1354
+ property_displayName: "@displayName",
1354
1355
  property_diffContext: "@diffContext",
1355
1356
  property_diffOp: "@diffOp",
1356
1357
  property_diffRef: "@diffRef",
@@ -1563,6 +1564,8 @@ var propertyKeys = {
1563
1564
  property_trim: "@trim",
1564
1565
  property_unit: "@unit",
1565
1566
  property_unitAbbr: "@unitAbbr",
1567
+ property_unitAbbrPlural: "@unitAbbrPlural",
1568
+ property_unitPlural: "@unitPlural",
1566
1569
  property_vendorDashboardId: "@vendorDashboardId",
1567
1570
  property_vendorSurveyId: "@vendorSurveyId",
1568
1571
  property_vendorUrl: "@vendorUrl",
@@ -2500,9 +2503,30 @@ var CARDSETS = {
2500
2503
  [CardSetConfigKey.definitionList]: {
2501
2504
  jsonKey: "definitions",
2502
2505
  exportJsonKey: { definitions: "$" },
2506
+ // PLAN-141 F1 (NISO import): each <def-item> is one card; the sides
2507
+ // read <term>/<def>; the enclosing <legend>'s <title> lands on the
2508
+ // term side's heading tag ([#Key] header card).
2509
+ // PLAN-141 F3: a <tbx:langSet> is ALSO one card (a terminology entry —
2510
+ // its enclosing <tbx:termEntry> is a transparent claim wrapper); its
2511
+ // children compose the term/definition sides via the side rules below.
2512
+ mappingKeys: {
2513
+ "xml-niso-iec": [
2514
+ { "@el": "def-item", "@children": "$" },
2515
+ { "@el": "tbx:langSet", "@children": "$" }
2516
+ ]
2517
+ },
2503
2518
  sides: [
2504
2519
  {
2505
2520
  name: "term",
2521
+ // F3: every <tbx:tig>'s <tbx:term> STACKS one-per-line onto the
2522
+ // single term side (the "$\n" template's authored separator; the
2523
+ // trailing one is trimmed) — the PDF's Maus/Mus/M/Müsli stack.
2524
+ mappingKeys: {
2525
+ "xml-niso-iec": [
2526
+ { "@el": "term", "@text": "$" },
2527
+ { "@el": "tbx:tig", "@children": { "@el": "tbx:term", "@text": "$\n" } }
2528
+ ]
2529
+ },
2506
2530
  variants: [
2507
2531
  {
2508
2532
  jsonKey: "term.text",
@@ -2518,7 +2542,8 @@ var CARDSETS = {
2518
2542
  format: TagFormat.plainText,
2519
2543
  nullable: true,
2520
2544
  jsonKey: "^heading.forKeys",
2521
- exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2545
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } },
2546
+ mappingKeys: { "xml-niso-iec": { "@el": "title", "@text": "$" } }
2522
2547
  },
2523
2548
  {
2524
2549
  key: ConfigKey.group_resourceIcon,
@@ -2544,6 +2569,24 @@ var CARDSETS = {
2544
2569
  },
2545
2570
  {
2546
2571
  name: "definition",
2572
+ // F3: the definition side COMPOSES from the entry's fields in
2573
+ // document order, with the ES-rendered locale affixes AUTHORED as
2574
+ // value-position templates (never engine text): the subject field
2575
+ // in ⟨⟩ glues (trailing space) onto the definition line; example /
2576
+ // notes / source follow as blank-line-separated lines. The TBX
2577
+ // grammar flags (normativeAuthorization, termType, partOfSpeech,
2578
+ // grammaticalNumber) are unrendered machine-only data — dropped and
2579
+ // recorded (catalog R-2, reviewed under D7 max-preservation).
2580
+ mappingKeys: {
2581
+ "xml-niso-iec": [
2582
+ { "@el": "def", "@children": "$" },
2583
+ { "@el": "tbx:subjectField", "@text": "\u27E8$\u27E9 " },
2584
+ { "@el": "tbx:definition", "@children": "$" },
2585
+ { "@el": "tbx:example", "@children": "BEISPIEL $" },
2586
+ { "@el": "tbx:note", "@children": "Anmerkung zu Begriff: $" },
2587
+ { "@el": "tbx:source", "@text": "[QUELLE: $]" }
2588
+ ]
2589
+ },
2547
2590
  variants: [
2548
2591
  {
2549
2592
  jsonKey: "definition.text",
@@ -3934,6 +3977,11 @@ var CARDSETS = {
3934
3977
  { table: { header: { rows: ["$"] } } }
3935
3978
  ],
3936
3979
  htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
3980
+ // PLAN-141 F2 (NISO import): the XHTML table model NISO uses — a
3981
+ // <thead> SECTION whose <tr> rows are the header cards.
3982
+ mappingKeys: {
3983
+ "xml-niso-iec": { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } }
3984
+ },
3937
3985
  sideJsonKey: "cells[{s}]|set(title=true)",
3938
3986
  sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
3939
3987
  // Header cells are `<th>`. The `width` attribute is contributed by the
@@ -3945,12 +3993,21 @@ var CARDSETS = {
3945
3993
  jsonKey: "table.body.rows",
3946
3994
  exportJsonKey: { table: { body: { rows: "$" } } },
3947
3995
  htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
3996
+ // PLAN-141 F2 (NISO import): <tbody> rows are the (default) data cards.
3997
+ mappingKeys: {
3998
+ "xml-niso-iec": { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } }
3999
+ },
3948
4000
  isDefault: true
3949
4001
  },
3950
4002
  "table-footer": {
3951
4003
  jsonKey: "table.footer.rows",
3952
4004
  exportJsonKey: { table: { footer: { rows: "$" } } },
3953
4005
  htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
4006
+ // PLAN-141 F2 (NISO import): NISO has no <tfoot> — the footer card's
4007
+ // source is the <table-wrap-foot> block (CONTENT-shaped: no rows; its
4008
+ // prose/notes flatten into one footer card — catalog table-wrap-foot
4009
+ // row; a contained <def-list> promotes as a sibling legend bit).
4010
+ mappingKeys: { "xml-niso-iec": { "@el": "table-wrap-foot", "@children": "$" } },
3954
4011
  sideJsonKey: "cells[{s}]|set(title=true)",
3955
4012
  sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
3956
4013
  // Footer cells render as `<th>` (mirrors the header `title: true`
@@ -3967,6 +4024,8 @@ var CARDSETS = {
3967
4024
  // Default (body) cell → `<td>`; the header/footer sections override the
3968
4025
  // side to `<th>` via their sideHtmlKey (HTML.md §8).
3969
4026
  htmlKey: { "@el": "td", "@children": "$" },
4027
+ // PLAN-141 F2 (NISO import): a <td> row child is a body cell side.
4028
+ mappingKeys: { "xml-niso-iec": { "@el": "td", "@children": "$" } },
3970
4029
  variants: [
3971
4030
  {
3972
4031
  jsonKey: "content",
@@ -3984,7 +4043,11 @@ var CARDSETS = {
3984
4043
  // cell with `title: true` automatically.
3985
4044
  jsonKey: "content",
3986
4045
  exportJsonKey: { content: "$" },
3987
- description: "Title text of the table cell (header rows)."
4046
+ description: "Title text of the table cell (header rows).",
4047
+ // PLAN-141 F2 (NISO import): a <th> row child is a TITLE cell —
4048
+ // its content lands in the `[#…]` tag (an empty <th> keeps its
4049
+ // slot as a bare `[#]`).
4050
+ mappingKeys: { "xml-niso-iec": { "@el": "th", "@children": "$" } }
3988
4051
  },
3989
4052
  {
3990
4053
  key: ConfigKey.property_tableCellType,
@@ -4003,6 +4066,9 @@ var CARDSETS = {
4003
4066
  // HTML-C2: contribute a `rowspan` attribute onto the enclosing
4004
4067
  // cell element (`<th>`/`<td>`).
4005
4068
  htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
4069
+ // PLAN-141 F2 (NISO import): recover the source cell's own
4070
+ // `rowspan` attribute (element-scope attr form).
4071
+ mappingKeys: { "xml-niso-iec": { "@el": { "@attr": { rowspan: "$" } } } },
4006
4072
  description: "Number of rows the cell spans.",
4007
4073
  format: TagFormat.number
4008
4074
  },
@@ -4013,6 +4079,9 @@ var CARDSETS = {
4013
4079
  // HTML-C2: contribute a `colspan` attribute onto the enclosing
4014
4080
  // cell element (`<th>`/`<td>`).
4015
4081
  htmlKey: { "@el": { "@attr": { colspan: "$" } } },
4082
+ // PLAN-141 F2 (NISO import): recover the source cell's own
4083
+ // `colspan` attribute (element-scope attr form).
4084
+ mappingKeys: { "xml-niso-iec": { "@el": { "@attr": { colspan: "$" } } } },
4016
4085
  description: "Number of columns the cell spans.",
4017
4086
  format: TagFormat.number
4018
4087
  },
@@ -4034,6 +4103,13 @@ var CARDSETS = {
4034
4103
  // HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
4035
4104
  // enclosing cell element (`<th>`/`<td>`).
4036
4105
  htmlKey: { "@el": { "@attr": { width: "$" } } },
4106
+ // PLAN-141 F2 (NISO import): NISO carries widths as PER-COLUMN
4107
+ // <col width="…"> descriptors at container level, not on cells.
4108
+ // The matched values distribute positionally onto the first
4109
+ // (header) card's sides. Number format ⇒ only an integral
4110
+ // percentage survives ("20.0000%" → 20); a fractional one
4111
+ // (renderer-equalised "4.7619%") is dropped — catalog `col` row.
4112
+ mappingKeys: { "xml-niso-iec": { "@el": "col", "@attr": { width: "$" } } },
4037
4113
  description: "Width for the column.",
4038
4114
  format: TagFormat.number
4039
4115
  }
@@ -4303,12 +4379,22 @@ var CARDSETS = {
4303
4379
  },
4304
4380
  {
4305
4381
  key: ConfigKey.property_unit,
4306
- description: "Unit of measurement for the ingredient.",
4382
+ description: "Unit of measurement for the ingredient (singular).",
4383
+ format: TagFormat.plainText
4384
+ },
4385
+ {
4386
+ key: ConfigKey.property_unitPlural,
4387
+ description: "Unit of measurement for the ingredient (plural).",
4307
4388
  format: TagFormat.plainText
4308
4389
  },
4309
4390
  {
4310
4391
  key: ConfigKey.property_unitAbbr,
4311
- description: "Abbreviation for the unit of measurement.",
4392
+ description: "Abbreviation for the unit of measurement (singular).",
4393
+ format: TagFormat.plainText
4394
+ },
4395
+ {
4396
+ key: ConfigKey.property_unitAbbrPlural,
4397
+ description: "Abbreviation for the unit of measurement (plural).",
4312
4398
  format: TagFormat.plainText
4313
4399
  },
4314
4400
  {
@@ -4407,7 +4493,22 @@ var GROUPS = {
4407
4493
  key: ConfigKey.property_externalId,
4408
4494
  description: "The external identifier for the bit",
4409
4495
  format: TagFormat.plainText,
4410
- maxCount: Count.infinity
4496
+ maxCount: Count.infinity,
4497
+ // PLAN-140 refs family (NISO import): the machine identifier of a
4498
+ // referenced standard. NESTED content slot — the tag reads (and
4499
+ // consumes) ONLY the <std-id> inside a <std> child; the remaining
4500
+ // designation/title text stays bit body. A <std> without <std-id>
4501
+ // does not fire the key.
4502
+ // PLAN-141 F5: on the [.book] bit, the DATED <std-ref> designation
4503
+ // is the document's external id. Safe rule order: <std-ref> is a
4504
+ // direct bit-element child only under <std-meta> (everywhere else
4505
+ // it nests inside <std>, which the tag spine never reaches).
4506
+ mappingKeys: {
4507
+ "xml-niso-iec": [
4508
+ { "@el": "std", "@children": { "@el": "std-id", "@text": "$" } },
4509
+ { "@el": "std-ref", "@attr": { type: "dated" }, "@text": "$" }
4510
+ ]
4511
+ }
4411
4512
  },
4412
4513
  {
4413
4514
  key: ConfigKey.property_sourceRL,
@@ -4469,6 +4570,11 @@ var GROUPS = {
4469
4570
  description: "Translation source reference",
4470
4571
  format: TagFormat.plainText
4471
4572
  },
4573
+ {
4574
+ key: ConfigKey.property_isCollapsible,
4575
+ description: "If true, the bit is collapsible",
4576
+ format: TagFormat.boolean
4577
+ },
4472
4578
  {
4473
4579
  key: ConfigKey.property_spansPageBreak,
4474
4580
  description: "If true, the bit spans a page break",
@@ -4548,7 +4654,8 @@ var GROUPS = {
4548
4654
  {
4549
4655
  key: ConfigKey.property_diffTime,
4550
4656
  description: "The diff time for the bit",
4551
- format: TagFormat.number
4657
+ format: TagFormat.number,
4658
+ nullable: true
4552
4659
  },
4553
4660
  {
4554
4661
  key: ConfigKey.property_ageRange,
@@ -4559,7 +4666,18 @@ var GROUPS = {
4559
4666
  {
4560
4667
  key: ConfigKey.property_lang,
4561
4668
  description: "The language for the bit",
4562
- format: TagFormat.plainText
4669
+ format: TagFormat.plainText,
4670
+ // PLAN-141 F3 (NISO import): a term-sec's language rides
4671
+ // <tbx:termEntry><tbx:langSet xml:lang> — a nested content slot
4672
+ // whose leaf is a $-in-ATTR-position slot (the nested counterpart
4673
+ // of the value-attr slot). Only termEntry elements match, so the
4674
+ // shared tag is inert everywhere else.
4675
+ mappingKeys: {
4676
+ "xml-niso-iec": {
4677
+ "@el": "tbx:termEntry",
4678
+ "@children": { "@el": "tbx:langSet", "@attr": { "xml:lang": "$" } }
4679
+ }
4680
+ }
4563
4681
  },
4564
4682
  {
4565
4683
  key: ConfigKey.property_publisher,
@@ -4758,6 +4876,9 @@ var GROUPS = {
4758
4876
  key: ConfigKey.tag_item,
4759
4877
  jsonKey: "item",
4760
4878
  exportJsonKey: { item: "$" },
4879
+ // PLAN-140 W3 (NISO import): the clause/note label of a mapped
4880
+ // source element ([%1], [%ANMERKUNG 1]).
4881
+ mappingKeys: { "xml-niso-iec": { "@el": "label", "@text": "$" } },
4761
4882
  description: "The item for the bit",
4762
4883
  chain: [
4763
4884
  {
@@ -5720,7 +5841,20 @@ var GROUPS = {
5720
5841
  key: ConfigKey.property_language,
5721
5842
  description: "The language of the book",
5722
5843
  format: TagFormat.plainText,
5723
- maxCount: Count.infinity
5844
+ maxCount: Count.infinity,
5845
+ // PLAN-141 F5 (NISO import): only the PRIMARY (first)
5846
+ // <content-language> survives — the maxEmits cap realises the
5847
+ // catalog's document-language rule (extras drop, R-4).
5848
+ mappingKeys: {
5849
+ "xml-niso-iec": [
5850
+ { predicates: [], maxEmits: 1, rule: { "@el": "content-language", "@text": "$" } }
5851
+ ]
5852
+ }
5853
+ },
5854
+ {
5855
+ key: ConfigKey.property_displayName,
5856
+ description: "The display name of the book",
5857
+ format: TagFormat.plainText
5724
5858
  },
5725
5859
  {
5726
5860
  key: ConfigKey.property_customerExternalId,
@@ -5796,7 +5930,18 @@ var GROUPS = {
5796
5930
  description: "The title of the book",
5797
5931
  maxCount: 2,
5798
5932
  jsonKey: "title|multi(count=2, key=subtitle)",
5799
- exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5933
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }],
5934
+ // PLAN-141 F5 (NISO import): the PRIMARY (first) <title-wrap>'s
5935
+ // assembled <full> title → [#]; the per-language extras drop (R-4).
5936
+ mappingKeys: {
5937
+ "xml-niso-iec": [
5938
+ {
5939
+ predicates: [],
5940
+ maxEmits: 1,
5941
+ rule: { "@el": "title-wrap", "@children": { "@el": "full", "@text": "$" } }
5942
+ }
5943
+ ]
5944
+ }
5800
5945
  },
5801
5946
  {
5802
5947
  key: ConfigKey.property_subtype,
@@ -6109,17 +6254,20 @@ var GROUPS = {
6109
6254
  {
6110
6255
  key: ConfigKey.property_platformMargin,
6111
6256
  description: "The platform margin",
6112
- format: TagFormat.number
6257
+ format: TagFormat.number,
6258
+ nullable: true
6113
6259
  },
6114
6260
  {
6115
6261
  key: ConfigKey.property_platformBorderRadius,
6116
6262
  description: "The platform border radius",
6117
- format: TagFormat.number
6263
+ format: TagFormat.number,
6264
+ nullable: true
6118
6265
  },
6119
6266
  {
6120
6267
  key: ConfigKey.property_platformSelectionBorderRadius,
6121
6268
  description: "The platform selection border radius",
6122
- format: TagFormat.number
6269
+ format: TagFormat.number,
6270
+ nullable: true
6123
6271
  },
6124
6272
  {
6125
6273
  key: ConfigKey.property_platformNeedsShadow,
@@ -6226,7 +6374,13 @@ var GROUPS = {
6226
6374
  {
6227
6375
  key: ConfigKey.property_caption,
6228
6376
  description: "The caption for the resource",
6229
- format: TagFormat.bitmarkText
6377
+ format: TagFormat.bitmarkText,
6378
+ // PLAN-141 F1 (NISO import): a figure's <caption><title> — the
6379
+ // nested content slot reads the title text; the caption rides the
6380
+ // resource chain ([&image:…][@caption:…], catalog D5).
6381
+ mappingKeys: {
6382
+ "xml-niso-iec": { "@el": "caption", "@children": { "@el": "title", "@text": "$" } }
6383
+ }
6230
6384
  },
6231
6385
  {
6232
6386
  key: ConfigKey.property_showInIndex,
@@ -6500,6 +6654,10 @@ var GROUPS = {
6500
6654
  {
6501
6655
  key: ConfigKey.resource_image,
6502
6656
  exportJsonKey: { resource: { type: "image", image: { src: "$" } } },
6657
+ // PLAN-141 F1 (NISO import): the image URL rides the `$`-in-attr
6658
+ // value slot — a <graphic xlink:href> child of the mapped bit
6659
+ // element roots the [&image:URL] chain.
6660
+ mappingKeys: { "xml-niso-iec": { "@el": "graphic", "@attr": { "xlink:href": "$" } } },
6503
6661
  description: "The image resource",
6504
6662
  chain: [
6505
6663
  {
@@ -7374,6 +7532,8 @@ var BITS = {
7374
7532
  maxCount: 2,
7375
7533
  jsonKey: "title|multi(count=2, key=subtitle)",
7376
7534
  exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }],
7535
+ // PLAN-140 W3 (NISO import): the title of a mapped source element.
7536
+ mappingKeys: { "xml-niso-iec": { "@el": "title", "@text": "$" } },
7377
7537
  key: ConfigKey.tag_title,
7378
7538
  description: "The title of the article"
7379
7539
  }
@@ -7415,22 +7575,84 @@ var BITS = {
7415
7575
  [BitType.smartStandardArticleNormative]: {
7416
7576
  since: "1.28.0",
7417
7577
  baseBitType: BitType.standardArticleNormative,
7418
- description: "Smart standard normative article bit"
7578
+ description: "Smart standard normative article bit",
7579
+ // PLAN-140 W3 (NISO import, tranche 1): one article bit per NISO
7580
+ // paragraph (catalog D1). CONTENT keys (@children): the subtree is the
7581
+ // bit's body; nothing inside it promotes. (Ancestor-context normativity
7582
+ // is the non-normative sibling's @ancestor key — plan Q4, resolved.)
7583
+ //
7584
+ // Second rule (catalog D1 push-down): a NUMBERED-PARAGRAPH sec is an
7585
+ // article, not a chapter — the sec-type literal outranks the chapter
7586
+ // key's plain sec|app rule (most-specific-wins). Content key: the sec's
7587
+ // label rides [%] via the label tag key, its inner <p> is the body, its
7588
+ // id is the bit's customerId, and the anchor slot marks it
7589
+ // anchor-bearing.
7590
+ mappingKeys: {
7591
+ "xml-niso-iec": [
7592
+ { "@el": "p", "@attr": { id: "$customerId" }, "@children": "$" },
7593
+ {
7594
+ "@el": "sec",
7595
+ "@attr": { "sec-type": "numbered-paragraph", id: "$customerId" },
7596
+ "@children": "$",
7597
+ "\u25BC": "$anchor"
7598
+ }
7599
+ ]
7600
+ }
7419
7601
  },
7420
7602
  [BitType.smartStandardArticleNonNormative]: {
7421
7603
  since: "1.28.0",
7422
7604
  baseBitType: BitType.standardArticleNonNormative,
7423
- description: "Smart standard non-normative article bit"
7605
+ description: "Smart standard non-normative article bit",
7606
+ // PLAN-140 Q4 (normativity inheritance): a <p> is non-normative because
7607
+ // of an ANCESTOR element — a foreword/intro sec or an informative annex.
7608
+ // @ancestor is a reverse-match-only constraint (forward emission ignores
7609
+ // it); the rules are alternatives, first-satisfied wins, and the
7610
+ // @ancestor literals give this key higher specificity than the plain
7611
+ // normative-article <p> key wherever the context applies.
7612
+ mappingKeys: {
7613
+ "xml-niso-iec": [
7614
+ {
7615
+ "@el": "p",
7616
+ "@attr": { id: "$customerId" },
7617
+ "@ancestor": { "@attr": { "sec-type": "foreword|intro" } },
7618
+ "@children": "$"
7619
+ },
7620
+ {
7621
+ "@el": "p",
7622
+ "@attr": { id: "$customerId" },
7623
+ "@ancestor": { "@attr": { "content-type": "informative" } },
7624
+ "@children": "$"
7625
+ }
7626
+ ]
7627
+ }
7424
7628
  },
7425
7629
  [BitType.smartStandardArticleNormativeCollapsible]: {
7426
7630
  since: "1.28.0",
7631
+ deprecated: "5.37.0",
7427
7632
  baseBitType: BitType.smartStandardArticleNormative,
7428
- description: "Smart standard normative article bit that is collapsible"
7633
+ description: "Smart standard normative article bit that is collapsible",
7634
+ tags: [
7635
+ {
7636
+ key: ConfigKey.property_isCollapsible,
7637
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
7638
+ format: TagFormat.boolean,
7639
+ defaultValue: "true"
7640
+ }
7641
+ ]
7429
7642
  },
7430
7643
  [BitType.smartStandardArticleNonNormativeCollapsible]: {
7431
7644
  since: "1.28.0",
7645
+ deprecated: "5.37.0",
7432
7646
  baseBitType: BitType.smartStandardArticleNonNormative,
7433
- description: "Smart standard non-normative article bit that is collapsible"
7647
+ description: "Smart standard non-normative article bit that is collapsible",
7648
+ tags: [
7649
+ {
7650
+ key: ConfigKey.property_isCollapsible,
7651
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
7652
+ format: TagFormat.boolean,
7653
+ defaultValue: "true"
7654
+ }
7655
+ ]
7434
7656
  },
7435
7657
  [BitType.statement]: {
7436
7658
  since: "1.3.0",
@@ -8051,7 +8273,8 @@ var BITS = {
8051
8273
  {
8052
8274
  key: ConfigKey.property_maxCreatedBits,
8053
8275
  description: "The maximum number of bits that can be created from this bit",
8054
- format: TagFormat.number
8276
+ format: TagFormat.number,
8277
+ nullable: true
8055
8278
  }
8056
8279
  ],
8057
8280
  textFormatDefault: TextFormat.plainText
@@ -8181,6 +8404,13 @@ var BITS = {
8181
8404
  since: "1.3.0",
8182
8405
  baseBitType: BitType._standard,
8183
8406
  description: "Book bit, used to represent a book",
8407
+ // PLAN-141 F5 (NISO import): the <std-meta> front-matter container is
8408
+ // the [.book] bit (STRUCTURAL, first in document order): primary
8409
+ // title-wrap → [#], primary content-language → [@language], dated
8410
+ // std-ref → [@externalId] (tag keys with maxEmits caps — the NISO
8411
+ // convention puts the document language first). std-meta has no id, so
8412
+ // no anchor/customerId. Remaining leaves drop as recorded loss (R-4).
8413
+ mappingKeys: { "xml-niso-iec": { "@el": "std-meta" } },
8184
8414
  tags: [
8185
8415
  {
8186
8416
  key: ConfigKey.group_bookCommon,
@@ -8467,12 +8697,14 @@ var BITS = {
8467
8697
  {
8468
8698
  key: ConfigKey.property_focusX,
8469
8699
  description: "The X coordinate for focusing the image in the browser",
8470
- format: TagFormat.number
8700
+ format: TagFormat.number,
8701
+ nullable: true
8471
8702
  },
8472
8703
  {
8473
8704
  key: ConfigKey.property_focusY,
8474
8705
  description: "The Y coordinate for focusing the image in the browser",
8475
- format: TagFormat.number
8706
+ format: TagFormat.number,
8707
+ nullable: true
8476
8708
  }
8477
8709
  ]
8478
8710
  },
@@ -8503,6 +8735,15 @@ var BITS = {
8503
8735
  since: "1.3.0",
8504
8736
  baseBitType: BitType._standard,
8505
8737
  description: "Chapter bit, used to define chapters in books or articles",
8738
+ // PLAN-140 W3 (NISO import, tranche 1): recover a chapter from a NISO
8739
+ // section or annex. STRUCTURAL key (no @children content slot): the
8740
+ // element carries no body of its own — tag children (label/title) map
8741
+ // via tag keys, every mapped descendant promotes to a following sibling
8742
+ // bit, and the chapter level derives from nesting depth (catalog D1).
8743
+ // The source id lands as [@customerId] (two-id model, D2).
8744
+ mappingKeys: {
8745
+ "xml-niso-iec": { "@el": "sec|app", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
8746
+ },
8506
8747
  tags: [
8507
8748
  {
8508
8749
  exportJsonKey: { anchor: "$" },
@@ -8514,7 +8755,10 @@ var BITS = {
8514
8755
  key: ConfigKey.tag_title,
8515
8756
  description: "The title of the chapter",
8516
8757
  jsonKey: "title|setMulti(level)",
8517
- exportJsonKey: { title: "$", level: "$level" }
8758
+ exportJsonKey: { title: "$", level: "$level" },
8759
+ // PLAN-140 W3 (NISO import): the section/annex title; the heading
8760
+ // level rides the normalizer-derived nesting depth (plan Q2).
8761
+ mappingKeys: { "xml-niso-iec": { "@el": "title", "@text": "$" } }
8518
8762
  },
8519
8763
  {
8520
8764
  key: ConfigKey.property_toc,
@@ -8527,12 +8771,6 @@ var BITS = {
8527
8771
  description: "The progress of the chapter, used for tracking reading progress",
8528
8772
  format: TagFormat.boolean,
8529
8773
  defaultValue: "true"
8530
- },
8531
- {
8532
- key: ConfigKey.property_isCollapsible,
8533
- description: "If true, the chapter is collapsible",
8534
- format: TagFormat.boolean,
8535
- defaultValue: "false"
8536
8774
  }
8537
8775
  ]
8538
8776
  },
@@ -8720,11 +8958,28 @@ var BITS = {
8720
8958
  since: "1.3.0",
8721
8959
  baseBitType: BitType._standard,
8722
8960
  description: "Code bit, used for code snippets in articles or documents",
8961
+ // PLAN-141 F4 (NISO import): a <code> block is a CONTENT bit with a
8962
+ // literal text body; @language recovers as [@computerLanguage] (absent
8963
+ // attr → no tag). Anchor = the source id (D2 revised).
8964
+ mappingKeys: {
8965
+ "xml-niso-iec": {
8966
+ "@el": "code",
8967
+ "@attr": { id: "$customerId", language: "$computerLanguage" },
8968
+ "\u25BC": "$anchor",
8969
+ "@text": "$"
8970
+ }
8971
+ },
8723
8972
  tags: [
8724
8973
  {
8725
8974
  key: ConfigKey.property_computerLanguage,
8726
8975
  description: "The programming language of the code snippet",
8727
- format: TagFormat.plainText
8976
+ format: TagFormat.plainText,
8977
+ // PLAN-141 F4 (NISO import): the bit key's `language` sigil recovers
8978
+ // a present attr; this `@absent` rule supplies the AUTHORED default
8979
+ // when the source carries none (catalog code row — an untyped block
8980
+ // is `[@computerLanguage:text]`). Fires only on foreign imports,
8981
+ // never the carrier round-trip.
8982
+ mappingKeys: { "xml-niso-iec": [{ "@absent": "text" }] }
8728
8983
  },
8729
8984
  {
8730
8985
  key: ConfigKey.property_codeLineNumbers,
@@ -8763,7 +9018,20 @@ var BITS = {
8763
9018
  [BitType.smartStandardFormulaNormative]: {
8764
9019
  since: "3.11.0",
8765
9020
  baseBitType: BitType.formula,
8766
- description: "Smart standard normative formula bit, used for mathematical formulas in smart standards that are normative"
9021
+ description: "Smart standard normative formula bit, used for mathematical formulas in smart standards that are normative",
9022
+ // PLAN-141 F4 (NISO import): a <disp-formula> is a CONTENT bit whose
9023
+ // latex-format body carries the <mml:math> subtree VERBATIM (G1 — no
9024
+ // MathML↔LaTeX transform; ids stripped); <label> → [%]; a contained
9025
+ // <legend> PROMOTES as a sibling legend bit (cards cannot nest in a
9026
+ // body). Anchor = the source id (D2 revised).
9027
+ mappingKeys: {
9028
+ "xml-niso-iec": {
9029
+ "@el": "disp-formula",
9030
+ "@attr": { id: "$customerId" },
9031
+ "\u25BC": "$anchor",
9032
+ "@children": "$"
9033
+ }
9034
+ }
8767
9035
  },
8768
9036
  [BitType.smartStandardRemarkFormula]: {
8769
9037
  since: "3.11.0",
@@ -9109,12 +9377,22 @@ var BITS = {
9109
9377
  chain: [
9110
9378
  {
9111
9379
  key: ConfigKey.property_unit,
9112
- description: "The unit of measurement for the ingredients",
9380
+ description: "The unit of measurement for the ingredients (singular)",
9381
+ format: TagFormat.plainText
9382
+ },
9383
+ {
9384
+ key: ConfigKey.property_unitPlural,
9385
+ description: "The unit of measurement for the ingredients (plural)",
9113
9386
  format: TagFormat.plainText
9114
9387
  },
9115
9388
  {
9116
9389
  key: ConfigKey.property_unitAbbr,
9117
- description: "The abbreviation for the unit of measurement",
9390
+ description: "The abbreviation for the unit of measurement (singular)",
9391
+ format: TagFormat.plainText
9392
+ },
9393
+ {
9394
+ key: ConfigKey.property_unitAbbrPlural,
9395
+ description: "The abbreviation for the unit of measurement (plural)",
9118
9396
  format: TagFormat.plainText
9119
9397
  },
9120
9398
  {
@@ -9290,7 +9568,8 @@ var BITS = {
9290
9568
  {
9291
9569
  key: ConfigKey.property_reasonableNumOfChars,
9292
9570
  description: "The reasonable number of characters for the essay",
9293
- format: TagFormat.number
9571
+ format: TagFormat.number,
9572
+ nullable: true
9294
9573
  },
9295
9574
  {
9296
9575
  key: ConfigKey.property_sampleSolution,
@@ -9392,13 +9671,31 @@ var BITS = {
9392
9671
  },
9393
9672
  [BitType.smartStandardExampleNormativeCollapsible]: {
9394
9673
  since: "1.28.0",
9674
+ deprecated: "5.37.0",
9395
9675
  baseBitType: BitType.smartStandardExampleNormative,
9396
- description: "Smart standard normative example collapsible bit, used to provide normative examples in smart standards that can be collapsed"
9676
+ description: "Smart standard normative example collapsible bit, used to provide normative examples in smart standards that can be collapsed",
9677
+ tags: [
9678
+ {
9679
+ key: ConfigKey.property_isCollapsible,
9680
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
9681
+ format: TagFormat.boolean,
9682
+ defaultValue: "true"
9683
+ }
9684
+ ]
9397
9685
  },
9398
9686
  [BitType.smartStandardExampleNonNormativeCollapsible]: {
9399
9687
  since: "1.28.0",
9688
+ deprecated: "5.37.0",
9400
9689
  baseBitType: BitType.smartStandardExampleNonNormative,
9401
- description: "Smart standard non-normative example collapsible bit, used to provide non-normative examples in smart standards that can be collapsed"
9690
+ description: "Smart standard non-normative example collapsible bit, used to provide non-normative examples in smart standards that can be collapsed",
9691
+ tags: [
9692
+ {
9693
+ key: ConfigKey.property_isCollapsible,
9694
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
9695
+ format: TagFormat.boolean,
9696
+ defaultValue: "true"
9697
+ }
9698
+ ]
9402
9699
  },
9403
9700
  [BitType.authorContentBitGenerator]: {
9404
9701
  since: "4.2.0",
@@ -9723,12 +10020,28 @@ var BITS = {
9723
10020
  [BitType.smartStandardList]: {
9724
10021
  since: "1.28.0",
9725
10022
  baseBitType: BitType.standardList,
9726
- description: "Smart standard list bit, used to create smart standard lists in articles or books"
10023
+ description: "Smart standard list bit, used to create smart standard lists in articles or books",
10024
+ // PLAN-140 refs family (NISO import): a reference list is a STRUCTURAL
10025
+ // bit (no @children — it takes a path ordinal anchor and its <ref>
10026
+ // children promote to sibling list-item bits); its <title> rides [#]
10027
+ // via the title tag key.
10028
+ mappingKeys: {
10029
+ "xml-niso-iec": { "@el": "ref-list", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
10030
+ }
9727
10031
  },
9728
10032
  [BitType.smartStandardListCollapsible]: {
9729
10033
  since: "1.28.0",
10034
+ deprecated: "5.37.0",
9730
10035
  baseBitType: BitType.smartStandardList,
9731
- description: "Smart standard list collapsible bit, used to create collapsible smart standard lists in articles or books"
10036
+ description: "Smart standard list collapsible bit, used to create collapsible smart standard lists in articles or books",
10037
+ tags: [
10038
+ {
10039
+ key: ConfigKey.property_isCollapsible,
10040
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10041
+ format: TagFormat.boolean,
10042
+ defaultValue: "true"
10043
+ }
10044
+ ]
9732
10045
  },
9733
10046
  [BitType.message]: {
9734
10047
  since: "1.3.0",
@@ -9768,17 +10081,45 @@ var BITS = {
9768
10081
  [BitType.smartStandardNoteNonNormative]: {
9769
10082
  since: "1.28.0",
9770
10083
  baseBitType: BitType.standardNoteNonNormative,
9771
- description: "Smart standard non-normative note bit, used to provide non-normative notes in smart standards"
10084
+ description: "Smart standard non-normative note bit, used to provide non-normative notes in smart standards",
10085
+ // PLAN-140 W3 (NISO import, tranche 1). CONTENT key (@children): a
10086
+ // note's inner paragraphs are note body, never separate bits.
10087
+ mappingKeys: {
10088
+ "xml-niso-iec": {
10089
+ "@el": "non-normative-note",
10090
+ "@attr": { id: "$customerId" },
10091
+ "@children": "$",
10092
+ "\u25BC": "$anchor"
10093
+ }
10094
+ }
9772
10095
  },
9773
10096
  [BitType.smartStandardNoteNormativeCollapsible]: {
9774
10097
  since: "1.28.0",
10098
+ deprecated: "5.37.0",
9775
10099
  baseBitType: BitType.smartStandardNoteNormative,
9776
- description: "Smart standard normative note collapsible bit, used to provide normative notes in smart standards that can be collapsed"
10100
+ description: "Smart standard normative note collapsible bit, used to provide normative notes in smart standards that can be collapsed",
10101
+ tags: [
10102
+ {
10103
+ key: ConfigKey.property_isCollapsible,
10104
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10105
+ format: TagFormat.boolean,
10106
+ defaultValue: "true"
10107
+ }
10108
+ ]
9777
10109
  },
9778
10110
  [BitType.smartStandardNoteNonNormativeCollapsible]: {
9779
10111
  since: "1.28.0",
10112
+ deprecated: "5.37.0",
9780
10113
  baseBitType: BitType.smartStandardNoteNonNormative,
9781
- description: "Smart standard non-normative note collapsible bit, used to provide non-normative notes in smart standards that can be collapsed"
10114
+ description: "Smart standard non-normative note collapsible bit, used to provide non-normative notes in smart standards that can be collapsed",
10115
+ tags: [
10116
+ {
10117
+ key: ConfigKey.property_isCollapsible,
10118
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10119
+ format: TagFormat.boolean,
10120
+ defaultValue: "true"
10121
+ }
10122
+ ]
9782
10123
  },
9783
10124
  [BitType.noteAi]: {
9784
10125
  since: "1.3.0",
@@ -9875,17 +10216,47 @@ var BITS = {
9875
10216
  [BitType.smartStandardRemarkNonNormative]: {
9876
10217
  since: "1.28.0",
9877
10218
  baseBitType: BitType.standardRemarkNonNormative,
9878
- description: "Smart standard non-normative remark bit, used to provide non-normative remarks in smart standards"
10219
+ description: "Smart standard non-normative remark bit, used to provide non-normative remarks in smart standards",
10220
+ // PLAN-140 Q4 rider: a warning/caution note routes to the remark bit —
10221
+ // the same element as the note key, distinguished by the content-type
10222
+ // attr literal (alias value: forward emits the first alternative,
10223
+ // reverse accepts any). Most-specific-wins beats the plain note key.
10224
+ mappingKeys: {
10225
+ "xml-niso-iec": {
10226
+ "@el": "non-normative-note",
10227
+ "@attr": { "content-type": "warning|caution", id: "$customerId" },
10228
+ "@children": "$",
10229
+ "\u25BC": "$anchor"
10230
+ }
10231
+ }
9879
10232
  },
9880
10233
  [BitType.smartStandardRemarkNormativeCollapsible]: {
9881
10234
  since: "1.28.0",
10235
+ deprecated: "5.37.0",
9882
10236
  baseBitType: BitType.smartStandardRemarkNormative,
9883
- description: "Smart standard normative remark collapsible bit, used to provide normative remarks in smart standards that can be collapsed"
10237
+ description: "Smart standard normative remark collapsible bit, used to provide normative remarks in smart standards that can be collapsed",
10238
+ tags: [
10239
+ {
10240
+ key: ConfigKey.property_isCollapsible,
10241
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10242
+ format: TagFormat.boolean,
10243
+ defaultValue: "true"
10244
+ }
10245
+ ]
9884
10246
  },
9885
10247
  [BitType.smartStandardRemarkNonNormativeCollapsible]: {
9886
10248
  since: "1.28.0",
10249
+ deprecated: "5.37.0",
9887
10250
  baseBitType: BitType.smartStandardRemarkNonNormative,
9888
- description: "Smart standard non-normative remark collapsible bit, used to provide non-normative remarks in smart standards that can be collapsed"
10251
+ description: "Smart standard non-normative remark collapsible bit, used to provide non-normative remarks in smart standards that can be collapsed",
10252
+ tags: [
10253
+ {
10254
+ key: ConfigKey.property_isCollapsible,
10255
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10256
+ format: TagFormat.boolean,
10257
+ defaultValue: "true"
10258
+ }
10259
+ ]
9889
10260
  },
9890
10261
  [BitType.selfAssessment]: {
9891
10262
  since: "1.3.0",
@@ -9956,53 +10327,143 @@ var BITS = {
9956
10327
  },
9957
10328
  [BitType.collapsible]: {
9958
10329
  since: "1.21.0",
10330
+ deprecated: "5.37.0",
9959
10331
  baseBitType: BitType.article,
9960
- description: "Collapsible bit, used to create collapsible sections in articles or books"
10332
+ description: "Collapsible bit, used to create collapsible sections in articles or books",
10333
+ tags: [
10334
+ {
10335
+ key: ConfigKey.property_isCollapsible,
10336
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10337
+ format: TagFormat.boolean,
10338
+ defaultValue: "true"
10339
+ }
10340
+ ]
9961
10341
  },
9962
10342
  [BitType.sideNoteCollapsible]: {
9963
10343
  since: "1.21.0",
9964
- baseBitType: BitType.article,
9965
- description: "Side note collapsible bit, used to create collapsible side notes in articles or books"
10344
+ deprecated: "5.37.0",
10345
+ baseBitType: BitType.sideNote,
10346
+ description: "Side note collapsible bit, used to create collapsible side notes in articles or books",
10347
+ tags: [
10348
+ {
10349
+ key: ConfigKey.property_isCollapsible,
10350
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10351
+ format: TagFormat.boolean,
10352
+ defaultValue: "true"
10353
+ }
10354
+ ]
9966
10355
  },
9967
10356
  [BitType.infoCollapsible]: {
9968
10357
  since: "1.21.0",
9969
- baseBitType: BitType.article,
9970
- description: "Info collapsible bit, used to create collapsible informational sections in articles or books"
10358
+ deprecated: "5.37.0",
10359
+ baseBitType: BitType.info,
10360
+ description: "Info collapsible bit, used to create collapsible informational sections in articles or books",
10361
+ tags: [
10362
+ {
10363
+ key: ConfigKey.property_isCollapsible,
10364
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10365
+ format: TagFormat.boolean,
10366
+ defaultValue: "true"
10367
+ }
10368
+ ]
9971
10369
  },
9972
10370
  [BitType.remarkCollapsible]: {
9973
10371
  since: "1.21.0",
9974
- baseBitType: BitType.article,
9975
- description: "Remark collapsible bit, used to create collapsible remarks in articles or books"
10372
+ deprecated: "5.37.0",
10373
+ baseBitType: BitType.remark,
10374
+ description: "Remark collapsible bit, used to create collapsible remarks in articles or books",
10375
+ tags: [
10376
+ {
10377
+ key: ConfigKey.property_isCollapsible,
10378
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10379
+ format: TagFormat.boolean,
10380
+ defaultValue: "true"
10381
+ }
10382
+ ]
9976
10383
  },
9977
10384
  [BitType.warningCollapsible]: {
9978
10385
  since: "1.21.0",
9979
- baseBitType: BitType.article,
9980
- description: "Warning collapsible bit, used to create collapsible warnings in articles or books"
10386
+ deprecated: "5.37.0",
10387
+ baseBitType: BitType.warning,
10388
+ description: "Warning collapsible bit, used to create collapsible warnings in articles or books",
10389
+ tags: [
10390
+ {
10391
+ key: ConfigKey.property_isCollapsible,
10392
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10393
+ format: TagFormat.boolean,
10394
+ defaultValue: "true"
10395
+ }
10396
+ ]
9981
10397
  },
9982
10398
  [BitType.dangerCollapsible]: {
9983
10399
  since: "1.21.0",
9984
- baseBitType: BitType.article,
9985
- description: "Danger collapsible bit, used to create collapsible danger sections in articles or books"
10400
+ deprecated: "5.37.0",
10401
+ baseBitType: BitType.danger,
10402
+ description: "Danger collapsible bit, used to create collapsible danger sections in articles or books",
10403
+ tags: [
10404
+ {
10405
+ key: ConfigKey.property_isCollapsible,
10406
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10407
+ format: TagFormat.boolean,
10408
+ defaultValue: "true"
10409
+ }
10410
+ ]
9986
10411
  },
9987
10412
  [BitType.noteCollapsible]: {
9988
10413
  since: "1.21.0",
9989
- baseBitType: BitType.article,
9990
- description: "Note collapsible bit, used to create collapsible notes in articles or books"
10414
+ deprecated: "5.37.0",
10415
+ baseBitType: BitType.note,
10416
+ description: "Note collapsible bit, used to create collapsible notes in articles or books",
10417
+ tags: [
10418
+ {
10419
+ key: ConfigKey.property_isCollapsible,
10420
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10421
+ format: TagFormat.boolean,
10422
+ defaultValue: "true"
10423
+ }
10424
+ ]
9991
10425
  },
9992
10426
  [BitType.exampleCollapsible]: {
9993
10427
  since: "1.21.0",
9994
- baseBitType: BitType.article,
9995
- description: "Example collapsible bit, used to create collapsible examples in articles or books"
10428
+ deprecated: "5.37.0",
10429
+ baseBitType: BitType.example,
10430
+ description: "Example collapsible bit, used to create collapsible examples in articles or books",
10431
+ tags: [
10432
+ {
10433
+ key: ConfigKey.property_isCollapsible,
10434
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10435
+ format: TagFormat.boolean,
10436
+ defaultValue: "true"
10437
+ }
10438
+ ]
9996
10439
  },
9997
10440
  [BitType.hintCollapsible]: {
9998
10441
  since: "1.21.0",
9999
- baseBitType: BitType.article,
10000
- description: "Hint collapsible bit, used to create collapsible hints in articles or books"
10442
+ deprecated: "5.37.0",
10443
+ baseBitType: BitType.hint,
10444
+ description: "Hint collapsible bit, used to create collapsible hints in articles or books",
10445
+ tags: [
10446
+ {
10447
+ key: ConfigKey.property_isCollapsible,
10448
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10449
+ format: TagFormat.boolean,
10450
+ defaultValue: "true"
10451
+ }
10452
+ ]
10001
10453
  },
10002
10454
  [BitType.bugCollapsible]: {
10003
10455
  since: "1.21.0",
10004
- baseBitType: BitType.article,
10005
- description: "Bug collapsible bit, used to create collapsible bug reports in articles or books"
10456
+ deprecated: "5.37.0",
10457
+ baseBitType: BitType.bug,
10458
+ description: "Bug collapsible bit, used to create collapsible bug reports in articles or books",
10459
+ tags: [
10460
+ {
10461
+ key: ConfigKey.property_isCollapsible,
10462
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10463
+ format: TagFormat.boolean,
10464
+ defaultValue: "true"
10465
+ }
10466
+ ]
10006
10467
  },
10007
10468
  [BitType.platformPath]: {
10008
10469
  since: "3.14.1",
@@ -10224,8 +10685,17 @@ var BITS = {
10224
10685
  },
10225
10686
  [BitType.extractorPageCollapsible]: {
10226
10687
  since: "1.30.0",
10688
+ deprecated: "5.37.0",
10227
10689
  baseBitType: BitType.extractorPage,
10228
- description: "Collapsible extractor page bit, used to extract pages from images with collapsible functionality"
10690
+ description: "Collapsible extractor page bit, used to extract pages from images with collapsible functionality",
10691
+ tags: [
10692
+ {
10693
+ key: ConfigKey.property_isCollapsible,
10694
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10695
+ format: TagFormat.boolean,
10696
+ defaultValue: "true"
10697
+ }
10698
+ ]
10229
10699
  },
10230
10700
  [BitType.extractorPageWithBlocks]: {
10231
10701
  since: "1.5.21",
@@ -10234,8 +10704,17 @@ var BITS = {
10234
10704
  },
10235
10705
  [BitType.extractorPageWithBlocksCollapsible]: {
10236
10706
  since: "1.30.0",
10707
+ deprecated: "5.37.0",
10237
10708
  baseBitType: BitType.extractorPageWithBlocks,
10238
- description: "Collapsible extractor page with blocks bit, used to extract pages with blocks from images with collapsible functionality"
10709
+ description: "Collapsible extractor page with blocks bit, used to extract pages with blocks from images with collapsible functionality",
10710
+ tags: [
10711
+ {
10712
+ key: ConfigKey.property_isCollapsible,
10713
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10714
+ format: TagFormat.boolean,
10715
+ defaultValue: "true"
10716
+ }
10717
+ ]
10239
10718
  },
10240
10719
  [BitType.extractorConfiguration]: {
10241
10720
  since: "1.7.1",
@@ -10275,8 +10754,17 @@ var BITS = {
10275
10754
  },
10276
10755
  [BitType.extractorImageCollapsible]: {
10277
10756
  since: "4.3.0",
10757
+ deprecated: "5.37.0",
10278
10758
  baseBitType: BitType.extractorImage,
10279
- description: "Collapsible extractor images bit, used for images extracted from PDFs"
10759
+ description: "Collapsible extractor images bit, used for images extracted from PDFs",
10760
+ tags: [
10761
+ {
10762
+ key: ConfigKey.property_isCollapsible,
10763
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10764
+ format: TagFormat.boolean,
10765
+ defaultValue: "true"
10766
+ }
10767
+ ]
10280
10768
  },
10281
10769
  [BitType.extractorBlueprint]: {
10282
10770
  since: "5.12.0",
@@ -10331,7 +10819,8 @@ var BITS = {
10331
10819
  {
10332
10820
  key: ConfigKey.property_pageNo,
10333
10821
  description: "Page number for the block, used to indicate the page on which the block appears",
10334
- format: TagFormat.number
10822
+ format: TagFormat.number,
10823
+ nullable: true
10335
10824
  },
10336
10825
  {
10337
10826
  key: ConfigKey.property_x,
@@ -10348,17 +10837,20 @@ var BITS = {
10348
10837
  {
10349
10838
  key: ConfigKey.property_width,
10350
10839
  description: "Width of the block, used to define the size of the block on the page",
10351
- format: TagFormat.number
10840
+ format: TagFormat.number,
10841
+ nullable: true
10352
10842
  },
10353
10843
  {
10354
10844
  key: ConfigKey.property_height,
10355
10845
  description: "Height of the block, used to define the size of the block on the page",
10356
- format: TagFormat.number
10846
+ format: TagFormat.number,
10847
+ nullable: true
10357
10848
  },
10358
10849
  {
10359
10850
  key: ConfigKey.property_index,
10360
10851
  description: "Index of the block, used to order blocks within the extractor page",
10361
- format: TagFormat.number
10852
+ format: TagFormat.number,
10853
+ nullable: true
10362
10854
  },
10363
10855
  {
10364
10856
  key: ConfigKey.property_classification,
@@ -10409,8 +10901,17 @@ var BITS = {
10409
10901
  },
10410
10902
  [BitType.extractorPageNumberCollapsible]: {
10411
10903
  since: "1.30.0",
10904
+ deprecated: "5.37.0",
10412
10905
  baseBitType: BitType.extractorPageNumber,
10413
- description: "Collapsible extractor page number bit, used to define page numbers in extractor pages with collapsible functionality"
10906
+ description: "Collapsible extractor page number bit, used to define page numbers in extractor pages with collapsible functionality",
10907
+ tags: [
10908
+ {
10909
+ key: ConfigKey.property_isCollapsible,
10910
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10911
+ format: TagFormat.boolean,
10912
+ defaultValue: "true"
10913
+ }
10914
+ ]
10414
10915
  },
10415
10916
  [BitType.extractorPageHeader]: {
10416
10917
  since: "1.5.21",
@@ -10419,8 +10920,17 @@ var BITS = {
10419
10920
  },
10420
10921
  [BitType.extractorPageHeaderCollapsible]: {
10421
10922
  since: "1.30.0",
10923
+ deprecated: "5.37.0",
10422
10924
  baseBitType: BitType.extractorPageHeader,
10423
- description: "Collapsible extractor page header bit, used to define headers in extractor pages with collapsible functionality"
10925
+ description: "Collapsible extractor page header bit, used to define headers in extractor pages with collapsible functionality",
10926
+ tags: [
10927
+ {
10928
+ key: ConfigKey.property_isCollapsible,
10929
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10930
+ format: TagFormat.boolean,
10931
+ defaultValue: "true"
10932
+ }
10933
+ ]
10424
10934
  },
10425
10935
  [BitType.extractorPageFooter]: {
10426
10936
  since: "1.5.21",
@@ -10429,8 +10939,17 @@ var BITS = {
10429
10939
  },
10430
10940
  [BitType.extractorPageFooterCollapsible]: {
10431
10941
  since: "1.30.0",
10942
+ deprecated: "5.37.0",
10432
10943
  baseBitType: BitType.extractorPageFooter,
10433
- description: "Collapsible extractor page footer bit, used to define footers in extractor pages with collapsible functionality"
10944
+ description: "Collapsible extractor page footer bit, used to define footers in extractor pages with collapsible functionality",
10945
+ tags: [
10946
+ {
10947
+ key: ConfigKey.property_isCollapsible,
10948
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10949
+ format: TagFormat.boolean,
10950
+ defaultValue: "true"
10951
+ }
10952
+ ]
10434
10953
  },
10435
10954
  [BitType.pageOpenBook]: {
10436
10955
  since: "1.5.10",
@@ -10668,7 +11187,20 @@ var BITS = {
10668
11187
  [BitType.smartStandardLegendNormative]: {
10669
11188
  since: "3.12.0",
10670
11189
  baseBitType: BitType.legend,
10671
- description: "Smart standard normative legend bit, used to provide normative smart standard legends in articles or books"
11190
+ description: "Smart standard normative legend bit, used to provide normative smart standard legends in articles or books",
11191
+ // PLAN-141 F2 (NISO import): a free-standing <legend> (a formula's) or
11192
+ // bare <def-list> (a table footer's — no <legend> wrapper there) that is
11193
+ // NOT the claimed card content of its enclosing bit is a legend bit:
11194
+ // STRUCTURAL-shaped, its <title> and <def-item>s build the
11195
+ // definition-list cards via the card set's authored keys. A <legend>
11196
+ // inside a figure/table bit stays that bit's claimed card content and
11197
+ // never reaches this key. Anchor = the source id (D2 revised).
11198
+ mappingKeys: {
11199
+ "xml-niso-iec": [
11200
+ { "@el": "legend", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" },
11201
+ { "@el": "def-list", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
11202
+ ]
11203
+ }
10672
11204
  },
10673
11205
  [BitType.smartStandardRemarkLegend]: {
10674
11206
  since: "3.12.0",
@@ -10707,8 +11239,17 @@ var BITS = {
10707
11239
  },
10708
11240
  [BitType.definitionListCollapsible]: {
10709
11241
  since: "5.25.0",
11242
+ deprecated: "5.37.0",
10710
11243
  baseBitType: BitType.definitionList,
10711
- description: "Collapsible definition list bit, used to create collapsible lists of definitions in articles or books"
11244
+ description: "Collapsible definition list bit, used to create collapsible lists of definitions in articles or books",
11245
+ tags: [
11246
+ {
11247
+ key: ConfigKey.property_isCollapsible,
11248
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11249
+ format: TagFormat.boolean,
11250
+ defaultValue: "true"
11251
+ }
11252
+ ]
10712
11253
  },
10713
11254
  [BitType.standardDefinitionListNormative]: {
10714
11255
  since: "5.24.0",
@@ -10723,7 +11264,16 @@ var BITS = {
10723
11264
  [BitType.smartStandardDefinitionListNormative]: {
10724
11265
  since: "5.24.0",
10725
11266
  baseBitType: BitType.standardDefinitionListNormative,
10726
- description: "Smart standard normative definition list bit, used to create normative smart standard definition lists in articles or books"
11267
+ description: "Smart standard normative definition list bit, used to create normative smart standard definition lists in articles or books",
11268
+ // PLAN-141 F3 (NISO import): a terms-and-definitions clause. STRUCTURAL-
11269
+ // shaped: <label> → [%], the tbx:termEntry/langSet subtree builds the
11270
+ // definition-list card via the card set's authored keys (all tig terms
11271
+ // stacked on the term side; definition/example/notes/source composed on
11272
+ // the definition side with authored locale affixes), langSet @xml:lang →
11273
+ // [@lang] (nested attr slot on the tag key). Anchor = the source id.
11274
+ mappingKeys: {
11275
+ "xml-niso-iec": { "@el": "term-sec", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
11276
+ }
10727
11277
  },
10728
11278
  [BitType.smartStandardDefinitionListNonNormative]: {
10729
11279
  since: "5.24.0",
@@ -10792,12 +11342,14 @@ var BITS = {
10792
11342
  {
10793
11343
  key: ConfigKey.property_focusX,
10794
11344
  description: "X-coordinate for the focus point, used to define the focus area in the image",
10795
- format: TagFormat.number
11345
+ format: TagFormat.number,
11346
+ nullable: true
10796
11347
  },
10797
11348
  {
10798
11349
  key: ConfigKey.property_focusY,
10799
11350
  description: "Y-coordinate for the focus point, used to define the focus area in the image",
10800
- format: TagFormat.number
11351
+ format: TagFormat.number,
11352
+ nullable: true
10801
11353
  }
10802
11354
  ]
10803
11355
  },
@@ -10904,7 +11456,15 @@ var BITS = {
10904
11456
  [BitType.smartStandardImageFigureNormative]: {
10905
11457
  since: "1.28.0",
10906
11458
  baseBitType: BitType.standardImageFigureNormative,
10907
- description: "Smart standard normative image figure bit, used to create smart standard normative image figures in articles or books"
11459
+ description: "Smart standard normative image figure bit, used to create smart standard normative image figures in articles or books",
11460
+ // PLAN-141 F1 (NISO import): a figure is STRUCTURAL-shaped (no
11461
+ // @children — no body): <label> → [%], <caption>/<graphic> ride the
11462
+ // [&image] resource chain, the <legend> def-list becomes the bit's
11463
+ // definition-list cards, and an inner note PROMOTES as a sibling bit.
11464
+ // Anchor = the source id (D2 revised).
11465
+ mappingKeys: {
11466
+ "xml-niso-iec": { "@el": "fig", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
11467
+ }
10908
11468
  },
10909
11469
  [BitType.smartStandardImageFigureNonNormative]: {
10910
11470
  since: "1.28.0",
@@ -10913,13 +11473,31 @@ var BITS = {
10913
11473
  },
10914
11474
  [BitType.smartStandardImageFigureNormativeCollapsible]: {
10915
11475
  since: "1.28.0",
11476
+ deprecated: "5.37.0",
10916
11477
  baseBitType: BitType.smartStandardImageFigureNormative,
10917
- description: "Collapsible smart standard normative image figure bit, used to create collapsible smart standard normative image figures in articles or books"
11478
+ description: "Collapsible smart standard normative image figure bit, used to create collapsible smart standard normative image figures in articles or books",
11479
+ tags: [
11480
+ {
11481
+ key: ConfigKey.property_isCollapsible,
11482
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11483
+ format: TagFormat.boolean,
11484
+ defaultValue: "true"
11485
+ }
11486
+ ]
10918
11487
  },
10919
11488
  [BitType.smartStandardImageFigureNonNormativeCollapsible]: {
10920
11489
  since: "1.28.0",
11490
+ deprecated: "5.37.0",
10921
11491
  baseBitType: BitType.smartStandardImageFigureNonNormative,
10922
- description: "Collapsible smart standard non-normative image figure bit, used to create collapsible smart standard non-normative image figures in articles or books"
11492
+ description: "Collapsible smart standard non-normative image figure bit, used to create collapsible smart standard non-normative image figures in articles or books",
11493
+ tags: [
11494
+ {
11495
+ key: ConfigKey.property_isCollapsible,
11496
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11497
+ format: TagFormat.boolean,
11498
+ defaultValue: "true"
11499
+ }
11500
+ ]
10923
11501
  },
10924
11502
  [BitType.imageLandscape]: {
10925
11503
  since: "1.3.0",
@@ -11131,43 +11709,115 @@ var BITS = {
11131
11709
  },
11132
11710
  [BitType.smartStandardTableImageNormativeCollapsible]: {
11133
11711
  since: "1.28.0",
11712
+ deprecated: "5.37.0",
11134
11713
  baseBitType: BitType.smartStandardTableImageNormative,
11135
- description: "Collapsible smart standard normative table image bit, used to create collapsible smart standard normative images in tables in articles or books"
11714
+ description: "Collapsible smart standard normative table image bit, used to create collapsible smart standard normative images in tables in articles or books",
11715
+ tags: [
11716
+ {
11717
+ key: ConfigKey.property_isCollapsible,
11718
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11719
+ format: TagFormat.boolean,
11720
+ defaultValue: "true"
11721
+ }
11722
+ ]
11136
11723
  },
11137
11724
  [BitType.smartStandardTableImageNonNormativeCollapsible]: {
11138
11725
  since: "1.28.0",
11726
+ deprecated: "5.37.0",
11139
11727
  baseBitType: BitType.smartStandardTableImageNonNormative,
11140
- description: "Collapsible smart standard non-normative table image bit, used to create collapsible smart standard non-normative images in tables in articles or books"
11728
+ description: "Collapsible smart standard non-normative table image bit, used to create collapsible smart standard non-normative images in tables in articles or books",
11729
+ tags: [
11730
+ {
11731
+ key: ConfigKey.property_isCollapsible,
11732
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11733
+ format: TagFormat.boolean,
11734
+ defaultValue: "true"
11735
+ }
11736
+ ]
11141
11737
  },
11142
11738
  [BitType.smartStandardRemarkTableImageNormativeCollapsible]: {
11143
11739
  since: "1.28.0",
11740
+ deprecated: "5.37.0",
11144
11741
  baseBitType: BitType.smartStandardRemarkTableImageNormative,
11145
- description: "Collapsible smart standard normative remark table image bit, used to create collapsible smart standard normative remark images in tables in articles or books"
11742
+ description: "Collapsible smart standard normative remark table image bit, used to create collapsible smart standard normative remark images in tables in articles or books",
11743
+ tags: [
11744
+ {
11745
+ key: ConfigKey.property_isCollapsible,
11746
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11747
+ format: TagFormat.boolean,
11748
+ defaultValue: "true"
11749
+ }
11750
+ ]
11146
11751
  },
11147
11752
  [BitType.smartStandardRemarkTableImageNonNormativeCollapsible]: {
11148
11753
  since: "1.28.0",
11754
+ deprecated: "5.37.0",
11149
11755
  baseBitType: BitType.smartStandardRemarkTableImageNonNormative,
11150
- description: "Collapsible smart standard non-normative remark table image bit, used to create collapsible smart standard non-normative remark images in tables in articles or books"
11756
+ description: "Collapsible smart standard non-normative remark table image bit, used to create collapsible smart standard non-normative remark images in tables in articles or books",
11757
+ tags: [
11758
+ {
11759
+ key: ConfigKey.property_isCollapsible,
11760
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11761
+ format: TagFormat.boolean,
11762
+ defaultValue: "true"
11763
+ }
11764
+ ]
11151
11765
  },
11152
11766
  [BitType.smartStandardTableExtendedImageNormativeCollapsible]: {
11153
11767
  since: "1.28.0",
11768
+ deprecated: "5.37.0",
11154
11769
  baseBitType: BitType.smartStandardTableExtendedImageNormative,
11155
- description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
11770
+ description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books",
11771
+ tags: [
11772
+ {
11773
+ key: ConfigKey.property_isCollapsible,
11774
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11775
+ format: TagFormat.boolean,
11776
+ defaultValue: "true"
11777
+ }
11778
+ ]
11156
11779
  },
11157
11780
  [BitType.smartStandardTableExtendedImageNonNormativeCollapsible]: {
11158
11781
  since: "1.28.0",
11782
+ deprecated: "5.37.0",
11159
11783
  baseBitType: BitType.smartStandardTableExtendedImageNonNormative,
11160
- description: "Collapsible smart standard non-normative extended table image bit, used to create collapsible smart standard non-normative extended images in tables in articles or books"
11784
+ description: "Collapsible smart standard non-normative extended table image bit, used to create collapsible smart standard non-normative extended images in tables in articles or books",
11785
+ tags: [
11786
+ {
11787
+ key: ConfigKey.property_isCollapsible,
11788
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11789
+ format: TagFormat.boolean,
11790
+ defaultValue: "true"
11791
+ }
11792
+ ]
11161
11793
  },
11162
11794
  [BitType.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
11163
11795
  since: "1.28.0",
11796
+ deprecated: "5.37.0",
11164
11797
  baseBitType: BitType.smartStandardRemarkTableExtendedImageNormative,
11165
- description: "Collapsible smart standard normative remark extended table image bit, used to create collapsible smart standard normative remark extended images in tables in articles or books"
11798
+ description: "Collapsible smart standard normative remark extended table image bit, used to create collapsible smart standard normative remark extended images in tables in articles or books",
11799
+ tags: [
11800
+ {
11801
+ key: ConfigKey.property_isCollapsible,
11802
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11803
+ format: TagFormat.boolean,
11804
+ defaultValue: "true"
11805
+ }
11806
+ ]
11166
11807
  },
11167
11808
  [BitType.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
11168
11809
  since: "1.28.0",
11810
+ deprecated: "5.37.0",
11169
11811
  baseBitType: BitType.smartStandardRemarkTableExtendedImageNonNormative,
11170
- description: "Collapsible smart standard non-normative remark extended table image bit, used to create collapsible smart standard non-normative remark extended images in tables in articles or books"
11812
+ description: "Collapsible smart standard non-normative remark extended table image bit, used to create collapsible smart standard non-normative remark extended images in tables in articles or books",
11813
+ tags: [
11814
+ {
11815
+ key: ConfigKey.property_isCollapsible,
11816
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11817
+ format: TagFormat.boolean,
11818
+ defaultValue: "true"
11819
+ }
11820
+ ]
11171
11821
  },
11172
11822
  [BitType.imageLink]: {
11173
11823
  since: "1.3.0",
@@ -11632,12 +12282,33 @@ var BITS = {
11632
12282
  [BitType.smartStandardListItem]: {
11633
12283
  since: "1.28.0",
11634
12284
  baseBitType: BitType.standardListItem,
11635
- description: "Smart standard list item bit, used to create smart standard list items in articles or books"
12285
+ description: "Smart standard list item bit, used to create smart standard list items in articles or books",
12286
+ // PLAN-140 refs family (NISO import): one list-item bit per <ref> —
12287
+ // CONTENT key (its citation subtree is the body), counter anchor scoped
12288
+ // to the containing list, <label> → [%], nested <std-id> → [@externalId]
12289
+ // (the externalId tag key's nested content slot).
12290
+ mappingKeys: {
12291
+ "xml-niso-iec": {
12292
+ "@el": "ref",
12293
+ "@attr": { id: "$customerId" },
12294
+ "@children": "$",
12295
+ "\u25BC": "$anchor"
12296
+ }
12297
+ }
11636
12298
  },
11637
12299
  [BitType.smartStandardListItemCollapsible]: {
11638
12300
  since: "1.28.0",
12301
+ deprecated: "5.37.0",
11639
12302
  baseBitType: BitType.smartStandardListItem,
11640
- description: "Collapsible smart standard list item bit, used to create collapsible smart standard list items in articles or books"
12303
+ description: "Collapsible smart standard list item bit, used to create collapsible smart standard list items in articles or books",
12304
+ tags: [
12305
+ {
12306
+ key: ConfigKey.property_isCollapsible,
12307
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
12308
+ format: TagFormat.boolean,
12309
+ defaultValue: "true"
12310
+ }
12311
+ ]
11641
12312
  },
11642
12313
  [BitType.mark]: {
11643
12314
  since: "1.3.0",
@@ -11970,8 +12641,17 @@ var BITS = {
11970
12641
  },
11971
12642
  [BitType.pageCollapsible]: {
11972
12643
  since: "1.30.0",
12644
+ deprecated: "5.37.0",
11973
12645
  baseBitType: BitType.page,
11974
- description: "Collapsible page bit, used to create collapsible sections in pages"
12646
+ description: "Collapsible page bit, used to create collapsible sections in pages",
12647
+ tags: [
12648
+ {
12649
+ key: ConfigKey.property_isCollapsible,
12650
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
12651
+ format: TagFormat.boolean,
12652
+ defaultValue: "true"
12653
+ }
12654
+ ]
11975
12655
  },
11976
12656
  [BitType.pageCoverImage]: {
11977
12657
  since: "1.22.0",
@@ -12739,7 +13419,13 @@ var BITS = {
12739
13419
  // `<caption>` — placed inside the idiomatic `<table>` container as
12740
13420
  // its first child. Outside a table context it falls back to the
12741
13421
  // residual carrier.
12742
- htmlKey: { "@el": "caption", "@children": "$" }
13422
+ htmlKey: { "@el": "caption", "@children": "$" },
13423
+ // PLAN-141 F2 (NISO import): a table-wrap's <caption><title> — the
13424
+ // nested content slot reads the title text (catalog D5: the caption
13425
+ // is a TOP-LEVEL bit property on table bits).
13426
+ mappingKeys: {
13427
+ "xml-niso-iec": { "@el": "caption", "@children": { "@el": "title", "@text": "$" } }
13428
+ }
12743
13429
  },
12744
13430
  {
12745
13431
  key: ConfigKey.property_tableFixedHeader,
@@ -12912,7 +13598,16 @@ var BITS = {
12912
13598
  [BitType.smartStandardTableExtendedNormative]: {
12913
13599
  since: "1.28.0",
12914
13600
  baseBitType: BitType.standardTableExtendedNormative,
12915
- description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
13601
+ description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books",
13602
+ // PLAN-141 F2 (NISO import): a table-wrap is STRUCTURAL-shaped (no
13603
+ // @children — no body): <label> → [%], <caption><title> → the bit-level
13604
+ // [@caption] (D5), the inner <table>/<table-wrap-foot> build the
13605
+ // table-extended card grid via the card set's authored keys, and a
13606
+ // footer <def-list> PROMOTES as a sibling legend bit. Anchor = the
13607
+ // source id (D2 revised).
13608
+ mappingKeys: {
13609
+ "xml-niso-iec": { "@el": "table-wrap", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
13610
+ }
12916
13611
  },
12917
13612
  [BitType.smartStandardTableExtendedNonNormative]: {
12918
13613
  since: "1.28.0",
@@ -12931,43 +13626,115 @@ var BITS = {
12931
13626
  },
12932
13627
  [BitType.smartStandardTableNormativeCollapsible]: {
12933
13628
  since: "1.28.0",
13629
+ deprecated: "5.37.0",
12934
13630
  baseBitType: BitType.smartStandardTableNormative,
12935
- description: "Collapsible smart standard normative table bit, used to create collapsible smart standard normative tables in articles or books"
13631
+ description: "Collapsible smart standard normative table bit, used to create collapsible smart standard normative tables in articles or books",
13632
+ tags: [
13633
+ {
13634
+ key: ConfigKey.property_isCollapsible,
13635
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13636
+ format: TagFormat.boolean,
13637
+ defaultValue: "true"
13638
+ }
13639
+ ]
12936
13640
  },
12937
13641
  [BitType.smartStandardTableNonNormativeCollapsible]: {
12938
13642
  since: "1.28.0",
13643
+ deprecated: "5.37.0",
12939
13644
  baseBitType: BitType.smartStandardTableNonNormative,
12940
- description: "Collapsible smart standard non-normative table bit, used to create collapsible smart standard non-normative tables in articles or books"
13645
+ description: "Collapsible smart standard non-normative table bit, used to create collapsible smart standard non-normative tables in articles or books",
13646
+ tags: [
13647
+ {
13648
+ key: ConfigKey.property_isCollapsible,
13649
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13650
+ format: TagFormat.boolean,
13651
+ defaultValue: "true"
13652
+ }
13653
+ ]
12941
13654
  },
12942
13655
  [BitType.smartStandardRemarkTableNormativeCollapsible]: {
12943
13656
  since: "1.28.0",
13657
+ deprecated: "5.37.0",
12944
13658
  baseBitType: BitType.smartStandardRemarkTableNormative,
12945
- description: "Collapsible smart standard normative remark table bit, used to create collapsible smart standard normative remark tables in articles or books"
13659
+ description: "Collapsible smart standard normative remark table bit, used to create collapsible smart standard normative remark tables in articles or books",
13660
+ tags: [
13661
+ {
13662
+ key: ConfigKey.property_isCollapsible,
13663
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13664
+ format: TagFormat.boolean,
13665
+ defaultValue: "true"
13666
+ }
13667
+ ]
12946
13668
  },
12947
13669
  [BitType.smartStandardRemarkTableNonNormativeCollapsible]: {
12948
13670
  since: "1.28.0",
13671
+ deprecated: "5.37.0",
12949
13672
  baseBitType: BitType.smartStandardRemarkTableNonNormative,
12950
- description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
13673
+ description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books",
13674
+ tags: [
13675
+ {
13676
+ key: ConfigKey.property_isCollapsible,
13677
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13678
+ format: TagFormat.boolean,
13679
+ defaultValue: "true"
13680
+ }
13681
+ ]
12951
13682
  },
12952
13683
  [BitType.smartStandardTableExtendedNormativeCollapsible]: {
12953
13684
  since: "1.28.0",
13685
+ deprecated: "5.37.0",
12954
13686
  baseBitType: BitType.smartStandardTableExtendedNormative,
12955
- description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
13687
+ description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books",
13688
+ tags: [
13689
+ {
13690
+ key: ConfigKey.property_isCollapsible,
13691
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13692
+ format: TagFormat.boolean,
13693
+ defaultValue: "true"
13694
+ }
13695
+ ]
12956
13696
  },
12957
13697
  [BitType.smartStandardTableExtendedNonNormativeCollapsible]: {
12958
13698
  since: "1.28.0",
13699
+ deprecated: "5.37.0",
12959
13700
  baseBitType: BitType.smartStandardTableExtendedNonNormative,
12960
- description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
13701
+ description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books",
13702
+ tags: [
13703
+ {
13704
+ key: ConfigKey.property_isCollapsible,
13705
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13706
+ format: TagFormat.boolean,
13707
+ defaultValue: "true"
13708
+ }
13709
+ ]
12961
13710
  },
12962
13711
  [BitType.smartStandardRemarkTableExtendedNormativeCollapsible]: {
12963
13712
  since: "1.28.0",
13713
+ deprecated: "5.37.0",
12964
13714
  baseBitType: BitType.smartStandardRemarkTableExtendedNormative,
12965
- description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
13715
+ description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books",
13716
+ tags: [
13717
+ {
13718
+ key: ConfigKey.property_isCollapsible,
13719
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13720
+ format: TagFormat.boolean,
13721
+ defaultValue: "true"
13722
+ }
13723
+ ]
12966
13724
  },
12967
13725
  [BitType.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
12968
13726
  since: "1.28.0",
13727
+ deprecated: "5.37.0",
12969
13728
  baseBitType: BitType.smartStandardRemarkTableExtendedNonNormative,
12970
- description: "Collapsible smart standard non-normative remark extended table bit, used to create collapsible smart standard non-normative remark extended tables in articles or books"
13729
+ description: "Collapsible smart standard non-normative remark extended table bit, used to create collapsible smart standard non-normative remark extended tables in articles or books",
13730
+ tags: [
13731
+ {
13732
+ key: ConfigKey.property_isCollapsible,
13733
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13734
+ format: TagFormat.boolean,
13735
+ defaultValue: "true"
13736
+ }
13737
+ ]
12971
13738
  },
12972
13739
  [BitType.parameters]: {
12973
13740
  since: "1.18.0",
@@ -12987,7 +13754,8 @@ var BITS = {
12987
13754
  {
12988
13755
  key: ConfigKey.property_maxDisplayLevel,
12989
13756
  description: "Maximum display level for the chapter in the table of contents",
12990
- format: TagFormat.number
13757
+ format: TagFormat.number,
13758
+ nullable: true
12991
13759
  }
12992
13760
  ]
12993
13761
  },
@@ -12999,7 +13767,8 @@ var BITS = {
12999
13767
  {
13000
13768
  key: ConfigKey.property_maxTocChapterLevel,
13001
13769
  description: "Maximum chapter level for the inline table of contents",
13002
- format: TagFormat.number
13770
+ format: TagFormat.number,
13771
+ nullable: true
13003
13772
  }
13004
13773
  ]
13005
13774
  },
@@ -13422,13 +14191,15 @@ var BITS = {
13422
14191
  key: ConfigKey.property_width,
13423
14192
  // Same as image
13424
14193
  description: "Width for the embedded content, used to define the width in pixels",
13425
- format: TagFormat.number
14194
+ format: TagFormat.number,
14195
+ nullable: true
13426
14196
  },
13427
14197
  {
13428
14198
  key: ConfigKey.property_height,
13429
14199
  // Same as image
13430
14200
  description: "Height for the embedded content, used to define the height in pixels",
13431
- format: TagFormat.number
14201
+ format: TagFormat.number,
14202
+ nullable: true
13432
14203
  },
13433
14204
  {
13434
14205
  key: ConfigKey.property_vendorUrl,
@@ -13466,7 +14237,8 @@ var BITS = {
13466
14237
  {
13467
14238
  key: ConfigKey.property_jupyterExecutionCount,
13468
14239
  description: "Execution count for the Jupyter output, used to define the execution order",
13469
- format: TagFormat.number
14240
+ format: TagFormat.number,
14241
+ nullable: true
13470
14242
  }
13471
14243
  ],
13472
14244
  textFormatDefault: TextFormat.plainText
@@ -13674,11 +14446,13 @@ var BITS = {
13674
14446
  };
13675
14447
 
13676
14448
  // src/config/Config.ts
14449
+ var COLLAPSIBLE_BIT_TYPE_SUFFIX = "-collapsible";
13677
14450
  var Config = class {
13678
14451
  constructor() {
13679
14452
  __publicField(this, "bitLevelMin", 1);
13680
14453
  __publicField(this, "bitLevelMax", 7);
13681
14454
  __publicField(this, "bitCache", /* @__PURE__ */ new Map());
14455
+ __publicField(this, "migratedBitCache", /* @__PURE__ */ new Map());
13682
14456
  __publicField(this, "allResourcesCache");
13683
14457
  __publicField(this, "comboResourcesCache", /* @__PURE__ */ new Map());
13684
14458
  }
@@ -13694,6 +14468,29 @@ var Config = class {
13694
14468
  if (bitType?.startsWith("|")) bitType = bitType.substring(1);
13695
14469
  return Enum3(BitType).fromValue(bitType) ?? BitType._error;
13696
14470
  }
14471
+ /**
14472
+ * PLAN-017: Return the migration target for a deprecated `*-collapsible` bit type.
14473
+ *
14474
+ * Every `*-collapsible` bit type declares its non-collapsible cousin as its `baseBitType`, so the
14475
+ * target is read from the config rather than a hand-maintained table — a new `*-collapsible` bit
14476
+ * type is covered automatically.
14477
+ *
14478
+ * `BitType.collapsible` is the one exclusion: it has no non-collapsible cousin (its `baseBitType`
14479
+ * is `article`, which is not a migration target).
14480
+ *
14481
+ * @param bitType the bit type
14482
+ * @returns the bit type to migrate to, or undefined if the bit type does not migrate
14483
+ */
14484
+ getMigratedBitType(bitType) {
14485
+ const cached = this.migratedBitCache.get(bitType);
14486
+ if (cached !== void 0 || this.migratedBitCache.has(bitType)) return cached;
14487
+ let target;
14488
+ if (bitType !== BitType.collapsible && bitType.endsWith(COLLAPSIBLE_BIT_TYPE_SUFFIX)) {
14489
+ target = BITS[bitType]?.baseBitType;
14490
+ }
14491
+ this.migratedBitCache.set(bitType, target);
14492
+ return target;
14493
+ }
13697
14494
  /**
13698
14495
  * Check if a bit type is and instance of the given root bit type.
13699
14496
  *
@@ -14016,7 +14813,7 @@ var instance2 = new Config();
14016
14813
  // src/generated/package_info.ts
14017
14814
  var PACKAGE_INFO = {
14018
14815
  "name": "@gmb/bitmark-parser-generator",
14019
- "version": "5.35.0",
14816
+ "version": "5.37.0",
14020
14817
  "author": "Get More Brain Ltd",
14021
14818
  "license": "ISC",
14022
14819
  "description": "A bitmark parser and generator using Peggy.js"
@@ -14545,6 +15342,8 @@ var NodeType = {
14545
15342
  definition: "definition",
14546
15343
  definitions: "definitions",
14547
15344
  definitionsValue: "definitionsValue",
15345
+ displayName: "displayName",
15346
+ displayNameValue: "displayNameValue",
14548
15347
  diffContext: "diffContext",
14549
15348
  diffContextValue: "diffContextValue",
14550
15349
  diffOp: "diffOp",
@@ -15073,6 +15872,8 @@ var NodeType = {
15073
15872
  type: "type",
15074
15873
  unit: "unit",
15075
15874
  unitAbbr: "unitAbbr",
15875
+ unitAbbrPlural: "unitAbbrPlural",
15876
+ unitPlural: "unitPlural",
15076
15877
  url: "url",
15077
15878
  validationDate: "validationDate",
15078
15879
  validationDateValue: "validationDateValue",
@@ -28248,8 +29049,14 @@ var Builder = class extends BaseBuilder {
28248
29049
  */
28249
29050
  buildBit(data, options) {
28250
29051
  data = structuredClone(data);
29052
+ const migratedBitType = instance2.getMigratedBitType(data.bitType);
29053
+ if (migratedBitType) {
29054
+ data.bitType = migratedBitType;
29055
+ data.isCollapsible = data.isCollapsible ?? true;
29056
+ }
28251
29057
  const bitType = data.bitType;
28252
29058
  const bitConfig = instance2.getBitConfig(bitType);
29059
+ const isCollapsibleDefaultsTrue = bitConfig.tags[ConfigKey.property_isCollapsible]?.defaultValue === "true";
28253
29060
  const deprecatedTextFormat = Enum7(DeprecatedTextFormat).fromValue(data.textFormat);
28254
29061
  let textFormat = Enum7(TextFormat).fromValue(data.textFormat) ?? bitConfig.textFormatDefault;
28255
29062
  if (deprecatedTextFormat === DeprecatedTextFormat.bitmarkMinusMinus) {
@@ -28467,6 +29274,12 @@ var Builder = class extends BaseBuilder {
28467
29274
  data.publisherName,
28468
29275
  options
28469
29276
  ),
29277
+ displayName: this.toAstProperty(
29278
+ bitType,
29279
+ ConfigKey.property_displayName,
29280
+ data.displayName,
29281
+ options
29282
+ ),
28470
29283
  theme: this.toAstProperty(bitType, ConfigKey.property_theme, data.theme, options),
28471
29284
  rtl: this.toAstProperty(bitType, ConfigKey.property_rtl, data.rtl, options),
28472
29285
  computerLanguage: this.toAstProperty(
@@ -29376,7 +30189,7 @@ var Builder = class extends BaseBuilder {
29376
30189
  isCollapsible: this.toAstProperty(
29377
30190
  bitType,
29378
30191
  ConfigKey.property_isCollapsible,
29379
- data.isCollapsible,
30192
+ data.isCollapsible ?? (isCollapsibleDefaultsTrue ? true : void 0),
29380
30193
  options
29381
30194
  ),
29382
30195
  anchor: data.anchor,
@@ -30145,7 +30958,9 @@ var Builder = class extends BaseBuilder {
30145
30958
  ingredient: this.handleJsonText(context, TextLocation.tag, data.ingredient),
30146
30959
  quantity: data.quantity ?? 0,
30147
30960
  unit: data.unit ?? "",
30961
+ unitPlural: data.unitPlural ?? "",
30148
30962
  unitAbbr: data.unitAbbr ?? "",
30963
+ unitAbbrPlural: data.unitAbbrPlural ?? "",
30149
30964
  decimalPlaces: data.decimalPlaces ?? 1,
30150
30965
  disableCalculation: data.disableCalculation ?? false,
30151
30966
  item: this.handleJsonText(context, TextLocation.tag, data.item),
@@ -30742,11 +31557,22 @@ var Builder = class extends BaseBuilder {
30742
31557
  */
30743
31558
  buildServings(_context, data) {
30744
31559
  if (!data) return void 0;
30745
- const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = data;
31560
+ const {
31561
+ servings,
31562
+ unit,
31563
+ unitPlural,
31564
+ unitAbbr,
31565
+ unitAbbrPlural,
31566
+ decimalPlaces,
31567
+ disableCalculation,
31568
+ hint
31569
+ } = data;
30746
31570
  const node = {
30747
31571
  servings: servings ?? 0,
30748
31572
  unit: unit ?? "",
31573
+ unitPlural: unitPlural ?? "",
30749
31574
  unitAbbr: unitAbbr ?? "",
31575
+ unitAbbrPlural: unitAbbrPlural ?? "",
30750
31576
  decimalPlaces: decimalPlaces ?? 1,
30751
31577
  disableCalculation: disableCalculation ?? false,
30752
31578
  hint: hint ?? ""
@@ -31683,7 +32509,16 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31683
32509
  const nodeValue = node.value;
31684
32510
  const parent = this.getParentNode(route);
31685
32511
  if (parent?.key !== NodeType.bitsValue) return true;
31686
- const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = nodeValue;
32512
+ const {
32513
+ servings,
32514
+ unit,
32515
+ unitPlural,
32516
+ unitAbbr,
32517
+ unitAbbrPlural,
32518
+ decimalPlaces,
32519
+ disableCalculation,
32520
+ hint
32521
+ } = nodeValue;
31687
32522
  this.writeProperty("servings", servings, route, {
31688
32523
  format: TagFormat.plainText
31689
32524
  });
@@ -31693,12 +32528,24 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31693
32528
  forceChain: true
31694
32529
  });
31695
32530
  }
32531
+ if (unitPlural != null) {
32532
+ this.writeProperty("unitPlural", unitPlural, route, {
32533
+ format: TagFormat.plainText,
32534
+ forceChain: true
32535
+ });
32536
+ }
31696
32537
  if (unitAbbr != null) {
31697
32538
  this.writeProperty("unitAbbr", unitAbbr, route, {
31698
32539
  format: TagFormat.plainText,
31699
32540
  forceChain: true
31700
32541
  });
31701
32542
  }
32543
+ if (unitAbbrPlural != null) {
32544
+ this.writeProperty("unitAbbrPlural", unitAbbrPlural, route, {
32545
+ format: TagFormat.plainText,
32546
+ forceChain: true
32547
+ });
32548
+ }
31702
32549
  if (decimalPlaces != null) {
31703
32550
  this.writeProperty("decimalPlaces", decimalPlaces, route, {
31704
32551
  format: TagFormat.plainText,
@@ -32545,10 +33392,18 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
32545
33392
  this.writeProperty("unit", ingredient.unit, route, {
32546
33393
  format: TagFormat.plainText
32547
33394
  });
33395
+ if (ingredient.unitPlural != null)
33396
+ this.writeProperty("unitPlural", ingredient.unitPlural, route, {
33397
+ format: TagFormat.plainText
33398
+ });
32548
33399
  if (ingredient.unitAbbr != null)
32549
33400
  this.writeProperty("unitAbbr", ingredient.unitAbbr, route, {
32550
33401
  format: TagFormat.plainText
32551
33402
  });
33403
+ if (ingredient.unitAbbrPlural != null)
33404
+ this.writeProperty("unitAbbrPlural", ingredient.unitAbbrPlural, route, {
33405
+ format: TagFormat.plainText
33406
+ });
32552
33407
  if (ingredient.decimalPlaces != null)
32553
33408
  this.writeProperty("decimalPlaces", ingredient.decimalPlaces, route, {
32554
33409
  format: TagFormat.plainText
@@ -34327,6 +35182,25 @@ var JsonGenerator = class extends AstWalkerGenerator {
34327
35182
  }
34328
35183
  return false;
34329
35184
  }
35185
+ // bitmarkAst -> bits -> bitsValue -> isCollapsible
35186
+ /**
35187
+ * PLAN-016: `isCollapsible` is emitted only when true. `false` is the implied
35188
+ * default for every bit, so it is never written to the JSON — an absent key
35189
+ * means the bit's configured default (`true` for the deprecated
35190
+ * `*-collapsible` bit types, `false` everywhere else).
35191
+ *
35192
+ * Defining these handlers suppresses the generic property handlers that
35193
+ * `generatePropertyHandlers()` would otherwise install for this tag.
35194
+ */
35195
+ leaf_isCollapsible(node, route) {
35196
+ const parent = this.getParentNode(route);
35197
+ if (parent?.key !== NodeType.bitsValue) return false;
35198
+ if (node.value === true) this.bitJson.isCollapsible = true;
35199
+ return false;
35200
+ }
35201
+ enter_isCollapsible(node, route) {
35202
+ return this.leaf_isCollapsible(node, route);
35203
+ }
34330
35204
  // bitmarkAst -> bits -> bitsValue -> markConfig
34331
35205
  enter_markConfig(_node, _route) {
34332
35206
  return true;
@@ -35200,7 +36074,6 @@ var JsonGenerator = class extends AstWalkerGenerator {
35200
36074
  if (instance2.isOfBitType(bitType, BitType.chapter)) {
35201
36075
  if (bitJson.toc == null) bitJson.toc = true;
35202
36076
  if (bitJson.progress == null) bitJson.progress = true;
35203
- if (bitJson.isCollapsible == null) bitJson.isCollapsible = false;
35204
36077
  if (bitJson.level == null) bitJson.level = 1;
35205
36078
  if (bitJson.body == null) bitJson.body = this.bodyDefault;
35206
36079
  }
@@ -38179,7 +39052,9 @@ function parseIngredients(_context, _bitType, cardSet) {
38179
39052
  title: titleArray,
38180
39053
  __instructionString,
38181
39054
  unit,
39055
+ unitPlural,
38182
39056
  unitAbbr,
39057
+ unitAbbrPlural,
38183
39058
  decimalPlaces,
38184
39059
  disableCalculation,
38185
39060
  cardBodyStr,
@@ -38209,7 +39084,9 @@ function parseIngredients(_context, _bitType, cardSet) {
38209
39084
  ingredient: cardBodyStr,
38210
39085
  quantity,
38211
39086
  unit: unit ?? instance3.EMPTY_STRING,
39087
+ unitPlural,
38212
39088
  unitAbbr: unitAbbr ?? instance3.EMPTY_STRING,
39089
+ unitAbbrPlural,
38213
39090
  decimalPlaces: decimalPlaces ?? 1,
38214
39091
  disableCalculation,
38215
39092
  ...tags2
@@ -38880,12 +39757,22 @@ function servingsChainContentProcessor(context, _contentDepth, tagsConfig, conte
38880
39757
  if (context.DEBUG_CHAIN_CONTENT) context.debugPrint("servings content", content);
38881
39758
  const tags2 = context.bitContentProcessor(ContentDepth.Chain, tagsConfig, content.chain);
38882
39759
  if (context.DEBUG_CHAIN_TAGS) context.debugPrint("servings TAGS", tags2);
38883
- const { unit, unitAbbr, decimalPlaces, disableCalculation, __hintString } = tags2;
39760
+ const {
39761
+ unit,
39762
+ unitPlural,
39763
+ unitAbbr,
39764
+ unitAbbrPlural,
39765
+ decimalPlaces,
39766
+ disableCalculation,
39767
+ __hintString
39768
+ } = tags2;
38884
39769
  const servings = instance6.asNumber(content.value) ?? 1;
38885
39770
  const node = {
38886
39771
  servings,
38887
39772
  unit,
39773
+ unitPlural,
38888
39774
  unitAbbr,
39775
+ unitAbbrPlural,
38889
39776
  decimalPlaces: decimalPlaces ?? 1,
38890
39777
  disableCalculation,
38891
39778
  hint: __hintString
@@ -44629,7 +45516,7 @@ var ConfigBuilder = class {
44629
45516
  }
44630
45517
  const outputFolder = opts.outputDir ?? "assets/config";
44631
45518
  const outputFolderBits = path3.join(outputFolder, "bits");
44632
- const outputFolderGroups = path3.join(outputFolder, "partials");
45519
+ const outputFolderGroups = path3.join(outputFolder, "groups");
44633
45520
  const outputFolderCards = path3.join(outputFolder, "cards");
44634
45521
  fs3.ensureDirSync(outputFolderBits);
44635
45522
  fs3.ensureDirSync(outputFolderGroups);
@@ -44664,6 +45551,15 @@ var ConfigBuilder = class {
44664
45551
  }
44665
45552
  return [{ key: groupKey }];
44666
45553
  };
45554
+ const mappingKeysField = (base, json, html) => {
45555
+ const record = {};
45556
+ for (const [id, value] of Object.entries(base ?? {})) {
45557
+ if (value != null) record[id] = value;
45558
+ }
45559
+ if (json.present && json.value != null) record.json = json.value;
45560
+ if (html.present && html.value != null) record.html = html.value;
45561
+ return Object.keys(record).length > 0 ? { mappingKeys: record } : {};
45562
+ };
44667
45563
  const bareKeyForProperty = (key) => {
44668
45564
  if (key.startsWith("@") || key.startsWith("&")) return key.substring(1);
44669
45565
  return void 0;
@@ -44684,22 +45580,20 @@ var ConfigBuilder = class {
44684
45580
  if (tag.format === TagFormat.plainText) {
44685
45581
  format = "string";
44686
45582
  } else if (tag.format === TagFormat.boolean) {
44687
- format = "bool";
44688
- } else if (tag.format === TagFormat.bitmarkText) {
44689
- format = "bitmark";
45583
+ format = "boolean";
44690
45584
  } else if (tag.format === TagFormat.number) {
44691
45585
  format = "number";
44692
45586
  } else {
44693
- format = "bitmark--";
45587
+ format = "bitmark+";
44694
45588
  }
44695
45589
  } else if (tagType === BitTagConfigKeyType.property) {
44696
45590
  tagName = tag.key;
44697
45591
  if (tag.format === TagFormat.plainText) {
44698
45592
  format = "string";
44699
45593
  } else if (tag.format === TagFormat.boolean) {
44700
- format = "bool";
45594
+ format = "boolean";
44701
45595
  } else if (tag.format === TagFormat.bitmarkText) {
44702
- format = "bitmark";
45596
+ format = "bitmark+";
44703
45597
  } else if (tag.format === TagFormat.number) {
44704
45598
  format = "number";
44705
45599
  } else if (tag.format === TagFormat.coordinates) {
@@ -44731,8 +45625,11 @@ var ConfigBuilder = class {
44731
45625
  tags2.push({
44732
45626
  type: "group",
44733
45627
  key: ref.key,
44734
- ...hasExportChosen ? { jsonKey: exportJsonKeyChosen } : {},
44735
- ...hasHtmlChosen ? { htmlKey: htmlKeyChosen } : {},
45628
+ ...mappingKeysField(
45629
+ { ...ref.extraKeys ?? {}, ...tag.mappingKeys ?? {} },
45630
+ { value: exportJsonKeyChosen, present: hasExportChosen },
45631
+ { value: htmlKeyChosen, present: hasHtmlChosen }
45632
+ ),
44736
45633
  ...min != null ? { min } : {},
44737
45634
  ...max != null ? { max } : {},
44738
45635
  ...description ? { description } : {}
@@ -44749,53 +45646,48 @@ var ConfigBuilder = class {
44749
45646
  chain = chainTags;
44750
45647
  }
44751
45648
  const hasExport = Object.prototype.hasOwnProperty.call(tag, "exportJsonKey");
44752
- let exportJsonKeyField;
44753
- if (hasExport) {
44754
- exportJsonKeyField = { jsonKey: tag.exportJsonKey };
44755
- } else if (legacyIsTrivialDefault(tag)) {
44756
- exportJsonKeyField = {};
44757
- } else {
45649
+ if (!hasExport && !legacyIsTrivialDefault(tag)) {
44758
45650
  const headingPath = [...pathStack, `tags.${tag.key}`].join(" / ");
44759
45651
  exportJsonKeyErrors.push(
44760
45652
  `Missing exportJsonKey for non-default jsonKey at ${headingPath}` + (tag.jsonKey ? ` (legacy: \`${tag.jsonKey}\`)` : ` (symbol-mapped tag \`${tag.key}\`)`)
44761
45653
  );
44762
- exportJsonKeyField = {};
44763
45654
  }
44764
45655
  const hasHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
44765
- const htmlKeyField = hasHtml ? { htmlKey: tag.htmlKey } : {};
44766
45656
  const t = {
44767
45657
  type: "tag",
44768
45658
  key: tagName,
44769
- ...exportJsonKeyField,
44770
- ...htmlKeyField,
44771
- format,
44772
- default: tag.defaultValue ?? null,
45659
+ ...mappingKeysField(
45660
+ tag.mappingKeys,
45661
+ { value: tag.exportJsonKey, present: hasExport },
45662
+ { value: tag.htmlKey, present: hasHtml }
45663
+ ),
45664
+ ...format && format !== "string" ? { format } : {},
45665
+ ...tag.defaultValue != null ? { default: tag.defaultValue } : {},
44773
45666
  ...tag.nullable ? { nullable: true } : {},
44774
- min: tag.minCount == null ? 0 : tag.minCount,
44775
- max: tag.maxCount == null ? 1 : tag.maxCount,
45667
+ ...tag.minCount != null && tag.minCount !== 0 ? { min: tag.minCount } : {},
45668
+ ...tag.maxCount != null && tag.maxCount !== 1 ? { max: tag.maxCount } : {},
44776
45669
  description: tag.description ?? "",
44777
45670
  tags: chain
44778
45671
  };
44779
45672
  tags2.push(t);
44780
45673
  return tags2;
44781
45674
  };
44782
- const cardJsonKeyField = (container, legacyKey, exportKey, pathHeading) => {
45675
+ const cardMappingKeysField = (container, base, legacyKey, exportKey, htmlExportKey, pathHeading) => {
44783
45676
  const c = container;
44784
45677
  const hasExport = Object.prototype.hasOwnProperty.call(c, exportKey);
44785
- if (hasExport) return { jsonKey: c[exportKey] };
44786
- const legacy = c[legacyKey];
44787
- if (legacy == null) return {};
44788
- exportJsonKeyErrors.push(
44789
- `Missing exportJsonKey for non-default jsonKey at ${pathHeading} (legacy: \`${legacy}\`)`
44790
- );
44791
- return {};
44792
- };
44793
- const cardHtmlKeyField = (container, htmlExportKey) => {
44794
- const c = container;
44795
- if (Object.prototype.hasOwnProperty.call(c, htmlExportKey)) {
44796
- return { htmlKey: c[htmlExportKey] };
45678
+ if (!hasExport && c[legacyKey] != null) {
45679
+ exportJsonKeyErrors.push(
45680
+ `Missing exportJsonKey for non-default jsonKey at ${pathHeading} (legacy: \`${c[legacyKey]}\`)`
45681
+ );
44797
45682
  }
44798
- return {};
45683
+ return mappingKeysField(
45684
+ base,
45685
+ { value: c[exportKey], present: hasExport },
45686
+ {
45687
+ value: c[htmlExportKey],
45688
+ present: Object.prototype.hasOwnProperty.call(c, htmlExportKey)
45689
+ }
45690
+ );
44799
45691
  };
44800
45692
  const serializeCardSet = (cardSetKey) => {
44801
45693
  const variantBodyFormat = (variant) => variant.format ?? TextFormat.bitmarkText;
@@ -44826,11 +45718,17 @@ var ConfigBuilder = class {
44826
45718
  variantTags.push(...processTagEntries(variantTag, [variantPath]));
44827
45719
  }
44828
45720
  return {
44829
- ...cardJsonKeyField(variant, "jsonKey", "exportJsonKey", variantPath),
44830
- ...cardHtmlKeyField(variant, "htmlKey"),
44831
- format: variantBodyFormat(variant),
45721
+ ...cardMappingKeysField(
45722
+ variant,
45723
+ void 0,
45724
+ "jsonKey",
45725
+ "exportJsonKey",
45726
+ "htmlKey",
45727
+ variantPath
45728
+ ),
45729
+ bodyFormat: variantBodyFormat(variant),
44832
45730
  tags: variantTags,
44833
- repeatCount: variant.repeatCount ?? 1,
45731
+ ...variant.repeatCount != null && variant.repeatCount !== 1 ? { repeatCount: variant.repeatCount } : {},
44834
45732
  ...variant.bodyRequired ? { bodyRequired: true } : {},
44835
45733
  ...variant.bodyAllowed === false ? { bodyForbidden: true } : {}
44836
45734
  };
@@ -44838,8 +45736,14 @@ var ConfigBuilder = class {
44838
45736
  return {
44839
45737
  name: side.name,
44840
45738
  ...side.repeat ? { repeat: side.repeat } : {},
44841
- ...cardJsonKeyField(side, "jsonKey", "exportJsonKey", sidePath),
44842
- ...cardHtmlKeyField(side, "htmlKey"),
45739
+ ...cardMappingKeysField(
45740
+ side,
45741
+ side.mappingKeys,
45742
+ "jsonKey",
45743
+ "exportJsonKey",
45744
+ "htmlKey",
45745
+ sidePath
45746
+ ),
44843
45747
  variants
44844
45748
  };
44845
45749
  });
@@ -44850,20 +45754,40 @@ var ConfigBuilder = class {
44850
45754
  const hasSideHtml = Object.prototype.hasOwnProperty.call(section, "sideHtmlKey");
44851
45755
  let cardSides = sides;
44852
45756
  if (hasSideExport || section.sideJsonKey != null || hasSideHtml) {
44853
- const sideOverride = cardJsonKeyField(
44854
- section,
44855
- "sideJsonKey",
44856
- "sideExportJsonKey",
44857
- `${sectionPath} / sides.*`
44858
- );
44859
- const sideHtmlOverride = cardHtmlKeyField(section, "sideHtmlKey");
44860
- cardSides = sides.map((s) => ({ ...s, ...sideOverride, ...sideHtmlOverride }));
45757
+ if (!hasSideExport && section.sideJsonKey != null) {
45758
+ exportJsonKeyErrors.push(
45759
+ `Missing exportJsonKey for non-default jsonKey at ${sectionPath} / sides.* (legacy: \`${section.sideJsonKey}\`)`
45760
+ );
45761
+ }
45762
+ cardSides = sides.map((s) => {
45763
+ const record = { ...s.mappingKeys ?? {} };
45764
+ if (hasSideExport) {
45765
+ if (section.sideExportJsonKey != null) record.json = section.sideExportJsonKey;
45766
+ else delete record.json;
45767
+ }
45768
+ if (hasSideHtml) {
45769
+ if (section.sideHtmlKey != null) record.html = section.sideHtmlKey;
45770
+ else delete record.html;
45771
+ }
45772
+ return {
45773
+ name: s.name,
45774
+ ...s.repeat ? { repeat: s.repeat } : {},
45775
+ ...Object.keys(record).length > 0 ? { mappingKeys: record } : {},
45776
+ variants: s.variants
45777
+ };
45778
+ });
44861
45779
  }
44862
45780
  return {
44863
45781
  name: sectionName,
44864
45782
  ...section.isDefault ? { isDefault: true } : {},
44865
- ...cardJsonKeyField(section, "jsonKey", "exportJsonKey", sectionPath),
44866
- ...cardHtmlKeyField(section, "htmlKey"),
45783
+ ...cardMappingKeysField(
45784
+ section,
45785
+ section.mappingKeys,
45786
+ "jsonKey",
45787
+ "exportJsonKey",
45788
+ "htmlKey",
45789
+ sectionPath
45790
+ ),
44867
45791
  // PLAN-085: per-section cardinality. Emit only when non-default
44868
45792
  // (treat `0` / undefined as "unbounded — omit").
44869
45793
  ...section.minCount != null && section.minCount !== 0 ? { min: section.minCount } : {},
@@ -44871,7 +45795,18 @@ var ConfigBuilder = class {
44871
45795
  sides: cardSides
44872
45796
  };
44873
45797
  });
44874
- return { name: normalizedKey, ...cardHtmlKeyField(cardSetConfig, "htmlKey"), cards };
45798
+ return {
45799
+ name: normalizedKey,
45800
+ ...mappingKeysField(
45801
+ void 0,
45802
+ { present: false },
45803
+ {
45804
+ value: cardSetConfig.htmlKey,
45805
+ present: Object.prototype.hasOwnProperty.call(cardSetConfig, "htmlKey")
45806
+ }
45807
+ ),
45808
+ cards
45809
+ };
44875
45810
  }
44876
45811
  const cardSetPath = `cardSets.${normalizedKey} / cards.default`;
44877
45812
  return {
@@ -44880,8 +45815,14 @@ var ConfigBuilder = class {
44880
45815
  {
44881
45816
  name: "default",
44882
45817
  isDefault: true,
44883
- ...cardJsonKeyField(cardSetConfig, "jsonKey", "exportJsonKey", cardSetPath),
44884
- ...cardHtmlKeyField(cardSetConfig, "htmlKey"),
45818
+ ...cardMappingKeysField(
45819
+ cardSetConfig,
45820
+ cardSetConfig.mappingKeys,
45821
+ "jsonKey",
45822
+ "exportJsonKey",
45823
+ "htmlKey",
45824
+ cardSetPath
45825
+ ),
44885
45826
  sides
44886
45827
  }
44887
45828
  ]
@@ -44917,14 +45858,19 @@ var ConfigBuilder = class {
44917
45858
  ...t.max != null ? { max: t.max } : {},
44918
45859
  ...t.description ? { description: t.description } : {}
44919
45860
  };
44920
- if (Object.prototype.hasOwnProperty.call(t, "jsonKey")) {
44921
- ref.exportJsonKey = t.jsonKey;
45861
+ const record = t.mappingKeys ?? {};
45862
+ if (Object.prototype.hasOwnProperty.call(record, "json")) {
45863
+ ref.exportJsonKey = record.json;
44922
45864
  ref.hasExportJsonKey = true;
44923
45865
  }
44924
- if (Object.prototype.hasOwnProperty.call(t, "htmlKey")) {
44925
- ref.htmlKey = t.htmlKey;
45866
+ if (Object.prototype.hasOwnProperty.call(record, "html")) {
45867
+ ref.htmlKey = record.html;
44926
45868
  ref.hasHtmlKey = true;
44927
45869
  }
45870
+ const extras = Object.fromEntries(
45871
+ Object.entries(record).filter(([id]) => id !== "json" && id !== "html")
45872
+ );
45873
+ if (Object.keys(extras).length > 0) ref.extraKeys = extras;
44928
45874
  replacements.push(ref);
44929
45875
  }
44930
45876
  squashedGroups.set(groupKey, replacements);
@@ -44958,8 +45904,11 @@ var ConfigBuilder = class {
44958
45904
  pushOrReplace({
44959
45905
  type: "group",
44960
45906
  key: ref.key,
44961
- ...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
44962
- ...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
45907
+ ...mappingKeysField(
45908
+ ref.extraKeys,
45909
+ { value: ref.exportJsonKey, present: !!ref.hasExportJsonKey },
45910
+ { value: ref.htmlKey, present: !!ref.hasHtmlKey }
45911
+ ),
44963
45912
  ...ref.min != null ? { min: ref.min } : {},
44964
45913
  ...ref.max != null ? { max: ref.max } : {},
44965
45914
  ...ref.description ? { description: ref.description } : {}
@@ -44972,8 +45921,11 @@ var ConfigBuilder = class {
44972
45921
  pushOrReplace({
44973
45922
  type: "group",
44974
45923
  key: ref.key,
44975
- ...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
44976
- ...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
45924
+ ...mappingKeysField(
45925
+ ref.extraKeys,
45926
+ { value: ref.exportJsonKey, present: !!ref.hasExportJsonKey },
45927
+ { value: ref.htmlKey, present: !!ref.hasHtmlKey }
45928
+ ),
44977
45929
  ...ref.min != null ? { min: ref.min } : {},
44978
45930
  ...ref.max != null ? { max: ref.max } : {},
44979
45931
  ...ref.description ? { description: ref.description } : {}
@@ -45000,20 +45952,17 @@ var ConfigBuilder = class {
45000
45952
  description: b.description ?? "",
45001
45953
  since: resolvedBitConfig.since,
45002
45954
  deprecated: resolvedBitConfig.deprecated,
45003
- history: [
45004
- {
45005
- version: resolvedBitConfig.since,
45006
- changes: ["Initial version"]
45007
- }
45008
- ],
45009
- format: resolvedBitConfig.textFormatDefault ?? "bitmark--",
45010
- bodyRequired: resolvedBitConfig.bodyRequired ?? false,
45011
- bodyForbidden: !(resolvedBitConfig.bodyAllowed ?? true),
45012
- footerRequired: resolvedBitConfig.footerRequired ?? false,
45013
- footerForbidden: !(resolvedBitConfig.footerAllowed ?? true),
45014
- resourceAttachmentAllowed: resolvedBitConfig.resourceAttachmentAllowed ?? true,
45955
+ bodyFormat: resolvedBitConfig.textFormatDefault ?? "bitmark--",
45956
+ ...resolvedBitConfig.bodyRequired ? { bodyRequired: true } : {},
45957
+ ...resolvedBitConfig.bodyAllowed === false ? { bodyForbidden: true } : {},
45958
+ ...resolvedBitConfig.footerRequired ? { footerRequired: true } : {},
45959
+ ...resolvedBitConfig.footerAllowed === false ? { footerForbidden: true } : {},
45960
+ ...resolvedBitConfig.resourceAttachmentAllowed === false ? { resourceAttachmentAllowed: false } : {},
45961
+ // Bit-level named key mappings (element keys for markup import),
45962
+ // carried verbatim from the raw config.
45963
+ ...mappingKeysField(b.mappingKeys, { present: false }, { present: false }),
45015
45964
  tags: tags2,
45016
- ...cardRef ? { card: cardRef } : {}
45965
+ ...cardRef ? { cardSet: cardRef } : {}
45017
45966
  };
45018
45967
  const output = path3.join(outputFolderBits, `${b.bitType}.jsonc`);
45019
45968
  const str = JSON.stringify(bitJson, null, 2);
@@ -45041,14 +45990,7 @@ var ConfigBuilder = class {
45041
45990
  const bitJson = {
45042
45991
  name: groupKey,
45043
45992
  description: g.description ?? "",
45044
- since: "UNKNOWN",
45045
45993
  deprecated: g.deprecated,
45046
- history: [
45047
- {
45048
- version: "UNKNOWN",
45049
- changes: ["Initial version"]
45050
- }
45051
- ],
45052
45994
  tags: tags2
45053
45995
  // cards: [
45054
45996
  // {
@@ -45102,8 +46044,11 @@ var ConfigBuilder = class {
45102
46044
  tags2.push({
45103
46045
  type: "group",
45104
46046
  key: ref.key,
45105
- ...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
45106
- ...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
46047
+ ...mappingKeysField(
46048
+ ref.extraKeys,
46049
+ { value: ref.exportJsonKey, present: !!ref.hasExportJsonKey },
46050
+ { value: ref.htmlKey, present: !!ref.hasHtmlKey }
46051
+ ),
45107
46052
  ...ref.min != null ? { min: ref.min } : {},
45108
46053
  ...ref.max != null ? { max: ref.max } : {},
45109
46054
  ...ref.description ? { description: ref.description } : {}
@@ -45124,14 +46069,7 @@ var ConfigBuilder = class {
45124
46069
  const bitJson = {
45125
46070
  name: groupKey,
45126
46071
  description: b.description ?? "",
45127
- since: "UNKNOWN",
45128
46072
  deprecated: b.deprecated,
45129
- history: [
45130
- {
45131
- version: "UNKNOWN",
45132
- changes: ["Initial version"]
45133
- }
45134
- ],
45135
46073
  tags: tags2
45136
46074
  };
45137
46075
  const output = path3.join(outputFolderGroups, `${groupKey}.jsonc`);
@@ -45172,7 +46110,7 @@ var ConfigBuilder = class {
45172
46110
  validateConfigTree(outputFolder) {
45173
46111
  const errors = [];
45174
46112
  const outputFolderBits = path3.join(outputFolder, "bits");
45175
- const outputFolderGroups = path3.join(outputFolder, "partials");
46113
+ const outputFolderGroups = path3.join(outputFolder, "groups");
45176
46114
  const outputFolderCards = path3.join(outputFolder, "cards");
45177
46115
  const availableGroups = /* @__PURE__ */ new Set();
45178
46116
  if (fs3.existsSync(outputFolderGroups)) {
@@ -45246,7 +46184,7 @@ var ConfigBuilder = class {
45246
46184
  const content = fs3.readFileSync(filePath, "utf-8");
45247
46185
  const config = JSON.parse(content);
45248
46186
  if (config.tags && Array.isArray(config.tags)) {
45249
- checkTags(config.tags, `partials/${file}`, 15);
46187
+ checkTags(config.tags, `groups/${file}`, 15);
45250
46188
  }
45251
46189
  } catch (err) {
45252
46190
  errors.push(`Failed to parse ${file}: ${err}`);