@gmb/bitmark-parser-generator 5.27.0 → 5.29.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
@@ -1369,6 +1369,7 @@ var propertyKeys = {
1369
1369
  property_bubbleTag: "@bubbleTag",
1370
1370
  property_extractorTag: "@extractorTag",
1371
1371
  property_extractorInternal: "@extractorInternal",
1372
+ property_bitFingerprint: "@bitFingerprint",
1372
1373
  property_buttonCaption: "@buttonCaption",
1373
1374
  property_callToActionUrl: "@callToActionUrl",
1374
1375
  property_caption: "@caption",
@@ -1430,6 +1431,8 @@ var propertyKeys = {
1430
1431
  property_externalLinkText: "@externalLinkText",
1431
1432
  property_feedbackEngine: "@feedbackEngine",
1432
1433
  property_feedbackType: "@feedbackType",
1434
+ property_userFeedbackTranslationUrl: "@userFeedbackTranslationUrl",
1435
+ property_userFeedbackContentUrl: "@userFeedbackContentUrl",
1433
1436
  property_flashcardSet: "@flashcardSet",
1434
1437
  property_focusX: "@focusX",
1435
1438
  property_focusY: "@focusY",
@@ -3894,16 +3897,25 @@ var CARDSETS = {
3894
3897
  },
3895
3898
  {
3896
3899
  key: ConfigKey.property_tableRowSpan,
3900
+ // HTML-C2: contribute a `rowspan` attribute onto the enclosing
3901
+ // cell element (`<th>`/`<td>`).
3902
+ htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
3897
3903
  description: "Number of rows the cell spans.",
3898
3904
  format: TagFormat.number
3899
3905
  },
3900
3906
  {
3901
3907
  key: ConfigKey.property_tableColSpan,
3908
+ // HTML-C2: contribute a `colspan` attribute onto the enclosing
3909
+ // cell element (`<th>`/`<td>`).
3910
+ htmlKey: { "@el": { "@attr": { colspan: "$" } } },
3902
3911
  description: "Number of columns the cell spans.",
3903
3912
  format: TagFormat.number
3904
3913
  },
3905
3914
  {
3906
3915
  key: ConfigKey.property_tableScope,
3916
+ // HTML-C2: contribute a `scope` attribute onto the enclosing
3917
+ // cell element (`<th>`/`<td>`).
3918
+ htmlKey: { "@el": { "@attr": { scope: "$" } } },
3907
3919
  description: "Scope attribute for header cells.",
3908
3920
  format: TagFormat.plainText
3909
3921
  },
@@ -4021,6 +4033,9 @@ var CARDSETS = {
4021
4033
  key: ConfigKey.property_tableRowSpan,
4022
4034
  jsonKey: "rowspan",
4023
4035
  exportJsonKey: { rowspan: "$" },
4036
+ // HTML-C2: contribute a `rowspan` attribute onto the enclosing
4037
+ // cell element (`<th>`/`<td>`).
4038
+ htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
4024
4039
  description: "Number of rows the cell spans.",
4025
4040
  format: TagFormat.number
4026
4041
  },
@@ -4028,6 +4043,9 @@ var CARDSETS = {
4028
4043
  key: ConfigKey.property_tableColSpan,
4029
4044
  jsonKey: "colspan",
4030
4045
  exportJsonKey: { colspan: "$" },
4046
+ // HTML-C2: contribute a `colspan` attribute onto the enclosing
4047
+ // cell element (`<th>`/`<td>`).
4048
+ htmlKey: { "@el": { "@attr": { colspan: "$" } } },
4031
4049
  description: "Number of columns the cell spans.",
4032
4050
  format: TagFormat.number
4033
4051
  },
@@ -4035,6 +4053,9 @@ var CARDSETS = {
4035
4053
  key: ConfigKey.property_tableScope,
4036
4054
  jsonKey: "scope",
4037
4055
  exportJsonKey: { scope: "$" },
4056
+ // HTML-C2: contribute a `scope` attribute onto the enclosing
4057
+ // cell element (`<th>`/`<td>`).
4058
+ htmlKey: { "@el": { "@attr": { scope: "$" } } },
4038
4059
  description: "Scope attribute for header cells.",
4039
4060
  format: TagFormat.plainText
4040
4061
  },
@@ -4641,6 +4662,12 @@ var GROUPS = {
4641
4662
  format: TagFormat.coordinates,
4642
4663
  maxCount: Count.infinity
4643
4664
  },
4665
+ {
4666
+ key: ConfigKey.property_bitFingerprint,
4667
+ description: "Fingerprint(s) used by the AI extractor to identify the bit (font, style, color, pixels, etc.)",
4668
+ format: TagFormat.plainText,
4669
+ maxCount: Count.infinity
4670
+ },
4644
4671
  {
4645
4672
  key: ConfigKey.property_levelCEFRp,
4646
4673
  description: "The CEFRp level for the bit",
@@ -5845,6 +5872,16 @@ var GROUPS = {
5845
5872
  description: "External Id of the translated book",
5846
5873
  format: TagFormat.plainText
5847
5874
  },
5875
+ {
5876
+ key: ConfigKey.property_userFeedbackTranslationUrl,
5877
+ description: "URL to an external feedback form for book translation feedback",
5878
+ format: TagFormat.plainText
5879
+ },
5880
+ {
5881
+ key: ConfigKey.property_userFeedbackContentUrl,
5882
+ description: "URL to an external feedback form for book content feedback",
5883
+ format: TagFormat.plainText
5884
+ },
5848
5885
  {
5849
5886
  key: ConfigKey.property_duration,
5850
5887
  description: "The duration of the book",
@@ -10224,7 +10261,18 @@ var BITS = {
10224
10261
  since: "5.12.0",
10225
10262
  baseBitType: BitType._standard,
10226
10263
  description: "Extractor blueprint bit, used to provide blueprint information about extractors",
10227
- textFormatDefault: TextFormat.json
10264
+ textFormatDefault: TextFormat.json,
10265
+ tags: [
10266
+ {
10267
+ key: ConfigKey.group_resourceBitTags,
10268
+ description: "Resource bit tags for the blueprint reference image"
10269
+ },
10270
+ {
10271
+ key: ConfigKey.group_resourceImage,
10272
+ description: "Optional uncropped reference page image, used so authoring tools can compute crops against the original page dimensions"
10273
+ }
10274
+ ],
10275
+ resourceAttachmentAllowed: false
10228
10276
  },
10229
10277
  [BitType.extractorInformation]: {
10230
10278
  since: "3.8.0",
@@ -10947,7 +10995,9 @@ var BITS = {
10947
10995
  {
10948
10996
  key: ConfigKey.property_caption,
10949
10997
  description: "Caption for the table image, used to provide a description for the image",
10950
- format: TagFormat.bitmarkText
10998
+ format: TagFormat.bitmarkText,
10999
+ // HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
11000
+ htmlKey: { "@el": "caption", "@children": "$" }
10951
11001
  },
10952
11002
  {
10953
11003
  key: ConfigKey.group_backgroundWallpaper,
@@ -12638,7 +12688,12 @@ var BITS = {
12638
12688
  {
12639
12689
  key: ConfigKey.property_caption,
12640
12690
  description: "Caption for the table, used to define the title of the table",
12641
- format: TagFormat.bitmarkText
12691
+ format: TagFormat.bitmarkText,
12692
+ // HTML-10 / HTML-C2: a bit-level caption renders as the table's
12693
+ // `<caption>` — placed inside the idiomatic `<table>` container as
12694
+ // its first child. Outside a table context it falls back to the
12695
+ // residual carrier.
12696
+ htmlKey: { "@el": "caption", "@children": "$" }
12642
12697
  },
12643
12698
  {
12644
12699
  key: ConfigKey.property_tableFixedHeader,
@@ -12723,7 +12778,9 @@ var BITS = {
12723
12778
  {
12724
12779
  key: ConfigKey.property_caption,
12725
12780
  description: "Caption for the table image, used to provide a description for the image",
12726
- format: TagFormat.bitmarkText
12781
+ format: TagFormat.bitmarkText,
12782
+ // HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
12783
+ htmlKey: { "@el": "caption", "@children": "$" }
12727
12784
  },
12728
12785
  {
12729
12786
  key: ConfigKey.group_backgroundWallpaper,
@@ -13913,7 +13970,7 @@ var instance2 = new Config();
13913
13970
  // src/generated/package_info.ts
13914
13971
  var PACKAGE_INFO = {
13915
13972
  "name": "@gmb/bitmark-parser-generator",
13916
- "version": "5.27.0",
13973
+ "version": "5.29.0",
13917
13974
  "author": "Get More Brain Ltd",
13918
13975
  "license": "ISC",
13919
13976
  "description": "A bitmark parser and generator using Peggy.js"
@@ -14326,6 +14383,8 @@ var NodeType = {
14326
14383
  // bit
14327
14384
  bitType: "bitType",
14328
14385
  // bit type
14386
+ bitFingerprint: "bitFingerprint",
14387
+ bitFingerprintValue: "bitFingerprintValue",
14329
14388
  blockId: "blockId",
14330
14389
  blockIdValue: "blockIdValue",
14331
14390
  body: "body",
@@ -14803,6 +14862,10 @@ var NodeType = {
14803
14862
  relatedBookValue: "relatedBookValue",
14804
14863
  translationOfBook: "translationOfBook",
14805
14864
  translationOfBookValue: "translationOfBookValue",
14865
+ userFeedbackTranslationUrl: "userFeedbackTranslationUrl",
14866
+ userFeedbackTranslationUrlValue: "userFeedbackTranslationUrlValue",
14867
+ userFeedbackContentUrl: "userFeedbackContentUrl",
14868
+ userFeedbackContentUrlValue: "userFeedbackContentUrlValue",
14806
14869
  releaseDate: "releaseDate",
14807
14870
  releaseDateValue: "releaseDateValue",
14808
14871
  releaseKind: "releaseKind",
@@ -27950,6 +28013,12 @@ var Builder = class extends BaseBuilder {
27950
28013
  options
27951
28014
  ),
27952
28015
  sourceBB: this.normaliseSourceBB(data.sourceBB),
28016
+ bitFingerprint: this.toAstProperty(
28017
+ bitType,
28018
+ ConfigKey.property_bitFingerprint,
28019
+ data.bitFingerprint,
28020
+ options
28021
+ ),
27953
28022
  levelCEFRp: this.toAstProperty(
27954
28023
  bitType,
27955
28024
  ConfigKey.property_levelCEFRp,
@@ -28012,6 +28081,18 @@ var Builder = class extends BaseBuilder {
28012
28081
  data.translationOfBook,
28013
28082
  options
28014
28083
  ),
28084
+ userFeedbackTranslationUrl: this.toAstProperty(
28085
+ bitType,
28086
+ ConfigKey.property_userFeedbackTranslationUrl,
28087
+ data.userFeedbackTranslationUrl,
28088
+ options
28089
+ ),
28090
+ userFeedbackContentUrl: this.toAstProperty(
28091
+ bitType,
28092
+ ConfigKey.property_userFeedbackContentUrl,
28093
+ data.userFeedbackContentUrl,
28094
+ options
28095
+ ),
28015
28096
  author: this.toAstProperty(bitType, ConfigKey.property_author, data.author, options),
28016
28097
  subject: this.toAstProperty(bitType, ConfigKey.property_subject, data.subject, options),
28017
28098
  date: this.toAstProperty(bitType, ConfigKey.property_date, data.date, options),
@@ -31803,7 +31884,8 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31803
31884
  this.writeNL();
31804
31885
  }
31805
31886
  const content = cell.content ?? instance3.EMPTY_STRING;
31806
- this.writeTextOrValue(content, this.textFormat, TextLocation.body);
31887
+ const options = this.options.noBreakscaping ? { noBreakscaping: true } : void 0;
31888
+ this.writeTextOrValue(content, this.textFormat, TextLocation.body, options);
31807
31889
  }
31808
31890
  writeTableCellProperty(name, value) {
31809
31891
  this.writeOPA();
@@ -33282,6 +33364,8 @@ var MARK_TO_TAG = {
33282
33364
  highlight: "mark",
33283
33365
  code: "code"
33284
33366
  };
33367
+ var INLINE_IMAGE_RE = /==([^=]*(?:=(?!=)[^=]*)*)==\|imageInline:([^|\s]+)((?:\|(?:@?[A-Za-z][A-Za-z0-9_-]*:[^|\s]+|#[^|\s]*))*)\|?/g;
33368
+ var MAX_IMAGE_DIMENSION = 9999;
33285
33369
  var HtmlTableGenerator = class {
33286
33370
  constructor() {
33287
33371
  __publicField(this, "indentUnit", " ");
@@ -33400,6 +33484,8 @@ var HtmlTableGenerator = class {
33400
33484
  case "image":
33401
33485
  case "imageInline":
33402
33486
  return this.imageToHtml(node);
33487
+ case "latex":
33488
+ return this.latexToHtml(node);
33403
33489
  default:
33404
33490
  return this.inlineToHtml([node]);
33405
33491
  }
@@ -33410,8 +33496,9 @@ var HtmlTableGenerator = class {
33410
33496
  inlineNodeToHtml(node) {
33411
33497
  if (node.type === "hardBreak") return "<br>";
33412
33498
  if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
33499
+ if (node.type === "latex") return this.latexToHtml(node);
33413
33500
  if (node.type === "text") {
33414
- return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
33501
+ return this.wrapMarks(this.textToHtml(node.text ?? ""), node.marks);
33415
33502
  }
33416
33503
  if (node.content) return this.inlineToHtml(node.content);
33417
33504
  return this.escapeText(node.text ?? "");
@@ -33489,6 +33576,44 @@ var HtmlTableGenerator = class {
33489
33576
  }
33490
33577
  return `<img ${parts.join(" ")}>`;
33491
33578
  }
33579
+ textToHtml(text) {
33580
+ let html = "";
33581
+ let lastIndex = 0;
33582
+ for (const match of text.matchAll(INLINE_IMAGE_RE)) {
33583
+ const index = match.index ?? 0;
33584
+ html += this.escapeText(text.slice(lastIndex, index));
33585
+ html += this.inlineImageTokenToHtml(match);
33586
+ lastIndex = index + match[0].length;
33587
+ }
33588
+ html += this.escapeText(text.slice(lastIndex));
33589
+ return html;
33590
+ }
33591
+ inlineImageTokenToHtml(match) {
33592
+ const attrs = {
33593
+ alt: match[1],
33594
+ src: match[2]
33595
+ };
33596
+ const rawAttrs = match[3] ?? "";
33597
+ for (const attr of rawAttrs.split("|")) {
33598
+ if (!attr || attr.startsWith("#")) continue;
33599
+ const colon = attr.indexOf(":");
33600
+ if (colon < 1) continue;
33601
+ const key = attr.slice(0, colon).replace(/^@/, "");
33602
+ const value = attr.slice(colon + 1);
33603
+ if (key === "width" || key === "height") {
33604
+ const n = Number.parseInt(value, 10);
33605
+ if (!Number.isNaN(n) && n > 0 && n <= MAX_IMAGE_DIMENSION) attrs[key] = n;
33606
+ } else if (key === "class" || key === "title") {
33607
+ attrs[key] = value;
33608
+ }
33609
+ }
33610
+ return this.imageToHtml({ type: "imageInline", attrs });
33611
+ }
33612
+ // --- formulas -------------------------------------------------------------
33613
+ latexToHtml(node) {
33614
+ const formula = node.attrs?.formula ?? "";
33615
+ return `<math alttext="${this.escapeAttr(formula)}"></math>`;
33616
+ }
33492
33617
  // --- escaping -------------------------------------------------------------
33493
33618
  escapeText(text) {
33494
33619
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -33800,6 +33925,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
33800
33925
  this.addProperty(this.bitJson, k, values, { array: true });
33801
33926
  }
33802
33927
  }
33928
+ return false;
33803
33929
  }
33804
33930
  // bitmarkAst -> bits -> bitsValue -> cardNode -> cardBits -> cardBitsValue
33805
33931
  enter_cardBitsValue(node, route) {
@@ -42870,7 +42996,7 @@ var IMPLIED_CLOSE = {
42870
42996
  p: /* @__PURE__ */ new Set(["p"]),
42871
42997
  option: /* @__PURE__ */ new Set(["option"])
42872
42998
  };
42873
- var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42999
+ var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9:-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42874
43000
  var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
42875
43001
  function parseAttrs(raw) {
42876
43002
  const attrs = {};
@@ -43201,6 +43327,9 @@ var HtmlTableParser = class {
43201
43327
  if (name === "img") {
43202
43328
  return [this.imageNode(el, true)];
43203
43329
  }
43330
+ if (this.isMathTag(name)) {
43331
+ return [this.latexNode(el)];
43332
+ }
43204
43333
  const markType = MARK_TAGS[name];
43205
43334
  if (markType) {
43206
43335
  return this.inlineNodes(el.children, [...marks, { type: markType }]);
@@ -43317,6 +43446,43 @@ var HtmlTableParser = class {
43317
43446
  if (el.attrs.class) attrs.class = el.attrs.class;
43318
43447
  return { type: inline ? "imageInline" : "image", attrs };
43319
43448
  }
43449
+ // --- formulas -------------------------------------------------------------
43450
+ isMathTag(name) {
43451
+ return this.localName(name) === "math";
43452
+ }
43453
+ latexNode(el) {
43454
+ return {
43455
+ type: "latex",
43456
+ attrs: {
43457
+ formula: this.latexFromMath(el)
43458
+ }
43459
+ };
43460
+ }
43461
+ latexFromMath(el) {
43462
+ const alt = el.attrs.alttext ?? el.attrs.alt ?? el.attrs.title;
43463
+ if (alt != null) return decodeEntities(alt);
43464
+ const annotation = this.findLatexAnnotation(el);
43465
+ if (annotation) return this.textContent(annotation).trim();
43466
+ return this.textContent(el).trim();
43467
+ }
43468
+ findLatexAnnotation(el) {
43469
+ for (const child of el.children) {
43470
+ if (!isElement(child)) continue;
43471
+ const lowerEncoding = (child.attrs.encoding ?? "").toLowerCase();
43472
+ if (this.localName(child.name) === "annotation" && (/\btex\b/.test(lowerEncoding) || /\blatex\b/.test(lowerEncoding))) {
43473
+ return child;
43474
+ }
43475
+ const nested = this.findLatexAnnotation(child);
43476
+ if (nested) return nested;
43477
+ }
43478
+ return void 0;
43479
+ }
43480
+ textContent(el) {
43481
+ return el.children.map((child) => isElement(child) ? this.textContent(child) : decodeEntities(child.value)).join("").replace(/\s+/g, " ");
43482
+ }
43483
+ localName(name) {
43484
+ return name.includes(":") ? name.slice(name.indexOf(":") + 1) : name;
43485
+ }
43320
43486
  // --- whitespace -----------------------------------------------------------
43321
43487
  /** Trim leading/trailing whitespace from inline content (edges only). */
43322
43488
  trimInline(nodes) {
@@ -45267,7 +45433,10 @@ var BitmarkParserGenerator = class {
45267
45433
  outputFile: opts.outputFile,
45268
45434
  fileOptions: opts.fileOptions,
45269
45435
  jsonOptions: opts.jsonOptions,
45270
- bitmarkOptions: opts.bitmarkOptions
45436
+ bitmarkOptions: {
45437
+ ...opts.bitmarkOptions,
45438
+ ...opts.noBreakscaping ? { noBreakscaping: true } : {}
45439
+ }
45271
45440
  });
45272
45441
  }
45273
45442
  const outputFormat = opts.outputFormat ?? "html";