@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.cjs CHANGED
@@ -1416,6 +1416,7 @@ var propertyKeys = {
1416
1416
  property_dateEnd: "@dateEnd",
1417
1417
  property_decimalPlaces: "@decimalPlaces",
1418
1418
  property_deeplink: "@deeplink",
1419
+ property_displayName: "@displayName",
1419
1420
  property_diffContext: "@diffContext",
1420
1421
  property_diffOp: "@diffOp",
1421
1422
  property_diffRef: "@diffRef",
@@ -1628,6 +1629,8 @@ var propertyKeys = {
1628
1629
  property_trim: "@trim",
1629
1630
  property_unit: "@unit",
1630
1631
  property_unitAbbr: "@unitAbbr",
1632
+ property_unitAbbrPlural: "@unitAbbrPlural",
1633
+ property_unitPlural: "@unitPlural",
1631
1634
  property_vendorDashboardId: "@vendorDashboardId",
1632
1635
  property_vendorSurveyId: "@vendorSurveyId",
1633
1636
  property_vendorUrl: "@vendorUrl",
@@ -2565,9 +2568,30 @@ var CARDSETS = {
2565
2568
  [CardSetConfigKey.definitionList]: {
2566
2569
  jsonKey: "definitions",
2567
2570
  exportJsonKey: { definitions: "$" },
2571
+ // PLAN-141 F1 (NISO import): each <def-item> is one card; the sides
2572
+ // read <term>/<def>; the enclosing <legend>'s <title> lands on the
2573
+ // term side's heading tag ([#Key] header card).
2574
+ // PLAN-141 F3: a <tbx:langSet> is ALSO one card (a terminology entry —
2575
+ // its enclosing <tbx:termEntry> is a transparent claim wrapper); its
2576
+ // children compose the term/definition sides via the side rules below.
2577
+ mappingKeys: {
2578
+ "xml-niso-iec": [
2579
+ { "@el": "def-item", "@children": "$" },
2580
+ { "@el": "tbx:langSet", "@children": "$" }
2581
+ ]
2582
+ },
2568
2583
  sides: [
2569
2584
  {
2570
2585
  name: "term",
2586
+ // F3: every <tbx:tig>'s <tbx:term> STACKS one-per-line onto the
2587
+ // single term side (the "$\n" template's authored separator; the
2588
+ // trailing one is trimmed) — the PDF's Maus/Mus/M/Müsli stack.
2589
+ mappingKeys: {
2590
+ "xml-niso-iec": [
2591
+ { "@el": "term", "@text": "$" },
2592
+ { "@el": "tbx:tig", "@children": { "@el": "tbx:term", "@text": "$\n" } }
2593
+ ]
2594
+ },
2571
2595
  variants: [
2572
2596
  {
2573
2597
  jsonKey: "term.text",
@@ -2583,7 +2607,8 @@ var CARDSETS = {
2583
2607
  format: TagFormat.plainText,
2584
2608
  nullable: true,
2585
2609
  jsonKey: "^heading.forKeys",
2586
- exportJsonKey: { "@bit": { heading: { forKeys: "$" } } }
2610
+ exportJsonKey: { "@bit": { heading: { forKeys: "$" } } },
2611
+ mappingKeys: { "xml-niso-iec": { "@el": "title", "@text": "$" } }
2587
2612
  },
2588
2613
  {
2589
2614
  key: ConfigKey.group_resourceIcon,
@@ -2609,6 +2634,24 @@ var CARDSETS = {
2609
2634
  },
2610
2635
  {
2611
2636
  name: "definition",
2637
+ // F3: the definition side COMPOSES from the entry's fields in
2638
+ // document order, with the ES-rendered locale affixes AUTHORED as
2639
+ // value-position templates (never engine text): the subject field
2640
+ // in ⟨⟩ glues (trailing space) onto the definition line; example /
2641
+ // notes / source follow as blank-line-separated lines. The TBX
2642
+ // grammar flags (normativeAuthorization, termType, partOfSpeech,
2643
+ // grammaticalNumber) are unrendered machine-only data — dropped and
2644
+ // recorded (catalog R-2, reviewed under D7 max-preservation).
2645
+ mappingKeys: {
2646
+ "xml-niso-iec": [
2647
+ { "@el": "def", "@children": "$" },
2648
+ { "@el": "tbx:subjectField", "@text": "\u27E8$\u27E9 " },
2649
+ { "@el": "tbx:definition", "@children": "$" },
2650
+ { "@el": "tbx:example", "@children": "BEISPIEL $" },
2651
+ { "@el": "tbx:note", "@children": "Anmerkung zu Begriff: $" },
2652
+ { "@el": "tbx:source", "@text": "[QUELLE: $]" }
2653
+ ]
2654
+ },
2612
2655
  variants: [
2613
2656
  {
2614
2657
  jsonKey: "definition.text",
@@ -3999,6 +4042,11 @@ var CARDSETS = {
3999
4042
  { table: { header: { rows: ["$"] } } }
4000
4043
  ],
4001
4044
  htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
4045
+ // PLAN-141 F2 (NISO import): the XHTML table model NISO uses — a
4046
+ // <thead> SECTION whose <tr> rows are the header cards.
4047
+ mappingKeys: {
4048
+ "xml-niso-iec": { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } }
4049
+ },
4002
4050
  sideJsonKey: "cells[{s}]|set(title=true)",
4003
4051
  sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
4004
4052
  // Header cells are `<th>`. The `width` attribute is contributed by the
@@ -4010,12 +4058,21 @@ var CARDSETS = {
4010
4058
  jsonKey: "table.body.rows",
4011
4059
  exportJsonKey: { table: { body: { rows: "$" } } },
4012
4060
  htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
4061
+ // PLAN-141 F2 (NISO import): <tbody> rows are the (default) data cards.
4062
+ mappingKeys: {
4063
+ "xml-niso-iec": { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } }
4064
+ },
4013
4065
  isDefault: true
4014
4066
  },
4015
4067
  "table-footer": {
4016
4068
  jsonKey: "table.footer.rows",
4017
4069
  exportJsonKey: { table: { footer: { rows: "$" } } },
4018
4070
  htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
4071
+ // PLAN-141 F2 (NISO import): NISO has no <tfoot> — the footer card's
4072
+ // source is the <table-wrap-foot> block (CONTENT-shaped: no rows; its
4073
+ // prose/notes flatten into one footer card — catalog table-wrap-foot
4074
+ // row; a contained <def-list> promotes as a sibling legend bit).
4075
+ mappingKeys: { "xml-niso-iec": { "@el": "table-wrap-foot", "@children": "$" } },
4019
4076
  sideJsonKey: "cells[{s}]|set(title=true)",
4020
4077
  sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
4021
4078
  // Footer cells render as `<th>` (mirrors the header `title: true`
@@ -4032,6 +4089,8 @@ var CARDSETS = {
4032
4089
  // Default (body) cell → `<td>`; the header/footer sections override the
4033
4090
  // side to `<th>` via their sideHtmlKey (HTML.md §8).
4034
4091
  htmlKey: { "@el": "td", "@children": "$" },
4092
+ // PLAN-141 F2 (NISO import): a <td> row child is a body cell side.
4093
+ mappingKeys: { "xml-niso-iec": { "@el": "td", "@children": "$" } },
4035
4094
  variants: [
4036
4095
  {
4037
4096
  jsonKey: "content",
@@ -4049,7 +4108,11 @@ var CARDSETS = {
4049
4108
  // cell with `title: true` automatically.
4050
4109
  jsonKey: "content",
4051
4110
  exportJsonKey: { content: "$" },
4052
- description: "Title text of the table cell (header rows)."
4111
+ description: "Title text of the table cell (header rows).",
4112
+ // PLAN-141 F2 (NISO import): a <th> row child is a TITLE cell —
4113
+ // its content lands in the `[#…]` tag (an empty <th> keeps its
4114
+ // slot as a bare `[#]`).
4115
+ mappingKeys: { "xml-niso-iec": { "@el": "th", "@children": "$" } }
4053
4116
  },
4054
4117
  {
4055
4118
  key: ConfigKey.property_tableCellType,
@@ -4068,6 +4131,9 @@ var CARDSETS = {
4068
4131
  // HTML-C2: contribute a `rowspan` attribute onto the enclosing
4069
4132
  // cell element (`<th>`/`<td>`).
4070
4133
  htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
4134
+ // PLAN-141 F2 (NISO import): recover the source cell's own
4135
+ // `rowspan` attribute (element-scope attr form).
4136
+ mappingKeys: { "xml-niso-iec": { "@el": { "@attr": { rowspan: "$" } } } },
4071
4137
  description: "Number of rows the cell spans.",
4072
4138
  format: TagFormat.number
4073
4139
  },
@@ -4078,6 +4144,9 @@ var CARDSETS = {
4078
4144
  // HTML-C2: contribute a `colspan` attribute onto the enclosing
4079
4145
  // cell element (`<th>`/`<td>`).
4080
4146
  htmlKey: { "@el": { "@attr": { colspan: "$" } } },
4147
+ // PLAN-141 F2 (NISO import): recover the source cell's own
4148
+ // `colspan` attribute (element-scope attr form).
4149
+ mappingKeys: { "xml-niso-iec": { "@el": { "@attr": { colspan: "$" } } } },
4081
4150
  description: "Number of columns the cell spans.",
4082
4151
  format: TagFormat.number
4083
4152
  },
@@ -4099,6 +4168,13 @@ var CARDSETS = {
4099
4168
  // HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
4100
4169
  // enclosing cell element (`<th>`/`<td>`).
4101
4170
  htmlKey: { "@el": { "@attr": { width: "$" } } },
4171
+ // PLAN-141 F2 (NISO import): NISO carries widths as PER-COLUMN
4172
+ // <col width="…"> descriptors at container level, not on cells.
4173
+ // The matched values distribute positionally onto the first
4174
+ // (header) card's sides. Number format ⇒ only an integral
4175
+ // percentage survives ("20.0000%" → 20); a fractional one
4176
+ // (renderer-equalised "4.7619%") is dropped — catalog `col` row.
4177
+ mappingKeys: { "xml-niso-iec": { "@el": "col", "@attr": { width: "$" } } },
4102
4178
  description: "Width for the column.",
4103
4179
  format: TagFormat.number
4104
4180
  }
@@ -4368,12 +4444,22 @@ var CARDSETS = {
4368
4444
  },
4369
4445
  {
4370
4446
  key: ConfigKey.property_unit,
4371
- description: "Unit of measurement for the ingredient.",
4447
+ description: "Unit of measurement for the ingredient (singular).",
4448
+ format: TagFormat.plainText
4449
+ },
4450
+ {
4451
+ key: ConfigKey.property_unitPlural,
4452
+ description: "Unit of measurement for the ingredient (plural).",
4372
4453
  format: TagFormat.plainText
4373
4454
  },
4374
4455
  {
4375
4456
  key: ConfigKey.property_unitAbbr,
4376
- description: "Abbreviation for the unit of measurement.",
4457
+ description: "Abbreviation for the unit of measurement (singular).",
4458
+ format: TagFormat.plainText
4459
+ },
4460
+ {
4461
+ key: ConfigKey.property_unitAbbrPlural,
4462
+ description: "Abbreviation for the unit of measurement (plural).",
4377
4463
  format: TagFormat.plainText
4378
4464
  },
4379
4465
  {
@@ -4472,7 +4558,22 @@ var GROUPS = {
4472
4558
  key: ConfigKey.property_externalId,
4473
4559
  description: "The external identifier for the bit",
4474
4560
  format: TagFormat.plainText,
4475
- maxCount: Count.infinity
4561
+ maxCount: Count.infinity,
4562
+ // PLAN-140 refs family (NISO import): the machine identifier of a
4563
+ // referenced standard. NESTED content slot — the tag reads (and
4564
+ // consumes) ONLY the <std-id> inside a <std> child; the remaining
4565
+ // designation/title text stays bit body. A <std> without <std-id>
4566
+ // does not fire the key.
4567
+ // PLAN-141 F5: on the [.book] bit, the DATED <std-ref> designation
4568
+ // is the document's external id. Safe rule order: <std-ref> is a
4569
+ // direct bit-element child only under <std-meta> (everywhere else
4570
+ // it nests inside <std>, which the tag spine never reaches).
4571
+ mappingKeys: {
4572
+ "xml-niso-iec": [
4573
+ { "@el": "std", "@children": { "@el": "std-id", "@text": "$" } },
4574
+ { "@el": "std-ref", "@attr": { type: "dated" }, "@text": "$" }
4575
+ ]
4576
+ }
4476
4577
  },
4477
4578
  {
4478
4579
  key: ConfigKey.property_sourceRL,
@@ -4534,6 +4635,11 @@ var GROUPS = {
4534
4635
  description: "Translation source reference",
4535
4636
  format: TagFormat.plainText
4536
4637
  },
4638
+ {
4639
+ key: ConfigKey.property_isCollapsible,
4640
+ description: "If true, the bit is collapsible",
4641
+ format: TagFormat.boolean
4642
+ },
4537
4643
  {
4538
4644
  key: ConfigKey.property_spansPageBreak,
4539
4645
  description: "If true, the bit spans a page break",
@@ -4613,7 +4719,8 @@ var GROUPS = {
4613
4719
  {
4614
4720
  key: ConfigKey.property_diffTime,
4615
4721
  description: "The diff time for the bit",
4616
- format: TagFormat.number
4722
+ format: TagFormat.number,
4723
+ nullable: true
4617
4724
  },
4618
4725
  {
4619
4726
  key: ConfigKey.property_ageRange,
@@ -4624,7 +4731,18 @@ var GROUPS = {
4624
4731
  {
4625
4732
  key: ConfigKey.property_lang,
4626
4733
  description: "The language for the bit",
4627
- format: TagFormat.plainText
4734
+ format: TagFormat.plainText,
4735
+ // PLAN-141 F3 (NISO import): a term-sec's language rides
4736
+ // <tbx:termEntry><tbx:langSet xml:lang> — a nested content slot
4737
+ // whose leaf is a $-in-ATTR-position slot (the nested counterpart
4738
+ // of the value-attr slot). Only termEntry elements match, so the
4739
+ // shared tag is inert everywhere else.
4740
+ mappingKeys: {
4741
+ "xml-niso-iec": {
4742
+ "@el": "tbx:termEntry",
4743
+ "@children": { "@el": "tbx:langSet", "@attr": { "xml:lang": "$" } }
4744
+ }
4745
+ }
4628
4746
  },
4629
4747
  {
4630
4748
  key: ConfigKey.property_publisher,
@@ -4823,6 +4941,9 @@ var GROUPS = {
4823
4941
  key: ConfigKey.tag_item,
4824
4942
  jsonKey: "item",
4825
4943
  exportJsonKey: { item: "$" },
4944
+ // PLAN-140 W3 (NISO import): the clause/note label of a mapped
4945
+ // source element ([%1], [%ANMERKUNG 1]).
4946
+ mappingKeys: { "xml-niso-iec": { "@el": "label", "@text": "$" } },
4826
4947
  description: "The item for the bit",
4827
4948
  chain: [
4828
4949
  {
@@ -5785,7 +5906,20 @@ var GROUPS = {
5785
5906
  key: ConfigKey.property_language,
5786
5907
  description: "The language of the book",
5787
5908
  format: TagFormat.plainText,
5788
- maxCount: Count.infinity
5909
+ maxCount: Count.infinity,
5910
+ // PLAN-141 F5 (NISO import): only the PRIMARY (first)
5911
+ // <content-language> survives — the maxEmits cap realises the
5912
+ // catalog's document-language rule (extras drop, R-4).
5913
+ mappingKeys: {
5914
+ "xml-niso-iec": [
5915
+ { predicates: [], maxEmits: 1, rule: { "@el": "content-language", "@text": "$" } }
5916
+ ]
5917
+ }
5918
+ },
5919
+ {
5920
+ key: ConfigKey.property_displayName,
5921
+ description: "The display name of the book",
5922
+ format: TagFormat.plainText
5789
5923
  },
5790
5924
  {
5791
5925
  key: ConfigKey.property_customerExternalId,
@@ -5861,7 +5995,18 @@ var GROUPS = {
5861
5995
  description: "The title of the book",
5862
5996
  maxCount: 2,
5863
5997
  jsonKey: "title|multi(count=2, key=subtitle)",
5864
- exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }]
5998
+ exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }],
5999
+ // PLAN-141 F5 (NISO import): the PRIMARY (first) <title-wrap>'s
6000
+ // assembled <full> title → [#]; the per-language extras drop (R-4).
6001
+ mappingKeys: {
6002
+ "xml-niso-iec": [
6003
+ {
6004
+ predicates: [],
6005
+ maxEmits: 1,
6006
+ rule: { "@el": "title-wrap", "@children": { "@el": "full", "@text": "$" } }
6007
+ }
6008
+ ]
6009
+ }
5865
6010
  },
5866
6011
  {
5867
6012
  key: ConfigKey.property_subtype,
@@ -6174,17 +6319,20 @@ var GROUPS = {
6174
6319
  {
6175
6320
  key: ConfigKey.property_platformMargin,
6176
6321
  description: "The platform margin",
6177
- format: TagFormat.number
6322
+ format: TagFormat.number,
6323
+ nullable: true
6178
6324
  },
6179
6325
  {
6180
6326
  key: ConfigKey.property_platformBorderRadius,
6181
6327
  description: "The platform border radius",
6182
- format: TagFormat.number
6328
+ format: TagFormat.number,
6329
+ nullable: true
6183
6330
  },
6184
6331
  {
6185
6332
  key: ConfigKey.property_platformSelectionBorderRadius,
6186
6333
  description: "The platform selection border radius",
6187
- format: TagFormat.number
6334
+ format: TagFormat.number,
6335
+ nullable: true
6188
6336
  },
6189
6337
  {
6190
6338
  key: ConfigKey.property_platformNeedsShadow,
@@ -6291,7 +6439,13 @@ var GROUPS = {
6291
6439
  {
6292
6440
  key: ConfigKey.property_caption,
6293
6441
  description: "The caption for the resource",
6294
- format: TagFormat.bitmarkText
6442
+ format: TagFormat.bitmarkText,
6443
+ // PLAN-141 F1 (NISO import): a figure's <caption><title> — the
6444
+ // nested content slot reads the title text; the caption rides the
6445
+ // resource chain ([&image:…][@caption:…], catalog D5).
6446
+ mappingKeys: {
6447
+ "xml-niso-iec": { "@el": "caption", "@children": { "@el": "title", "@text": "$" } }
6448
+ }
6295
6449
  },
6296
6450
  {
6297
6451
  key: ConfigKey.property_showInIndex,
@@ -6565,6 +6719,10 @@ var GROUPS = {
6565
6719
  {
6566
6720
  key: ConfigKey.resource_image,
6567
6721
  exportJsonKey: { resource: { type: "image", image: { src: "$" } } },
6722
+ // PLAN-141 F1 (NISO import): the image URL rides the `$`-in-attr
6723
+ // value slot — a <graphic xlink:href> child of the mapped bit
6724
+ // element roots the [&image:URL] chain.
6725
+ mappingKeys: { "xml-niso-iec": { "@el": "graphic", "@attr": { "xlink:href": "$" } } },
6568
6726
  description: "The image resource",
6569
6727
  chain: [
6570
6728
  {
@@ -7439,6 +7597,8 @@ var BITS = {
7439
7597
  maxCount: 2,
7440
7598
  jsonKey: "title|multi(count=2, key=subtitle)",
7441
7599
  exportJsonKey: [{ "@level=1": { title: "$" } }, { "@level=2": { subtitle: "$" } }],
7600
+ // PLAN-140 W3 (NISO import): the title of a mapped source element.
7601
+ mappingKeys: { "xml-niso-iec": { "@el": "title", "@text": "$" } },
7442
7602
  key: ConfigKey.tag_title,
7443
7603
  description: "The title of the article"
7444
7604
  }
@@ -7480,22 +7640,84 @@ var BITS = {
7480
7640
  [BitType.smartStandardArticleNormative]: {
7481
7641
  since: "1.28.0",
7482
7642
  baseBitType: BitType.standardArticleNormative,
7483
- description: "Smart standard normative article bit"
7643
+ description: "Smart standard normative article bit",
7644
+ // PLAN-140 W3 (NISO import, tranche 1): one article bit per NISO
7645
+ // paragraph (catalog D1). CONTENT keys (@children): the subtree is the
7646
+ // bit's body; nothing inside it promotes. (Ancestor-context normativity
7647
+ // is the non-normative sibling's @ancestor key — plan Q4, resolved.)
7648
+ //
7649
+ // Second rule (catalog D1 push-down): a NUMBERED-PARAGRAPH sec is an
7650
+ // article, not a chapter — the sec-type literal outranks the chapter
7651
+ // key's plain sec|app rule (most-specific-wins). Content key: the sec's
7652
+ // label rides [%] via the label tag key, its inner <p> is the body, its
7653
+ // id is the bit's customerId, and the anchor slot marks it
7654
+ // anchor-bearing.
7655
+ mappingKeys: {
7656
+ "xml-niso-iec": [
7657
+ { "@el": "p", "@attr": { id: "$customerId" }, "@children": "$" },
7658
+ {
7659
+ "@el": "sec",
7660
+ "@attr": { "sec-type": "numbered-paragraph", id: "$customerId" },
7661
+ "@children": "$",
7662
+ "\u25BC": "$anchor"
7663
+ }
7664
+ ]
7665
+ }
7484
7666
  },
7485
7667
  [BitType.smartStandardArticleNonNormative]: {
7486
7668
  since: "1.28.0",
7487
7669
  baseBitType: BitType.standardArticleNonNormative,
7488
- description: "Smart standard non-normative article bit"
7670
+ description: "Smart standard non-normative article bit",
7671
+ // PLAN-140 Q4 (normativity inheritance): a <p> is non-normative because
7672
+ // of an ANCESTOR element — a foreword/intro sec or an informative annex.
7673
+ // @ancestor is a reverse-match-only constraint (forward emission ignores
7674
+ // it); the rules are alternatives, first-satisfied wins, and the
7675
+ // @ancestor literals give this key higher specificity than the plain
7676
+ // normative-article <p> key wherever the context applies.
7677
+ mappingKeys: {
7678
+ "xml-niso-iec": [
7679
+ {
7680
+ "@el": "p",
7681
+ "@attr": { id: "$customerId" },
7682
+ "@ancestor": { "@attr": { "sec-type": "foreword|intro" } },
7683
+ "@children": "$"
7684
+ },
7685
+ {
7686
+ "@el": "p",
7687
+ "@attr": { id: "$customerId" },
7688
+ "@ancestor": { "@attr": { "content-type": "informative" } },
7689
+ "@children": "$"
7690
+ }
7691
+ ]
7692
+ }
7489
7693
  },
7490
7694
  [BitType.smartStandardArticleNormativeCollapsible]: {
7491
7695
  since: "1.28.0",
7696
+ deprecated: "5.37.0",
7492
7697
  baseBitType: BitType.smartStandardArticleNormative,
7493
- description: "Smart standard normative article bit that is collapsible"
7698
+ description: "Smart standard normative article bit that is collapsible",
7699
+ tags: [
7700
+ {
7701
+ key: ConfigKey.property_isCollapsible,
7702
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
7703
+ format: TagFormat.boolean,
7704
+ defaultValue: "true"
7705
+ }
7706
+ ]
7494
7707
  },
7495
7708
  [BitType.smartStandardArticleNonNormativeCollapsible]: {
7496
7709
  since: "1.28.0",
7710
+ deprecated: "5.37.0",
7497
7711
  baseBitType: BitType.smartStandardArticleNonNormative,
7498
- description: "Smart standard non-normative article bit that is collapsible"
7712
+ description: "Smart standard non-normative article bit that is collapsible",
7713
+ tags: [
7714
+ {
7715
+ key: ConfigKey.property_isCollapsible,
7716
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
7717
+ format: TagFormat.boolean,
7718
+ defaultValue: "true"
7719
+ }
7720
+ ]
7499
7721
  },
7500
7722
  [BitType.statement]: {
7501
7723
  since: "1.3.0",
@@ -8116,7 +8338,8 @@ var BITS = {
8116
8338
  {
8117
8339
  key: ConfigKey.property_maxCreatedBits,
8118
8340
  description: "The maximum number of bits that can be created from this bit",
8119
- format: TagFormat.number
8341
+ format: TagFormat.number,
8342
+ nullable: true
8120
8343
  }
8121
8344
  ],
8122
8345
  textFormatDefault: TextFormat.plainText
@@ -8246,6 +8469,13 @@ var BITS = {
8246
8469
  since: "1.3.0",
8247
8470
  baseBitType: BitType._standard,
8248
8471
  description: "Book bit, used to represent a book",
8472
+ // PLAN-141 F5 (NISO import): the <std-meta> front-matter container is
8473
+ // the [.book] bit (STRUCTURAL, first in document order): primary
8474
+ // title-wrap → [#], primary content-language → [@language], dated
8475
+ // std-ref → [@externalId] (tag keys with maxEmits caps — the NISO
8476
+ // convention puts the document language first). std-meta has no id, so
8477
+ // no anchor/customerId. Remaining leaves drop as recorded loss (R-4).
8478
+ mappingKeys: { "xml-niso-iec": { "@el": "std-meta" } },
8249
8479
  tags: [
8250
8480
  {
8251
8481
  key: ConfigKey.group_bookCommon,
@@ -8532,12 +8762,14 @@ var BITS = {
8532
8762
  {
8533
8763
  key: ConfigKey.property_focusX,
8534
8764
  description: "The X coordinate for focusing the image in the browser",
8535
- format: TagFormat.number
8765
+ format: TagFormat.number,
8766
+ nullable: true
8536
8767
  },
8537
8768
  {
8538
8769
  key: ConfigKey.property_focusY,
8539
8770
  description: "The Y coordinate for focusing the image in the browser",
8540
- format: TagFormat.number
8771
+ format: TagFormat.number,
8772
+ nullable: true
8541
8773
  }
8542
8774
  ]
8543
8775
  },
@@ -8568,6 +8800,15 @@ var BITS = {
8568
8800
  since: "1.3.0",
8569
8801
  baseBitType: BitType._standard,
8570
8802
  description: "Chapter bit, used to define chapters in books or articles",
8803
+ // PLAN-140 W3 (NISO import, tranche 1): recover a chapter from a NISO
8804
+ // section or annex. STRUCTURAL key (no @children content slot): the
8805
+ // element carries no body of its own — tag children (label/title) map
8806
+ // via tag keys, every mapped descendant promotes to a following sibling
8807
+ // bit, and the chapter level derives from nesting depth (catalog D1).
8808
+ // The source id lands as [@customerId] (two-id model, D2).
8809
+ mappingKeys: {
8810
+ "xml-niso-iec": { "@el": "sec|app", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
8811
+ },
8571
8812
  tags: [
8572
8813
  {
8573
8814
  exportJsonKey: { anchor: "$" },
@@ -8579,7 +8820,10 @@ var BITS = {
8579
8820
  key: ConfigKey.tag_title,
8580
8821
  description: "The title of the chapter",
8581
8822
  jsonKey: "title|setMulti(level)",
8582
- exportJsonKey: { title: "$", level: "$level" }
8823
+ exportJsonKey: { title: "$", level: "$level" },
8824
+ // PLAN-140 W3 (NISO import): the section/annex title; the heading
8825
+ // level rides the normalizer-derived nesting depth (plan Q2).
8826
+ mappingKeys: { "xml-niso-iec": { "@el": "title", "@text": "$" } }
8583
8827
  },
8584
8828
  {
8585
8829
  key: ConfigKey.property_toc,
@@ -8592,12 +8836,6 @@ var BITS = {
8592
8836
  description: "The progress of the chapter, used for tracking reading progress",
8593
8837
  format: TagFormat.boolean,
8594
8838
  defaultValue: "true"
8595
- },
8596
- {
8597
- key: ConfigKey.property_isCollapsible,
8598
- description: "If true, the chapter is collapsible",
8599
- format: TagFormat.boolean,
8600
- defaultValue: "false"
8601
8839
  }
8602
8840
  ]
8603
8841
  },
@@ -8785,11 +9023,28 @@ var BITS = {
8785
9023
  since: "1.3.0",
8786
9024
  baseBitType: BitType._standard,
8787
9025
  description: "Code bit, used for code snippets in articles or documents",
9026
+ // PLAN-141 F4 (NISO import): a <code> block is a CONTENT bit with a
9027
+ // literal text body; @language recovers as [@computerLanguage] (absent
9028
+ // attr → no tag). Anchor = the source id (D2 revised).
9029
+ mappingKeys: {
9030
+ "xml-niso-iec": {
9031
+ "@el": "code",
9032
+ "@attr": { id: "$customerId", language: "$computerLanguage" },
9033
+ "\u25BC": "$anchor",
9034
+ "@text": "$"
9035
+ }
9036
+ },
8788
9037
  tags: [
8789
9038
  {
8790
9039
  key: ConfigKey.property_computerLanguage,
8791
9040
  description: "The programming language of the code snippet",
8792
- format: TagFormat.plainText
9041
+ format: TagFormat.plainText,
9042
+ // PLAN-141 F4 (NISO import): the bit key's `language` sigil recovers
9043
+ // a present attr; this `@absent` rule supplies the AUTHORED default
9044
+ // when the source carries none (catalog code row — an untyped block
9045
+ // is `[@computerLanguage:text]`). Fires only on foreign imports,
9046
+ // never the carrier round-trip.
9047
+ mappingKeys: { "xml-niso-iec": [{ "@absent": "text" }] }
8793
9048
  },
8794
9049
  {
8795
9050
  key: ConfigKey.property_codeLineNumbers,
@@ -8828,7 +9083,20 @@ var BITS = {
8828
9083
  [BitType.smartStandardFormulaNormative]: {
8829
9084
  since: "3.11.0",
8830
9085
  baseBitType: BitType.formula,
8831
- description: "Smart standard normative formula bit, used for mathematical formulas in smart standards that are normative"
9086
+ description: "Smart standard normative formula bit, used for mathematical formulas in smart standards that are normative",
9087
+ // PLAN-141 F4 (NISO import): a <disp-formula> is a CONTENT bit whose
9088
+ // latex-format body carries the <mml:math> subtree VERBATIM (G1 — no
9089
+ // MathML↔LaTeX transform; ids stripped); <label> → [%]; a contained
9090
+ // <legend> PROMOTES as a sibling legend bit (cards cannot nest in a
9091
+ // body). Anchor = the source id (D2 revised).
9092
+ mappingKeys: {
9093
+ "xml-niso-iec": {
9094
+ "@el": "disp-formula",
9095
+ "@attr": { id: "$customerId" },
9096
+ "\u25BC": "$anchor",
9097
+ "@children": "$"
9098
+ }
9099
+ }
8832
9100
  },
8833
9101
  [BitType.smartStandardRemarkFormula]: {
8834
9102
  since: "3.11.0",
@@ -9174,12 +9442,22 @@ var BITS = {
9174
9442
  chain: [
9175
9443
  {
9176
9444
  key: ConfigKey.property_unit,
9177
- description: "The unit of measurement for the ingredients",
9445
+ description: "The unit of measurement for the ingredients (singular)",
9446
+ format: TagFormat.plainText
9447
+ },
9448
+ {
9449
+ key: ConfigKey.property_unitPlural,
9450
+ description: "The unit of measurement for the ingredients (plural)",
9178
9451
  format: TagFormat.plainText
9179
9452
  },
9180
9453
  {
9181
9454
  key: ConfigKey.property_unitAbbr,
9182
- description: "The abbreviation for the unit of measurement",
9455
+ description: "The abbreviation for the unit of measurement (singular)",
9456
+ format: TagFormat.plainText
9457
+ },
9458
+ {
9459
+ key: ConfigKey.property_unitAbbrPlural,
9460
+ description: "The abbreviation for the unit of measurement (plural)",
9183
9461
  format: TagFormat.plainText
9184
9462
  },
9185
9463
  {
@@ -9355,7 +9633,8 @@ var BITS = {
9355
9633
  {
9356
9634
  key: ConfigKey.property_reasonableNumOfChars,
9357
9635
  description: "The reasonable number of characters for the essay",
9358
- format: TagFormat.number
9636
+ format: TagFormat.number,
9637
+ nullable: true
9359
9638
  },
9360
9639
  {
9361
9640
  key: ConfigKey.property_sampleSolution,
@@ -9457,13 +9736,31 @@ var BITS = {
9457
9736
  },
9458
9737
  [BitType.smartStandardExampleNormativeCollapsible]: {
9459
9738
  since: "1.28.0",
9739
+ deprecated: "5.37.0",
9460
9740
  baseBitType: BitType.smartStandardExampleNormative,
9461
- description: "Smart standard normative example collapsible bit, used to provide normative examples in smart standards that can be collapsed"
9741
+ description: "Smart standard normative example collapsible bit, used to provide normative examples in smart standards that can be collapsed",
9742
+ tags: [
9743
+ {
9744
+ key: ConfigKey.property_isCollapsible,
9745
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
9746
+ format: TagFormat.boolean,
9747
+ defaultValue: "true"
9748
+ }
9749
+ ]
9462
9750
  },
9463
9751
  [BitType.smartStandardExampleNonNormativeCollapsible]: {
9464
9752
  since: "1.28.0",
9753
+ deprecated: "5.37.0",
9465
9754
  baseBitType: BitType.smartStandardExampleNonNormative,
9466
- description: "Smart standard non-normative example collapsible bit, used to provide non-normative examples in smart standards that can be collapsed"
9755
+ description: "Smart standard non-normative example collapsible bit, used to provide non-normative examples in smart standards that can be collapsed",
9756
+ tags: [
9757
+ {
9758
+ key: ConfigKey.property_isCollapsible,
9759
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
9760
+ format: TagFormat.boolean,
9761
+ defaultValue: "true"
9762
+ }
9763
+ ]
9467
9764
  },
9468
9765
  [BitType.authorContentBitGenerator]: {
9469
9766
  since: "4.2.0",
@@ -9788,12 +10085,28 @@ var BITS = {
9788
10085
  [BitType.smartStandardList]: {
9789
10086
  since: "1.28.0",
9790
10087
  baseBitType: BitType.standardList,
9791
- description: "Smart standard list bit, used to create smart standard lists in articles or books"
10088
+ description: "Smart standard list bit, used to create smart standard lists in articles or books",
10089
+ // PLAN-140 refs family (NISO import): a reference list is a STRUCTURAL
10090
+ // bit (no @children — it takes a path ordinal anchor and its <ref>
10091
+ // children promote to sibling list-item bits); its <title> rides [#]
10092
+ // via the title tag key.
10093
+ mappingKeys: {
10094
+ "xml-niso-iec": { "@el": "ref-list", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
10095
+ }
9792
10096
  },
9793
10097
  [BitType.smartStandardListCollapsible]: {
9794
10098
  since: "1.28.0",
10099
+ deprecated: "5.37.0",
9795
10100
  baseBitType: BitType.smartStandardList,
9796
- description: "Smart standard list collapsible bit, used to create collapsible smart standard lists in articles or books"
10101
+ description: "Smart standard list collapsible bit, used to create collapsible smart standard lists in articles or books",
10102
+ tags: [
10103
+ {
10104
+ key: ConfigKey.property_isCollapsible,
10105
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10106
+ format: TagFormat.boolean,
10107
+ defaultValue: "true"
10108
+ }
10109
+ ]
9797
10110
  },
9798
10111
  [BitType.message]: {
9799
10112
  since: "1.3.0",
@@ -9833,17 +10146,45 @@ var BITS = {
9833
10146
  [BitType.smartStandardNoteNonNormative]: {
9834
10147
  since: "1.28.0",
9835
10148
  baseBitType: BitType.standardNoteNonNormative,
9836
- description: "Smart standard non-normative note bit, used to provide non-normative notes in smart standards"
10149
+ description: "Smart standard non-normative note bit, used to provide non-normative notes in smart standards",
10150
+ // PLAN-140 W3 (NISO import, tranche 1). CONTENT key (@children): a
10151
+ // note's inner paragraphs are note body, never separate bits.
10152
+ mappingKeys: {
10153
+ "xml-niso-iec": {
10154
+ "@el": "non-normative-note",
10155
+ "@attr": { id: "$customerId" },
10156
+ "@children": "$",
10157
+ "\u25BC": "$anchor"
10158
+ }
10159
+ }
9837
10160
  },
9838
10161
  [BitType.smartStandardNoteNormativeCollapsible]: {
9839
10162
  since: "1.28.0",
10163
+ deprecated: "5.37.0",
9840
10164
  baseBitType: BitType.smartStandardNoteNormative,
9841
- description: "Smart standard normative note collapsible bit, used to provide normative notes in smart standards that can be collapsed"
10165
+ description: "Smart standard normative note collapsible bit, used to provide normative notes in smart standards that can be collapsed",
10166
+ tags: [
10167
+ {
10168
+ key: ConfigKey.property_isCollapsible,
10169
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10170
+ format: TagFormat.boolean,
10171
+ defaultValue: "true"
10172
+ }
10173
+ ]
9842
10174
  },
9843
10175
  [BitType.smartStandardNoteNonNormativeCollapsible]: {
9844
10176
  since: "1.28.0",
10177
+ deprecated: "5.37.0",
9845
10178
  baseBitType: BitType.smartStandardNoteNonNormative,
9846
- description: "Smart standard non-normative note collapsible bit, used to provide non-normative notes in smart standards that can be collapsed"
10179
+ description: "Smart standard non-normative note collapsible bit, used to provide non-normative notes in smart standards that can be collapsed",
10180
+ tags: [
10181
+ {
10182
+ key: ConfigKey.property_isCollapsible,
10183
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10184
+ format: TagFormat.boolean,
10185
+ defaultValue: "true"
10186
+ }
10187
+ ]
9847
10188
  },
9848
10189
  [BitType.noteAi]: {
9849
10190
  since: "1.3.0",
@@ -9940,17 +10281,47 @@ var BITS = {
9940
10281
  [BitType.smartStandardRemarkNonNormative]: {
9941
10282
  since: "1.28.0",
9942
10283
  baseBitType: BitType.standardRemarkNonNormative,
9943
- description: "Smart standard non-normative remark bit, used to provide non-normative remarks in smart standards"
10284
+ description: "Smart standard non-normative remark bit, used to provide non-normative remarks in smart standards",
10285
+ // PLAN-140 Q4 rider: a warning/caution note routes to the remark bit —
10286
+ // the same element as the note key, distinguished by the content-type
10287
+ // attr literal (alias value: forward emits the first alternative,
10288
+ // reverse accepts any). Most-specific-wins beats the plain note key.
10289
+ mappingKeys: {
10290
+ "xml-niso-iec": {
10291
+ "@el": "non-normative-note",
10292
+ "@attr": { "content-type": "warning|caution", id: "$customerId" },
10293
+ "@children": "$",
10294
+ "\u25BC": "$anchor"
10295
+ }
10296
+ }
9944
10297
  },
9945
10298
  [BitType.smartStandardRemarkNormativeCollapsible]: {
9946
10299
  since: "1.28.0",
10300
+ deprecated: "5.37.0",
9947
10301
  baseBitType: BitType.smartStandardRemarkNormative,
9948
- description: "Smart standard normative remark collapsible bit, used to provide normative remarks in smart standards that can be collapsed"
10302
+ description: "Smart standard normative remark collapsible bit, used to provide normative remarks in smart standards that can be collapsed",
10303
+ tags: [
10304
+ {
10305
+ key: ConfigKey.property_isCollapsible,
10306
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10307
+ format: TagFormat.boolean,
10308
+ defaultValue: "true"
10309
+ }
10310
+ ]
9949
10311
  },
9950
10312
  [BitType.smartStandardRemarkNonNormativeCollapsible]: {
9951
10313
  since: "1.28.0",
10314
+ deprecated: "5.37.0",
9952
10315
  baseBitType: BitType.smartStandardRemarkNonNormative,
9953
- description: "Smart standard non-normative remark collapsible bit, used to provide non-normative remarks in smart standards that can be collapsed"
10316
+ description: "Smart standard non-normative remark collapsible bit, used to provide non-normative remarks in smart standards that can be collapsed",
10317
+ tags: [
10318
+ {
10319
+ key: ConfigKey.property_isCollapsible,
10320
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10321
+ format: TagFormat.boolean,
10322
+ defaultValue: "true"
10323
+ }
10324
+ ]
9954
10325
  },
9955
10326
  [BitType.selfAssessment]: {
9956
10327
  since: "1.3.0",
@@ -10021,53 +10392,143 @@ var BITS = {
10021
10392
  },
10022
10393
  [BitType.collapsible]: {
10023
10394
  since: "1.21.0",
10395
+ deprecated: "5.37.0",
10024
10396
  baseBitType: BitType.article,
10025
- description: "Collapsible bit, used to create collapsible sections in articles or books"
10397
+ description: "Collapsible bit, used to create collapsible sections in articles or books",
10398
+ tags: [
10399
+ {
10400
+ key: ConfigKey.property_isCollapsible,
10401
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10402
+ format: TagFormat.boolean,
10403
+ defaultValue: "true"
10404
+ }
10405
+ ]
10026
10406
  },
10027
10407
  [BitType.sideNoteCollapsible]: {
10028
10408
  since: "1.21.0",
10029
- baseBitType: BitType.article,
10030
- description: "Side note collapsible bit, used to create collapsible side notes in articles or books"
10409
+ deprecated: "5.37.0",
10410
+ baseBitType: BitType.sideNote,
10411
+ description: "Side note collapsible bit, used to create collapsible side notes in articles or books",
10412
+ tags: [
10413
+ {
10414
+ key: ConfigKey.property_isCollapsible,
10415
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10416
+ format: TagFormat.boolean,
10417
+ defaultValue: "true"
10418
+ }
10419
+ ]
10031
10420
  },
10032
10421
  [BitType.infoCollapsible]: {
10033
10422
  since: "1.21.0",
10034
- baseBitType: BitType.article,
10035
- description: "Info collapsible bit, used to create collapsible informational sections in articles or books"
10423
+ deprecated: "5.37.0",
10424
+ baseBitType: BitType.info,
10425
+ description: "Info collapsible bit, used to create collapsible informational sections in articles or books",
10426
+ tags: [
10427
+ {
10428
+ key: ConfigKey.property_isCollapsible,
10429
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10430
+ format: TagFormat.boolean,
10431
+ defaultValue: "true"
10432
+ }
10433
+ ]
10036
10434
  },
10037
10435
  [BitType.remarkCollapsible]: {
10038
10436
  since: "1.21.0",
10039
- baseBitType: BitType.article,
10040
- description: "Remark collapsible bit, used to create collapsible remarks in articles or books"
10437
+ deprecated: "5.37.0",
10438
+ baseBitType: BitType.remark,
10439
+ description: "Remark collapsible bit, used to create collapsible remarks in articles or books",
10440
+ tags: [
10441
+ {
10442
+ key: ConfigKey.property_isCollapsible,
10443
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10444
+ format: TagFormat.boolean,
10445
+ defaultValue: "true"
10446
+ }
10447
+ ]
10041
10448
  },
10042
10449
  [BitType.warningCollapsible]: {
10043
10450
  since: "1.21.0",
10044
- baseBitType: BitType.article,
10045
- description: "Warning collapsible bit, used to create collapsible warnings in articles or books"
10451
+ deprecated: "5.37.0",
10452
+ baseBitType: BitType.warning,
10453
+ description: "Warning collapsible bit, used to create collapsible warnings in articles or books",
10454
+ tags: [
10455
+ {
10456
+ key: ConfigKey.property_isCollapsible,
10457
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10458
+ format: TagFormat.boolean,
10459
+ defaultValue: "true"
10460
+ }
10461
+ ]
10046
10462
  },
10047
10463
  [BitType.dangerCollapsible]: {
10048
10464
  since: "1.21.0",
10049
- baseBitType: BitType.article,
10050
- description: "Danger collapsible bit, used to create collapsible danger sections in articles or books"
10465
+ deprecated: "5.37.0",
10466
+ baseBitType: BitType.danger,
10467
+ description: "Danger collapsible bit, used to create collapsible danger sections in articles or books",
10468
+ tags: [
10469
+ {
10470
+ key: ConfigKey.property_isCollapsible,
10471
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10472
+ format: TagFormat.boolean,
10473
+ defaultValue: "true"
10474
+ }
10475
+ ]
10051
10476
  },
10052
10477
  [BitType.noteCollapsible]: {
10053
10478
  since: "1.21.0",
10054
- baseBitType: BitType.article,
10055
- description: "Note collapsible bit, used to create collapsible notes in articles or books"
10479
+ deprecated: "5.37.0",
10480
+ baseBitType: BitType.note,
10481
+ description: "Note collapsible bit, used to create collapsible notes in articles or books",
10482
+ tags: [
10483
+ {
10484
+ key: ConfigKey.property_isCollapsible,
10485
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10486
+ format: TagFormat.boolean,
10487
+ defaultValue: "true"
10488
+ }
10489
+ ]
10056
10490
  },
10057
10491
  [BitType.exampleCollapsible]: {
10058
10492
  since: "1.21.0",
10059
- baseBitType: BitType.article,
10060
- description: "Example collapsible bit, used to create collapsible examples in articles or books"
10493
+ deprecated: "5.37.0",
10494
+ baseBitType: BitType.example,
10495
+ description: "Example collapsible bit, used to create collapsible examples in articles or books",
10496
+ tags: [
10497
+ {
10498
+ key: ConfigKey.property_isCollapsible,
10499
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10500
+ format: TagFormat.boolean,
10501
+ defaultValue: "true"
10502
+ }
10503
+ ]
10061
10504
  },
10062
10505
  [BitType.hintCollapsible]: {
10063
10506
  since: "1.21.0",
10064
- baseBitType: BitType.article,
10065
- description: "Hint collapsible bit, used to create collapsible hints in articles or books"
10507
+ deprecated: "5.37.0",
10508
+ baseBitType: BitType.hint,
10509
+ description: "Hint collapsible bit, used to create collapsible hints in articles or books",
10510
+ tags: [
10511
+ {
10512
+ key: ConfigKey.property_isCollapsible,
10513
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10514
+ format: TagFormat.boolean,
10515
+ defaultValue: "true"
10516
+ }
10517
+ ]
10066
10518
  },
10067
10519
  [BitType.bugCollapsible]: {
10068
10520
  since: "1.21.0",
10069
- baseBitType: BitType.article,
10070
- description: "Bug collapsible bit, used to create collapsible bug reports in articles or books"
10521
+ deprecated: "5.37.0",
10522
+ baseBitType: BitType.bug,
10523
+ description: "Bug collapsible bit, used to create collapsible bug reports in articles or books",
10524
+ tags: [
10525
+ {
10526
+ key: ConfigKey.property_isCollapsible,
10527
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10528
+ format: TagFormat.boolean,
10529
+ defaultValue: "true"
10530
+ }
10531
+ ]
10071
10532
  },
10072
10533
  [BitType.platformPath]: {
10073
10534
  since: "3.14.1",
@@ -10289,8 +10750,17 @@ var BITS = {
10289
10750
  },
10290
10751
  [BitType.extractorPageCollapsible]: {
10291
10752
  since: "1.30.0",
10753
+ deprecated: "5.37.0",
10292
10754
  baseBitType: BitType.extractorPage,
10293
- description: "Collapsible extractor page bit, used to extract pages from images with collapsible functionality"
10755
+ description: "Collapsible extractor page bit, used to extract pages from images with collapsible functionality",
10756
+ tags: [
10757
+ {
10758
+ key: ConfigKey.property_isCollapsible,
10759
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10760
+ format: TagFormat.boolean,
10761
+ defaultValue: "true"
10762
+ }
10763
+ ]
10294
10764
  },
10295
10765
  [BitType.extractorPageWithBlocks]: {
10296
10766
  since: "1.5.21",
@@ -10299,8 +10769,17 @@ var BITS = {
10299
10769
  },
10300
10770
  [BitType.extractorPageWithBlocksCollapsible]: {
10301
10771
  since: "1.30.0",
10772
+ deprecated: "5.37.0",
10302
10773
  baseBitType: BitType.extractorPageWithBlocks,
10303
- description: "Collapsible extractor page with blocks bit, used to extract pages with blocks from images with collapsible functionality"
10774
+ description: "Collapsible extractor page with blocks bit, used to extract pages with blocks from images with collapsible functionality",
10775
+ tags: [
10776
+ {
10777
+ key: ConfigKey.property_isCollapsible,
10778
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10779
+ format: TagFormat.boolean,
10780
+ defaultValue: "true"
10781
+ }
10782
+ ]
10304
10783
  },
10305
10784
  [BitType.extractorConfiguration]: {
10306
10785
  since: "1.7.1",
@@ -10340,8 +10819,17 @@ var BITS = {
10340
10819
  },
10341
10820
  [BitType.extractorImageCollapsible]: {
10342
10821
  since: "4.3.0",
10822
+ deprecated: "5.37.0",
10343
10823
  baseBitType: BitType.extractorImage,
10344
- description: "Collapsible extractor images bit, used for images extracted from PDFs"
10824
+ description: "Collapsible extractor images bit, used for images extracted from PDFs",
10825
+ tags: [
10826
+ {
10827
+ key: ConfigKey.property_isCollapsible,
10828
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10829
+ format: TagFormat.boolean,
10830
+ defaultValue: "true"
10831
+ }
10832
+ ]
10345
10833
  },
10346
10834
  [BitType.extractorBlueprint]: {
10347
10835
  since: "5.12.0",
@@ -10396,7 +10884,8 @@ var BITS = {
10396
10884
  {
10397
10885
  key: ConfigKey.property_pageNo,
10398
10886
  description: "Page number for the block, used to indicate the page on which the block appears",
10399
- format: TagFormat.number
10887
+ format: TagFormat.number,
10888
+ nullable: true
10400
10889
  },
10401
10890
  {
10402
10891
  key: ConfigKey.property_x,
@@ -10413,17 +10902,20 @@ var BITS = {
10413
10902
  {
10414
10903
  key: ConfigKey.property_width,
10415
10904
  description: "Width of the block, used to define the size of the block on the page",
10416
- format: TagFormat.number
10905
+ format: TagFormat.number,
10906
+ nullable: true
10417
10907
  },
10418
10908
  {
10419
10909
  key: ConfigKey.property_height,
10420
10910
  description: "Height of the block, used to define the size of the block on the page",
10421
- format: TagFormat.number
10911
+ format: TagFormat.number,
10912
+ nullable: true
10422
10913
  },
10423
10914
  {
10424
10915
  key: ConfigKey.property_index,
10425
10916
  description: "Index of the block, used to order blocks within the extractor page",
10426
- format: TagFormat.number
10917
+ format: TagFormat.number,
10918
+ nullable: true
10427
10919
  },
10428
10920
  {
10429
10921
  key: ConfigKey.property_classification,
@@ -10474,8 +10966,17 @@ var BITS = {
10474
10966
  },
10475
10967
  [BitType.extractorPageNumberCollapsible]: {
10476
10968
  since: "1.30.0",
10969
+ deprecated: "5.37.0",
10477
10970
  baseBitType: BitType.extractorPageNumber,
10478
- description: "Collapsible extractor page number bit, used to define page numbers in extractor pages with collapsible functionality"
10971
+ description: "Collapsible extractor page number bit, used to define page numbers in extractor pages with collapsible functionality",
10972
+ tags: [
10973
+ {
10974
+ key: ConfigKey.property_isCollapsible,
10975
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10976
+ format: TagFormat.boolean,
10977
+ defaultValue: "true"
10978
+ }
10979
+ ]
10479
10980
  },
10480
10981
  [BitType.extractorPageHeader]: {
10481
10982
  since: "1.5.21",
@@ -10484,8 +10985,17 @@ var BITS = {
10484
10985
  },
10485
10986
  [BitType.extractorPageHeaderCollapsible]: {
10486
10987
  since: "1.30.0",
10988
+ deprecated: "5.37.0",
10487
10989
  baseBitType: BitType.extractorPageHeader,
10488
- description: "Collapsible extractor page header bit, used to define headers in extractor pages with collapsible functionality"
10990
+ description: "Collapsible extractor page header bit, used to define headers in extractor pages with collapsible functionality",
10991
+ tags: [
10992
+ {
10993
+ key: ConfigKey.property_isCollapsible,
10994
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
10995
+ format: TagFormat.boolean,
10996
+ defaultValue: "true"
10997
+ }
10998
+ ]
10489
10999
  },
10490
11000
  [BitType.extractorPageFooter]: {
10491
11001
  since: "1.5.21",
@@ -10494,8 +11004,17 @@ var BITS = {
10494
11004
  },
10495
11005
  [BitType.extractorPageFooterCollapsible]: {
10496
11006
  since: "1.30.0",
11007
+ deprecated: "5.37.0",
10497
11008
  baseBitType: BitType.extractorPageFooter,
10498
- description: "Collapsible extractor page footer bit, used to define footers in extractor pages with collapsible functionality"
11009
+ description: "Collapsible extractor page footer bit, used to define footers in extractor pages with collapsible functionality",
11010
+ tags: [
11011
+ {
11012
+ key: ConfigKey.property_isCollapsible,
11013
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11014
+ format: TagFormat.boolean,
11015
+ defaultValue: "true"
11016
+ }
11017
+ ]
10499
11018
  },
10500
11019
  [BitType.pageOpenBook]: {
10501
11020
  since: "1.5.10",
@@ -10733,7 +11252,20 @@ var BITS = {
10733
11252
  [BitType.smartStandardLegendNormative]: {
10734
11253
  since: "3.12.0",
10735
11254
  baseBitType: BitType.legend,
10736
- description: "Smart standard normative legend bit, used to provide normative smart standard legends in articles or books"
11255
+ description: "Smart standard normative legend bit, used to provide normative smart standard legends in articles or books",
11256
+ // PLAN-141 F2 (NISO import): a free-standing <legend> (a formula's) or
11257
+ // bare <def-list> (a table footer's — no <legend> wrapper there) that is
11258
+ // NOT the claimed card content of its enclosing bit is a legend bit:
11259
+ // STRUCTURAL-shaped, its <title> and <def-item>s build the
11260
+ // definition-list cards via the card set's authored keys. A <legend>
11261
+ // inside a figure/table bit stays that bit's claimed card content and
11262
+ // never reaches this key. Anchor = the source id (D2 revised).
11263
+ mappingKeys: {
11264
+ "xml-niso-iec": [
11265
+ { "@el": "legend", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" },
11266
+ { "@el": "def-list", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
11267
+ ]
11268
+ }
10737
11269
  },
10738
11270
  [BitType.smartStandardRemarkLegend]: {
10739
11271
  since: "3.12.0",
@@ -10772,8 +11304,17 @@ var BITS = {
10772
11304
  },
10773
11305
  [BitType.definitionListCollapsible]: {
10774
11306
  since: "5.25.0",
11307
+ deprecated: "5.37.0",
10775
11308
  baseBitType: BitType.definitionList,
10776
- description: "Collapsible definition list bit, used to create collapsible lists of definitions in articles or books"
11309
+ description: "Collapsible definition list bit, used to create collapsible lists of definitions in articles or books",
11310
+ tags: [
11311
+ {
11312
+ key: ConfigKey.property_isCollapsible,
11313
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11314
+ format: TagFormat.boolean,
11315
+ defaultValue: "true"
11316
+ }
11317
+ ]
10777
11318
  },
10778
11319
  [BitType.standardDefinitionListNormative]: {
10779
11320
  since: "5.24.0",
@@ -10788,7 +11329,16 @@ var BITS = {
10788
11329
  [BitType.smartStandardDefinitionListNormative]: {
10789
11330
  since: "5.24.0",
10790
11331
  baseBitType: BitType.standardDefinitionListNormative,
10791
- description: "Smart standard normative definition list bit, used to create normative smart standard definition lists in articles or books"
11332
+ description: "Smart standard normative definition list bit, used to create normative smart standard definition lists in articles or books",
11333
+ // PLAN-141 F3 (NISO import): a terms-and-definitions clause. STRUCTURAL-
11334
+ // shaped: <label> → [%], the tbx:termEntry/langSet subtree builds the
11335
+ // definition-list card via the card set's authored keys (all tig terms
11336
+ // stacked on the term side; definition/example/notes/source composed on
11337
+ // the definition side with authored locale affixes), langSet @xml:lang →
11338
+ // [@lang] (nested attr slot on the tag key). Anchor = the source id.
11339
+ mappingKeys: {
11340
+ "xml-niso-iec": { "@el": "term-sec", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
11341
+ }
10792
11342
  },
10793
11343
  [BitType.smartStandardDefinitionListNonNormative]: {
10794
11344
  since: "5.24.0",
@@ -10857,12 +11407,14 @@ var BITS = {
10857
11407
  {
10858
11408
  key: ConfigKey.property_focusX,
10859
11409
  description: "X-coordinate for the focus point, used to define the focus area in the image",
10860
- format: TagFormat.number
11410
+ format: TagFormat.number,
11411
+ nullable: true
10861
11412
  },
10862
11413
  {
10863
11414
  key: ConfigKey.property_focusY,
10864
11415
  description: "Y-coordinate for the focus point, used to define the focus area in the image",
10865
- format: TagFormat.number
11416
+ format: TagFormat.number,
11417
+ nullable: true
10866
11418
  }
10867
11419
  ]
10868
11420
  },
@@ -10969,7 +11521,15 @@ var BITS = {
10969
11521
  [BitType.smartStandardImageFigureNormative]: {
10970
11522
  since: "1.28.0",
10971
11523
  baseBitType: BitType.standardImageFigureNormative,
10972
- description: "Smart standard normative image figure bit, used to create smart standard normative image figures in articles or books"
11524
+ description: "Smart standard normative image figure bit, used to create smart standard normative image figures in articles or books",
11525
+ // PLAN-141 F1 (NISO import): a figure is STRUCTURAL-shaped (no
11526
+ // @children — no body): <label> → [%], <caption>/<graphic> ride the
11527
+ // [&image] resource chain, the <legend> def-list becomes the bit's
11528
+ // definition-list cards, and an inner note PROMOTES as a sibling bit.
11529
+ // Anchor = the source id (D2 revised).
11530
+ mappingKeys: {
11531
+ "xml-niso-iec": { "@el": "fig", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
11532
+ }
10973
11533
  },
10974
11534
  [BitType.smartStandardImageFigureNonNormative]: {
10975
11535
  since: "1.28.0",
@@ -10978,13 +11538,31 @@ var BITS = {
10978
11538
  },
10979
11539
  [BitType.smartStandardImageFigureNormativeCollapsible]: {
10980
11540
  since: "1.28.0",
11541
+ deprecated: "5.37.0",
10981
11542
  baseBitType: BitType.smartStandardImageFigureNormative,
10982
- description: "Collapsible smart standard normative image figure bit, used to create collapsible smart standard normative image figures in articles or books"
11543
+ description: "Collapsible smart standard normative image figure bit, used to create collapsible smart standard normative image figures in articles or books",
11544
+ tags: [
11545
+ {
11546
+ key: ConfigKey.property_isCollapsible,
11547
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11548
+ format: TagFormat.boolean,
11549
+ defaultValue: "true"
11550
+ }
11551
+ ]
10983
11552
  },
10984
11553
  [BitType.smartStandardImageFigureNonNormativeCollapsible]: {
10985
11554
  since: "1.28.0",
11555
+ deprecated: "5.37.0",
10986
11556
  baseBitType: BitType.smartStandardImageFigureNonNormative,
10987
- description: "Collapsible smart standard non-normative image figure bit, used to create collapsible smart standard non-normative image figures in articles or books"
11557
+ description: "Collapsible smart standard non-normative image figure bit, used to create collapsible smart standard non-normative image figures in articles or books",
11558
+ tags: [
11559
+ {
11560
+ key: ConfigKey.property_isCollapsible,
11561
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11562
+ format: TagFormat.boolean,
11563
+ defaultValue: "true"
11564
+ }
11565
+ ]
10988
11566
  },
10989
11567
  [BitType.imageLandscape]: {
10990
11568
  since: "1.3.0",
@@ -11196,43 +11774,115 @@ var BITS = {
11196
11774
  },
11197
11775
  [BitType.smartStandardTableImageNormativeCollapsible]: {
11198
11776
  since: "1.28.0",
11777
+ deprecated: "5.37.0",
11199
11778
  baseBitType: BitType.smartStandardTableImageNormative,
11200
- description: "Collapsible smart standard normative table image bit, used to create collapsible smart standard normative images in tables in articles or books"
11779
+ description: "Collapsible smart standard normative table image bit, used to create collapsible smart standard normative images in tables in articles or books",
11780
+ tags: [
11781
+ {
11782
+ key: ConfigKey.property_isCollapsible,
11783
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11784
+ format: TagFormat.boolean,
11785
+ defaultValue: "true"
11786
+ }
11787
+ ]
11201
11788
  },
11202
11789
  [BitType.smartStandardTableImageNonNormativeCollapsible]: {
11203
11790
  since: "1.28.0",
11791
+ deprecated: "5.37.0",
11204
11792
  baseBitType: BitType.smartStandardTableImageNonNormative,
11205
- description: "Collapsible smart standard non-normative table image bit, used to create collapsible smart standard non-normative images in tables in articles or books"
11793
+ description: "Collapsible smart standard non-normative table image bit, used to create collapsible smart standard non-normative images in tables in articles or books",
11794
+ tags: [
11795
+ {
11796
+ key: ConfigKey.property_isCollapsible,
11797
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11798
+ format: TagFormat.boolean,
11799
+ defaultValue: "true"
11800
+ }
11801
+ ]
11206
11802
  },
11207
11803
  [BitType.smartStandardRemarkTableImageNormativeCollapsible]: {
11208
11804
  since: "1.28.0",
11805
+ deprecated: "5.37.0",
11209
11806
  baseBitType: BitType.smartStandardRemarkTableImageNormative,
11210
- description: "Collapsible smart standard normative remark table image bit, used to create collapsible smart standard normative remark images in tables in articles or books"
11807
+ description: "Collapsible smart standard normative remark table image bit, used to create collapsible smart standard normative remark images in tables in articles or books",
11808
+ tags: [
11809
+ {
11810
+ key: ConfigKey.property_isCollapsible,
11811
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11812
+ format: TagFormat.boolean,
11813
+ defaultValue: "true"
11814
+ }
11815
+ ]
11211
11816
  },
11212
11817
  [BitType.smartStandardRemarkTableImageNonNormativeCollapsible]: {
11213
11818
  since: "1.28.0",
11819
+ deprecated: "5.37.0",
11214
11820
  baseBitType: BitType.smartStandardRemarkTableImageNonNormative,
11215
- 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"
11821
+ 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",
11822
+ tags: [
11823
+ {
11824
+ key: ConfigKey.property_isCollapsible,
11825
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11826
+ format: TagFormat.boolean,
11827
+ defaultValue: "true"
11828
+ }
11829
+ ]
11216
11830
  },
11217
11831
  [BitType.smartStandardTableExtendedImageNormativeCollapsible]: {
11218
11832
  since: "1.28.0",
11833
+ deprecated: "5.37.0",
11219
11834
  baseBitType: BitType.smartStandardTableExtendedImageNormative,
11220
- description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
11835
+ description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books",
11836
+ tags: [
11837
+ {
11838
+ key: ConfigKey.property_isCollapsible,
11839
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11840
+ format: TagFormat.boolean,
11841
+ defaultValue: "true"
11842
+ }
11843
+ ]
11221
11844
  },
11222
11845
  [BitType.smartStandardTableExtendedImageNonNormativeCollapsible]: {
11223
11846
  since: "1.28.0",
11847
+ deprecated: "5.37.0",
11224
11848
  baseBitType: BitType.smartStandardTableExtendedImageNonNormative,
11225
- 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"
11849
+ 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",
11850
+ tags: [
11851
+ {
11852
+ key: ConfigKey.property_isCollapsible,
11853
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11854
+ format: TagFormat.boolean,
11855
+ defaultValue: "true"
11856
+ }
11857
+ ]
11226
11858
  },
11227
11859
  [BitType.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
11228
11860
  since: "1.28.0",
11861
+ deprecated: "5.37.0",
11229
11862
  baseBitType: BitType.smartStandardRemarkTableExtendedImageNormative,
11230
- 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"
11863
+ 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",
11864
+ tags: [
11865
+ {
11866
+ key: ConfigKey.property_isCollapsible,
11867
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11868
+ format: TagFormat.boolean,
11869
+ defaultValue: "true"
11870
+ }
11871
+ ]
11231
11872
  },
11232
11873
  [BitType.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
11233
11874
  since: "1.28.0",
11875
+ deprecated: "5.37.0",
11234
11876
  baseBitType: BitType.smartStandardRemarkTableExtendedImageNonNormative,
11235
- 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"
11877
+ 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",
11878
+ tags: [
11879
+ {
11880
+ key: ConfigKey.property_isCollapsible,
11881
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
11882
+ format: TagFormat.boolean,
11883
+ defaultValue: "true"
11884
+ }
11885
+ ]
11236
11886
  },
11237
11887
  [BitType.imageLink]: {
11238
11888
  since: "1.3.0",
@@ -11697,12 +12347,33 @@ var BITS = {
11697
12347
  [BitType.smartStandardListItem]: {
11698
12348
  since: "1.28.0",
11699
12349
  baseBitType: BitType.standardListItem,
11700
- description: "Smart standard list item bit, used to create smart standard list items in articles or books"
12350
+ description: "Smart standard list item bit, used to create smart standard list items in articles or books",
12351
+ // PLAN-140 refs family (NISO import): one list-item bit per <ref> —
12352
+ // CONTENT key (its citation subtree is the body), counter anchor scoped
12353
+ // to the containing list, <label> → [%], nested <std-id> → [@externalId]
12354
+ // (the externalId tag key's nested content slot).
12355
+ mappingKeys: {
12356
+ "xml-niso-iec": {
12357
+ "@el": "ref",
12358
+ "@attr": { id: "$customerId" },
12359
+ "@children": "$",
12360
+ "\u25BC": "$anchor"
12361
+ }
12362
+ }
11701
12363
  },
11702
12364
  [BitType.smartStandardListItemCollapsible]: {
11703
12365
  since: "1.28.0",
12366
+ deprecated: "5.37.0",
11704
12367
  baseBitType: BitType.smartStandardListItem,
11705
- description: "Collapsible smart standard list item bit, used to create collapsible smart standard list items in articles or books"
12368
+ description: "Collapsible smart standard list item bit, used to create collapsible smart standard list items in articles or books",
12369
+ tags: [
12370
+ {
12371
+ key: ConfigKey.property_isCollapsible,
12372
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
12373
+ format: TagFormat.boolean,
12374
+ defaultValue: "true"
12375
+ }
12376
+ ]
11706
12377
  },
11707
12378
  [BitType.mark]: {
11708
12379
  since: "1.3.0",
@@ -12035,8 +12706,17 @@ var BITS = {
12035
12706
  },
12036
12707
  [BitType.pageCollapsible]: {
12037
12708
  since: "1.30.0",
12709
+ deprecated: "5.37.0",
12038
12710
  baseBitType: BitType.page,
12039
- description: "Collapsible page bit, used to create collapsible sections in pages"
12711
+ description: "Collapsible page bit, used to create collapsible sections in pages",
12712
+ tags: [
12713
+ {
12714
+ key: ConfigKey.property_isCollapsible,
12715
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
12716
+ format: TagFormat.boolean,
12717
+ defaultValue: "true"
12718
+ }
12719
+ ]
12040
12720
  },
12041
12721
  [BitType.pageCoverImage]: {
12042
12722
  since: "1.22.0",
@@ -12804,7 +13484,13 @@ var BITS = {
12804
13484
  // `<caption>` — placed inside the idiomatic `<table>` container as
12805
13485
  // its first child. Outside a table context it falls back to the
12806
13486
  // residual carrier.
12807
- htmlKey: { "@el": "caption", "@children": "$" }
13487
+ htmlKey: { "@el": "caption", "@children": "$" },
13488
+ // PLAN-141 F2 (NISO import): a table-wrap's <caption><title> — the
13489
+ // nested content slot reads the title text (catalog D5: the caption
13490
+ // is a TOP-LEVEL bit property on table bits).
13491
+ mappingKeys: {
13492
+ "xml-niso-iec": { "@el": "caption", "@children": { "@el": "title", "@text": "$" } }
13493
+ }
12808
13494
  },
12809
13495
  {
12810
13496
  key: ConfigKey.property_tableFixedHeader,
@@ -12977,7 +13663,16 @@ var BITS = {
12977
13663
  [BitType.smartStandardTableExtendedNormative]: {
12978
13664
  since: "1.28.0",
12979
13665
  baseBitType: BitType.standardTableExtendedNormative,
12980
- description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
13666
+ description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books",
13667
+ // PLAN-141 F2 (NISO import): a table-wrap is STRUCTURAL-shaped (no
13668
+ // @children — no body): <label> → [%], <caption><title> → the bit-level
13669
+ // [@caption] (D5), the inner <table>/<table-wrap-foot> build the
13670
+ // table-extended card grid via the card set's authored keys, and a
13671
+ // footer <def-list> PROMOTES as a sibling legend bit. Anchor = the
13672
+ // source id (D2 revised).
13673
+ mappingKeys: {
13674
+ "xml-niso-iec": { "@el": "table-wrap", "@attr": { id: "$customerId" }, "\u25BC": "$anchor" }
13675
+ }
12981
13676
  },
12982
13677
  [BitType.smartStandardTableExtendedNonNormative]: {
12983
13678
  since: "1.28.0",
@@ -12996,43 +13691,115 @@ var BITS = {
12996
13691
  },
12997
13692
  [BitType.smartStandardTableNormativeCollapsible]: {
12998
13693
  since: "1.28.0",
13694
+ deprecated: "5.37.0",
12999
13695
  baseBitType: BitType.smartStandardTableNormative,
13000
- description: "Collapsible smart standard normative table bit, used to create collapsible smart standard normative tables in articles or books"
13696
+ description: "Collapsible smart standard normative table bit, used to create collapsible smart standard normative tables in articles or books",
13697
+ tags: [
13698
+ {
13699
+ key: ConfigKey.property_isCollapsible,
13700
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13701
+ format: TagFormat.boolean,
13702
+ defaultValue: "true"
13703
+ }
13704
+ ]
13001
13705
  },
13002
13706
  [BitType.smartStandardTableNonNormativeCollapsible]: {
13003
13707
  since: "1.28.0",
13708
+ deprecated: "5.37.0",
13004
13709
  baseBitType: BitType.smartStandardTableNonNormative,
13005
- description: "Collapsible smart standard non-normative table bit, used to create collapsible smart standard non-normative tables in articles or books"
13710
+ description: "Collapsible smart standard non-normative table bit, used to create collapsible smart standard non-normative tables in articles or books",
13711
+ tags: [
13712
+ {
13713
+ key: ConfigKey.property_isCollapsible,
13714
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13715
+ format: TagFormat.boolean,
13716
+ defaultValue: "true"
13717
+ }
13718
+ ]
13006
13719
  },
13007
13720
  [BitType.smartStandardRemarkTableNormativeCollapsible]: {
13008
13721
  since: "1.28.0",
13722
+ deprecated: "5.37.0",
13009
13723
  baseBitType: BitType.smartStandardRemarkTableNormative,
13010
- description: "Collapsible smart standard normative remark table bit, used to create collapsible smart standard normative remark tables in articles or books"
13724
+ description: "Collapsible smart standard normative remark table bit, used to create collapsible smart standard normative remark tables in articles or books",
13725
+ tags: [
13726
+ {
13727
+ key: ConfigKey.property_isCollapsible,
13728
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13729
+ format: TagFormat.boolean,
13730
+ defaultValue: "true"
13731
+ }
13732
+ ]
13011
13733
  },
13012
13734
  [BitType.smartStandardRemarkTableNonNormativeCollapsible]: {
13013
13735
  since: "1.28.0",
13736
+ deprecated: "5.37.0",
13014
13737
  baseBitType: BitType.smartStandardRemarkTableNonNormative,
13015
- description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
13738
+ description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books",
13739
+ tags: [
13740
+ {
13741
+ key: ConfigKey.property_isCollapsible,
13742
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13743
+ format: TagFormat.boolean,
13744
+ defaultValue: "true"
13745
+ }
13746
+ ]
13016
13747
  },
13017
13748
  [BitType.smartStandardTableExtendedNormativeCollapsible]: {
13018
13749
  since: "1.28.0",
13750
+ deprecated: "5.37.0",
13019
13751
  baseBitType: BitType.smartStandardTableExtendedNormative,
13020
- description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
13752
+ description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books",
13753
+ tags: [
13754
+ {
13755
+ key: ConfigKey.property_isCollapsible,
13756
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13757
+ format: TagFormat.boolean,
13758
+ defaultValue: "true"
13759
+ }
13760
+ ]
13021
13761
  },
13022
13762
  [BitType.smartStandardTableExtendedNonNormativeCollapsible]: {
13023
13763
  since: "1.28.0",
13764
+ deprecated: "5.37.0",
13024
13765
  baseBitType: BitType.smartStandardTableExtendedNonNormative,
13025
- description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
13766
+ description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books",
13767
+ tags: [
13768
+ {
13769
+ key: ConfigKey.property_isCollapsible,
13770
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13771
+ format: TagFormat.boolean,
13772
+ defaultValue: "true"
13773
+ }
13774
+ ]
13026
13775
  },
13027
13776
  [BitType.smartStandardRemarkTableExtendedNormativeCollapsible]: {
13028
13777
  since: "1.28.0",
13778
+ deprecated: "5.37.0",
13029
13779
  baseBitType: BitType.smartStandardRemarkTableExtendedNormative,
13030
- description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
13780
+ description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books",
13781
+ tags: [
13782
+ {
13783
+ key: ConfigKey.property_isCollapsible,
13784
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13785
+ format: TagFormat.boolean,
13786
+ defaultValue: "true"
13787
+ }
13788
+ ]
13031
13789
  },
13032
13790
  [BitType.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
13033
13791
  since: "1.28.0",
13792
+ deprecated: "5.37.0",
13034
13793
  baseBitType: BitType.smartStandardRemarkTableExtendedNonNormative,
13035
- 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"
13794
+ 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",
13795
+ tags: [
13796
+ {
13797
+ key: ConfigKey.property_isCollapsible,
13798
+ description: "If true, the bit is collapsible (defaults true for this deprecated bit type)",
13799
+ format: TagFormat.boolean,
13800
+ defaultValue: "true"
13801
+ }
13802
+ ]
13036
13803
  },
13037
13804
  [BitType.parameters]: {
13038
13805
  since: "1.18.0",
@@ -13052,7 +13819,8 @@ var BITS = {
13052
13819
  {
13053
13820
  key: ConfigKey.property_maxDisplayLevel,
13054
13821
  description: "Maximum display level for the chapter in the table of contents",
13055
- format: TagFormat.number
13822
+ format: TagFormat.number,
13823
+ nullable: true
13056
13824
  }
13057
13825
  ]
13058
13826
  },
@@ -13064,7 +13832,8 @@ var BITS = {
13064
13832
  {
13065
13833
  key: ConfigKey.property_maxTocChapterLevel,
13066
13834
  description: "Maximum chapter level for the inline table of contents",
13067
- format: TagFormat.number
13835
+ format: TagFormat.number,
13836
+ nullable: true
13068
13837
  }
13069
13838
  ]
13070
13839
  },
@@ -13487,13 +14256,15 @@ var BITS = {
13487
14256
  key: ConfigKey.property_width,
13488
14257
  // Same as image
13489
14258
  description: "Width for the embedded content, used to define the width in pixels",
13490
- format: TagFormat.number
14259
+ format: TagFormat.number,
14260
+ nullable: true
13491
14261
  },
13492
14262
  {
13493
14263
  key: ConfigKey.property_height,
13494
14264
  // Same as image
13495
14265
  description: "Height for the embedded content, used to define the height in pixels",
13496
- format: TagFormat.number
14266
+ format: TagFormat.number,
14267
+ nullable: true
13497
14268
  },
13498
14269
  {
13499
14270
  key: ConfigKey.property_vendorUrl,
@@ -13531,7 +14302,8 @@ var BITS = {
13531
14302
  {
13532
14303
  key: ConfigKey.property_jupyterExecutionCount,
13533
14304
  description: "Execution count for the Jupyter output, used to define the execution order",
13534
- format: TagFormat.number
14305
+ format: TagFormat.number,
14306
+ nullable: true
13535
14307
  }
13536
14308
  ],
13537
14309
  textFormatDefault: TextFormat.plainText
@@ -13739,11 +14511,13 @@ var BITS = {
13739
14511
  };
13740
14512
 
13741
14513
  // src/config/Config.ts
14514
+ var COLLAPSIBLE_BIT_TYPE_SUFFIX = "-collapsible";
13742
14515
  var Config = class {
13743
14516
  constructor() {
13744
14517
  __publicField(this, "bitLevelMin", 1);
13745
14518
  __publicField(this, "bitLevelMax", 7);
13746
14519
  __publicField(this, "bitCache", /* @__PURE__ */ new Map());
14520
+ __publicField(this, "migratedBitCache", /* @__PURE__ */ new Map());
13747
14521
  __publicField(this, "allResourcesCache");
13748
14522
  __publicField(this, "comboResourcesCache", /* @__PURE__ */ new Map());
13749
14523
  }
@@ -13759,6 +14533,29 @@ var Config = class {
13759
14533
  if (bitType?.startsWith("|")) bitType = bitType.substring(1);
13760
14534
  return (0, import_superenum16.Enum)(BitType).fromValue(bitType) ?? BitType._error;
13761
14535
  }
14536
+ /**
14537
+ * PLAN-017: Return the migration target for a deprecated `*-collapsible` bit type.
14538
+ *
14539
+ * Every `*-collapsible` bit type declares its non-collapsible cousin as its `baseBitType`, so the
14540
+ * target is read from the config rather than a hand-maintained table — a new `*-collapsible` bit
14541
+ * type is covered automatically.
14542
+ *
14543
+ * `BitType.collapsible` is the one exclusion: it has no non-collapsible cousin (its `baseBitType`
14544
+ * is `article`, which is not a migration target).
14545
+ *
14546
+ * @param bitType the bit type
14547
+ * @returns the bit type to migrate to, or undefined if the bit type does not migrate
14548
+ */
14549
+ getMigratedBitType(bitType) {
14550
+ const cached = this.migratedBitCache.get(bitType);
14551
+ if (cached !== void 0 || this.migratedBitCache.has(bitType)) return cached;
14552
+ let target;
14553
+ if (bitType !== BitType.collapsible && bitType.endsWith(COLLAPSIBLE_BIT_TYPE_SUFFIX)) {
14554
+ target = BITS[bitType]?.baseBitType;
14555
+ }
14556
+ this.migratedBitCache.set(bitType, target);
14557
+ return target;
14558
+ }
13762
14559
  /**
13763
14560
  * Check if a bit type is and instance of the given root bit type.
13764
14561
  *
@@ -14081,7 +14878,7 @@ var instance2 = new Config();
14081
14878
  // src/generated/package_info.ts
14082
14879
  var PACKAGE_INFO = {
14083
14880
  "name": "@gmb/bitmark-parser-generator",
14084
- "version": "5.35.0",
14881
+ "version": "5.37.0",
14085
14882
  "author": "Get More Brain Ltd",
14086
14883
  "license": "ISC",
14087
14884
  "description": "A bitmark parser and generator using Peggy.js"
@@ -14610,6 +15407,8 @@ var NodeType = {
14610
15407
  definition: "definition",
14611
15408
  definitions: "definitions",
14612
15409
  definitionsValue: "definitionsValue",
15410
+ displayName: "displayName",
15411
+ displayNameValue: "displayNameValue",
14613
15412
  diffContext: "diffContext",
14614
15413
  diffContextValue: "diffContextValue",
14615
15414
  diffOp: "diffOp",
@@ -15138,6 +15937,8 @@ var NodeType = {
15138
15937
  type: "type",
15139
15938
  unit: "unit",
15140
15939
  unitAbbr: "unitAbbr",
15940
+ unitAbbrPlural: "unitAbbrPlural",
15941
+ unitPlural: "unitPlural",
15141
15942
  url: "url",
15142
15943
  validationDate: "validationDate",
15143
15944
  validationDateValue: "validationDateValue",
@@ -28313,8 +29114,14 @@ var Builder = class extends BaseBuilder {
28313
29114
  */
28314
29115
  buildBit(data, options) {
28315
29116
  data = structuredClone(data);
29117
+ const migratedBitType = instance2.getMigratedBitType(data.bitType);
29118
+ if (migratedBitType) {
29119
+ data.bitType = migratedBitType;
29120
+ data.isCollapsible = data.isCollapsible ?? true;
29121
+ }
28316
29122
  const bitType = data.bitType;
28317
29123
  const bitConfig = instance2.getBitConfig(bitType);
29124
+ const isCollapsibleDefaultsTrue = bitConfig.tags[ConfigKey.property_isCollapsible]?.defaultValue === "true";
28318
29125
  const deprecatedTextFormat = (0, import_superenum30.Enum)(DeprecatedTextFormat).fromValue(data.textFormat);
28319
29126
  let textFormat = (0, import_superenum30.Enum)(TextFormat).fromValue(data.textFormat) ?? bitConfig.textFormatDefault;
28320
29127
  if (deprecatedTextFormat === DeprecatedTextFormat.bitmarkMinusMinus) {
@@ -28532,6 +29339,12 @@ var Builder = class extends BaseBuilder {
28532
29339
  data.publisherName,
28533
29340
  options
28534
29341
  ),
29342
+ displayName: this.toAstProperty(
29343
+ bitType,
29344
+ ConfigKey.property_displayName,
29345
+ data.displayName,
29346
+ options
29347
+ ),
28535
29348
  theme: this.toAstProperty(bitType, ConfigKey.property_theme, data.theme, options),
28536
29349
  rtl: this.toAstProperty(bitType, ConfigKey.property_rtl, data.rtl, options),
28537
29350
  computerLanguage: this.toAstProperty(
@@ -29441,7 +30254,7 @@ var Builder = class extends BaseBuilder {
29441
30254
  isCollapsible: this.toAstProperty(
29442
30255
  bitType,
29443
30256
  ConfigKey.property_isCollapsible,
29444
- data.isCollapsible,
30257
+ data.isCollapsible ?? (isCollapsibleDefaultsTrue ? true : void 0),
29445
30258
  options
29446
30259
  ),
29447
30260
  anchor: data.anchor,
@@ -30210,7 +31023,9 @@ var Builder = class extends BaseBuilder {
30210
31023
  ingredient: this.handleJsonText(context, TextLocation.tag, data.ingredient),
30211
31024
  quantity: data.quantity ?? 0,
30212
31025
  unit: data.unit ?? "",
31026
+ unitPlural: data.unitPlural ?? "",
30213
31027
  unitAbbr: data.unitAbbr ?? "",
31028
+ unitAbbrPlural: data.unitAbbrPlural ?? "",
30214
31029
  decimalPlaces: data.decimalPlaces ?? 1,
30215
31030
  disableCalculation: data.disableCalculation ?? false,
30216
31031
  item: this.handleJsonText(context, TextLocation.tag, data.item),
@@ -30807,11 +31622,22 @@ var Builder = class extends BaseBuilder {
30807
31622
  */
30808
31623
  buildServings(_context, data) {
30809
31624
  if (!data) return void 0;
30810
- const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = data;
31625
+ const {
31626
+ servings,
31627
+ unit,
31628
+ unitPlural,
31629
+ unitAbbr,
31630
+ unitAbbrPlural,
31631
+ decimalPlaces,
31632
+ disableCalculation,
31633
+ hint
31634
+ } = data;
30811
31635
  const node = {
30812
31636
  servings: servings ?? 0,
30813
31637
  unit: unit ?? "",
31638
+ unitPlural: unitPlural ?? "",
30814
31639
  unitAbbr: unitAbbr ?? "",
31640
+ unitAbbrPlural: unitAbbrPlural ?? "",
30815
31641
  decimalPlaces: decimalPlaces ?? 1,
30816
31642
  disableCalculation: disableCalculation ?? false,
30817
31643
  hint: hint ?? ""
@@ -31748,7 +32574,16 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31748
32574
  const nodeValue = node.value;
31749
32575
  const parent = this.getParentNode(route);
31750
32576
  if (parent?.key !== NodeType.bitsValue) return true;
31751
- const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = nodeValue;
32577
+ const {
32578
+ servings,
32579
+ unit,
32580
+ unitPlural,
32581
+ unitAbbr,
32582
+ unitAbbrPlural,
32583
+ decimalPlaces,
32584
+ disableCalculation,
32585
+ hint
32586
+ } = nodeValue;
31752
32587
  this.writeProperty("servings", servings, route, {
31753
32588
  format: TagFormat.plainText
31754
32589
  });
@@ -31758,12 +32593,24 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31758
32593
  forceChain: true
31759
32594
  });
31760
32595
  }
32596
+ if (unitPlural != null) {
32597
+ this.writeProperty("unitPlural", unitPlural, route, {
32598
+ format: TagFormat.plainText,
32599
+ forceChain: true
32600
+ });
32601
+ }
31761
32602
  if (unitAbbr != null) {
31762
32603
  this.writeProperty("unitAbbr", unitAbbr, route, {
31763
32604
  format: TagFormat.plainText,
31764
32605
  forceChain: true
31765
32606
  });
31766
32607
  }
32608
+ if (unitAbbrPlural != null) {
32609
+ this.writeProperty("unitAbbrPlural", unitAbbrPlural, route, {
32610
+ format: TagFormat.plainText,
32611
+ forceChain: true
32612
+ });
32613
+ }
31767
32614
  if (decimalPlaces != null) {
31768
32615
  this.writeProperty("decimalPlaces", decimalPlaces, route, {
31769
32616
  format: TagFormat.plainText,
@@ -32610,10 +33457,18 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
32610
33457
  this.writeProperty("unit", ingredient.unit, route, {
32611
33458
  format: TagFormat.plainText
32612
33459
  });
33460
+ if (ingredient.unitPlural != null)
33461
+ this.writeProperty("unitPlural", ingredient.unitPlural, route, {
33462
+ format: TagFormat.plainText
33463
+ });
32613
33464
  if (ingredient.unitAbbr != null)
32614
33465
  this.writeProperty("unitAbbr", ingredient.unitAbbr, route, {
32615
33466
  format: TagFormat.plainText
32616
33467
  });
33468
+ if (ingredient.unitAbbrPlural != null)
33469
+ this.writeProperty("unitAbbrPlural", ingredient.unitAbbrPlural, route, {
33470
+ format: TagFormat.plainText
33471
+ });
32617
33472
  if (ingredient.decimalPlaces != null)
32618
33473
  this.writeProperty("decimalPlaces", ingredient.decimalPlaces, route, {
32619
33474
  format: TagFormat.plainText
@@ -34392,6 +35247,25 @@ var JsonGenerator = class extends AstWalkerGenerator {
34392
35247
  }
34393
35248
  return false;
34394
35249
  }
35250
+ // bitmarkAst -> bits -> bitsValue -> isCollapsible
35251
+ /**
35252
+ * PLAN-016: `isCollapsible` is emitted only when true. `false` is the implied
35253
+ * default for every bit, so it is never written to the JSON — an absent key
35254
+ * means the bit's configured default (`true` for the deprecated
35255
+ * `*-collapsible` bit types, `false` everywhere else).
35256
+ *
35257
+ * Defining these handlers suppresses the generic property handlers that
35258
+ * `generatePropertyHandlers()` would otherwise install for this tag.
35259
+ */
35260
+ leaf_isCollapsible(node, route) {
35261
+ const parent = this.getParentNode(route);
35262
+ if (parent?.key !== NodeType.bitsValue) return false;
35263
+ if (node.value === true) this.bitJson.isCollapsible = true;
35264
+ return false;
35265
+ }
35266
+ enter_isCollapsible(node, route) {
35267
+ return this.leaf_isCollapsible(node, route);
35268
+ }
34395
35269
  // bitmarkAst -> bits -> bitsValue -> markConfig
34396
35270
  enter_markConfig(_node, _route) {
34397
35271
  return true;
@@ -35265,7 +36139,6 @@ var JsonGenerator = class extends AstWalkerGenerator {
35265
36139
  if (instance2.isOfBitType(bitType, BitType.chapter)) {
35266
36140
  if (bitJson.toc == null) bitJson.toc = true;
35267
36141
  if (bitJson.progress == null) bitJson.progress = true;
35268
- if (bitJson.isCollapsible == null) bitJson.isCollapsible = false;
35269
36142
  if (bitJson.level == null) bitJson.level = 1;
35270
36143
  if (bitJson.body == null) bitJson.body = this.bodyDefault;
35271
36144
  }
@@ -38244,7 +39117,9 @@ function parseIngredients(_context, _bitType, cardSet) {
38244
39117
  title: titleArray,
38245
39118
  __instructionString,
38246
39119
  unit,
39120
+ unitPlural,
38247
39121
  unitAbbr,
39122
+ unitAbbrPlural,
38248
39123
  decimalPlaces,
38249
39124
  disableCalculation,
38250
39125
  cardBodyStr,
@@ -38274,7 +39149,9 @@ function parseIngredients(_context, _bitType, cardSet) {
38274
39149
  ingredient: cardBodyStr,
38275
39150
  quantity,
38276
39151
  unit: unit ?? instance3.EMPTY_STRING,
39152
+ unitPlural,
38277
39153
  unitAbbr: unitAbbr ?? instance3.EMPTY_STRING,
39154
+ unitAbbrPlural,
38278
39155
  decimalPlaces: decimalPlaces ?? 1,
38279
39156
  disableCalculation,
38280
39157
  ...tags2
@@ -38945,12 +39822,22 @@ function servingsChainContentProcessor(context, _contentDepth, tagsConfig, conte
38945
39822
  if (context.DEBUG_CHAIN_CONTENT) context.debugPrint("servings content", content);
38946
39823
  const tags2 = context.bitContentProcessor(ContentDepth.Chain, tagsConfig, content.chain);
38947
39824
  if (context.DEBUG_CHAIN_TAGS) context.debugPrint("servings TAGS", tags2);
38948
- const { unit, unitAbbr, decimalPlaces, disableCalculation, __hintString } = tags2;
39825
+ const {
39826
+ unit,
39827
+ unitPlural,
39828
+ unitAbbr,
39829
+ unitAbbrPlural,
39830
+ decimalPlaces,
39831
+ disableCalculation,
39832
+ __hintString
39833
+ } = tags2;
38949
39834
  const servings = instance6.asNumber(content.value) ?? 1;
38950
39835
  const node = {
38951
39836
  servings,
38952
39837
  unit,
39838
+ unitPlural,
38953
39839
  unitAbbr,
39840
+ unitAbbrPlural,
38954
39841
  decimalPlaces: decimalPlaces ?? 1,
38955
39842
  disableCalculation,
38956
39843
  hint: __hintString
@@ -44694,7 +45581,7 @@ var ConfigBuilder = class {
44694
45581
  }
44695
45582
  const outputFolder = opts.outputDir ?? "assets/config";
44696
45583
  const outputFolderBits = import_node_path3.default.join(outputFolder, "bits");
44697
- const outputFolderGroups = import_node_path3.default.join(outputFolder, "partials");
45584
+ const outputFolderGroups = import_node_path3.default.join(outputFolder, "groups");
44698
45585
  const outputFolderCards = import_node_path3.default.join(outputFolder, "cards");
44699
45586
  import_fs_extra3.default.ensureDirSync(outputFolderBits);
44700
45587
  import_fs_extra3.default.ensureDirSync(outputFolderGroups);
@@ -44729,6 +45616,15 @@ var ConfigBuilder = class {
44729
45616
  }
44730
45617
  return [{ key: groupKey }];
44731
45618
  };
45619
+ const mappingKeysField = (base, json, html) => {
45620
+ const record = {};
45621
+ for (const [id, value] of Object.entries(base ?? {})) {
45622
+ if (value != null) record[id] = value;
45623
+ }
45624
+ if (json.present && json.value != null) record.json = json.value;
45625
+ if (html.present && html.value != null) record.html = html.value;
45626
+ return Object.keys(record).length > 0 ? { mappingKeys: record } : {};
45627
+ };
44732
45628
  const bareKeyForProperty = (key) => {
44733
45629
  if (key.startsWith("@") || key.startsWith("&")) return key.substring(1);
44734
45630
  return void 0;
@@ -44749,22 +45645,20 @@ var ConfigBuilder = class {
44749
45645
  if (tag.format === TagFormat.plainText) {
44750
45646
  format = "string";
44751
45647
  } else if (tag.format === TagFormat.boolean) {
44752
- format = "bool";
44753
- } else if (tag.format === TagFormat.bitmarkText) {
44754
- format = "bitmark";
45648
+ format = "boolean";
44755
45649
  } else if (tag.format === TagFormat.number) {
44756
45650
  format = "number";
44757
45651
  } else {
44758
- format = "bitmark--";
45652
+ format = "bitmark+";
44759
45653
  }
44760
45654
  } else if (tagType === BitTagConfigKeyType.property) {
44761
45655
  tagName = tag.key;
44762
45656
  if (tag.format === TagFormat.plainText) {
44763
45657
  format = "string";
44764
45658
  } else if (tag.format === TagFormat.boolean) {
44765
- format = "bool";
45659
+ format = "boolean";
44766
45660
  } else if (tag.format === TagFormat.bitmarkText) {
44767
- format = "bitmark";
45661
+ format = "bitmark+";
44768
45662
  } else if (tag.format === TagFormat.number) {
44769
45663
  format = "number";
44770
45664
  } else if (tag.format === TagFormat.coordinates) {
@@ -44796,8 +45690,11 @@ var ConfigBuilder = class {
44796
45690
  tags2.push({
44797
45691
  type: "group",
44798
45692
  key: ref.key,
44799
- ...hasExportChosen ? { jsonKey: exportJsonKeyChosen } : {},
44800
- ...hasHtmlChosen ? { htmlKey: htmlKeyChosen } : {},
45693
+ ...mappingKeysField(
45694
+ { ...ref.extraKeys ?? {}, ...tag.mappingKeys ?? {} },
45695
+ { value: exportJsonKeyChosen, present: hasExportChosen },
45696
+ { value: htmlKeyChosen, present: hasHtmlChosen }
45697
+ ),
44801
45698
  ...min != null ? { min } : {},
44802
45699
  ...max != null ? { max } : {},
44803
45700
  ...description ? { description } : {}
@@ -44814,53 +45711,48 @@ var ConfigBuilder = class {
44814
45711
  chain = chainTags;
44815
45712
  }
44816
45713
  const hasExport = Object.prototype.hasOwnProperty.call(tag, "exportJsonKey");
44817
- let exportJsonKeyField;
44818
- if (hasExport) {
44819
- exportJsonKeyField = { jsonKey: tag.exportJsonKey };
44820
- } else if (legacyIsTrivialDefault(tag)) {
44821
- exportJsonKeyField = {};
44822
- } else {
45714
+ if (!hasExport && !legacyIsTrivialDefault(tag)) {
44823
45715
  const headingPath = [...pathStack, `tags.${tag.key}`].join(" / ");
44824
45716
  exportJsonKeyErrors.push(
44825
45717
  `Missing exportJsonKey for non-default jsonKey at ${headingPath}` + (tag.jsonKey ? ` (legacy: \`${tag.jsonKey}\`)` : ` (symbol-mapped tag \`${tag.key}\`)`)
44826
45718
  );
44827
- exportJsonKeyField = {};
44828
45719
  }
44829
45720
  const hasHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
44830
- const htmlKeyField = hasHtml ? { htmlKey: tag.htmlKey } : {};
44831
45721
  const t = {
44832
45722
  type: "tag",
44833
45723
  key: tagName,
44834
- ...exportJsonKeyField,
44835
- ...htmlKeyField,
44836
- format,
44837
- default: tag.defaultValue ?? null,
45724
+ ...mappingKeysField(
45725
+ tag.mappingKeys,
45726
+ { value: tag.exportJsonKey, present: hasExport },
45727
+ { value: tag.htmlKey, present: hasHtml }
45728
+ ),
45729
+ ...format && format !== "string" ? { format } : {},
45730
+ ...tag.defaultValue != null ? { default: tag.defaultValue } : {},
44838
45731
  ...tag.nullable ? { nullable: true } : {},
44839
- min: tag.minCount == null ? 0 : tag.minCount,
44840
- max: tag.maxCount == null ? 1 : tag.maxCount,
45732
+ ...tag.minCount != null && tag.minCount !== 0 ? { min: tag.minCount } : {},
45733
+ ...tag.maxCount != null && tag.maxCount !== 1 ? { max: tag.maxCount } : {},
44841
45734
  description: tag.description ?? "",
44842
45735
  tags: chain
44843
45736
  };
44844
45737
  tags2.push(t);
44845
45738
  return tags2;
44846
45739
  };
44847
- const cardJsonKeyField = (container, legacyKey, exportKey, pathHeading) => {
45740
+ const cardMappingKeysField = (container, base, legacyKey, exportKey, htmlExportKey, pathHeading) => {
44848
45741
  const c = container;
44849
45742
  const hasExport = Object.prototype.hasOwnProperty.call(c, exportKey);
44850
- if (hasExport) return { jsonKey: c[exportKey] };
44851
- const legacy = c[legacyKey];
44852
- if (legacy == null) return {};
44853
- exportJsonKeyErrors.push(
44854
- `Missing exportJsonKey for non-default jsonKey at ${pathHeading} (legacy: \`${legacy}\`)`
44855
- );
44856
- return {};
44857
- };
44858
- const cardHtmlKeyField = (container, htmlExportKey) => {
44859
- const c = container;
44860
- if (Object.prototype.hasOwnProperty.call(c, htmlExportKey)) {
44861
- return { htmlKey: c[htmlExportKey] };
45743
+ if (!hasExport && c[legacyKey] != null) {
45744
+ exportJsonKeyErrors.push(
45745
+ `Missing exportJsonKey for non-default jsonKey at ${pathHeading} (legacy: \`${c[legacyKey]}\`)`
45746
+ );
44862
45747
  }
44863
- return {};
45748
+ return mappingKeysField(
45749
+ base,
45750
+ { value: c[exportKey], present: hasExport },
45751
+ {
45752
+ value: c[htmlExportKey],
45753
+ present: Object.prototype.hasOwnProperty.call(c, htmlExportKey)
45754
+ }
45755
+ );
44864
45756
  };
44865
45757
  const serializeCardSet = (cardSetKey) => {
44866
45758
  const variantBodyFormat = (variant) => variant.format ?? TextFormat.bitmarkText;
@@ -44891,11 +45783,17 @@ var ConfigBuilder = class {
44891
45783
  variantTags.push(...processTagEntries(variantTag, [variantPath]));
44892
45784
  }
44893
45785
  return {
44894
- ...cardJsonKeyField(variant, "jsonKey", "exportJsonKey", variantPath),
44895
- ...cardHtmlKeyField(variant, "htmlKey"),
44896
- format: variantBodyFormat(variant),
45786
+ ...cardMappingKeysField(
45787
+ variant,
45788
+ void 0,
45789
+ "jsonKey",
45790
+ "exportJsonKey",
45791
+ "htmlKey",
45792
+ variantPath
45793
+ ),
45794
+ bodyFormat: variantBodyFormat(variant),
44897
45795
  tags: variantTags,
44898
- repeatCount: variant.repeatCount ?? 1,
45796
+ ...variant.repeatCount != null && variant.repeatCount !== 1 ? { repeatCount: variant.repeatCount } : {},
44899
45797
  ...variant.bodyRequired ? { bodyRequired: true } : {},
44900
45798
  ...variant.bodyAllowed === false ? { bodyForbidden: true } : {}
44901
45799
  };
@@ -44903,8 +45801,14 @@ var ConfigBuilder = class {
44903
45801
  return {
44904
45802
  name: side.name,
44905
45803
  ...side.repeat ? { repeat: side.repeat } : {},
44906
- ...cardJsonKeyField(side, "jsonKey", "exportJsonKey", sidePath),
44907
- ...cardHtmlKeyField(side, "htmlKey"),
45804
+ ...cardMappingKeysField(
45805
+ side,
45806
+ side.mappingKeys,
45807
+ "jsonKey",
45808
+ "exportJsonKey",
45809
+ "htmlKey",
45810
+ sidePath
45811
+ ),
44908
45812
  variants
44909
45813
  };
44910
45814
  });
@@ -44915,20 +45819,40 @@ var ConfigBuilder = class {
44915
45819
  const hasSideHtml = Object.prototype.hasOwnProperty.call(section, "sideHtmlKey");
44916
45820
  let cardSides = sides;
44917
45821
  if (hasSideExport || section.sideJsonKey != null || hasSideHtml) {
44918
- const sideOverride = cardJsonKeyField(
44919
- section,
44920
- "sideJsonKey",
44921
- "sideExportJsonKey",
44922
- `${sectionPath} / sides.*`
44923
- );
44924
- const sideHtmlOverride = cardHtmlKeyField(section, "sideHtmlKey");
44925
- cardSides = sides.map((s) => ({ ...s, ...sideOverride, ...sideHtmlOverride }));
45822
+ if (!hasSideExport && section.sideJsonKey != null) {
45823
+ exportJsonKeyErrors.push(
45824
+ `Missing exportJsonKey for non-default jsonKey at ${sectionPath} / sides.* (legacy: \`${section.sideJsonKey}\`)`
45825
+ );
45826
+ }
45827
+ cardSides = sides.map((s) => {
45828
+ const record = { ...s.mappingKeys ?? {} };
45829
+ if (hasSideExport) {
45830
+ if (section.sideExportJsonKey != null) record.json = section.sideExportJsonKey;
45831
+ else delete record.json;
45832
+ }
45833
+ if (hasSideHtml) {
45834
+ if (section.sideHtmlKey != null) record.html = section.sideHtmlKey;
45835
+ else delete record.html;
45836
+ }
45837
+ return {
45838
+ name: s.name,
45839
+ ...s.repeat ? { repeat: s.repeat } : {},
45840
+ ...Object.keys(record).length > 0 ? { mappingKeys: record } : {},
45841
+ variants: s.variants
45842
+ };
45843
+ });
44926
45844
  }
44927
45845
  return {
44928
45846
  name: sectionName,
44929
45847
  ...section.isDefault ? { isDefault: true } : {},
44930
- ...cardJsonKeyField(section, "jsonKey", "exportJsonKey", sectionPath),
44931
- ...cardHtmlKeyField(section, "htmlKey"),
45848
+ ...cardMappingKeysField(
45849
+ section,
45850
+ section.mappingKeys,
45851
+ "jsonKey",
45852
+ "exportJsonKey",
45853
+ "htmlKey",
45854
+ sectionPath
45855
+ ),
44932
45856
  // PLAN-085: per-section cardinality. Emit only when non-default
44933
45857
  // (treat `0` / undefined as "unbounded — omit").
44934
45858
  ...section.minCount != null && section.minCount !== 0 ? { min: section.minCount } : {},
@@ -44936,7 +45860,18 @@ var ConfigBuilder = class {
44936
45860
  sides: cardSides
44937
45861
  };
44938
45862
  });
44939
- return { name: normalizedKey, ...cardHtmlKeyField(cardSetConfig, "htmlKey"), cards };
45863
+ return {
45864
+ name: normalizedKey,
45865
+ ...mappingKeysField(
45866
+ void 0,
45867
+ { present: false },
45868
+ {
45869
+ value: cardSetConfig.htmlKey,
45870
+ present: Object.prototype.hasOwnProperty.call(cardSetConfig, "htmlKey")
45871
+ }
45872
+ ),
45873
+ cards
45874
+ };
44940
45875
  }
44941
45876
  const cardSetPath = `cardSets.${normalizedKey} / cards.default`;
44942
45877
  return {
@@ -44945,8 +45880,14 @@ var ConfigBuilder = class {
44945
45880
  {
44946
45881
  name: "default",
44947
45882
  isDefault: true,
44948
- ...cardJsonKeyField(cardSetConfig, "jsonKey", "exportJsonKey", cardSetPath),
44949
- ...cardHtmlKeyField(cardSetConfig, "htmlKey"),
45883
+ ...cardMappingKeysField(
45884
+ cardSetConfig,
45885
+ cardSetConfig.mappingKeys,
45886
+ "jsonKey",
45887
+ "exportJsonKey",
45888
+ "htmlKey",
45889
+ cardSetPath
45890
+ ),
44950
45891
  sides
44951
45892
  }
44952
45893
  ]
@@ -44982,14 +45923,19 @@ var ConfigBuilder = class {
44982
45923
  ...t.max != null ? { max: t.max } : {},
44983
45924
  ...t.description ? { description: t.description } : {}
44984
45925
  };
44985
- if (Object.prototype.hasOwnProperty.call(t, "jsonKey")) {
44986
- ref.exportJsonKey = t.jsonKey;
45926
+ const record = t.mappingKeys ?? {};
45927
+ if (Object.prototype.hasOwnProperty.call(record, "json")) {
45928
+ ref.exportJsonKey = record.json;
44987
45929
  ref.hasExportJsonKey = true;
44988
45930
  }
44989
- if (Object.prototype.hasOwnProperty.call(t, "htmlKey")) {
44990
- ref.htmlKey = t.htmlKey;
45931
+ if (Object.prototype.hasOwnProperty.call(record, "html")) {
45932
+ ref.htmlKey = record.html;
44991
45933
  ref.hasHtmlKey = true;
44992
45934
  }
45935
+ const extras = Object.fromEntries(
45936
+ Object.entries(record).filter(([id]) => id !== "json" && id !== "html")
45937
+ );
45938
+ if (Object.keys(extras).length > 0) ref.extraKeys = extras;
44993
45939
  replacements.push(ref);
44994
45940
  }
44995
45941
  squashedGroups.set(groupKey, replacements);
@@ -45023,8 +45969,11 @@ var ConfigBuilder = class {
45023
45969
  pushOrReplace({
45024
45970
  type: "group",
45025
45971
  key: ref.key,
45026
- ...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
45027
- ...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
45972
+ ...mappingKeysField(
45973
+ ref.extraKeys,
45974
+ { value: ref.exportJsonKey, present: !!ref.hasExportJsonKey },
45975
+ { value: ref.htmlKey, present: !!ref.hasHtmlKey }
45976
+ ),
45028
45977
  ...ref.min != null ? { min: ref.min } : {},
45029
45978
  ...ref.max != null ? { max: ref.max } : {},
45030
45979
  ...ref.description ? { description: ref.description } : {}
@@ -45037,8 +45986,11 @@ var ConfigBuilder = class {
45037
45986
  pushOrReplace({
45038
45987
  type: "group",
45039
45988
  key: ref.key,
45040
- ...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
45041
- ...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
45989
+ ...mappingKeysField(
45990
+ ref.extraKeys,
45991
+ { value: ref.exportJsonKey, present: !!ref.hasExportJsonKey },
45992
+ { value: ref.htmlKey, present: !!ref.hasHtmlKey }
45993
+ ),
45042
45994
  ...ref.min != null ? { min: ref.min } : {},
45043
45995
  ...ref.max != null ? { max: ref.max } : {},
45044
45996
  ...ref.description ? { description: ref.description } : {}
@@ -45065,20 +46017,17 @@ var ConfigBuilder = class {
45065
46017
  description: b.description ?? "",
45066
46018
  since: resolvedBitConfig.since,
45067
46019
  deprecated: resolvedBitConfig.deprecated,
45068
- history: [
45069
- {
45070
- version: resolvedBitConfig.since,
45071
- changes: ["Initial version"]
45072
- }
45073
- ],
45074
- format: resolvedBitConfig.textFormatDefault ?? "bitmark--",
45075
- bodyRequired: resolvedBitConfig.bodyRequired ?? false,
45076
- bodyForbidden: !(resolvedBitConfig.bodyAllowed ?? true),
45077
- footerRequired: resolvedBitConfig.footerRequired ?? false,
45078
- footerForbidden: !(resolvedBitConfig.footerAllowed ?? true),
45079
- resourceAttachmentAllowed: resolvedBitConfig.resourceAttachmentAllowed ?? true,
46020
+ bodyFormat: resolvedBitConfig.textFormatDefault ?? "bitmark--",
46021
+ ...resolvedBitConfig.bodyRequired ? { bodyRequired: true } : {},
46022
+ ...resolvedBitConfig.bodyAllowed === false ? { bodyForbidden: true } : {},
46023
+ ...resolvedBitConfig.footerRequired ? { footerRequired: true } : {},
46024
+ ...resolvedBitConfig.footerAllowed === false ? { footerForbidden: true } : {},
46025
+ ...resolvedBitConfig.resourceAttachmentAllowed === false ? { resourceAttachmentAllowed: false } : {},
46026
+ // Bit-level named key mappings (element keys for markup import),
46027
+ // carried verbatim from the raw config.
46028
+ ...mappingKeysField(b.mappingKeys, { present: false }, { present: false }),
45080
46029
  tags: tags2,
45081
- ...cardRef ? { card: cardRef } : {}
46030
+ ...cardRef ? { cardSet: cardRef } : {}
45082
46031
  };
45083
46032
  const output = import_node_path3.default.join(outputFolderBits, `${b.bitType}.jsonc`);
45084
46033
  const str = JSON.stringify(bitJson, null, 2);
@@ -45106,14 +46055,7 @@ var ConfigBuilder = class {
45106
46055
  const bitJson = {
45107
46056
  name: groupKey,
45108
46057
  description: g.description ?? "",
45109
- since: "UNKNOWN",
45110
46058
  deprecated: g.deprecated,
45111
- history: [
45112
- {
45113
- version: "UNKNOWN",
45114
- changes: ["Initial version"]
45115
- }
45116
- ],
45117
46059
  tags: tags2
45118
46060
  // cards: [
45119
46061
  // {
@@ -45167,8 +46109,11 @@ var ConfigBuilder = class {
45167
46109
  tags2.push({
45168
46110
  type: "group",
45169
46111
  key: ref.key,
45170
- ...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
45171
- ...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
46112
+ ...mappingKeysField(
46113
+ ref.extraKeys,
46114
+ { value: ref.exportJsonKey, present: !!ref.hasExportJsonKey },
46115
+ { value: ref.htmlKey, present: !!ref.hasHtmlKey }
46116
+ ),
45172
46117
  ...ref.min != null ? { min: ref.min } : {},
45173
46118
  ...ref.max != null ? { max: ref.max } : {},
45174
46119
  ...ref.description ? { description: ref.description } : {}
@@ -45189,14 +46134,7 @@ var ConfigBuilder = class {
45189
46134
  const bitJson = {
45190
46135
  name: groupKey,
45191
46136
  description: b.description ?? "",
45192
- since: "UNKNOWN",
45193
46137
  deprecated: b.deprecated,
45194
- history: [
45195
- {
45196
- version: "UNKNOWN",
45197
- changes: ["Initial version"]
45198
- }
45199
- ],
45200
46138
  tags: tags2
45201
46139
  };
45202
46140
  const output = import_node_path3.default.join(outputFolderGroups, `${groupKey}.jsonc`);
@@ -45237,7 +46175,7 @@ var ConfigBuilder = class {
45237
46175
  validateConfigTree(outputFolder) {
45238
46176
  const errors = [];
45239
46177
  const outputFolderBits = import_node_path3.default.join(outputFolder, "bits");
45240
- const outputFolderGroups = import_node_path3.default.join(outputFolder, "partials");
46178
+ const outputFolderGroups = import_node_path3.default.join(outputFolder, "groups");
45241
46179
  const outputFolderCards = import_node_path3.default.join(outputFolder, "cards");
45242
46180
  const availableGroups = /* @__PURE__ */ new Set();
45243
46181
  if (import_fs_extra3.default.existsSync(outputFolderGroups)) {
@@ -45311,7 +46249,7 @@ var ConfigBuilder = class {
45311
46249
  const content = import_fs_extra3.default.readFileSync(filePath, "utf-8");
45312
46250
  const config = JSON.parse(content);
45313
46251
  if (config.tags && Array.isArray(config.tags)) {
45314
- checkTags(config.tags, `partials/${file}`, 15);
46252
+ checkTags(config.tags, `groups/${file}`, 15);
45315
46253
  }
45316
46254
  } catch (err) {
45317
46255
  errors.push(`Failed to parse ${file}: ${err}`);