@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/cli/main.js CHANGED
@@ -1269,6 +1269,7 @@ var propertyKeys = {
1269
1269
  property_bubbleTag: "@bubbleTag",
1270
1270
  property_extractorTag: "@extractorTag",
1271
1271
  property_extractorInternal: "@extractorInternal",
1272
+ property_bitFingerprint: "@bitFingerprint",
1272
1273
  property_buttonCaption: "@buttonCaption",
1273
1274
  property_callToActionUrl: "@callToActionUrl",
1274
1275
  property_caption: "@caption",
@@ -1330,6 +1331,8 @@ var propertyKeys = {
1330
1331
  property_externalLinkText: "@externalLinkText",
1331
1332
  property_feedbackEngine: "@feedbackEngine",
1332
1333
  property_feedbackType: "@feedbackType",
1334
+ property_userFeedbackTranslationUrl: "@userFeedbackTranslationUrl",
1335
+ property_userFeedbackContentUrl: "@userFeedbackContentUrl",
1333
1336
  property_flashcardSet: "@flashcardSet",
1334
1337
  property_focusX: "@focusX",
1335
1338
  property_focusY: "@focusY",
@@ -3785,16 +3788,25 @@ var CARDSETS = {
3785
3788
  },
3786
3789
  {
3787
3790
  key: ConfigKey.property_tableRowSpan,
3791
+ // HTML-C2: contribute a `rowspan` attribute onto the enclosing
3792
+ // cell element (`<th>`/`<td>`).
3793
+ htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
3788
3794
  description: "Number of rows the cell spans.",
3789
3795
  format: TagFormat.number
3790
3796
  },
3791
3797
  {
3792
3798
  key: ConfigKey.property_tableColSpan,
3799
+ // HTML-C2: contribute a `colspan` attribute onto the enclosing
3800
+ // cell element (`<th>`/`<td>`).
3801
+ htmlKey: { "@el": { "@attr": { colspan: "$" } } },
3793
3802
  description: "Number of columns the cell spans.",
3794
3803
  format: TagFormat.number
3795
3804
  },
3796
3805
  {
3797
3806
  key: ConfigKey.property_tableScope,
3807
+ // HTML-C2: contribute a `scope` attribute onto the enclosing
3808
+ // cell element (`<th>`/`<td>`).
3809
+ htmlKey: { "@el": { "@attr": { scope: "$" } } },
3798
3810
  description: "Scope attribute for header cells.",
3799
3811
  format: TagFormat.plainText
3800
3812
  },
@@ -3912,6 +3924,9 @@ var CARDSETS = {
3912
3924
  key: ConfigKey.property_tableRowSpan,
3913
3925
  jsonKey: "rowspan",
3914
3926
  exportJsonKey: { rowspan: "$" },
3927
+ // HTML-C2: contribute a `rowspan` attribute onto the enclosing
3928
+ // cell element (`<th>`/`<td>`).
3929
+ htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
3915
3930
  description: "Number of rows the cell spans.",
3916
3931
  format: TagFormat.number
3917
3932
  },
@@ -3919,6 +3934,9 @@ var CARDSETS = {
3919
3934
  key: ConfigKey.property_tableColSpan,
3920
3935
  jsonKey: "colspan",
3921
3936
  exportJsonKey: { colspan: "$" },
3937
+ // HTML-C2: contribute a `colspan` attribute onto the enclosing
3938
+ // cell element (`<th>`/`<td>`).
3939
+ htmlKey: { "@el": { "@attr": { colspan: "$" } } },
3922
3940
  description: "Number of columns the cell spans.",
3923
3941
  format: TagFormat.number
3924
3942
  },
@@ -3926,6 +3944,9 @@ var CARDSETS = {
3926
3944
  key: ConfigKey.property_tableScope,
3927
3945
  jsonKey: "scope",
3928
3946
  exportJsonKey: { scope: "$" },
3947
+ // HTML-C2: contribute a `scope` attribute onto the enclosing
3948
+ // cell element (`<th>`/`<td>`).
3949
+ htmlKey: { "@el": { "@attr": { scope: "$" } } },
3929
3950
  description: "Scope attribute for header cells.",
3930
3951
  format: TagFormat.plainText
3931
3952
  },
@@ -4532,6 +4553,12 @@ var GROUPS = {
4532
4553
  format: TagFormat.coordinates,
4533
4554
  maxCount: Count.infinity
4534
4555
  },
4556
+ {
4557
+ key: ConfigKey.property_bitFingerprint,
4558
+ description: "Fingerprint(s) used by the AI extractor to identify the bit (font, style, color, pixels, etc.)",
4559
+ format: TagFormat.plainText,
4560
+ maxCount: Count.infinity
4561
+ },
4535
4562
  {
4536
4563
  key: ConfigKey.property_levelCEFRp,
4537
4564
  description: "The CEFRp level for the bit",
@@ -5736,6 +5763,16 @@ var GROUPS = {
5736
5763
  description: "External Id of the translated book",
5737
5764
  format: TagFormat.plainText
5738
5765
  },
5766
+ {
5767
+ key: ConfigKey.property_userFeedbackTranslationUrl,
5768
+ description: "URL to an external feedback form for book translation feedback",
5769
+ format: TagFormat.plainText
5770
+ },
5771
+ {
5772
+ key: ConfigKey.property_userFeedbackContentUrl,
5773
+ description: "URL to an external feedback form for book content feedback",
5774
+ format: TagFormat.plainText
5775
+ },
5739
5776
  {
5740
5777
  key: ConfigKey.property_duration,
5741
5778
  description: "The duration of the book",
@@ -10115,7 +10152,18 @@ var BITS = {
10115
10152
  since: "5.12.0",
10116
10153
  baseBitType: BitType._standard,
10117
10154
  description: "Extractor blueprint bit, used to provide blueprint information about extractors",
10118
- textFormatDefault: TextFormat.json
10155
+ textFormatDefault: TextFormat.json,
10156
+ tags: [
10157
+ {
10158
+ key: ConfigKey.group_resourceBitTags,
10159
+ description: "Resource bit tags for the blueprint reference image"
10160
+ },
10161
+ {
10162
+ key: ConfigKey.group_resourceImage,
10163
+ description: "Optional uncropped reference page image, used so authoring tools can compute crops against the original page dimensions"
10164
+ }
10165
+ ],
10166
+ resourceAttachmentAllowed: false
10119
10167
  },
10120
10168
  [BitType.extractorInformation]: {
10121
10169
  since: "3.8.0",
@@ -10838,7 +10886,9 @@ var BITS = {
10838
10886
  {
10839
10887
  key: ConfigKey.property_caption,
10840
10888
  description: "Caption for the table image, used to provide a description for the image",
10841
- format: TagFormat.bitmarkText
10889
+ format: TagFormat.bitmarkText,
10890
+ // HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
10891
+ htmlKey: { "@el": "caption", "@children": "$" }
10842
10892
  },
10843
10893
  {
10844
10894
  key: ConfigKey.group_backgroundWallpaper,
@@ -12529,7 +12579,12 @@ var BITS = {
12529
12579
  {
12530
12580
  key: ConfigKey.property_caption,
12531
12581
  description: "Caption for the table, used to define the title of the table",
12532
- format: TagFormat.bitmarkText
12582
+ format: TagFormat.bitmarkText,
12583
+ // HTML-10 / HTML-C2: a bit-level caption renders as the table's
12584
+ // `<caption>` — placed inside the idiomatic `<table>` container as
12585
+ // its first child. Outside a table context it falls back to the
12586
+ // residual carrier.
12587
+ htmlKey: { "@el": "caption", "@children": "$" }
12533
12588
  },
12534
12589
  {
12535
12590
  key: ConfigKey.property_tableFixedHeader,
@@ -12614,7 +12669,9 @@ var BITS = {
12614
12669
  {
12615
12670
  key: ConfigKey.property_caption,
12616
12671
  description: "Caption for the table image, used to provide a description for the image",
12617
- format: TagFormat.bitmarkText
12672
+ format: TagFormat.bitmarkText,
12673
+ // HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
12674
+ htmlKey: { "@el": "caption", "@children": "$" }
12618
12675
  },
12619
12676
  {
12620
12677
  key: ConfigKey.group_backgroundWallpaper,
@@ -13804,7 +13861,7 @@ var instance2 = new Config();
13804
13861
  // src/generated/package_info.ts
13805
13862
  var PACKAGE_INFO = {
13806
13863
  "name": "@gmb/bitmark-parser-generator",
13807
- "version": "5.27.0",
13864
+ "version": "5.29.0",
13808
13865
  "license": "ISC"};
13809
13866
  var Environment = {
13810
13867
  unknown: "",
@@ -14185,6 +14242,8 @@ var NodeType = {
14185
14242
  // bit
14186
14243
  bitType: "bitType",
14187
14244
  // bit type
14245
+ bitFingerprint: "bitFingerprint",
14246
+ bitFingerprintValue: "bitFingerprintValue",
14188
14247
  blockId: "blockId",
14189
14248
  blockIdValue: "blockIdValue",
14190
14249
  body: "body",
@@ -14662,6 +14721,10 @@ var NodeType = {
14662
14721
  relatedBookValue: "relatedBookValue",
14663
14722
  translationOfBook: "translationOfBook",
14664
14723
  translationOfBookValue: "translationOfBookValue",
14724
+ userFeedbackTranslationUrl: "userFeedbackTranslationUrl",
14725
+ userFeedbackTranslationUrlValue: "userFeedbackTranslationUrlValue",
14726
+ userFeedbackContentUrl: "userFeedbackContentUrl",
14727
+ userFeedbackContentUrlValue: "userFeedbackContentUrlValue",
14665
14728
  releaseDate: "releaseDate",
14666
14729
  releaseDateValue: "releaseDateValue",
14667
14730
  releaseKind: "releaseKind",
@@ -27625,6 +27688,12 @@ var Builder = class extends BaseBuilder {
27625
27688
  options
27626
27689
  ),
27627
27690
  sourceBB: this.normaliseSourceBB(data.sourceBB),
27691
+ bitFingerprint: this.toAstProperty(
27692
+ bitType,
27693
+ ConfigKey.property_bitFingerprint,
27694
+ data.bitFingerprint,
27695
+ options
27696
+ ),
27628
27697
  levelCEFRp: this.toAstProperty(
27629
27698
  bitType,
27630
27699
  ConfigKey.property_levelCEFRp,
@@ -27687,6 +27756,18 @@ var Builder = class extends BaseBuilder {
27687
27756
  data.translationOfBook,
27688
27757
  options
27689
27758
  ),
27759
+ userFeedbackTranslationUrl: this.toAstProperty(
27760
+ bitType,
27761
+ ConfigKey.property_userFeedbackTranslationUrl,
27762
+ data.userFeedbackTranslationUrl,
27763
+ options
27764
+ ),
27765
+ userFeedbackContentUrl: this.toAstProperty(
27766
+ bitType,
27767
+ ConfigKey.property_userFeedbackContentUrl,
27768
+ data.userFeedbackContentUrl,
27769
+ options
27770
+ ),
27690
27771
  author: this.toAstProperty(bitType, ConfigKey.property_author, data.author, options),
27691
27772
  subject: this.toAstProperty(bitType, ConfigKey.property_subject, data.subject, options),
27692
27773
  date: this.toAstProperty(bitType, ConfigKey.property_date, data.date, options),
@@ -31462,7 +31543,8 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31462
31543
  this.writeNL();
31463
31544
  }
31464
31545
  const content = cell.content ?? instance3.EMPTY_STRING;
31465
- this.writeTextOrValue(content, this.textFormat, TextLocation.body);
31546
+ const options = this.options.noBreakscaping ? { noBreakscaping: true } : void 0;
31547
+ this.writeTextOrValue(content, this.textFormat, TextLocation.body, options);
31466
31548
  }
31467
31549
  writeTableCellProperty(name, value) {
31468
31550
  this.writeOPA();
@@ -32937,6 +33019,8 @@ var MARK_TO_TAG = {
32937
33019
  highlight: "mark",
32938
33020
  code: "code"
32939
33021
  };
33022
+ var INLINE_IMAGE_RE = /==([^=]*(?:=(?!=)[^=]*)*)==\|imageInline:([^|\s]+)((?:\|(?:@?[A-Za-z][A-Za-z0-9_-]*:[^|\s]+|#[^|\s]*))*)\|?/g;
33023
+ var MAX_IMAGE_DIMENSION = 9999;
32940
33024
  var HtmlTableGenerator = class {
32941
33025
  indentUnit = " ";
32942
33026
  /**
@@ -33053,6 +33137,8 @@ var HtmlTableGenerator = class {
33053
33137
  case "image":
33054
33138
  case "imageInline":
33055
33139
  return this.imageToHtml(node);
33140
+ case "latex":
33141
+ return this.latexToHtml(node);
33056
33142
  default:
33057
33143
  return this.inlineToHtml([node]);
33058
33144
  }
@@ -33063,8 +33149,9 @@ var HtmlTableGenerator = class {
33063
33149
  inlineNodeToHtml(node) {
33064
33150
  if (node.type === "hardBreak") return "<br>";
33065
33151
  if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
33152
+ if (node.type === "latex") return this.latexToHtml(node);
33066
33153
  if (node.type === "text") {
33067
- return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
33154
+ return this.wrapMarks(this.textToHtml(node.text ?? ""), node.marks);
33068
33155
  }
33069
33156
  if (node.content) return this.inlineToHtml(node.content);
33070
33157
  return this.escapeText(node.text ?? "");
@@ -33142,6 +33229,44 @@ var HtmlTableGenerator = class {
33142
33229
  }
33143
33230
  return `<img ${parts.join(" ")}>`;
33144
33231
  }
33232
+ textToHtml(text) {
33233
+ let html = "";
33234
+ let lastIndex = 0;
33235
+ for (const match of text.matchAll(INLINE_IMAGE_RE)) {
33236
+ const index = match.index ?? 0;
33237
+ html += this.escapeText(text.slice(lastIndex, index));
33238
+ html += this.inlineImageTokenToHtml(match);
33239
+ lastIndex = index + match[0].length;
33240
+ }
33241
+ html += this.escapeText(text.slice(lastIndex));
33242
+ return html;
33243
+ }
33244
+ inlineImageTokenToHtml(match) {
33245
+ const attrs = {
33246
+ alt: match[1],
33247
+ src: match[2]
33248
+ };
33249
+ const rawAttrs = match[3] ?? "";
33250
+ for (const attr of rawAttrs.split("|")) {
33251
+ if (!attr || attr.startsWith("#")) continue;
33252
+ const colon = attr.indexOf(":");
33253
+ if (colon < 1) continue;
33254
+ const key = attr.slice(0, colon).replace(/^@/, "");
33255
+ const value = attr.slice(colon + 1);
33256
+ if (key === "width" || key === "height") {
33257
+ const n = Number.parseInt(value, 10);
33258
+ if (!Number.isNaN(n) && n > 0 && n <= MAX_IMAGE_DIMENSION) attrs[key] = n;
33259
+ } else if (key === "class" || key === "title") {
33260
+ attrs[key] = value;
33261
+ }
33262
+ }
33263
+ return this.imageToHtml({ type: "imageInline", attrs });
33264
+ }
33265
+ // --- formulas -------------------------------------------------------------
33266
+ latexToHtml(node) {
33267
+ const formula = node.attrs?.formula ?? "";
33268
+ return `<math alttext="${this.escapeAttr(formula)}"></math>`;
33269
+ }
33145
33270
  // --- escaping -------------------------------------------------------------
33146
33271
  escapeText(text) {
33147
33272
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -33450,6 +33575,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
33450
33575
  this.addProperty(this.bitJson, k, values, { array: true });
33451
33576
  }
33452
33577
  }
33578
+ return false;
33453
33579
  }
33454
33580
  // bitmarkAst -> bits -> bitsValue -> cardNode -> cardBits -> cardBitsValue
33455
33581
  enter_cardBitsValue(node, route) {
@@ -42381,7 +42507,7 @@ var IMPLIED_CLOSE = {
42381
42507
  p: /* @__PURE__ */ new Set(["p"]),
42382
42508
  option: /* @__PURE__ */ new Set(["option"])
42383
42509
  };
42384
- var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42510
+ var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9:-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42385
42511
  var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
42386
42512
  function parseAttrs(raw) {
42387
42513
  const attrs = {};
@@ -42710,6 +42836,9 @@ var HtmlTableParser = class {
42710
42836
  if (name === "img") {
42711
42837
  return [this.imageNode(el, true)];
42712
42838
  }
42839
+ if (this.isMathTag(name)) {
42840
+ return [this.latexNode(el)];
42841
+ }
42713
42842
  const markType = MARK_TAGS[name];
42714
42843
  if (markType) {
42715
42844
  return this.inlineNodes(el.children, [...marks, { type: markType }]);
@@ -42826,6 +42955,43 @@ var HtmlTableParser = class {
42826
42955
  if (el.attrs.class) attrs.class = el.attrs.class;
42827
42956
  return { type: inline ? "imageInline" : "image", attrs };
42828
42957
  }
42958
+ // --- formulas -------------------------------------------------------------
42959
+ isMathTag(name) {
42960
+ return this.localName(name) === "math";
42961
+ }
42962
+ latexNode(el) {
42963
+ return {
42964
+ type: "latex",
42965
+ attrs: {
42966
+ formula: this.latexFromMath(el)
42967
+ }
42968
+ };
42969
+ }
42970
+ latexFromMath(el) {
42971
+ const alt = el.attrs.alttext ?? el.attrs.alt ?? el.attrs.title;
42972
+ if (alt != null) return decodeEntities(alt);
42973
+ const annotation = this.findLatexAnnotation(el);
42974
+ if (annotation) return this.textContent(annotation).trim();
42975
+ return this.textContent(el).trim();
42976
+ }
42977
+ findLatexAnnotation(el) {
42978
+ for (const child of el.children) {
42979
+ if (!isElement(child)) continue;
42980
+ const lowerEncoding = (child.attrs.encoding ?? "").toLowerCase();
42981
+ if (this.localName(child.name) === "annotation" && (/\btex\b/.test(lowerEncoding) || /\blatex\b/.test(lowerEncoding))) {
42982
+ return child;
42983
+ }
42984
+ const nested = this.findLatexAnnotation(child);
42985
+ if (nested) return nested;
42986
+ }
42987
+ return void 0;
42988
+ }
42989
+ textContent(el) {
42990
+ return el.children.map((child) => isElement(child) ? this.textContent(child) : decodeEntities(child.value)).join("").replace(/\s+/g, " ");
42991
+ }
42992
+ localName(name) {
42993
+ return name.includes(":") ? name.slice(name.indexOf(":") + 1) : name;
42994
+ }
42829
42995
  // --- whitespace -----------------------------------------------------------
42830
42996
  /** Trim leading/trailing whitespace from inline content (edges only). */
42831
42997
  trimInline(nodes) {
@@ -44723,7 +44889,10 @@ var BitmarkParserGenerator = class {
44723
44889
  outputFile: opts.outputFile,
44724
44890
  fileOptions: opts.fileOptions,
44725
44891
  jsonOptions: opts.jsonOptions,
44726
- bitmarkOptions: opts.bitmarkOptions
44892
+ bitmarkOptions: {
44893
+ ...opts.bitmarkOptions,
44894
+ ...opts.noBreakscaping ? { noBreakscaping: true } : {}
44895
+ }
44727
44896
  });
44728
44897
  }
44729
44898
  const outputFormat = opts.outputFormat ?? "html";
@@ -45085,7 +45254,7 @@ function createConvertHtmlTableCommand() {
45085
45254
  )
45086
45255
  ).addOption(
45087
45256
  new Option("--tableFormat <format>", "bit type to emit for HTML input").choices(TABLE_FORMAT_CHOICES).default("table-extended")
45088
- ).option("--keepUnknownTags", "keep unmappable HTML tags as literal text (HTML input only)").option("-p, --pretty", "prettify the JSON output with indent").option(
45257
+ ).option("--keepUnknownTags", "keep unmappable HTML tags as literal text (HTML input only)").option("--noBreakscaping", "do not breakscape generated bitmark table cell content").option("-p, --pretty", "prettify the JSON output with indent").option(
45089
45258
  "--indent <indent>",
45090
45259
  "prettify indent (default: 2 when --pretty is set)",
45091
45260
  (v) => Number.parseInt(v, 10)
@@ -45101,6 +45270,7 @@ function createConvertHtmlTableCommand() {
45101
45270
  options.tableFormat
45102
45271
  ),
45103
45272
  keepUnknownTags: options.keepUnknownTags,
45273
+ noBreakscaping: options.noBreakscaping,
45104
45274
  jsonOptions: {
45105
45275
  prettify
45106
45276
  }
@@ -45126,7 +45296,9 @@ Examples:
45126
45296
 
45127
45297
  $ bitmark-parser convertHtmlTable input.bitmark -o output.html
45128
45298
 
45129
- $ bitmark-parser convertHtmlTable --tableFormat table input.html`
45299
+ $ bitmark-parser convertHtmlTable --tableFormat table input.html
45300
+
45301
+ $ bitmark-parser convertHtmlTable --noBreakscaping input.html`
45130
45302
  );
45131
45303
  return cmd;
45132
45304
  }