@gmb/bitmark-parser-generator 5.25.0 → 5.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 -738
- 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 -738
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/cli/main.js +1014 -749
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +1016 -751
- 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 -751
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -610,6 +610,14 @@ var BitType = {
|
|
|
610
610
|
smartStandardRemarkNonNormativeCollapsible: "smart-standard-remark-non-normative-collapsible",
|
|
611
611
|
smartStandardRemarkNormative: "smart-standard-remark-normative",
|
|
612
612
|
smartStandardRemarkNormativeCollapsible: "smart-standard-remark-normative-collapsible",
|
|
613
|
+
smartStandardRemarkTableExtendedImageNonNormative: "smart-standard-remark-table-extended-image-non-normative",
|
|
614
|
+
smartStandardRemarkTableExtendedImageNonNormativeCollapsible: "smart-standard-remark-table-extended-image-non-normative-collapsible",
|
|
615
|
+
smartStandardRemarkTableExtendedImageNormative: "smart-standard-remark-table-extended-image-normative",
|
|
616
|
+
smartStandardRemarkTableExtendedImageNormativeCollapsible: "smart-standard-remark-table-extended-image-normative-collapsible",
|
|
617
|
+
smartStandardRemarkTableExtendedNonNormative: "smart-standard-remark-table-extended-non-normative",
|
|
618
|
+
smartStandardRemarkTableExtendedNonNormativeCollapsible: "smart-standard-remark-table-extended-non-normative-collapsible",
|
|
619
|
+
smartStandardRemarkTableExtendedNormative: "smart-standard-remark-table-extended-normative",
|
|
620
|
+
smartStandardRemarkTableExtendedNormativeCollapsible: "smart-standard-remark-table-extended-normative-collapsible",
|
|
613
621
|
smartStandardRemarkTableImageNonNormative: "smart-standard-remark-table-image-non-normative",
|
|
614
622
|
smartStandardRemarkTableImageNonNormativeCollapsible: "smart-standard-remark-table-image-non-normative-collapsible",
|
|
615
623
|
smartStandardRemarkTableImageNormative: "smart-standard-remark-table-image-normative",
|
|
@@ -618,6 +626,14 @@ var BitType = {
|
|
|
618
626
|
smartStandardRemarkTableNonNormativeCollapsible: "smart-standard-remark-table-non-normative-collapsible",
|
|
619
627
|
smartStandardRemarkTableNormative: "smart-standard-remark-table-normative",
|
|
620
628
|
smartStandardRemarkTableNormativeCollapsible: "smart-standard-remark-table-normative-collapsible",
|
|
629
|
+
smartStandardTableExtendedImageNonNormative: "smart-standard-table-extended-image-non-normative",
|
|
630
|
+
smartStandardTableExtendedImageNonNormativeCollapsible: "smart-standard-table-extended-image-non-normative-collapsible",
|
|
631
|
+
smartStandardTableExtendedImageNormative: "smart-standard-table-extended-image-normative",
|
|
632
|
+
smartStandardTableExtendedImageNormativeCollapsible: "smart-standard-table-extended-image-normative-collapsible",
|
|
633
|
+
smartStandardTableExtendedNonNormative: "smart-standard-table-extended-non-normative",
|
|
634
|
+
smartStandardTableExtendedNonNormativeCollapsible: "smart-standard-table-extended-non-normative-collapsible",
|
|
635
|
+
smartStandardTableExtendedNormative: "smart-standard-table-extended-normative",
|
|
636
|
+
smartStandardTableExtendedNormativeCollapsible: "smart-standard-table-extended-normative-collapsible",
|
|
621
637
|
smartStandardTableImageNonNormative: "smart-standard-table-image-non-normative",
|
|
622
638
|
smartStandardTableImageNonNormativeCollapsible: "smart-standard-table-image-non-normative-collapsible",
|
|
623
639
|
smartStandardTableImageNormative: "smart-standard-table-image-normative",
|
|
@@ -640,10 +656,18 @@ var BitType = {
|
|
|
640
656
|
standardNoteNormative: "standard-note-normative",
|
|
641
657
|
standardRemarkNonNormative: "standard-remark-non-normative",
|
|
642
658
|
standardRemarkNormative: "standard-remark-normative",
|
|
659
|
+
standardRemarkTableExtendedImageNonNormative: "standard-remark-table-extended-image-non-normative",
|
|
660
|
+
standardRemarkTableExtendedImageNormative: "standard-remark-table-extended-image-normative",
|
|
661
|
+
standardRemarkTableExtendedNonNormative: "standard-remark-table-extended-non-normative",
|
|
662
|
+
standardRemarkTableExtendedNormative: "standard-remark-table-extended-normative",
|
|
643
663
|
standardRemarkTableImageNonNormative: "standard-remark-table-image-non-normative",
|
|
644
664
|
standardRemarkTableImageNormative: "standard-remark-table-image-normative",
|
|
645
665
|
standardRemarkTableNonNormative: "standard-remark-table-non-normative",
|
|
646
666
|
standardRemarkTableNormative: "standard-remark-table-normative",
|
|
667
|
+
standardTableExtendedImageNonNormative: "standard-table-extended-image-non-normative",
|
|
668
|
+
standardTableExtendedImageNormative: "standard-table-extended-image-normative",
|
|
669
|
+
standardTableExtendedNonNormative: "standard-table-extended-non-normative",
|
|
670
|
+
standardTableExtendedNormative: "standard-table-extended-normative",
|
|
647
671
|
standardTableImageNonNormative: "standard-table-image-non-normative",
|
|
648
672
|
standardTableImageNormative: "standard-table-image-normative",
|
|
649
673
|
standardTableNonNormative: "standard-table-non-normative",
|
|
@@ -870,6 +894,10 @@ var AbstractTagConfig = class {
|
|
|
870
894
|
// New JSON-pattern jsonKey (export-only)
|
|
871
895
|
__publicField(this, "hasExportJsonKey");
|
|
872
896
|
// True iff exportJsonKey was explicitly set
|
|
897
|
+
__publicField(this, "htmlKey");
|
|
898
|
+
// HTML key-pattern (export-only)
|
|
899
|
+
__publicField(this, "hasHtmlKey");
|
|
900
|
+
// True iff htmlKey was explicitly set
|
|
873
901
|
__publicField(this, "deprecated");
|
|
874
902
|
this.type = params.type;
|
|
875
903
|
this.configKey = params.configKey;
|
|
@@ -880,6 +908,8 @@ var AbstractTagConfig = class {
|
|
|
880
908
|
this.jsonKey = params.jsonKey;
|
|
881
909
|
this.exportJsonKey = params.exportJsonKey;
|
|
882
910
|
this.hasExportJsonKey = params.hasExportJsonKey;
|
|
911
|
+
this.htmlKey = params.htmlKey;
|
|
912
|
+
this.hasHtmlKey = params.hasHtmlKey;
|
|
883
913
|
this.deprecated = params.deprecated;
|
|
884
914
|
}
|
|
885
915
|
};
|
|
@@ -1001,7 +1031,7 @@ var ResourceTagConfig = class extends AbstractTagConfig {
|
|
|
1001
1031
|
// src/model/config/CardVariantConfig.ts
|
|
1002
1032
|
var CardVariantConfig = class {
|
|
1003
1033
|
// Body text format. Default: bitmark++
|
|
1004
|
-
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
|
|
1034
|
+
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format, htmlKey, hasHtmlKey = false) {
|
|
1005
1035
|
__publicField(this, "tags");
|
|
1006
1036
|
__publicField(this, "bodyAllowed");
|
|
1007
1037
|
// Default: true
|
|
@@ -1015,6 +1045,9 @@ var CardVariantConfig = class {
|
|
|
1015
1045
|
__publicField(this, "exportJsonKey");
|
|
1016
1046
|
// New JSON-pattern jsonKey
|
|
1017
1047
|
__publicField(this, "hasExportJsonKey");
|
|
1048
|
+
__publicField(this, "htmlKey");
|
|
1049
|
+
// HTML key-pattern
|
|
1050
|
+
__publicField(this, "hasHtmlKey");
|
|
1018
1051
|
__publicField(this, "format");
|
|
1019
1052
|
this.tags = tags2;
|
|
1020
1053
|
this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
|
|
@@ -1023,6 +1056,8 @@ var CardVariantConfig = class {
|
|
|
1023
1056
|
this.jsonKey = jsonKey;
|
|
1024
1057
|
this.exportJsonKey = exportJsonKey;
|
|
1025
1058
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1059
|
+
this.htmlKey = htmlKey;
|
|
1060
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1026
1061
|
this.format = format;
|
|
1027
1062
|
}
|
|
1028
1063
|
toString(options) {
|
|
@@ -1047,18 +1082,22 @@ ${tag.toString(opts)}`;
|
|
|
1047
1082
|
|
|
1048
1083
|
// src/model/config/CardSideConfig.ts
|
|
1049
1084
|
var CardSideConfig = class {
|
|
1050
|
-
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
|
|
1085
|
+
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false, htmlKey, hasHtmlKey = false) {
|
|
1051
1086
|
__publicField(this, "name");
|
|
1052
1087
|
__publicField(this, "repeat");
|
|
1053
1088
|
__publicField(this, "jsonKey");
|
|
1054
1089
|
__publicField(this, "exportJsonKey");
|
|
1055
1090
|
__publicField(this, "hasExportJsonKey");
|
|
1091
|
+
__publicField(this, "htmlKey");
|
|
1092
|
+
__publicField(this, "hasHtmlKey");
|
|
1056
1093
|
__publicField(this, "variants");
|
|
1057
1094
|
this.name = name;
|
|
1058
1095
|
this.repeat = repeat;
|
|
1059
1096
|
this.jsonKey = jsonKey;
|
|
1060
1097
|
this.exportJsonKey = exportJsonKey;
|
|
1061
1098
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1099
|
+
this.htmlKey = htmlKey;
|
|
1100
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1062
1101
|
this.variants = variants;
|
|
1063
1102
|
}
|
|
1064
1103
|
toString(options) {
|
|
@@ -1080,17 +1119,21 @@ var CardSideConfig = class {
|
|
|
1080
1119
|
|
|
1081
1120
|
// src/model/config/CardSetConfig.ts
|
|
1082
1121
|
var CardSetConfig = class {
|
|
1083
|
-
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
|
|
1122
|
+
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides, htmlKey = void 0, hasHtmlKey = false) {
|
|
1084
1123
|
__publicField(this, "configKey");
|
|
1085
1124
|
__publicField(this, "jsonKey");
|
|
1086
1125
|
__publicField(this, "exportJsonKey");
|
|
1087
1126
|
__publicField(this, "hasExportJsonKey");
|
|
1127
|
+
__publicField(this, "htmlKey");
|
|
1128
|
+
__publicField(this, "hasHtmlKey");
|
|
1088
1129
|
__publicField(this, "sections");
|
|
1089
1130
|
__publicField(this, "sides");
|
|
1090
1131
|
this.configKey = configKey;
|
|
1091
1132
|
this.jsonKey = jsonKey;
|
|
1092
1133
|
this.exportJsonKey = exportJsonKey;
|
|
1093
1134
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1135
|
+
this.htmlKey = htmlKey;
|
|
1136
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1094
1137
|
this.sections = sections;
|
|
1095
1138
|
this.sides = sides;
|
|
1096
1139
|
}
|
|
@@ -3770,6 +3813,16 @@ var CARDSETS = {
|
|
|
3770
3813
|
[CardSetConfigKey.table]: {
|
|
3771
3814
|
jsonKey: null,
|
|
3772
3815
|
exportJsonKey: null,
|
|
3816
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping. The classic (non-extended)
|
|
3817
|
+
// table produces the same `<table>`/`<thead>`/`<tbody>`/`<tfoot>` structure as
|
|
3818
|
+
// table-extended, so the structural htmlKeys mirror that cardSet. NOTE: the
|
|
3819
|
+
// JSON side routes the FIRST header card → `columns` (header) and SUBSEQUENT
|
|
3820
|
+
// header cards → `data` (body); HTML uses a uniform `<thead>` for the whole
|
|
3821
|
+
// `table-header` section, so a multi-card header (e.g. a second header card
|
|
3822
|
+
// that JSON sends to `data`) renders as additional `<thead>` rows rather than
|
|
3823
|
+
// moving to `<tbody>`. Per-card header/body splitting needs engine-level
|
|
3824
|
+
// routing not yet expressible in the pattern vocabulary — see PLAN-109.
|
|
3825
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3773
3826
|
sections: {
|
|
3774
3827
|
"table-header": {
|
|
3775
3828
|
// First header card's row of cells → `columns`. Subsequent header
|
|
@@ -3788,25 +3841,36 @@ var CARDSETS = {
|
|
|
3788
3841
|
},
|
|
3789
3842
|
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3790
3843
|
{ "@bit": { table: { data: ["$"] } } }
|
|
3791
|
-
]
|
|
3844
|
+
],
|
|
3845
|
+
// Header section → `<thead>` rows of `<th>`; `@tableColWidth` bubbles a
|
|
3846
|
+
// `width` attr onto the enclosing `<th>` (HTML-C2).
|
|
3847
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3848
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3792
3849
|
},
|
|
3793
3850
|
"table-body": {
|
|
3794
3851
|
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3795
3852
|
// This is the default section (no qualifier → cards land here).
|
|
3796
3853
|
jsonKey: "table.data",
|
|
3797
3854
|
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3855
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3798
3856
|
isDefault: true
|
|
3799
3857
|
},
|
|
3800
3858
|
"table-footer": {
|
|
3801
3859
|
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3802
3860
|
jsonKey: "table.data",
|
|
3803
|
-
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3861
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3862
|
+
// Footer cells route to `data` (not `columns`), so they are `<td>` (no
|
|
3863
|
+
// sideHtmlKey override — the cell side default applies).
|
|
3864
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } }
|
|
3804
3865
|
}
|
|
3805
3866
|
},
|
|
3806
3867
|
sides: [
|
|
3807
3868
|
{
|
|
3808
3869
|
name: "cell",
|
|
3809
3870
|
repeat: true,
|
|
3871
|
+
// Default (body/footer) cell → `<td>`; the header section overrides to
|
|
3872
|
+
// `<th>` via its sideHtmlKey (HTML.md §8).
|
|
3873
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3810
3874
|
variants: [
|
|
3811
3875
|
{
|
|
3812
3876
|
jsonKey: null,
|
|
@@ -3823,6 +3887,8 @@ var CARDSETS = {
|
|
|
3823
3887
|
},
|
|
3824
3888
|
{
|
|
3825
3889
|
key: ConfigKey.property_tableCellType,
|
|
3890
|
+
// HTML.md §8: first-match predicate selecting `<th>` vs `<td>`.
|
|
3891
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3826
3892
|
description: "Table cell type (th/td).",
|
|
3827
3893
|
format: TagFormat.plainText
|
|
3828
3894
|
},
|
|
@@ -3845,6 +3911,9 @@ var CARDSETS = {
|
|
|
3845
3911
|
key: ConfigKey.property_tableColWidth,
|
|
3846
3912
|
jsonKey: "^table.columnWidths[{s}]",
|
|
3847
3913
|
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
3914
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3915
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3916
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3848
3917
|
description: "Width for the column.",
|
|
3849
3918
|
format: TagFormat.number
|
|
3850
3919
|
}
|
|
@@ -3860,6 +3929,12 @@ var CARDSETS = {
|
|
|
3860
3929
|
//
|
|
3861
3930
|
[CardSetConfigKey.tableExtended]: {
|
|
3862
3931
|
jsonKey: null,
|
|
3932
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping for the extended table.
|
|
3933
|
+
// The card-set container is the `<table>` element; each section is a
|
|
3934
|
+
// table section element (`<thead>`/`<tbody>`/`<tfoot>`) whose children are
|
|
3935
|
+
// `<tr>` rows, and each cell side is a `<td>` (body) or `<th>` (header /
|
|
3936
|
+
// footer, via the section sideHtmlKey override).
|
|
3937
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3863
3938
|
sections: {
|
|
3864
3939
|
"table-header": {
|
|
3865
3940
|
jsonKey: "table.header.rows",
|
|
@@ -3879,19 +3954,29 @@ var CARDSETS = {
|
|
|
3879
3954
|
},
|
|
3880
3955
|
{ table: { header: { rows: ["$"] } } }
|
|
3881
3956
|
],
|
|
3957
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3882
3958
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3883
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3959
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3960
|
+
// Header cells are `<th>`. The `width` attribute is contributed by the
|
|
3961
|
+
// `@tableColWidth` tag, which bubbles it onto the enclosing `<th>`
|
|
3962
|
+
// (HTML-C2) — so it is not repeated here.
|
|
3963
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3884
3964
|
},
|
|
3885
3965
|
"table-body": {
|
|
3886
3966
|
jsonKey: "table.body.rows",
|
|
3887
3967
|
exportJsonKey: { table: { body: { rows: "$" } } },
|
|
3968
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3888
3969
|
isDefault: true
|
|
3889
3970
|
},
|
|
3890
3971
|
"table-footer": {
|
|
3891
3972
|
jsonKey: "table.footer.rows",
|
|
3892
3973
|
exportJsonKey: { table: { footer: { rows: "$" } } },
|
|
3974
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
|
|
3893
3975
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3894
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3976
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3977
|
+
// Footer cells render as `<th>` (mirrors the header `title: true`
|
|
3978
|
+
// mapping); §8 lists only the header side, so this parallels it.
|
|
3979
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3895
3980
|
}
|
|
3896
3981
|
},
|
|
3897
3982
|
sides: [
|
|
@@ -3900,6 +3985,9 @@ var CARDSETS = {
|
|
|
3900
3985
|
repeat: true,
|
|
3901
3986
|
jsonKey: "cells[{s}]",
|
|
3902
3987
|
exportJsonKey: { cells: { $s: "$" } },
|
|
3988
|
+
// Default (body) cell → `<td>`; the header/footer sections override the
|
|
3989
|
+
// side to `<th>` via their sideHtmlKey (HTML.md §8).
|
|
3990
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3903
3991
|
variants: [
|
|
3904
3992
|
{
|
|
3905
3993
|
jsonKey: "content",
|
|
@@ -3923,6 +4011,9 @@ var CARDSETS = {
|
|
|
3923
4011
|
key: ConfigKey.property_tableCellType,
|
|
3924
4012
|
jsonKey: "title|bool(th)",
|
|
3925
4013
|
exportJsonKey: [{ "@value=th": { title: true } }],
|
|
4014
|
+
// HTML.md §8: same first-match predicate machinery selecting
|
|
4015
|
+
// `<th>` vs `<td>` instead of `title:true` vs nothing.
|
|
4016
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3926
4017
|
description: "Table cell type (th/td).",
|
|
3927
4018
|
format: TagFormat.plainText
|
|
3928
4019
|
},
|
|
@@ -3952,6 +4043,9 @@ var CARDSETS = {
|
|
|
3952
4043
|
// PLAN-080: write to the cell's `colwidth` field.
|
|
3953
4044
|
jsonKey: "colwidth",
|
|
3954
4045
|
exportJsonKey: { colwidth: "$" },
|
|
4046
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
4047
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
4048
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3955
4049
|
description: "Width for the column.",
|
|
3956
4050
|
format: TagFormat.number
|
|
3957
4051
|
}
|
|
@@ -6880,7 +6974,9 @@ var ConfigHydrator = class {
|
|
|
6880
6974
|
variantsOfSide,
|
|
6881
6975
|
_side.jsonKey,
|
|
6882
6976
|
_side.exportJsonKey,
|
|
6883
|
-
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
|
|
6977
|
+
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey"),
|
|
6978
|
+
_side.htmlKey,
|
|
6979
|
+
Object.prototype.hasOwnProperty.call(_side, "htmlKey")
|
|
6884
6980
|
);
|
|
6885
6981
|
sides.push(sideConfig);
|
|
6886
6982
|
}
|
|
@@ -6890,7 +6986,9 @@ var ConfigHydrator = class {
|
|
|
6890
6986
|
_cardSetConfig.exportJsonKey,
|
|
6891
6987
|
Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
|
|
6892
6988
|
this.hydrateCardSections(_cardSetConfig.sections),
|
|
6893
|
-
sides
|
|
6989
|
+
sides,
|
|
6990
|
+
_cardSetConfig.htmlKey,
|
|
6991
|
+
Object.prototype.hasOwnProperty.call(_cardSetConfig, "htmlKey")
|
|
6894
6992
|
);
|
|
6895
6993
|
return cardSetConfig;
|
|
6896
6994
|
}
|
|
@@ -6902,10 +7000,14 @@ var ConfigHydrator = class {
|
|
|
6902
7000
|
jsonKey: v.jsonKey,
|
|
6903
7001
|
exportJsonKey: v.exportJsonKey,
|
|
6904
7002
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
|
|
7003
|
+
htmlKey: v.htmlKey,
|
|
7004
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(v, "htmlKey"),
|
|
6905
7005
|
isDefault: v.isDefault,
|
|
6906
7006
|
sideJsonKey: v.sideJsonKey,
|
|
6907
7007
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
6908
7008
|
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
7009
|
+
sideHtmlKey: v.sideHtmlKey,
|
|
7010
|
+
hasSideHtmlKey: Object.prototype.hasOwnProperty.call(v, "sideHtmlKey"),
|
|
6909
7011
|
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6910
7012
|
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6911
7013
|
// as unbounded).
|
|
@@ -6923,7 +7025,8 @@ var ConfigHydrator = class {
|
|
|
6923
7025
|
chain: _chain,
|
|
6924
7026
|
deprecated,
|
|
6925
7027
|
jsonKey,
|
|
6926
|
-
exportJsonKey
|
|
7028
|
+
exportJsonKey,
|
|
7029
|
+
htmlKey
|
|
6927
7030
|
} = _tag;
|
|
6928
7031
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6929
7032
|
if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
|
|
@@ -6942,6 +7045,8 @@ var ConfigHydrator = class {
|
|
|
6942
7045
|
jsonKey,
|
|
6943
7046
|
exportJsonKey,
|
|
6944
7047
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7048
|
+
htmlKey,
|
|
7049
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6945
7050
|
deprecated
|
|
6946
7051
|
});
|
|
6947
7052
|
return {
|
|
@@ -6961,7 +7066,8 @@ var ConfigHydrator = class {
|
|
|
6961
7066
|
values,
|
|
6962
7067
|
defaultValue,
|
|
6963
7068
|
jsonKey,
|
|
6964
|
-
exportJsonKey
|
|
7069
|
+
exportJsonKey,
|
|
7070
|
+
htmlKey
|
|
6965
7071
|
} = _tag;
|
|
6966
7072
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6967
7073
|
if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
|
|
@@ -6979,6 +7085,8 @@ var ConfigHydrator = class {
|
|
|
6979
7085
|
jsonKey,
|
|
6980
7086
|
exportJsonKey,
|
|
6981
7087
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7088
|
+
htmlKey,
|
|
7089
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6982
7090
|
format,
|
|
6983
7091
|
values,
|
|
6984
7092
|
defaultValue,
|
|
@@ -6998,7 +7106,8 @@ var ConfigHydrator = class {
|
|
|
6998
7106
|
chain: _chain,
|
|
6999
7107
|
deprecated,
|
|
7000
7108
|
jsonKey,
|
|
7001
|
-
exportJsonKey
|
|
7109
|
+
exportJsonKey,
|
|
7110
|
+
htmlKey
|
|
7002
7111
|
} = _tag;
|
|
7003
7112
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
7004
7113
|
if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
|
|
@@ -7016,6 +7125,8 @@ var ConfigHydrator = class {
|
|
|
7016
7125
|
jsonKey,
|
|
7017
7126
|
exportJsonKey,
|
|
7018
7127
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7128
|
+
htmlKey,
|
|
7129
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
7019
7130
|
deprecated
|
|
7020
7131
|
});
|
|
7021
7132
|
return {
|
|
@@ -7054,6 +7165,7 @@ var ConfigHydrator = class {
|
|
|
7054
7165
|
repeatCount,
|
|
7055
7166
|
jsonKey,
|
|
7056
7167
|
exportJsonKey,
|
|
7168
|
+
htmlKey,
|
|
7057
7169
|
format
|
|
7058
7170
|
} = _variant;
|
|
7059
7171
|
const tags2 = this.hydrateTagsConfig(_tags);
|
|
@@ -7065,7 +7177,9 @@ var ConfigHydrator = class {
|
|
|
7065
7177
|
jsonKey,
|
|
7066
7178
|
exportJsonKey,
|
|
7067
7179
|
Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
|
|
7068
|
-
format
|
|
7180
|
+
format,
|
|
7181
|
+
htmlKey,
|
|
7182
|
+
Object.prototype.hasOwnProperty.call(_variant, "htmlKey")
|
|
7069
7183
|
);
|
|
7070
7184
|
return cardSetConfig;
|
|
7071
7185
|
}
|
|
@@ -10876,6 +10990,26 @@ var BITS = {
|
|
|
10876
10990
|
baseBitType: BitType.tableImage,
|
|
10877
10991
|
description: "Standard non-normative remark table image bit, used to create non-normative remark images in tables in articles or books"
|
|
10878
10992
|
},
|
|
10993
|
+
[BitType.standardTableExtendedImageNormative]: {
|
|
10994
|
+
since: "1.16.0",
|
|
10995
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10996
|
+
description: "Standard normative extended table image bit, used to create normative extended images in tables in articles or books"
|
|
10997
|
+
},
|
|
10998
|
+
[BitType.standardTableExtendedImageNonNormative]: {
|
|
10999
|
+
since: "1.16.0",
|
|
11000
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11001
|
+
description: "Standard non-normative extended table image bit, used to create non-normative extended images in tables in articles or books"
|
|
11002
|
+
},
|
|
11003
|
+
[BitType.standardRemarkTableExtendedImageNormative]: {
|
|
11004
|
+
since: "1.17.0",
|
|
11005
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11006
|
+
description: "Standard normative remark extended table image bit, used to create normative remark extended images in tables in articles or books"
|
|
11007
|
+
},
|
|
11008
|
+
[BitType.standardRemarkTableExtendedImageNonNormative]: {
|
|
11009
|
+
since: "1.17.0",
|
|
11010
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11011
|
+
description: "Standard non-normative remark extended table image bit, used to create non-normative remark extended images in tables in articles or books"
|
|
11012
|
+
},
|
|
10879
11013
|
[BitType.smartStandardTableImageNormative]: {
|
|
10880
11014
|
since: "1.28.0",
|
|
10881
11015
|
baseBitType: BitType.standardTableImageNormative,
|
|
@@ -10896,6 +11030,26 @@ var BITS = {
|
|
|
10896
11030
|
baseBitType: BitType.standardRemarkTableImageNonNormative,
|
|
10897
11031
|
description: "Smart standard non-normative remark table image bit, used to create smart standard non-normative remark images in tables in articles or books"
|
|
10898
11032
|
},
|
|
11033
|
+
[BitType.smartStandardTableExtendedImageNormative]: {
|
|
11034
|
+
since: "1.28.0",
|
|
11035
|
+
baseBitType: BitType.standardTableExtendedImageNormative,
|
|
11036
|
+
description: "Smart standard normative extended table image bit, used to create smart standard normative extended images in tables in articles or books"
|
|
11037
|
+
},
|
|
11038
|
+
[BitType.smartStandardTableExtendedImageNonNormative]: {
|
|
11039
|
+
since: "1.28.0",
|
|
11040
|
+
baseBitType: BitType.standardTableExtendedImageNonNormative,
|
|
11041
|
+
description: "Smart standard non-normative extended table image bit, used to create smart standard non-normative extended images in tables in articles or books"
|
|
11042
|
+
},
|
|
11043
|
+
[BitType.smartStandardRemarkTableExtendedImageNormative]: {
|
|
11044
|
+
since: "1.28.0",
|
|
11045
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNormative,
|
|
11046
|
+
description: "Smart standard normative remark extended table image bit, used to create smart standard normative remark extended images in tables in articles or books"
|
|
11047
|
+
},
|
|
11048
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormative]: {
|
|
11049
|
+
since: "1.28.0",
|
|
11050
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNonNormative,
|
|
11051
|
+
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"
|
|
11052
|
+
},
|
|
10899
11053
|
[BitType.smartStandardTableImageNormativeCollapsible]: {
|
|
10900
11054
|
since: "1.28.0",
|
|
10901
11055
|
baseBitType: BitType.smartStandardTableImageNormative,
|
|
@@ -10916,6 +11070,26 @@ var BITS = {
|
|
|
10916
11070
|
baseBitType: BitType.smartStandardRemarkTableImageNonNormative,
|
|
10917
11071
|
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"
|
|
10918
11072
|
},
|
|
11073
|
+
[BitType.smartStandardTableExtendedImageNormativeCollapsible]: {
|
|
11074
|
+
since: "1.28.0",
|
|
11075
|
+
baseBitType: BitType.smartStandardTableExtendedImageNormative,
|
|
11076
|
+
description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
|
|
11077
|
+
},
|
|
11078
|
+
[BitType.smartStandardTableExtendedImageNonNormativeCollapsible]: {
|
|
11079
|
+
since: "1.28.0",
|
|
11080
|
+
baseBitType: BitType.smartStandardTableExtendedImageNonNormative,
|
|
11081
|
+
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"
|
|
11082
|
+
},
|
|
11083
|
+
[BitType.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
|
|
11084
|
+
since: "1.28.0",
|
|
11085
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNormative,
|
|
11086
|
+
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"
|
|
11087
|
+
},
|
|
11088
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
|
|
11089
|
+
since: "1.28.0",
|
|
11090
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNonNormative,
|
|
11091
|
+
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"
|
|
11092
|
+
},
|
|
10919
11093
|
[BitType.imageLink]: {
|
|
10920
11094
|
since: "1.3.0",
|
|
10921
11095
|
baseBitType: BitType._standard,
|
|
@@ -12592,6 +12766,26 @@ var BITS = {
|
|
|
12592
12766
|
baseBitType: BitType.table,
|
|
12593
12767
|
description: "Standard non-normative remark table bit, used to create standard non-normative remark tables in articles or books"
|
|
12594
12768
|
},
|
|
12769
|
+
[BitType.standardTableExtendedNormative]: {
|
|
12770
|
+
since: "1.16.0",
|
|
12771
|
+
baseBitType: BitType.tableExtended,
|
|
12772
|
+
description: "Standard normative extended table bit, used to create standard normative extended tables in articles or books"
|
|
12773
|
+
},
|
|
12774
|
+
[BitType.standardTableExtendedNonNormative]: {
|
|
12775
|
+
since: "1.16.0",
|
|
12776
|
+
baseBitType: BitType.tableExtended,
|
|
12777
|
+
description: "Standard non-normative extended table bit, used to create standard non-normative extended tables in articles or books"
|
|
12778
|
+
},
|
|
12779
|
+
[BitType.standardRemarkTableExtendedNormative]: {
|
|
12780
|
+
since: "1.17.0",
|
|
12781
|
+
baseBitType: BitType.tableExtended,
|
|
12782
|
+
description: "Standard normative remark extended table bit, used to create standard normative remark extended tables in articles or books"
|
|
12783
|
+
},
|
|
12784
|
+
[BitType.standardRemarkTableExtendedNonNormative]: {
|
|
12785
|
+
since: "1.17.0",
|
|
12786
|
+
baseBitType: BitType.tableExtended,
|
|
12787
|
+
description: "Standard non-normative remark extended table bit, used to create standard non-normative remark extended tables in articles or books"
|
|
12788
|
+
},
|
|
12595
12789
|
[BitType.smartStandardTableNormative]: {
|
|
12596
12790
|
since: "1.28.0",
|
|
12597
12791
|
baseBitType: BitType.standardTableNormative,
|
|
@@ -12612,6 +12806,26 @@ var BITS = {
|
|
|
12612
12806
|
baseBitType: BitType.standardRemarkTableNonNormative,
|
|
12613
12807
|
description: "Smart standard non-normative remark table bit, used to create smart standard non-normative remark tables in articles or books"
|
|
12614
12808
|
},
|
|
12809
|
+
[BitType.smartStandardTableExtendedNormative]: {
|
|
12810
|
+
since: "1.28.0",
|
|
12811
|
+
baseBitType: BitType.standardTableExtendedNormative,
|
|
12812
|
+
description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
|
|
12813
|
+
},
|
|
12814
|
+
[BitType.smartStandardTableExtendedNonNormative]: {
|
|
12815
|
+
since: "1.28.0",
|
|
12816
|
+
baseBitType: BitType.standardTableExtendedNonNormative,
|
|
12817
|
+
description: "Smart standard non-normative extended table bit, used to create smart standard non-normative extended tables in articles or books"
|
|
12818
|
+
},
|
|
12819
|
+
[BitType.smartStandardRemarkTableExtendedNormative]: {
|
|
12820
|
+
since: "1.28.0",
|
|
12821
|
+
baseBitType: BitType.standardRemarkTableExtendedNormative,
|
|
12822
|
+
description: "Smart standard normative remark extended table bit, used to create smart standard normative remark extended tables in articles or books"
|
|
12823
|
+
},
|
|
12824
|
+
[BitType.smartStandardRemarkTableExtendedNonNormative]: {
|
|
12825
|
+
since: "1.28.0",
|
|
12826
|
+
baseBitType: BitType.standardRemarkTableExtendedNonNormative,
|
|
12827
|
+
description: "Smart standard non-normative remark extended table bit, used to create smart standard non-normative remark extended tables in articles or books"
|
|
12828
|
+
},
|
|
12615
12829
|
[BitType.smartStandardTableNormativeCollapsible]: {
|
|
12616
12830
|
since: "1.28.0",
|
|
12617
12831
|
baseBitType: BitType.smartStandardTableNormative,
|
|
@@ -12632,6 +12846,26 @@ var BITS = {
|
|
|
12632
12846
|
baseBitType: BitType.smartStandardRemarkTableNonNormative,
|
|
12633
12847
|
description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
|
|
12634
12848
|
},
|
|
12849
|
+
[BitType.smartStandardTableExtendedNormativeCollapsible]: {
|
|
12850
|
+
since: "1.28.0",
|
|
12851
|
+
baseBitType: BitType.smartStandardTableExtendedNormative,
|
|
12852
|
+
description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
|
|
12853
|
+
},
|
|
12854
|
+
[BitType.smartStandardTableExtendedNonNormativeCollapsible]: {
|
|
12855
|
+
since: "1.28.0",
|
|
12856
|
+
baseBitType: BitType.smartStandardTableExtendedNonNormative,
|
|
12857
|
+
description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
|
|
12858
|
+
},
|
|
12859
|
+
[BitType.smartStandardRemarkTableExtendedNormativeCollapsible]: {
|
|
12860
|
+
since: "1.28.0",
|
|
12861
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNormative,
|
|
12862
|
+
description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
|
|
12863
|
+
},
|
|
12864
|
+
[BitType.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
|
|
12865
|
+
since: "1.28.0",
|
|
12866
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNonNormative,
|
|
12867
|
+
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"
|
|
12868
|
+
},
|
|
12635
12869
|
[BitType.parameters]: {
|
|
12636
12870
|
since: "1.18.0",
|
|
12637
12871
|
baseBitType: BitType.table,
|
|
@@ -13573,6 +13807,8 @@ var Config = class {
|
|
|
13573
13807
|
jsonKey: tag.jsonKey,
|
|
13574
13808
|
exportJsonKey: tag.exportJsonKey,
|
|
13575
13809
|
hasExportJsonKey: tag.hasExportJsonKey,
|
|
13810
|
+
htmlKey: tag.htmlKey,
|
|
13811
|
+
hasHtmlKey: tag.hasHtmlKey,
|
|
13576
13812
|
deprecated: tag.deprecated
|
|
13577
13813
|
});
|
|
13578
13814
|
finalResourceTags[k] = newTag;
|
|
@@ -13677,7 +13913,7 @@ var instance2 = new Config();
|
|
|
13677
13913
|
// src/generated/package_info.ts
|
|
13678
13914
|
var PACKAGE_INFO = {
|
|
13679
13915
|
"name": "@gmb/bitmark-parser-generator",
|
|
13680
|
-
"version": "5.
|
|
13916
|
+
"version": "5.27.0",
|
|
13681
13917
|
"author": "Get More Brain Ltd",
|
|
13682
13918
|
"license": "ISC",
|
|
13683
13919
|
"description": "A bitmark parser and generator using Peggy.js"
|
|
@@ -33033,6 +33269,235 @@ var BitmarkStringGenerator = class {
|
|
|
33033
33269
|
}
|
|
33034
33270
|
};
|
|
33035
33271
|
|
|
33272
|
+
// src/generator/html/HtmlTableGenerator.ts
|
|
33273
|
+
var MARK_TO_TAG = {
|
|
33274
|
+
bold: "b",
|
|
33275
|
+
italic: "i",
|
|
33276
|
+
superscript: "sup",
|
|
33277
|
+
subscript: "sub",
|
|
33278
|
+
strike: "s",
|
|
33279
|
+
del: "del",
|
|
33280
|
+
ins: "ins",
|
|
33281
|
+
underline: "u",
|
|
33282
|
+
highlight: "mark",
|
|
33283
|
+
code: "code"
|
|
33284
|
+
};
|
|
33285
|
+
var HtmlTableGenerator = class {
|
|
33286
|
+
constructor() {
|
|
33287
|
+
__publicField(this, "indentUnit", " ");
|
|
33288
|
+
}
|
|
33289
|
+
/**
|
|
33290
|
+
* Generate HTML table fragments from a string or JSON value.
|
|
33291
|
+
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
33292
|
+
*/
|
|
33293
|
+
generate(input) {
|
|
33294
|
+
let data = input;
|
|
33295
|
+
if (typeof data === "string") {
|
|
33296
|
+
try {
|
|
33297
|
+
data = JSON.parse(data);
|
|
33298
|
+
} catch {
|
|
33299
|
+
return "";
|
|
33300
|
+
}
|
|
33301
|
+
}
|
|
33302
|
+
const bits = this.collectBits(data);
|
|
33303
|
+
const fragments = [];
|
|
33304
|
+
for (const bit of bits) {
|
|
33305
|
+
const html = this.renderTableBit(bit);
|
|
33306
|
+
if (html) fragments.push(html);
|
|
33307
|
+
}
|
|
33308
|
+
return fragments.join("\n\n");
|
|
33309
|
+
}
|
|
33310
|
+
// --- bit collection -------------------------------------------------------
|
|
33311
|
+
collectBits(data) {
|
|
33312
|
+
const out = [];
|
|
33313
|
+
const visit = (value) => {
|
|
33314
|
+
if (value == null || typeof value !== "object") return;
|
|
33315
|
+
if (Array.isArray(value)) {
|
|
33316
|
+
value.forEach(visit);
|
|
33317
|
+
return;
|
|
33318
|
+
}
|
|
33319
|
+
const obj = value;
|
|
33320
|
+
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
33321
|
+
out.push(obj.bit);
|
|
33322
|
+
} else if ("type" in obj) {
|
|
33323
|
+
out.push(obj);
|
|
33324
|
+
}
|
|
33325
|
+
};
|
|
33326
|
+
visit(data);
|
|
33327
|
+
return out;
|
|
33328
|
+
}
|
|
33329
|
+
// --- table rendering ------------------------------------------------------
|
|
33330
|
+
renderTableBit(bit) {
|
|
33331
|
+
const table = bit.table;
|
|
33332
|
+
if (!table) return "";
|
|
33333
|
+
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
33334
|
+
const extended = this.toExtended(table);
|
|
33335
|
+
const lines = [];
|
|
33336
|
+
lines.push("<table>");
|
|
33337
|
+
if (bit.caption != null) {
|
|
33338
|
+
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
33339
|
+
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
33340
|
+
}
|
|
33341
|
+
this.renderSection(lines, "thead", extended.header, "header");
|
|
33342
|
+
this.renderSection(lines, "tbody", extended.body, "body");
|
|
33343
|
+
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
33344
|
+
lines.push("</table>");
|
|
33345
|
+
return lines.join("\n");
|
|
33346
|
+
}
|
|
33347
|
+
toExtended(table) {
|
|
33348
|
+
const t = table;
|
|
33349
|
+
if (t.header || t.body || t.footer) return table;
|
|
33350
|
+
return convertBasicToExtendedTableFormat(table);
|
|
33351
|
+
}
|
|
33352
|
+
renderSection(lines, tag, section, key) {
|
|
33353
|
+
if (!section || !section.rows || section.rows.length === 0) return;
|
|
33354
|
+
lines.push(`${this.indentUnit}<${tag}>`);
|
|
33355
|
+
for (const row of section.rows) {
|
|
33356
|
+
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
33357
|
+
for (const cell of row.cells ?? []) {
|
|
33358
|
+
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
33359
|
+
}
|
|
33360
|
+
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
33361
|
+
}
|
|
33362
|
+
lines.push(`${this.indentUnit}</${tag}>`);
|
|
33363
|
+
}
|
|
33364
|
+
renderCell(cell, _key) {
|
|
33365
|
+
const tag = cell.title === true ? "th" : "td";
|
|
33366
|
+
const attrs = [];
|
|
33367
|
+
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
33368
|
+
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
33369
|
+
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
33370
|
+
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
33371
|
+
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
33372
|
+
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
33373
|
+
}
|
|
33374
|
+
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
33375
|
+
asTextAst(content) {
|
|
33376
|
+
if (content == null) return [];
|
|
33377
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
33378
|
+
return content;
|
|
33379
|
+
}
|
|
33380
|
+
cellContentToHtml(blocks) {
|
|
33381
|
+
if (blocks.length === 0) return "";
|
|
33382
|
+
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
33383
|
+
return this.inlineToHtml(blocks[0].content ?? []);
|
|
33384
|
+
}
|
|
33385
|
+
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
33386
|
+
}
|
|
33387
|
+
blockToHtml(node) {
|
|
33388
|
+
switch (node.type) {
|
|
33389
|
+
case "paragraph":
|
|
33390
|
+
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
33391
|
+
case "bulletList":
|
|
33392
|
+
case "noBulletList":
|
|
33393
|
+
case "orderedList":
|
|
33394
|
+
case "orderedListRoman":
|
|
33395
|
+
case "orderedListRomanLower":
|
|
33396
|
+
case "letteredList":
|
|
33397
|
+
case "letteredListLower":
|
|
33398
|
+
case "taskList":
|
|
33399
|
+
return this.listToHtml(node);
|
|
33400
|
+
case "image":
|
|
33401
|
+
case "imageInline":
|
|
33402
|
+
return this.imageToHtml(node);
|
|
33403
|
+
default:
|
|
33404
|
+
return this.inlineToHtml([node]);
|
|
33405
|
+
}
|
|
33406
|
+
}
|
|
33407
|
+
inlineToHtml(nodes) {
|
|
33408
|
+
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
33409
|
+
}
|
|
33410
|
+
inlineNodeToHtml(node) {
|
|
33411
|
+
if (node.type === "hardBreak") return "<br>";
|
|
33412
|
+
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
33413
|
+
if (node.type === "text") {
|
|
33414
|
+
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
33415
|
+
}
|
|
33416
|
+
if (node.content) return this.inlineToHtml(node.content);
|
|
33417
|
+
return this.escapeText(node.text ?? "");
|
|
33418
|
+
}
|
|
33419
|
+
wrapMarks(text, marks) {
|
|
33420
|
+
if (!marks || marks.length === 0) return text;
|
|
33421
|
+
let open = "";
|
|
33422
|
+
let close = "";
|
|
33423
|
+
for (const mark of marks) {
|
|
33424
|
+
if (mark.type === "link") {
|
|
33425
|
+
const href = mark.attrs?.href ?? "";
|
|
33426
|
+
open += `<a href="${this.escapeAttr(href)}">`;
|
|
33427
|
+
close = `</a>${close}`;
|
|
33428
|
+
} else {
|
|
33429
|
+
const tag = MARK_TO_TAG[mark.type];
|
|
33430
|
+
if (tag) {
|
|
33431
|
+
open += `<${tag}>`;
|
|
33432
|
+
close = `</${tag}>${close}`;
|
|
33433
|
+
}
|
|
33434
|
+
}
|
|
33435
|
+
}
|
|
33436
|
+
return `${open}${text}${close}`;
|
|
33437
|
+
}
|
|
33438
|
+
// --- lists ----------------------------------------------------------------
|
|
33439
|
+
listToHtml(node) {
|
|
33440
|
+
const { tag, attrs } = this.listTag(node);
|
|
33441
|
+
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
33442
|
+
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
33443
|
+
}
|
|
33444
|
+
listTag(node) {
|
|
33445
|
+
const start = node.attrs?.start;
|
|
33446
|
+
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
33447
|
+
switch (node.type) {
|
|
33448
|
+
case "orderedList":
|
|
33449
|
+
return { tag: "ol", attrs: startAttr };
|
|
33450
|
+
case "orderedListRoman":
|
|
33451
|
+
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
33452
|
+
case "orderedListRomanLower":
|
|
33453
|
+
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
33454
|
+
case "letteredList":
|
|
33455
|
+
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
33456
|
+
case "letteredListLower":
|
|
33457
|
+
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
33458
|
+
case "noBulletList":
|
|
33459
|
+
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
33460
|
+
case "taskList":
|
|
33461
|
+
case "bulletList":
|
|
33462
|
+
default:
|
|
33463
|
+
return { tag: "ul", attrs: "" };
|
|
33464
|
+
}
|
|
33465
|
+
}
|
|
33466
|
+
listItemToHtml(item, task) {
|
|
33467
|
+
const inner = (item.content ?? []).map((b) => {
|
|
33468
|
+
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
33469
|
+
return this.blockToHtml(b);
|
|
33470
|
+
}).join("");
|
|
33471
|
+
if (task) {
|
|
33472
|
+
const checked = item.attrs?.checked ? " checked" : "";
|
|
33473
|
+
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
33474
|
+
}
|
|
33475
|
+
return `<li>${inner}</li>`;
|
|
33476
|
+
}
|
|
33477
|
+
// --- images ---------------------------------------------------------------
|
|
33478
|
+
imageToHtml(node) {
|
|
33479
|
+
const attrs = node.attrs ?? {};
|
|
33480
|
+
const parts = [];
|
|
33481
|
+
const src = attrs.src;
|
|
33482
|
+
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
33483
|
+
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
33484
|
+
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
33485
|
+
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
33486
|
+
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
33487
|
+
if (typeof attrs.class === "string" && attrs.class) {
|
|
33488
|
+
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
33489
|
+
}
|
|
33490
|
+
return `<img ${parts.join(" ")}>`;
|
|
33491
|
+
}
|
|
33492
|
+
// --- escaping -------------------------------------------------------------
|
|
33493
|
+
escapeText(text) {
|
|
33494
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
33495
|
+
}
|
|
33496
|
+
escapeAttr(text) {
|
|
33497
|
+
return this.escapeText(text).replace(/"/g, """);
|
|
33498
|
+
}
|
|
33499
|
+
};
|
|
33500
|
+
|
|
33036
33501
|
// src/generator/json/JsonGenerator.ts
|
|
33037
33502
|
var import_superenum33 = require("@ncoderz/superenum");
|
|
33038
33503
|
var MOVE_BODY_RECURSION_LIMIT = 5e3;
|
|
@@ -37978,6 +38443,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
|
|
|
37978
38443
|
jsonKey: void 0,
|
|
37979
38444
|
exportJsonKey: void 0,
|
|
37980
38445
|
hasExportJsonKey: false,
|
|
38446
|
+
htmlKey: void 0,
|
|
38447
|
+
hasHtmlKey: false,
|
|
37981
38448
|
format: TagFormat.bitmarkText,
|
|
37982
38449
|
values: void 0,
|
|
37983
38450
|
defaultValue: void 0,
|
|
@@ -42375,6 +42842,499 @@ var BitmarkParser = class {
|
|
|
42375
42842
|
}
|
|
42376
42843
|
};
|
|
42377
42844
|
|
|
42845
|
+
// src/parser/html/HtmlDom.ts
|
|
42846
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
42847
|
+
"area",
|
|
42848
|
+
"base",
|
|
42849
|
+
"br",
|
|
42850
|
+
"col",
|
|
42851
|
+
"embed",
|
|
42852
|
+
"hr",
|
|
42853
|
+
"img",
|
|
42854
|
+
"input",
|
|
42855
|
+
"link",
|
|
42856
|
+
"meta",
|
|
42857
|
+
"param",
|
|
42858
|
+
"source",
|
|
42859
|
+
"track",
|
|
42860
|
+
"wbr"
|
|
42861
|
+
]);
|
|
42862
|
+
var IMPLIED_CLOSE = {
|
|
42863
|
+
li: /* @__PURE__ */ new Set(["li"]),
|
|
42864
|
+
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42865
|
+
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42866
|
+
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
42867
|
+
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42868
|
+
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42869
|
+
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42870
|
+
p: /* @__PURE__ */ new Set(["p"]),
|
|
42871
|
+
option: /* @__PURE__ */ new Set(["option"])
|
|
42872
|
+
};
|
|
42873
|
+
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
42874
|
+
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
42875
|
+
function parseAttrs(raw) {
|
|
42876
|
+
const attrs = {};
|
|
42877
|
+
if (!raw) return attrs;
|
|
42878
|
+
ATTR_RE.lastIndex = 0;
|
|
42879
|
+
let m;
|
|
42880
|
+
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
42881
|
+
const name = m[1].toLowerCase();
|
|
42882
|
+
let value = m[2] ?? "";
|
|
42883
|
+
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
42884
|
+
value = value.slice(1, -1);
|
|
42885
|
+
}
|
|
42886
|
+
attrs[name] = value;
|
|
42887
|
+
}
|
|
42888
|
+
return attrs;
|
|
42889
|
+
}
|
|
42890
|
+
function stripNonContent(html) {
|
|
42891
|
+
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, "");
|
|
42892
|
+
}
|
|
42893
|
+
function tokenize(html) {
|
|
42894
|
+
const tokens = [];
|
|
42895
|
+
const clean = stripNonContent(html);
|
|
42896
|
+
TAG_RE.lastIndex = 0;
|
|
42897
|
+
let lastIndex = 0;
|
|
42898
|
+
let m;
|
|
42899
|
+
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
42900
|
+
if (m.index > lastIndex) {
|
|
42901
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
42902
|
+
}
|
|
42903
|
+
lastIndex = TAG_RE.lastIndex;
|
|
42904
|
+
const isClose = m[1] === "/";
|
|
42905
|
+
const name = m[2].toLowerCase();
|
|
42906
|
+
if (isClose) {
|
|
42907
|
+
tokens.push({ kind: "close", name });
|
|
42908
|
+
} else {
|
|
42909
|
+
tokens.push({
|
|
42910
|
+
kind: "open",
|
|
42911
|
+
name,
|
|
42912
|
+
attrs: parseAttrs(m[3]),
|
|
42913
|
+
selfClose: m[4] === "/"
|
|
42914
|
+
});
|
|
42915
|
+
}
|
|
42916
|
+
}
|
|
42917
|
+
if (lastIndex < clean.length) {
|
|
42918
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
42919
|
+
}
|
|
42920
|
+
return tokens;
|
|
42921
|
+
}
|
|
42922
|
+
function parseHtml(html) {
|
|
42923
|
+
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
42924
|
+
const stack = [root];
|
|
42925
|
+
const top = () => stack[stack.length - 1];
|
|
42926
|
+
for (const token of tokenize(html)) {
|
|
42927
|
+
if (token.kind === "text") {
|
|
42928
|
+
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
42929
|
+
continue;
|
|
42930
|
+
}
|
|
42931
|
+
if (token.kind === "open") {
|
|
42932
|
+
const name = token.name;
|
|
42933
|
+
const closes = IMPLIED_CLOSE[name];
|
|
42934
|
+
if (closes) {
|
|
42935
|
+
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
42936
|
+
}
|
|
42937
|
+
const el = {
|
|
42938
|
+
type: "element",
|
|
42939
|
+
name,
|
|
42940
|
+
attrs: token.attrs ?? {},
|
|
42941
|
+
children: []
|
|
42942
|
+
};
|
|
42943
|
+
top().children.push(el);
|
|
42944
|
+
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
42945
|
+
stack.push(el);
|
|
42946
|
+
}
|
|
42947
|
+
continue;
|
|
42948
|
+
}
|
|
42949
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
42950
|
+
if (stack[i].name === token.name) {
|
|
42951
|
+
stack.length = i;
|
|
42952
|
+
break;
|
|
42953
|
+
}
|
|
42954
|
+
}
|
|
42955
|
+
}
|
|
42956
|
+
return root.children;
|
|
42957
|
+
}
|
|
42958
|
+
function childElements(el, names) {
|
|
42959
|
+
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
42960
|
+
}
|
|
42961
|
+
|
|
42962
|
+
// src/parser/html/HtmlTableParser.ts
|
|
42963
|
+
var MARK_TAGS = {
|
|
42964
|
+
b: "bold",
|
|
42965
|
+
strong: "bold",
|
|
42966
|
+
i: "italic",
|
|
42967
|
+
em: "italic",
|
|
42968
|
+
sup: "superscript",
|
|
42969
|
+
sub: "subscript",
|
|
42970
|
+
s: "strike",
|
|
42971
|
+
strike: "strike",
|
|
42972
|
+
del: "del",
|
|
42973
|
+
ins: "ins",
|
|
42974
|
+
u: "underline",
|
|
42975
|
+
mark: "highlight",
|
|
42976
|
+
code: "code"
|
|
42977
|
+
};
|
|
42978
|
+
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
42979
|
+
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
42980
|
+
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
42981
|
+
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
42982
|
+
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
42983
|
+
var NAMED_ENTITIES = {
|
|
42984
|
+
amp: "&",
|
|
42985
|
+
lt: "<",
|
|
42986
|
+
gt: ">",
|
|
42987
|
+
quot: '"',
|
|
42988
|
+
apos: "'",
|
|
42989
|
+
nbsp: "\xA0"
|
|
42990
|
+
};
|
|
42991
|
+
function decodeEntities(text) {
|
|
42992
|
+
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
42993
|
+
if (body[0] === "#") {
|
|
42994
|
+
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
42995
|
+
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
42996
|
+
try {
|
|
42997
|
+
return String.fromCodePoint(code);
|
|
42998
|
+
} catch {
|
|
42999
|
+
return whole;
|
|
43000
|
+
}
|
|
43001
|
+
}
|
|
43002
|
+
return whole;
|
|
43003
|
+
}
|
|
43004
|
+
return NAMED_ENTITIES[body] ?? whole;
|
|
43005
|
+
});
|
|
43006
|
+
}
|
|
43007
|
+
function intAttr(value) {
|
|
43008
|
+
if (value == null) return void 0;
|
|
43009
|
+
const n = Number.parseInt(value, 10);
|
|
43010
|
+
return Number.isInteger(n) ? n : void 0;
|
|
43011
|
+
}
|
|
43012
|
+
function isElement(node) {
|
|
43013
|
+
return node.type === "element";
|
|
43014
|
+
}
|
|
43015
|
+
var HtmlTableParser = class {
|
|
43016
|
+
constructor() {
|
|
43017
|
+
__publicField(this, "keepUnknownTags", false);
|
|
43018
|
+
}
|
|
43019
|
+
/**
|
|
43020
|
+
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
43021
|
+
*/
|
|
43022
|
+
parse(html, options) {
|
|
43023
|
+
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
43024
|
+
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
43025
|
+
const onWarning = options?.onWarning;
|
|
43026
|
+
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
43027
|
+
const bits = [];
|
|
43028
|
+
for (const table of tables) {
|
|
43029
|
+
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
43030
|
+
if (bit) bits.push(bit);
|
|
43031
|
+
}
|
|
43032
|
+
return bits;
|
|
43033
|
+
}
|
|
43034
|
+
// --- table extraction -----------------------------------------------------
|
|
43035
|
+
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
43036
|
+
collectTopLevelTables(nodes) {
|
|
43037
|
+
const tables = [];
|
|
43038
|
+
const visit = (node) => {
|
|
43039
|
+
if (!isElement(node)) return;
|
|
43040
|
+
if (node.name === "table") {
|
|
43041
|
+
tables.push(node);
|
|
43042
|
+
return;
|
|
43043
|
+
}
|
|
43044
|
+
node.children.forEach(visit);
|
|
43045
|
+
};
|
|
43046
|
+
nodes.forEach(visit);
|
|
43047
|
+
return tables;
|
|
43048
|
+
}
|
|
43049
|
+
tableToBit(table, tableFormat, onWarning) {
|
|
43050
|
+
const header = [];
|
|
43051
|
+
const body = [];
|
|
43052
|
+
const footer = [];
|
|
43053
|
+
let caption;
|
|
43054
|
+
for (const child of table.children) {
|
|
43055
|
+
if (!isElement(child)) continue;
|
|
43056
|
+
if (child.name === "caption") {
|
|
43057
|
+
const capContent = this.inlineNodes(child.children, []);
|
|
43058
|
+
const trimmed = this.trimInline(capContent);
|
|
43059
|
+
if (trimmed.length > 0) caption = trimmed;
|
|
43060
|
+
} else if (SECTION_TAGS.has(child.name)) {
|
|
43061
|
+
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
43062
|
+
for (const tr of childElements(child, ROW_TAGS)) {
|
|
43063
|
+
target.push(this.rowToCells(tr));
|
|
43064
|
+
}
|
|
43065
|
+
} else if (ROW_TAGS.has(child.name)) {
|
|
43066
|
+
body.push(this.rowToCells(child));
|
|
43067
|
+
}
|
|
43068
|
+
}
|
|
43069
|
+
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
43070
|
+
return void 0;
|
|
43071
|
+
}
|
|
43072
|
+
const tableExtended = {};
|
|
43073
|
+
if (header.length > 0) tableExtended.header = { rows: header };
|
|
43074
|
+
if (body.length > 0) tableExtended.body = { rows: body };
|
|
43075
|
+
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
43076
|
+
let tableData = tableExtended;
|
|
43077
|
+
if (tableFormat === "table") {
|
|
43078
|
+
if (this.isLossyAsBasic(tableExtended)) {
|
|
43079
|
+
onWarning?.(
|
|
43080
|
+
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
43081
|
+
);
|
|
43082
|
+
}
|
|
43083
|
+
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
43084
|
+
}
|
|
43085
|
+
const bit = {
|
|
43086
|
+
type: tableFormat,
|
|
43087
|
+
format: "bitmark++",
|
|
43088
|
+
table: tableData
|
|
43089
|
+
};
|
|
43090
|
+
if (caption) bit.caption = caption;
|
|
43091
|
+
return bit;
|
|
43092
|
+
}
|
|
43093
|
+
rowToCells(tr) {
|
|
43094
|
+
const cells = [];
|
|
43095
|
+
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
43096
|
+
cells.push(this.cellToJson(cell));
|
|
43097
|
+
}
|
|
43098
|
+
return { cells };
|
|
43099
|
+
}
|
|
43100
|
+
cellToJson(cell) {
|
|
43101
|
+
const json = {
|
|
43102
|
+
content: this.blockNodes(cell.children)
|
|
43103
|
+
};
|
|
43104
|
+
if (cell.name === "th") json.title = true;
|
|
43105
|
+
const rowspan = intAttr(cell.attrs.rowspan);
|
|
43106
|
+
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
43107
|
+
const colspan = intAttr(cell.attrs.colspan);
|
|
43108
|
+
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
43109
|
+
const scope = cell.attrs.scope?.toLowerCase();
|
|
43110
|
+
if (scope && VALID_SCOPES.has(scope)) {
|
|
43111
|
+
json.scope = scope;
|
|
43112
|
+
}
|
|
43113
|
+
const width = this.widthFromCell(cell);
|
|
43114
|
+
if (width != null) json.colwidth = width;
|
|
43115
|
+
return json;
|
|
43116
|
+
}
|
|
43117
|
+
widthFromCell(cell) {
|
|
43118
|
+
const attrWidth = intAttr(cell.attrs.width);
|
|
43119
|
+
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
43120
|
+
const style = cell.attrs.style;
|
|
43121
|
+
if (style) {
|
|
43122
|
+
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
43123
|
+
if (m) {
|
|
43124
|
+
const n = Number.parseInt(m[1], 10);
|
|
43125
|
+
if (Number.isInteger(n) && n > 0) return n;
|
|
43126
|
+
}
|
|
43127
|
+
}
|
|
43128
|
+
return void 0;
|
|
43129
|
+
}
|
|
43130
|
+
isLossyAsBasic(table) {
|
|
43131
|
+
if (table.footer) return true;
|
|
43132
|
+
if (table.header && table.header.rows.length > 1) return true;
|
|
43133
|
+
const sections = [table.header, table.body, table.footer];
|
|
43134
|
+
for (const section of sections) {
|
|
43135
|
+
if (!section) continue;
|
|
43136
|
+
for (const row of section.rows) {
|
|
43137
|
+
for (const cell of row.cells) {
|
|
43138
|
+
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
43139
|
+
}
|
|
43140
|
+
}
|
|
43141
|
+
}
|
|
43142
|
+
return false;
|
|
43143
|
+
}
|
|
43144
|
+
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
43145
|
+
/**
|
|
43146
|
+
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
43147
|
+
*/
|
|
43148
|
+
blockNodes(nodes) {
|
|
43149
|
+
const blocks = [];
|
|
43150
|
+
let inline = [];
|
|
43151
|
+
const flush = () => {
|
|
43152
|
+
const trimmed = this.trimInline(inline);
|
|
43153
|
+
inline = [];
|
|
43154
|
+
if (trimmed.length === 0) return;
|
|
43155
|
+
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
43156
|
+
blocks.push({ ...trimmed[0], type: "image" });
|
|
43157
|
+
} else {
|
|
43158
|
+
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
43159
|
+
}
|
|
43160
|
+
};
|
|
43161
|
+
for (const node of nodes) {
|
|
43162
|
+
if (!isElement(node)) {
|
|
43163
|
+
inline.push(...this.inlineText(node.value, []));
|
|
43164
|
+
continue;
|
|
43165
|
+
}
|
|
43166
|
+
const name = node.name;
|
|
43167
|
+
if (name === "p") {
|
|
43168
|
+
flush();
|
|
43169
|
+
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
43170
|
+
if (content.length > 0) {
|
|
43171
|
+
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
43172
|
+
}
|
|
43173
|
+
} else if (this.isListTag(name)) {
|
|
43174
|
+
flush();
|
|
43175
|
+
const list = this.listNode(node);
|
|
43176
|
+
if (list) blocks.push(list);
|
|
43177
|
+
} else {
|
|
43178
|
+
inline.push(...this.inlineFromElement(node, []));
|
|
43179
|
+
}
|
|
43180
|
+
}
|
|
43181
|
+
flush();
|
|
43182
|
+
return blocks;
|
|
43183
|
+
}
|
|
43184
|
+
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
43185
|
+
inlineNodes(nodes, marks) {
|
|
43186
|
+
const out = [];
|
|
43187
|
+
for (const node of nodes) {
|
|
43188
|
+
if (!isElement(node)) {
|
|
43189
|
+
out.push(...this.inlineText(node.value, marks));
|
|
43190
|
+
} else {
|
|
43191
|
+
out.push(...this.inlineFromElement(node, marks));
|
|
43192
|
+
}
|
|
43193
|
+
}
|
|
43194
|
+
return out;
|
|
43195
|
+
}
|
|
43196
|
+
inlineFromElement(el, marks) {
|
|
43197
|
+
const name = el.name;
|
|
43198
|
+
if (name === "br") {
|
|
43199
|
+
return [{ type: "hardBreak" }];
|
|
43200
|
+
}
|
|
43201
|
+
if (name === "img") {
|
|
43202
|
+
return [this.imageNode(el, true)];
|
|
43203
|
+
}
|
|
43204
|
+
const markType = MARK_TAGS[name];
|
|
43205
|
+
if (markType) {
|
|
43206
|
+
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
43207
|
+
}
|
|
43208
|
+
if (name === "a") {
|
|
43209
|
+
const linkMark = {
|
|
43210
|
+
type: "link",
|
|
43211
|
+
attrs: {
|
|
43212
|
+
href: el.attrs.href ?? "",
|
|
43213
|
+
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
43214
|
+
}
|
|
43215
|
+
};
|
|
43216
|
+
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
43217
|
+
}
|
|
43218
|
+
if (this.keepUnknownTags) {
|
|
43219
|
+
const open = this.serializeOpenTag(el);
|
|
43220
|
+
const close = `</${name}>`;
|
|
43221
|
+
return [
|
|
43222
|
+
...this.inlineText(open, marks),
|
|
43223
|
+
...this.inlineNodes(el.children, marks),
|
|
43224
|
+
...this.inlineText(close, marks)
|
|
43225
|
+
];
|
|
43226
|
+
}
|
|
43227
|
+
return this.inlineNodes(el.children, marks);
|
|
43228
|
+
}
|
|
43229
|
+
inlineText(raw, marks) {
|
|
43230
|
+
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
43231
|
+
if (text === "") return [];
|
|
43232
|
+
const node = { text, type: "text" };
|
|
43233
|
+
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
43234
|
+
return [node];
|
|
43235
|
+
}
|
|
43236
|
+
serializeOpenTag(el) {
|
|
43237
|
+
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
43238
|
+
return `<${el.name}${attrs}>`;
|
|
43239
|
+
}
|
|
43240
|
+
// --- lists ----------------------------------------------------------------
|
|
43241
|
+
isListTag(name) {
|
|
43242
|
+
return name === "ul" || name === "ol";
|
|
43243
|
+
}
|
|
43244
|
+
listNode(el) {
|
|
43245
|
+
const items = childElements(el, LI_TAGS);
|
|
43246
|
+
if (items.length === 0) return void 0;
|
|
43247
|
+
const isTask = el.name === "ul" && items.some((li) => {
|
|
43248
|
+
const firstEl = li.children.find(isElement);
|
|
43249
|
+
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
43250
|
+
});
|
|
43251
|
+
if (isTask) {
|
|
43252
|
+
return {
|
|
43253
|
+
type: "taskList",
|
|
43254
|
+
content: items.map((li) => this.taskItemNode(li))
|
|
43255
|
+
};
|
|
43256
|
+
}
|
|
43257
|
+
const type = this.listType(el);
|
|
43258
|
+
const node = {
|
|
43259
|
+
type,
|
|
43260
|
+
content: items.map((li) => this.listItemNode(li))
|
|
43261
|
+
};
|
|
43262
|
+
if (el.name === "ol") {
|
|
43263
|
+
const start = intAttr(el.attrs.start);
|
|
43264
|
+
if (start != null) {
|
|
43265
|
+
node.attrs = { start };
|
|
43266
|
+
}
|
|
43267
|
+
}
|
|
43268
|
+
return node;
|
|
43269
|
+
}
|
|
43270
|
+
listType(el) {
|
|
43271
|
+
if (el.name === "ol") {
|
|
43272
|
+
switch (el.attrs.type) {
|
|
43273
|
+
case "i":
|
|
43274
|
+
return "orderedListRomanLower";
|
|
43275
|
+
case "I":
|
|
43276
|
+
return "orderedListRoman";
|
|
43277
|
+
case "a":
|
|
43278
|
+
return "letteredListLower";
|
|
43279
|
+
case "A":
|
|
43280
|
+
return "letteredList";
|
|
43281
|
+
default:
|
|
43282
|
+
return "orderedList";
|
|
43283
|
+
}
|
|
43284
|
+
}
|
|
43285
|
+
const style = el.attrs.style ?? "";
|
|
43286
|
+
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
43287
|
+
return "bulletList";
|
|
43288
|
+
}
|
|
43289
|
+
listItemNode(li) {
|
|
43290
|
+
let content = this.blockNodes(li.children);
|
|
43291
|
+
if (content.length === 0) {
|
|
43292
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43293
|
+
}
|
|
43294
|
+
return { type: "listItem", content };
|
|
43295
|
+
}
|
|
43296
|
+
taskItemNode(li) {
|
|
43297
|
+
const checkbox = li.children.find(
|
|
43298
|
+
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
43299
|
+
);
|
|
43300
|
+
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
43301
|
+
const rest = li.children.filter((c) => c !== checkbox);
|
|
43302
|
+
let content = this.blockNodes(rest);
|
|
43303
|
+
if (content.length === 0) {
|
|
43304
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43305
|
+
}
|
|
43306
|
+
return { type: "taskItem", attrs: { checked }, content };
|
|
43307
|
+
}
|
|
43308
|
+
// --- images ---------------------------------------------------------------
|
|
43309
|
+
imageNode(el, inline) {
|
|
43310
|
+
const attrs = { src: el.attrs.src ?? "" };
|
|
43311
|
+
attrs.alt = el.attrs.alt ?? null;
|
|
43312
|
+
attrs.title = el.attrs.title ?? null;
|
|
43313
|
+
const width = intAttr(el.attrs.width);
|
|
43314
|
+
if (width != null) attrs.width = width;
|
|
43315
|
+
const height = intAttr(el.attrs.height);
|
|
43316
|
+
if (height != null) attrs.height = height;
|
|
43317
|
+
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
43318
|
+
return { type: inline ? "imageInline" : "image", attrs };
|
|
43319
|
+
}
|
|
43320
|
+
// --- whitespace -----------------------------------------------------------
|
|
43321
|
+
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
43322
|
+
trimInline(nodes) {
|
|
43323
|
+
const out = nodes.slice();
|
|
43324
|
+
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
43325
|
+
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
43326
|
+
if (out.length > 0 && out[0].type === "text") {
|
|
43327
|
+
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
43328
|
+
}
|
|
43329
|
+
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
43330
|
+
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
43331
|
+
const last = out.length - 1;
|
|
43332
|
+
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
43333
|
+
}
|
|
43334
|
+
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
43335
|
+
}
|
|
43336
|
+
};
|
|
43337
|
+
|
|
42378
43338
|
// src/BitmarkParserGenerator.ts
|
|
42379
43339
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
42380
43340
|
var import_fs_extra4 = __toESM(require("fs-extra"), 1);
|
|
@@ -42652,248 +43612,19 @@ var BitmarkFileGenerator = class {
|
|
|
42652
43612
|
*
|
|
42653
43613
|
* @param ast bitmark AST
|
|
42654
43614
|
*/
|
|
42655
|
-
async generate(ast) {
|
|
42656
|
-
return this.generator.generate(ast);
|
|
42657
|
-
}
|
|
42658
|
-
/**
|
|
42659
|
-
* Generate bitmark markup from bitmark AST as a file synchronously
|
|
42660
|
-
*
|
|
42661
|
-
* @param ast bitmark AST
|
|
42662
|
-
*/
|
|
42663
|
-
generateSync(_ast) {
|
|
42664
|
-
if (this.async) {
|
|
42665
|
-
throw new Error("Sync operation not supported");
|
|
42666
|
-
}
|
|
42667
|
-
this.generator.generateSync(_ast);
|
|
42668
|
-
}
|
|
42669
|
-
};
|
|
42670
|
-
|
|
42671
|
-
// src/generator/html/HtmlTableGenerator.ts
|
|
42672
|
-
var MARK_TO_TAG = {
|
|
42673
|
-
bold: "b",
|
|
42674
|
-
italic: "i",
|
|
42675
|
-
superscript: "sup",
|
|
42676
|
-
subscript: "sub",
|
|
42677
|
-
strike: "s",
|
|
42678
|
-
del: "del",
|
|
42679
|
-
ins: "ins",
|
|
42680
|
-
underline: "u",
|
|
42681
|
-
highlight: "mark",
|
|
42682
|
-
code: "code"
|
|
42683
|
-
};
|
|
42684
|
-
var HtmlTableGenerator = class {
|
|
42685
|
-
constructor() {
|
|
42686
|
-
__publicField(this, "indentUnit", " ");
|
|
42687
|
-
}
|
|
42688
|
-
/**
|
|
42689
|
-
* Generate HTML table fragments from a string or JSON value.
|
|
42690
|
-
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
42691
|
-
*/
|
|
42692
|
-
generate(input) {
|
|
42693
|
-
let data = input;
|
|
42694
|
-
if (typeof data === "string") {
|
|
42695
|
-
try {
|
|
42696
|
-
data = JSON.parse(data);
|
|
42697
|
-
} catch {
|
|
42698
|
-
return "";
|
|
42699
|
-
}
|
|
42700
|
-
}
|
|
42701
|
-
const bits = this.collectBits(data);
|
|
42702
|
-
const fragments = [];
|
|
42703
|
-
for (const bit of bits) {
|
|
42704
|
-
const html = this.renderTableBit(bit);
|
|
42705
|
-
if (html) fragments.push(html);
|
|
42706
|
-
}
|
|
42707
|
-
return fragments.join("\n\n");
|
|
42708
|
-
}
|
|
42709
|
-
// --- bit collection -------------------------------------------------------
|
|
42710
|
-
collectBits(data) {
|
|
42711
|
-
const out = [];
|
|
42712
|
-
const visit = (value) => {
|
|
42713
|
-
if (value == null || typeof value !== "object") return;
|
|
42714
|
-
if (Array.isArray(value)) {
|
|
42715
|
-
value.forEach(visit);
|
|
42716
|
-
return;
|
|
42717
|
-
}
|
|
42718
|
-
const obj = value;
|
|
42719
|
-
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
42720
|
-
out.push(obj.bit);
|
|
42721
|
-
} else if ("type" in obj) {
|
|
42722
|
-
out.push(obj);
|
|
42723
|
-
}
|
|
42724
|
-
};
|
|
42725
|
-
visit(data);
|
|
42726
|
-
return out;
|
|
42727
|
-
}
|
|
42728
|
-
// --- table rendering ------------------------------------------------------
|
|
42729
|
-
renderTableBit(bit) {
|
|
42730
|
-
const table = bit.table;
|
|
42731
|
-
if (!table) return "";
|
|
42732
|
-
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
42733
|
-
const extended = this.toExtended(table);
|
|
42734
|
-
const lines = [];
|
|
42735
|
-
lines.push("<table>");
|
|
42736
|
-
if (bit.caption != null) {
|
|
42737
|
-
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
42738
|
-
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
42739
|
-
}
|
|
42740
|
-
this.renderSection(lines, "thead", extended.header, "header");
|
|
42741
|
-
this.renderSection(lines, "tbody", extended.body, "body");
|
|
42742
|
-
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
42743
|
-
lines.push("</table>");
|
|
42744
|
-
return lines.join("\n");
|
|
42745
|
-
}
|
|
42746
|
-
toExtended(table) {
|
|
42747
|
-
const t = table;
|
|
42748
|
-
if (t.header || t.body || t.footer) return table;
|
|
42749
|
-
return convertBasicToExtendedTableFormat(table);
|
|
42750
|
-
}
|
|
42751
|
-
renderSection(lines, tag, section, key) {
|
|
42752
|
-
if (!section || !section.rows || section.rows.length === 0) return;
|
|
42753
|
-
lines.push(`${this.indentUnit}<${tag}>`);
|
|
42754
|
-
for (const row of section.rows) {
|
|
42755
|
-
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
42756
|
-
for (const cell of row.cells ?? []) {
|
|
42757
|
-
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
42758
|
-
}
|
|
42759
|
-
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
42760
|
-
}
|
|
42761
|
-
lines.push(`${this.indentUnit}</${tag}>`);
|
|
42762
|
-
}
|
|
42763
|
-
renderCell(cell, _key) {
|
|
42764
|
-
const tag = cell.title === true ? "th" : "td";
|
|
42765
|
-
const attrs = [];
|
|
42766
|
-
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
42767
|
-
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
42768
|
-
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
42769
|
-
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
42770
|
-
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
42771
|
-
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
42772
|
-
}
|
|
42773
|
-
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
42774
|
-
asTextAst(content) {
|
|
42775
|
-
if (content == null) return [];
|
|
42776
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
42777
|
-
return content;
|
|
42778
|
-
}
|
|
42779
|
-
cellContentToHtml(blocks) {
|
|
42780
|
-
if (blocks.length === 0) return "";
|
|
42781
|
-
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
42782
|
-
return this.inlineToHtml(blocks[0].content ?? []);
|
|
42783
|
-
}
|
|
42784
|
-
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
42785
|
-
}
|
|
42786
|
-
blockToHtml(node) {
|
|
42787
|
-
switch (node.type) {
|
|
42788
|
-
case "paragraph":
|
|
42789
|
-
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
42790
|
-
case "bulletList":
|
|
42791
|
-
case "noBulletList":
|
|
42792
|
-
case "orderedList":
|
|
42793
|
-
case "orderedListRoman":
|
|
42794
|
-
case "orderedListRomanLower":
|
|
42795
|
-
case "letteredList":
|
|
42796
|
-
case "letteredListLower":
|
|
42797
|
-
case "taskList":
|
|
42798
|
-
return this.listToHtml(node);
|
|
42799
|
-
case "image":
|
|
42800
|
-
case "imageInline":
|
|
42801
|
-
return this.imageToHtml(node);
|
|
42802
|
-
default:
|
|
42803
|
-
return this.inlineToHtml([node]);
|
|
42804
|
-
}
|
|
42805
|
-
}
|
|
42806
|
-
inlineToHtml(nodes) {
|
|
42807
|
-
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
42808
|
-
}
|
|
42809
|
-
inlineNodeToHtml(node) {
|
|
42810
|
-
if (node.type === "hardBreak") return "<br>";
|
|
42811
|
-
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
42812
|
-
if (node.type === "text") {
|
|
42813
|
-
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
42814
|
-
}
|
|
42815
|
-
if (node.content) return this.inlineToHtml(node.content);
|
|
42816
|
-
return this.escapeText(node.text ?? "");
|
|
42817
|
-
}
|
|
42818
|
-
wrapMarks(text, marks) {
|
|
42819
|
-
if (!marks || marks.length === 0) return text;
|
|
42820
|
-
let open = "";
|
|
42821
|
-
let close = "";
|
|
42822
|
-
for (const mark of marks) {
|
|
42823
|
-
if (mark.type === "link") {
|
|
42824
|
-
const href = mark.attrs?.href ?? "";
|
|
42825
|
-
open += `<a href="${this.escapeAttr(href)}">`;
|
|
42826
|
-
close = `</a>${close}`;
|
|
42827
|
-
} else {
|
|
42828
|
-
const tag = MARK_TO_TAG[mark.type];
|
|
42829
|
-
if (tag) {
|
|
42830
|
-
open += `<${tag}>`;
|
|
42831
|
-
close = `</${tag}>${close}`;
|
|
42832
|
-
}
|
|
42833
|
-
}
|
|
42834
|
-
}
|
|
42835
|
-
return `${open}${text}${close}`;
|
|
42836
|
-
}
|
|
42837
|
-
// --- lists ----------------------------------------------------------------
|
|
42838
|
-
listToHtml(node) {
|
|
42839
|
-
const { tag, attrs } = this.listTag(node);
|
|
42840
|
-
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
42841
|
-
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
42842
|
-
}
|
|
42843
|
-
listTag(node) {
|
|
42844
|
-
const start = node.attrs?.start;
|
|
42845
|
-
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
42846
|
-
switch (node.type) {
|
|
42847
|
-
case "orderedList":
|
|
42848
|
-
return { tag: "ol", attrs: startAttr };
|
|
42849
|
-
case "orderedListRoman":
|
|
42850
|
-
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
42851
|
-
case "orderedListRomanLower":
|
|
42852
|
-
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
42853
|
-
case "letteredList":
|
|
42854
|
-
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
42855
|
-
case "letteredListLower":
|
|
42856
|
-
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
42857
|
-
case "noBulletList":
|
|
42858
|
-
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
42859
|
-
case "taskList":
|
|
42860
|
-
case "bulletList":
|
|
42861
|
-
default:
|
|
42862
|
-
return { tag: "ul", attrs: "" };
|
|
42863
|
-
}
|
|
42864
|
-
}
|
|
42865
|
-
listItemToHtml(item, task) {
|
|
42866
|
-
const inner = (item.content ?? []).map((b) => {
|
|
42867
|
-
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
42868
|
-
return this.blockToHtml(b);
|
|
42869
|
-
}).join("");
|
|
42870
|
-
if (task) {
|
|
42871
|
-
const checked = item.attrs?.checked ? " checked" : "";
|
|
42872
|
-
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
42873
|
-
}
|
|
42874
|
-
return `<li>${inner}</li>`;
|
|
42875
|
-
}
|
|
42876
|
-
// --- images ---------------------------------------------------------------
|
|
42877
|
-
imageToHtml(node) {
|
|
42878
|
-
const attrs = node.attrs ?? {};
|
|
42879
|
-
const parts = [];
|
|
42880
|
-
const src = attrs.src;
|
|
42881
|
-
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
42882
|
-
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
42883
|
-
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
42884
|
-
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
42885
|
-
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
42886
|
-
if (typeof attrs.class === "string" && attrs.class) {
|
|
42887
|
-
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
42888
|
-
}
|
|
42889
|
-
return `<img ${parts.join(" ")}>`;
|
|
42890
|
-
}
|
|
42891
|
-
// --- escaping -------------------------------------------------------------
|
|
42892
|
-
escapeText(text) {
|
|
42893
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
43615
|
+
async generate(ast) {
|
|
43616
|
+
return this.generator.generate(ast);
|
|
42894
43617
|
}
|
|
42895
|
-
|
|
42896
|
-
|
|
43618
|
+
/**
|
|
43619
|
+
* Generate bitmark markup from bitmark AST as a file synchronously
|
|
43620
|
+
*
|
|
43621
|
+
* @param ast bitmark AST
|
|
43622
|
+
*/
|
|
43623
|
+
generateSync(_ast) {
|
|
43624
|
+
if (this.async) {
|
|
43625
|
+
throw new Error("Sync operation not supported");
|
|
43626
|
+
}
|
|
43627
|
+
this.generator.generateSync(_ast);
|
|
42897
43628
|
}
|
|
42898
43629
|
};
|
|
42899
43630
|
|
|
@@ -43320,6 +44051,7 @@ var ConfigBuilder = class {
|
|
|
43320
44051
|
k = stringUtils.camelToKebab(k);
|
|
43321
44052
|
const resolvedGroups = resolveGroupReferences(k);
|
|
43322
44053
|
const hasOuterExport = Object.prototype.hasOwnProperty.call(tag, "exportJsonKey");
|
|
44054
|
+
const hasOuterHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
43323
44055
|
if (!hasOuterExport && tag.jsonKey != null) {
|
|
43324
44056
|
const headingPath = [...pathStack, `tags.${tag.key}`].join(" / ");
|
|
43325
44057
|
exportJsonKeyErrors.push(
|
|
@@ -43329,6 +44061,8 @@ var ConfigBuilder = class {
|
|
|
43329
44061
|
for (const ref of resolvedGroups) {
|
|
43330
44062
|
const exportJsonKeyChosen = hasOuterExport ? tag.exportJsonKey : ref.exportJsonKey;
|
|
43331
44063
|
const hasExportChosen = hasOuterExport || !!ref.hasExportJsonKey;
|
|
44064
|
+
const htmlKeyChosen = hasOuterHtml ? tag.htmlKey : ref.htmlKey;
|
|
44065
|
+
const hasHtmlChosen = hasOuterHtml || !!ref.hasHtmlKey;
|
|
43332
44066
|
const min = tag.minCount != null ? tag.minCount : ref.min;
|
|
43333
44067
|
const max = tag.maxCount != null ? tag.maxCount : ref.max;
|
|
43334
44068
|
const description = tag.description ? tag.description : ref.description;
|
|
@@ -43336,6 +44070,7 @@ var ConfigBuilder = class {
|
|
|
43336
44070
|
type: "group",
|
|
43337
44071
|
key: ref.key,
|
|
43338
44072
|
...hasExportChosen ? { jsonKey: exportJsonKeyChosen } : {},
|
|
44073
|
+
...hasHtmlChosen ? { htmlKey: htmlKeyChosen } : {},
|
|
43339
44074
|
...min != null ? { min } : {},
|
|
43340
44075
|
...max != null ? { max } : {},
|
|
43341
44076
|
...description ? { description } : {}
|
|
@@ -43364,10 +44099,13 @@ var ConfigBuilder = class {
|
|
|
43364
44099
|
);
|
|
43365
44100
|
exportJsonKeyField = {};
|
|
43366
44101
|
}
|
|
44102
|
+
const hasHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
44103
|
+
const htmlKeyField = hasHtml ? { htmlKey: tag.htmlKey } : {};
|
|
43367
44104
|
const t = {
|
|
43368
44105
|
type: "tag",
|
|
43369
44106
|
key: tagName,
|
|
43370
44107
|
...exportJsonKeyField,
|
|
44108
|
+
...htmlKeyField,
|
|
43371
44109
|
format,
|
|
43372
44110
|
default: tag.defaultValue ?? null,
|
|
43373
44111
|
...tag.nullable ? { nullable: true } : {},
|
|
@@ -43390,6 +44128,13 @@ var ConfigBuilder = class {
|
|
|
43390
44128
|
);
|
|
43391
44129
|
return {};
|
|
43392
44130
|
};
|
|
44131
|
+
const cardHtmlKeyField = (container, htmlExportKey) => {
|
|
44132
|
+
const c = container;
|
|
44133
|
+
if (Object.prototype.hasOwnProperty.call(c, htmlExportKey)) {
|
|
44134
|
+
return { htmlKey: c[htmlExportKey] };
|
|
44135
|
+
}
|
|
44136
|
+
return {};
|
|
44137
|
+
};
|
|
43393
44138
|
const serializeCardSet = (cardSetKey) => {
|
|
43394
44139
|
const variantBodyFormat = (variant) => variant.format ?? TextFormat.bitmarkText;
|
|
43395
44140
|
const cardSetConfig = CARDSETS[cardSetKey];
|
|
@@ -43420,6 +44165,7 @@ var ConfigBuilder = class {
|
|
|
43420
44165
|
}
|
|
43421
44166
|
return {
|
|
43422
44167
|
...cardJsonKeyField(variant, "jsonKey", "exportJsonKey", variantPath),
|
|
44168
|
+
...cardHtmlKeyField(variant, "htmlKey"),
|
|
43423
44169
|
format: variantBodyFormat(variant),
|
|
43424
44170
|
tags: variantTags,
|
|
43425
44171
|
repeatCount: variant.repeatCount ?? 1,
|
|
@@ -43431,6 +44177,7 @@ var ConfigBuilder = class {
|
|
|
43431
44177
|
name: side.name,
|
|
43432
44178
|
...side.repeat ? { repeat: side.repeat } : {},
|
|
43433
44179
|
...cardJsonKeyField(side, "jsonKey", "exportJsonKey", sidePath),
|
|
44180
|
+
...cardHtmlKeyField(side, "htmlKey"),
|
|
43434
44181
|
variants
|
|
43435
44182
|
};
|
|
43436
44183
|
});
|
|
@@ -43438,20 +44185,23 @@ var ConfigBuilder = class {
|
|
|
43438
44185
|
const cards = Object.entries(cardSetConfig.sections).map(([sectionName, section]) => {
|
|
43439
44186
|
const sectionPath = `cardSets.${normalizedKey} / cards.${sectionName}`;
|
|
43440
44187
|
const hasSideExport = Object.prototype.hasOwnProperty.call(section, "sideExportJsonKey");
|
|
44188
|
+
const hasSideHtml = Object.prototype.hasOwnProperty.call(section, "sideHtmlKey");
|
|
43441
44189
|
let cardSides = sides;
|
|
43442
|
-
if (hasSideExport || section.sideJsonKey != null) {
|
|
44190
|
+
if (hasSideExport || section.sideJsonKey != null || hasSideHtml) {
|
|
43443
44191
|
const sideOverride = cardJsonKeyField(
|
|
43444
44192
|
section,
|
|
43445
44193
|
"sideJsonKey",
|
|
43446
44194
|
"sideExportJsonKey",
|
|
43447
44195
|
`${sectionPath} / sides.*`
|
|
43448
44196
|
);
|
|
43449
|
-
|
|
44197
|
+
const sideHtmlOverride = cardHtmlKeyField(section, "sideHtmlKey");
|
|
44198
|
+
cardSides = sides.map((s) => ({ ...s, ...sideOverride, ...sideHtmlOverride }));
|
|
43450
44199
|
}
|
|
43451
44200
|
return {
|
|
43452
44201
|
name: sectionName,
|
|
43453
44202
|
...section.isDefault ? { isDefault: true } : {},
|
|
43454
44203
|
...cardJsonKeyField(section, "jsonKey", "exportJsonKey", sectionPath),
|
|
44204
|
+
...cardHtmlKeyField(section, "htmlKey"),
|
|
43455
44205
|
// PLAN-085: per-section cardinality. Emit only when non-default
|
|
43456
44206
|
// (treat `0` / undefined as "unbounded — omit").
|
|
43457
44207
|
...section.minCount != null && section.minCount !== 0 ? { min: section.minCount } : {},
|
|
@@ -43459,7 +44209,7 @@ var ConfigBuilder = class {
|
|
|
43459
44209
|
sides: cardSides
|
|
43460
44210
|
};
|
|
43461
44211
|
});
|
|
43462
|
-
return { name: normalizedKey, cards };
|
|
44212
|
+
return { name: normalizedKey, ...cardHtmlKeyField(cardSetConfig, "htmlKey"), cards };
|
|
43463
44213
|
}
|
|
43464
44214
|
const cardSetPath = `cardSets.${normalizedKey} / cards.default`;
|
|
43465
44215
|
return {
|
|
@@ -43469,6 +44219,7 @@ var ConfigBuilder = class {
|
|
|
43469
44219
|
name: "default",
|
|
43470
44220
|
isDefault: true,
|
|
43471
44221
|
...cardJsonKeyField(cardSetConfig, "jsonKey", "exportJsonKey", cardSetPath),
|
|
44222
|
+
...cardHtmlKeyField(cardSetConfig, "htmlKey"),
|
|
43472
44223
|
sides
|
|
43473
44224
|
}
|
|
43474
44225
|
]
|
|
@@ -43508,6 +44259,10 @@ var ConfigBuilder = class {
|
|
|
43508
44259
|
ref.exportJsonKey = t.jsonKey;
|
|
43509
44260
|
ref.hasExportJsonKey = true;
|
|
43510
44261
|
}
|
|
44262
|
+
if (Object.prototype.hasOwnProperty.call(t, "htmlKey")) {
|
|
44263
|
+
ref.htmlKey = t.htmlKey;
|
|
44264
|
+
ref.hasHtmlKey = true;
|
|
44265
|
+
}
|
|
43511
44266
|
replacements.push(ref);
|
|
43512
44267
|
}
|
|
43513
44268
|
squashedGroups.set(groupKey, replacements);
|
|
@@ -43542,6 +44297,7 @@ var ConfigBuilder = class {
|
|
|
43542
44297
|
type: "group",
|
|
43543
44298
|
key: ref.key,
|
|
43544
44299
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44300
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43545
44301
|
...ref.min != null ? { min: ref.min } : {},
|
|
43546
44302
|
...ref.max != null ? { max: ref.max } : {},
|
|
43547
44303
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43555,6 +44311,7 @@ var ConfigBuilder = class {
|
|
|
43555
44311
|
type: "group",
|
|
43556
44312
|
key: ref.key,
|
|
43557
44313
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44314
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43558
44315
|
...ref.min != null ? { min: ref.min } : {},
|
|
43559
44316
|
...ref.max != null ? { max: ref.max } : {},
|
|
43560
44317
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43684,6 +44441,7 @@ var ConfigBuilder = class {
|
|
|
43684
44441
|
type: "group",
|
|
43685
44442
|
key: ref.key,
|
|
43686
44443
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44444
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43687
44445
|
...ref.min != null ? { min: ref.min } : {},
|
|
43688
44446
|
...ref.max != null ? { max: ref.max } : {},
|
|
43689
44447
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43873,499 +44631,6 @@ var ConfigBuilder = class {
|
|
|
43873
44631
|
}
|
|
43874
44632
|
};
|
|
43875
44633
|
|
|
43876
|
-
// src/parser/html/HtmlDom.ts
|
|
43877
|
-
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
43878
|
-
"area",
|
|
43879
|
-
"base",
|
|
43880
|
-
"br",
|
|
43881
|
-
"col",
|
|
43882
|
-
"embed",
|
|
43883
|
-
"hr",
|
|
43884
|
-
"img",
|
|
43885
|
-
"input",
|
|
43886
|
-
"link",
|
|
43887
|
-
"meta",
|
|
43888
|
-
"param",
|
|
43889
|
-
"source",
|
|
43890
|
-
"track",
|
|
43891
|
-
"wbr"
|
|
43892
|
-
]);
|
|
43893
|
-
var IMPLIED_CLOSE = {
|
|
43894
|
-
li: /* @__PURE__ */ new Set(["li"]),
|
|
43895
|
-
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43896
|
-
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43897
|
-
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
43898
|
-
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43899
|
-
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43900
|
-
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43901
|
-
p: /* @__PURE__ */ new Set(["p"]),
|
|
43902
|
-
option: /* @__PURE__ */ new Set(["option"])
|
|
43903
|
-
};
|
|
43904
|
-
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
43905
|
-
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
43906
|
-
function parseAttrs(raw) {
|
|
43907
|
-
const attrs = {};
|
|
43908
|
-
if (!raw) return attrs;
|
|
43909
|
-
ATTR_RE.lastIndex = 0;
|
|
43910
|
-
let m;
|
|
43911
|
-
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
43912
|
-
const name = m[1].toLowerCase();
|
|
43913
|
-
let value = m[2] ?? "";
|
|
43914
|
-
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
43915
|
-
value = value.slice(1, -1);
|
|
43916
|
-
}
|
|
43917
|
-
attrs[name] = value;
|
|
43918
|
-
}
|
|
43919
|
-
return attrs;
|
|
43920
|
-
}
|
|
43921
|
-
function stripNonContent(html) {
|
|
43922
|
-
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, "");
|
|
43923
|
-
}
|
|
43924
|
-
function tokenize(html) {
|
|
43925
|
-
const tokens = [];
|
|
43926
|
-
const clean = stripNonContent(html);
|
|
43927
|
-
TAG_RE.lastIndex = 0;
|
|
43928
|
-
let lastIndex = 0;
|
|
43929
|
-
let m;
|
|
43930
|
-
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
43931
|
-
if (m.index > lastIndex) {
|
|
43932
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
43933
|
-
}
|
|
43934
|
-
lastIndex = TAG_RE.lastIndex;
|
|
43935
|
-
const isClose = m[1] === "/";
|
|
43936
|
-
const name = m[2].toLowerCase();
|
|
43937
|
-
if (isClose) {
|
|
43938
|
-
tokens.push({ kind: "close", name });
|
|
43939
|
-
} else {
|
|
43940
|
-
tokens.push({
|
|
43941
|
-
kind: "open",
|
|
43942
|
-
name,
|
|
43943
|
-
attrs: parseAttrs(m[3]),
|
|
43944
|
-
selfClose: m[4] === "/"
|
|
43945
|
-
});
|
|
43946
|
-
}
|
|
43947
|
-
}
|
|
43948
|
-
if (lastIndex < clean.length) {
|
|
43949
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
43950
|
-
}
|
|
43951
|
-
return tokens;
|
|
43952
|
-
}
|
|
43953
|
-
function parseHtml(html) {
|
|
43954
|
-
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
43955
|
-
const stack = [root];
|
|
43956
|
-
const top = () => stack[stack.length - 1];
|
|
43957
|
-
for (const token of tokenize(html)) {
|
|
43958
|
-
if (token.kind === "text") {
|
|
43959
|
-
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
43960
|
-
continue;
|
|
43961
|
-
}
|
|
43962
|
-
if (token.kind === "open") {
|
|
43963
|
-
const name = token.name;
|
|
43964
|
-
const closes = IMPLIED_CLOSE[name];
|
|
43965
|
-
if (closes) {
|
|
43966
|
-
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
43967
|
-
}
|
|
43968
|
-
const el = {
|
|
43969
|
-
type: "element",
|
|
43970
|
-
name,
|
|
43971
|
-
attrs: token.attrs ?? {},
|
|
43972
|
-
children: []
|
|
43973
|
-
};
|
|
43974
|
-
top().children.push(el);
|
|
43975
|
-
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
43976
|
-
stack.push(el);
|
|
43977
|
-
}
|
|
43978
|
-
continue;
|
|
43979
|
-
}
|
|
43980
|
-
for (let i = stack.length - 1; i > 0; i--) {
|
|
43981
|
-
if (stack[i].name === token.name) {
|
|
43982
|
-
stack.length = i;
|
|
43983
|
-
break;
|
|
43984
|
-
}
|
|
43985
|
-
}
|
|
43986
|
-
}
|
|
43987
|
-
return root.children;
|
|
43988
|
-
}
|
|
43989
|
-
function childElements(el, names) {
|
|
43990
|
-
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43991
|
-
}
|
|
43992
|
-
|
|
43993
|
-
// src/parser/html/HtmlTableParser.ts
|
|
43994
|
-
var MARK_TAGS = {
|
|
43995
|
-
b: "bold",
|
|
43996
|
-
strong: "bold",
|
|
43997
|
-
i: "italic",
|
|
43998
|
-
em: "italic",
|
|
43999
|
-
sup: "superscript",
|
|
44000
|
-
sub: "subscript",
|
|
44001
|
-
s: "strike",
|
|
44002
|
-
strike: "strike",
|
|
44003
|
-
del: "del",
|
|
44004
|
-
ins: "ins",
|
|
44005
|
-
u: "underline",
|
|
44006
|
-
mark: "highlight",
|
|
44007
|
-
code: "code"
|
|
44008
|
-
};
|
|
44009
|
-
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
44010
|
-
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
44011
|
-
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
44012
|
-
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
44013
|
-
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
44014
|
-
var NAMED_ENTITIES = {
|
|
44015
|
-
amp: "&",
|
|
44016
|
-
lt: "<",
|
|
44017
|
-
gt: ">",
|
|
44018
|
-
quot: '"',
|
|
44019
|
-
apos: "'",
|
|
44020
|
-
nbsp: "\xA0"
|
|
44021
|
-
};
|
|
44022
|
-
function decodeEntities(text) {
|
|
44023
|
-
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
44024
|
-
if (body[0] === "#") {
|
|
44025
|
-
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
44026
|
-
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
44027
|
-
try {
|
|
44028
|
-
return String.fromCodePoint(code);
|
|
44029
|
-
} catch {
|
|
44030
|
-
return whole;
|
|
44031
|
-
}
|
|
44032
|
-
}
|
|
44033
|
-
return whole;
|
|
44034
|
-
}
|
|
44035
|
-
return NAMED_ENTITIES[body] ?? whole;
|
|
44036
|
-
});
|
|
44037
|
-
}
|
|
44038
|
-
function intAttr(value) {
|
|
44039
|
-
if (value == null) return void 0;
|
|
44040
|
-
const n = Number.parseInt(value, 10);
|
|
44041
|
-
return Number.isInteger(n) ? n : void 0;
|
|
44042
|
-
}
|
|
44043
|
-
function isElement(node) {
|
|
44044
|
-
return node.type === "element";
|
|
44045
|
-
}
|
|
44046
|
-
var HtmlTableParser = class {
|
|
44047
|
-
constructor() {
|
|
44048
|
-
__publicField(this, "keepUnknownTags", false);
|
|
44049
|
-
}
|
|
44050
|
-
/**
|
|
44051
|
-
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
44052
|
-
*/
|
|
44053
|
-
parse(html, options) {
|
|
44054
|
-
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
44055
|
-
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
44056
|
-
const onWarning = options?.onWarning;
|
|
44057
|
-
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
44058
|
-
const bits = [];
|
|
44059
|
-
for (const table of tables) {
|
|
44060
|
-
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
44061
|
-
if (bit) bits.push(bit);
|
|
44062
|
-
}
|
|
44063
|
-
return bits;
|
|
44064
|
-
}
|
|
44065
|
-
// --- table extraction -----------------------------------------------------
|
|
44066
|
-
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
44067
|
-
collectTopLevelTables(nodes) {
|
|
44068
|
-
const tables = [];
|
|
44069
|
-
const visit = (node) => {
|
|
44070
|
-
if (!isElement(node)) return;
|
|
44071
|
-
if (node.name === "table") {
|
|
44072
|
-
tables.push(node);
|
|
44073
|
-
return;
|
|
44074
|
-
}
|
|
44075
|
-
node.children.forEach(visit);
|
|
44076
|
-
};
|
|
44077
|
-
nodes.forEach(visit);
|
|
44078
|
-
return tables;
|
|
44079
|
-
}
|
|
44080
|
-
tableToBit(table, tableFormat, onWarning) {
|
|
44081
|
-
const header = [];
|
|
44082
|
-
const body = [];
|
|
44083
|
-
const footer = [];
|
|
44084
|
-
let caption;
|
|
44085
|
-
for (const child of table.children) {
|
|
44086
|
-
if (!isElement(child)) continue;
|
|
44087
|
-
if (child.name === "caption") {
|
|
44088
|
-
const capContent = this.inlineNodes(child.children, []);
|
|
44089
|
-
const trimmed = this.trimInline(capContent);
|
|
44090
|
-
if (trimmed.length > 0) caption = trimmed;
|
|
44091
|
-
} else if (SECTION_TAGS.has(child.name)) {
|
|
44092
|
-
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
44093
|
-
for (const tr of childElements(child, ROW_TAGS)) {
|
|
44094
|
-
target.push(this.rowToCells(tr));
|
|
44095
|
-
}
|
|
44096
|
-
} else if (ROW_TAGS.has(child.name)) {
|
|
44097
|
-
body.push(this.rowToCells(child));
|
|
44098
|
-
}
|
|
44099
|
-
}
|
|
44100
|
-
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
44101
|
-
return void 0;
|
|
44102
|
-
}
|
|
44103
|
-
const tableExtended = {};
|
|
44104
|
-
if (header.length > 0) tableExtended.header = { rows: header };
|
|
44105
|
-
if (body.length > 0) tableExtended.body = { rows: body };
|
|
44106
|
-
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
44107
|
-
let tableData = tableExtended;
|
|
44108
|
-
if (tableFormat === "table") {
|
|
44109
|
-
if (this.isLossyAsBasic(tableExtended)) {
|
|
44110
|
-
onWarning?.(
|
|
44111
|
-
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
44112
|
-
);
|
|
44113
|
-
}
|
|
44114
|
-
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
44115
|
-
}
|
|
44116
|
-
const bit = {
|
|
44117
|
-
type: tableFormat,
|
|
44118
|
-
format: "bitmark++",
|
|
44119
|
-
table: tableData
|
|
44120
|
-
};
|
|
44121
|
-
if (caption) bit.caption = caption;
|
|
44122
|
-
return bit;
|
|
44123
|
-
}
|
|
44124
|
-
rowToCells(tr) {
|
|
44125
|
-
const cells = [];
|
|
44126
|
-
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
44127
|
-
cells.push(this.cellToJson(cell));
|
|
44128
|
-
}
|
|
44129
|
-
return { cells };
|
|
44130
|
-
}
|
|
44131
|
-
cellToJson(cell) {
|
|
44132
|
-
const json = {
|
|
44133
|
-
content: this.blockNodes(cell.children)
|
|
44134
|
-
};
|
|
44135
|
-
if (cell.name === "th") json.title = true;
|
|
44136
|
-
const rowspan = intAttr(cell.attrs.rowspan);
|
|
44137
|
-
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
44138
|
-
const colspan = intAttr(cell.attrs.colspan);
|
|
44139
|
-
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
44140
|
-
const scope = cell.attrs.scope?.toLowerCase();
|
|
44141
|
-
if (scope && VALID_SCOPES.has(scope)) {
|
|
44142
|
-
json.scope = scope;
|
|
44143
|
-
}
|
|
44144
|
-
const width = this.widthFromCell(cell);
|
|
44145
|
-
if (width != null) json.colwidth = width;
|
|
44146
|
-
return json;
|
|
44147
|
-
}
|
|
44148
|
-
widthFromCell(cell) {
|
|
44149
|
-
const attrWidth = intAttr(cell.attrs.width);
|
|
44150
|
-
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
44151
|
-
const style = cell.attrs.style;
|
|
44152
|
-
if (style) {
|
|
44153
|
-
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
44154
|
-
if (m) {
|
|
44155
|
-
const n = Number.parseInt(m[1], 10);
|
|
44156
|
-
if (Number.isInteger(n) && n > 0) return n;
|
|
44157
|
-
}
|
|
44158
|
-
}
|
|
44159
|
-
return void 0;
|
|
44160
|
-
}
|
|
44161
|
-
isLossyAsBasic(table) {
|
|
44162
|
-
if (table.footer) return true;
|
|
44163
|
-
if (table.header && table.header.rows.length > 1) return true;
|
|
44164
|
-
const sections = [table.header, table.body, table.footer];
|
|
44165
|
-
for (const section of sections) {
|
|
44166
|
-
if (!section) continue;
|
|
44167
|
-
for (const row of section.rows) {
|
|
44168
|
-
for (const cell of row.cells) {
|
|
44169
|
-
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
44170
|
-
}
|
|
44171
|
-
}
|
|
44172
|
-
}
|
|
44173
|
-
return false;
|
|
44174
|
-
}
|
|
44175
|
-
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
44176
|
-
/**
|
|
44177
|
-
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
44178
|
-
*/
|
|
44179
|
-
blockNodes(nodes) {
|
|
44180
|
-
const blocks = [];
|
|
44181
|
-
let inline = [];
|
|
44182
|
-
const flush = () => {
|
|
44183
|
-
const trimmed = this.trimInline(inline);
|
|
44184
|
-
inline = [];
|
|
44185
|
-
if (trimmed.length === 0) return;
|
|
44186
|
-
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
44187
|
-
blocks.push({ ...trimmed[0], type: "image" });
|
|
44188
|
-
} else {
|
|
44189
|
-
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
44190
|
-
}
|
|
44191
|
-
};
|
|
44192
|
-
for (const node of nodes) {
|
|
44193
|
-
if (!isElement(node)) {
|
|
44194
|
-
inline.push(...this.inlineText(node.value, []));
|
|
44195
|
-
continue;
|
|
44196
|
-
}
|
|
44197
|
-
const name = node.name;
|
|
44198
|
-
if (name === "p") {
|
|
44199
|
-
flush();
|
|
44200
|
-
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
44201
|
-
if (content.length > 0) {
|
|
44202
|
-
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
44203
|
-
}
|
|
44204
|
-
} else if (this.isListTag(name)) {
|
|
44205
|
-
flush();
|
|
44206
|
-
const list = this.listNode(node);
|
|
44207
|
-
if (list) blocks.push(list);
|
|
44208
|
-
} else {
|
|
44209
|
-
inline.push(...this.inlineFromElement(node, []));
|
|
44210
|
-
}
|
|
44211
|
-
}
|
|
44212
|
-
flush();
|
|
44213
|
-
return blocks;
|
|
44214
|
-
}
|
|
44215
|
-
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
44216
|
-
inlineNodes(nodes, marks) {
|
|
44217
|
-
const out = [];
|
|
44218
|
-
for (const node of nodes) {
|
|
44219
|
-
if (!isElement(node)) {
|
|
44220
|
-
out.push(...this.inlineText(node.value, marks));
|
|
44221
|
-
} else {
|
|
44222
|
-
out.push(...this.inlineFromElement(node, marks));
|
|
44223
|
-
}
|
|
44224
|
-
}
|
|
44225
|
-
return out;
|
|
44226
|
-
}
|
|
44227
|
-
inlineFromElement(el, marks) {
|
|
44228
|
-
const name = el.name;
|
|
44229
|
-
if (name === "br") {
|
|
44230
|
-
return [{ type: "hardBreak" }];
|
|
44231
|
-
}
|
|
44232
|
-
if (name === "img") {
|
|
44233
|
-
return [this.imageNode(el, true)];
|
|
44234
|
-
}
|
|
44235
|
-
const markType = MARK_TAGS[name];
|
|
44236
|
-
if (markType) {
|
|
44237
|
-
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
44238
|
-
}
|
|
44239
|
-
if (name === "a") {
|
|
44240
|
-
const linkMark = {
|
|
44241
|
-
type: "link",
|
|
44242
|
-
attrs: {
|
|
44243
|
-
href: el.attrs.href ?? "",
|
|
44244
|
-
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
44245
|
-
}
|
|
44246
|
-
};
|
|
44247
|
-
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
44248
|
-
}
|
|
44249
|
-
if (this.keepUnknownTags) {
|
|
44250
|
-
const open = this.serializeOpenTag(el);
|
|
44251
|
-
const close = `</${name}>`;
|
|
44252
|
-
return [
|
|
44253
|
-
...this.inlineText(open, marks),
|
|
44254
|
-
...this.inlineNodes(el.children, marks),
|
|
44255
|
-
...this.inlineText(close, marks)
|
|
44256
|
-
];
|
|
44257
|
-
}
|
|
44258
|
-
return this.inlineNodes(el.children, marks);
|
|
44259
|
-
}
|
|
44260
|
-
inlineText(raw, marks) {
|
|
44261
|
-
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
44262
|
-
if (text === "") return [];
|
|
44263
|
-
const node = { text, type: "text" };
|
|
44264
|
-
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
44265
|
-
return [node];
|
|
44266
|
-
}
|
|
44267
|
-
serializeOpenTag(el) {
|
|
44268
|
-
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
44269
|
-
return `<${el.name}${attrs}>`;
|
|
44270
|
-
}
|
|
44271
|
-
// --- lists ----------------------------------------------------------------
|
|
44272
|
-
isListTag(name) {
|
|
44273
|
-
return name === "ul" || name === "ol";
|
|
44274
|
-
}
|
|
44275
|
-
listNode(el) {
|
|
44276
|
-
const items = childElements(el, LI_TAGS);
|
|
44277
|
-
if (items.length === 0) return void 0;
|
|
44278
|
-
const isTask = el.name === "ul" && items.some((li) => {
|
|
44279
|
-
const firstEl = li.children.find(isElement);
|
|
44280
|
-
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
44281
|
-
});
|
|
44282
|
-
if (isTask) {
|
|
44283
|
-
return {
|
|
44284
|
-
type: "taskList",
|
|
44285
|
-
content: items.map((li) => this.taskItemNode(li))
|
|
44286
|
-
};
|
|
44287
|
-
}
|
|
44288
|
-
const type = this.listType(el);
|
|
44289
|
-
const node = {
|
|
44290
|
-
type,
|
|
44291
|
-
content: items.map((li) => this.listItemNode(li))
|
|
44292
|
-
};
|
|
44293
|
-
if (el.name === "ol") {
|
|
44294
|
-
const start = intAttr(el.attrs.start);
|
|
44295
|
-
if (start != null) {
|
|
44296
|
-
node.attrs = { start };
|
|
44297
|
-
}
|
|
44298
|
-
}
|
|
44299
|
-
return node;
|
|
44300
|
-
}
|
|
44301
|
-
listType(el) {
|
|
44302
|
-
if (el.name === "ol") {
|
|
44303
|
-
switch (el.attrs.type) {
|
|
44304
|
-
case "i":
|
|
44305
|
-
return "orderedListRomanLower";
|
|
44306
|
-
case "I":
|
|
44307
|
-
return "orderedListRoman";
|
|
44308
|
-
case "a":
|
|
44309
|
-
return "letteredListLower";
|
|
44310
|
-
case "A":
|
|
44311
|
-
return "letteredList";
|
|
44312
|
-
default:
|
|
44313
|
-
return "orderedList";
|
|
44314
|
-
}
|
|
44315
|
-
}
|
|
44316
|
-
const style = el.attrs.style ?? "";
|
|
44317
|
-
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
44318
|
-
return "bulletList";
|
|
44319
|
-
}
|
|
44320
|
-
listItemNode(li) {
|
|
44321
|
-
let content = this.blockNodes(li.children);
|
|
44322
|
-
if (content.length === 0) {
|
|
44323
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
44324
|
-
}
|
|
44325
|
-
return { type: "listItem", content };
|
|
44326
|
-
}
|
|
44327
|
-
taskItemNode(li) {
|
|
44328
|
-
const checkbox = li.children.find(
|
|
44329
|
-
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
44330
|
-
);
|
|
44331
|
-
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
44332
|
-
const rest = li.children.filter((c) => c !== checkbox);
|
|
44333
|
-
let content = this.blockNodes(rest);
|
|
44334
|
-
if (content.length === 0) {
|
|
44335
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
44336
|
-
}
|
|
44337
|
-
return { type: "taskItem", attrs: { checked }, content };
|
|
44338
|
-
}
|
|
44339
|
-
// --- images ---------------------------------------------------------------
|
|
44340
|
-
imageNode(el, inline) {
|
|
44341
|
-
const attrs = { src: el.attrs.src ?? "" };
|
|
44342
|
-
attrs.alt = el.attrs.alt ?? null;
|
|
44343
|
-
attrs.title = el.attrs.title ?? null;
|
|
44344
|
-
const width = intAttr(el.attrs.width);
|
|
44345
|
-
if (width != null) attrs.width = width;
|
|
44346
|
-
const height = intAttr(el.attrs.height);
|
|
44347
|
-
if (height != null) attrs.height = height;
|
|
44348
|
-
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
44349
|
-
return { type: inline ? "imageInline" : "image", attrs };
|
|
44350
|
-
}
|
|
44351
|
-
// --- whitespace -----------------------------------------------------------
|
|
44352
|
-
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
44353
|
-
trimInline(nodes) {
|
|
44354
|
-
const out = nodes.slice();
|
|
44355
|
-
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
44356
|
-
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
44357
|
-
if (out.length > 0 && out[0].type === "text") {
|
|
44358
|
-
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
44359
|
-
}
|
|
44360
|
-
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
44361
|
-
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
44362
|
-
const last = out.length - 1;
|
|
44363
|
-
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
44364
|
-
}
|
|
44365
|
-
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
44366
|
-
}
|
|
44367
|
-
};
|
|
44368
|
-
|
|
44369
44634
|
// src/BitmarkParserGenerator.ts
|
|
44370
44635
|
var Input = {
|
|
44371
44636
|
/**
|