@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/index.cjs CHANGED
@@ -1277,6 +1277,7 @@ var import_superenum14 = require("@ncoderz/superenum");
1277
1277
  // src/model/enum/GroupKey.ts
1278
1278
  var import_superenum10 = require("@ncoderz/superenum");
1279
1279
  var groupKeys = {
1280
+ group_accessibilityDecorative: "group_accessibilityDecorative",
1280
1281
  group_standardAllBits: "group_standardAllBits",
1281
1282
  group_standardItemLead: "group_standardItemLead",
1282
1283
  group_standardItemLeadInstructionHint: "group_standardItemLeadInstructionHint",
@@ -1342,6 +1343,8 @@ var groupKeys = {
1342
1343
  // src/model/enum/PropertyKey.ts
1343
1344
  var import_superenum11 = require("@ncoderz/superenum");
1344
1345
  var propertyKeys = {
1346
+ property_accessibilityGroupTag: "@accessibilityGroupTag",
1347
+ property_accessibilityTag: "@accessibilityTag",
1345
1348
  property_action: "@action",
1346
1349
  property_activityType: "@activityType",
1347
1350
  property_additionalSolutions: "@additionalSolutions",
@@ -4532,6 +4535,7 @@ var CARDSETS = {
4532
4535
  };
4533
4536
 
4534
4537
  // src/config/raw/groups.ts
4538
+ var ACCESSIBILITY_TAG_VALUES = ["complex", "functional", "decorative", "standard"];
4535
4539
  var GROUPS = {
4536
4540
  [ConfigKey.group_standardAllBits]: {
4537
4541
  name: "Standard",
@@ -4638,7 +4642,8 @@ var GROUPS = {
4638
4642
  {
4639
4643
  key: ConfigKey.property_isCollapsible,
4640
4644
  description: "If true, the bit is collapsible",
4641
- format: TagFormat.boolean
4645
+ format: TagFormat.boolean,
4646
+ nullable: true
4642
4647
  },
4643
4648
  {
4644
4649
  key: ConfigKey.property_spansPageBreak,
@@ -4803,6 +4808,36 @@ var GROUPS = {
4803
4808
  }
4804
4809
  ]
4805
4810
  },
4811
+ {
4812
+ key: ConfigKey.property_accessibilityTag,
4813
+ description: "The accessibility classification(s) for the bit",
4814
+ format: TagFormat.enumeration,
4815
+ values: ACCESSIBILITY_TAG_VALUES,
4816
+ nullable: true,
4817
+ maxCount: Count.infinity
4818
+ },
4819
+ {
4820
+ key: ConfigKey.property_accessibilityGroupTag,
4821
+ jsonKey: "accessibilityGroupTag.name",
4822
+ // Entity-merge semantics, as for `@groupTag`: repeated
4823
+ // `[@accessibilityGroupTag: name]` occurrences with the same value fold
4824
+ // into one entry; chained `@accessibilityTag` children's arrays merge as sets.
4825
+ exportJsonKey: { accessibilityGroupTag: [{ "@id": "name", name: "$" }] },
4826
+ description: "The accessibility group tag(s) for the bit",
4827
+ format: TagFormat.plainText,
4828
+ maxCount: Count.infinity,
4829
+ chain: [
4830
+ {
4831
+ key: ConfigKey.property_accessibilityTag,
4832
+ exportJsonKey: { tags: ["$"] },
4833
+ description: "The accessibility classification(s) for the group",
4834
+ format: TagFormat.enumeration,
4835
+ values: ACCESSIBILITY_TAG_VALUES,
4836
+ nullable: true,
4837
+ maxCount: Count.infinity
4838
+ }
4839
+ ]
4840
+ },
4806
4841
  {
4807
4842
  key: ConfigKey.property_reviewTag,
4808
4843
  description: "The review tag(s) for the bit",
@@ -4933,6 +4968,37 @@ var GROUPS = {
4933
4968
  }
4934
4969
  ]
4935
4970
  },
4971
+ [ConfigKey.group_accessibilityDecorative]: {
4972
+ name: "Accessibility (decorative)",
4973
+ description: "Accessibility tags defaulting to a decorative image, for bits that are decorative by definition",
4974
+ type: GroupConfigType.standard,
4975
+ // Re-declares `@accessibilityGroupTag` (in full — tag hydration is last-wins
4976
+ // per config key, it does not merge) with the decorative defaults. The
4977
+ // standalone `@accessibilityTag` is deliberately NOT re-declared: the default
4978
+ // belongs to the group structure only.
4979
+ tags: [
4980
+ {
4981
+ key: ConfigKey.property_accessibilityGroupTag,
4982
+ jsonKey: "accessibilityGroupTag.name",
4983
+ exportJsonKey: { accessibilityGroupTag: [{ "@id": "name", name: "$" }] },
4984
+ description: "The accessibility group tag(s) for the bit",
4985
+ format: TagFormat.plainText,
4986
+ defaultValue: "image",
4987
+ maxCount: Count.infinity,
4988
+ chain: [
4989
+ {
4990
+ key: ConfigKey.property_accessibilityTag,
4991
+ exportJsonKey: { tags: ["$"] },
4992
+ description: "The accessibility classification(s) for the group",
4993
+ format: TagFormat.enumeration,
4994
+ values: ACCESSIBILITY_TAG_VALUES,
4995
+ defaultValue: "decorative",
4996
+ maxCount: Count.infinity
4997
+ }
4998
+ ]
4999
+ }
5000
+ ]
5001
+ },
4936
5002
  [ConfigKey.group_standardItemLead]: {
4937
5003
  type: GroupConfigType.standard,
4938
5004
  description: "Standard group for item, lead, page number, and margin number tags",
@@ -8836,6 +8902,12 @@ var BITS = {
8836
8902
  description: "The progress of the chapter, used for tracking reading progress",
8837
8903
  format: TagFormat.boolean,
8838
8904
  defaultValue: "true"
8905
+ },
8906
+ {
8907
+ key: ConfigKey.property_isCollapsible,
8908
+ description: "If true, the chapter is collapsible (always emitted; defaults false)",
8909
+ format: TagFormat.boolean,
8910
+ defaultValue: "false"
8839
8911
  }
8840
8912
  ]
8841
8913
  },
@@ -10245,7 +10317,9 @@ var BITS = {
10245
10317
  },
10246
10318
  [BitType.printPageBreak]: {
10247
10319
  since: "5.4.0",
10248
- baseBitType: BitType.separator,
10320
+ // Based on `article`, not `separator`: `separator` adds nothing over `article`,
10321
+ // and basing on it would inherit the decorative accessibility defaults.
10322
+ baseBitType: BitType.article,
10249
10323
  description: "Print page break bit, used to create page breaks for printing in articles or books"
10250
10324
  },
10251
10325
  [BitType.releaseNotesSummary]: {
@@ -10331,12 +10405,24 @@ var BITS = {
10331
10405
  [BitType.separator]: {
10332
10406
  since: "1.4.15",
10333
10407
  baseBitType: BitType.article,
10334
- description: "Separator bit, used to create visual separators in articles or books"
10408
+ description: "Separator bit, used to create visual separators in articles or books",
10409
+ tags: [
10410
+ {
10411
+ key: ConfigKey.group_accessibilityDecorative,
10412
+ description: "Accessibility tags, defaulting to a decorative image"
10413
+ }
10414
+ ]
10335
10415
  },
10336
10416
  [BitType.separatorAlt]: {
10337
10417
  since: "1.16.0",
10338
10418
  baseBitType: BitType.separator,
10339
- description: "Alternative separator bit, used to create visual separators in articles or books with alternative styling"
10419
+ description: "Alternative separator bit, used to create visual separators in articles or books with alternative styling",
10420
+ tags: [
10421
+ {
10422
+ key: ConfigKey.group_accessibilityDecorative,
10423
+ description: "Accessibility tags, defaulting to a decorative image"
10424
+ }
10425
+ ]
10340
10426
  },
10341
10427
  [BitType.sticker]: {
10342
10428
  since: "1.5.28",
@@ -11572,7 +11658,13 @@ var BITS = {
11572
11658
  [BitType.imageMood]: {
11573
11659
  since: "1.3.0",
11574
11660
  baseBitType: BitType.image,
11575
- description: "Image mood bit, used to create mood images in articles or books"
11661
+ description: "Image mood bit, used to create mood images in articles or books",
11662
+ tags: [
11663
+ {
11664
+ key: ConfigKey.group_accessibilityDecorative,
11665
+ description: "Accessibility tags, defaulting to a decorative image"
11666
+ }
11667
+ ]
11576
11668
  },
11577
11669
  [BitType.imagePortrait]: {
11578
11670
  since: "1.3.0",
@@ -11592,6 +11684,10 @@ var BITS = {
11592
11684
  {
11593
11685
  key: ConfigKey.group_imageNoZoom,
11594
11686
  description: "Image no zoom tags for images, used to define whether images should have zoom functionality"
11687
+ },
11688
+ {
11689
+ key: ConfigKey.group_accessibilityDecorative,
11690
+ description: "Accessibility tags, defaulting to a decorative image"
11595
11691
  }
11596
11692
  ],
11597
11693
  resourceAttachmentAllowed: false
@@ -11599,7 +11695,13 @@ var BITS = {
11599
11695
  [BitType.imageSeparatorAlt]: {
11600
11696
  since: "1.16.0",
11601
11697
  baseBitType: BitType.imageSeparator,
11602
- description: "Alternative image separator bit, used to create alternative separators in articles or books"
11698
+ description: "Alternative image separator bit, used to create alternative separators in articles or books",
11699
+ tags: [
11700
+ {
11701
+ key: ConfigKey.group_accessibilityDecorative,
11702
+ description: "Accessibility tags, defaulting to a decorative image"
11703
+ }
11704
+ ]
11603
11705
  },
11604
11706
  [BitType.imageScreenshot]: {
11605
11707
  since: "1.3.0",
@@ -14878,7 +14980,7 @@ var instance2 = new Config();
14878
14980
  // src/generated/package_info.ts
14879
14981
  var PACKAGE_INFO = {
14880
14982
  "name": "@gmb/bitmark-parser-generator",
14881
- "version": "5.37.0",
14983
+ "version": "5.38.0",
14882
14984
  "author": "Get More Brain Ltd",
14883
14985
  "license": "ISC",
14884
14986
  "description": "A bitmark parser and generator using Peggy.js"
@@ -15232,6 +15334,10 @@ var NodeType = {
15232
15334
  // unknown
15233
15335
  __isDefaultExample: "__isDefaultExample",
15234
15336
  __typeAlias: "__typeAlias",
15337
+ accessibilityGroupTag: "accessibilityGroupTag",
15338
+ accessibilityGroupTagValue: "accessibilityGroupTagValue",
15339
+ accessibilityTag: "accessibilityTag",
15340
+ accessibilityTagValue: "accessibilityTagValue",
15235
15341
  action: "action",
15236
15342
  actionValue: "actionValue",
15237
15343
  activityType: "activityType",
@@ -27556,6 +27662,12 @@ var BaseBuilder = class {
27556
27662
  case TagFormat.plainText:
27557
27663
  if (instance6.asNumber(v) != null) v = `${v}`;
27558
27664
  return stringUtils.isString(v) ? stringUtils.trimmedString(v) : void 0;
27665
+ case TagFormat.enumeration: {
27666
+ if (instance6.asNumber(v) != null) v = `${v}`;
27667
+ const enumValue = stringUtils.isString(v) ? stringUtils.trimmedString(v) : void 0;
27668
+ if (enumValue == null || enumValue === "") return propertyConfig?.defaultValue ?? "";
27669
+ return enumValue;
27670
+ }
27559
27671
  case TagFormat.number:
27560
27672
  return instance6.asNumber(v);
27561
27673
  case TagFormat.boolean:
@@ -29122,6 +29234,10 @@ var Builder = class extends BaseBuilder {
29122
29234
  const bitType = data.bitType;
29123
29235
  const bitConfig = instance2.getBitConfig(bitType);
29124
29236
  const isCollapsibleDefaultsTrue = bitConfig.tags[ConfigKey.property_isCollapsible]?.defaultValue === "true";
29237
+ const accessibilityGroupTag = this.resolveAccessibilityGroupTag(
29238
+ bitConfig,
29239
+ data.accessibilityGroupTag
29240
+ );
29125
29241
  const deprecatedTextFormat = (0, import_superenum30.Enum)(DeprecatedTextFormat).fromValue(data.textFormat);
29126
29242
  let textFormat = (0, import_superenum30.Enum)(TextFormat).fromValue(data.textFormat) ?? bitConfig.textFormatDefault;
29127
29243
  if (deprecatedTextFormat === DeprecatedTextFormat.bitmarkMinusMinus) {
@@ -29357,6 +29473,13 @@ var Builder = class extends BaseBuilder {
29357
29473
  slug: this.toAstProperty(bitType, ConfigKey.property_slug, data.slug, options),
29358
29474
  tag: this.toAstProperty(bitType, ConfigKey.property_tag, data.tag, options),
29359
29475
  groupTag: this.buildGroupTags(context, data.groupTag),
29476
+ accessibilityTag: this.toAstProperty(
29477
+ bitType,
29478
+ ConfigKey.property_accessibilityTag,
29479
+ data.accessibilityTag,
29480
+ options
29481
+ ),
29482
+ accessibilityGroupTag: this.buildGroupTags(context, accessibilityGroupTag),
29360
29483
  reviewTag: this.toAstProperty(bitType, ConfigKey.property_reviewTag, data.reviewTag, options),
29361
29484
  reviewerTag: this.toAstProperty(
29362
29485
  bitType,
@@ -30409,6 +30532,26 @@ var Builder = class extends BaseBuilder {
30409
30532
  });
30410
30533
  return node;
30411
30534
  }
30535
+ /**
30536
+ * Resolve the accessibilityGroupTag data, materialising the bit type's default when absent.
30537
+ *
30538
+ * PLAN-019: `group_accessibilityDecorative` re-declares `@accessibilityGroupTag` with a
30539
+ * `defaultValue`, and its chained `@accessibilityTag` likewise. When the bit carries no
30540
+ * authored value, synthesize the default group so it reaches both generators. An authored
30541
+ * value always wins.
30542
+ *
30543
+ * @param bitConfig - the resolved config for the bit
30544
+ * @param data - authored data for the node, if any
30545
+ * @returns
30546
+ */
30547
+ resolveAccessibilityGroupTag(bitConfig, data) {
30548
+ if (data != null && (!Array.isArray(data) || data.length > 0)) return data;
30549
+ const groupConfig = bitConfig.tags[ConfigKey.property_accessibilityGroupTag];
30550
+ const name = groupConfig?.defaultValue;
30551
+ if (name == null) return data;
30552
+ const tag = groupConfig?.chain?.[ConfigKey.property_accessibilityTag]?.defaultValue;
30553
+ return [{ name, tags: tag != null ? [tag] : [] }];
30554
+ }
30412
30555
  /**
30413
30556
  * Build groupTag[] node
30414
30557
  *
@@ -32491,6 +32634,29 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
32491
32634
  }
32492
32635
  return false;
32493
32636
  }
32637
+ // bitmarkAst -> bits -> bitsValue -> accessibilityGroupTag
32638
+ enter_accessibilityGroupTag(node, route) {
32639
+ const accessibilityGroupTag = node.value;
32640
+ const parent = this.getParentNode(route);
32641
+ if (parent?.key !== NodeType.bitsValue) return true;
32642
+ for (const gt of accessibilityGroupTag) {
32643
+ const { name, tags: tags2 } = gt;
32644
+ this.writeProperty("accessibilityGroupTag", name, route, {
32645
+ format: TagFormat.plainText,
32646
+ writeEmpty: true
32647
+ });
32648
+ if (tags2 && tags2.length > 0) {
32649
+ for (const t of tags2) {
32650
+ this.writeProperty("accessibilityTag", t, route, {
32651
+ format: TagFormat.plainText,
32652
+ writeEmpty: true,
32653
+ forceChain: true
32654
+ });
32655
+ }
32656
+ }
32657
+ }
32658
+ return false;
32659
+ }
32494
32660
  // bitmarkAst -> bits -> bitsValue -> labelTrue / labelFalse
32495
32661
  leaf_labelTrue(node, route) {
32496
32662
  const value = node.value;
@@ -35249,10 +35415,14 @@ var JsonGenerator = class extends AstWalkerGenerator {
35249
35415
  }
35250
35416
  // bitmarkAst -> bits -> bitsValue -> isCollapsible
35251
35417
  /**
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).
35418
+ * `isCollapsible` is emitted only when explicitly set on the bit — an explicit
35419
+ * `true`/`false` in the source is emitted as-is, and an absent tag yields no
35420
+ * JSON key (the tag is nullable in the config: no default, unset when absent).
35421
+ *
35422
+ * Two exceptions always carry a value: chapter bits default to `false`
35423
+ * (`defaultValue: 'false'` in the bit config, applied in `cleanBitJson()`),
35424
+ * and the deprecated `*-collapsible` bit types default to `true` (materialised
35425
+ * into the AST by the Builder).
35256
35426
  *
35257
35427
  * Defining these handlers suppresses the generic property handlers that
35258
35428
  * `generatePropertyHandlers()` would otherwise install for this tag.
@@ -35260,7 +35430,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
35260
35430
  leaf_isCollapsible(node, route) {
35261
35431
  const parent = this.getParentNode(route);
35262
35432
  if (parent?.key !== NodeType.bitsValue) return false;
35263
- if (node.value === true) this.bitJson.isCollapsible = true;
35433
+ if (node.value != null) this.bitJson.isCollapsible = node.value === true;
35264
35434
  return false;
35265
35435
  }
35266
35436
  enter_isCollapsible(node, route) {
@@ -36139,6 +36309,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
36139
36309
  if (instance2.isOfBitType(bitType, BitType.chapter)) {
36140
36310
  if (bitJson.toc == null) bitJson.toc = true;
36141
36311
  if (bitJson.progress == null) bitJson.progress = true;
36312
+ if (bitJson.isCollapsible == null) bitJson.isCollapsible = false;
36142
36313
  if (bitJson.level == null) bitJson.level = 1;
36143
36314
  if (bitJson.body == null) bitJson.body = this.bodyDefault;
36144
36315
  }
@@ -39653,19 +39824,25 @@ function handleStandardStringExample(context, _content, example, target) {
39653
39824
  }
39654
39825
 
39655
39826
  // src/parser/bitmark/peg/contentProcessors/GroupTagChainContentProcessor.ts
39656
- function groupTagChainContentProcessor(context, _contentDepth, tagsConfig, content, target) {
39827
+ var GROUP_TAG = { groupKey: "groupTag", memberKey: "tag" };
39828
+ var ACCESSIBILITY_GROUP_TAG = {
39829
+ groupKey: "accessibilityGroupTag",
39830
+ memberKey: "accessibilityTag"
39831
+ };
39832
+ function groupTagChainContentProcessor(context, _contentDepth, tagsConfig, content, target, keys = GROUP_TAG) {
39657
39833
  const { value } = content;
39658
- if (context.DEBUG_CHAIN_CONTENT) context.debugPrint("groupTag content", content);
39834
+ const { groupKey, memberKey } = keys;
39835
+ if (context.DEBUG_CHAIN_CONTENT) context.debugPrint(`${groupKey} content`, content);
39659
39836
  const tags2 = context.bitContentProcessor(ContentDepth.Chain, tagsConfig, content.chain);
39660
- if (context.DEBUG_CHAIN_TAGS) context.debugPrint("groupTag TAGS", tags2);
39661
- const { tag } = tags2;
39837
+ if (context.DEBUG_CHAIN_TAGS) context.debugPrint(`${groupKey} TAGS`, tags2);
39838
+ const memberTags = tags2[memberKey];
39662
39839
  const name = stringUtils.trimmedString(value) ?? "";
39663
39840
  const node = {
39664
39841
  name,
39665
- tags: tag ?? []
39842
+ tags: memberTags ?? []
39666
39843
  };
39667
- if (!Array.isArray(target.groupTag)) target.groupTag = [];
39668
- target.groupTag.push(node);
39844
+ if (!Array.isArray(target[groupKey])) target[groupKey] = [];
39845
+ target[groupKey].push(node);
39669
39846
  }
39670
39847
 
39671
39848
  // src/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.ts
@@ -39885,6 +40062,16 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
39885
40062
  } else if (configKey === ConfigKey.property_groupTag) {
39886
40063
  groupTagChainContentProcessor(context, contentDepth, propertyConfig.chain, content, target);
39887
40064
  return;
40065
+ } else if (configKey === ConfigKey.property_accessibilityGroupTag) {
40066
+ groupTagChainContentProcessor(
40067
+ context,
40068
+ contentDepth,
40069
+ propertyConfig.chain,
40070
+ content,
40071
+ target,
40072
+ ACCESSIBILITY_GROUP_TAG
40073
+ );
40074
+ return;
39888
40075
  } else if (configKey === ConfigKey.property_ratingLevelStart || configKey === ConfigKey.property_ratingLevelEnd) {
39889
40076
  ratingLevelChainContentProcessor(
39890
40077
  context,
@@ -39937,6 +40124,23 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
39937
40124
  location: TextLocation.tag
39938
40125
  }
39939
40126
  );
40127
+ case TagFormat.enumeration: {
40128
+ const enumValue = instance3.unbreakscape(
40129
+ stringUtils.isString(v2) ? stringUtils.trimmedString(v2) : void 0,
40130
+ {
40131
+ format: TextFormat.plainText,
40132
+ location: TextLocation.tag
40133
+ }
40134
+ );
40135
+ if (enumValue == null || enumValue === "") return c.defaultValue ?? "";
40136
+ if (c.values && !c.values.includes(enumValue)) {
40137
+ context.addWarning(
40138
+ `Invalid value '${enumValue}' for property [@${tag}]. Valid values: ${c.values.join(" | ")}`,
40139
+ content
40140
+ );
40141
+ }
40142
+ return enumValue;
40143
+ }
39940
40144
  case TagFormat.number:
39941
40145
  return instance6.asNumber(
39942
40146
  instance3.unbreakscape(v2, {
@@ -45663,6 +45867,8 @@ var ConfigBuilder = class {
45663
45867
  format = "number";
45664
45868
  } else if (tag.format === TagFormat.coordinates) {
45665
45869
  format = "coordinates";
45870
+ } else if (tag.format === TagFormat.enumeration) {
45871
+ format = "enum";
45666
45872
  }
45667
45873
  } else if (tagType === BitTagConfigKeyType.resource) {
45668
45874
  format = "string";
@@ -45727,6 +45933,7 @@ var ConfigBuilder = class {
45727
45933
  { value: tag.htmlKey, present: hasHtml }
45728
45934
  ),
45729
45935
  ...format && format !== "string" ? { format } : {},
45936
+ ...tag.values != null ? { values: tag.values } : {},
45730
45937
  ...tag.defaultValue != null ? { default: tag.defaultValue } : {},
45731
45938
  ...tag.nullable ? { nullable: true } : {},
45732
45939
  ...tag.minCount != null && tag.minCount !== 0 ? { min: tag.minCount } : {},