@gmb/bitmark-parser-generator 5.25.0 → 5.27.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.
@@ -34,8 +34,8 @@ __export(index_exports, {
34
34
  BoundingBoxIndex: () => BoundingBoxIndex,
35
35
  Builder: () => Builder,
36
36
  CardSetVersion: () => CardSetVersion,
37
- HtmlTableGenerator: () => HtmlTableGenerator2,
38
- HtmlTableParser: () => HtmlTableParser2,
37
+ HtmlTableGenerator: () => HtmlTableGenerator,
38
+ HtmlTableParser: () => HtmlTableParser,
39
39
  InfoFormat: () => InfoFormat,
40
40
  InfoType: () => InfoType,
41
41
  Input: () => Input,
@@ -596,6 +596,14 @@ var BitType2 = {
596
596
  smartStandardRemarkNonNormativeCollapsible: "smart-standard-remark-non-normative-collapsible",
597
597
  smartStandardRemarkNormative: "smart-standard-remark-normative",
598
598
  smartStandardRemarkNormativeCollapsible: "smart-standard-remark-normative-collapsible",
599
+ smartStandardRemarkTableExtendedImageNonNormative: "smart-standard-remark-table-extended-image-non-normative",
600
+ smartStandardRemarkTableExtendedImageNonNormativeCollapsible: "smart-standard-remark-table-extended-image-non-normative-collapsible",
601
+ smartStandardRemarkTableExtendedImageNormative: "smart-standard-remark-table-extended-image-normative",
602
+ smartStandardRemarkTableExtendedImageNormativeCollapsible: "smart-standard-remark-table-extended-image-normative-collapsible",
603
+ smartStandardRemarkTableExtendedNonNormative: "smart-standard-remark-table-extended-non-normative",
604
+ smartStandardRemarkTableExtendedNonNormativeCollapsible: "smart-standard-remark-table-extended-non-normative-collapsible",
605
+ smartStandardRemarkTableExtendedNormative: "smart-standard-remark-table-extended-normative",
606
+ smartStandardRemarkTableExtendedNormativeCollapsible: "smart-standard-remark-table-extended-normative-collapsible",
599
607
  smartStandardRemarkTableImageNonNormative: "smart-standard-remark-table-image-non-normative",
600
608
  smartStandardRemarkTableImageNonNormativeCollapsible: "smart-standard-remark-table-image-non-normative-collapsible",
601
609
  smartStandardRemarkTableImageNormative: "smart-standard-remark-table-image-normative",
@@ -604,6 +612,14 @@ var BitType2 = {
604
612
  smartStandardRemarkTableNonNormativeCollapsible: "smart-standard-remark-table-non-normative-collapsible",
605
613
  smartStandardRemarkTableNormative: "smart-standard-remark-table-normative",
606
614
  smartStandardRemarkTableNormativeCollapsible: "smart-standard-remark-table-normative-collapsible",
615
+ smartStandardTableExtendedImageNonNormative: "smart-standard-table-extended-image-non-normative",
616
+ smartStandardTableExtendedImageNonNormativeCollapsible: "smart-standard-table-extended-image-non-normative-collapsible",
617
+ smartStandardTableExtendedImageNormative: "smart-standard-table-extended-image-normative",
618
+ smartStandardTableExtendedImageNormativeCollapsible: "smart-standard-table-extended-image-normative-collapsible",
619
+ smartStandardTableExtendedNonNormative: "smart-standard-table-extended-non-normative",
620
+ smartStandardTableExtendedNonNormativeCollapsible: "smart-standard-table-extended-non-normative-collapsible",
621
+ smartStandardTableExtendedNormative: "smart-standard-table-extended-normative",
622
+ smartStandardTableExtendedNormativeCollapsible: "smart-standard-table-extended-normative-collapsible",
607
623
  smartStandardTableImageNonNormative: "smart-standard-table-image-non-normative",
608
624
  smartStandardTableImageNonNormativeCollapsible: "smart-standard-table-image-non-normative-collapsible",
609
625
  smartStandardTableImageNormative: "smart-standard-table-image-normative",
@@ -626,10 +642,18 @@ var BitType2 = {
626
642
  standardNoteNormative: "standard-note-normative",
627
643
  standardRemarkNonNormative: "standard-remark-non-normative",
628
644
  standardRemarkNormative: "standard-remark-normative",
645
+ standardRemarkTableExtendedImageNonNormative: "standard-remark-table-extended-image-non-normative",
646
+ standardRemarkTableExtendedImageNormative: "standard-remark-table-extended-image-normative",
647
+ standardRemarkTableExtendedNonNormative: "standard-remark-table-extended-non-normative",
648
+ standardRemarkTableExtendedNormative: "standard-remark-table-extended-normative",
629
649
  standardRemarkTableImageNonNormative: "standard-remark-table-image-non-normative",
630
650
  standardRemarkTableImageNormative: "standard-remark-table-image-normative",
631
651
  standardRemarkTableNonNormative: "standard-remark-table-non-normative",
632
652
  standardRemarkTableNormative: "standard-remark-table-normative",
653
+ standardTableExtendedImageNonNormative: "standard-table-extended-image-non-normative",
654
+ standardTableExtendedImageNormative: "standard-table-extended-image-normative",
655
+ standardTableExtendedNonNormative: "standard-table-extended-non-normative",
656
+ standardTableExtendedNormative: "standard-table-extended-normative",
633
657
  standardTableImageNonNormative: "standard-table-image-non-normative",
634
658
  standardTableImageNormative: "standard-table-image-normative",
635
659
  standardTableNonNormative: "standard-table-non-normative",
@@ -856,6 +880,10 @@ var AbstractTagConfig = class {
856
880
  // New JSON-pattern jsonKey (export-only)
857
881
  __publicField(this, "hasExportJsonKey");
858
882
  // True iff exportJsonKey was explicitly set
883
+ __publicField(this, "htmlKey");
884
+ // HTML key-pattern (export-only)
885
+ __publicField(this, "hasHtmlKey");
886
+ // True iff htmlKey was explicitly set
859
887
  __publicField(this, "deprecated");
860
888
  this.type = params.type;
861
889
  this.configKey = params.configKey;
@@ -866,6 +894,8 @@ var AbstractTagConfig = class {
866
894
  this.jsonKey = params.jsonKey;
867
895
  this.exportJsonKey = params.exportJsonKey;
868
896
  this.hasExportJsonKey = params.hasExportJsonKey;
897
+ this.htmlKey = params.htmlKey;
898
+ this.hasHtmlKey = params.hasHtmlKey;
869
899
  this.deprecated = params.deprecated;
870
900
  }
871
901
  };
@@ -987,7 +1017,7 @@ var ResourceTagConfig = class extends AbstractTagConfig {
987
1017
  // src/model/config/CardVariantConfig.ts
988
1018
  var CardVariantConfig = class {
989
1019
  // Body text format. Default: bitmark++
990
- constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
1020
+ constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format, htmlKey, hasHtmlKey = false) {
991
1021
  __publicField(this, "tags");
992
1022
  __publicField(this, "bodyAllowed");
993
1023
  // Default: true
@@ -1001,6 +1031,9 @@ var CardVariantConfig = class {
1001
1031
  __publicField(this, "exportJsonKey");
1002
1032
  // New JSON-pattern jsonKey
1003
1033
  __publicField(this, "hasExportJsonKey");
1034
+ __publicField(this, "htmlKey");
1035
+ // HTML key-pattern
1036
+ __publicField(this, "hasHtmlKey");
1004
1037
  __publicField(this, "format");
1005
1038
  this.tags = tags2;
1006
1039
  this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
@@ -1009,6 +1042,8 @@ var CardVariantConfig = class {
1009
1042
  this.jsonKey = jsonKey;
1010
1043
  this.exportJsonKey = exportJsonKey;
1011
1044
  this.hasExportJsonKey = hasExportJsonKey;
1045
+ this.htmlKey = htmlKey;
1046
+ this.hasHtmlKey = hasHtmlKey;
1012
1047
  this.format = format;
1013
1048
  }
1014
1049
  toString(options) {
@@ -1033,18 +1068,22 @@ ${tag.toString(opts)}`;
1033
1068
 
1034
1069
  // src/model/config/CardSideConfig.ts
1035
1070
  var CardSideConfig = class {
1036
- constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
1071
+ constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false, htmlKey, hasHtmlKey = false) {
1037
1072
  __publicField(this, "name");
1038
1073
  __publicField(this, "repeat");
1039
1074
  __publicField(this, "jsonKey");
1040
1075
  __publicField(this, "exportJsonKey");
1041
1076
  __publicField(this, "hasExportJsonKey");
1077
+ __publicField(this, "htmlKey");
1078
+ __publicField(this, "hasHtmlKey");
1042
1079
  __publicField(this, "variants");
1043
1080
  this.name = name;
1044
1081
  this.repeat = repeat;
1045
1082
  this.jsonKey = jsonKey;
1046
1083
  this.exportJsonKey = exportJsonKey;
1047
1084
  this.hasExportJsonKey = hasExportJsonKey;
1085
+ this.htmlKey = htmlKey;
1086
+ this.hasHtmlKey = hasHtmlKey;
1048
1087
  this.variants = variants;
1049
1088
  }
1050
1089
  toString(options) {
@@ -1066,17 +1105,21 @@ var CardSideConfig = class {
1066
1105
 
1067
1106
  // src/model/config/CardSetConfig.ts
1068
1107
  var CardSetConfig = class {
1069
- constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
1108
+ constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides, htmlKey = void 0, hasHtmlKey = false) {
1070
1109
  __publicField(this, "configKey");
1071
1110
  __publicField(this, "jsonKey");
1072
1111
  __publicField(this, "exportJsonKey");
1073
1112
  __publicField(this, "hasExportJsonKey");
1113
+ __publicField(this, "htmlKey");
1114
+ __publicField(this, "hasHtmlKey");
1074
1115
  __publicField(this, "sections");
1075
1116
  __publicField(this, "sides");
1076
1117
  this.configKey = configKey;
1077
1118
  this.jsonKey = jsonKey;
1078
1119
  this.exportJsonKey = exportJsonKey;
1079
1120
  this.hasExportJsonKey = hasExportJsonKey;
1121
+ this.htmlKey = htmlKey;
1122
+ this.hasHtmlKey = hasHtmlKey;
1080
1123
  this.sections = sections;
1081
1124
  this.sides = sides;
1082
1125
  }
@@ -3756,6 +3799,16 @@ var CARDSETS = {
3756
3799
  [CardSetConfigKey.table]: {
3757
3800
  jsonKey: null,
3758
3801
  exportJsonKey: null,
3802
+ // PLAN-109 / HTML.md §8 — idiomatic HTML mapping. The classic (non-extended)
3803
+ // table produces the same `<table>`/`<thead>`/`<tbody>`/`<tfoot>` structure as
3804
+ // table-extended, so the structural htmlKeys mirror that cardSet. NOTE: the
3805
+ // JSON side routes the FIRST header card → `columns` (header) and SUBSEQUENT
3806
+ // header cards → `data` (body); HTML uses a uniform `<thead>` for the whole
3807
+ // `table-header` section, so a multi-card header (e.g. a second header card
3808
+ // that JSON sends to `data`) renders as additional `<thead>` rows rather than
3809
+ // moving to `<tbody>`. Per-card header/body splitting needs engine-level
3810
+ // routing not yet expressible in the pattern vocabulary — see PLAN-109.
3811
+ htmlKey: { "@el": "table", "@children": "$" },
3759
3812
  sections: {
3760
3813
  "table-header": {
3761
3814
  // First header card's row of cells → `columns`. Subsequent header
@@ -3774,25 +3827,36 @@ var CARDSETS = {
3774
3827
  },
3775
3828
  { "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
3776
3829
  { "@bit": { table: { data: ["$"] } } }
3777
- ]
3830
+ ],
3831
+ // Header section → `<thead>` rows of `<th>`; `@tableColWidth` bubbles a
3832
+ // `width` attr onto the enclosing `<th>` (HTML-C2).
3833
+ htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
3834
+ sideHtmlKey: { "@el": "th", "@children": "$" }
3778
3835
  },
3779
3836
  "table-body": {
3780
3837
  // Batched emission: `$` is the entire 2D array of body card rows.
3781
3838
  // This is the default section (no qualifier → cards land here).
3782
3839
  jsonKey: "table.data",
3783
3840
  exportJsonKey: { "@bit": { table: { data: "$" } } },
3841
+ htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
3784
3842
  isDefault: true
3785
3843
  },
3786
3844
  "table-footer": {
3787
3845
  // Batched emission: `$` is the entire 2D array of footer rows.
3788
3846
  jsonKey: "table.data",
3789
- exportJsonKey: { "@bit": { table: { data: "$" } } }
3847
+ exportJsonKey: { "@bit": { table: { data: "$" } } },
3848
+ // Footer cells route to `data` (not `columns`), so they are `<td>` (no
3849
+ // sideHtmlKey override — the cell side default applies).
3850
+ htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } }
3790
3851
  }
3791
3852
  },
3792
3853
  sides: [
3793
3854
  {
3794
3855
  name: "cell",
3795
3856
  repeat: true,
3857
+ // Default (body/footer) cell → `<td>`; the header section overrides to
3858
+ // `<th>` via its sideHtmlKey (HTML.md §8).
3859
+ htmlKey: { "@el": "td", "@children": "$" },
3796
3860
  variants: [
3797
3861
  {
3798
3862
  jsonKey: null,
@@ -3809,6 +3873,8 @@ var CARDSETS = {
3809
3873
  },
3810
3874
  {
3811
3875
  key: ConfigKey.property_tableCellType,
3876
+ // HTML.md §8: first-match predicate selecting `<th>` vs `<td>`.
3877
+ htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
3812
3878
  description: "Table cell type (th/td).",
3813
3879
  format: TagFormat.plainText
3814
3880
  },
@@ -3831,6 +3897,9 @@ var CARDSETS = {
3831
3897
  key: ConfigKey.property_tableColWidth,
3832
3898
  jsonKey: "^table.columnWidths[{s}]",
3833
3899
  exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
3900
+ // HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
3901
+ // enclosing cell element (`<th>`/`<td>`).
3902
+ htmlKey: { "@el": { "@attr": { width: "$" } } },
3834
3903
  description: "Width for the column.",
3835
3904
  format: TagFormat.number
3836
3905
  }
@@ -3846,6 +3915,12 @@ var CARDSETS = {
3846
3915
  //
3847
3916
  [CardSetConfigKey.tableExtended]: {
3848
3917
  jsonKey: null,
3918
+ // PLAN-109 / HTML.md §8 — idiomatic HTML mapping for the extended table.
3919
+ // The card-set container is the `<table>` element; each section is a
3920
+ // table section element (`<thead>`/`<tbody>`/`<tfoot>`) whose children are
3921
+ // `<tr>` rows, and each cell side is a `<td>` (body) or `<th>` (header /
3922
+ // footer, via the section sideHtmlKey override).
3923
+ htmlKey: { "@el": "table", "@children": "$" },
3849
3924
  sections: {
3850
3925
  "table-header": {
3851
3926
  jsonKey: "table.header.rows",
@@ -3865,19 +3940,29 @@ var CARDSETS = {
3865
3940
  },
3866
3941
  { table: { header: { rows: ["$"] } } }
3867
3942
  ],
3943
+ htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
3868
3944
  sideJsonKey: "cells[{s}]|set(title=true)",
3869
- sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
3945
+ sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
3946
+ // Header cells are `<th>`. The `width` attribute is contributed by the
3947
+ // `@tableColWidth` tag, which bubbles it onto the enclosing `<th>`
3948
+ // (HTML-C2) — so it is not repeated here.
3949
+ sideHtmlKey: { "@el": "th", "@children": "$" }
3870
3950
  },
3871
3951
  "table-body": {
3872
3952
  jsonKey: "table.body.rows",
3873
3953
  exportJsonKey: { table: { body: { rows: "$" } } },
3954
+ htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
3874
3955
  isDefault: true
3875
3956
  },
3876
3957
  "table-footer": {
3877
3958
  jsonKey: "table.footer.rows",
3878
3959
  exportJsonKey: { table: { footer: { rows: "$" } } },
3960
+ htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
3879
3961
  sideJsonKey: "cells[{s}]|set(title=true)",
3880
- sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
3962
+ sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
3963
+ // Footer cells render as `<th>` (mirrors the header `title: true`
3964
+ // mapping); §8 lists only the header side, so this parallels it.
3965
+ sideHtmlKey: { "@el": "th", "@children": "$" }
3881
3966
  }
3882
3967
  },
3883
3968
  sides: [
@@ -3886,6 +3971,9 @@ var CARDSETS = {
3886
3971
  repeat: true,
3887
3972
  jsonKey: "cells[{s}]",
3888
3973
  exportJsonKey: { cells: { $s: "$" } },
3974
+ // Default (body) cell → `<td>`; the header/footer sections override the
3975
+ // side to `<th>` via their sideHtmlKey (HTML.md §8).
3976
+ htmlKey: { "@el": "td", "@children": "$" },
3889
3977
  variants: [
3890
3978
  {
3891
3979
  jsonKey: "content",
@@ -3909,6 +3997,9 @@ var CARDSETS = {
3909
3997
  key: ConfigKey.property_tableCellType,
3910
3998
  jsonKey: "title|bool(th)",
3911
3999
  exportJsonKey: [{ "@value=th": { title: true } }],
4000
+ // HTML.md §8: same first-match predicate machinery selecting
4001
+ // `<th>` vs `<td>` instead of `title:true` vs nothing.
4002
+ htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
3912
4003
  description: "Table cell type (th/td).",
3913
4004
  format: TagFormat.plainText
3914
4005
  },
@@ -3938,6 +4029,9 @@ var CARDSETS = {
3938
4029
  // PLAN-080: write to the cell's `colwidth` field.
3939
4030
  jsonKey: "colwidth",
3940
4031
  exportJsonKey: { colwidth: "$" },
4032
+ // HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
4033
+ // enclosing cell element (`<th>`/`<td>`).
4034
+ htmlKey: { "@el": { "@attr": { width: "$" } } },
3941
4035
  description: "Width for the column.",
3942
4036
  format: TagFormat.number
3943
4037
  }
@@ -6866,7 +6960,9 @@ var ConfigHydrator = class {
6866
6960
  variantsOfSide,
6867
6961
  _side.jsonKey,
6868
6962
  _side.exportJsonKey,
6869
- Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
6963
+ Object.prototype.hasOwnProperty.call(_side, "exportJsonKey"),
6964
+ _side.htmlKey,
6965
+ Object.prototype.hasOwnProperty.call(_side, "htmlKey")
6870
6966
  );
6871
6967
  sides.push(sideConfig);
6872
6968
  }
@@ -6876,7 +6972,9 @@ var ConfigHydrator = class {
6876
6972
  _cardSetConfig.exportJsonKey,
6877
6973
  Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
6878
6974
  this.hydrateCardSections(_cardSetConfig.sections),
6879
- sides
6975
+ sides,
6976
+ _cardSetConfig.htmlKey,
6977
+ Object.prototype.hasOwnProperty.call(_cardSetConfig, "htmlKey")
6880
6978
  );
6881
6979
  return cardSetConfig;
6882
6980
  }
@@ -6888,10 +6986,14 @@ var ConfigHydrator = class {
6888
6986
  jsonKey: v.jsonKey,
6889
6987
  exportJsonKey: v.exportJsonKey,
6890
6988
  hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
6989
+ htmlKey: v.htmlKey,
6990
+ hasHtmlKey: Object.prototype.hasOwnProperty.call(v, "htmlKey"),
6891
6991
  isDefault: v.isDefault,
6892
6992
  sideJsonKey: v.sideJsonKey,
6893
6993
  sideExportJsonKey: v.sideExportJsonKey,
6894
6994
  hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
6995
+ sideHtmlKey: v.sideHtmlKey,
6996
+ hasSideHtmlKey: Object.prototype.hasOwnProperty.call(v, "sideHtmlKey"),
6895
6997
  // PLAN-085: cardinality fields pass through; defaults applied
6896
6998
  // downstream by the config consumer (Rust treats `0` / undefined
6897
6999
  // as unbounded).
@@ -6909,7 +7011,8 @@ var ConfigHydrator = class {
6909
7011
  chain: _chain,
6910
7012
  deprecated,
6911
7013
  jsonKey,
6912
- exportJsonKey
7014
+ exportJsonKey,
7015
+ htmlKey
6913
7016
  } = _tag;
6914
7017
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
6915
7018
  if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
@@ -6928,6 +7031,8 @@ var ConfigHydrator = class {
6928
7031
  jsonKey,
6929
7032
  exportJsonKey,
6930
7033
  hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
7034
+ htmlKey,
7035
+ hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
6931
7036
  deprecated
6932
7037
  });
6933
7038
  return {
@@ -6947,7 +7052,8 @@ var ConfigHydrator = class {
6947
7052
  values,
6948
7053
  defaultValue,
6949
7054
  jsonKey,
6950
- exportJsonKey
7055
+ exportJsonKey,
7056
+ htmlKey
6951
7057
  } = _tag;
6952
7058
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
6953
7059
  if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
@@ -6965,6 +7071,8 @@ var ConfigHydrator = class {
6965
7071
  jsonKey,
6966
7072
  exportJsonKey,
6967
7073
  hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
7074
+ htmlKey,
7075
+ hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
6968
7076
  format,
6969
7077
  values,
6970
7078
  defaultValue,
@@ -6984,7 +7092,8 @@ var ConfigHydrator = class {
6984
7092
  chain: _chain,
6985
7093
  deprecated,
6986
7094
  jsonKey,
6987
- exportJsonKey
7095
+ exportJsonKey,
7096
+ htmlKey
6988
7097
  } = _tag;
6989
7098
  const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
6990
7099
  if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
@@ -7002,6 +7111,8 @@ var ConfigHydrator = class {
7002
7111
  jsonKey,
7003
7112
  exportJsonKey,
7004
7113
  hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
7114
+ htmlKey,
7115
+ hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
7005
7116
  deprecated
7006
7117
  });
7007
7118
  return {
@@ -7040,6 +7151,7 @@ var ConfigHydrator = class {
7040
7151
  repeatCount,
7041
7152
  jsonKey,
7042
7153
  exportJsonKey,
7154
+ htmlKey,
7043
7155
  format
7044
7156
  } = _variant;
7045
7157
  const tags2 = this.hydrateTagsConfig(_tags);
@@ -7051,7 +7163,9 @@ var ConfigHydrator = class {
7051
7163
  jsonKey,
7052
7164
  exportJsonKey,
7053
7165
  Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
7054
- format
7166
+ format,
7167
+ htmlKey,
7168
+ Object.prototype.hasOwnProperty.call(_variant, "htmlKey")
7055
7169
  );
7056
7170
  return cardSetConfig;
7057
7171
  }
@@ -10862,6 +10976,26 @@ var BITS = {
10862
10976
  baseBitType: BitType2.tableImage,
10863
10977
  description: "Standard non-normative remark table image bit, used to create non-normative remark images in tables in articles or books"
10864
10978
  },
10979
+ [BitType2.standardTableExtendedImageNormative]: {
10980
+ since: "1.16.0",
10981
+ baseBitType: BitType2.tableExtendedImage,
10982
+ description: "Standard normative extended table image bit, used to create normative extended images in tables in articles or books"
10983
+ },
10984
+ [BitType2.standardTableExtendedImageNonNormative]: {
10985
+ since: "1.16.0",
10986
+ baseBitType: BitType2.tableExtendedImage,
10987
+ description: "Standard non-normative extended table image bit, used to create non-normative extended images in tables in articles or books"
10988
+ },
10989
+ [BitType2.standardRemarkTableExtendedImageNormative]: {
10990
+ since: "1.17.0",
10991
+ baseBitType: BitType2.tableExtendedImage,
10992
+ description: "Standard normative remark extended table image bit, used to create normative remark extended images in tables in articles or books"
10993
+ },
10994
+ [BitType2.standardRemarkTableExtendedImageNonNormative]: {
10995
+ since: "1.17.0",
10996
+ baseBitType: BitType2.tableExtendedImage,
10997
+ description: "Standard non-normative remark extended table image bit, used to create non-normative remark extended images in tables in articles or books"
10998
+ },
10865
10999
  [BitType2.smartStandardTableImageNormative]: {
10866
11000
  since: "1.28.0",
10867
11001
  baseBitType: BitType2.standardTableImageNormative,
@@ -10882,6 +11016,26 @@ var BITS = {
10882
11016
  baseBitType: BitType2.standardRemarkTableImageNonNormative,
10883
11017
  description: "Smart standard non-normative remark table image bit, used to create smart standard non-normative remark images in tables in articles or books"
10884
11018
  },
11019
+ [BitType2.smartStandardTableExtendedImageNormative]: {
11020
+ since: "1.28.0",
11021
+ baseBitType: BitType2.standardTableExtendedImageNormative,
11022
+ description: "Smart standard normative extended table image bit, used to create smart standard normative extended images in tables in articles or books"
11023
+ },
11024
+ [BitType2.smartStandardTableExtendedImageNonNormative]: {
11025
+ since: "1.28.0",
11026
+ baseBitType: BitType2.standardTableExtendedImageNonNormative,
11027
+ description: "Smart standard non-normative extended table image bit, used to create smart standard non-normative extended images in tables in articles or books"
11028
+ },
11029
+ [BitType2.smartStandardRemarkTableExtendedImageNormative]: {
11030
+ since: "1.28.0",
11031
+ baseBitType: BitType2.standardRemarkTableExtendedImageNormative,
11032
+ description: "Smart standard normative remark extended table image bit, used to create smart standard normative remark extended images in tables in articles or books"
11033
+ },
11034
+ [BitType2.smartStandardRemarkTableExtendedImageNonNormative]: {
11035
+ since: "1.28.0",
11036
+ baseBitType: BitType2.standardRemarkTableExtendedImageNonNormative,
11037
+ description: "Smart standard non-normative remark extended table image bit, used to create smart standard non-normative remark extended images in tables in articles or books"
11038
+ },
10885
11039
  [BitType2.smartStandardTableImageNormativeCollapsible]: {
10886
11040
  since: "1.28.0",
10887
11041
  baseBitType: BitType2.smartStandardTableImageNormative,
@@ -10902,6 +11056,26 @@ var BITS = {
10902
11056
  baseBitType: BitType2.smartStandardRemarkTableImageNonNormative,
10903
11057
  description: "Collapsible smart standard non-normative remark table image bit, used to create collapsible smart standard non-normative remark images in tables in articles or books"
10904
11058
  },
11059
+ [BitType2.smartStandardTableExtendedImageNormativeCollapsible]: {
11060
+ since: "1.28.0",
11061
+ baseBitType: BitType2.smartStandardTableExtendedImageNormative,
11062
+ description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
11063
+ },
11064
+ [BitType2.smartStandardTableExtendedImageNonNormativeCollapsible]: {
11065
+ since: "1.28.0",
11066
+ baseBitType: BitType2.smartStandardTableExtendedImageNonNormative,
11067
+ description: "Collapsible smart standard non-normative extended table image bit, used to create collapsible smart standard non-normative extended images in tables in articles or books"
11068
+ },
11069
+ [BitType2.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
11070
+ since: "1.28.0",
11071
+ baseBitType: BitType2.smartStandardRemarkTableExtendedImageNormative,
11072
+ description: "Collapsible smart standard normative remark extended table image bit, used to create collapsible smart standard normative remark extended images in tables in articles or books"
11073
+ },
11074
+ [BitType2.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
11075
+ since: "1.28.0",
11076
+ baseBitType: BitType2.smartStandardRemarkTableExtendedImageNonNormative,
11077
+ description: "Collapsible smart standard non-normative remark extended table image bit, used to create collapsible smart standard non-normative remark extended images in tables in articles or books"
11078
+ },
10905
11079
  [BitType2.imageLink]: {
10906
11080
  since: "1.3.0",
10907
11081
  baseBitType: BitType2._standard,
@@ -12578,6 +12752,26 @@ var BITS = {
12578
12752
  baseBitType: BitType2.table,
12579
12753
  description: "Standard non-normative remark table bit, used to create standard non-normative remark tables in articles or books"
12580
12754
  },
12755
+ [BitType2.standardTableExtendedNormative]: {
12756
+ since: "1.16.0",
12757
+ baseBitType: BitType2.tableExtended,
12758
+ description: "Standard normative extended table bit, used to create standard normative extended tables in articles or books"
12759
+ },
12760
+ [BitType2.standardTableExtendedNonNormative]: {
12761
+ since: "1.16.0",
12762
+ baseBitType: BitType2.tableExtended,
12763
+ description: "Standard non-normative extended table bit, used to create standard non-normative extended tables in articles or books"
12764
+ },
12765
+ [BitType2.standardRemarkTableExtendedNormative]: {
12766
+ since: "1.17.0",
12767
+ baseBitType: BitType2.tableExtended,
12768
+ description: "Standard normative remark extended table bit, used to create standard normative remark extended tables in articles or books"
12769
+ },
12770
+ [BitType2.standardRemarkTableExtendedNonNormative]: {
12771
+ since: "1.17.0",
12772
+ baseBitType: BitType2.tableExtended,
12773
+ description: "Standard non-normative remark extended table bit, used to create standard non-normative remark extended tables in articles or books"
12774
+ },
12581
12775
  [BitType2.smartStandardTableNormative]: {
12582
12776
  since: "1.28.0",
12583
12777
  baseBitType: BitType2.standardTableNormative,
@@ -12598,6 +12792,26 @@ var BITS = {
12598
12792
  baseBitType: BitType2.standardRemarkTableNonNormative,
12599
12793
  description: "Smart standard non-normative remark table bit, used to create smart standard non-normative remark tables in articles or books"
12600
12794
  },
12795
+ [BitType2.smartStandardTableExtendedNormative]: {
12796
+ since: "1.28.0",
12797
+ baseBitType: BitType2.standardTableExtendedNormative,
12798
+ description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
12799
+ },
12800
+ [BitType2.smartStandardTableExtendedNonNormative]: {
12801
+ since: "1.28.0",
12802
+ baseBitType: BitType2.standardTableExtendedNonNormative,
12803
+ description: "Smart standard non-normative extended table bit, used to create smart standard non-normative extended tables in articles or books"
12804
+ },
12805
+ [BitType2.smartStandardRemarkTableExtendedNormative]: {
12806
+ since: "1.28.0",
12807
+ baseBitType: BitType2.standardRemarkTableExtendedNormative,
12808
+ description: "Smart standard normative remark extended table bit, used to create smart standard normative remark extended tables in articles or books"
12809
+ },
12810
+ [BitType2.smartStandardRemarkTableExtendedNonNormative]: {
12811
+ since: "1.28.0",
12812
+ baseBitType: BitType2.standardRemarkTableExtendedNonNormative,
12813
+ description: "Smart standard non-normative remark extended table bit, used to create smart standard non-normative remark extended tables in articles or books"
12814
+ },
12601
12815
  [BitType2.smartStandardTableNormativeCollapsible]: {
12602
12816
  since: "1.28.0",
12603
12817
  baseBitType: BitType2.smartStandardTableNormative,
@@ -12618,6 +12832,26 @@ var BITS = {
12618
12832
  baseBitType: BitType2.smartStandardRemarkTableNonNormative,
12619
12833
  description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
12620
12834
  },
12835
+ [BitType2.smartStandardTableExtendedNormativeCollapsible]: {
12836
+ since: "1.28.0",
12837
+ baseBitType: BitType2.smartStandardTableExtendedNormative,
12838
+ description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
12839
+ },
12840
+ [BitType2.smartStandardTableExtendedNonNormativeCollapsible]: {
12841
+ since: "1.28.0",
12842
+ baseBitType: BitType2.smartStandardTableExtendedNonNormative,
12843
+ description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
12844
+ },
12845
+ [BitType2.smartStandardRemarkTableExtendedNormativeCollapsible]: {
12846
+ since: "1.28.0",
12847
+ baseBitType: BitType2.smartStandardRemarkTableExtendedNormative,
12848
+ description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
12849
+ },
12850
+ [BitType2.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
12851
+ since: "1.28.0",
12852
+ baseBitType: BitType2.smartStandardRemarkTableExtendedNonNormative,
12853
+ description: "Collapsible smart standard non-normative remark extended table bit, used to create collapsible smart standard non-normative remark extended tables in articles or books"
12854
+ },
12621
12855
  [BitType2.parameters]: {
12622
12856
  since: "1.18.0",
12623
12857
  baseBitType: BitType2.table,
@@ -13559,6 +13793,8 @@ var Config = class {
13559
13793
  jsonKey: tag.jsonKey,
13560
13794
  exportJsonKey: tag.exportJsonKey,
13561
13795
  hasExportJsonKey: tag.hasExportJsonKey,
13796
+ htmlKey: tag.htmlKey,
13797
+ hasHtmlKey: tag.hasHtmlKey,
13562
13798
  deprecated: tag.deprecated
13563
13799
  });
13564
13800
  finalResourceTags[k] = newTag;
@@ -13663,7 +13899,7 @@ var instance2 = new Config();
13663
13899
  // src/generated/package_info.ts
13664
13900
  var PACKAGE_INFO = {
13665
13901
  "name": "@gmb/bitmark-parser-generator",
13666
- "version": "5.25.0",
13902
+ "version": "5.27.0",
13667
13903
  "author": "Get More Brain Ltd",
13668
13904
  "license": "ISC",
13669
13905
  "description": "A bitmark parser and generator using Peggy.js"
@@ -33019,6 +33255,235 @@ var BitmarkStringGenerator = class {
33019
33255
  }
33020
33256
  };
33021
33257
 
33258
+ // src/generator/html/HtmlTableGenerator.ts
33259
+ var MARK_TO_TAG = {
33260
+ bold: "b",
33261
+ italic: "i",
33262
+ superscript: "sup",
33263
+ subscript: "sub",
33264
+ strike: "s",
33265
+ del: "del",
33266
+ ins: "ins",
33267
+ underline: "u",
33268
+ highlight: "mark",
33269
+ code: "code"
33270
+ };
33271
+ var HtmlTableGenerator = class {
33272
+ constructor() {
33273
+ __publicField(this, "indentUnit", " ");
33274
+ }
33275
+ /**
33276
+ * Generate HTML table fragments from a string or JSON value.
33277
+ * @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
33278
+ */
33279
+ generate(input) {
33280
+ let data = input;
33281
+ if (typeof data === "string") {
33282
+ try {
33283
+ data = JSON.parse(data);
33284
+ } catch {
33285
+ return "";
33286
+ }
33287
+ }
33288
+ const bits = this.collectBits(data);
33289
+ const fragments = [];
33290
+ for (const bit of bits) {
33291
+ const html = this.renderTableBit(bit);
33292
+ if (html) fragments.push(html);
33293
+ }
33294
+ return fragments.join("\n\n");
33295
+ }
33296
+ // --- bit collection -------------------------------------------------------
33297
+ collectBits(data) {
33298
+ const out = [];
33299
+ const visit = (value) => {
33300
+ if (value == null || typeof value !== "object") return;
33301
+ if (Array.isArray(value)) {
33302
+ value.forEach(visit);
33303
+ return;
33304
+ }
33305
+ const obj = value;
33306
+ if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
33307
+ out.push(obj.bit);
33308
+ } else if ("type" in obj) {
33309
+ out.push(obj);
33310
+ }
33311
+ };
33312
+ visit(data);
33313
+ return out;
33314
+ }
33315
+ // --- table rendering ------------------------------------------------------
33316
+ renderTableBit(bit) {
33317
+ const table = bit.table;
33318
+ if (!table) return "";
33319
+ if (bit.type !== "table" && bit.type !== "table-extended") return "";
33320
+ const extended = this.toExtended(table);
33321
+ const lines = [];
33322
+ lines.push("<table>");
33323
+ if (bit.caption != null) {
33324
+ const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
33325
+ if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
33326
+ }
33327
+ this.renderSection(lines, "thead", extended.header, "header");
33328
+ this.renderSection(lines, "tbody", extended.body, "body");
33329
+ this.renderSection(lines, "tfoot", extended.footer, "footer");
33330
+ lines.push("</table>");
33331
+ return lines.join("\n");
33332
+ }
33333
+ toExtended(table) {
33334
+ const t = table;
33335
+ if (t.header || t.body || t.footer) return table;
33336
+ return convertBasicToExtendedTableFormat(table);
33337
+ }
33338
+ renderSection(lines, tag, section, key) {
33339
+ if (!section || !section.rows || section.rows.length === 0) return;
33340
+ lines.push(`${this.indentUnit}<${tag}>`);
33341
+ for (const row of section.rows) {
33342
+ lines.push(`${this.indentUnit.repeat(2)}<tr>`);
33343
+ for (const cell of row.cells ?? []) {
33344
+ lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
33345
+ }
33346
+ lines.push(`${this.indentUnit.repeat(2)}</tr>`);
33347
+ }
33348
+ lines.push(`${this.indentUnit}</${tag}>`);
33349
+ }
33350
+ renderCell(cell, _key) {
33351
+ const tag = cell.title === true ? "th" : "td";
33352
+ const attrs = [];
33353
+ if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
33354
+ if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
33355
+ if (cell.scope) attrs.push(`scope="${cell.scope}"`);
33356
+ if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
33357
+ const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
33358
+ return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
33359
+ }
33360
+ // --- cell content (TextAst -> HTML) ---------------------------------------
33361
+ asTextAst(content) {
33362
+ if (content == null) return [];
33363
+ if (typeof content === "string") return [{ type: "text", text: content }];
33364
+ return content;
33365
+ }
33366
+ cellContentToHtml(blocks) {
33367
+ if (blocks.length === 0) return "";
33368
+ if (blocks.length === 1 && blocks[0].type === "paragraph") {
33369
+ return this.inlineToHtml(blocks[0].content ?? []);
33370
+ }
33371
+ return blocks.map((b) => this.blockToHtml(b)).join("");
33372
+ }
33373
+ blockToHtml(node) {
33374
+ switch (node.type) {
33375
+ case "paragraph":
33376
+ return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
33377
+ case "bulletList":
33378
+ case "noBulletList":
33379
+ case "orderedList":
33380
+ case "orderedListRoman":
33381
+ case "orderedListRomanLower":
33382
+ case "letteredList":
33383
+ case "letteredListLower":
33384
+ case "taskList":
33385
+ return this.listToHtml(node);
33386
+ case "image":
33387
+ case "imageInline":
33388
+ return this.imageToHtml(node);
33389
+ default:
33390
+ return this.inlineToHtml([node]);
33391
+ }
33392
+ }
33393
+ inlineToHtml(nodes) {
33394
+ return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
33395
+ }
33396
+ inlineNodeToHtml(node) {
33397
+ if (node.type === "hardBreak") return "<br>";
33398
+ if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
33399
+ if (node.type === "text") {
33400
+ return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
33401
+ }
33402
+ if (node.content) return this.inlineToHtml(node.content);
33403
+ return this.escapeText(node.text ?? "");
33404
+ }
33405
+ wrapMarks(text, marks) {
33406
+ if (!marks || marks.length === 0) return text;
33407
+ let open = "";
33408
+ let close = "";
33409
+ for (const mark of marks) {
33410
+ if (mark.type === "link") {
33411
+ const href = mark.attrs?.href ?? "";
33412
+ open += `<a href="${this.escapeAttr(href)}">`;
33413
+ close = `</a>${close}`;
33414
+ } else {
33415
+ const tag = MARK_TO_TAG[mark.type];
33416
+ if (tag) {
33417
+ open += `<${tag}>`;
33418
+ close = `</${tag}>${close}`;
33419
+ }
33420
+ }
33421
+ }
33422
+ return `${open}${text}${close}`;
33423
+ }
33424
+ // --- lists ----------------------------------------------------------------
33425
+ listToHtml(node) {
33426
+ const { tag, attrs } = this.listTag(node);
33427
+ const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
33428
+ return `<${tag}${attrs}>${items}</${tag}>`;
33429
+ }
33430
+ listTag(node) {
33431
+ const start = node.attrs?.start;
33432
+ const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
33433
+ switch (node.type) {
33434
+ case "orderedList":
33435
+ return { tag: "ol", attrs: startAttr };
33436
+ case "orderedListRoman":
33437
+ return { tag: "ol", attrs: ` type="I"${startAttr}` };
33438
+ case "orderedListRomanLower":
33439
+ return { tag: "ol", attrs: ` type="i"${startAttr}` };
33440
+ case "letteredList":
33441
+ return { tag: "ol", attrs: ` type="A"${startAttr}` };
33442
+ case "letteredListLower":
33443
+ return { tag: "ol", attrs: ` type="a"${startAttr}` };
33444
+ case "noBulletList":
33445
+ return { tag: "ul", attrs: ' style="list-style:none"' };
33446
+ case "taskList":
33447
+ case "bulletList":
33448
+ default:
33449
+ return { tag: "ul", attrs: "" };
33450
+ }
33451
+ }
33452
+ listItemToHtml(item, task) {
33453
+ const inner = (item.content ?? []).map((b) => {
33454
+ if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
33455
+ return this.blockToHtml(b);
33456
+ }).join("");
33457
+ if (task) {
33458
+ const checked = item.attrs?.checked ? " checked" : "";
33459
+ return `<li><input type="checkbox"${checked}>${inner}</li>`;
33460
+ }
33461
+ return `<li>${inner}</li>`;
33462
+ }
33463
+ // --- images ---------------------------------------------------------------
33464
+ imageToHtml(node) {
33465
+ const attrs = node.attrs ?? {};
33466
+ const parts = [];
33467
+ const src = attrs.src;
33468
+ parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
33469
+ if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
33470
+ if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
33471
+ if (attrs.width != null) parts.push(`width="${attrs.width}"`);
33472
+ if (attrs.height != null) parts.push(`height="${attrs.height}"`);
33473
+ if (typeof attrs.class === "string" && attrs.class) {
33474
+ parts.push(`class="${this.escapeAttr(attrs.class)}"`);
33475
+ }
33476
+ return `<img ${parts.join(" ")}>`;
33477
+ }
33478
+ // --- escaping -------------------------------------------------------------
33479
+ escapeText(text) {
33480
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
33481
+ }
33482
+ escapeAttr(text) {
33483
+ return this.escapeText(text).replace(/"/g, "&quot;");
33484
+ }
33485
+ };
33486
+
33022
33487
  // src/generator/json/JsonGenerator.ts
33023
33488
  var import_superenum33 = require("@ncoderz/superenum");
33024
33489
  var MOVE_BODY_RECURSION_LIMIT = 5e3;
@@ -37946,6 +38411,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
37946
38411
  jsonKey: void 0,
37947
38412
  exportJsonKey: void 0,
37948
38413
  hasExportJsonKey: false,
38414
+ htmlKey: void 0,
38415
+ hasHtmlKey: false,
37949
38416
  format: TagFormat.bitmarkText,
37950
38417
  values: void 0,
37951
38418
  defaultValue: void 0,
@@ -42325,6 +42792,499 @@ var BitmarkParser = class {
42325
42792
  }
42326
42793
  };
42327
42794
 
42795
+ // src/parser/html/HtmlDom.ts
42796
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
42797
+ "area",
42798
+ "base",
42799
+ "br",
42800
+ "col",
42801
+ "embed",
42802
+ "hr",
42803
+ "img",
42804
+ "input",
42805
+ "link",
42806
+ "meta",
42807
+ "param",
42808
+ "source",
42809
+ "track",
42810
+ "wbr"
42811
+ ]);
42812
+ var IMPLIED_CLOSE = {
42813
+ li: /* @__PURE__ */ new Set(["li"]),
42814
+ td: /* @__PURE__ */ new Set(["td", "th"]),
42815
+ th: /* @__PURE__ */ new Set(["td", "th"]),
42816
+ tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
42817
+ thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
42818
+ tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
42819
+ tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
42820
+ p: /* @__PURE__ */ new Set(["p"]),
42821
+ option: /* @__PURE__ */ new Set(["option"])
42822
+ };
42823
+ var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
42824
+ var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
42825
+ function parseAttrs(raw) {
42826
+ const attrs = {};
42827
+ if (!raw) return attrs;
42828
+ ATTR_RE.lastIndex = 0;
42829
+ let m;
42830
+ while ((m = ATTR_RE.exec(raw)) !== null) {
42831
+ const name = m[1].toLowerCase();
42832
+ let value = m[2] ?? "";
42833
+ if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
42834
+ value = value.slice(1, -1);
42835
+ }
42836
+ attrs[name] = value;
42837
+ }
42838
+ return attrs;
42839
+ }
42840
+ function stripNonContent(html) {
42841
+ return html.replace(/<!--[\s\S]*?-->/g, "").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, "").replace(/<!doctype[^>]*>/gi, "").replace(/<script\b[\s\S]*?<\/script>/gi, "").replace(/<style\b[\s\S]*?<\/style>/gi, "");
42842
+ }
42843
+ function tokenize(html) {
42844
+ const tokens = [];
42845
+ const clean = stripNonContent(html);
42846
+ TAG_RE.lastIndex = 0;
42847
+ let lastIndex = 0;
42848
+ let m;
42849
+ while ((m = TAG_RE.exec(clean)) !== null) {
42850
+ if (m.index > lastIndex) {
42851
+ tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
42852
+ }
42853
+ lastIndex = TAG_RE.lastIndex;
42854
+ const isClose = m[1] === "/";
42855
+ const name = m[2].toLowerCase();
42856
+ if (isClose) {
42857
+ tokens.push({ kind: "close", name });
42858
+ } else {
42859
+ tokens.push({
42860
+ kind: "open",
42861
+ name,
42862
+ attrs: parseAttrs(m[3]),
42863
+ selfClose: m[4] === "/"
42864
+ });
42865
+ }
42866
+ }
42867
+ if (lastIndex < clean.length) {
42868
+ tokens.push({ kind: "text", text: clean.slice(lastIndex) });
42869
+ }
42870
+ return tokens;
42871
+ }
42872
+ function parseHtml(html) {
42873
+ const root = { type: "element", name: "#root", attrs: {}, children: [] };
42874
+ const stack = [root];
42875
+ const top = () => stack[stack.length - 1];
42876
+ for (const token of tokenize(html)) {
42877
+ if (token.kind === "text") {
42878
+ if (token.text) top().children.push({ type: "text", value: token.text });
42879
+ continue;
42880
+ }
42881
+ if (token.kind === "open") {
42882
+ const name = token.name;
42883
+ const closes = IMPLIED_CLOSE[name];
42884
+ if (closes) {
42885
+ while (stack.length > 1 && closes.has(top().name)) stack.pop();
42886
+ }
42887
+ const el = {
42888
+ type: "element",
42889
+ name,
42890
+ attrs: token.attrs ?? {},
42891
+ children: []
42892
+ };
42893
+ top().children.push(el);
42894
+ if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
42895
+ stack.push(el);
42896
+ }
42897
+ continue;
42898
+ }
42899
+ for (let i = stack.length - 1; i > 0; i--) {
42900
+ if (stack[i].name === token.name) {
42901
+ stack.length = i;
42902
+ break;
42903
+ }
42904
+ }
42905
+ }
42906
+ return root.children;
42907
+ }
42908
+ function childElements(el, names) {
42909
+ return el.children.filter((c) => c.type === "element" && names.has(c.name));
42910
+ }
42911
+
42912
+ // src/parser/html/HtmlTableParser.ts
42913
+ var MARK_TAGS = {
42914
+ b: "bold",
42915
+ strong: "bold",
42916
+ i: "italic",
42917
+ em: "italic",
42918
+ sup: "superscript",
42919
+ sub: "subscript",
42920
+ s: "strike",
42921
+ strike: "strike",
42922
+ del: "del",
42923
+ ins: "ins",
42924
+ u: "underline",
42925
+ mark: "highlight",
42926
+ code: "code"
42927
+ };
42928
+ var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
42929
+ var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
42930
+ var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
42931
+ var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
42932
+ var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
42933
+ var NAMED_ENTITIES = {
42934
+ amp: "&",
42935
+ lt: "<",
42936
+ gt: ">",
42937
+ quot: '"',
42938
+ apos: "'",
42939
+ nbsp: "\xA0"
42940
+ };
42941
+ function decodeEntities(text) {
42942
+ return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
42943
+ if (body[0] === "#") {
42944
+ const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
42945
+ if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
42946
+ try {
42947
+ return String.fromCodePoint(code);
42948
+ } catch {
42949
+ return whole;
42950
+ }
42951
+ }
42952
+ return whole;
42953
+ }
42954
+ return NAMED_ENTITIES[body] ?? whole;
42955
+ });
42956
+ }
42957
+ function intAttr(value) {
42958
+ if (value == null) return void 0;
42959
+ const n = Number.parseInt(value, 10);
42960
+ return Number.isInteger(n) ? n : void 0;
42961
+ }
42962
+ function isElement(node) {
42963
+ return node.type === "element";
42964
+ }
42965
+ var HtmlTableParser = class {
42966
+ constructor() {
42967
+ __publicField(this, "keepUnknownTags", false);
42968
+ }
42969
+ /**
42970
+ * Parse an HTML string and return one table bit per top-level `<table>`.
42971
+ */
42972
+ parse(html, options) {
42973
+ this.keepUnknownTags = options?.keepUnknownTags ?? false;
42974
+ const tableFormat = options?.tableFormat ?? "table-extended";
42975
+ const onWarning = options?.onWarning;
42976
+ const tables = this.collectTopLevelTables(parseHtml(html));
42977
+ const bits = [];
42978
+ for (const table of tables) {
42979
+ const bit = this.tableToBit(table, tableFormat, onWarning);
42980
+ if (bit) bits.push(bit);
42981
+ }
42982
+ return bits;
42983
+ }
42984
+ // --- table extraction -----------------------------------------------------
42985
+ /** Collect every `<table>` element, NOT descending into nested tables. */
42986
+ collectTopLevelTables(nodes) {
42987
+ const tables = [];
42988
+ const visit = (node) => {
42989
+ if (!isElement(node)) return;
42990
+ if (node.name === "table") {
42991
+ tables.push(node);
42992
+ return;
42993
+ }
42994
+ node.children.forEach(visit);
42995
+ };
42996
+ nodes.forEach(visit);
42997
+ return tables;
42998
+ }
42999
+ tableToBit(table, tableFormat, onWarning) {
43000
+ const header = [];
43001
+ const body = [];
43002
+ const footer = [];
43003
+ let caption;
43004
+ for (const child of table.children) {
43005
+ if (!isElement(child)) continue;
43006
+ if (child.name === "caption") {
43007
+ const capContent = this.inlineNodes(child.children, []);
43008
+ const trimmed = this.trimInline(capContent);
43009
+ if (trimmed.length > 0) caption = trimmed;
43010
+ } else if (SECTION_TAGS.has(child.name)) {
43011
+ const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
43012
+ for (const tr of childElements(child, ROW_TAGS)) {
43013
+ target.push(this.rowToCells(tr));
43014
+ }
43015
+ } else if (ROW_TAGS.has(child.name)) {
43016
+ body.push(this.rowToCells(child));
43017
+ }
43018
+ }
43019
+ if (header.length === 0 && body.length === 0 && footer.length === 0) {
43020
+ return void 0;
43021
+ }
43022
+ const tableExtended = {};
43023
+ if (header.length > 0) tableExtended.header = { rows: header };
43024
+ if (body.length > 0) tableExtended.body = { rows: body };
43025
+ if (footer.length > 0) tableExtended.footer = { rows: footer };
43026
+ let tableData = tableExtended;
43027
+ if (tableFormat === "table") {
43028
+ if (this.isLossyAsBasic(tableExtended)) {
43029
+ onWarning?.(
43030
+ "Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
43031
+ );
43032
+ }
43033
+ tableData = convertExtendedToBasicTableFormat(tableExtended);
43034
+ }
43035
+ const bit = {
43036
+ type: tableFormat,
43037
+ format: "bitmark++",
43038
+ table: tableData
43039
+ };
43040
+ if (caption) bit.caption = caption;
43041
+ return bit;
43042
+ }
43043
+ rowToCells(tr) {
43044
+ const cells = [];
43045
+ for (const cell of childElements(tr, CELL_TAGS)) {
43046
+ cells.push(this.cellToJson(cell));
43047
+ }
43048
+ return { cells };
43049
+ }
43050
+ cellToJson(cell) {
43051
+ const json = {
43052
+ content: this.blockNodes(cell.children)
43053
+ };
43054
+ if (cell.name === "th") json.title = true;
43055
+ const rowspan = intAttr(cell.attrs.rowspan);
43056
+ if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
43057
+ const colspan = intAttr(cell.attrs.colspan);
43058
+ if (colspan != null && colspan >= 2) json.colspan = colspan;
43059
+ const scope = cell.attrs.scope?.toLowerCase();
43060
+ if (scope && VALID_SCOPES.has(scope)) {
43061
+ json.scope = scope;
43062
+ }
43063
+ const width = this.widthFromCell(cell);
43064
+ if (width != null) json.colwidth = width;
43065
+ return json;
43066
+ }
43067
+ widthFromCell(cell) {
43068
+ const attrWidth = intAttr(cell.attrs.width);
43069
+ if (attrWidth != null && attrWidth > 0) return attrWidth;
43070
+ const style = cell.attrs.style;
43071
+ if (style) {
43072
+ const m = style.match(/width\s*:\s*(\d+)\s*px/i);
43073
+ if (m) {
43074
+ const n = Number.parseInt(m[1], 10);
43075
+ if (Number.isInteger(n) && n > 0) return n;
43076
+ }
43077
+ }
43078
+ return void 0;
43079
+ }
43080
+ isLossyAsBasic(table) {
43081
+ if (table.footer) return true;
43082
+ if (table.header && table.header.rows.length > 1) return true;
43083
+ const sections = [table.header, table.body, table.footer];
43084
+ for (const section of sections) {
43085
+ if (!section) continue;
43086
+ for (const row of section.rows) {
43087
+ for (const cell of row.cells) {
43088
+ if (cell.rowspan || cell.colspan || cell.scope) return true;
43089
+ }
43090
+ }
43091
+ }
43092
+ return false;
43093
+ }
43094
+ // --- content conversion (HTML -> TextAst) ---------------------------------
43095
+ /**
43096
+ * Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
43097
+ */
43098
+ blockNodes(nodes) {
43099
+ const blocks = [];
43100
+ let inline = [];
43101
+ const flush = () => {
43102
+ const trimmed = this.trimInline(inline);
43103
+ inline = [];
43104
+ if (trimmed.length === 0) return;
43105
+ if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
43106
+ blocks.push({ ...trimmed[0], type: "image" });
43107
+ } else {
43108
+ blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
43109
+ }
43110
+ };
43111
+ for (const node of nodes) {
43112
+ if (!isElement(node)) {
43113
+ inline.push(...this.inlineText(node.value, []));
43114
+ continue;
43115
+ }
43116
+ const name = node.name;
43117
+ if (name === "p") {
43118
+ flush();
43119
+ const content = this.trimInline(this.inlineNodes(node.children, []));
43120
+ if (content.length > 0) {
43121
+ blocks.push({ type: "paragraph", content, attrs: {} });
43122
+ }
43123
+ } else if (this.isListTag(name)) {
43124
+ flush();
43125
+ const list = this.listNode(node);
43126
+ if (list) blocks.push(list);
43127
+ } else {
43128
+ inline.push(...this.inlineFromElement(node, []));
43129
+ }
43130
+ }
43131
+ flush();
43132
+ return blocks;
43133
+ }
43134
+ /** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
43135
+ inlineNodes(nodes, marks) {
43136
+ const out = [];
43137
+ for (const node of nodes) {
43138
+ if (!isElement(node)) {
43139
+ out.push(...this.inlineText(node.value, marks));
43140
+ } else {
43141
+ out.push(...this.inlineFromElement(node, marks));
43142
+ }
43143
+ }
43144
+ return out;
43145
+ }
43146
+ inlineFromElement(el, marks) {
43147
+ const name = el.name;
43148
+ if (name === "br") {
43149
+ return [{ type: "hardBreak" }];
43150
+ }
43151
+ if (name === "img") {
43152
+ return [this.imageNode(el, true)];
43153
+ }
43154
+ const markType = MARK_TAGS[name];
43155
+ if (markType) {
43156
+ return this.inlineNodes(el.children, [...marks, { type: markType }]);
43157
+ }
43158
+ if (name === "a") {
43159
+ const linkMark = {
43160
+ type: "link",
43161
+ attrs: {
43162
+ href: el.attrs.href ?? "",
43163
+ ...el.attrs.target ? { target: el.attrs.target } : {}
43164
+ }
43165
+ };
43166
+ return this.inlineNodes(el.children, [...marks, linkMark]);
43167
+ }
43168
+ if (this.keepUnknownTags) {
43169
+ const open = this.serializeOpenTag(el);
43170
+ const close = `</${name}>`;
43171
+ return [
43172
+ ...this.inlineText(open, marks),
43173
+ ...this.inlineNodes(el.children, marks),
43174
+ ...this.inlineText(close, marks)
43175
+ ];
43176
+ }
43177
+ return this.inlineNodes(el.children, marks);
43178
+ }
43179
+ inlineText(raw, marks) {
43180
+ const text = decodeEntities(raw).replace(/\s+/g, " ");
43181
+ if (text === "") return [];
43182
+ const node = { text, type: "text" };
43183
+ if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
43184
+ return [node];
43185
+ }
43186
+ serializeOpenTag(el) {
43187
+ const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
43188
+ return `<${el.name}${attrs}>`;
43189
+ }
43190
+ // --- lists ----------------------------------------------------------------
43191
+ isListTag(name) {
43192
+ return name === "ul" || name === "ol";
43193
+ }
43194
+ listNode(el) {
43195
+ const items = childElements(el, LI_TAGS);
43196
+ if (items.length === 0) return void 0;
43197
+ const isTask = el.name === "ul" && items.some((li) => {
43198
+ const firstEl = li.children.find(isElement);
43199
+ return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
43200
+ });
43201
+ if (isTask) {
43202
+ return {
43203
+ type: "taskList",
43204
+ content: items.map((li) => this.taskItemNode(li))
43205
+ };
43206
+ }
43207
+ const type = this.listType(el);
43208
+ const node = {
43209
+ type,
43210
+ content: items.map((li) => this.listItemNode(li))
43211
+ };
43212
+ if (el.name === "ol") {
43213
+ const start = intAttr(el.attrs.start);
43214
+ if (start != null) {
43215
+ node.attrs = { start };
43216
+ }
43217
+ }
43218
+ return node;
43219
+ }
43220
+ listType(el) {
43221
+ if (el.name === "ol") {
43222
+ switch (el.attrs.type) {
43223
+ case "i":
43224
+ return "orderedListRomanLower";
43225
+ case "I":
43226
+ return "orderedListRoman";
43227
+ case "a":
43228
+ return "letteredListLower";
43229
+ case "A":
43230
+ return "letteredList";
43231
+ default:
43232
+ return "orderedList";
43233
+ }
43234
+ }
43235
+ const style = el.attrs.style ?? "";
43236
+ if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
43237
+ return "bulletList";
43238
+ }
43239
+ listItemNode(li) {
43240
+ let content = this.blockNodes(li.children);
43241
+ if (content.length === 0) {
43242
+ content = [{ type: "paragraph", content: [], attrs: {} }];
43243
+ }
43244
+ return { type: "listItem", content };
43245
+ }
43246
+ taskItemNode(li) {
43247
+ const checkbox = li.children.find(
43248
+ (c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
43249
+ );
43250
+ const checked = checkbox ? "checked" in checkbox.attrs : false;
43251
+ const rest = li.children.filter((c) => c !== checkbox);
43252
+ let content = this.blockNodes(rest);
43253
+ if (content.length === 0) {
43254
+ content = [{ type: "paragraph", content: [], attrs: {} }];
43255
+ }
43256
+ return { type: "taskItem", attrs: { checked }, content };
43257
+ }
43258
+ // --- images ---------------------------------------------------------------
43259
+ imageNode(el, inline) {
43260
+ const attrs = { src: el.attrs.src ?? "" };
43261
+ attrs.alt = el.attrs.alt ?? null;
43262
+ attrs.title = el.attrs.title ?? null;
43263
+ const width = intAttr(el.attrs.width);
43264
+ if (width != null) attrs.width = width;
43265
+ const height = intAttr(el.attrs.height);
43266
+ if (height != null) attrs.height = height;
43267
+ if (el.attrs.class) attrs.class = el.attrs.class;
43268
+ return { type: inline ? "imageInline" : "image", attrs };
43269
+ }
43270
+ // --- whitespace -----------------------------------------------------------
43271
+ /** Trim leading/trailing whitespace from inline content (edges only). */
43272
+ trimInline(nodes) {
43273
+ const out = nodes.slice();
43274
+ const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
43275
+ while (out.length > 0 && isWs(out[0])) out.shift();
43276
+ if (out.length > 0 && out[0].type === "text") {
43277
+ out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
43278
+ }
43279
+ while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
43280
+ if (out.length > 0 && out[out.length - 1].type === "text") {
43281
+ const last = out.length - 1;
43282
+ out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
43283
+ }
43284
+ return out.filter((n) => !(n.type === "text" && n.text === ""));
43285
+ }
43286
+ };
43287
+
42328
43288
  // src/BitmarkParserGenerator.ts
42329
43289
  var Input = {
42330
43290
  /**
@@ -43264,728 +44224,6 @@ var BoundingBoxIndex = class _BoundingBoxIndex {
43264
44224
  }
43265
44225
  };
43266
44226
 
43267
- // src/generator/html/HtmlTableGenerator.ts
43268
- var MARK_TO_TAG = {
43269
- bold: "b",
43270
- italic: "i",
43271
- superscript: "sup",
43272
- subscript: "sub",
43273
- strike: "s",
43274
- del: "del",
43275
- ins: "ins",
43276
- underline: "u",
43277
- highlight: "mark",
43278
- code: "code"
43279
- };
43280
- var HtmlTableGenerator2 = class {
43281
- constructor() {
43282
- __publicField(this, "indentUnit", " ");
43283
- }
43284
- /**
43285
- * Generate HTML table fragments from a string or JSON value.
43286
- * @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
43287
- */
43288
- generate(input) {
43289
- let data = input;
43290
- if (typeof data === "string") {
43291
- try {
43292
- data = JSON.parse(data);
43293
- } catch {
43294
- return "";
43295
- }
43296
- }
43297
- const bits = this.collectBits(data);
43298
- const fragments = [];
43299
- for (const bit of bits) {
43300
- const html = this.renderTableBit(bit);
43301
- if (html) fragments.push(html);
43302
- }
43303
- return fragments.join("\n\n");
43304
- }
43305
- // --- bit collection -------------------------------------------------------
43306
- collectBits(data) {
43307
- const out = [];
43308
- const visit = (value) => {
43309
- if (value == null || typeof value !== "object") return;
43310
- if (Array.isArray(value)) {
43311
- value.forEach(visit);
43312
- return;
43313
- }
43314
- const obj = value;
43315
- if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
43316
- out.push(obj.bit);
43317
- } else if ("type" in obj) {
43318
- out.push(obj);
43319
- }
43320
- };
43321
- visit(data);
43322
- return out;
43323
- }
43324
- // --- table rendering ------------------------------------------------------
43325
- renderTableBit(bit) {
43326
- const table = bit.table;
43327
- if (!table) return "";
43328
- if (bit.type !== "table" && bit.type !== "table-extended") return "";
43329
- const extended = this.toExtended(table);
43330
- const lines = [];
43331
- lines.push("<table>");
43332
- if (bit.caption != null) {
43333
- const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
43334
- if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
43335
- }
43336
- this.renderSection(lines, "thead", extended.header, "header");
43337
- this.renderSection(lines, "tbody", extended.body, "body");
43338
- this.renderSection(lines, "tfoot", extended.footer, "footer");
43339
- lines.push("</table>");
43340
- return lines.join("\n");
43341
- }
43342
- toExtended(table) {
43343
- const t = table;
43344
- if (t.header || t.body || t.footer) return table;
43345
- return convertBasicToExtendedTableFormat(table);
43346
- }
43347
- renderSection(lines, tag, section, key) {
43348
- if (!section || !section.rows || section.rows.length === 0) return;
43349
- lines.push(`${this.indentUnit}<${tag}>`);
43350
- for (const row of section.rows) {
43351
- lines.push(`${this.indentUnit.repeat(2)}<tr>`);
43352
- for (const cell of row.cells ?? []) {
43353
- lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
43354
- }
43355
- lines.push(`${this.indentUnit.repeat(2)}</tr>`);
43356
- }
43357
- lines.push(`${this.indentUnit}</${tag}>`);
43358
- }
43359
- renderCell(cell, _key) {
43360
- const tag = cell.title === true ? "th" : "td";
43361
- const attrs = [];
43362
- if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
43363
- if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
43364
- if (cell.scope) attrs.push(`scope="${cell.scope}"`);
43365
- if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
43366
- const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
43367
- return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
43368
- }
43369
- // --- cell content (TextAst -> HTML) ---------------------------------------
43370
- asTextAst(content) {
43371
- if (content == null) return [];
43372
- if (typeof content === "string") return [{ type: "text", text: content }];
43373
- return content;
43374
- }
43375
- cellContentToHtml(blocks) {
43376
- if (blocks.length === 0) return "";
43377
- if (blocks.length === 1 && blocks[0].type === "paragraph") {
43378
- return this.inlineToHtml(blocks[0].content ?? []);
43379
- }
43380
- return blocks.map((b) => this.blockToHtml(b)).join("");
43381
- }
43382
- blockToHtml(node) {
43383
- switch (node.type) {
43384
- case "paragraph":
43385
- return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
43386
- case "bulletList":
43387
- case "noBulletList":
43388
- case "orderedList":
43389
- case "orderedListRoman":
43390
- case "orderedListRomanLower":
43391
- case "letteredList":
43392
- case "letteredListLower":
43393
- case "taskList":
43394
- return this.listToHtml(node);
43395
- case "image":
43396
- case "imageInline":
43397
- return this.imageToHtml(node);
43398
- default:
43399
- return this.inlineToHtml([node]);
43400
- }
43401
- }
43402
- inlineToHtml(nodes) {
43403
- return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
43404
- }
43405
- inlineNodeToHtml(node) {
43406
- if (node.type === "hardBreak") return "<br>";
43407
- if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
43408
- if (node.type === "text") {
43409
- return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
43410
- }
43411
- if (node.content) return this.inlineToHtml(node.content);
43412
- return this.escapeText(node.text ?? "");
43413
- }
43414
- wrapMarks(text, marks) {
43415
- if (!marks || marks.length === 0) return text;
43416
- let open = "";
43417
- let close = "";
43418
- for (const mark of marks) {
43419
- if (mark.type === "link") {
43420
- const href = mark.attrs?.href ?? "";
43421
- open += `<a href="${this.escapeAttr(href)}">`;
43422
- close = `</a>${close}`;
43423
- } else {
43424
- const tag = MARK_TO_TAG[mark.type];
43425
- if (tag) {
43426
- open += `<${tag}>`;
43427
- close = `</${tag}>${close}`;
43428
- }
43429
- }
43430
- }
43431
- return `${open}${text}${close}`;
43432
- }
43433
- // --- lists ----------------------------------------------------------------
43434
- listToHtml(node) {
43435
- const { tag, attrs } = this.listTag(node);
43436
- const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
43437
- return `<${tag}${attrs}>${items}</${tag}>`;
43438
- }
43439
- listTag(node) {
43440
- const start = node.attrs?.start;
43441
- const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
43442
- switch (node.type) {
43443
- case "orderedList":
43444
- return { tag: "ol", attrs: startAttr };
43445
- case "orderedListRoman":
43446
- return { tag: "ol", attrs: ` type="I"${startAttr}` };
43447
- case "orderedListRomanLower":
43448
- return { tag: "ol", attrs: ` type="i"${startAttr}` };
43449
- case "letteredList":
43450
- return { tag: "ol", attrs: ` type="A"${startAttr}` };
43451
- case "letteredListLower":
43452
- return { tag: "ol", attrs: ` type="a"${startAttr}` };
43453
- case "noBulletList":
43454
- return { tag: "ul", attrs: ' style="list-style:none"' };
43455
- case "taskList":
43456
- case "bulletList":
43457
- default:
43458
- return { tag: "ul", attrs: "" };
43459
- }
43460
- }
43461
- listItemToHtml(item, task) {
43462
- const inner = (item.content ?? []).map((b) => {
43463
- if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
43464
- return this.blockToHtml(b);
43465
- }).join("");
43466
- if (task) {
43467
- const checked = item.attrs?.checked ? " checked" : "";
43468
- return `<li><input type="checkbox"${checked}>${inner}</li>`;
43469
- }
43470
- return `<li>${inner}</li>`;
43471
- }
43472
- // --- images ---------------------------------------------------------------
43473
- imageToHtml(node) {
43474
- const attrs = node.attrs ?? {};
43475
- const parts = [];
43476
- const src = attrs.src;
43477
- parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
43478
- if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
43479
- if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
43480
- if (attrs.width != null) parts.push(`width="${attrs.width}"`);
43481
- if (attrs.height != null) parts.push(`height="${attrs.height}"`);
43482
- if (typeof attrs.class === "string" && attrs.class) {
43483
- parts.push(`class="${this.escapeAttr(attrs.class)}"`);
43484
- }
43485
- return `<img ${parts.join(" ")}>`;
43486
- }
43487
- // --- escaping -------------------------------------------------------------
43488
- escapeText(text) {
43489
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
43490
- }
43491
- escapeAttr(text) {
43492
- return this.escapeText(text).replace(/"/g, "&quot;");
43493
- }
43494
- };
43495
-
43496
- // src/parser/html/HtmlDom.ts
43497
- var VOID_ELEMENTS = /* @__PURE__ */ new Set([
43498
- "area",
43499
- "base",
43500
- "br",
43501
- "col",
43502
- "embed",
43503
- "hr",
43504
- "img",
43505
- "input",
43506
- "link",
43507
- "meta",
43508
- "param",
43509
- "source",
43510
- "track",
43511
- "wbr"
43512
- ]);
43513
- var IMPLIED_CLOSE = {
43514
- li: /* @__PURE__ */ new Set(["li"]),
43515
- td: /* @__PURE__ */ new Set(["td", "th"]),
43516
- th: /* @__PURE__ */ new Set(["td", "th"]),
43517
- tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
43518
- thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
43519
- tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
43520
- tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
43521
- p: /* @__PURE__ */ new Set(["p"]),
43522
- option: /* @__PURE__ */ new Set(["option"])
43523
- };
43524
- var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
43525
- var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
43526
- function parseAttrs(raw) {
43527
- const attrs = {};
43528
- if (!raw) return attrs;
43529
- ATTR_RE.lastIndex = 0;
43530
- let m;
43531
- while ((m = ATTR_RE.exec(raw)) !== null) {
43532
- const name = m[1].toLowerCase();
43533
- let value = m[2] ?? "";
43534
- if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
43535
- value = value.slice(1, -1);
43536
- }
43537
- attrs[name] = value;
43538
- }
43539
- return attrs;
43540
- }
43541
- function stripNonContent(html) {
43542
- return html.replace(/<!--[\s\S]*?-->/g, "").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, "").replace(/<!doctype[^>]*>/gi, "").replace(/<script\b[\s\S]*?<\/script>/gi, "").replace(/<style\b[\s\S]*?<\/style>/gi, "");
43543
- }
43544
- function tokenize(html) {
43545
- const tokens = [];
43546
- const clean = stripNonContent(html);
43547
- TAG_RE.lastIndex = 0;
43548
- let lastIndex = 0;
43549
- let m;
43550
- while ((m = TAG_RE.exec(clean)) !== null) {
43551
- if (m.index > lastIndex) {
43552
- tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
43553
- }
43554
- lastIndex = TAG_RE.lastIndex;
43555
- const isClose = m[1] === "/";
43556
- const name = m[2].toLowerCase();
43557
- if (isClose) {
43558
- tokens.push({ kind: "close", name });
43559
- } else {
43560
- tokens.push({
43561
- kind: "open",
43562
- name,
43563
- attrs: parseAttrs(m[3]),
43564
- selfClose: m[4] === "/"
43565
- });
43566
- }
43567
- }
43568
- if (lastIndex < clean.length) {
43569
- tokens.push({ kind: "text", text: clean.slice(lastIndex) });
43570
- }
43571
- return tokens;
43572
- }
43573
- function parseHtml(html) {
43574
- const root = { type: "element", name: "#root", attrs: {}, children: [] };
43575
- const stack = [root];
43576
- const top = () => stack[stack.length - 1];
43577
- for (const token of tokenize(html)) {
43578
- if (token.kind === "text") {
43579
- if (token.text) top().children.push({ type: "text", value: token.text });
43580
- continue;
43581
- }
43582
- if (token.kind === "open") {
43583
- const name = token.name;
43584
- const closes = IMPLIED_CLOSE[name];
43585
- if (closes) {
43586
- while (stack.length > 1 && closes.has(top().name)) stack.pop();
43587
- }
43588
- const el = {
43589
- type: "element",
43590
- name,
43591
- attrs: token.attrs ?? {},
43592
- children: []
43593
- };
43594
- top().children.push(el);
43595
- if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
43596
- stack.push(el);
43597
- }
43598
- continue;
43599
- }
43600
- for (let i = stack.length - 1; i > 0; i--) {
43601
- if (stack[i].name === token.name) {
43602
- stack.length = i;
43603
- break;
43604
- }
43605
- }
43606
- }
43607
- return root.children;
43608
- }
43609
- function childElements(el, names) {
43610
- return el.children.filter((c) => c.type === "element" && names.has(c.name));
43611
- }
43612
-
43613
- // src/parser/html/HtmlTableParser.ts
43614
- var MARK_TAGS = {
43615
- b: "bold",
43616
- strong: "bold",
43617
- i: "italic",
43618
- em: "italic",
43619
- sup: "superscript",
43620
- sub: "subscript",
43621
- s: "strike",
43622
- strike: "strike",
43623
- del: "del",
43624
- ins: "ins",
43625
- u: "underline",
43626
- mark: "highlight",
43627
- code: "code"
43628
- };
43629
- var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
43630
- var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
43631
- var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
43632
- var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
43633
- var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
43634
- var NAMED_ENTITIES = {
43635
- amp: "&",
43636
- lt: "<",
43637
- gt: ">",
43638
- quot: '"',
43639
- apos: "'",
43640
- nbsp: "\xA0"
43641
- };
43642
- function decodeEntities(text) {
43643
- return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
43644
- if (body[0] === "#") {
43645
- const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
43646
- if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
43647
- try {
43648
- return String.fromCodePoint(code);
43649
- } catch {
43650
- return whole;
43651
- }
43652
- }
43653
- return whole;
43654
- }
43655
- return NAMED_ENTITIES[body] ?? whole;
43656
- });
43657
- }
43658
- function intAttr(value) {
43659
- if (value == null) return void 0;
43660
- const n = Number.parseInt(value, 10);
43661
- return Number.isInteger(n) ? n : void 0;
43662
- }
43663
- function isElement(node) {
43664
- return node.type === "element";
43665
- }
43666
- var HtmlTableParser2 = class {
43667
- constructor() {
43668
- __publicField(this, "keepUnknownTags", false);
43669
- }
43670
- /**
43671
- * Parse an HTML string and return one table bit per top-level `<table>`.
43672
- */
43673
- parse(html, options) {
43674
- this.keepUnknownTags = options?.keepUnknownTags ?? false;
43675
- const tableFormat = options?.tableFormat ?? "table-extended";
43676
- const onWarning = options?.onWarning;
43677
- const tables = this.collectTopLevelTables(parseHtml(html));
43678
- const bits = [];
43679
- for (const table of tables) {
43680
- const bit = this.tableToBit(table, tableFormat, onWarning);
43681
- if (bit) bits.push(bit);
43682
- }
43683
- return bits;
43684
- }
43685
- // --- table extraction -----------------------------------------------------
43686
- /** Collect every `<table>` element, NOT descending into nested tables. */
43687
- collectTopLevelTables(nodes) {
43688
- const tables = [];
43689
- const visit = (node) => {
43690
- if (!isElement(node)) return;
43691
- if (node.name === "table") {
43692
- tables.push(node);
43693
- return;
43694
- }
43695
- node.children.forEach(visit);
43696
- };
43697
- nodes.forEach(visit);
43698
- return tables;
43699
- }
43700
- tableToBit(table, tableFormat, onWarning) {
43701
- const header = [];
43702
- const body = [];
43703
- const footer = [];
43704
- let caption;
43705
- for (const child of table.children) {
43706
- if (!isElement(child)) continue;
43707
- if (child.name === "caption") {
43708
- const capContent = this.inlineNodes(child.children, []);
43709
- const trimmed = this.trimInline(capContent);
43710
- if (trimmed.length > 0) caption = trimmed;
43711
- } else if (SECTION_TAGS.has(child.name)) {
43712
- const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
43713
- for (const tr of childElements(child, ROW_TAGS)) {
43714
- target.push(this.rowToCells(tr));
43715
- }
43716
- } else if (ROW_TAGS.has(child.name)) {
43717
- body.push(this.rowToCells(child));
43718
- }
43719
- }
43720
- if (header.length === 0 && body.length === 0 && footer.length === 0) {
43721
- return void 0;
43722
- }
43723
- const tableExtended = {};
43724
- if (header.length > 0) tableExtended.header = { rows: header };
43725
- if (body.length > 0) tableExtended.body = { rows: body };
43726
- if (footer.length > 0) tableExtended.footer = { rows: footer };
43727
- let tableData = tableExtended;
43728
- if (tableFormat === "table") {
43729
- if (this.isLossyAsBasic(tableExtended)) {
43730
- onWarning?.(
43731
- "Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
43732
- );
43733
- }
43734
- tableData = convertExtendedToBasicTableFormat(tableExtended);
43735
- }
43736
- const bit = {
43737
- type: tableFormat,
43738
- format: "bitmark++",
43739
- table: tableData
43740
- };
43741
- if (caption) bit.caption = caption;
43742
- return bit;
43743
- }
43744
- rowToCells(tr) {
43745
- const cells = [];
43746
- for (const cell of childElements(tr, CELL_TAGS)) {
43747
- cells.push(this.cellToJson(cell));
43748
- }
43749
- return { cells };
43750
- }
43751
- cellToJson(cell) {
43752
- const json = {
43753
- content: this.blockNodes(cell.children)
43754
- };
43755
- if (cell.name === "th") json.title = true;
43756
- const rowspan = intAttr(cell.attrs.rowspan);
43757
- if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
43758
- const colspan = intAttr(cell.attrs.colspan);
43759
- if (colspan != null && colspan >= 2) json.colspan = colspan;
43760
- const scope = cell.attrs.scope?.toLowerCase();
43761
- if (scope && VALID_SCOPES.has(scope)) {
43762
- json.scope = scope;
43763
- }
43764
- const width = this.widthFromCell(cell);
43765
- if (width != null) json.colwidth = width;
43766
- return json;
43767
- }
43768
- widthFromCell(cell) {
43769
- const attrWidth = intAttr(cell.attrs.width);
43770
- if (attrWidth != null && attrWidth > 0) return attrWidth;
43771
- const style = cell.attrs.style;
43772
- if (style) {
43773
- const m = style.match(/width\s*:\s*(\d+)\s*px/i);
43774
- if (m) {
43775
- const n = Number.parseInt(m[1], 10);
43776
- if (Number.isInteger(n) && n > 0) return n;
43777
- }
43778
- }
43779
- return void 0;
43780
- }
43781
- isLossyAsBasic(table) {
43782
- if (table.footer) return true;
43783
- if (table.header && table.header.rows.length > 1) return true;
43784
- const sections = [table.header, table.body, table.footer];
43785
- for (const section of sections) {
43786
- if (!section) continue;
43787
- for (const row of section.rows) {
43788
- for (const cell of row.cells) {
43789
- if (cell.rowspan || cell.colspan || cell.scope) return true;
43790
- }
43791
- }
43792
- }
43793
- return false;
43794
- }
43795
- // --- content conversion (HTML -> TextAst) ---------------------------------
43796
- /**
43797
- * Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
43798
- */
43799
- blockNodes(nodes) {
43800
- const blocks = [];
43801
- let inline = [];
43802
- const flush = () => {
43803
- const trimmed = this.trimInline(inline);
43804
- inline = [];
43805
- if (trimmed.length === 0) return;
43806
- if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
43807
- blocks.push({ ...trimmed[0], type: "image" });
43808
- } else {
43809
- blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
43810
- }
43811
- };
43812
- for (const node of nodes) {
43813
- if (!isElement(node)) {
43814
- inline.push(...this.inlineText(node.value, []));
43815
- continue;
43816
- }
43817
- const name = node.name;
43818
- if (name === "p") {
43819
- flush();
43820
- const content = this.trimInline(this.inlineNodes(node.children, []));
43821
- if (content.length > 0) {
43822
- blocks.push({ type: "paragraph", content, attrs: {} });
43823
- }
43824
- } else if (this.isListTag(name)) {
43825
- flush();
43826
- const list = this.listNode(node);
43827
- if (list) blocks.push(list);
43828
- } else {
43829
- inline.push(...this.inlineFromElement(node, []));
43830
- }
43831
- }
43832
- flush();
43833
- return blocks;
43834
- }
43835
- /** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
43836
- inlineNodes(nodes, marks) {
43837
- const out = [];
43838
- for (const node of nodes) {
43839
- if (!isElement(node)) {
43840
- out.push(...this.inlineText(node.value, marks));
43841
- } else {
43842
- out.push(...this.inlineFromElement(node, marks));
43843
- }
43844
- }
43845
- return out;
43846
- }
43847
- inlineFromElement(el, marks) {
43848
- const name = el.name;
43849
- if (name === "br") {
43850
- return [{ type: "hardBreak" }];
43851
- }
43852
- if (name === "img") {
43853
- return [this.imageNode(el, true)];
43854
- }
43855
- const markType = MARK_TAGS[name];
43856
- if (markType) {
43857
- return this.inlineNodes(el.children, [...marks, { type: markType }]);
43858
- }
43859
- if (name === "a") {
43860
- const linkMark = {
43861
- type: "link",
43862
- attrs: {
43863
- href: el.attrs.href ?? "",
43864
- ...el.attrs.target ? { target: el.attrs.target } : {}
43865
- }
43866
- };
43867
- return this.inlineNodes(el.children, [...marks, linkMark]);
43868
- }
43869
- if (this.keepUnknownTags) {
43870
- const open = this.serializeOpenTag(el);
43871
- const close = `</${name}>`;
43872
- return [
43873
- ...this.inlineText(open, marks),
43874
- ...this.inlineNodes(el.children, marks),
43875
- ...this.inlineText(close, marks)
43876
- ];
43877
- }
43878
- return this.inlineNodes(el.children, marks);
43879
- }
43880
- inlineText(raw, marks) {
43881
- const text = decodeEntities(raw).replace(/\s+/g, " ");
43882
- if (text === "") return [];
43883
- const node = { text, type: "text" };
43884
- if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
43885
- return [node];
43886
- }
43887
- serializeOpenTag(el) {
43888
- const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
43889
- return `<${el.name}${attrs}>`;
43890
- }
43891
- // --- lists ----------------------------------------------------------------
43892
- isListTag(name) {
43893
- return name === "ul" || name === "ol";
43894
- }
43895
- listNode(el) {
43896
- const items = childElements(el, LI_TAGS);
43897
- if (items.length === 0) return void 0;
43898
- const isTask = el.name === "ul" && items.some((li) => {
43899
- const firstEl = li.children.find(isElement);
43900
- return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
43901
- });
43902
- if (isTask) {
43903
- return {
43904
- type: "taskList",
43905
- content: items.map((li) => this.taskItemNode(li))
43906
- };
43907
- }
43908
- const type = this.listType(el);
43909
- const node = {
43910
- type,
43911
- content: items.map((li) => this.listItemNode(li))
43912
- };
43913
- if (el.name === "ol") {
43914
- const start = intAttr(el.attrs.start);
43915
- if (start != null) {
43916
- node.attrs = { start };
43917
- }
43918
- }
43919
- return node;
43920
- }
43921
- listType(el) {
43922
- if (el.name === "ol") {
43923
- switch (el.attrs.type) {
43924
- case "i":
43925
- return "orderedListRomanLower";
43926
- case "I":
43927
- return "orderedListRoman";
43928
- case "a":
43929
- return "letteredListLower";
43930
- case "A":
43931
- return "letteredList";
43932
- default:
43933
- return "orderedList";
43934
- }
43935
- }
43936
- const style = el.attrs.style ?? "";
43937
- if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
43938
- return "bulletList";
43939
- }
43940
- listItemNode(li) {
43941
- let content = this.blockNodes(li.children);
43942
- if (content.length === 0) {
43943
- content = [{ type: "paragraph", content: [], attrs: {} }];
43944
- }
43945
- return { type: "listItem", content };
43946
- }
43947
- taskItemNode(li) {
43948
- const checkbox = li.children.find(
43949
- (c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
43950
- );
43951
- const checked = checkbox ? "checked" in checkbox.attrs : false;
43952
- const rest = li.children.filter((c) => c !== checkbox);
43953
- let content = this.blockNodes(rest);
43954
- if (content.length === 0) {
43955
- content = [{ type: "paragraph", content: [], attrs: {} }];
43956
- }
43957
- return { type: "taskItem", attrs: { checked }, content };
43958
- }
43959
- // --- images ---------------------------------------------------------------
43960
- imageNode(el, inline) {
43961
- const attrs = { src: el.attrs.src ?? "" };
43962
- attrs.alt = el.attrs.alt ?? null;
43963
- attrs.title = el.attrs.title ?? null;
43964
- const width = intAttr(el.attrs.width);
43965
- if (width != null) attrs.width = width;
43966
- const height = intAttr(el.attrs.height);
43967
- if (height != null) attrs.height = height;
43968
- if (el.attrs.class) attrs.class = el.attrs.class;
43969
- return { type: inline ? "imageInline" : "image", attrs };
43970
- }
43971
- // --- whitespace -----------------------------------------------------------
43972
- /** Trim leading/trailing whitespace from inline content (edges only). */
43973
- trimInline(nodes) {
43974
- const out = nodes.slice();
43975
- const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
43976
- while (out.length > 0 && isWs(out[0])) out.shift();
43977
- if (out.length > 0 && out[0].type === "text") {
43978
- out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
43979
- }
43980
- while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
43981
- if (out.length > 0 && out[out.length - 1].type === "text") {
43982
- const last = out.length - 1;
43983
- out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
43984
- }
43985
- return out.filter((n) => !(n.type === "text" && n.text === ""));
43986
- }
43987
- };
43988
-
43989
44227
  // src/index.ts
43990
44228
  init();
43991
44229
  // Annotate the CommonJS export names for ESM import in node: