@gmb/bitmark-parser-generator 5.27.0 → 5.28.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
@@ -1430,6 +1430,8 @@ var propertyKeys = {
1430
1430
  property_externalLinkText: "@externalLinkText",
1431
1431
  property_feedbackEngine: "@feedbackEngine",
1432
1432
  property_feedbackType: "@feedbackType",
1433
+ property_userFeedbackTranslationUrl: "@userFeedbackTranslationUrl",
1434
+ property_userFeedbackContentUrl: "@userFeedbackContentUrl",
1433
1435
  property_flashcardSet: "@flashcardSet",
1434
1436
  property_focusX: "@focusX",
1435
1437
  property_focusY: "@focusY",
@@ -3894,16 +3896,25 @@ var CARDSETS = {
3894
3896
  },
3895
3897
  {
3896
3898
  key: ConfigKey.property_tableRowSpan,
3899
+ // HTML-C2: contribute a `rowspan` attribute onto the enclosing
3900
+ // cell element (`<th>`/`<td>`).
3901
+ htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
3897
3902
  description: "Number of rows the cell spans.",
3898
3903
  format: TagFormat.number
3899
3904
  },
3900
3905
  {
3901
3906
  key: ConfigKey.property_tableColSpan,
3907
+ // HTML-C2: contribute a `colspan` attribute onto the enclosing
3908
+ // cell element (`<th>`/`<td>`).
3909
+ htmlKey: { "@el": { "@attr": { colspan: "$" } } },
3902
3910
  description: "Number of columns the cell spans.",
3903
3911
  format: TagFormat.number
3904
3912
  },
3905
3913
  {
3906
3914
  key: ConfigKey.property_tableScope,
3915
+ // HTML-C2: contribute a `scope` attribute onto the enclosing
3916
+ // cell element (`<th>`/`<td>`).
3917
+ htmlKey: { "@el": { "@attr": { scope: "$" } } },
3907
3918
  description: "Scope attribute for header cells.",
3908
3919
  format: TagFormat.plainText
3909
3920
  },
@@ -4021,6 +4032,9 @@ var CARDSETS = {
4021
4032
  key: ConfigKey.property_tableRowSpan,
4022
4033
  jsonKey: "rowspan",
4023
4034
  exportJsonKey: { rowspan: "$" },
4035
+ // HTML-C2: contribute a `rowspan` attribute onto the enclosing
4036
+ // cell element (`<th>`/`<td>`).
4037
+ htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
4024
4038
  description: "Number of rows the cell spans.",
4025
4039
  format: TagFormat.number
4026
4040
  },
@@ -4028,6 +4042,9 @@ var CARDSETS = {
4028
4042
  key: ConfigKey.property_tableColSpan,
4029
4043
  jsonKey: "colspan",
4030
4044
  exportJsonKey: { colspan: "$" },
4045
+ // HTML-C2: contribute a `colspan` attribute onto the enclosing
4046
+ // cell element (`<th>`/`<td>`).
4047
+ htmlKey: { "@el": { "@attr": { colspan: "$" } } },
4031
4048
  description: "Number of columns the cell spans.",
4032
4049
  format: TagFormat.number
4033
4050
  },
@@ -4035,6 +4052,9 @@ var CARDSETS = {
4035
4052
  key: ConfigKey.property_tableScope,
4036
4053
  jsonKey: "scope",
4037
4054
  exportJsonKey: { scope: "$" },
4055
+ // HTML-C2: contribute a `scope` attribute onto the enclosing
4056
+ // cell element (`<th>`/`<td>`).
4057
+ htmlKey: { "@el": { "@attr": { scope: "$" } } },
4038
4058
  description: "Scope attribute for header cells.",
4039
4059
  format: TagFormat.plainText
4040
4060
  },
@@ -5845,6 +5865,16 @@ var GROUPS = {
5845
5865
  description: "External Id of the translated book",
5846
5866
  format: TagFormat.plainText
5847
5867
  },
5868
+ {
5869
+ key: ConfigKey.property_userFeedbackTranslationUrl,
5870
+ description: "URL to an external feedback form for book translation feedback",
5871
+ format: TagFormat.plainText
5872
+ },
5873
+ {
5874
+ key: ConfigKey.property_userFeedbackContentUrl,
5875
+ description: "URL to an external feedback form for book content feedback",
5876
+ format: TagFormat.plainText
5877
+ },
5848
5878
  {
5849
5879
  key: ConfigKey.property_duration,
5850
5880
  description: "The duration of the book",
@@ -10947,7 +10977,9 @@ var BITS = {
10947
10977
  {
10948
10978
  key: ConfigKey.property_caption,
10949
10979
  description: "Caption for the table image, used to provide a description for the image",
10950
- format: TagFormat.bitmarkText
10980
+ format: TagFormat.bitmarkText,
10981
+ // HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
10982
+ htmlKey: { "@el": "caption", "@children": "$" }
10951
10983
  },
10952
10984
  {
10953
10985
  key: ConfigKey.group_backgroundWallpaper,
@@ -12638,7 +12670,12 @@ var BITS = {
12638
12670
  {
12639
12671
  key: ConfigKey.property_caption,
12640
12672
  description: "Caption for the table, used to define the title of the table",
12641
- format: TagFormat.bitmarkText
12673
+ format: TagFormat.bitmarkText,
12674
+ // HTML-10 / HTML-C2: a bit-level caption renders as the table's
12675
+ // `<caption>` — placed inside the idiomatic `<table>` container as
12676
+ // its first child. Outside a table context it falls back to the
12677
+ // residual carrier.
12678
+ htmlKey: { "@el": "caption", "@children": "$" }
12642
12679
  },
12643
12680
  {
12644
12681
  key: ConfigKey.property_tableFixedHeader,
@@ -12723,7 +12760,9 @@ var BITS = {
12723
12760
  {
12724
12761
  key: ConfigKey.property_caption,
12725
12762
  description: "Caption for the table image, used to provide a description for the image",
12726
- format: TagFormat.bitmarkText
12763
+ format: TagFormat.bitmarkText,
12764
+ // HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
12765
+ htmlKey: { "@el": "caption", "@children": "$" }
12727
12766
  },
12728
12767
  {
12729
12768
  key: ConfigKey.group_backgroundWallpaper,
@@ -13913,7 +13952,7 @@ var instance2 = new Config();
13913
13952
  // src/generated/package_info.ts
13914
13953
  var PACKAGE_INFO = {
13915
13954
  "name": "@gmb/bitmark-parser-generator",
13916
- "version": "5.27.0",
13955
+ "version": "5.28.0",
13917
13956
  "author": "Get More Brain Ltd",
13918
13957
  "license": "ISC",
13919
13958
  "description": "A bitmark parser and generator using Peggy.js"
@@ -14803,6 +14842,10 @@ var NodeType = {
14803
14842
  relatedBookValue: "relatedBookValue",
14804
14843
  translationOfBook: "translationOfBook",
14805
14844
  translationOfBookValue: "translationOfBookValue",
14845
+ userFeedbackTranslationUrl: "userFeedbackTranslationUrl",
14846
+ userFeedbackTranslationUrlValue: "userFeedbackTranslationUrlValue",
14847
+ userFeedbackContentUrl: "userFeedbackContentUrl",
14848
+ userFeedbackContentUrlValue: "userFeedbackContentUrlValue",
14806
14849
  releaseDate: "releaseDate",
14807
14850
  releaseDateValue: "releaseDateValue",
14808
14851
  releaseKind: "releaseKind",
@@ -28012,6 +28055,18 @@ var Builder = class extends BaseBuilder {
28012
28055
  data.translationOfBook,
28013
28056
  options
28014
28057
  ),
28058
+ userFeedbackTranslationUrl: this.toAstProperty(
28059
+ bitType,
28060
+ ConfigKey.property_userFeedbackTranslationUrl,
28061
+ data.userFeedbackTranslationUrl,
28062
+ options
28063
+ ),
28064
+ userFeedbackContentUrl: this.toAstProperty(
28065
+ bitType,
28066
+ ConfigKey.property_userFeedbackContentUrl,
28067
+ data.userFeedbackContentUrl,
28068
+ options
28069
+ ),
28015
28070
  author: this.toAstProperty(bitType, ConfigKey.property_author, data.author, options),
28016
28071
  subject: this.toAstProperty(bitType, ConfigKey.property_subject, data.subject, options),
28017
28072
  date: this.toAstProperty(bitType, ConfigKey.property_date, data.date, options),
@@ -31803,7 +31858,8 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
31803
31858
  this.writeNL();
31804
31859
  }
31805
31860
  const content = cell.content ?? instance3.EMPTY_STRING;
31806
- this.writeTextOrValue(content, this.textFormat, TextLocation.body);
31861
+ const options = this.options.noBreakscaping ? { noBreakscaping: true } : void 0;
31862
+ this.writeTextOrValue(content, this.textFormat, TextLocation.body, options);
31807
31863
  }
31808
31864
  writeTableCellProperty(name, value) {
31809
31865
  this.writeOPA();
@@ -33282,6 +33338,8 @@ var MARK_TO_TAG = {
33282
33338
  highlight: "mark",
33283
33339
  code: "code"
33284
33340
  };
33341
+ var INLINE_IMAGE_RE = /==([^=]*(?:=(?!=)[^=]*)*)==\|imageInline:([^|\s]+)((?:\|(?:@?[A-Za-z][A-Za-z0-9_-]*:[^|\s]+|#[^|\s]*))*)\|?/g;
33342
+ var MAX_IMAGE_DIMENSION = 9999;
33285
33343
  var HtmlTableGenerator = class {
33286
33344
  constructor() {
33287
33345
  __publicField(this, "indentUnit", " ");
@@ -33400,6 +33458,8 @@ var HtmlTableGenerator = class {
33400
33458
  case "image":
33401
33459
  case "imageInline":
33402
33460
  return this.imageToHtml(node);
33461
+ case "latex":
33462
+ return this.latexToHtml(node);
33403
33463
  default:
33404
33464
  return this.inlineToHtml([node]);
33405
33465
  }
@@ -33410,8 +33470,9 @@ var HtmlTableGenerator = class {
33410
33470
  inlineNodeToHtml(node) {
33411
33471
  if (node.type === "hardBreak") return "<br>";
33412
33472
  if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
33473
+ if (node.type === "latex") return this.latexToHtml(node);
33413
33474
  if (node.type === "text") {
33414
- return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
33475
+ return this.wrapMarks(this.textToHtml(node.text ?? ""), node.marks);
33415
33476
  }
33416
33477
  if (node.content) return this.inlineToHtml(node.content);
33417
33478
  return this.escapeText(node.text ?? "");
@@ -33489,6 +33550,44 @@ var HtmlTableGenerator = class {
33489
33550
  }
33490
33551
  return `<img ${parts.join(" ")}>`;
33491
33552
  }
33553
+ textToHtml(text) {
33554
+ let html = "";
33555
+ let lastIndex = 0;
33556
+ for (const match of text.matchAll(INLINE_IMAGE_RE)) {
33557
+ const index = match.index ?? 0;
33558
+ html += this.escapeText(text.slice(lastIndex, index));
33559
+ html += this.inlineImageTokenToHtml(match);
33560
+ lastIndex = index + match[0].length;
33561
+ }
33562
+ html += this.escapeText(text.slice(lastIndex));
33563
+ return html;
33564
+ }
33565
+ inlineImageTokenToHtml(match) {
33566
+ const attrs = {
33567
+ alt: match[1],
33568
+ src: match[2]
33569
+ };
33570
+ const rawAttrs = match[3] ?? "";
33571
+ for (const attr of rawAttrs.split("|")) {
33572
+ if (!attr || attr.startsWith("#")) continue;
33573
+ const colon = attr.indexOf(":");
33574
+ if (colon < 1) continue;
33575
+ const key = attr.slice(0, colon).replace(/^@/, "");
33576
+ const value = attr.slice(colon + 1);
33577
+ if (key === "width" || key === "height") {
33578
+ const n = Number.parseInt(value, 10);
33579
+ if (!Number.isNaN(n) && n > 0 && n <= MAX_IMAGE_DIMENSION) attrs[key] = n;
33580
+ } else if (key === "class" || key === "title") {
33581
+ attrs[key] = value;
33582
+ }
33583
+ }
33584
+ return this.imageToHtml({ type: "imageInline", attrs });
33585
+ }
33586
+ // --- formulas -------------------------------------------------------------
33587
+ latexToHtml(node) {
33588
+ const formula = node.attrs?.formula ?? "";
33589
+ return `<math alttext="${this.escapeAttr(formula)}"></math>`;
33590
+ }
33492
33591
  // --- escaping -------------------------------------------------------------
33493
33592
  escapeText(text) {
33494
33593
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
@@ -33800,6 +33899,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
33800
33899
  this.addProperty(this.bitJson, k, values, { array: true });
33801
33900
  }
33802
33901
  }
33902
+ return false;
33803
33903
  }
33804
33904
  // bitmarkAst -> bits -> bitsValue -> cardNode -> cardBits -> cardBitsValue
33805
33905
  enter_cardBitsValue(node, route) {
@@ -42870,7 +42970,7 @@ var IMPLIED_CLOSE = {
42870
42970
  p: /* @__PURE__ */ new Set(["p"]),
42871
42971
  option: /* @__PURE__ */ new Set(["option"])
42872
42972
  };
42873
- var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42973
+ var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9:-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42874
42974
  var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
42875
42975
  function parseAttrs(raw) {
42876
42976
  const attrs = {};
@@ -43201,6 +43301,9 @@ var HtmlTableParser = class {
43201
43301
  if (name === "img") {
43202
43302
  return [this.imageNode(el, true)];
43203
43303
  }
43304
+ if (this.isMathTag(name)) {
43305
+ return [this.latexNode(el)];
43306
+ }
43204
43307
  const markType = MARK_TAGS[name];
43205
43308
  if (markType) {
43206
43309
  return this.inlineNodes(el.children, [...marks, { type: markType }]);
@@ -43317,6 +43420,43 @@ var HtmlTableParser = class {
43317
43420
  if (el.attrs.class) attrs.class = el.attrs.class;
43318
43421
  return { type: inline ? "imageInline" : "image", attrs };
43319
43422
  }
43423
+ // --- formulas -------------------------------------------------------------
43424
+ isMathTag(name) {
43425
+ return this.localName(name) === "math";
43426
+ }
43427
+ latexNode(el) {
43428
+ return {
43429
+ type: "latex",
43430
+ attrs: {
43431
+ formula: this.latexFromMath(el)
43432
+ }
43433
+ };
43434
+ }
43435
+ latexFromMath(el) {
43436
+ const alt = el.attrs.alttext ?? el.attrs.alt ?? el.attrs.title;
43437
+ if (alt != null) return decodeEntities(alt);
43438
+ const annotation = this.findLatexAnnotation(el);
43439
+ if (annotation) return this.textContent(annotation).trim();
43440
+ return this.textContent(el).trim();
43441
+ }
43442
+ findLatexAnnotation(el) {
43443
+ for (const child of el.children) {
43444
+ if (!isElement(child)) continue;
43445
+ const lowerEncoding = (child.attrs.encoding ?? "").toLowerCase();
43446
+ if (this.localName(child.name) === "annotation" && (/\btex\b/.test(lowerEncoding) || /\blatex\b/.test(lowerEncoding))) {
43447
+ return child;
43448
+ }
43449
+ const nested = this.findLatexAnnotation(child);
43450
+ if (nested) return nested;
43451
+ }
43452
+ return void 0;
43453
+ }
43454
+ textContent(el) {
43455
+ return el.children.map((child) => isElement(child) ? this.textContent(child) : decodeEntities(child.value)).join("").replace(/\s+/g, " ");
43456
+ }
43457
+ localName(name) {
43458
+ return name.includes(":") ? name.slice(name.indexOf(":") + 1) : name;
43459
+ }
43320
43460
  // --- whitespace -----------------------------------------------------------
43321
43461
  /** Trim leading/trailing whitespace from inline content (edges only). */
43322
43462
  trimInline(nodes) {
@@ -45267,7 +45407,10 @@ var BitmarkParserGenerator = class {
45267
45407
  outputFile: opts.outputFile,
45268
45408
  fileOptions: opts.fileOptions,
45269
45409
  jsonOptions: opts.jsonOptions,
45270
- bitmarkOptions: opts.bitmarkOptions
45410
+ bitmarkOptions: {
45411
+ ...opts.bitmarkOptions,
45412
+ ...opts.noBreakscaping ? { noBreakscaping: true } : {}
45413
+ }
45271
45414
  });
45272
45415
  }
45273
45416
  const outputFormat = opts.outputFormat ?? "html";