@gmb/bitmark-parser-generator 5.26.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.
- package/dist/browser/bitmark-parser-generator.min.js +1 -1
- package/dist/browser/bundle-report.html +2 -2
- package/dist/browser/cjs/index.cjs +976 -743
- package/dist/browser/cjs/index.cjs.map +1 -1
- package/dist/browser/cjs/index.d.cts +120 -62
- package/dist/browser/esm/index.d.ts +120 -62
- package/dist/browser/esm/index.js +976 -743
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/cli/main.js +1014 -754
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +1016 -756
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -62
- package/dist/index.d.ts +120 -62
- package/dist/index.js +1016 -756
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -545,6 +545,14 @@ var BitType = {
|
|
|
545
545
|
smartStandardRemarkNonNormativeCollapsible: "smart-standard-remark-non-normative-collapsible",
|
|
546
546
|
smartStandardRemarkNormative: "smart-standard-remark-normative",
|
|
547
547
|
smartStandardRemarkNormativeCollapsible: "smart-standard-remark-normative-collapsible",
|
|
548
|
+
smartStandardRemarkTableExtendedImageNonNormative: "smart-standard-remark-table-extended-image-non-normative",
|
|
549
|
+
smartStandardRemarkTableExtendedImageNonNormativeCollapsible: "smart-standard-remark-table-extended-image-non-normative-collapsible",
|
|
550
|
+
smartStandardRemarkTableExtendedImageNormative: "smart-standard-remark-table-extended-image-normative",
|
|
551
|
+
smartStandardRemarkTableExtendedImageNormativeCollapsible: "smart-standard-remark-table-extended-image-normative-collapsible",
|
|
552
|
+
smartStandardRemarkTableExtendedNonNormative: "smart-standard-remark-table-extended-non-normative",
|
|
553
|
+
smartStandardRemarkTableExtendedNonNormativeCollapsible: "smart-standard-remark-table-extended-non-normative-collapsible",
|
|
554
|
+
smartStandardRemarkTableExtendedNormative: "smart-standard-remark-table-extended-normative",
|
|
555
|
+
smartStandardRemarkTableExtendedNormativeCollapsible: "smart-standard-remark-table-extended-normative-collapsible",
|
|
548
556
|
smartStandardRemarkTableImageNonNormative: "smart-standard-remark-table-image-non-normative",
|
|
549
557
|
smartStandardRemarkTableImageNonNormativeCollapsible: "smart-standard-remark-table-image-non-normative-collapsible",
|
|
550
558
|
smartStandardRemarkTableImageNormative: "smart-standard-remark-table-image-normative",
|
|
@@ -553,6 +561,14 @@ var BitType = {
|
|
|
553
561
|
smartStandardRemarkTableNonNormativeCollapsible: "smart-standard-remark-table-non-normative-collapsible",
|
|
554
562
|
smartStandardRemarkTableNormative: "smart-standard-remark-table-normative",
|
|
555
563
|
smartStandardRemarkTableNormativeCollapsible: "smart-standard-remark-table-normative-collapsible",
|
|
564
|
+
smartStandardTableExtendedImageNonNormative: "smart-standard-table-extended-image-non-normative",
|
|
565
|
+
smartStandardTableExtendedImageNonNormativeCollapsible: "smart-standard-table-extended-image-non-normative-collapsible",
|
|
566
|
+
smartStandardTableExtendedImageNormative: "smart-standard-table-extended-image-normative",
|
|
567
|
+
smartStandardTableExtendedImageNormativeCollapsible: "smart-standard-table-extended-image-normative-collapsible",
|
|
568
|
+
smartStandardTableExtendedNonNormative: "smart-standard-table-extended-non-normative",
|
|
569
|
+
smartStandardTableExtendedNonNormativeCollapsible: "smart-standard-table-extended-non-normative-collapsible",
|
|
570
|
+
smartStandardTableExtendedNormative: "smart-standard-table-extended-normative",
|
|
571
|
+
smartStandardTableExtendedNormativeCollapsible: "smart-standard-table-extended-normative-collapsible",
|
|
556
572
|
smartStandardTableImageNonNormative: "smart-standard-table-image-non-normative",
|
|
557
573
|
smartStandardTableImageNonNormativeCollapsible: "smart-standard-table-image-non-normative-collapsible",
|
|
558
574
|
smartStandardTableImageNormative: "smart-standard-table-image-normative",
|
|
@@ -575,10 +591,18 @@ var BitType = {
|
|
|
575
591
|
standardNoteNormative: "standard-note-normative",
|
|
576
592
|
standardRemarkNonNormative: "standard-remark-non-normative",
|
|
577
593
|
standardRemarkNormative: "standard-remark-normative",
|
|
594
|
+
standardRemarkTableExtendedImageNonNormative: "standard-remark-table-extended-image-non-normative",
|
|
595
|
+
standardRemarkTableExtendedImageNormative: "standard-remark-table-extended-image-normative",
|
|
596
|
+
standardRemarkTableExtendedNonNormative: "standard-remark-table-extended-non-normative",
|
|
597
|
+
standardRemarkTableExtendedNormative: "standard-remark-table-extended-normative",
|
|
578
598
|
standardRemarkTableImageNonNormative: "standard-remark-table-image-non-normative",
|
|
579
599
|
standardRemarkTableImageNormative: "standard-remark-table-image-normative",
|
|
580
600
|
standardRemarkTableNonNormative: "standard-remark-table-non-normative",
|
|
581
601
|
standardRemarkTableNormative: "standard-remark-table-normative",
|
|
602
|
+
standardTableExtendedImageNonNormative: "standard-table-extended-image-non-normative",
|
|
603
|
+
standardTableExtendedImageNormative: "standard-table-extended-image-normative",
|
|
604
|
+
standardTableExtendedNonNormative: "standard-table-extended-non-normative",
|
|
605
|
+
standardTableExtendedNormative: "standard-table-extended-normative",
|
|
582
606
|
standardTableImageNonNormative: "standard-table-image-non-normative",
|
|
583
607
|
standardTableImageNormative: "standard-table-image-normative",
|
|
584
608
|
standardTableNonNormative: "standard-table-non-normative",
|
|
@@ -805,6 +829,10 @@ var AbstractTagConfig = class {
|
|
|
805
829
|
// New JSON-pattern jsonKey (export-only)
|
|
806
830
|
__publicField(this, "hasExportJsonKey");
|
|
807
831
|
// True iff exportJsonKey was explicitly set
|
|
832
|
+
__publicField(this, "htmlKey");
|
|
833
|
+
// HTML key-pattern (export-only)
|
|
834
|
+
__publicField(this, "hasHtmlKey");
|
|
835
|
+
// True iff htmlKey was explicitly set
|
|
808
836
|
__publicField(this, "deprecated");
|
|
809
837
|
this.type = params.type;
|
|
810
838
|
this.configKey = params.configKey;
|
|
@@ -815,6 +843,8 @@ var AbstractTagConfig = class {
|
|
|
815
843
|
this.jsonKey = params.jsonKey;
|
|
816
844
|
this.exportJsonKey = params.exportJsonKey;
|
|
817
845
|
this.hasExportJsonKey = params.hasExportJsonKey;
|
|
846
|
+
this.htmlKey = params.htmlKey;
|
|
847
|
+
this.hasHtmlKey = params.hasHtmlKey;
|
|
818
848
|
this.deprecated = params.deprecated;
|
|
819
849
|
}
|
|
820
850
|
};
|
|
@@ -936,7 +966,7 @@ var ResourceTagConfig = class extends AbstractTagConfig {
|
|
|
936
966
|
// src/model/config/CardVariantConfig.ts
|
|
937
967
|
var CardVariantConfig = class {
|
|
938
968
|
// Body text format. Default: bitmark++
|
|
939
|
-
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
|
|
969
|
+
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format, htmlKey, hasHtmlKey = false) {
|
|
940
970
|
__publicField(this, "tags");
|
|
941
971
|
__publicField(this, "bodyAllowed");
|
|
942
972
|
// Default: true
|
|
@@ -950,6 +980,9 @@ var CardVariantConfig = class {
|
|
|
950
980
|
__publicField(this, "exportJsonKey");
|
|
951
981
|
// New JSON-pattern jsonKey
|
|
952
982
|
__publicField(this, "hasExportJsonKey");
|
|
983
|
+
__publicField(this, "htmlKey");
|
|
984
|
+
// HTML key-pattern
|
|
985
|
+
__publicField(this, "hasHtmlKey");
|
|
953
986
|
__publicField(this, "format");
|
|
954
987
|
this.tags = tags2;
|
|
955
988
|
this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
|
|
@@ -958,6 +991,8 @@ var CardVariantConfig = class {
|
|
|
958
991
|
this.jsonKey = jsonKey;
|
|
959
992
|
this.exportJsonKey = exportJsonKey;
|
|
960
993
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
994
|
+
this.htmlKey = htmlKey;
|
|
995
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
961
996
|
this.format = format;
|
|
962
997
|
}
|
|
963
998
|
toString(options) {
|
|
@@ -982,18 +1017,22 @@ ${tag.toString(opts)}`;
|
|
|
982
1017
|
|
|
983
1018
|
// src/model/config/CardSideConfig.ts
|
|
984
1019
|
var CardSideConfig = class {
|
|
985
|
-
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
|
|
1020
|
+
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false, htmlKey, hasHtmlKey = false) {
|
|
986
1021
|
__publicField(this, "name");
|
|
987
1022
|
__publicField(this, "repeat");
|
|
988
1023
|
__publicField(this, "jsonKey");
|
|
989
1024
|
__publicField(this, "exportJsonKey");
|
|
990
1025
|
__publicField(this, "hasExportJsonKey");
|
|
1026
|
+
__publicField(this, "htmlKey");
|
|
1027
|
+
__publicField(this, "hasHtmlKey");
|
|
991
1028
|
__publicField(this, "variants");
|
|
992
1029
|
this.name = name;
|
|
993
1030
|
this.repeat = repeat;
|
|
994
1031
|
this.jsonKey = jsonKey;
|
|
995
1032
|
this.exportJsonKey = exportJsonKey;
|
|
996
1033
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1034
|
+
this.htmlKey = htmlKey;
|
|
1035
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
997
1036
|
this.variants = variants;
|
|
998
1037
|
}
|
|
999
1038
|
toString(options) {
|
|
@@ -1015,17 +1054,21 @@ var CardSideConfig = class {
|
|
|
1015
1054
|
|
|
1016
1055
|
// src/model/config/CardSetConfig.ts
|
|
1017
1056
|
var CardSetConfig = class {
|
|
1018
|
-
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
|
|
1057
|
+
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides, htmlKey = void 0, hasHtmlKey = false) {
|
|
1019
1058
|
__publicField(this, "configKey");
|
|
1020
1059
|
__publicField(this, "jsonKey");
|
|
1021
1060
|
__publicField(this, "exportJsonKey");
|
|
1022
1061
|
__publicField(this, "hasExportJsonKey");
|
|
1062
|
+
__publicField(this, "htmlKey");
|
|
1063
|
+
__publicField(this, "hasHtmlKey");
|
|
1023
1064
|
__publicField(this, "sections");
|
|
1024
1065
|
__publicField(this, "sides");
|
|
1025
1066
|
this.configKey = configKey;
|
|
1026
1067
|
this.jsonKey = jsonKey;
|
|
1027
1068
|
this.exportJsonKey = exportJsonKey;
|
|
1028
1069
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1070
|
+
this.htmlKey = htmlKey;
|
|
1071
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1029
1072
|
this.sections = sections;
|
|
1030
1073
|
this.sides = sides;
|
|
1031
1074
|
}
|
|
@@ -3705,6 +3748,16 @@ var CARDSETS = {
|
|
|
3705
3748
|
[CardSetConfigKey.table]: {
|
|
3706
3749
|
jsonKey: null,
|
|
3707
3750
|
exportJsonKey: null,
|
|
3751
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping. The classic (non-extended)
|
|
3752
|
+
// table produces the same `<table>`/`<thead>`/`<tbody>`/`<tfoot>` structure as
|
|
3753
|
+
// table-extended, so the structural htmlKeys mirror that cardSet. NOTE: the
|
|
3754
|
+
// JSON side routes the FIRST header card → `columns` (header) and SUBSEQUENT
|
|
3755
|
+
// header cards → `data` (body); HTML uses a uniform `<thead>` for the whole
|
|
3756
|
+
// `table-header` section, so a multi-card header (e.g. a second header card
|
|
3757
|
+
// that JSON sends to `data`) renders as additional `<thead>` rows rather than
|
|
3758
|
+
// moving to `<tbody>`. Per-card header/body splitting needs engine-level
|
|
3759
|
+
// routing not yet expressible in the pattern vocabulary — see PLAN-109.
|
|
3760
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3708
3761
|
sections: {
|
|
3709
3762
|
"table-header": {
|
|
3710
3763
|
// First header card's row of cells → `columns`. Subsequent header
|
|
@@ -3723,25 +3776,36 @@ var CARDSETS = {
|
|
|
3723
3776
|
},
|
|
3724
3777
|
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3725
3778
|
{ "@bit": { table: { data: ["$"] } } }
|
|
3726
|
-
]
|
|
3779
|
+
],
|
|
3780
|
+
// Header section → `<thead>` rows of `<th>`; `@tableColWidth` bubbles a
|
|
3781
|
+
// `width` attr onto the enclosing `<th>` (HTML-C2).
|
|
3782
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3783
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3727
3784
|
},
|
|
3728
3785
|
"table-body": {
|
|
3729
3786
|
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3730
3787
|
// This is the default section (no qualifier → cards land here).
|
|
3731
3788
|
jsonKey: "table.data",
|
|
3732
3789
|
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3790
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3733
3791
|
isDefault: true
|
|
3734
3792
|
},
|
|
3735
3793
|
"table-footer": {
|
|
3736
3794
|
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3737
3795
|
jsonKey: "table.data",
|
|
3738
|
-
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3796
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3797
|
+
// Footer cells route to `data` (not `columns`), so they are `<td>` (no
|
|
3798
|
+
// sideHtmlKey override — the cell side default applies).
|
|
3799
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } }
|
|
3739
3800
|
}
|
|
3740
3801
|
},
|
|
3741
3802
|
sides: [
|
|
3742
3803
|
{
|
|
3743
3804
|
name: "cell",
|
|
3744
3805
|
repeat: true,
|
|
3806
|
+
// Default (body/footer) cell → `<td>`; the header section overrides to
|
|
3807
|
+
// `<th>` via its sideHtmlKey (HTML.md §8).
|
|
3808
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3745
3809
|
variants: [
|
|
3746
3810
|
{
|
|
3747
3811
|
jsonKey: null,
|
|
@@ -3758,6 +3822,8 @@ var CARDSETS = {
|
|
|
3758
3822
|
},
|
|
3759
3823
|
{
|
|
3760
3824
|
key: ConfigKey.property_tableCellType,
|
|
3825
|
+
// HTML.md §8: first-match predicate selecting `<th>` vs `<td>`.
|
|
3826
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3761
3827
|
description: "Table cell type (th/td).",
|
|
3762
3828
|
format: TagFormat.plainText
|
|
3763
3829
|
},
|
|
@@ -3780,6 +3846,9 @@ var CARDSETS = {
|
|
|
3780
3846
|
key: ConfigKey.property_tableColWidth,
|
|
3781
3847
|
jsonKey: "^table.columnWidths[{s}]",
|
|
3782
3848
|
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
3849
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3850
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3851
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3783
3852
|
description: "Width for the column.",
|
|
3784
3853
|
format: TagFormat.number
|
|
3785
3854
|
}
|
|
@@ -3795,6 +3864,12 @@ var CARDSETS = {
|
|
|
3795
3864
|
//
|
|
3796
3865
|
[CardSetConfigKey.tableExtended]: {
|
|
3797
3866
|
jsonKey: null,
|
|
3867
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping for the extended table.
|
|
3868
|
+
// The card-set container is the `<table>` element; each section is a
|
|
3869
|
+
// table section element (`<thead>`/`<tbody>`/`<tfoot>`) whose children are
|
|
3870
|
+
// `<tr>` rows, and each cell side is a `<td>` (body) or `<th>` (header /
|
|
3871
|
+
// footer, via the section sideHtmlKey override).
|
|
3872
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3798
3873
|
sections: {
|
|
3799
3874
|
"table-header": {
|
|
3800
3875
|
jsonKey: "table.header.rows",
|
|
@@ -3814,19 +3889,29 @@ var CARDSETS = {
|
|
|
3814
3889
|
},
|
|
3815
3890
|
{ table: { header: { rows: ["$"] } } }
|
|
3816
3891
|
],
|
|
3892
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3817
3893
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3818
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3894
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3895
|
+
// Header cells are `<th>`. The `width` attribute is contributed by the
|
|
3896
|
+
// `@tableColWidth` tag, which bubbles it onto the enclosing `<th>`
|
|
3897
|
+
// (HTML-C2) — so it is not repeated here.
|
|
3898
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3819
3899
|
},
|
|
3820
3900
|
"table-body": {
|
|
3821
3901
|
jsonKey: "table.body.rows",
|
|
3822
3902
|
exportJsonKey: { table: { body: { rows: "$" } } },
|
|
3903
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3823
3904
|
isDefault: true
|
|
3824
3905
|
},
|
|
3825
3906
|
"table-footer": {
|
|
3826
3907
|
jsonKey: "table.footer.rows",
|
|
3827
3908
|
exportJsonKey: { table: { footer: { rows: "$" } } },
|
|
3909
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
|
|
3828
3910
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3829
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3911
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3912
|
+
// Footer cells render as `<th>` (mirrors the header `title: true`
|
|
3913
|
+
// mapping); §8 lists only the header side, so this parallels it.
|
|
3914
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3830
3915
|
}
|
|
3831
3916
|
},
|
|
3832
3917
|
sides: [
|
|
@@ -3835,6 +3920,9 @@ var CARDSETS = {
|
|
|
3835
3920
|
repeat: true,
|
|
3836
3921
|
jsonKey: "cells[{s}]",
|
|
3837
3922
|
exportJsonKey: { cells: { $s: "$" } },
|
|
3923
|
+
// Default (body) cell → `<td>`; the header/footer sections override the
|
|
3924
|
+
// side to `<th>` via their sideHtmlKey (HTML.md §8).
|
|
3925
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3838
3926
|
variants: [
|
|
3839
3927
|
{
|
|
3840
3928
|
jsonKey: "content",
|
|
@@ -3858,6 +3946,9 @@ var CARDSETS = {
|
|
|
3858
3946
|
key: ConfigKey.property_tableCellType,
|
|
3859
3947
|
jsonKey: "title|bool(th)",
|
|
3860
3948
|
exportJsonKey: [{ "@value=th": { title: true } }],
|
|
3949
|
+
// HTML.md §8: same first-match predicate machinery selecting
|
|
3950
|
+
// `<th>` vs `<td>` instead of `title:true` vs nothing.
|
|
3951
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3861
3952
|
description: "Table cell type (th/td).",
|
|
3862
3953
|
format: TagFormat.plainText
|
|
3863
3954
|
},
|
|
@@ -3887,6 +3978,9 @@ var CARDSETS = {
|
|
|
3887
3978
|
// PLAN-080: write to the cell's `colwidth` field.
|
|
3888
3979
|
jsonKey: "colwidth",
|
|
3889
3980
|
exportJsonKey: { colwidth: "$" },
|
|
3981
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3982
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3983
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3890
3984
|
description: "Width for the column.",
|
|
3891
3985
|
format: TagFormat.number
|
|
3892
3986
|
}
|
|
@@ -6815,7 +6909,9 @@ var ConfigHydrator = class {
|
|
|
6815
6909
|
variantsOfSide,
|
|
6816
6910
|
_side.jsonKey,
|
|
6817
6911
|
_side.exportJsonKey,
|
|
6818
|
-
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
|
|
6912
|
+
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey"),
|
|
6913
|
+
_side.htmlKey,
|
|
6914
|
+
Object.prototype.hasOwnProperty.call(_side, "htmlKey")
|
|
6819
6915
|
);
|
|
6820
6916
|
sides.push(sideConfig);
|
|
6821
6917
|
}
|
|
@@ -6825,7 +6921,9 @@ var ConfigHydrator = class {
|
|
|
6825
6921
|
_cardSetConfig.exportJsonKey,
|
|
6826
6922
|
Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
|
|
6827
6923
|
this.hydrateCardSections(_cardSetConfig.sections),
|
|
6828
|
-
sides
|
|
6924
|
+
sides,
|
|
6925
|
+
_cardSetConfig.htmlKey,
|
|
6926
|
+
Object.prototype.hasOwnProperty.call(_cardSetConfig, "htmlKey")
|
|
6829
6927
|
);
|
|
6830
6928
|
return cardSetConfig;
|
|
6831
6929
|
}
|
|
@@ -6837,10 +6935,14 @@ var ConfigHydrator = class {
|
|
|
6837
6935
|
jsonKey: v.jsonKey,
|
|
6838
6936
|
exportJsonKey: v.exportJsonKey,
|
|
6839
6937
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
|
|
6938
|
+
htmlKey: v.htmlKey,
|
|
6939
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(v, "htmlKey"),
|
|
6840
6940
|
isDefault: v.isDefault,
|
|
6841
6941
|
sideJsonKey: v.sideJsonKey,
|
|
6842
6942
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
6843
6943
|
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
6944
|
+
sideHtmlKey: v.sideHtmlKey,
|
|
6945
|
+
hasSideHtmlKey: Object.prototype.hasOwnProperty.call(v, "sideHtmlKey"),
|
|
6844
6946
|
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6845
6947
|
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6846
6948
|
// as unbounded).
|
|
@@ -6858,7 +6960,8 @@ var ConfigHydrator = class {
|
|
|
6858
6960
|
chain: _chain,
|
|
6859
6961
|
deprecated,
|
|
6860
6962
|
jsonKey,
|
|
6861
|
-
exportJsonKey
|
|
6963
|
+
exportJsonKey,
|
|
6964
|
+
htmlKey
|
|
6862
6965
|
} = _tag;
|
|
6863
6966
|
const configKey = Enum2(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6864
6967
|
if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
|
|
@@ -6877,6 +6980,8 @@ var ConfigHydrator = class {
|
|
|
6877
6980
|
jsonKey,
|
|
6878
6981
|
exportJsonKey,
|
|
6879
6982
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
6983
|
+
htmlKey,
|
|
6984
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6880
6985
|
deprecated
|
|
6881
6986
|
});
|
|
6882
6987
|
return {
|
|
@@ -6896,7 +7001,8 @@ var ConfigHydrator = class {
|
|
|
6896
7001
|
values,
|
|
6897
7002
|
defaultValue,
|
|
6898
7003
|
jsonKey,
|
|
6899
|
-
exportJsonKey
|
|
7004
|
+
exportJsonKey,
|
|
7005
|
+
htmlKey
|
|
6900
7006
|
} = _tag;
|
|
6901
7007
|
const configKey = Enum2(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6902
7008
|
if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
|
|
@@ -6914,6 +7020,8 @@ var ConfigHydrator = class {
|
|
|
6914
7020
|
jsonKey,
|
|
6915
7021
|
exportJsonKey,
|
|
6916
7022
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7023
|
+
htmlKey,
|
|
7024
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6917
7025
|
format,
|
|
6918
7026
|
values,
|
|
6919
7027
|
defaultValue,
|
|
@@ -6933,7 +7041,8 @@ var ConfigHydrator = class {
|
|
|
6933
7041
|
chain: _chain,
|
|
6934
7042
|
deprecated,
|
|
6935
7043
|
jsonKey,
|
|
6936
|
-
exportJsonKey
|
|
7044
|
+
exportJsonKey,
|
|
7045
|
+
htmlKey
|
|
6937
7046
|
} = _tag;
|
|
6938
7047
|
const configKey = Enum2(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6939
7048
|
if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
|
|
@@ -6951,6 +7060,8 @@ var ConfigHydrator = class {
|
|
|
6951
7060
|
jsonKey,
|
|
6952
7061
|
exportJsonKey,
|
|
6953
7062
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7063
|
+
htmlKey,
|
|
7064
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6954
7065
|
deprecated
|
|
6955
7066
|
});
|
|
6956
7067
|
return {
|
|
@@ -6989,6 +7100,7 @@ var ConfigHydrator = class {
|
|
|
6989
7100
|
repeatCount,
|
|
6990
7101
|
jsonKey,
|
|
6991
7102
|
exportJsonKey,
|
|
7103
|
+
htmlKey,
|
|
6992
7104
|
format
|
|
6993
7105
|
} = _variant;
|
|
6994
7106
|
const tags2 = this.hydrateTagsConfig(_tags);
|
|
@@ -7000,7 +7112,9 @@ var ConfigHydrator = class {
|
|
|
7000
7112
|
jsonKey,
|
|
7001
7113
|
exportJsonKey,
|
|
7002
7114
|
Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
|
|
7003
|
-
format
|
|
7115
|
+
format,
|
|
7116
|
+
htmlKey,
|
|
7117
|
+
Object.prototype.hasOwnProperty.call(_variant, "htmlKey")
|
|
7004
7118
|
);
|
|
7005
7119
|
return cardSetConfig;
|
|
7006
7120
|
}
|
|
@@ -10133,11 +10247,6 @@ var BITS = {
|
|
|
10133
10247
|
baseBitType: BitType._standard,
|
|
10134
10248
|
description: "Extractor rule bit, used to define extraction rules with reference images and instructions",
|
|
10135
10249
|
tags: [
|
|
10136
|
-
{
|
|
10137
|
-
exportJsonKey: { title: "$" },
|
|
10138
|
-
key: ConfigKey.tag_title,
|
|
10139
|
-
description: "The name of the extraction rule"
|
|
10140
|
-
},
|
|
10141
10250
|
{
|
|
10142
10251
|
key: ConfigKey.group_resourceBitTags,
|
|
10143
10252
|
description: "Resource bit tags for extraction rule images"
|
|
@@ -10816,6 +10925,26 @@ var BITS = {
|
|
|
10816
10925
|
baseBitType: BitType.tableImage,
|
|
10817
10926
|
description: "Standard non-normative remark table image bit, used to create non-normative remark images in tables in articles or books"
|
|
10818
10927
|
},
|
|
10928
|
+
[BitType.standardTableExtendedImageNormative]: {
|
|
10929
|
+
since: "1.16.0",
|
|
10930
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10931
|
+
description: "Standard normative extended table image bit, used to create normative extended images in tables in articles or books"
|
|
10932
|
+
},
|
|
10933
|
+
[BitType.standardTableExtendedImageNonNormative]: {
|
|
10934
|
+
since: "1.16.0",
|
|
10935
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10936
|
+
description: "Standard non-normative extended table image bit, used to create non-normative extended images in tables in articles or books"
|
|
10937
|
+
},
|
|
10938
|
+
[BitType.standardRemarkTableExtendedImageNormative]: {
|
|
10939
|
+
since: "1.17.0",
|
|
10940
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10941
|
+
description: "Standard normative remark extended table image bit, used to create normative remark extended images in tables in articles or books"
|
|
10942
|
+
},
|
|
10943
|
+
[BitType.standardRemarkTableExtendedImageNonNormative]: {
|
|
10944
|
+
since: "1.17.0",
|
|
10945
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10946
|
+
description: "Standard non-normative remark extended table image bit, used to create non-normative remark extended images in tables in articles or books"
|
|
10947
|
+
},
|
|
10819
10948
|
[BitType.smartStandardTableImageNormative]: {
|
|
10820
10949
|
since: "1.28.0",
|
|
10821
10950
|
baseBitType: BitType.standardTableImageNormative,
|
|
@@ -10836,6 +10965,26 @@ var BITS = {
|
|
|
10836
10965
|
baseBitType: BitType.standardRemarkTableImageNonNormative,
|
|
10837
10966
|
description: "Smart standard non-normative remark table image bit, used to create smart standard non-normative remark images in tables in articles or books"
|
|
10838
10967
|
},
|
|
10968
|
+
[BitType.smartStandardTableExtendedImageNormative]: {
|
|
10969
|
+
since: "1.28.0",
|
|
10970
|
+
baseBitType: BitType.standardTableExtendedImageNormative,
|
|
10971
|
+
description: "Smart standard normative extended table image bit, used to create smart standard normative extended images in tables in articles or books"
|
|
10972
|
+
},
|
|
10973
|
+
[BitType.smartStandardTableExtendedImageNonNormative]: {
|
|
10974
|
+
since: "1.28.0",
|
|
10975
|
+
baseBitType: BitType.standardTableExtendedImageNonNormative,
|
|
10976
|
+
description: "Smart standard non-normative extended table image bit, used to create smart standard non-normative extended images in tables in articles or books"
|
|
10977
|
+
},
|
|
10978
|
+
[BitType.smartStandardRemarkTableExtendedImageNormative]: {
|
|
10979
|
+
since: "1.28.0",
|
|
10980
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNormative,
|
|
10981
|
+
description: "Smart standard normative remark extended table image bit, used to create smart standard normative remark extended images in tables in articles or books"
|
|
10982
|
+
},
|
|
10983
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormative]: {
|
|
10984
|
+
since: "1.28.0",
|
|
10985
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNonNormative,
|
|
10986
|
+
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"
|
|
10987
|
+
},
|
|
10839
10988
|
[BitType.smartStandardTableImageNormativeCollapsible]: {
|
|
10840
10989
|
since: "1.28.0",
|
|
10841
10990
|
baseBitType: BitType.smartStandardTableImageNormative,
|
|
@@ -10856,6 +11005,26 @@ var BITS = {
|
|
|
10856
11005
|
baseBitType: BitType.smartStandardRemarkTableImageNonNormative,
|
|
10857
11006
|
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"
|
|
10858
11007
|
},
|
|
11008
|
+
[BitType.smartStandardTableExtendedImageNormativeCollapsible]: {
|
|
11009
|
+
since: "1.28.0",
|
|
11010
|
+
baseBitType: BitType.smartStandardTableExtendedImageNormative,
|
|
11011
|
+
description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
|
|
11012
|
+
},
|
|
11013
|
+
[BitType.smartStandardTableExtendedImageNonNormativeCollapsible]: {
|
|
11014
|
+
since: "1.28.0",
|
|
11015
|
+
baseBitType: BitType.smartStandardTableExtendedImageNonNormative,
|
|
11016
|
+
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"
|
|
11017
|
+
},
|
|
11018
|
+
[BitType.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
|
|
11019
|
+
since: "1.28.0",
|
|
11020
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNormative,
|
|
11021
|
+
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"
|
|
11022
|
+
},
|
|
11023
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
|
|
11024
|
+
since: "1.28.0",
|
|
11025
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNonNormative,
|
|
11026
|
+
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"
|
|
11027
|
+
},
|
|
10859
11028
|
[BitType.imageLink]: {
|
|
10860
11029
|
since: "1.3.0",
|
|
10861
11030
|
baseBitType: BitType._standard,
|
|
@@ -12532,6 +12701,26 @@ var BITS = {
|
|
|
12532
12701
|
baseBitType: BitType.table,
|
|
12533
12702
|
description: "Standard non-normative remark table bit, used to create standard non-normative remark tables in articles or books"
|
|
12534
12703
|
},
|
|
12704
|
+
[BitType.standardTableExtendedNormative]: {
|
|
12705
|
+
since: "1.16.0",
|
|
12706
|
+
baseBitType: BitType.tableExtended,
|
|
12707
|
+
description: "Standard normative extended table bit, used to create standard normative extended tables in articles or books"
|
|
12708
|
+
},
|
|
12709
|
+
[BitType.standardTableExtendedNonNormative]: {
|
|
12710
|
+
since: "1.16.0",
|
|
12711
|
+
baseBitType: BitType.tableExtended,
|
|
12712
|
+
description: "Standard non-normative extended table bit, used to create standard non-normative extended tables in articles or books"
|
|
12713
|
+
},
|
|
12714
|
+
[BitType.standardRemarkTableExtendedNormative]: {
|
|
12715
|
+
since: "1.17.0",
|
|
12716
|
+
baseBitType: BitType.tableExtended,
|
|
12717
|
+
description: "Standard normative remark extended table bit, used to create standard normative remark extended tables in articles or books"
|
|
12718
|
+
},
|
|
12719
|
+
[BitType.standardRemarkTableExtendedNonNormative]: {
|
|
12720
|
+
since: "1.17.0",
|
|
12721
|
+
baseBitType: BitType.tableExtended,
|
|
12722
|
+
description: "Standard non-normative remark extended table bit, used to create standard non-normative remark extended tables in articles or books"
|
|
12723
|
+
},
|
|
12535
12724
|
[BitType.smartStandardTableNormative]: {
|
|
12536
12725
|
since: "1.28.0",
|
|
12537
12726
|
baseBitType: BitType.standardTableNormative,
|
|
@@ -12552,6 +12741,26 @@ var BITS = {
|
|
|
12552
12741
|
baseBitType: BitType.standardRemarkTableNonNormative,
|
|
12553
12742
|
description: "Smart standard non-normative remark table bit, used to create smart standard non-normative remark tables in articles or books"
|
|
12554
12743
|
},
|
|
12744
|
+
[BitType.smartStandardTableExtendedNormative]: {
|
|
12745
|
+
since: "1.28.0",
|
|
12746
|
+
baseBitType: BitType.standardTableExtendedNormative,
|
|
12747
|
+
description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
|
|
12748
|
+
},
|
|
12749
|
+
[BitType.smartStandardTableExtendedNonNormative]: {
|
|
12750
|
+
since: "1.28.0",
|
|
12751
|
+
baseBitType: BitType.standardTableExtendedNonNormative,
|
|
12752
|
+
description: "Smart standard non-normative extended table bit, used to create smart standard non-normative extended tables in articles or books"
|
|
12753
|
+
},
|
|
12754
|
+
[BitType.smartStandardRemarkTableExtendedNormative]: {
|
|
12755
|
+
since: "1.28.0",
|
|
12756
|
+
baseBitType: BitType.standardRemarkTableExtendedNormative,
|
|
12757
|
+
description: "Smart standard normative remark extended table bit, used to create smart standard normative remark extended tables in articles or books"
|
|
12758
|
+
},
|
|
12759
|
+
[BitType.smartStandardRemarkTableExtendedNonNormative]: {
|
|
12760
|
+
since: "1.28.0",
|
|
12761
|
+
baseBitType: BitType.standardRemarkTableExtendedNonNormative,
|
|
12762
|
+
description: "Smart standard non-normative remark extended table bit, used to create smart standard non-normative remark extended tables in articles or books"
|
|
12763
|
+
},
|
|
12555
12764
|
[BitType.smartStandardTableNormativeCollapsible]: {
|
|
12556
12765
|
since: "1.28.0",
|
|
12557
12766
|
baseBitType: BitType.smartStandardTableNormative,
|
|
@@ -12572,6 +12781,26 @@ var BITS = {
|
|
|
12572
12781
|
baseBitType: BitType.smartStandardRemarkTableNonNormative,
|
|
12573
12782
|
description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
|
|
12574
12783
|
},
|
|
12784
|
+
[BitType.smartStandardTableExtendedNormativeCollapsible]: {
|
|
12785
|
+
since: "1.28.0",
|
|
12786
|
+
baseBitType: BitType.smartStandardTableExtendedNormative,
|
|
12787
|
+
description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
|
|
12788
|
+
},
|
|
12789
|
+
[BitType.smartStandardTableExtendedNonNormativeCollapsible]: {
|
|
12790
|
+
since: "1.28.0",
|
|
12791
|
+
baseBitType: BitType.smartStandardTableExtendedNonNormative,
|
|
12792
|
+
description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
|
|
12793
|
+
},
|
|
12794
|
+
[BitType.smartStandardRemarkTableExtendedNormativeCollapsible]: {
|
|
12795
|
+
since: "1.28.0",
|
|
12796
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNormative,
|
|
12797
|
+
description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
|
|
12798
|
+
},
|
|
12799
|
+
[BitType.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
|
|
12800
|
+
since: "1.28.0",
|
|
12801
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNonNormative,
|
|
12802
|
+
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"
|
|
12803
|
+
},
|
|
12575
12804
|
[BitType.parameters]: {
|
|
12576
12805
|
since: "1.18.0",
|
|
12577
12806
|
baseBitType: BitType.table,
|
|
@@ -13513,6 +13742,8 @@ var Config = class {
|
|
|
13513
13742
|
jsonKey: tag.jsonKey,
|
|
13514
13743
|
exportJsonKey: tag.exportJsonKey,
|
|
13515
13744
|
hasExportJsonKey: tag.hasExportJsonKey,
|
|
13745
|
+
htmlKey: tag.htmlKey,
|
|
13746
|
+
hasHtmlKey: tag.hasHtmlKey,
|
|
13516
13747
|
deprecated: tag.deprecated
|
|
13517
13748
|
});
|
|
13518
13749
|
finalResourceTags[k] = newTag;
|
|
@@ -13617,7 +13848,7 @@ var instance2 = new Config();
|
|
|
13617
13848
|
// src/generated/package_info.ts
|
|
13618
13849
|
var PACKAGE_INFO = {
|
|
13619
13850
|
"name": "@gmb/bitmark-parser-generator",
|
|
13620
|
-
"version": "5.
|
|
13851
|
+
"version": "5.27.0",
|
|
13621
13852
|
"author": "Get More Brain Ltd",
|
|
13622
13853
|
"license": "ISC",
|
|
13623
13854
|
"description": "A bitmark parser and generator using Peggy.js"
|
|
@@ -32973,6 +33204,235 @@ var BitmarkStringGenerator = class {
|
|
|
32973
33204
|
}
|
|
32974
33205
|
};
|
|
32975
33206
|
|
|
33207
|
+
// src/generator/html/HtmlTableGenerator.ts
|
|
33208
|
+
var MARK_TO_TAG = {
|
|
33209
|
+
bold: "b",
|
|
33210
|
+
italic: "i",
|
|
33211
|
+
superscript: "sup",
|
|
33212
|
+
subscript: "sub",
|
|
33213
|
+
strike: "s",
|
|
33214
|
+
del: "del",
|
|
33215
|
+
ins: "ins",
|
|
33216
|
+
underline: "u",
|
|
33217
|
+
highlight: "mark",
|
|
33218
|
+
code: "code"
|
|
33219
|
+
};
|
|
33220
|
+
var HtmlTableGenerator = class {
|
|
33221
|
+
constructor() {
|
|
33222
|
+
__publicField(this, "indentUnit", " ");
|
|
33223
|
+
}
|
|
33224
|
+
/**
|
|
33225
|
+
* Generate HTML table fragments from a string or JSON value.
|
|
33226
|
+
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
33227
|
+
*/
|
|
33228
|
+
generate(input) {
|
|
33229
|
+
let data = input;
|
|
33230
|
+
if (typeof data === "string") {
|
|
33231
|
+
try {
|
|
33232
|
+
data = JSON.parse(data);
|
|
33233
|
+
} catch {
|
|
33234
|
+
return "";
|
|
33235
|
+
}
|
|
33236
|
+
}
|
|
33237
|
+
const bits = this.collectBits(data);
|
|
33238
|
+
const fragments = [];
|
|
33239
|
+
for (const bit of bits) {
|
|
33240
|
+
const html = this.renderTableBit(bit);
|
|
33241
|
+
if (html) fragments.push(html);
|
|
33242
|
+
}
|
|
33243
|
+
return fragments.join("\n\n");
|
|
33244
|
+
}
|
|
33245
|
+
// --- bit collection -------------------------------------------------------
|
|
33246
|
+
collectBits(data) {
|
|
33247
|
+
const out = [];
|
|
33248
|
+
const visit = (value) => {
|
|
33249
|
+
if (value == null || typeof value !== "object") return;
|
|
33250
|
+
if (Array.isArray(value)) {
|
|
33251
|
+
value.forEach(visit);
|
|
33252
|
+
return;
|
|
33253
|
+
}
|
|
33254
|
+
const obj = value;
|
|
33255
|
+
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
33256
|
+
out.push(obj.bit);
|
|
33257
|
+
} else if ("type" in obj) {
|
|
33258
|
+
out.push(obj);
|
|
33259
|
+
}
|
|
33260
|
+
};
|
|
33261
|
+
visit(data);
|
|
33262
|
+
return out;
|
|
33263
|
+
}
|
|
33264
|
+
// --- table rendering ------------------------------------------------------
|
|
33265
|
+
renderTableBit(bit) {
|
|
33266
|
+
const table = bit.table;
|
|
33267
|
+
if (!table) return "";
|
|
33268
|
+
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
33269
|
+
const extended = this.toExtended(table);
|
|
33270
|
+
const lines = [];
|
|
33271
|
+
lines.push("<table>");
|
|
33272
|
+
if (bit.caption != null) {
|
|
33273
|
+
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
33274
|
+
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
33275
|
+
}
|
|
33276
|
+
this.renderSection(lines, "thead", extended.header, "header");
|
|
33277
|
+
this.renderSection(lines, "tbody", extended.body, "body");
|
|
33278
|
+
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
33279
|
+
lines.push("</table>");
|
|
33280
|
+
return lines.join("\n");
|
|
33281
|
+
}
|
|
33282
|
+
toExtended(table) {
|
|
33283
|
+
const t = table;
|
|
33284
|
+
if (t.header || t.body || t.footer) return table;
|
|
33285
|
+
return convertBasicToExtendedTableFormat(table);
|
|
33286
|
+
}
|
|
33287
|
+
renderSection(lines, tag, section, key) {
|
|
33288
|
+
if (!section || !section.rows || section.rows.length === 0) return;
|
|
33289
|
+
lines.push(`${this.indentUnit}<${tag}>`);
|
|
33290
|
+
for (const row of section.rows) {
|
|
33291
|
+
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
33292
|
+
for (const cell of row.cells ?? []) {
|
|
33293
|
+
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
33294
|
+
}
|
|
33295
|
+
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
33296
|
+
}
|
|
33297
|
+
lines.push(`${this.indentUnit}</${tag}>`);
|
|
33298
|
+
}
|
|
33299
|
+
renderCell(cell, _key) {
|
|
33300
|
+
const tag = cell.title === true ? "th" : "td";
|
|
33301
|
+
const attrs = [];
|
|
33302
|
+
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
33303
|
+
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
33304
|
+
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
33305
|
+
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
33306
|
+
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
33307
|
+
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
33308
|
+
}
|
|
33309
|
+
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
33310
|
+
asTextAst(content) {
|
|
33311
|
+
if (content == null) return [];
|
|
33312
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
33313
|
+
return content;
|
|
33314
|
+
}
|
|
33315
|
+
cellContentToHtml(blocks) {
|
|
33316
|
+
if (blocks.length === 0) return "";
|
|
33317
|
+
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
33318
|
+
return this.inlineToHtml(blocks[0].content ?? []);
|
|
33319
|
+
}
|
|
33320
|
+
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
33321
|
+
}
|
|
33322
|
+
blockToHtml(node) {
|
|
33323
|
+
switch (node.type) {
|
|
33324
|
+
case "paragraph":
|
|
33325
|
+
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
33326
|
+
case "bulletList":
|
|
33327
|
+
case "noBulletList":
|
|
33328
|
+
case "orderedList":
|
|
33329
|
+
case "orderedListRoman":
|
|
33330
|
+
case "orderedListRomanLower":
|
|
33331
|
+
case "letteredList":
|
|
33332
|
+
case "letteredListLower":
|
|
33333
|
+
case "taskList":
|
|
33334
|
+
return this.listToHtml(node);
|
|
33335
|
+
case "image":
|
|
33336
|
+
case "imageInline":
|
|
33337
|
+
return this.imageToHtml(node);
|
|
33338
|
+
default:
|
|
33339
|
+
return this.inlineToHtml([node]);
|
|
33340
|
+
}
|
|
33341
|
+
}
|
|
33342
|
+
inlineToHtml(nodes) {
|
|
33343
|
+
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
33344
|
+
}
|
|
33345
|
+
inlineNodeToHtml(node) {
|
|
33346
|
+
if (node.type === "hardBreak") return "<br>";
|
|
33347
|
+
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
33348
|
+
if (node.type === "text") {
|
|
33349
|
+
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
33350
|
+
}
|
|
33351
|
+
if (node.content) return this.inlineToHtml(node.content);
|
|
33352
|
+
return this.escapeText(node.text ?? "");
|
|
33353
|
+
}
|
|
33354
|
+
wrapMarks(text, marks) {
|
|
33355
|
+
if (!marks || marks.length === 0) return text;
|
|
33356
|
+
let open = "";
|
|
33357
|
+
let close = "";
|
|
33358
|
+
for (const mark of marks) {
|
|
33359
|
+
if (mark.type === "link") {
|
|
33360
|
+
const href = mark.attrs?.href ?? "";
|
|
33361
|
+
open += `<a href="${this.escapeAttr(href)}">`;
|
|
33362
|
+
close = `</a>${close}`;
|
|
33363
|
+
} else {
|
|
33364
|
+
const tag = MARK_TO_TAG[mark.type];
|
|
33365
|
+
if (tag) {
|
|
33366
|
+
open += `<${tag}>`;
|
|
33367
|
+
close = `</${tag}>${close}`;
|
|
33368
|
+
}
|
|
33369
|
+
}
|
|
33370
|
+
}
|
|
33371
|
+
return `${open}${text}${close}`;
|
|
33372
|
+
}
|
|
33373
|
+
// --- lists ----------------------------------------------------------------
|
|
33374
|
+
listToHtml(node) {
|
|
33375
|
+
const { tag, attrs } = this.listTag(node);
|
|
33376
|
+
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
33377
|
+
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
33378
|
+
}
|
|
33379
|
+
listTag(node) {
|
|
33380
|
+
const start = node.attrs?.start;
|
|
33381
|
+
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
33382
|
+
switch (node.type) {
|
|
33383
|
+
case "orderedList":
|
|
33384
|
+
return { tag: "ol", attrs: startAttr };
|
|
33385
|
+
case "orderedListRoman":
|
|
33386
|
+
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
33387
|
+
case "orderedListRomanLower":
|
|
33388
|
+
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
33389
|
+
case "letteredList":
|
|
33390
|
+
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
33391
|
+
case "letteredListLower":
|
|
33392
|
+
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
33393
|
+
case "noBulletList":
|
|
33394
|
+
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
33395
|
+
case "taskList":
|
|
33396
|
+
case "bulletList":
|
|
33397
|
+
default:
|
|
33398
|
+
return { tag: "ul", attrs: "" };
|
|
33399
|
+
}
|
|
33400
|
+
}
|
|
33401
|
+
listItemToHtml(item, task) {
|
|
33402
|
+
const inner = (item.content ?? []).map((b) => {
|
|
33403
|
+
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
33404
|
+
return this.blockToHtml(b);
|
|
33405
|
+
}).join("");
|
|
33406
|
+
if (task) {
|
|
33407
|
+
const checked = item.attrs?.checked ? " checked" : "";
|
|
33408
|
+
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
33409
|
+
}
|
|
33410
|
+
return `<li>${inner}</li>`;
|
|
33411
|
+
}
|
|
33412
|
+
// --- images ---------------------------------------------------------------
|
|
33413
|
+
imageToHtml(node) {
|
|
33414
|
+
const attrs = node.attrs ?? {};
|
|
33415
|
+
const parts = [];
|
|
33416
|
+
const src = attrs.src;
|
|
33417
|
+
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
33418
|
+
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
33419
|
+
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
33420
|
+
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
33421
|
+
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
33422
|
+
if (typeof attrs.class === "string" && attrs.class) {
|
|
33423
|
+
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
33424
|
+
}
|
|
33425
|
+
return `<img ${parts.join(" ")}>`;
|
|
33426
|
+
}
|
|
33427
|
+
// --- escaping -------------------------------------------------------------
|
|
33428
|
+
escapeText(text) {
|
|
33429
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
33430
|
+
}
|
|
33431
|
+
escapeAttr(text) {
|
|
33432
|
+
return this.escapeText(text).replace(/"/g, """);
|
|
33433
|
+
}
|
|
33434
|
+
};
|
|
33435
|
+
|
|
32976
33436
|
// src/generator/json/JsonGenerator.ts
|
|
32977
33437
|
import { Enum as Enum9 } from "@ncoderz/superenum";
|
|
32978
33438
|
var MOVE_BODY_RECURSION_LIMIT = 5e3;
|
|
@@ -37918,6 +38378,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
|
|
|
37918
38378
|
jsonKey: void 0,
|
|
37919
38379
|
exportJsonKey: void 0,
|
|
37920
38380
|
hasExportJsonKey: false,
|
|
38381
|
+
htmlKey: void 0,
|
|
38382
|
+
hasHtmlKey: false,
|
|
37921
38383
|
format: TagFormat.bitmarkText,
|
|
37922
38384
|
values: void 0,
|
|
37923
38385
|
defaultValue: void 0,
|
|
@@ -42315,6 +42777,499 @@ var BitmarkParser = class {
|
|
|
42315
42777
|
}
|
|
42316
42778
|
};
|
|
42317
42779
|
|
|
42780
|
+
// src/parser/html/HtmlDom.ts
|
|
42781
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
42782
|
+
"area",
|
|
42783
|
+
"base",
|
|
42784
|
+
"br",
|
|
42785
|
+
"col",
|
|
42786
|
+
"embed",
|
|
42787
|
+
"hr",
|
|
42788
|
+
"img",
|
|
42789
|
+
"input",
|
|
42790
|
+
"link",
|
|
42791
|
+
"meta",
|
|
42792
|
+
"param",
|
|
42793
|
+
"source",
|
|
42794
|
+
"track",
|
|
42795
|
+
"wbr"
|
|
42796
|
+
]);
|
|
42797
|
+
var IMPLIED_CLOSE = {
|
|
42798
|
+
li: /* @__PURE__ */ new Set(["li"]),
|
|
42799
|
+
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42800
|
+
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42801
|
+
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
42802
|
+
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42803
|
+
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42804
|
+
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42805
|
+
p: /* @__PURE__ */ new Set(["p"]),
|
|
42806
|
+
option: /* @__PURE__ */ new Set(["option"])
|
|
42807
|
+
};
|
|
42808
|
+
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
42809
|
+
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
42810
|
+
function parseAttrs(raw) {
|
|
42811
|
+
const attrs = {};
|
|
42812
|
+
if (!raw) return attrs;
|
|
42813
|
+
ATTR_RE.lastIndex = 0;
|
|
42814
|
+
let m;
|
|
42815
|
+
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
42816
|
+
const name = m[1].toLowerCase();
|
|
42817
|
+
let value = m[2] ?? "";
|
|
42818
|
+
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
42819
|
+
value = value.slice(1, -1);
|
|
42820
|
+
}
|
|
42821
|
+
attrs[name] = value;
|
|
42822
|
+
}
|
|
42823
|
+
return attrs;
|
|
42824
|
+
}
|
|
42825
|
+
function stripNonContent(html) {
|
|
42826
|
+
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, "");
|
|
42827
|
+
}
|
|
42828
|
+
function tokenize(html) {
|
|
42829
|
+
const tokens = [];
|
|
42830
|
+
const clean = stripNonContent(html);
|
|
42831
|
+
TAG_RE.lastIndex = 0;
|
|
42832
|
+
let lastIndex = 0;
|
|
42833
|
+
let m;
|
|
42834
|
+
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
42835
|
+
if (m.index > lastIndex) {
|
|
42836
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
42837
|
+
}
|
|
42838
|
+
lastIndex = TAG_RE.lastIndex;
|
|
42839
|
+
const isClose = m[1] === "/";
|
|
42840
|
+
const name = m[2].toLowerCase();
|
|
42841
|
+
if (isClose) {
|
|
42842
|
+
tokens.push({ kind: "close", name });
|
|
42843
|
+
} else {
|
|
42844
|
+
tokens.push({
|
|
42845
|
+
kind: "open",
|
|
42846
|
+
name,
|
|
42847
|
+
attrs: parseAttrs(m[3]),
|
|
42848
|
+
selfClose: m[4] === "/"
|
|
42849
|
+
});
|
|
42850
|
+
}
|
|
42851
|
+
}
|
|
42852
|
+
if (lastIndex < clean.length) {
|
|
42853
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
42854
|
+
}
|
|
42855
|
+
return tokens;
|
|
42856
|
+
}
|
|
42857
|
+
function parseHtml(html) {
|
|
42858
|
+
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
42859
|
+
const stack = [root];
|
|
42860
|
+
const top = () => stack[stack.length - 1];
|
|
42861
|
+
for (const token of tokenize(html)) {
|
|
42862
|
+
if (token.kind === "text") {
|
|
42863
|
+
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
42864
|
+
continue;
|
|
42865
|
+
}
|
|
42866
|
+
if (token.kind === "open") {
|
|
42867
|
+
const name = token.name;
|
|
42868
|
+
const closes = IMPLIED_CLOSE[name];
|
|
42869
|
+
if (closes) {
|
|
42870
|
+
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
42871
|
+
}
|
|
42872
|
+
const el = {
|
|
42873
|
+
type: "element",
|
|
42874
|
+
name,
|
|
42875
|
+
attrs: token.attrs ?? {},
|
|
42876
|
+
children: []
|
|
42877
|
+
};
|
|
42878
|
+
top().children.push(el);
|
|
42879
|
+
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
42880
|
+
stack.push(el);
|
|
42881
|
+
}
|
|
42882
|
+
continue;
|
|
42883
|
+
}
|
|
42884
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
42885
|
+
if (stack[i].name === token.name) {
|
|
42886
|
+
stack.length = i;
|
|
42887
|
+
break;
|
|
42888
|
+
}
|
|
42889
|
+
}
|
|
42890
|
+
}
|
|
42891
|
+
return root.children;
|
|
42892
|
+
}
|
|
42893
|
+
function childElements(el, names) {
|
|
42894
|
+
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
42895
|
+
}
|
|
42896
|
+
|
|
42897
|
+
// src/parser/html/HtmlTableParser.ts
|
|
42898
|
+
var MARK_TAGS = {
|
|
42899
|
+
b: "bold",
|
|
42900
|
+
strong: "bold",
|
|
42901
|
+
i: "italic",
|
|
42902
|
+
em: "italic",
|
|
42903
|
+
sup: "superscript",
|
|
42904
|
+
sub: "subscript",
|
|
42905
|
+
s: "strike",
|
|
42906
|
+
strike: "strike",
|
|
42907
|
+
del: "del",
|
|
42908
|
+
ins: "ins",
|
|
42909
|
+
u: "underline",
|
|
42910
|
+
mark: "highlight",
|
|
42911
|
+
code: "code"
|
|
42912
|
+
};
|
|
42913
|
+
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
42914
|
+
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
42915
|
+
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
42916
|
+
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
42917
|
+
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
42918
|
+
var NAMED_ENTITIES = {
|
|
42919
|
+
amp: "&",
|
|
42920
|
+
lt: "<",
|
|
42921
|
+
gt: ">",
|
|
42922
|
+
quot: '"',
|
|
42923
|
+
apos: "'",
|
|
42924
|
+
nbsp: "\xA0"
|
|
42925
|
+
};
|
|
42926
|
+
function decodeEntities(text) {
|
|
42927
|
+
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
42928
|
+
if (body[0] === "#") {
|
|
42929
|
+
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
42930
|
+
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
42931
|
+
try {
|
|
42932
|
+
return String.fromCodePoint(code);
|
|
42933
|
+
} catch {
|
|
42934
|
+
return whole;
|
|
42935
|
+
}
|
|
42936
|
+
}
|
|
42937
|
+
return whole;
|
|
42938
|
+
}
|
|
42939
|
+
return NAMED_ENTITIES[body] ?? whole;
|
|
42940
|
+
});
|
|
42941
|
+
}
|
|
42942
|
+
function intAttr(value) {
|
|
42943
|
+
if (value == null) return void 0;
|
|
42944
|
+
const n = Number.parseInt(value, 10);
|
|
42945
|
+
return Number.isInteger(n) ? n : void 0;
|
|
42946
|
+
}
|
|
42947
|
+
function isElement(node) {
|
|
42948
|
+
return node.type === "element";
|
|
42949
|
+
}
|
|
42950
|
+
var HtmlTableParser = class {
|
|
42951
|
+
constructor() {
|
|
42952
|
+
__publicField(this, "keepUnknownTags", false);
|
|
42953
|
+
}
|
|
42954
|
+
/**
|
|
42955
|
+
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
42956
|
+
*/
|
|
42957
|
+
parse(html, options) {
|
|
42958
|
+
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
42959
|
+
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
42960
|
+
const onWarning = options?.onWarning;
|
|
42961
|
+
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
42962
|
+
const bits = [];
|
|
42963
|
+
for (const table of tables) {
|
|
42964
|
+
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
42965
|
+
if (bit) bits.push(bit);
|
|
42966
|
+
}
|
|
42967
|
+
return bits;
|
|
42968
|
+
}
|
|
42969
|
+
// --- table extraction -----------------------------------------------------
|
|
42970
|
+
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
42971
|
+
collectTopLevelTables(nodes) {
|
|
42972
|
+
const tables = [];
|
|
42973
|
+
const visit = (node) => {
|
|
42974
|
+
if (!isElement(node)) return;
|
|
42975
|
+
if (node.name === "table") {
|
|
42976
|
+
tables.push(node);
|
|
42977
|
+
return;
|
|
42978
|
+
}
|
|
42979
|
+
node.children.forEach(visit);
|
|
42980
|
+
};
|
|
42981
|
+
nodes.forEach(visit);
|
|
42982
|
+
return tables;
|
|
42983
|
+
}
|
|
42984
|
+
tableToBit(table, tableFormat, onWarning) {
|
|
42985
|
+
const header = [];
|
|
42986
|
+
const body = [];
|
|
42987
|
+
const footer = [];
|
|
42988
|
+
let caption;
|
|
42989
|
+
for (const child of table.children) {
|
|
42990
|
+
if (!isElement(child)) continue;
|
|
42991
|
+
if (child.name === "caption") {
|
|
42992
|
+
const capContent = this.inlineNodes(child.children, []);
|
|
42993
|
+
const trimmed = this.trimInline(capContent);
|
|
42994
|
+
if (trimmed.length > 0) caption = trimmed;
|
|
42995
|
+
} else if (SECTION_TAGS.has(child.name)) {
|
|
42996
|
+
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
42997
|
+
for (const tr of childElements(child, ROW_TAGS)) {
|
|
42998
|
+
target.push(this.rowToCells(tr));
|
|
42999
|
+
}
|
|
43000
|
+
} else if (ROW_TAGS.has(child.name)) {
|
|
43001
|
+
body.push(this.rowToCells(child));
|
|
43002
|
+
}
|
|
43003
|
+
}
|
|
43004
|
+
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
43005
|
+
return void 0;
|
|
43006
|
+
}
|
|
43007
|
+
const tableExtended = {};
|
|
43008
|
+
if (header.length > 0) tableExtended.header = { rows: header };
|
|
43009
|
+
if (body.length > 0) tableExtended.body = { rows: body };
|
|
43010
|
+
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
43011
|
+
let tableData = tableExtended;
|
|
43012
|
+
if (tableFormat === "table") {
|
|
43013
|
+
if (this.isLossyAsBasic(tableExtended)) {
|
|
43014
|
+
onWarning?.(
|
|
43015
|
+
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
43016
|
+
);
|
|
43017
|
+
}
|
|
43018
|
+
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
43019
|
+
}
|
|
43020
|
+
const bit = {
|
|
43021
|
+
type: tableFormat,
|
|
43022
|
+
format: "bitmark++",
|
|
43023
|
+
table: tableData
|
|
43024
|
+
};
|
|
43025
|
+
if (caption) bit.caption = caption;
|
|
43026
|
+
return bit;
|
|
43027
|
+
}
|
|
43028
|
+
rowToCells(tr) {
|
|
43029
|
+
const cells = [];
|
|
43030
|
+
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
43031
|
+
cells.push(this.cellToJson(cell));
|
|
43032
|
+
}
|
|
43033
|
+
return { cells };
|
|
43034
|
+
}
|
|
43035
|
+
cellToJson(cell) {
|
|
43036
|
+
const json = {
|
|
43037
|
+
content: this.blockNodes(cell.children)
|
|
43038
|
+
};
|
|
43039
|
+
if (cell.name === "th") json.title = true;
|
|
43040
|
+
const rowspan = intAttr(cell.attrs.rowspan);
|
|
43041
|
+
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
43042
|
+
const colspan = intAttr(cell.attrs.colspan);
|
|
43043
|
+
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
43044
|
+
const scope = cell.attrs.scope?.toLowerCase();
|
|
43045
|
+
if (scope && VALID_SCOPES.has(scope)) {
|
|
43046
|
+
json.scope = scope;
|
|
43047
|
+
}
|
|
43048
|
+
const width = this.widthFromCell(cell);
|
|
43049
|
+
if (width != null) json.colwidth = width;
|
|
43050
|
+
return json;
|
|
43051
|
+
}
|
|
43052
|
+
widthFromCell(cell) {
|
|
43053
|
+
const attrWidth = intAttr(cell.attrs.width);
|
|
43054
|
+
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
43055
|
+
const style = cell.attrs.style;
|
|
43056
|
+
if (style) {
|
|
43057
|
+
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
43058
|
+
if (m) {
|
|
43059
|
+
const n = Number.parseInt(m[1], 10);
|
|
43060
|
+
if (Number.isInteger(n) && n > 0) return n;
|
|
43061
|
+
}
|
|
43062
|
+
}
|
|
43063
|
+
return void 0;
|
|
43064
|
+
}
|
|
43065
|
+
isLossyAsBasic(table) {
|
|
43066
|
+
if (table.footer) return true;
|
|
43067
|
+
if (table.header && table.header.rows.length > 1) return true;
|
|
43068
|
+
const sections = [table.header, table.body, table.footer];
|
|
43069
|
+
for (const section of sections) {
|
|
43070
|
+
if (!section) continue;
|
|
43071
|
+
for (const row of section.rows) {
|
|
43072
|
+
for (const cell of row.cells) {
|
|
43073
|
+
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
43074
|
+
}
|
|
43075
|
+
}
|
|
43076
|
+
}
|
|
43077
|
+
return false;
|
|
43078
|
+
}
|
|
43079
|
+
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
43080
|
+
/**
|
|
43081
|
+
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
43082
|
+
*/
|
|
43083
|
+
blockNodes(nodes) {
|
|
43084
|
+
const blocks = [];
|
|
43085
|
+
let inline = [];
|
|
43086
|
+
const flush = () => {
|
|
43087
|
+
const trimmed = this.trimInline(inline);
|
|
43088
|
+
inline = [];
|
|
43089
|
+
if (trimmed.length === 0) return;
|
|
43090
|
+
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
43091
|
+
blocks.push({ ...trimmed[0], type: "image" });
|
|
43092
|
+
} else {
|
|
43093
|
+
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
43094
|
+
}
|
|
43095
|
+
};
|
|
43096
|
+
for (const node of nodes) {
|
|
43097
|
+
if (!isElement(node)) {
|
|
43098
|
+
inline.push(...this.inlineText(node.value, []));
|
|
43099
|
+
continue;
|
|
43100
|
+
}
|
|
43101
|
+
const name = node.name;
|
|
43102
|
+
if (name === "p") {
|
|
43103
|
+
flush();
|
|
43104
|
+
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
43105
|
+
if (content.length > 0) {
|
|
43106
|
+
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
43107
|
+
}
|
|
43108
|
+
} else if (this.isListTag(name)) {
|
|
43109
|
+
flush();
|
|
43110
|
+
const list = this.listNode(node);
|
|
43111
|
+
if (list) blocks.push(list);
|
|
43112
|
+
} else {
|
|
43113
|
+
inline.push(...this.inlineFromElement(node, []));
|
|
43114
|
+
}
|
|
43115
|
+
}
|
|
43116
|
+
flush();
|
|
43117
|
+
return blocks;
|
|
43118
|
+
}
|
|
43119
|
+
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
43120
|
+
inlineNodes(nodes, marks) {
|
|
43121
|
+
const out = [];
|
|
43122
|
+
for (const node of nodes) {
|
|
43123
|
+
if (!isElement(node)) {
|
|
43124
|
+
out.push(...this.inlineText(node.value, marks));
|
|
43125
|
+
} else {
|
|
43126
|
+
out.push(...this.inlineFromElement(node, marks));
|
|
43127
|
+
}
|
|
43128
|
+
}
|
|
43129
|
+
return out;
|
|
43130
|
+
}
|
|
43131
|
+
inlineFromElement(el, marks) {
|
|
43132
|
+
const name = el.name;
|
|
43133
|
+
if (name === "br") {
|
|
43134
|
+
return [{ type: "hardBreak" }];
|
|
43135
|
+
}
|
|
43136
|
+
if (name === "img") {
|
|
43137
|
+
return [this.imageNode(el, true)];
|
|
43138
|
+
}
|
|
43139
|
+
const markType = MARK_TAGS[name];
|
|
43140
|
+
if (markType) {
|
|
43141
|
+
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
43142
|
+
}
|
|
43143
|
+
if (name === "a") {
|
|
43144
|
+
const linkMark = {
|
|
43145
|
+
type: "link",
|
|
43146
|
+
attrs: {
|
|
43147
|
+
href: el.attrs.href ?? "",
|
|
43148
|
+
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
43149
|
+
}
|
|
43150
|
+
};
|
|
43151
|
+
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
43152
|
+
}
|
|
43153
|
+
if (this.keepUnknownTags) {
|
|
43154
|
+
const open = this.serializeOpenTag(el);
|
|
43155
|
+
const close = `</${name}>`;
|
|
43156
|
+
return [
|
|
43157
|
+
...this.inlineText(open, marks),
|
|
43158
|
+
...this.inlineNodes(el.children, marks),
|
|
43159
|
+
...this.inlineText(close, marks)
|
|
43160
|
+
];
|
|
43161
|
+
}
|
|
43162
|
+
return this.inlineNodes(el.children, marks);
|
|
43163
|
+
}
|
|
43164
|
+
inlineText(raw, marks) {
|
|
43165
|
+
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
43166
|
+
if (text === "") return [];
|
|
43167
|
+
const node = { text, type: "text" };
|
|
43168
|
+
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
43169
|
+
return [node];
|
|
43170
|
+
}
|
|
43171
|
+
serializeOpenTag(el) {
|
|
43172
|
+
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
43173
|
+
return `<${el.name}${attrs}>`;
|
|
43174
|
+
}
|
|
43175
|
+
// --- lists ----------------------------------------------------------------
|
|
43176
|
+
isListTag(name) {
|
|
43177
|
+
return name === "ul" || name === "ol";
|
|
43178
|
+
}
|
|
43179
|
+
listNode(el) {
|
|
43180
|
+
const items = childElements(el, LI_TAGS);
|
|
43181
|
+
if (items.length === 0) return void 0;
|
|
43182
|
+
const isTask = el.name === "ul" && items.some((li) => {
|
|
43183
|
+
const firstEl = li.children.find(isElement);
|
|
43184
|
+
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
43185
|
+
});
|
|
43186
|
+
if (isTask) {
|
|
43187
|
+
return {
|
|
43188
|
+
type: "taskList",
|
|
43189
|
+
content: items.map((li) => this.taskItemNode(li))
|
|
43190
|
+
};
|
|
43191
|
+
}
|
|
43192
|
+
const type = this.listType(el);
|
|
43193
|
+
const node = {
|
|
43194
|
+
type,
|
|
43195
|
+
content: items.map((li) => this.listItemNode(li))
|
|
43196
|
+
};
|
|
43197
|
+
if (el.name === "ol") {
|
|
43198
|
+
const start = intAttr(el.attrs.start);
|
|
43199
|
+
if (start != null) {
|
|
43200
|
+
node.attrs = { start };
|
|
43201
|
+
}
|
|
43202
|
+
}
|
|
43203
|
+
return node;
|
|
43204
|
+
}
|
|
43205
|
+
listType(el) {
|
|
43206
|
+
if (el.name === "ol") {
|
|
43207
|
+
switch (el.attrs.type) {
|
|
43208
|
+
case "i":
|
|
43209
|
+
return "orderedListRomanLower";
|
|
43210
|
+
case "I":
|
|
43211
|
+
return "orderedListRoman";
|
|
43212
|
+
case "a":
|
|
43213
|
+
return "letteredListLower";
|
|
43214
|
+
case "A":
|
|
43215
|
+
return "letteredList";
|
|
43216
|
+
default:
|
|
43217
|
+
return "orderedList";
|
|
43218
|
+
}
|
|
43219
|
+
}
|
|
43220
|
+
const style = el.attrs.style ?? "";
|
|
43221
|
+
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
43222
|
+
return "bulletList";
|
|
43223
|
+
}
|
|
43224
|
+
listItemNode(li) {
|
|
43225
|
+
let content = this.blockNodes(li.children);
|
|
43226
|
+
if (content.length === 0) {
|
|
43227
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43228
|
+
}
|
|
43229
|
+
return { type: "listItem", content };
|
|
43230
|
+
}
|
|
43231
|
+
taskItemNode(li) {
|
|
43232
|
+
const checkbox = li.children.find(
|
|
43233
|
+
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
43234
|
+
);
|
|
43235
|
+
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
43236
|
+
const rest = li.children.filter((c) => c !== checkbox);
|
|
43237
|
+
let content = this.blockNodes(rest);
|
|
43238
|
+
if (content.length === 0) {
|
|
43239
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43240
|
+
}
|
|
43241
|
+
return { type: "taskItem", attrs: { checked }, content };
|
|
43242
|
+
}
|
|
43243
|
+
// --- images ---------------------------------------------------------------
|
|
43244
|
+
imageNode(el, inline) {
|
|
43245
|
+
const attrs = { src: el.attrs.src ?? "" };
|
|
43246
|
+
attrs.alt = el.attrs.alt ?? null;
|
|
43247
|
+
attrs.title = el.attrs.title ?? null;
|
|
43248
|
+
const width = intAttr(el.attrs.width);
|
|
43249
|
+
if (width != null) attrs.width = width;
|
|
43250
|
+
const height = intAttr(el.attrs.height);
|
|
43251
|
+
if (height != null) attrs.height = height;
|
|
43252
|
+
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
43253
|
+
return { type: inline ? "imageInline" : "image", attrs };
|
|
43254
|
+
}
|
|
43255
|
+
// --- whitespace -----------------------------------------------------------
|
|
43256
|
+
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
43257
|
+
trimInline(nodes) {
|
|
43258
|
+
const out = nodes.slice();
|
|
43259
|
+
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
43260
|
+
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
43261
|
+
if (out.length > 0 && out[0].type === "text") {
|
|
43262
|
+
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
43263
|
+
}
|
|
43264
|
+
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
43265
|
+
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
43266
|
+
const last = out.length - 1;
|
|
43267
|
+
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
43268
|
+
}
|
|
43269
|
+
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
43270
|
+
}
|
|
43271
|
+
};
|
|
43272
|
+
|
|
42318
43273
|
// src/BitmarkParserGenerator.ts
|
|
42319
43274
|
import path4 from "path";
|
|
42320
43275
|
import fs4 from "fs-extra";
|
|
@@ -42592,248 +43547,19 @@ var BitmarkFileGenerator = class {
|
|
|
42592
43547
|
*
|
|
42593
43548
|
* @param ast bitmark AST
|
|
42594
43549
|
*/
|
|
42595
|
-
async generate(ast) {
|
|
42596
|
-
return this.generator.generate(ast);
|
|
42597
|
-
}
|
|
42598
|
-
/**
|
|
42599
|
-
* Generate bitmark markup from bitmark AST as a file synchronously
|
|
42600
|
-
*
|
|
42601
|
-
* @param ast bitmark AST
|
|
42602
|
-
*/
|
|
42603
|
-
generateSync(_ast) {
|
|
42604
|
-
if (this.async) {
|
|
42605
|
-
throw new Error("Sync operation not supported");
|
|
42606
|
-
}
|
|
42607
|
-
this.generator.generateSync(_ast);
|
|
42608
|
-
}
|
|
42609
|
-
};
|
|
42610
|
-
|
|
42611
|
-
// src/generator/html/HtmlTableGenerator.ts
|
|
42612
|
-
var MARK_TO_TAG = {
|
|
42613
|
-
bold: "b",
|
|
42614
|
-
italic: "i",
|
|
42615
|
-
superscript: "sup",
|
|
42616
|
-
subscript: "sub",
|
|
42617
|
-
strike: "s",
|
|
42618
|
-
del: "del",
|
|
42619
|
-
ins: "ins",
|
|
42620
|
-
underline: "u",
|
|
42621
|
-
highlight: "mark",
|
|
42622
|
-
code: "code"
|
|
42623
|
-
};
|
|
42624
|
-
var HtmlTableGenerator = class {
|
|
42625
|
-
constructor() {
|
|
42626
|
-
__publicField(this, "indentUnit", " ");
|
|
42627
|
-
}
|
|
42628
|
-
/**
|
|
42629
|
-
* Generate HTML table fragments from a string or JSON value.
|
|
42630
|
-
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
42631
|
-
*/
|
|
42632
|
-
generate(input) {
|
|
42633
|
-
let data = input;
|
|
42634
|
-
if (typeof data === "string") {
|
|
42635
|
-
try {
|
|
42636
|
-
data = JSON.parse(data);
|
|
42637
|
-
} catch {
|
|
42638
|
-
return "";
|
|
42639
|
-
}
|
|
42640
|
-
}
|
|
42641
|
-
const bits = this.collectBits(data);
|
|
42642
|
-
const fragments = [];
|
|
42643
|
-
for (const bit of bits) {
|
|
42644
|
-
const html = this.renderTableBit(bit);
|
|
42645
|
-
if (html) fragments.push(html);
|
|
42646
|
-
}
|
|
42647
|
-
return fragments.join("\n\n");
|
|
42648
|
-
}
|
|
42649
|
-
// --- bit collection -------------------------------------------------------
|
|
42650
|
-
collectBits(data) {
|
|
42651
|
-
const out = [];
|
|
42652
|
-
const visit = (value) => {
|
|
42653
|
-
if (value == null || typeof value !== "object") return;
|
|
42654
|
-
if (Array.isArray(value)) {
|
|
42655
|
-
value.forEach(visit);
|
|
42656
|
-
return;
|
|
42657
|
-
}
|
|
42658
|
-
const obj = value;
|
|
42659
|
-
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
42660
|
-
out.push(obj.bit);
|
|
42661
|
-
} else if ("type" in obj) {
|
|
42662
|
-
out.push(obj);
|
|
42663
|
-
}
|
|
42664
|
-
};
|
|
42665
|
-
visit(data);
|
|
42666
|
-
return out;
|
|
42667
|
-
}
|
|
42668
|
-
// --- table rendering ------------------------------------------------------
|
|
42669
|
-
renderTableBit(bit) {
|
|
42670
|
-
const table = bit.table;
|
|
42671
|
-
if (!table) return "";
|
|
42672
|
-
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
42673
|
-
const extended = this.toExtended(table);
|
|
42674
|
-
const lines = [];
|
|
42675
|
-
lines.push("<table>");
|
|
42676
|
-
if (bit.caption != null) {
|
|
42677
|
-
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
42678
|
-
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
42679
|
-
}
|
|
42680
|
-
this.renderSection(lines, "thead", extended.header, "header");
|
|
42681
|
-
this.renderSection(lines, "tbody", extended.body, "body");
|
|
42682
|
-
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
42683
|
-
lines.push("</table>");
|
|
42684
|
-
return lines.join("\n");
|
|
42685
|
-
}
|
|
42686
|
-
toExtended(table) {
|
|
42687
|
-
const t = table;
|
|
42688
|
-
if (t.header || t.body || t.footer) return table;
|
|
42689
|
-
return convertBasicToExtendedTableFormat(table);
|
|
42690
|
-
}
|
|
42691
|
-
renderSection(lines, tag, section, key) {
|
|
42692
|
-
if (!section || !section.rows || section.rows.length === 0) return;
|
|
42693
|
-
lines.push(`${this.indentUnit}<${tag}>`);
|
|
42694
|
-
for (const row of section.rows) {
|
|
42695
|
-
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
42696
|
-
for (const cell of row.cells ?? []) {
|
|
42697
|
-
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
42698
|
-
}
|
|
42699
|
-
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
42700
|
-
}
|
|
42701
|
-
lines.push(`${this.indentUnit}</${tag}>`);
|
|
42702
|
-
}
|
|
42703
|
-
renderCell(cell, _key) {
|
|
42704
|
-
const tag = cell.title === true ? "th" : "td";
|
|
42705
|
-
const attrs = [];
|
|
42706
|
-
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
42707
|
-
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
42708
|
-
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
42709
|
-
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
42710
|
-
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
42711
|
-
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
42712
|
-
}
|
|
42713
|
-
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
42714
|
-
asTextAst(content) {
|
|
42715
|
-
if (content == null) return [];
|
|
42716
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
42717
|
-
return content;
|
|
42718
|
-
}
|
|
42719
|
-
cellContentToHtml(blocks) {
|
|
42720
|
-
if (blocks.length === 0) return "";
|
|
42721
|
-
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
42722
|
-
return this.inlineToHtml(blocks[0].content ?? []);
|
|
42723
|
-
}
|
|
42724
|
-
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
42725
|
-
}
|
|
42726
|
-
blockToHtml(node) {
|
|
42727
|
-
switch (node.type) {
|
|
42728
|
-
case "paragraph":
|
|
42729
|
-
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
42730
|
-
case "bulletList":
|
|
42731
|
-
case "noBulletList":
|
|
42732
|
-
case "orderedList":
|
|
42733
|
-
case "orderedListRoman":
|
|
42734
|
-
case "orderedListRomanLower":
|
|
42735
|
-
case "letteredList":
|
|
42736
|
-
case "letteredListLower":
|
|
42737
|
-
case "taskList":
|
|
42738
|
-
return this.listToHtml(node);
|
|
42739
|
-
case "image":
|
|
42740
|
-
case "imageInline":
|
|
42741
|
-
return this.imageToHtml(node);
|
|
42742
|
-
default:
|
|
42743
|
-
return this.inlineToHtml([node]);
|
|
42744
|
-
}
|
|
42745
|
-
}
|
|
42746
|
-
inlineToHtml(nodes) {
|
|
42747
|
-
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
42748
|
-
}
|
|
42749
|
-
inlineNodeToHtml(node) {
|
|
42750
|
-
if (node.type === "hardBreak") return "<br>";
|
|
42751
|
-
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
42752
|
-
if (node.type === "text") {
|
|
42753
|
-
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
42754
|
-
}
|
|
42755
|
-
if (node.content) return this.inlineToHtml(node.content);
|
|
42756
|
-
return this.escapeText(node.text ?? "");
|
|
42757
|
-
}
|
|
42758
|
-
wrapMarks(text, marks) {
|
|
42759
|
-
if (!marks || marks.length === 0) return text;
|
|
42760
|
-
let open = "";
|
|
42761
|
-
let close = "";
|
|
42762
|
-
for (const mark of marks) {
|
|
42763
|
-
if (mark.type === "link") {
|
|
42764
|
-
const href = mark.attrs?.href ?? "";
|
|
42765
|
-
open += `<a href="${this.escapeAttr(href)}">`;
|
|
42766
|
-
close = `</a>${close}`;
|
|
42767
|
-
} else {
|
|
42768
|
-
const tag = MARK_TO_TAG[mark.type];
|
|
42769
|
-
if (tag) {
|
|
42770
|
-
open += `<${tag}>`;
|
|
42771
|
-
close = `</${tag}>${close}`;
|
|
42772
|
-
}
|
|
42773
|
-
}
|
|
42774
|
-
}
|
|
42775
|
-
return `${open}${text}${close}`;
|
|
42776
|
-
}
|
|
42777
|
-
// --- lists ----------------------------------------------------------------
|
|
42778
|
-
listToHtml(node) {
|
|
42779
|
-
const { tag, attrs } = this.listTag(node);
|
|
42780
|
-
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
42781
|
-
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
42782
|
-
}
|
|
42783
|
-
listTag(node) {
|
|
42784
|
-
const start = node.attrs?.start;
|
|
42785
|
-
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
42786
|
-
switch (node.type) {
|
|
42787
|
-
case "orderedList":
|
|
42788
|
-
return { tag: "ol", attrs: startAttr };
|
|
42789
|
-
case "orderedListRoman":
|
|
42790
|
-
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
42791
|
-
case "orderedListRomanLower":
|
|
42792
|
-
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
42793
|
-
case "letteredList":
|
|
42794
|
-
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
42795
|
-
case "letteredListLower":
|
|
42796
|
-
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
42797
|
-
case "noBulletList":
|
|
42798
|
-
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
42799
|
-
case "taskList":
|
|
42800
|
-
case "bulletList":
|
|
42801
|
-
default:
|
|
42802
|
-
return { tag: "ul", attrs: "" };
|
|
42803
|
-
}
|
|
42804
|
-
}
|
|
42805
|
-
listItemToHtml(item, task) {
|
|
42806
|
-
const inner = (item.content ?? []).map((b) => {
|
|
42807
|
-
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
42808
|
-
return this.blockToHtml(b);
|
|
42809
|
-
}).join("");
|
|
42810
|
-
if (task) {
|
|
42811
|
-
const checked = item.attrs?.checked ? " checked" : "";
|
|
42812
|
-
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
42813
|
-
}
|
|
42814
|
-
return `<li>${inner}</li>`;
|
|
42815
|
-
}
|
|
42816
|
-
// --- images ---------------------------------------------------------------
|
|
42817
|
-
imageToHtml(node) {
|
|
42818
|
-
const attrs = node.attrs ?? {};
|
|
42819
|
-
const parts = [];
|
|
42820
|
-
const src = attrs.src;
|
|
42821
|
-
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
42822
|
-
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
42823
|
-
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
42824
|
-
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
42825
|
-
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
42826
|
-
if (typeof attrs.class === "string" && attrs.class) {
|
|
42827
|
-
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
42828
|
-
}
|
|
42829
|
-
return `<img ${parts.join(" ")}>`;
|
|
42830
|
-
}
|
|
42831
|
-
// --- escaping -------------------------------------------------------------
|
|
42832
|
-
escapeText(text) {
|
|
42833
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
43550
|
+
async generate(ast) {
|
|
43551
|
+
return this.generator.generate(ast);
|
|
42834
43552
|
}
|
|
42835
|
-
|
|
42836
|
-
|
|
43553
|
+
/**
|
|
43554
|
+
* Generate bitmark markup from bitmark AST as a file synchronously
|
|
43555
|
+
*
|
|
43556
|
+
* @param ast bitmark AST
|
|
43557
|
+
*/
|
|
43558
|
+
generateSync(_ast) {
|
|
43559
|
+
if (this.async) {
|
|
43560
|
+
throw new Error("Sync operation not supported");
|
|
43561
|
+
}
|
|
43562
|
+
this.generator.generateSync(_ast);
|
|
42837
43563
|
}
|
|
42838
43564
|
};
|
|
42839
43565
|
|
|
@@ -43260,6 +43986,7 @@ var ConfigBuilder = class {
|
|
|
43260
43986
|
k = stringUtils.camelToKebab(k);
|
|
43261
43987
|
const resolvedGroups = resolveGroupReferences(k);
|
|
43262
43988
|
const hasOuterExport = Object.prototype.hasOwnProperty.call(tag, "exportJsonKey");
|
|
43989
|
+
const hasOuterHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
43263
43990
|
if (!hasOuterExport && tag.jsonKey != null) {
|
|
43264
43991
|
const headingPath = [...pathStack, `tags.${tag.key}`].join(" / ");
|
|
43265
43992
|
exportJsonKeyErrors.push(
|
|
@@ -43269,6 +43996,8 @@ var ConfigBuilder = class {
|
|
|
43269
43996
|
for (const ref of resolvedGroups) {
|
|
43270
43997
|
const exportJsonKeyChosen = hasOuterExport ? tag.exportJsonKey : ref.exportJsonKey;
|
|
43271
43998
|
const hasExportChosen = hasOuterExport || !!ref.hasExportJsonKey;
|
|
43999
|
+
const htmlKeyChosen = hasOuterHtml ? tag.htmlKey : ref.htmlKey;
|
|
44000
|
+
const hasHtmlChosen = hasOuterHtml || !!ref.hasHtmlKey;
|
|
43272
44001
|
const min = tag.minCount != null ? tag.minCount : ref.min;
|
|
43273
44002
|
const max = tag.maxCount != null ? tag.maxCount : ref.max;
|
|
43274
44003
|
const description = tag.description ? tag.description : ref.description;
|
|
@@ -43276,6 +44005,7 @@ var ConfigBuilder = class {
|
|
|
43276
44005
|
type: "group",
|
|
43277
44006
|
key: ref.key,
|
|
43278
44007
|
...hasExportChosen ? { jsonKey: exportJsonKeyChosen } : {},
|
|
44008
|
+
...hasHtmlChosen ? { htmlKey: htmlKeyChosen } : {},
|
|
43279
44009
|
...min != null ? { min } : {},
|
|
43280
44010
|
...max != null ? { max } : {},
|
|
43281
44011
|
...description ? { description } : {}
|
|
@@ -43304,10 +44034,13 @@ var ConfigBuilder = class {
|
|
|
43304
44034
|
);
|
|
43305
44035
|
exportJsonKeyField = {};
|
|
43306
44036
|
}
|
|
44037
|
+
const hasHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
44038
|
+
const htmlKeyField = hasHtml ? { htmlKey: tag.htmlKey } : {};
|
|
43307
44039
|
const t = {
|
|
43308
44040
|
type: "tag",
|
|
43309
44041
|
key: tagName,
|
|
43310
44042
|
...exportJsonKeyField,
|
|
44043
|
+
...htmlKeyField,
|
|
43311
44044
|
format,
|
|
43312
44045
|
default: tag.defaultValue ?? null,
|
|
43313
44046
|
...tag.nullable ? { nullable: true } : {},
|
|
@@ -43330,6 +44063,13 @@ var ConfigBuilder = class {
|
|
|
43330
44063
|
);
|
|
43331
44064
|
return {};
|
|
43332
44065
|
};
|
|
44066
|
+
const cardHtmlKeyField = (container, htmlExportKey) => {
|
|
44067
|
+
const c = container;
|
|
44068
|
+
if (Object.prototype.hasOwnProperty.call(c, htmlExportKey)) {
|
|
44069
|
+
return { htmlKey: c[htmlExportKey] };
|
|
44070
|
+
}
|
|
44071
|
+
return {};
|
|
44072
|
+
};
|
|
43333
44073
|
const serializeCardSet = (cardSetKey) => {
|
|
43334
44074
|
const variantBodyFormat = (variant) => variant.format ?? TextFormat.bitmarkText;
|
|
43335
44075
|
const cardSetConfig = CARDSETS[cardSetKey];
|
|
@@ -43360,6 +44100,7 @@ var ConfigBuilder = class {
|
|
|
43360
44100
|
}
|
|
43361
44101
|
return {
|
|
43362
44102
|
...cardJsonKeyField(variant, "jsonKey", "exportJsonKey", variantPath),
|
|
44103
|
+
...cardHtmlKeyField(variant, "htmlKey"),
|
|
43363
44104
|
format: variantBodyFormat(variant),
|
|
43364
44105
|
tags: variantTags,
|
|
43365
44106
|
repeatCount: variant.repeatCount ?? 1,
|
|
@@ -43371,6 +44112,7 @@ var ConfigBuilder = class {
|
|
|
43371
44112
|
name: side.name,
|
|
43372
44113
|
...side.repeat ? { repeat: side.repeat } : {},
|
|
43373
44114
|
...cardJsonKeyField(side, "jsonKey", "exportJsonKey", sidePath),
|
|
44115
|
+
...cardHtmlKeyField(side, "htmlKey"),
|
|
43374
44116
|
variants
|
|
43375
44117
|
};
|
|
43376
44118
|
});
|
|
@@ -43378,20 +44120,23 @@ var ConfigBuilder = class {
|
|
|
43378
44120
|
const cards = Object.entries(cardSetConfig.sections).map(([sectionName, section]) => {
|
|
43379
44121
|
const sectionPath = `cardSets.${normalizedKey} / cards.${sectionName}`;
|
|
43380
44122
|
const hasSideExport = Object.prototype.hasOwnProperty.call(section, "sideExportJsonKey");
|
|
44123
|
+
const hasSideHtml = Object.prototype.hasOwnProperty.call(section, "sideHtmlKey");
|
|
43381
44124
|
let cardSides = sides;
|
|
43382
|
-
if (hasSideExport || section.sideJsonKey != null) {
|
|
44125
|
+
if (hasSideExport || section.sideJsonKey != null || hasSideHtml) {
|
|
43383
44126
|
const sideOverride = cardJsonKeyField(
|
|
43384
44127
|
section,
|
|
43385
44128
|
"sideJsonKey",
|
|
43386
44129
|
"sideExportJsonKey",
|
|
43387
44130
|
`${sectionPath} / sides.*`
|
|
43388
44131
|
);
|
|
43389
|
-
|
|
44132
|
+
const sideHtmlOverride = cardHtmlKeyField(section, "sideHtmlKey");
|
|
44133
|
+
cardSides = sides.map((s) => ({ ...s, ...sideOverride, ...sideHtmlOverride }));
|
|
43390
44134
|
}
|
|
43391
44135
|
return {
|
|
43392
44136
|
name: sectionName,
|
|
43393
44137
|
...section.isDefault ? { isDefault: true } : {},
|
|
43394
44138
|
...cardJsonKeyField(section, "jsonKey", "exportJsonKey", sectionPath),
|
|
44139
|
+
...cardHtmlKeyField(section, "htmlKey"),
|
|
43395
44140
|
// PLAN-085: per-section cardinality. Emit only when non-default
|
|
43396
44141
|
// (treat `0` / undefined as "unbounded — omit").
|
|
43397
44142
|
...section.minCount != null && section.minCount !== 0 ? { min: section.minCount } : {},
|
|
@@ -43399,7 +44144,7 @@ var ConfigBuilder = class {
|
|
|
43399
44144
|
sides: cardSides
|
|
43400
44145
|
};
|
|
43401
44146
|
});
|
|
43402
|
-
return { name: normalizedKey, cards };
|
|
44147
|
+
return { name: normalizedKey, ...cardHtmlKeyField(cardSetConfig, "htmlKey"), cards };
|
|
43403
44148
|
}
|
|
43404
44149
|
const cardSetPath = `cardSets.${normalizedKey} / cards.default`;
|
|
43405
44150
|
return {
|
|
@@ -43409,6 +44154,7 @@ var ConfigBuilder = class {
|
|
|
43409
44154
|
name: "default",
|
|
43410
44155
|
isDefault: true,
|
|
43411
44156
|
...cardJsonKeyField(cardSetConfig, "jsonKey", "exportJsonKey", cardSetPath),
|
|
44157
|
+
...cardHtmlKeyField(cardSetConfig, "htmlKey"),
|
|
43412
44158
|
sides
|
|
43413
44159
|
}
|
|
43414
44160
|
]
|
|
@@ -43448,6 +44194,10 @@ var ConfigBuilder = class {
|
|
|
43448
44194
|
ref.exportJsonKey = t.jsonKey;
|
|
43449
44195
|
ref.hasExportJsonKey = true;
|
|
43450
44196
|
}
|
|
44197
|
+
if (Object.prototype.hasOwnProperty.call(t, "htmlKey")) {
|
|
44198
|
+
ref.htmlKey = t.htmlKey;
|
|
44199
|
+
ref.hasHtmlKey = true;
|
|
44200
|
+
}
|
|
43451
44201
|
replacements.push(ref);
|
|
43452
44202
|
}
|
|
43453
44203
|
squashedGroups.set(groupKey, replacements);
|
|
@@ -43482,6 +44232,7 @@ var ConfigBuilder = class {
|
|
|
43482
44232
|
type: "group",
|
|
43483
44233
|
key: ref.key,
|
|
43484
44234
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44235
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43485
44236
|
...ref.min != null ? { min: ref.min } : {},
|
|
43486
44237
|
...ref.max != null ? { max: ref.max } : {},
|
|
43487
44238
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43495,6 +44246,7 @@ var ConfigBuilder = class {
|
|
|
43495
44246
|
type: "group",
|
|
43496
44247
|
key: ref.key,
|
|
43497
44248
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44249
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43498
44250
|
...ref.min != null ? { min: ref.min } : {},
|
|
43499
44251
|
...ref.max != null ? { max: ref.max } : {},
|
|
43500
44252
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43624,6 +44376,7 @@ var ConfigBuilder = class {
|
|
|
43624
44376
|
type: "group",
|
|
43625
44377
|
key: ref.key,
|
|
43626
44378
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44379
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43627
44380
|
...ref.min != null ? { min: ref.min } : {},
|
|
43628
44381
|
...ref.max != null ? { max: ref.max } : {},
|
|
43629
44382
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43813,499 +44566,6 @@ var ConfigBuilder = class {
|
|
|
43813
44566
|
}
|
|
43814
44567
|
};
|
|
43815
44568
|
|
|
43816
|
-
// src/parser/html/HtmlDom.ts
|
|
43817
|
-
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
43818
|
-
"area",
|
|
43819
|
-
"base",
|
|
43820
|
-
"br",
|
|
43821
|
-
"col",
|
|
43822
|
-
"embed",
|
|
43823
|
-
"hr",
|
|
43824
|
-
"img",
|
|
43825
|
-
"input",
|
|
43826
|
-
"link",
|
|
43827
|
-
"meta",
|
|
43828
|
-
"param",
|
|
43829
|
-
"source",
|
|
43830
|
-
"track",
|
|
43831
|
-
"wbr"
|
|
43832
|
-
]);
|
|
43833
|
-
var IMPLIED_CLOSE = {
|
|
43834
|
-
li: /* @__PURE__ */ new Set(["li"]),
|
|
43835
|
-
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43836
|
-
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43837
|
-
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
43838
|
-
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43839
|
-
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43840
|
-
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43841
|
-
p: /* @__PURE__ */ new Set(["p"]),
|
|
43842
|
-
option: /* @__PURE__ */ new Set(["option"])
|
|
43843
|
-
};
|
|
43844
|
-
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
43845
|
-
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
43846
|
-
function parseAttrs(raw) {
|
|
43847
|
-
const attrs = {};
|
|
43848
|
-
if (!raw) return attrs;
|
|
43849
|
-
ATTR_RE.lastIndex = 0;
|
|
43850
|
-
let m;
|
|
43851
|
-
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
43852
|
-
const name = m[1].toLowerCase();
|
|
43853
|
-
let value = m[2] ?? "";
|
|
43854
|
-
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
43855
|
-
value = value.slice(1, -1);
|
|
43856
|
-
}
|
|
43857
|
-
attrs[name] = value;
|
|
43858
|
-
}
|
|
43859
|
-
return attrs;
|
|
43860
|
-
}
|
|
43861
|
-
function stripNonContent(html) {
|
|
43862
|
-
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, "");
|
|
43863
|
-
}
|
|
43864
|
-
function tokenize(html) {
|
|
43865
|
-
const tokens = [];
|
|
43866
|
-
const clean = stripNonContent(html);
|
|
43867
|
-
TAG_RE.lastIndex = 0;
|
|
43868
|
-
let lastIndex = 0;
|
|
43869
|
-
let m;
|
|
43870
|
-
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
43871
|
-
if (m.index > lastIndex) {
|
|
43872
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
43873
|
-
}
|
|
43874
|
-
lastIndex = TAG_RE.lastIndex;
|
|
43875
|
-
const isClose = m[1] === "/";
|
|
43876
|
-
const name = m[2].toLowerCase();
|
|
43877
|
-
if (isClose) {
|
|
43878
|
-
tokens.push({ kind: "close", name });
|
|
43879
|
-
} else {
|
|
43880
|
-
tokens.push({
|
|
43881
|
-
kind: "open",
|
|
43882
|
-
name,
|
|
43883
|
-
attrs: parseAttrs(m[3]),
|
|
43884
|
-
selfClose: m[4] === "/"
|
|
43885
|
-
});
|
|
43886
|
-
}
|
|
43887
|
-
}
|
|
43888
|
-
if (lastIndex < clean.length) {
|
|
43889
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
43890
|
-
}
|
|
43891
|
-
return tokens;
|
|
43892
|
-
}
|
|
43893
|
-
function parseHtml(html) {
|
|
43894
|
-
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
43895
|
-
const stack = [root];
|
|
43896
|
-
const top = () => stack[stack.length - 1];
|
|
43897
|
-
for (const token of tokenize(html)) {
|
|
43898
|
-
if (token.kind === "text") {
|
|
43899
|
-
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
43900
|
-
continue;
|
|
43901
|
-
}
|
|
43902
|
-
if (token.kind === "open") {
|
|
43903
|
-
const name = token.name;
|
|
43904
|
-
const closes = IMPLIED_CLOSE[name];
|
|
43905
|
-
if (closes) {
|
|
43906
|
-
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
43907
|
-
}
|
|
43908
|
-
const el = {
|
|
43909
|
-
type: "element",
|
|
43910
|
-
name,
|
|
43911
|
-
attrs: token.attrs ?? {},
|
|
43912
|
-
children: []
|
|
43913
|
-
};
|
|
43914
|
-
top().children.push(el);
|
|
43915
|
-
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
43916
|
-
stack.push(el);
|
|
43917
|
-
}
|
|
43918
|
-
continue;
|
|
43919
|
-
}
|
|
43920
|
-
for (let i = stack.length - 1; i > 0; i--) {
|
|
43921
|
-
if (stack[i].name === token.name) {
|
|
43922
|
-
stack.length = i;
|
|
43923
|
-
break;
|
|
43924
|
-
}
|
|
43925
|
-
}
|
|
43926
|
-
}
|
|
43927
|
-
return root.children;
|
|
43928
|
-
}
|
|
43929
|
-
function childElements(el, names) {
|
|
43930
|
-
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43931
|
-
}
|
|
43932
|
-
|
|
43933
|
-
// src/parser/html/HtmlTableParser.ts
|
|
43934
|
-
var MARK_TAGS = {
|
|
43935
|
-
b: "bold",
|
|
43936
|
-
strong: "bold",
|
|
43937
|
-
i: "italic",
|
|
43938
|
-
em: "italic",
|
|
43939
|
-
sup: "superscript",
|
|
43940
|
-
sub: "subscript",
|
|
43941
|
-
s: "strike",
|
|
43942
|
-
strike: "strike",
|
|
43943
|
-
del: "del",
|
|
43944
|
-
ins: "ins",
|
|
43945
|
-
u: "underline",
|
|
43946
|
-
mark: "highlight",
|
|
43947
|
-
code: "code"
|
|
43948
|
-
};
|
|
43949
|
-
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
43950
|
-
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
43951
|
-
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
43952
|
-
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
43953
|
-
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
43954
|
-
var NAMED_ENTITIES = {
|
|
43955
|
-
amp: "&",
|
|
43956
|
-
lt: "<",
|
|
43957
|
-
gt: ">",
|
|
43958
|
-
quot: '"',
|
|
43959
|
-
apos: "'",
|
|
43960
|
-
nbsp: "\xA0"
|
|
43961
|
-
};
|
|
43962
|
-
function decodeEntities(text) {
|
|
43963
|
-
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
43964
|
-
if (body[0] === "#") {
|
|
43965
|
-
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
43966
|
-
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
43967
|
-
try {
|
|
43968
|
-
return String.fromCodePoint(code);
|
|
43969
|
-
} catch {
|
|
43970
|
-
return whole;
|
|
43971
|
-
}
|
|
43972
|
-
}
|
|
43973
|
-
return whole;
|
|
43974
|
-
}
|
|
43975
|
-
return NAMED_ENTITIES[body] ?? whole;
|
|
43976
|
-
});
|
|
43977
|
-
}
|
|
43978
|
-
function intAttr(value) {
|
|
43979
|
-
if (value == null) return void 0;
|
|
43980
|
-
const n = Number.parseInt(value, 10);
|
|
43981
|
-
return Number.isInteger(n) ? n : void 0;
|
|
43982
|
-
}
|
|
43983
|
-
function isElement(node) {
|
|
43984
|
-
return node.type === "element";
|
|
43985
|
-
}
|
|
43986
|
-
var HtmlTableParser = class {
|
|
43987
|
-
constructor() {
|
|
43988
|
-
__publicField(this, "keepUnknownTags", false);
|
|
43989
|
-
}
|
|
43990
|
-
/**
|
|
43991
|
-
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
43992
|
-
*/
|
|
43993
|
-
parse(html, options) {
|
|
43994
|
-
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
43995
|
-
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
43996
|
-
const onWarning = options?.onWarning;
|
|
43997
|
-
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
43998
|
-
const bits = [];
|
|
43999
|
-
for (const table of tables) {
|
|
44000
|
-
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
44001
|
-
if (bit) bits.push(bit);
|
|
44002
|
-
}
|
|
44003
|
-
return bits;
|
|
44004
|
-
}
|
|
44005
|
-
// --- table extraction -----------------------------------------------------
|
|
44006
|
-
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
44007
|
-
collectTopLevelTables(nodes) {
|
|
44008
|
-
const tables = [];
|
|
44009
|
-
const visit = (node) => {
|
|
44010
|
-
if (!isElement(node)) return;
|
|
44011
|
-
if (node.name === "table") {
|
|
44012
|
-
tables.push(node);
|
|
44013
|
-
return;
|
|
44014
|
-
}
|
|
44015
|
-
node.children.forEach(visit);
|
|
44016
|
-
};
|
|
44017
|
-
nodes.forEach(visit);
|
|
44018
|
-
return tables;
|
|
44019
|
-
}
|
|
44020
|
-
tableToBit(table, tableFormat, onWarning) {
|
|
44021
|
-
const header = [];
|
|
44022
|
-
const body = [];
|
|
44023
|
-
const footer = [];
|
|
44024
|
-
let caption;
|
|
44025
|
-
for (const child of table.children) {
|
|
44026
|
-
if (!isElement(child)) continue;
|
|
44027
|
-
if (child.name === "caption") {
|
|
44028
|
-
const capContent = this.inlineNodes(child.children, []);
|
|
44029
|
-
const trimmed = this.trimInline(capContent);
|
|
44030
|
-
if (trimmed.length > 0) caption = trimmed;
|
|
44031
|
-
} else if (SECTION_TAGS.has(child.name)) {
|
|
44032
|
-
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
44033
|
-
for (const tr of childElements(child, ROW_TAGS)) {
|
|
44034
|
-
target.push(this.rowToCells(tr));
|
|
44035
|
-
}
|
|
44036
|
-
} else if (ROW_TAGS.has(child.name)) {
|
|
44037
|
-
body.push(this.rowToCells(child));
|
|
44038
|
-
}
|
|
44039
|
-
}
|
|
44040
|
-
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
44041
|
-
return void 0;
|
|
44042
|
-
}
|
|
44043
|
-
const tableExtended = {};
|
|
44044
|
-
if (header.length > 0) tableExtended.header = { rows: header };
|
|
44045
|
-
if (body.length > 0) tableExtended.body = { rows: body };
|
|
44046
|
-
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
44047
|
-
let tableData = tableExtended;
|
|
44048
|
-
if (tableFormat === "table") {
|
|
44049
|
-
if (this.isLossyAsBasic(tableExtended)) {
|
|
44050
|
-
onWarning?.(
|
|
44051
|
-
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
44052
|
-
);
|
|
44053
|
-
}
|
|
44054
|
-
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
44055
|
-
}
|
|
44056
|
-
const bit = {
|
|
44057
|
-
type: tableFormat,
|
|
44058
|
-
format: "bitmark++",
|
|
44059
|
-
table: tableData
|
|
44060
|
-
};
|
|
44061
|
-
if (caption) bit.caption = caption;
|
|
44062
|
-
return bit;
|
|
44063
|
-
}
|
|
44064
|
-
rowToCells(tr) {
|
|
44065
|
-
const cells = [];
|
|
44066
|
-
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
44067
|
-
cells.push(this.cellToJson(cell));
|
|
44068
|
-
}
|
|
44069
|
-
return { cells };
|
|
44070
|
-
}
|
|
44071
|
-
cellToJson(cell) {
|
|
44072
|
-
const json = {
|
|
44073
|
-
content: this.blockNodes(cell.children)
|
|
44074
|
-
};
|
|
44075
|
-
if (cell.name === "th") json.title = true;
|
|
44076
|
-
const rowspan = intAttr(cell.attrs.rowspan);
|
|
44077
|
-
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
44078
|
-
const colspan = intAttr(cell.attrs.colspan);
|
|
44079
|
-
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
44080
|
-
const scope = cell.attrs.scope?.toLowerCase();
|
|
44081
|
-
if (scope && VALID_SCOPES.has(scope)) {
|
|
44082
|
-
json.scope = scope;
|
|
44083
|
-
}
|
|
44084
|
-
const width = this.widthFromCell(cell);
|
|
44085
|
-
if (width != null) json.colwidth = width;
|
|
44086
|
-
return json;
|
|
44087
|
-
}
|
|
44088
|
-
widthFromCell(cell) {
|
|
44089
|
-
const attrWidth = intAttr(cell.attrs.width);
|
|
44090
|
-
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
44091
|
-
const style = cell.attrs.style;
|
|
44092
|
-
if (style) {
|
|
44093
|
-
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
44094
|
-
if (m) {
|
|
44095
|
-
const n = Number.parseInt(m[1], 10);
|
|
44096
|
-
if (Number.isInteger(n) && n > 0) return n;
|
|
44097
|
-
}
|
|
44098
|
-
}
|
|
44099
|
-
return void 0;
|
|
44100
|
-
}
|
|
44101
|
-
isLossyAsBasic(table) {
|
|
44102
|
-
if (table.footer) return true;
|
|
44103
|
-
if (table.header && table.header.rows.length > 1) return true;
|
|
44104
|
-
const sections = [table.header, table.body, table.footer];
|
|
44105
|
-
for (const section of sections) {
|
|
44106
|
-
if (!section) continue;
|
|
44107
|
-
for (const row of section.rows) {
|
|
44108
|
-
for (const cell of row.cells) {
|
|
44109
|
-
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
44110
|
-
}
|
|
44111
|
-
}
|
|
44112
|
-
}
|
|
44113
|
-
return false;
|
|
44114
|
-
}
|
|
44115
|
-
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
44116
|
-
/**
|
|
44117
|
-
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
44118
|
-
*/
|
|
44119
|
-
blockNodes(nodes) {
|
|
44120
|
-
const blocks = [];
|
|
44121
|
-
let inline = [];
|
|
44122
|
-
const flush = () => {
|
|
44123
|
-
const trimmed = this.trimInline(inline);
|
|
44124
|
-
inline = [];
|
|
44125
|
-
if (trimmed.length === 0) return;
|
|
44126
|
-
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
44127
|
-
blocks.push({ ...trimmed[0], type: "image" });
|
|
44128
|
-
} else {
|
|
44129
|
-
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
44130
|
-
}
|
|
44131
|
-
};
|
|
44132
|
-
for (const node of nodes) {
|
|
44133
|
-
if (!isElement(node)) {
|
|
44134
|
-
inline.push(...this.inlineText(node.value, []));
|
|
44135
|
-
continue;
|
|
44136
|
-
}
|
|
44137
|
-
const name = node.name;
|
|
44138
|
-
if (name === "p") {
|
|
44139
|
-
flush();
|
|
44140
|
-
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
44141
|
-
if (content.length > 0) {
|
|
44142
|
-
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
44143
|
-
}
|
|
44144
|
-
} else if (this.isListTag(name)) {
|
|
44145
|
-
flush();
|
|
44146
|
-
const list = this.listNode(node);
|
|
44147
|
-
if (list) blocks.push(list);
|
|
44148
|
-
} else {
|
|
44149
|
-
inline.push(...this.inlineFromElement(node, []));
|
|
44150
|
-
}
|
|
44151
|
-
}
|
|
44152
|
-
flush();
|
|
44153
|
-
return blocks;
|
|
44154
|
-
}
|
|
44155
|
-
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
44156
|
-
inlineNodes(nodes, marks) {
|
|
44157
|
-
const out = [];
|
|
44158
|
-
for (const node of nodes) {
|
|
44159
|
-
if (!isElement(node)) {
|
|
44160
|
-
out.push(...this.inlineText(node.value, marks));
|
|
44161
|
-
} else {
|
|
44162
|
-
out.push(...this.inlineFromElement(node, marks));
|
|
44163
|
-
}
|
|
44164
|
-
}
|
|
44165
|
-
return out;
|
|
44166
|
-
}
|
|
44167
|
-
inlineFromElement(el, marks) {
|
|
44168
|
-
const name = el.name;
|
|
44169
|
-
if (name === "br") {
|
|
44170
|
-
return [{ type: "hardBreak" }];
|
|
44171
|
-
}
|
|
44172
|
-
if (name === "img") {
|
|
44173
|
-
return [this.imageNode(el, true)];
|
|
44174
|
-
}
|
|
44175
|
-
const markType = MARK_TAGS[name];
|
|
44176
|
-
if (markType) {
|
|
44177
|
-
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
44178
|
-
}
|
|
44179
|
-
if (name === "a") {
|
|
44180
|
-
const linkMark = {
|
|
44181
|
-
type: "link",
|
|
44182
|
-
attrs: {
|
|
44183
|
-
href: el.attrs.href ?? "",
|
|
44184
|
-
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
44185
|
-
}
|
|
44186
|
-
};
|
|
44187
|
-
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
44188
|
-
}
|
|
44189
|
-
if (this.keepUnknownTags) {
|
|
44190
|
-
const open = this.serializeOpenTag(el);
|
|
44191
|
-
const close = `</${name}>`;
|
|
44192
|
-
return [
|
|
44193
|
-
...this.inlineText(open, marks),
|
|
44194
|
-
...this.inlineNodes(el.children, marks),
|
|
44195
|
-
...this.inlineText(close, marks)
|
|
44196
|
-
];
|
|
44197
|
-
}
|
|
44198
|
-
return this.inlineNodes(el.children, marks);
|
|
44199
|
-
}
|
|
44200
|
-
inlineText(raw, marks) {
|
|
44201
|
-
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
44202
|
-
if (text === "") return [];
|
|
44203
|
-
const node = { text, type: "text" };
|
|
44204
|
-
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
44205
|
-
return [node];
|
|
44206
|
-
}
|
|
44207
|
-
serializeOpenTag(el) {
|
|
44208
|
-
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
44209
|
-
return `<${el.name}${attrs}>`;
|
|
44210
|
-
}
|
|
44211
|
-
// --- lists ----------------------------------------------------------------
|
|
44212
|
-
isListTag(name) {
|
|
44213
|
-
return name === "ul" || name === "ol";
|
|
44214
|
-
}
|
|
44215
|
-
listNode(el) {
|
|
44216
|
-
const items = childElements(el, LI_TAGS);
|
|
44217
|
-
if (items.length === 0) return void 0;
|
|
44218
|
-
const isTask = el.name === "ul" && items.some((li) => {
|
|
44219
|
-
const firstEl = li.children.find(isElement);
|
|
44220
|
-
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
44221
|
-
});
|
|
44222
|
-
if (isTask) {
|
|
44223
|
-
return {
|
|
44224
|
-
type: "taskList",
|
|
44225
|
-
content: items.map((li) => this.taskItemNode(li))
|
|
44226
|
-
};
|
|
44227
|
-
}
|
|
44228
|
-
const type = this.listType(el);
|
|
44229
|
-
const node = {
|
|
44230
|
-
type,
|
|
44231
|
-
content: items.map((li) => this.listItemNode(li))
|
|
44232
|
-
};
|
|
44233
|
-
if (el.name === "ol") {
|
|
44234
|
-
const start = intAttr(el.attrs.start);
|
|
44235
|
-
if (start != null) {
|
|
44236
|
-
node.attrs = { start };
|
|
44237
|
-
}
|
|
44238
|
-
}
|
|
44239
|
-
return node;
|
|
44240
|
-
}
|
|
44241
|
-
listType(el) {
|
|
44242
|
-
if (el.name === "ol") {
|
|
44243
|
-
switch (el.attrs.type) {
|
|
44244
|
-
case "i":
|
|
44245
|
-
return "orderedListRomanLower";
|
|
44246
|
-
case "I":
|
|
44247
|
-
return "orderedListRoman";
|
|
44248
|
-
case "a":
|
|
44249
|
-
return "letteredListLower";
|
|
44250
|
-
case "A":
|
|
44251
|
-
return "letteredList";
|
|
44252
|
-
default:
|
|
44253
|
-
return "orderedList";
|
|
44254
|
-
}
|
|
44255
|
-
}
|
|
44256
|
-
const style = el.attrs.style ?? "";
|
|
44257
|
-
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
44258
|
-
return "bulletList";
|
|
44259
|
-
}
|
|
44260
|
-
listItemNode(li) {
|
|
44261
|
-
let content = this.blockNodes(li.children);
|
|
44262
|
-
if (content.length === 0) {
|
|
44263
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
44264
|
-
}
|
|
44265
|
-
return { type: "listItem", content };
|
|
44266
|
-
}
|
|
44267
|
-
taskItemNode(li) {
|
|
44268
|
-
const checkbox = li.children.find(
|
|
44269
|
-
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
44270
|
-
);
|
|
44271
|
-
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
44272
|
-
const rest = li.children.filter((c) => c !== checkbox);
|
|
44273
|
-
let content = this.blockNodes(rest);
|
|
44274
|
-
if (content.length === 0) {
|
|
44275
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
44276
|
-
}
|
|
44277
|
-
return { type: "taskItem", attrs: { checked }, content };
|
|
44278
|
-
}
|
|
44279
|
-
// --- images ---------------------------------------------------------------
|
|
44280
|
-
imageNode(el, inline) {
|
|
44281
|
-
const attrs = { src: el.attrs.src ?? "" };
|
|
44282
|
-
attrs.alt = el.attrs.alt ?? null;
|
|
44283
|
-
attrs.title = el.attrs.title ?? null;
|
|
44284
|
-
const width = intAttr(el.attrs.width);
|
|
44285
|
-
if (width != null) attrs.width = width;
|
|
44286
|
-
const height = intAttr(el.attrs.height);
|
|
44287
|
-
if (height != null) attrs.height = height;
|
|
44288
|
-
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
44289
|
-
return { type: inline ? "imageInline" : "image", attrs };
|
|
44290
|
-
}
|
|
44291
|
-
// --- whitespace -----------------------------------------------------------
|
|
44292
|
-
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
44293
|
-
trimInline(nodes) {
|
|
44294
|
-
const out = nodes.slice();
|
|
44295
|
-
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
44296
|
-
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
44297
|
-
if (out.length > 0 && out[0].type === "text") {
|
|
44298
|
-
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
44299
|
-
}
|
|
44300
|
-
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
44301
|
-
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
44302
|
-
const last = out.length - 1;
|
|
44303
|
-
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
44304
|
-
}
|
|
44305
|
-
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
44306
|
-
}
|
|
44307
|
-
};
|
|
44308
|
-
|
|
44309
44569
|
// src/BitmarkParserGenerator.ts
|
|
44310
44570
|
var Input = {
|
|
44311
44571
|
/**
|