@gmb/bitmark-parser-generator 5.37.0 → 5.38.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/cli/main.js CHANGED
@@ -1180,6 +1180,7 @@ ${this.cardSet.toString(opts)}`;
1180
1180
  }
1181
1181
  };
1182
1182
  var groupKeys = {
1183
+ group_accessibilityDecorative: "group_accessibilityDecorative",
1183
1184
  group_standardAllBits: "group_standardAllBits",
1184
1185
  group_standardItemLead: "group_standardItemLead",
1185
1186
  group_standardItemLeadInstructionHint: "group_standardItemLeadInstructionHint",
@@ -1242,6 +1243,8 @@ var groupKeys = {
1242
1243
  group_previewVideos: "group_previewVideos"
1243
1244
  };
1244
1245
  var propertyKeys = {
1246
+ property_accessibilityGroupTag: "@accessibilityGroupTag",
1247
+ property_accessibilityTag: "@accessibilityTag",
1245
1248
  property_action: "@action",
1246
1249
  property_activityType: "@activityType",
1247
1250
  property_additionalSolutions: "@additionalSolutions",
@@ -4423,6 +4426,7 @@ var CARDSETS = {
4423
4426
  };
4424
4427
 
4425
4428
  // src/config/raw/groups.ts
4429
+ var ACCESSIBILITY_TAG_VALUES = ["complex", "functional", "decorative", "standard"];
4426
4430
  var GROUPS = {
4427
4431
  [ConfigKey.group_standardAllBits]: {
4428
4432
  name: "Standard",
@@ -4529,7 +4533,8 @@ var GROUPS = {
4529
4533
  {
4530
4534
  key: ConfigKey.property_isCollapsible,
4531
4535
  description: "If true, the bit is collapsible",
4532
- format: TagFormat.boolean
4536
+ format: TagFormat.boolean,
4537
+ nullable: true
4533
4538
  },
4534
4539
  {
4535
4540
  key: ConfigKey.property_spansPageBreak,
@@ -4694,6 +4699,36 @@ var GROUPS = {
4694
4699
  }
4695
4700
  ]
4696
4701
  },
4702
+ {
4703
+ key: ConfigKey.property_accessibilityTag,
4704
+ description: "The accessibility classification(s) for the bit",
4705
+ format: TagFormat.enumeration,
4706
+ values: ACCESSIBILITY_TAG_VALUES,
4707
+ nullable: true,
4708
+ maxCount: Count.infinity
4709
+ },
4710
+ {
4711
+ key: ConfigKey.property_accessibilityGroupTag,
4712
+ jsonKey: "accessibilityGroupTag.name",
4713
+ // Entity-merge semantics, as for `@groupTag`: repeated
4714
+ // `[@accessibilityGroupTag: name]` occurrences with the same value fold
4715
+ // into one entry; chained `@accessibilityTag` children's arrays merge as sets.
4716
+ exportJsonKey: { accessibilityGroupTag: [{ "@id": "name", name: "$" }] },
4717
+ description: "The accessibility group tag(s) for the bit",
4718
+ format: TagFormat.plainText,
4719
+ maxCount: Count.infinity,
4720
+ chain: [
4721
+ {
4722
+ key: ConfigKey.property_accessibilityTag,
4723
+ exportJsonKey: { tags: ["$"] },
4724
+ description: "The accessibility classification(s) for the group",
4725
+ format: TagFormat.enumeration,
4726
+ values: ACCESSIBILITY_TAG_VALUES,
4727
+ nullable: true,
4728
+ maxCount: Count.infinity
4729
+ }
4730
+ ]
4731
+ },
4697
4732
  {
4698
4733
  key: ConfigKey.property_reviewTag,
4699
4734
  description: "The review tag(s) for the bit",
@@ -4824,6 +4859,37 @@ var GROUPS = {
4824
4859
  }
4825
4860
  ]
4826
4861
  },
4862
+ [ConfigKey.group_accessibilityDecorative]: {
4863
+ name: "Accessibility (decorative)",
4864
+ description: "Accessibility tags defaulting to a decorative image, for bits that are decorative by definition",
4865
+ type: GroupConfigType.standard,
4866
+ // Re-declares `@accessibilityGroupTag` (in full — tag hydration is last-wins
4867
+ // per config key, it does not merge) with the decorative defaults. The
4868
+ // standalone `@accessibilityTag` is deliberately NOT re-declared: the default
4869
+ // belongs to the group structure only.
4870
+ tags: [
4871
+ {
4872
+ key: ConfigKey.property_accessibilityGroupTag,
4873
+ jsonKey: "accessibilityGroupTag.name",
4874
+ exportJsonKey: { accessibilityGroupTag: [{ "@id": "name", name: "$" }] },
4875
+ description: "The accessibility group tag(s) for the bit",
4876
+ format: TagFormat.plainText,
4877
+ defaultValue: "image",
4878
+ maxCount: Count.infinity,
4879
+ chain: [
4880
+ {
4881
+ key: ConfigKey.property_accessibilityTag,
4882
+ exportJsonKey: { tags: ["$"] },
4883
+ description: "The accessibility classification(s) for the group",
4884
+ format: TagFormat.enumeration,
4885
+ values: ACCESSIBILITY_TAG_VALUES,
4886
+ defaultValue: "decorative",
4887
+ maxCount: Count.infinity
4888
+ }
4889
+ ]
4890
+ }
4891
+ ]
4892
+ },
4827
4893
  [ConfigKey.group_standardItemLead]: {
4828
4894
  type: GroupConfigType.standard,
4829
4895
  description: "Standard group for item, lead, page number, and margin number tags",
@@ -8727,6 +8793,12 @@ var BITS = {
8727
8793
  description: "The progress of the chapter, used for tracking reading progress",
8728
8794
  format: TagFormat.boolean,
8729
8795
  defaultValue: "true"
8796
+ },
8797
+ {
8798
+ key: ConfigKey.property_isCollapsible,
8799
+ description: "If true, the chapter is collapsible (always emitted; defaults false)",
8800
+ format: TagFormat.boolean,
8801
+ defaultValue: "false"
8730
8802
  }
8731
8803
  ]
8732
8804
  },
@@ -10136,7 +10208,9 @@ var BITS = {
10136
10208
  },
10137
10209
  [BitType.printPageBreak]: {
10138
10210
  since: "5.4.0",
10139
- baseBitType: BitType.separator,
10211
+ // Based on `article`, not `separator`: `separator` adds nothing over `article`,
10212
+ // and basing on it would inherit the decorative accessibility defaults.
10213
+ baseBitType: BitType.article,
10140
10214
  description: "Print page break bit, used to create page breaks for printing in articles or books"
10141
10215
  },
10142
10216
  [BitType.releaseNotesSummary]: {
@@ -10222,12 +10296,24 @@ var BITS = {
10222
10296
  [BitType.separator]: {
10223
10297
  since: "1.4.15",
10224
10298
  baseBitType: BitType.article,
10225
- description: "Separator bit, used to create visual separators in articles or books"
10299
+ description: "Separator bit, used to create visual separators in articles or books",
10300
+ tags: [
10301
+ {
10302
+ key: ConfigKey.group_accessibilityDecorative,
10303
+ description: "Accessibility tags, defaulting to a decorative image"
10304
+ }
10305
+ ]
10226
10306
  },
10227
10307
  [BitType.separatorAlt]: {
10228
10308
  since: "1.16.0",
10229
10309
  baseBitType: BitType.separator,
10230
- description: "Alternative separator bit, used to create visual separators in articles or books with alternative styling"
10310
+ description: "Alternative separator bit, used to create visual separators in articles or books with alternative styling",
10311
+ tags: [
10312
+ {
10313
+ key: ConfigKey.group_accessibilityDecorative,
10314
+ description: "Accessibility tags, defaulting to a decorative image"
10315
+ }
10316
+ ]
10231
10317
  },
10232
10318
  [BitType.sticker]: {
10233
10319
  since: "1.5.28",
@@ -11463,7 +11549,13 @@ var BITS = {
11463
11549
  [BitType.imageMood]: {
11464
11550
  since: "1.3.0",
11465
11551
  baseBitType: BitType.image,
11466
- description: "Image mood bit, used to create mood images in articles or books"
11552
+ description: "Image mood bit, used to create mood images in articles or books",
11553
+ tags: [
11554
+ {
11555
+ key: ConfigKey.group_accessibilityDecorative,
11556
+ description: "Accessibility tags, defaulting to a decorative image"
11557
+ }
11558
+ ]
11467
11559
  },
11468
11560
  [BitType.imagePortrait]: {
11469
11561
  since: "1.3.0",
@@ -11483,6 +11575,10 @@ var BITS = {
11483
11575
  {
11484
11576
  key: ConfigKey.group_imageNoZoom,
11485
11577
  description: "Image no zoom tags for images, used to define whether images should have zoom functionality"
11578
+ },
11579
+ {
11580
+ key: ConfigKey.group_accessibilityDecorative,
11581
+ description: "Accessibility tags, defaulting to a decorative image"
11486
11582
  }
11487
11583
  ],
11488
11584
  resourceAttachmentAllowed: false
@@ -11490,7 +11586,13 @@ var BITS = {
11490
11586
  [BitType.imageSeparatorAlt]: {
11491
11587
  since: "1.16.0",
11492
11588
  baseBitType: BitType.imageSeparator,
11493
- description: "Alternative image separator bit, used to create alternative separators in articles or books"
11589
+ description: "Alternative image separator bit, used to create alternative separators in articles or books",
11590
+ tags: [
11591
+ {
11592
+ key: ConfigKey.group_accessibilityDecorative,
11593
+ description: "Accessibility tags, defaulting to a decorative image"
11594
+ }
11595
+ ]
11494
11596
  },
11495
11597
  [BitType.imageScreenshot]: {
11496
11598
  since: "1.3.0",
@@ -14769,7 +14871,7 @@ var instance2 = new Config();
14769
14871
  // src/generated/package_info.ts
14770
14872
  var PACKAGE_INFO = {
14771
14873
  "name": "@gmb/bitmark-parser-generator",
14772
- "version": "5.37.0",
14874
+ "version": "5.38.0",
14773
14875
  "license": "ISC"};
14774
14876
  var Environment = {
14775
14877
  unknown: "",
@@ -15091,6 +15193,10 @@ var NodeType = {
15091
15193
  // unknown
15092
15194
  __isDefaultExample: "__isDefaultExample",
15093
15195
  __typeAlias: "__typeAlias",
15196
+ accessibilityGroupTag: "accessibilityGroupTag",
15197
+ accessibilityGroupTagValue: "accessibilityGroupTagValue",
15198
+ accessibilityTag: "accessibilityTag",
15199
+ accessibilityTagValue: "accessibilityTagValue",
15094
15200
  action: "action",
15095
15201
  actionValue: "actionValue",
15096
15202
  activityType: "activityType",
@@ -27237,6 +27343,12 @@ var BaseBuilder = class {
27237
27343
  case TagFormat.plainText:
27238
27344
  if (instance6.asNumber(v) != null) v = `${v}`;
27239
27345
  return stringUtils.isString(v) ? stringUtils.trimmedString(v) : void 0;
27346
+ case TagFormat.enumeration: {
27347
+ if (instance6.asNumber(v) != null) v = `${v}`;
27348
+ const enumValue = stringUtils.isString(v) ? stringUtils.trimmedString(v) : void 0;
27349
+ if (enumValue == null || enumValue === "") return propertyConfig?.defaultValue ?? "";
27350
+ return enumValue;
27351
+ }
27240
27352
  case TagFormat.number:
27241
27353
  return instance6.asNumber(v);
27242
27354
  case TagFormat.boolean:
@@ -28796,6 +28908,10 @@ var Builder = class extends BaseBuilder {
28796
28908
  const bitType = data.bitType;
28797
28909
  const bitConfig = instance2.getBitConfig(bitType);
28798
28910
  const isCollapsibleDefaultsTrue = bitConfig.tags[ConfigKey.property_isCollapsible]?.defaultValue === "true";
28911
+ const accessibilityGroupTag = this.resolveAccessibilityGroupTag(
28912
+ bitConfig,
28913
+ data.accessibilityGroupTag
28914
+ );
28799
28915
  const deprecatedTextFormat = Enum(DeprecatedTextFormat).fromValue(data.textFormat);
28800
28916
  let textFormat = Enum(TextFormat).fromValue(data.textFormat) ?? bitConfig.textFormatDefault;
28801
28917
  if (deprecatedTextFormat === DeprecatedTextFormat.bitmarkMinusMinus) {
@@ -29031,6 +29147,13 @@ var Builder = class extends BaseBuilder {
29031
29147
  slug: this.toAstProperty(bitType, ConfigKey.property_slug, data.slug, options),
29032
29148
  tag: this.toAstProperty(bitType, ConfigKey.property_tag, data.tag, options),
29033
29149
  groupTag: this.buildGroupTags(context, data.groupTag),
29150
+ accessibilityTag: this.toAstProperty(
29151
+ bitType,
29152
+ ConfigKey.property_accessibilityTag,
29153
+ data.accessibilityTag,
29154
+ options
29155
+ ),
29156
+ accessibilityGroupTag: this.buildGroupTags(context, accessibilityGroupTag),
29034
29157
  reviewTag: this.toAstProperty(bitType, ConfigKey.property_reviewTag, data.reviewTag, options),
29035
29158
  reviewerTag: this.toAstProperty(
29036
29159
  bitType,
@@ -30083,6 +30206,26 @@ var Builder = class extends BaseBuilder {
30083
30206
  });
30084
30207
  return node;
30085
30208
  }
30209
+ /**
30210
+ * Resolve the accessibilityGroupTag data, materialising the bit type's default when absent.
30211
+ *
30212
+ * PLAN-019: `group_accessibilityDecorative` re-declares `@accessibilityGroupTag` with a
30213
+ * `defaultValue`, and its chained `@accessibilityTag` likewise. When the bit carries no
30214
+ * authored value, synthesize the default group so it reaches both generators. An authored
30215
+ * value always wins.
30216
+ *
30217
+ * @param bitConfig - the resolved config for the bit
30218
+ * @param data - authored data for the node, if any
30219
+ * @returns
30220
+ */
30221
+ resolveAccessibilityGroupTag(bitConfig, data) {
30222
+ if (data != null && (!Array.isArray(data) || data.length > 0)) return data;
30223
+ const groupConfig = bitConfig.tags[ConfigKey.property_accessibilityGroupTag];
30224
+ const name = groupConfig?.defaultValue;
30225
+ if (name == null) return data;
30226
+ const tag = groupConfig?.chain?.[ConfigKey.property_accessibilityTag]?.defaultValue;
30227
+ return [{ name, tags: tag != null ? [tag] : [] }];
30228
+ }
30086
30229
  /**
30087
30230
  * Build groupTag[] node
30088
30231
  *
@@ -32152,6 +32295,29 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
32152
32295
  }
32153
32296
  return false;
32154
32297
  }
32298
+ // bitmarkAst -> bits -> bitsValue -> accessibilityGroupTag
32299
+ enter_accessibilityGroupTag(node, route) {
32300
+ const accessibilityGroupTag = node.value;
32301
+ const parent = this.getParentNode(route);
32302
+ if (parent?.key !== NodeType.bitsValue) return true;
32303
+ for (const gt of accessibilityGroupTag) {
32304
+ const { name, tags: tags2 } = gt;
32305
+ this.writeProperty("accessibilityGroupTag", name, route, {
32306
+ format: TagFormat.plainText,
32307
+ writeEmpty: true
32308
+ });
32309
+ if (tags2 && tags2.length > 0) {
32310
+ for (const t of tags2) {
32311
+ this.writeProperty("accessibilityTag", t, route, {
32312
+ format: TagFormat.plainText,
32313
+ writeEmpty: true,
32314
+ forceChain: true
32315
+ });
32316
+ }
32317
+ }
32318
+ }
32319
+ return false;
32320
+ }
32155
32321
  // bitmarkAst -> bits -> bitsValue -> labelTrue / labelFalse
32156
32322
  leaf_labelTrue(node, route) {
32157
32323
  const value = node.value;
@@ -34898,10 +35064,14 @@ var JsonGenerator = class extends AstWalkerGenerator {
34898
35064
  }
34899
35065
  // bitmarkAst -> bits -> bitsValue -> isCollapsible
34900
35066
  /**
34901
- * PLAN-016: `isCollapsible` is emitted only when true. `false` is the implied
34902
- * default for every bit, so it is never written to the JSON — an absent key
34903
- * means the bit's configured default (`true` for the deprecated
34904
- * `*-collapsible` bit types, `false` everywhere else).
35067
+ * `isCollapsible` is emitted only when explicitly set on the bit — an explicit
35068
+ * `true`/`false` in the source is emitted as-is, and an absent tag yields no
35069
+ * JSON key (the tag is nullable in the config: no default, unset when absent).
35070
+ *
35071
+ * Two exceptions always carry a value: chapter bits default to `false`
35072
+ * (`defaultValue: 'false'` in the bit config, applied in `cleanBitJson()`),
35073
+ * and the deprecated `*-collapsible` bit types default to `true` (materialised
35074
+ * into the AST by the Builder).
34905
35075
  *
34906
35076
  * Defining these handlers suppresses the generic property handlers that
34907
35077
  * `generatePropertyHandlers()` would otherwise install for this tag.
@@ -34909,7 +35079,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
34909
35079
  leaf_isCollapsible(node, route) {
34910
35080
  const parent = this.getParentNode(route);
34911
35081
  if (parent?.key !== NodeType.bitsValue) return false;
34912
- if (node.value === true) this.bitJson.isCollapsible = true;
35082
+ if (node.value != null) this.bitJson.isCollapsible = node.value === true;
34913
35083
  return false;
34914
35084
  }
34915
35085
  enter_isCollapsible(node, route) {
@@ -35786,6 +35956,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
35786
35956
  if (instance2.isOfBitType(bitType, BitType.chapter)) {
35787
35957
  if (bitJson.toc == null) bitJson.toc = true;
35788
35958
  if (bitJson.progress == null) bitJson.progress = true;
35959
+ if (bitJson.isCollapsible == null) bitJson.isCollapsible = false;
35789
35960
  if (bitJson.level == null) bitJson.level = 1;
35790
35961
  if (bitJson.body == null) bitJson.body = this.bodyDefault;
35791
35962
  }
@@ -39212,19 +39383,25 @@ function handleStandardStringExample(context, _content, example, target) {
39212
39383
  }
39213
39384
 
39214
39385
  // src/parser/bitmark/peg/contentProcessors/GroupTagChainContentProcessor.ts
39215
- function groupTagChainContentProcessor(context, _contentDepth, tagsConfig, content, target) {
39386
+ var GROUP_TAG = { groupKey: "groupTag", memberKey: "tag" };
39387
+ var ACCESSIBILITY_GROUP_TAG = {
39388
+ groupKey: "accessibilityGroupTag",
39389
+ memberKey: "accessibilityTag"
39390
+ };
39391
+ function groupTagChainContentProcessor(context, _contentDepth, tagsConfig, content, target, keys = GROUP_TAG) {
39216
39392
  const { value } = content;
39217
- if (context.DEBUG_CHAIN_CONTENT) context.debugPrint("groupTag content", content);
39393
+ const { groupKey, memberKey } = keys;
39394
+ if (context.DEBUG_CHAIN_CONTENT) context.debugPrint(`${groupKey} content`, content);
39218
39395
  const tags2 = context.bitContentProcessor(ContentDepth.Chain, tagsConfig, content.chain);
39219
- if (context.DEBUG_CHAIN_TAGS) context.debugPrint("groupTag TAGS", tags2);
39220
- const { tag } = tags2;
39396
+ if (context.DEBUG_CHAIN_TAGS) context.debugPrint(`${groupKey} TAGS`, tags2);
39397
+ const memberTags = tags2[memberKey];
39221
39398
  const name = stringUtils.trimmedString(value) ?? "";
39222
39399
  const node = {
39223
39400
  name,
39224
- tags: tag ?? []
39401
+ tags: memberTags ?? []
39225
39402
  };
39226
- if (!Array.isArray(target.groupTag)) target.groupTag = [];
39227
- target.groupTag.push(node);
39403
+ if (!Array.isArray(target[groupKey])) target[groupKey] = [];
39404
+ target[groupKey].push(node);
39228
39405
  }
39229
39406
  function imageSourceChainContentProcessor(context, contentDepth, tagsConfig, content, target) {
39230
39407
  if (contentDepth === ContentDepth.Chain) {
@@ -39437,6 +39614,16 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
39437
39614
  } else if (configKey === ConfigKey.property_groupTag) {
39438
39615
  groupTagChainContentProcessor(context, contentDepth, propertyConfig.chain, content, target);
39439
39616
  return;
39617
+ } else if (configKey === ConfigKey.property_accessibilityGroupTag) {
39618
+ groupTagChainContentProcessor(
39619
+ context,
39620
+ contentDepth,
39621
+ propertyConfig.chain,
39622
+ content,
39623
+ target,
39624
+ ACCESSIBILITY_GROUP_TAG
39625
+ );
39626
+ return;
39440
39627
  } else if (configKey === ConfigKey.property_ratingLevelStart || configKey === ConfigKey.property_ratingLevelEnd) {
39441
39628
  ratingLevelChainContentProcessor(
39442
39629
  context,
@@ -39489,6 +39676,23 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
39489
39676
  location: TextLocation.tag
39490
39677
  }
39491
39678
  );
39679
+ case TagFormat.enumeration: {
39680
+ const enumValue = instance3.unbreakscape(
39681
+ stringUtils.isString(v2) ? stringUtils.trimmedString(v2) : void 0,
39682
+ {
39683
+ format: TextFormat.plainText,
39684
+ location: TextLocation.tag
39685
+ }
39686
+ );
39687
+ if (enumValue == null || enumValue === "") return c.defaultValue ?? "";
39688
+ if (c.values && !c.values.includes(enumValue)) {
39689
+ context.addWarning(
39690
+ `Invalid value '${enumValue}' for property [@${tag}]. Valid values: ${c.values.join(" | ")}`,
39691
+ content
39692
+ );
39693
+ }
39694
+ return enumValue;
39695
+ }
39492
39696
  case TagFormat.number:
39493
39697
  return instance6.asNumber(
39494
39698
  instance3.unbreakscape(v2, {
@@ -45140,6 +45344,8 @@ var ConfigBuilder = class {
45140
45344
  format = "number";
45141
45345
  } else if (tag.format === TagFormat.coordinates) {
45142
45346
  format = "coordinates";
45347
+ } else if (tag.format === TagFormat.enumeration) {
45348
+ format = "enum";
45143
45349
  }
45144
45350
  } else if (tagType === BitTagConfigKeyType.resource) {
45145
45351
  format = "string";
@@ -45204,6 +45410,7 @@ var ConfigBuilder = class {
45204
45410
  { value: tag.htmlKey, present: hasHtml }
45205
45411
  ),
45206
45412
  ...format && format !== "string" ? { format } : {},
45413
+ ...tag.values != null ? { values: tag.values } : {},
45207
45414
  ...tag.defaultValue != null ? { default: tag.defaultValue } : {},
45208
45415
  ...tag.nullable ? { nullable: true } : {},
45209
45416
  ...tag.minCount != null && tag.minCount !== 0 ? { min: tag.minCount } : {},