@gmb/bitmark-parser-generator 5.26.0 → 5.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/bitmark-parser-generator.min.js +1 -1
- package/dist/browser/bundle-report.html +2 -2
- package/dist/browser/cjs/index.cjs +1124 -748
- package/dist/browser/cjs/index.cjs.map +1 -1
- package/dist/browser/cjs/index.d.cts +151 -63
- package/dist/browser/esm/index.d.ts +151 -63
- package/dist/browser/esm/index.js +1124 -748
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/cli/main.js +1153 -747
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +1152 -749
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +151 -63
- package/dist/index.d.ts +151 -63
- package/dist/index.js +1152 -749
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
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
|
}
|
|
@@ -1387,6 +1430,8 @@ var propertyKeys = {
|
|
|
1387
1430
|
property_externalLinkText: "@externalLinkText",
|
|
1388
1431
|
property_feedbackEngine: "@feedbackEngine",
|
|
1389
1432
|
property_feedbackType: "@feedbackType",
|
|
1433
|
+
property_userFeedbackTranslationUrl: "@userFeedbackTranslationUrl",
|
|
1434
|
+
property_userFeedbackContentUrl: "@userFeedbackContentUrl",
|
|
1390
1435
|
property_flashcardSet: "@flashcardSet",
|
|
1391
1436
|
property_focusX: "@focusX",
|
|
1392
1437
|
property_focusY: "@focusY",
|
|
@@ -3770,6 +3815,16 @@ var CARDSETS = {
|
|
|
3770
3815
|
[CardSetConfigKey.table]: {
|
|
3771
3816
|
jsonKey: null,
|
|
3772
3817
|
exportJsonKey: null,
|
|
3818
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping. The classic (non-extended)
|
|
3819
|
+
// table produces the same `<table>`/`<thead>`/`<tbody>`/`<tfoot>` structure as
|
|
3820
|
+
// table-extended, so the structural htmlKeys mirror that cardSet. NOTE: the
|
|
3821
|
+
// JSON side routes the FIRST header card → `columns` (header) and SUBSEQUENT
|
|
3822
|
+
// header cards → `data` (body); HTML uses a uniform `<thead>` for the whole
|
|
3823
|
+
// `table-header` section, so a multi-card header (e.g. a second header card
|
|
3824
|
+
// that JSON sends to `data`) renders as additional `<thead>` rows rather than
|
|
3825
|
+
// moving to `<tbody>`. Per-card header/body splitting needs engine-level
|
|
3826
|
+
// routing not yet expressible in the pattern vocabulary — see PLAN-109.
|
|
3827
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3773
3828
|
sections: {
|
|
3774
3829
|
"table-header": {
|
|
3775
3830
|
// First header card's row of cells → `columns`. Subsequent header
|
|
@@ -3788,25 +3843,36 @@ var CARDSETS = {
|
|
|
3788
3843
|
},
|
|
3789
3844
|
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3790
3845
|
{ "@bit": { table: { data: ["$"] } } }
|
|
3791
|
-
]
|
|
3846
|
+
],
|
|
3847
|
+
// Header section → `<thead>` rows of `<th>`; `@tableColWidth` bubbles a
|
|
3848
|
+
// `width` attr onto the enclosing `<th>` (HTML-C2).
|
|
3849
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3850
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3792
3851
|
},
|
|
3793
3852
|
"table-body": {
|
|
3794
3853
|
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3795
3854
|
// This is the default section (no qualifier → cards land here).
|
|
3796
3855
|
jsonKey: "table.data",
|
|
3797
3856
|
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3857
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3798
3858
|
isDefault: true
|
|
3799
3859
|
},
|
|
3800
3860
|
"table-footer": {
|
|
3801
3861
|
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3802
3862
|
jsonKey: "table.data",
|
|
3803
|
-
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3863
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3864
|
+
// Footer cells route to `data` (not `columns`), so they are `<td>` (no
|
|
3865
|
+
// sideHtmlKey override — the cell side default applies).
|
|
3866
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } }
|
|
3804
3867
|
}
|
|
3805
3868
|
},
|
|
3806
3869
|
sides: [
|
|
3807
3870
|
{
|
|
3808
3871
|
name: "cell",
|
|
3809
3872
|
repeat: true,
|
|
3873
|
+
// Default (body/footer) cell → `<td>`; the header section overrides to
|
|
3874
|
+
// `<th>` via its sideHtmlKey (HTML.md §8).
|
|
3875
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3810
3876
|
variants: [
|
|
3811
3877
|
{
|
|
3812
3878
|
jsonKey: null,
|
|
@@ -3823,21 +3889,32 @@ var CARDSETS = {
|
|
|
3823
3889
|
},
|
|
3824
3890
|
{
|
|
3825
3891
|
key: ConfigKey.property_tableCellType,
|
|
3892
|
+
// HTML.md §8: first-match predicate selecting `<th>` vs `<td>`.
|
|
3893
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3826
3894
|
description: "Table cell type (th/td).",
|
|
3827
3895
|
format: TagFormat.plainText
|
|
3828
3896
|
},
|
|
3829
3897
|
{
|
|
3830
3898
|
key: ConfigKey.property_tableRowSpan,
|
|
3899
|
+
// HTML-C2: contribute a `rowspan` attribute onto the enclosing
|
|
3900
|
+
// cell element (`<th>`/`<td>`).
|
|
3901
|
+
htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
|
|
3831
3902
|
description: "Number of rows the cell spans.",
|
|
3832
3903
|
format: TagFormat.number
|
|
3833
3904
|
},
|
|
3834
3905
|
{
|
|
3835
3906
|
key: ConfigKey.property_tableColSpan,
|
|
3907
|
+
// HTML-C2: contribute a `colspan` attribute onto the enclosing
|
|
3908
|
+
// cell element (`<th>`/`<td>`).
|
|
3909
|
+
htmlKey: { "@el": { "@attr": { colspan: "$" } } },
|
|
3836
3910
|
description: "Number of columns the cell spans.",
|
|
3837
3911
|
format: TagFormat.number
|
|
3838
3912
|
},
|
|
3839
3913
|
{
|
|
3840
3914
|
key: ConfigKey.property_tableScope,
|
|
3915
|
+
// HTML-C2: contribute a `scope` attribute onto the enclosing
|
|
3916
|
+
// cell element (`<th>`/`<td>`).
|
|
3917
|
+
htmlKey: { "@el": { "@attr": { scope: "$" } } },
|
|
3841
3918
|
description: "Scope attribute for header cells.",
|
|
3842
3919
|
format: TagFormat.plainText
|
|
3843
3920
|
},
|
|
@@ -3845,6 +3922,9 @@ var CARDSETS = {
|
|
|
3845
3922
|
key: ConfigKey.property_tableColWidth,
|
|
3846
3923
|
jsonKey: "^table.columnWidths[{s}]",
|
|
3847
3924
|
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
3925
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3926
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3927
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3848
3928
|
description: "Width for the column.",
|
|
3849
3929
|
format: TagFormat.number
|
|
3850
3930
|
}
|
|
@@ -3860,6 +3940,12 @@ var CARDSETS = {
|
|
|
3860
3940
|
//
|
|
3861
3941
|
[CardSetConfigKey.tableExtended]: {
|
|
3862
3942
|
jsonKey: null,
|
|
3943
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping for the extended table.
|
|
3944
|
+
// The card-set container is the `<table>` element; each section is a
|
|
3945
|
+
// table section element (`<thead>`/`<tbody>`/`<tfoot>`) whose children are
|
|
3946
|
+
// `<tr>` rows, and each cell side is a `<td>` (body) or `<th>` (header /
|
|
3947
|
+
// footer, via the section sideHtmlKey override).
|
|
3948
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3863
3949
|
sections: {
|
|
3864
3950
|
"table-header": {
|
|
3865
3951
|
jsonKey: "table.header.rows",
|
|
@@ -3879,19 +3965,29 @@ var CARDSETS = {
|
|
|
3879
3965
|
},
|
|
3880
3966
|
{ table: { header: { rows: ["$"] } } }
|
|
3881
3967
|
],
|
|
3968
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3882
3969
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3883
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3970
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3971
|
+
// Header cells are `<th>`. The `width` attribute is contributed by the
|
|
3972
|
+
// `@tableColWidth` tag, which bubbles it onto the enclosing `<th>`
|
|
3973
|
+
// (HTML-C2) — so it is not repeated here.
|
|
3974
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3884
3975
|
},
|
|
3885
3976
|
"table-body": {
|
|
3886
3977
|
jsonKey: "table.body.rows",
|
|
3887
3978
|
exportJsonKey: { table: { body: { rows: "$" } } },
|
|
3979
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3888
3980
|
isDefault: true
|
|
3889
3981
|
},
|
|
3890
3982
|
"table-footer": {
|
|
3891
3983
|
jsonKey: "table.footer.rows",
|
|
3892
3984
|
exportJsonKey: { table: { footer: { rows: "$" } } },
|
|
3985
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
|
|
3893
3986
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3894
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3987
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3988
|
+
// Footer cells render as `<th>` (mirrors the header `title: true`
|
|
3989
|
+
// mapping); §8 lists only the header side, so this parallels it.
|
|
3990
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3895
3991
|
}
|
|
3896
3992
|
},
|
|
3897
3993
|
sides: [
|
|
@@ -3900,6 +3996,9 @@ var CARDSETS = {
|
|
|
3900
3996
|
repeat: true,
|
|
3901
3997
|
jsonKey: "cells[{s}]",
|
|
3902
3998
|
exportJsonKey: { cells: { $s: "$" } },
|
|
3999
|
+
// Default (body) cell → `<td>`; the header/footer sections override the
|
|
4000
|
+
// side to `<th>` via their sideHtmlKey (HTML.md §8).
|
|
4001
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3903
4002
|
variants: [
|
|
3904
4003
|
{
|
|
3905
4004
|
jsonKey: "content",
|
|
@@ -3923,6 +4022,9 @@ var CARDSETS = {
|
|
|
3923
4022
|
key: ConfigKey.property_tableCellType,
|
|
3924
4023
|
jsonKey: "title|bool(th)",
|
|
3925
4024
|
exportJsonKey: [{ "@value=th": { title: true } }],
|
|
4025
|
+
// HTML.md §8: same first-match predicate machinery selecting
|
|
4026
|
+
// `<th>` vs `<td>` instead of `title:true` vs nothing.
|
|
4027
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3926
4028
|
description: "Table cell type (th/td).",
|
|
3927
4029
|
format: TagFormat.plainText
|
|
3928
4030
|
},
|
|
@@ -3930,6 +4032,9 @@ var CARDSETS = {
|
|
|
3930
4032
|
key: ConfigKey.property_tableRowSpan,
|
|
3931
4033
|
jsonKey: "rowspan",
|
|
3932
4034
|
exportJsonKey: { rowspan: "$" },
|
|
4035
|
+
// HTML-C2: contribute a `rowspan` attribute onto the enclosing
|
|
4036
|
+
// cell element (`<th>`/`<td>`).
|
|
4037
|
+
htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
|
|
3933
4038
|
description: "Number of rows the cell spans.",
|
|
3934
4039
|
format: TagFormat.number
|
|
3935
4040
|
},
|
|
@@ -3937,6 +4042,9 @@ var CARDSETS = {
|
|
|
3937
4042
|
key: ConfigKey.property_tableColSpan,
|
|
3938
4043
|
jsonKey: "colspan",
|
|
3939
4044
|
exportJsonKey: { colspan: "$" },
|
|
4045
|
+
// HTML-C2: contribute a `colspan` attribute onto the enclosing
|
|
4046
|
+
// cell element (`<th>`/`<td>`).
|
|
4047
|
+
htmlKey: { "@el": { "@attr": { colspan: "$" } } },
|
|
3940
4048
|
description: "Number of columns the cell spans.",
|
|
3941
4049
|
format: TagFormat.number
|
|
3942
4050
|
},
|
|
@@ -3944,6 +4052,9 @@ var CARDSETS = {
|
|
|
3944
4052
|
key: ConfigKey.property_tableScope,
|
|
3945
4053
|
jsonKey: "scope",
|
|
3946
4054
|
exportJsonKey: { scope: "$" },
|
|
4055
|
+
// HTML-C2: contribute a `scope` attribute onto the enclosing
|
|
4056
|
+
// cell element (`<th>`/`<td>`).
|
|
4057
|
+
htmlKey: { "@el": { "@attr": { scope: "$" } } },
|
|
3947
4058
|
description: "Scope attribute for header cells.",
|
|
3948
4059
|
format: TagFormat.plainText
|
|
3949
4060
|
},
|
|
@@ -3952,6 +4063,9 @@ var CARDSETS = {
|
|
|
3952
4063
|
// PLAN-080: write to the cell's `colwidth` field.
|
|
3953
4064
|
jsonKey: "colwidth",
|
|
3954
4065
|
exportJsonKey: { colwidth: "$" },
|
|
4066
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
4067
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
4068
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3955
4069
|
description: "Width for the column.",
|
|
3956
4070
|
format: TagFormat.number
|
|
3957
4071
|
}
|
|
@@ -5751,6 +5865,16 @@ var GROUPS = {
|
|
|
5751
5865
|
description: "External Id of the translated book",
|
|
5752
5866
|
format: TagFormat.plainText
|
|
5753
5867
|
},
|
|
5868
|
+
{
|
|
5869
|
+
key: ConfigKey.property_userFeedbackTranslationUrl,
|
|
5870
|
+
description: "URL to an external feedback form for book translation feedback",
|
|
5871
|
+
format: TagFormat.plainText
|
|
5872
|
+
},
|
|
5873
|
+
{
|
|
5874
|
+
key: ConfigKey.property_userFeedbackContentUrl,
|
|
5875
|
+
description: "URL to an external feedback form for book content feedback",
|
|
5876
|
+
format: TagFormat.plainText
|
|
5877
|
+
},
|
|
5754
5878
|
{
|
|
5755
5879
|
key: ConfigKey.property_duration,
|
|
5756
5880
|
description: "The duration of the book",
|
|
@@ -6880,7 +7004,9 @@ var ConfigHydrator = class {
|
|
|
6880
7004
|
variantsOfSide,
|
|
6881
7005
|
_side.jsonKey,
|
|
6882
7006
|
_side.exportJsonKey,
|
|
6883
|
-
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
|
|
7007
|
+
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey"),
|
|
7008
|
+
_side.htmlKey,
|
|
7009
|
+
Object.prototype.hasOwnProperty.call(_side, "htmlKey")
|
|
6884
7010
|
);
|
|
6885
7011
|
sides.push(sideConfig);
|
|
6886
7012
|
}
|
|
@@ -6890,7 +7016,9 @@ var ConfigHydrator = class {
|
|
|
6890
7016
|
_cardSetConfig.exportJsonKey,
|
|
6891
7017
|
Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
|
|
6892
7018
|
this.hydrateCardSections(_cardSetConfig.sections),
|
|
6893
|
-
sides
|
|
7019
|
+
sides,
|
|
7020
|
+
_cardSetConfig.htmlKey,
|
|
7021
|
+
Object.prototype.hasOwnProperty.call(_cardSetConfig, "htmlKey")
|
|
6894
7022
|
);
|
|
6895
7023
|
return cardSetConfig;
|
|
6896
7024
|
}
|
|
@@ -6902,10 +7030,14 @@ var ConfigHydrator = class {
|
|
|
6902
7030
|
jsonKey: v.jsonKey,
|
|
6903
7031
|
exportJsonKey: v.exportJsonKey,
|
|
6904
7032
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
|
|
7033
|
+
htmlKey: v.htmlKey,
|
|
7034
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(v, "htmlKey"),
|
|
6905
7035
|
isDefault: v.isDefault,
|
|
6906
7036
|
sideJsonKey: v.sideJsonKey,
|
|
6907
7037
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
6908
7038
|
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
7039
|
+
sideHtmlKey: v.sideHtmlKey,
|
|
7040
|
+
hasSideHtmlKey: Object.prototype.hasOwnProperty.call(v, "sideHtmlKey"),
|
|
6909
7041
|
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6910
7042
|
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6911
7043
|
// as unbounded).
|
|
@@ -6923,7 +7055,8 @@ var ConfigHydrator = class {
|
|
|
6923
7055
|
chain: _chain,
|
|
6924
7056
|
deprecated,
|
|
6925
7057
|
jsonKey,
|
|
6926
|
-
exportJsonKey
|
|
7058
|
+
exportJsonKey,
|
|
7059
|
+
htmlKey
|
|
6927
7060
|
} = _tag;
|
|
6928
7061
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6929
7062
|
if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
|
|
@@ -6942,6 +7075,8 @@ var ConfigHydrator = class {
|
|
|
6942
7075
|
jsonKey,
|
|
6943
7076
|
exportJsonKey,
|
|
6944
7077
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7078
|
+
htmlKey,
|
|
7079
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6945
7080
|
deprecated
|
|
6946
7081
|
});
|
|
6947
7082
|
return {
|
|
@@ -6961,7 +7096,8 @@ var ConfigHydrator = class {
|
|
|
6961
7096
|
values,
|
|
6962
7097
|
defaultValue,
|
|
6963
7098
|
jsonKey,
|
|
6964
|
-
exportJsonKey
|
|
7099
|
+
exportJsonKey,
|
|
7100
|
+
htmlKey
|
|
6965
7101
|
} = _tag;
|
|
6966
7102
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6967
7103
|
if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
|
|
@@ -6979,6 +7115,8 @@ var ConfigHydrator = class {
|
|
|
6979
7115
|
jsonKey,
|
|
6980
7116
|
exportJsonKey,
|
|
6981
7117
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7118
|
+
htmlKey,
|
|
7119
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6982
7120
|
format,
|
|
6983
7121
|
values,
|
|
6984
7122
|
defaultValue,
|
|
@@ -6998,7 +7136,8 @@ var ConfigHydrator = class {
|
|
|
6998
7136
|
chain: _chain,
|
|
6999
7137
|
deprecated,
|
|
7000
7138
|
jsonKey,
|
|
7001
|
-
exportJsonKey
|
|
7139
|
+
exportJsonKey,
|
|
7140
|
+
htmlKey
|
|
7002
7141
|
} = _tag;
|
|
7003
7142
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
7004
7143
|
if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
|
|
@@ -7016,6 +7155,8 @@ var ConfigHydrator = class {
|
|
|
7016
7155
|
jsonKey,
|
|
7017
7156
|
exportJsonKey,
|
|
7018
7157
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7158
|
+
htmlKey,
|
|
7159
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
7019
7160
|
deprecated
|
|
7020
7161
|
});
|
|
7021
7162
|
return {
|
|
@@ -7054,6 +7195,7 @@ var ConfigHydrator = class {
|
|
|
7054
7195
|
repeatCount,
|
|
7055
7196
|
jsonKey,
|
|
7056
7197
|
exportJsonKey,
|
|
7198
|
+
htmlKey,
|
|
7057
7199
|
format
|
|
7058
7200
|
} = _variant;
|
|
7059
7201
|
const tags2 = this.hydrateTagsConfig(_tags);
|
|
@@ -7065,7 +7207,9 @@ var ConfigHydrator = class {
|
|
|
7065
7207
|
jsonKey,
|
|
7066
7208
|
exportJsonKey,
|
|
7067
7209
|
Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
|
|
7068
|
-
format
|
|
7210
|
+
format,
|
|
7211
|
+
htmlKey,
|
|
7212
|
+
Object.prototype.hasOwnProperty.call(_variant, "htmlKey")
|
|
7069
7213
|
);
|
|
7070
7214
|
return cardSetConfig;
|
|
7071
7215
|
}
|
|
@@ -10198,11 +10342,6 @@ var BITS = {
|
|
|
10198
10342
|
baseBitType: BitType._standard,
|
|
10199
10343
|
description: "Extractor rule bit, used to define extraction rules with reference images and instructions",
|
|
10200
10344
|
tags: [
|
|
10201
|
-
{
|
|
10202
|
-
exportJsonKey: { title: "$" },
|
|
10203
|
-
key: ConfigKey.tag_title,
|
|
10204
|
-
description: "The name of the extraction rule"
|
|
10205
|
-
},
|
|
10206
10345
|
{
|
|
10207
10346
|
key: ConfigKey.group_resourceBitTags,
|
|
10208
10347
|
description: "Resource bit tags for extraction rule images"
|
|
@@ -10838,7 +10977,9 @@ var BITS = {
|
|
|
10838
10977
|
{
|
|
10839
10978
|
key: ConfigKey.property_caption,
|
|
10840
10979
|
description: "Caption for the table image, used to provide a description for the image",
|
|
10841
|
-
format: TagFormat.bitmarkText
|
|
10980
|
+
format: TagFormat.bitmarkText,
|
|
10981
|
+
// HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
|
|
10982
|
+
htmlKey: { "@el": "caption", "@children": "$" }
|
|
10842
10983
|
},
|
|
10843
10984
|
{
|
|
10844
10985
|
key: ConfigKey.group_backgroundWallpaper,
|
|
@@ -10881,6 +11022,26 @@ var BITS = {
|
|
|
10881
11022
|
baseBitType: BitType.tableImage,
|
|
10882
11023
|
description: "Standard non-normative remark table image bit, used to create non-normative remark images in tables in articles or books"
|
|
10883
11024
|
},
|
|
11025
|
+
[BitType.standardTableExtendedImageNormative]: {
|
|
11026
|
+
since: "1.16.0",
|
|
11027
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11028
|
+
description: "Standard normative extended table image bit, used to create normative extended images in tables in articles or books"
|
|
11029
|
+
},
|
|
11030
|
+
[BitType.standardTableExtendedImageNonNormative]: {
|
|
11031
|
+
since: "1.16.0",
|
|
11032
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11033
|
+
description: "Standard non-normative extended table image bit, used to create non-normative extended images in tables in articles or books"
|
|
11034
|
+
},
|
|
11035
|
+
[BitType.standardRemarkTableExtendedImageNormative]: {
|
|
11036
|
+
since: "1.17.0",
|
|
11037
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11038
|
+
description: "Standard normative remark extended table image bit, used to create normative remark extended images in tables in articles or books"
|
|
11039
|
+
},
|
|
11040
|
+
[BitType.standardRemarkTableExtendedImageNonNormative]: {
|
|
11041
|
+
since: "1.17.0",
|
|
11042
|
+
baseBitType: BitType.tableExtendedImage,
|
|
11043
|
+
description: "Standard non-normative remark extended table image bit, used to create non-normative remark extended images in tables in articles or books"
|
|
11044
|
+
},
|
|
10884
11045
|
[BitType.smartStandardTableImageNormative]: {
|
|
10885
11046
|
since: "1.28.0",
|
|
10886
11047
|
baseBitType: BitType.standardTableImageNormative,
|
|
@@ -10901,6 +11062,26 @@ var BITS = {
|
|
|
10901
11062
|
baseBitType: BitType.standardRemarkTableImageNonNormative,
|
|
10902
11063
|
description: "Smart standard non-normative remark table image bit, used to create smart standard non-normative remark images in tables in articles or books"
|
|
10903
11064
|
},
|
|
11065
|
+
[BitType.smartStandardTableExtendedImageNormative]: {
|
|
11066
|
+
since: "1.28.0",
|
|
11067
|
+
baseBitType: BitType.standardTableExtendedImageNormative,
|
|
11068
|
+
description: "Smart standard normative extended table image bit, used to create smart standard normative extended images in tables in articles or books"
|
|
11069
|
+
},
|
|
11070
|
+
[BitType.smartStandardTableExtendedImageNonNormative]: {
|
|
11071
|
+
since: "1.28.0",
|
|
11072
|
+
baseBitType: BitType.standardTableExtendedImageNonNormative,
|
|
11073
|
+
description: "Smart standard non-normative extended table image bit, used to create smart standard non-normative extended images in tables in articles or books"
|
|
11074
|
+
},
|
|
11075
|
+
[BitType.smartStandardRemarkTableExtendedImageNormative]: {
|
|
11076
|
+
since: "1.28.0",
|
|
11077
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNormative,
|
|
11078
|
+
description: "Smart standard normative remark extended table image bit, used to create smart standard normative remark extended images in tables in articles or books"
|
|
11079
|
+
},
|
|
11080
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormative]: {
|
|
11081
|
+
since: "1.28.0",
|
|
11082
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNonNormative,
|
|
11083
|
+
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"
|
|
11084
|
+
},
|
|
10904
11085
|
[BitType.smartStandardTableImageNormativeCollapsible]: {
|
|
10905
11086
|
since: "1.28.0",
|
|
10906
11087
|
baseBitType: BitType.smartStandardTableImageNormative,
|
|
@@ -10921,6 +11102,26 @@ var BITS = {
|
|
|
10921
11102
|
baseBitType: BitType.smartStandardRemarkTableImageNonNormative,
|
|
10922
11103
|
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"
|
|
10923
11104
|
},
|
|
11105
|
+
[BitType.smartStandardTableExtendedImageNormativeCollapsible]: {
|
|
11106
|
+
since: "1.28.0",
|
|
11107
|
+
baseBitType: BitType.smartStandardTableExtendedImageNormative,
|
|
11108
|
+
description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
|
|
11109
|
+
},
|
|
11110
|
+
[BitType.smartStandardTableExtendedImageNonNormativeCollapsible]: {
|
|
11111
|
+
since: "1.28.0",
|
|
11112
|
+
baseBitType: BitType.smartStandardTableExtendedImageNonNormative,
|
|
11113
|
+
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"
|
|
11114
|
+
},
|
|
11115
|
+
[BitType.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
|
|
11116
|
+
since: "1.28.0",
|
|
11117
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNormative,
|
|
11118
|
+
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"
|
|
11119
|
+
},
|
|
11120
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
|
|
11121
|
+
since: "1.28.0",
|
|
11122
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNonNormative,
|
|
11123
|
+
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"
|
|
11124
|
+
},
|
|
10924
11125
|
[BitType.imageLink]: {
|
|
10925
11126
|
since: "1.3.0",
|
|
10926
11127
|
baseBitType: BitType._standard,
|
|
@@ -12469,7 +12670,12 @@ var BITS = {
|
|
|
12469
12670
|
{
|
|
12470
12671
|
key: ConfigKey.property_caption,
|
|
12471
12672
|
description: "Caption for the table, used to define the title of the table",
|
|
12472
|
-
format: TagFormat.bitmarkText
|
|
12673
|
+
format: TagFormat.bitmarkText,
|
|
12674
|
+
// HTML-10 / HTML-C2: a bit-level caption renders as the table's
|
|
12675
|
+
// `<caption>` — placed inside the idiomatic `<table>` container as
|
|
12676
|
+
// its first child. Outside a table context it falls back to the
|
|
12677
|
+
// residual carrier.
|
|
12678
|
+
htmlKey: { "@el": "caption", "@children": "$" }
|
|
12473
12679
|
},
|
|
12474
12680
|
{
|
|
12475
12681
|
key: ConfigKey.property_tableFixedHeader,
|
|
@@ -12554,7 +12760,9 @@ var BITS = {
|
|
|
12554
12760
|
{
|
|
12555
12761
|
key: ConfigKey.property_caption,
|
|
12556
12762
|
description: "Caption for the table image, used to provide a description for the image",
|
|
12557
|
-
format: TagFormat.bitmarkText
|
|
12763
|
+
format: TagFormat.bitmarkText,
|
|
12764
|
+
// HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
|
|
12765
|
+
htmlKey: { "@el": "caption", "@children": "$" }
|
|
12558
12766
|
},
|
|
12559
12767
|
{
|
|
12560
12768
|
key: ConfigKey.group_backgroundWallpaper,
|
|
@@ -12597,6 +12805,26 @@ var BITS = {
|
|
|
12597
12805
|
baseBitType: BitType.table,
|
|
12598
12806
|
description: "Standard non-normative remark table bit, used to create standard non-normative remark tables in articles or books"
|
|
12599
12807
|
},
|
|
12808
|
+
[BitType.standardTableExtendedNormative]: {
|
|
12809
|
+
since: "1.16.0",
|
|
12810
|
+
baseBitType: BitType.tableExtended,
|
|
12811
|
+
description: "Standard normative extended table bit, used to create standard normative extended tables in articles or books"
|
|
12812
|
+
},
|
|
12813
|
+
[BitType.standardTableExtendedNonNormative]: {
|
|
12814
|
+
since: "1.16.0",
|
|
12815
|
+
baseBitType: BitType.tableExtended,
|
|
12816
|
+
description: "Standard non-normative extended table bit, used to create standard non-normative extended tables in articles or books"
|
|
12817
|
+
},
|
|
12818
|
+
[BitType.standardRemarkTableExtendedNormative]: {
|
|
12819
|
+
since: "1.17.0",
|
|
12820
|
+
baseBitType: BitType.tableExtended,
|
|
12821
|
+
description: "Standard normative remark extended table bit, used to create standard normative remark extended tables in articles or books"
|
|
12822
|
+
},
|
|
12823
|
+
[BitType.standardRemarkTableExtendedNonNormative]: {
|
|
12824
|
+
since: "1.17.0",
|
|
12825
|
+
baseBitType: BitType.tableExtended,
|
|
12826
|
+
description: "Standard non-normative remark extended table bit, used to create standard non-normative remark extended tables in articles or books"
|
|
12827
|
+
},
|
|
12600
12828
|
[BitType.smartStandardTableNormative]: {
|
|
12601
12829
|
since: "1.28.0",
|
|
12602
12830
|
baseBitType: BitType.standardTableNormative,
|
|
@@ -12617,6 +12845,26 @@ var BITS = {
|
|
|
12617
12845
|
baseBitType: BitType.standardRemarkTableNonNormative,
|
|
12618
12846
|
description: "Smart standard non-normative remark table bit, used to create smart standard non-normative remark tables in articles or books"
|
|
12619
12847
|
},
|
|
12848
|
+
[BitType.smartStandardTableExtendedNormative]: {
|
|
12849
|
+
since: "1.28.0",
|
|
12850
|
+
baseBitType: BitType.standardTableExtendedNormative,
|
|
12851
|
+
description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
|
|
12852
|
+
},
|
|
12853
|
+
[BitType.smartStandardTableExtendedNonNormative]: {
|
|
12854
|
+
since: "1.28.0",
|
|
12855
|
+
baseBitType: BitType.standardTableExtendedNonNormative,
|
|
12856
|
+
description: "Smart standard non-normative extended table bit, used to create smart standard non-normative extended tables in articles or books"
|
|
12857
|
+
},
|
|
12858
|
+
[BitType.smartStandardRemarkTableExtendedNormative]: {
|
|
12859
|
+
since: "1.28.0",
|
|
12860
|
+
baseBitType: BitType.standardRemarkTableExtendedNormative,
|
|
12861
|
+
description: "Smart standard normative remark extended table bit, used to create smart standard normative remark extended tables in articles or books"
|
|
12862
|
+
},
|
|
12863
|
+
[BitType.smartStandardRemarkTableExtendedNonNormative]: {
|
|
12864
|
+
since: "1.28.0",
|
|
12865
|
+
baseBitType: BitType.standardRemarkTableExtendedNonNormative,
|
|
12866
|
+
description: "Smart standard non-normative remark extended table bit, used to create smart standard non-normative remark extended tables in articles or books"
|
|
12867
|
+
},
|
|
12620
12868
|
[BitType.smartStandardTableNormativeCollapsible]: {
|
|
12621
12869
|
since: "1.28.0",
|
|
12622
12870
|
baseBitType: BitType.smartStandardTableNormative,
|
|
@@ -12637,6 +12885,26 @@ var BITS = {
|
|
|
12637
12885
|
baseBitType: BitType.smartStandardRemarkTableNonNormative,
|
|
12638
12886
|
description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
|
|
12639
12887
|
},
|
|
12888
|
+
[BitType.smartStandardTableExtendedNormativeCollapsible]: {
|
|
12889
|
+
since: "1.28.0",
|
|
12890
|
+
baseBitType: BitType.smartStandardTableExtendedNormative,
|
|
12891
|
+
description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
|
|
12892
|
+
},
|
|
12893
|
+
[BitType.smartStandardTableExtendedNonNormativeCollapsible]: {
|
|
12894
|
+
since: "1.28.0",
|
|
12895
|
+
baseBitType: BitType.smartStandardTableExtendedNonNormative,
|
|
12896
|
+
description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
|
|
12897
|
+
},
|
|
12898
|
+
[BitType.smartStandardRemarkTableExtendedNormativeCollapsible]: {
|
|
12899
|
+
since: "1.28.0",
|
|
12900
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNormative,
|
|
12901
|
+
description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
|
|
12902
|
+
},
|
|
12903
|
+
[BitType.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
|
|
12904
|
+
since: "1.28.0",
|
|
12905
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNonNormative,
|
|
12906
|
+
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"
|
|
12907
|
+
},
|
|
12640
12908
|
[BitType.parameters]: {
|
|
12641
12909
|
since: "1.18.0",
|
|
12642
12910
|
baseBitType: BitType.table,
|
|
@@ -13578,6 +13846,8 @@ var Config = class {
|
|
|
13578
13846
|
jsonKey: tag.jsonKey,
|
|
13579
13847
|
exportJsonKey: tag.exportJsonKey,
|
|
13580
13848
|
hasExportJsonKey: tag.hasExportJsonKey,
|
|
13849
|
+
htmlKey: tag.htmlKey,
|
|
13850
|
+
hasHtmlKey: tag.hasHtmlKey,
|
|
13581
13851
|
deprecated: tag.deprecated
|
|
13582
13852
|
});
|
|
13583
13853
|
finalResourceTags[k] = newTag;
|
|
@@ -13682,7 +13952,7 @@ var instance2 = new Config();
|
|
|
13682
13952
|
// src/generated/package_info.ts
|
|
13683
13953
|
var PACKAGE_INFO = {
|
|
13684
13954
|
"name": "@gmb/bitmark-parser-generator",
|
|
13685
|
-
"version": "5.
|
|
13955
|
+
"version": "5.28.0",
|
|
13686
13956
|
"author": "Get More Brain Ltd",
|
|
13687
13957
|
"license": "ISC",
|
|
13688
13958
|
"description": "A bitmark parser and generator using Peggy.js"
|
|
@@ -14572,6 +14842,10 @@ var NodeType = {
|
|
|
14572
14842
|
relatedBookValue: "relatedBookValue",
|
|
14573
14843
|
translationOfBook: "translationOfBook",
|
|
14574
14844
|
translationOfBookValue: "translationOfBookValue",
|
|
14845
|
+
userFeedbackTranslationUrl: "userFeedbackTranslationUrl",
|
|
14846
|
+
userFeedbackTranslationUrlValue: "userFeedbackTranslationUrlValue",
|
|
14847
|
+
userFeedbackContentUrl: "userFeedbackContentUrl",
|
|
14848
|
+
userFeedbackContentUrlValue: "userFeedbackContentUrlValue",
|
|
14575
14849
|
releaseDate: "releaseDate",
|
|
14576
14850
|
releaseDateValue: "releaseDateValue",
|
|
14577
14851
|
releaseKind: "releaseKind",
|
|
@@ -27781,6 +28055,18 @@ var Builder = class extends BaseBuilder {
|
|
|
27781
28055
|
data.translationOfBook,
|
|
27782
28056
|
options
|
|
27783
28057
|
),
|
|
28058
|
+
userFeedbackTranslationUrl: this.toAstProperty(
|
|
28059
|
+
bitType,
|
|
28060
|
+
ConfigKey.property_userFeedbackTranslationUrl,
|
|
28061
|
+
data.userFeedbackTranslationUrl,
|
|
28062
|
+
options
|
|
28063
|
+
),
|
|
28064
|
+
userFeedbackContentUrl: this.toAstProperty(
|
|
28065
|
+
bitType,
|
|
28066
|
+
ConfigKey.property_userFeedbackContentUrl,
|
|
28067
|
+
data.userFeedbackContentUrl,
|
|
28068
|
+
options
|
|
28069
|
+
),
|
|
27784
28070
|
author: this.toAstProperty(bitType, ConfigKey.property_author, data.author, options),
|
|
27785
28071
|
subject: this.toAstProperty(bitType, ConfigKey.property_subject, data.subject, options),
|
|
27786
28072
|
date: this.toAstProperty(bitType, ConfigKey.property_date, data.date, options),
|
|
@@ -31572,7 +31858,8 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
|
|
|
31572
31858
|
this.writeNL();
|
|
31573
31859
|
}
|
|
31574
31860
|
const content = cell.content ?? instance3.EMPTY_STRING;
|
|
31575
|
-
|
|
31861
|
+
const options = this.options.noBreakscaping ? { noBreakscaping: true } : void 0;
|
|
31862
|
+
this.writeTextOrValue(content, this.textFormat, TextLocation.body, options);
|
|
31576
31863
|
}
|
|
31577
31864
|
writeTableCellProperty(name, value) {
|
|
31578
31865
|
this.writeOPA();
|
|
@@ -33038,6 +33325,278 @@ var BitmarkStringGenerator = class {
|
|
|
33038
33325
|
}
|
|
33039
33326
|
};
|
|
33040
33327
|
|
|
33328
|
+
// src/generator/html/HtmlTableGenerator.ts
|
|
33329
|
+
var MARK_TO_TAG = {
|
|
33330
|
+
bold: "b",
|
|
33331
|
+
italic: "i",
|
|
33332
|
+
superscript: "sup",
|
|
33333
|
+
subscript: "sub",
|
|
33334
|
+
strike: "s",
|
|
33335
|
+
del: "del",
|
|
33336
|
+
ins: "ins",
|
|
33337
|
+
underline: "u",
|
|
33338
|
+
highlight: "mark",
|
|
33339
|
+
code: "code"
|
|
33340
|
+
};
|
|
33341
|
+
var INLINE_IMAGE_RE = /==([^=]*(?:=(?!=)[^=]*)*)==\|imageInline:([^|\s]+)((?:\|(?:@?[A-Za-z][A-Za-z0-9_-]*:[^|\s]+|#[^|\s]*))*)\|?/g;
|
|
33342
|
+
var MAX_IMAGE_DIMENSION = 9999;
|
|
33343
|
+
var HtmlTableGenerator = class {
|
|
33344
|
+
constructor() {
|
|
33345
|
+
__publicField(this, "indentUnit", " ");
|
|
33346
|
+
}
|
|
33347
|
+
/**
|
|
33348
|
+
* Generate HTML table fragments from a string or JSON value.
|
|
33349
|
+
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
33350
|
+
*/
|
|
33351
|
+
generate(input) {
|
|
33352
|
+
let data = input;
|
|
33353
|
+
if (typeof data === "string") {
|
|
33354
|
+
try {
|
|
33355
|
+
data = JSON.parse(data);
|
|
33356
|
+
} catch {
|
|
33357
|
+
return "";
|
|
33358
|
+
}
|
|
33359
|
+
}
|
|
33360
|
+
const bits = this.collectBits(data);
|
|
33361
|
+
const fragments = [];
|
|
33362
|
+
for (const bit of bits) {
|
|
33363
|
+
const html = this.renderTableBit(bit);
|
|
33364
|
+
if (html) fragments.push(html);
|
|
33365
|
+
}
|
|
33366
|
+
return fragments.join("\n\n");
|
|
33367
|
+
}
|
|
33368
|
+
// --- bit collection -------------------------------------------------------
|
|
33369
|
+
collectBits(data) {
|
|
33370
|
+
const out = [];
|
|
33371
|
+
const visit = (value) => {
|
|
33372
|
+
if (value == null || typeof value !== "object") return;
|
|
33373
|
+
if (Array.isArray(value)) {
|
|
33374
|
+
value.forEach(visit);
|
|
33375
|
+
return;
|
|
33376
|
+
}
|
|
33377
|
+
const obj = value;
|
|
33378
|
+
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
33379
|
+
out.push(obj.bit);
|
|
33380
|
+
} else if ("type" in obj) {
|
|
33381
|
+
out.push(obj);
|
|
33382
|
+
}
|
|
33383
|
+
};
|
|
33384
|
+
visit(data);
|
|
33385
|
+
return out;
|
|
33386
|
+
}
|
|
33387
|
+
// --- table rendering ------------------------------------------------------
|
|
33388
|
+
renderTableBit(bit) {
|
|
33389
|
+
const table = bit.table;
|
|
33390
|
+
if (!table) return "";
|
|
33391
|
+
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
33392
|
+
const extended = this.toExtended(table);
|
|
33393
|
+
const lines = [];
|
|
33394
|
+
lines.push("<table>");
|
|
33395
|
+
if (bit.caption != null) {
|
|
33396
|
+
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
33397
|
+
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
33398
|
+
}
|
|
33399
|
+
this.renderSection(lines, "thead", extended.header, "header");
|
|
33400
|
+
this.renderSection(lines, "tbody", extended.body, "body");
|
|
33401
|
+
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
33402
|
+
lines.push("</table>");
|
|
33403
|
+
return lines.join("\n");
|
|
33404
|
+
}
|
|
33405
|
+
toExtended(table) {
|
|
33406
|
+
const t = table;
|
|
33407
|
+
if (t.header || t.body || t.footer) return table;
|
|
33408
|
+
return convertBasicToExtendedTableFormat(table);
|
|
33409
|
+
}
|
|
33410
|
+
renderSection(lines, tag, section, key) {
|
|
33411
|
+
if (!section || !section.rows || section.rows.length === 0) return;
|
|
33412
|
+
lines.push(`${this.indentUnit}<${tag}>`);
|
|
33413
|
+
for (const row of section.rows) {
|
|
33414
|
+
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
33415
|
+
for (const cell of row.cells ?? []) {
|
|
33416
|
+
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
33417
|
+
}
|
|
33418
|
+
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
33419
|
+
}
|
|
33420
|
+
lines.push(`${this.indentUnit}</${tag}>`);
|
|
33421
|
+
}
|
|
33422
|
+
renderCell(cell, _key) {
|
|
33423
|
+
const tag = cell.title === true ? "th" : "td";
|
|
33424
|
+
const attrs = [];
|
|
33425
|
+
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
33426
|
+
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
33427
|
+
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
33428
|
+
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
33429
|
+
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
33430
|
+
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
33431
|
+
}
|
|
33432
|
+
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
33433
|
+
asTextAst(content) {
|
|
33434
|
+
if (content == null) return [];
|
|
33435
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
33436
|
+
return content;
|
|
33437
|
+
}
|
|
33438
|
+
cellContentToHtml(blocks) {
|
|
33439
|
+
if (blocks.length === 0) return "";
|
|
33440
|
+
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
33441
|
+
return this.inlineToHtml(blocks[0].content ?? []);
|
|
33442
|
+
}
|
|
33443
|
+
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
33444
|
+
}
|
|
33445
|
+
blockToHtml(node) {
|
|
33446
|
+
switch (node.type) {
|
|
33447
|
+
case "paragraph":
|
|
33448
|
+
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
33449
|
+
case "bulletList":
|
|
33450
|
+
case "noBulletList":
|
|
33451
|
+
case "orderedList":
|
|
33452
|
+
case "orderedListRoman":
|
|
33453
|
+
case "orderedListRomanLower":
|
|
33454
|
+
case "letteredList":
|
|
33455
|
+
case "letteredListLower":
|
|
33456
|
+
case "taskList":
|
|
33457
|
+
return this.listToHtml(node);
|
|
33458
|
+
case "image":
|
|
33459
|
+
case "imageInline":
|
|
33460
|
+
return this.imageToHtml(node);
|
|
33461
|
+
case "latex":
|
|
33462
|
+
return this.latexToHtml(node);
|
|
33463
|
+
default:
|
|
33464
|
+
return this.inlineToHtml([node]);
|
|
33465
|
+
}
|
|
33466
|
+
}
|
|
33467
|
+
inlineToHtml(nodes) {
|
|
33468
|
+
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
33469
|
+
}
|
|
33470
|
+
inlineNodeToHtml(node) {
|
|
33471
|
+
if (node.type === "hardBreak") return "<br>";
|
|
33472
|
+
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
33473
|
+
if (node.type === "latex") return this.latexToHtml(node);
|
|
33474
|
+
if (node.type === "text") {
|
|
33475
|
+
return this.wrapMarks(this.textToHtml(node.text ?? ""), node.marks);
|
|
33476
|
+
}
|
|
33477
|
+
if (node.content) return this.inlineToHtml(node.content);
|
|
33478
|
+
return this.escapeText(node.text ?? "");
|
|
33479
|
+
}
|
|
33480
|
+
wrapMarks(text, marks) {
|
|
33481
|
+
if (!marks || marks.length === 0) return text;
|
|
33482
|
+
let open = "";
|
|
33483
|
+
let close = "";
|
|
33484
|
+
for (const mark of marks) {
|
|
33485
|
+
if (mark.type === "link") {
|
|
33486
|
+
const href = mark.attrs?.href ?? "";
|
|
33487
|
+
open += `<a href="${this.escapeAttr(href)}">`;
|
|
33488
|
+
close = `</a>${close}`;
|
|
33489
|
+
} else {
|
|
33490
|
+
const tag = MARK_TO_TAG[mark.type];
|
|
33491
|
+
if (tag) {
|
|
33492
|
+
open += `<${tag}>`;
|
|
33493
|
+
close = `</${tag}>${close}`;
|
|
33494
|
+
}
|
|
33495
|
+
}
|
|
33496
|
+
}
|
|
33497
|
+
return `${open}${text}${close}`;
|
|
33498
|
+
}
|
|
33499
|
+
// --- lists ----------------------------------------------------------------
|
|
33500
|
+
listToHtml(node) {
|
|
33501
|
+
const { tag, attrs } = this.listTag(node);
|
|
33502
|
+
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
33503
|
+
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
33504
|
+
}
|
|
33505
|
+
listTag(node) {
|
|
33506
|
+
const start = node.attrs?.start;
|
|
33507
|
+
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
33508
|
+
switch (node.type) {
|
|
33509
|
+
case "orderedList":
|
|
33510
|
+
return { tag: "ol", attrs: startAttr };
|
|
33511
|
+
case "orderedListRoman":
|
|
33512
|
+
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
33513
|
+
case "orderedListRomanLower":
|
|
33514
|
+
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
33515
|
+
case "letteredList":
|
|
33516
|
+
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
33517
|
+
case "letteredListLower":
|
|
33518
|
+
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
33519
|
+
case "noBulletList":
|
|
33520
|
+
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
33521
|
+
case "taskList":
|
|
33522
|
+
case "bulletList":
|
|
33523
|
+
default:
|
|
33524
|
+
return { tag: "ul", attrs: "" };
|
|
33525
|
+
}
|
|
33526
|
+
}
|
|
33527
|
+
listItemToHtml(item, task) {
|
|
33528
|
+
const inner = (item.content ?? []).map((b) => {
|
|
33529
|
+
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
33530
|
+
return this.blockToHtml(b);
|
|
33531
|
+
}).join("");
|
|
33532
|
+
if (task) {
|
|
33533
|
+
const checked = item.attrs?.checked ? " checked" : "";
|
|
33534
|
+
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
33535
|
+
}
|
|
33536
|
+
return `<li>${inner}</li>`;
|
|
33537
|
+
}
|
|
33538
|
+
// --- images ---------------------------------------------------------------
|
|
33539
|
+
imageToHtml(node) {
|
|
33540
|
+
const attrs = node.attrs ?? {};
|
|
33541
|
+
const parts = [];
|
|
33542
|
+
const src = attrs.src;
|
|
33543
|
+
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
33544
|
+
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
33545
|
+
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
33546
|
+
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
33547
|
+
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
33548
|
+
if (typeof attrs.class === "string" && attrs.class) {
|
|
33549
|
+
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
33550
|
+
}
|
|
33551
|
+
return `<img ${parts.join(" ")}>`;
|
|
33552
|
+
}
|
|
33553
|
+
textToHtml(text) {
|
|
33554
|
+
let html = "";
|
|
33555
|
+
let lastIndex = 0;
|
|
33556
|
+
for (const match of text.matchAll(INLINE_IMAGE_RE)) {
|
|
33557
|
+
const index = match.index ?? 0;
|
|
33558
|
+
html += this.escapeText(text.slice(lastIndex, index));
|
|
33559
|
+
html += this.inlineImageTokenToHtml(match);
|
|
33560
|
+
lastIndex = index + match[0].length;
|
|
33561
|
+
}
|
|
33562
|
+
html += this.escapeText(text.slice(lastIndex));
|
|
33563
|
+
return html;
|
|
33564
|
+
}
|
|
33565
|
+
inlineImageTokenToHtml(match) {
|
|
33566
|
+
const attrs = {
|
|
33567
|
+
alt: match[1],
|
|
33568
|
+
src: match[2]
|
|
33569
|
+
};
|
|
33570
|
+
const rawAttrs = match[3] ?? "";
|
|
33571
|
+
for (const attr of rawAttrs.split("|")) {
|
|
33572
|
+
if (!attr || attr.startsWith("#")) continue;
|
|
33573
|
+
const colon = attr.indexOf(":");
|
|
33574
|
+
if (colon < 1) continue;
|
|
33575
|
+
const key = attr.slice(0, colon).replace(/^@/, "");
|
|
33576
|
+
const value = attr.slice(colon + 1);
|
|
33577
|
+
if (key === "width" || key === "height") {
|
|
33578
|
+
const n = Number.parseInt(value, 10);
|
|
33579
|
+
if (!Number.isNaN(n) && n > 0 && n <= MAX_IMAGE_DIMENSION) attrs[key] = n;
|
|
33580
|
+
} else if (key === "class" || key === "title") {
|
|
33581
|
+
attrs[key] = value;
|
|
33582
|
+
}
|
|
33583
|
+
}
|
|
33584
|
+
return this.imageToHtml({ type: "imageInline", attrs });
|
|
33585
|
+
}
|
|
33586
|
+
// --- formulas -------------------------------------------------------------
|
|
33587
|
+
latexToHtml(node) {
|
|
33588
|
+
const formula = node.attrs?.formula ?? "";
|
|
33589
|
+
return `<math alttext="${this.escapeAttr(formula)}"></math>`;
|
|
33590
|
+
}
|
|
33591
|
+
// --- escaping -------------------------------------------------------------
|
|
33592
|
+
escapeText(text) {
|
|
33593
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
33594
|
+
}
|
|
33595
|
+
escapeAttr(text) {
|
|
33596
|
+
return this.escapeText(text).replace(/"/g, """);
|
|
33597
|
+
}
|
|
33598
|
+
};
|
|
33599
|
+
|
|
33041
33600
|
// src/generator/json/JsonGenerator.ts
|
|
33042
33601
|
var import_superenum33 = require("@ncoderz/superenum");
|
|
33043
33602
|
var MOVE_BODY_RECURSION_LIMIT = 5e3;
|
|
@@ -33340,6 +33899,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
|
|
|
33340
33899
|
this.addProperty(this.bitJson, k, values, { array: true });
|
|
33341
33900
|
}
|
|
33342
33901
|
}
|
|
33902
|
+
return false;
|
|
33343
33903
|
}
|
|
33344
33904
|
// bitmarkAst -> bits -> bitsValue -> cardNode -> cardBits -> cardBitsValue
|
|
33345
33905
|
enter_cardBitsValue(node, route) {
|
|
@@ -37983,6 +38543,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
|
|
|
37983
38543
|
jsonKey: void 0,
|
|
37984
38544
|
exportJsonKey: void 0,
|
|
37985
38545
|
hasExportJsonKey: false,
|
|
38546
|
+
htmlKey: void 0,
|
|
38547
|
+
hasHtmlKey: false,
|
|
37986
38548
|
format: TagFormat.bitmarkText,
|
|
37987
38549
|
values: void 0,
|
|
37988
38550
|
defaultValue: void 0,
|
|
@@ -42380,6 +42942,539 @@ var BitmarkParser = class {
|
|
|
42380
42942
|
}
|
|
42381
42943
|
};
|
|
42382
42944
|
|
|
42945
|
+
// src/parser/html/HtmlDom.ts
|
|
42946
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
42947
|
+
"area",
|
|
42948
|
+
"base",
|
|
42949
|
+
"br",
|
|
42950
|
+
"col",
|
|
42951
|
+
"embed",
|
|
42952
|
+
"hr",
|
|
42953
|
+
"img",
|
|
42954
|
+
"input",
|
|
42955
|
+
"link",
|
|
42956
|
+
"meta",
|
|
42957
|
+
"param",
|
|
42958
|
+
"source",
|
|
42959
|
+
"track",
|
|
42960
|
+
"wbr"
|
|
42961
|
+
]);
|
|
42962
|
+
var IMPLIED_CLOSE = {
|
|
42963
|
+
li: /* @__PURE__ */ new Set(["li"]),
|
|
42964
|
+
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42965
|
+
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42966
|
+
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
42967
|
+
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42968
|
+
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42969
|
+
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42970
|
+
p: /* @__PURE__ */ new Set(["p"]),
|
|
42971
|
+
option: /* @__PURE__ */ new Set(["option"])
|
|
42972
|
+
};
|
|
42973
|
+
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9:-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
42974
|
+
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
42975
|
+
function parseAttrs(raw) {
|
|
42976
|
+
const attrs = {};
|
|
42977
|
+
if (!raw) return attrs;
|
|
42978
|
+
ATTR_RE.lastIndex = 0;
|
|
42979
|
+
let m;
|
|
42980
|
+
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
42981
|
+
const name = m[1].toLowerCase();
|
|
42982
|
+
let value = m[2] ?? "";
|
|
42983
|
+
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
42984
|
+
value = value.slice(1, -1);
|
|
42985
|
+
}
|
|
42986
|
+
attrs[name] = value;
|
|
42987
|
+
}
|
|
42988
|
+
return attrs;
|
|
42989
|
+
}
|
|
42990
|
+
function stripNonContent(html) {
|
|
42991
|
+
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, "");
|
|
42992
|
+
}
|
|
42993
|
+
function tokenize(html) {
|
|
42994
|
+
const tokens = [];
|
|
42995
|
+
const clean = stripNonContent(html);
|
|
42996
|
+
TAG_RE.lastIndex = 0;
|
|
42997
|
+
let lastIndex = 0;
|
|
42998
|
+
let m;
|
|
42999
|
+
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
43000
|
+
if (m.index > lastIndex) {
|
|
43001
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
43002
|
+
}
|
|
43003
|
+
lastIndex = TAG_RE.lastIndex;
|
|
43004
|
+
const isClose = m[1] === "/";
|
|
43005
|
+
const name = m[2].toLowerCase();
|
|
43006
|
+
if (isClose) {
|
|
43007
|
+
tokens.push({ kind: "close", name });
|
|
43008
|
+
} else {
|
|
43009
|
+
tokens.push({
|
|
43010
|
+
kind: "open",
|
|
43011
|
+
name,
|
|
43012
|
+
attrs: parseAttrs(m[3]),
|
|
43013
|
+
selfClose: m[4] === "/"
|
|
43014
|
+
});
|
|
43015
|
+
}
|
|
43016
|
+
}
|
|
43017
|
+
if (lastIndex < clean.length) {
|
|
43018
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
43019
|
+
}
|
|
43020
|
+
return tokens;
|
|
43021
|
+
}
|
|
43022
|
+
function parseHtml(html) {
|
|
43023
|
+
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
43024
|
+
const stack = [root];
|
|
43025
|
+
const top = () => stack[stack.length - 1];
|
|
43026
|
+
for (const token of tokenize(html)) {
|
|
43027
|
+
if (token.kind === "text") {
|
|
43028
|
+
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
43029
|
+
continue;
|
|
43030
|
+
}
|
|
43031
|
+
if (token.kind === "open") {
|
|
43032
|
+
const name = token.name;
|
|
43033
|
+
const closes = IMPLIED_CLOSE[name];
|
|
43034
|
+
if (closes) {
|
|
43035
|
+
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
43036
|
+
}
|
|
43037
|
+
const el = {
|
|
43038
|
+
type: "element",
|
|
43039
|
+
name,
|
|
43040
|
+
attrs: token.attrs ?? {},
|
|
43041
|
+
children: []
|
|
43042
|
+
};
|
|
43043
|
+
top().children.push(el);
|
|
43044
|
+
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
43045
|
+
stack.push(el);
|
|
43046
|
+
}
|
|
43047
|
+
continue;
|
|
43048
|
+
}
|
|
43049
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
43050
|
+
if (stack[i].name === token.name) {
|
|
43051
|
+
stack.length = i;
|
|
43052
|
+
break;
|
|
43053
|
+
}
|
|
43054
|
+
}
|
|
43055
|
+
}
|
|
43056
|
+
return root.children;
|
|
43057
|
+
}
|
|
43058
|
+
function childElements(el, names) {
|
|
43059
|
+
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43060
|
+
}
|
|
43061
|
+
|
|
43062
|
+
// src/parser/html/HtmlTableParser.ts
|
|
43063
|
+
var MARK_TAGS = {
|
|
43064
|
+
b: "bold",
|
|
43065
|
+
strong: "bold",
|
|
43066
|
+
i: "italic",
|
|
43067
|
+
em: "italic",
|
|
43068
|
+
sup: "superscript",
|
|
43069
|
+
sub: "subscript",
|
|
43070
|
+
s: "strike",
|
|
43071
|
+
strike: "strike",
|
|
43072
|
+
del: "del",
|
|
43073
|
+
ins: "ins",
|
|
43074
|
+
u: "underline",
|
|
43075
|
+
mark: "highlight",
|
|
43076
|
+
code: "code"
|
|
43077
|
+
};
|
|
43078
|
+
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
43079
|
+
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
43080
|
+
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
43081
|
+
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
43082
|
+
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
43083
|
+
var NAMED_ENTITIES = {
|
|
43084
|
+
amp: "&",
|
|
43085
|
+
lt: "<",
|
|
43086
|
+
gt: ">",
|
|
43087
|
+
quot: '"',
|
|
43088
|
+
apos: "'",
|
|
43089
|
+
nbsp: "\xA0"
|
|
43090
|
+
};
|
|
43091
|
+
function decodeEntities(text) {
|
|
43092
|
+
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
43093
|
+
if (body[0] === "#") {
|
|
43094
|
+
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
43095
|
+
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
43096
|
+
try {
|
|
43097
|
+
return String.fromCodePoint(code);
|
|
43098
|
+
} catch {
|
|
43099
|
+
return whole;
|
|
43100
|
+
}
|
|
43101
|
+
}
|
|
43102
|
+
return whole;
|
|
43103
|
+
}
|
|
43104
|
+
return NAMED_ENTITIES[body] ?? whole;
|
|
43105
|
+
});
|
|
43106
|
+
}
|
|
43107
|
+
function intAttr(value) {
|
|
43108
|
+
if (value == null) return void 0;
|
|
43109
|
+
const n = Number.parseInt(value, 10);
|
|
43110
|
+
return Number.isInteger(n) ? n : void 0;
|
|
43111
|
+
}
|
|
43112
|
+
function isElement(node) {
|
|
43113
|
+
return node.type === "element";
|
|
43114
|
+
}
|
|
43115
|
+
var HtmlTableParser = class {
|
|
43116
|
+
constructor() {
|
|
43117
|
+
__publicField(this, "keepUnknownTags", false);
|
|
43118
|
+
}
|
|
43119
|
+
/**
|
|
43120
|
+
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
43121
|
+
*/
|
|
43122
|
+
parse(html, options) {
|
|
43123
|
+
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
43124
|
+
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
43125
|
+
const onWarning = options?.onWarning;
|
|
43126
|
+
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
43127
|
+
const bits = [];
|
|
43128
|
+
for (const table of tables) {
|
|
43129
|
+
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
43130
|
+
if (bit) bits.push(bit);
|
|
43131
|
+
}
|
|
43132
|
+
return bits;
|
|
43133
|
+
}
|
|
43134
|
+
// --- table extraction -----------------------------------------------------
|
|
43135
|
+
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
43136
|
+
collectTopLevelTables(nodes) {
|
|
43137
|
+
const tables = [];
|
|
43138
|
+
const visit = (node) => {
|
|
43139
|
+
if (!isElement(node)) return;
|
|
43140
|
+
if (node.name === "table") {
|
|
43141
|
+
tables.push(node);
|
|
43142
|
+
return;
|
|
43143
|
+
}
|
|
43144
|
+
node.children.forEach(visit);
|
|
43145
|
+
};
|
|
43146
|
+
nodes.forEach(visit);
|
|
43147
|
+
return tables;
|
|
43148
|
+
}
|
|
43149
|
+
tableToBit(table, tableFormat, onWarning) {
|
|
43150
|
+
const header = [];
|
|
43151
|
+
const body = [];
|
|
43152
|
+
const footer = [];
|
|
43153
|
+
let caption;
|
|
43154
|
+
for (const child of table.children) {
|
|
43155
|
+
if (!isElement(child)) continue;
|
|
43156
|
+
if (child.name === "caption") {
|
|
43157
|
+
const capContent = this.inlineNodes(child.children, []);
|
|
43158
|
+
const trimmed = this.trimInline(capContent);
|
|
43159
|
+
if (trimmed.length > 0) caption = trimmed;
|
|
43160
|
+
} else if (SECTION_TAGS.has(child.name)) {
|
|
43161
|
+
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
43162
|
+
for (const tr of childElements(child, ROW_TAGS)) {
|
|
43163
|
+
target.push(this.rowToCells(tr));
|
|
43164
|
+
}
|
|
43165
|
+
} else if (ROW_TAGS.has(child.name)) {
|
|
43166
|
+
body.push(this.rowToCells(child));
|
|
43167
|
+
}
|
|
43168
|
+
}
|
|
43169
|
+
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
43170
|
+
return void 0;
|
|
43171
|
+
}
|
|
43172
|
+
const tableExtended = {};
|
|
43173
|
+
if (header.length > 0) tableExtended.header = { rows: header };
|
|
43174
|
+
if (body.length > 0) tableExtended.body = { rows: body };
|
|
43175
|
+
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
43176
|
+
let tableData = tableExtended;
|
|
43177
|
+
if (tableFormat === "table") {
|
|
43178
|
+
if (this.isLossyAsBasic(tableExtended)) {
|
|
43179
|
+
onWarning?.(
|
|
43180
|
+
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
43181
|
+
);
|
|
43182
|
+
}
|
|
43183
|
+
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
43184
|
+
}
|
|
43185
|
+
const bit = {
|
|
43186
|
+
type: tableFormat,
|
|
43187
|
+
format: "bitmark++",
|
|
43188
|
+
table: tableData
|
|
43189
|
+
};
|
|
43190
|
+
if (caption) bit.caption = caption;
|
|
43191
|
+
return bit;
|
|
43192
|
+
}
|
|
43193
|
+
rowToCells(tr) {
|
|
43194
|
+
const cells = [];
|
|
43195
|
+
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
43196
|
+
cells.push(this.cellToJson(cell));
|
|
43197
|
+
}
|
|
43198
|
+
return { cells };
|
|
43199
|
+
}
|
|
43200
|
+
cellToJson(cell) {
|
|
43201
|
+
const json = {
|
|
43202
|
+
content: this.blockNodes(cell.children)
|
|
43203
|
+
};
|
|
43204
|
+
if (cell.name === "th") json.title = true;
|
|
43205
|
+
const rowspan = intAttr(cell.attrs.rowspan);
|
|
43206
|
+
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
43207
|
+
const colspan = intAttr(cell.attrs.colspan);
|
|
43208
|
+
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
43209
|
+
const scope = cell.attrs.scope?.toLowerCase();
|
|
43210
|
+
if (scope && VALID_SCOPES.has(scope)) {
|
|
43211
|
+
json.scope = scope;
|
|
43212
|
+
}
|
|
43213
|
+
const width = this.widthFromCell(cell);
|
|
43214
|
+
if (width != null) json.colwidth = width;
|
|
43215
|
+
return json;
|
|
43216
|
+
}
|
|
43217
|
+
widthFromCell(cell) {
|
|
43218
|
+
const attrWidth = intAttr(cell.attrs.width);
|
|
43219
|
+
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
43220
|
+
const style = cell.attrs.style;
|
|
43221
|
+
if (style) {
|
|
43222
|
+
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
43223
|
+
if (m) {
|
|
43224
|
+
const n = Number.parseInt(m[1], 10);
|
|
43225
|
+
if (Number.isInteger(n) && n > 0) return n;
|
|
43226
|
+
}
|
|
43227
|
+
}
|
|
43228
|
+
return void 0;
|
|
43229
|
+
}
|
|
43230
|
+
isLossyAsBasic(table) {
|
|
43231
|
+
if (table.footer) return true;
|
|
43232
|
+
if (table.header && table.header.rows.length > 1) return true;
|
|
43233
|
+
const sections = [table.header, table.body, table.footer];
|
|
43234
|
+
for (const section of sections) {
|
|
43235
|
+
if (!section) continue;
|
|
43236
|
+
for (const row of section.rows) {
|
|
43237
|
+
for (const cell of row.cells) {
|
|
43238
|
+
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
43239
|
+
}
|
|
43240
|
+
}
|
|
43241
|
+
}
|
|
43242
|
+
return false;
|
|
43243
|
+
}
|
|
43244
|
+
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
43245
|
+
/**
|
|
43246
|
+
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
43247
|
+
*/
|
|
43248
|
+
blockNodes(nodes) {
|
|
43249
|
+
const blocks = [];
|
|
43250
|
+
let inline = [];
|
|
43251
|
+
const flush = () => {
|
|
43252
|
+
const trimmed = this.trimInline(inline);
|
|
43253
|
+
inline = [];
|
|
43254
|
+
if (trimmed.length === 0) return;
|
|
43255
|
+
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
43256
|
+
blocks.push({ ...trimmed[0], type: "image" });
|
|
43257
|
+
} else {
|
|
43258
|
+
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
43259
|
+
}
|
|
43260
|
+
};
|
|
43261
|
+
for (const node of nodes) {
|
|
43262
|
+
if (!isElement(node)) {
|
|
43263
|
+
inline.push(...this.inlineText(node.value, []));
|
|
43264
|
+
continue;
|
|
43265
|
+
}
|
|
43266
|
+
const name = node.name;
|
|
43267
|
+
if (name === "p") {
|
|
43268
|
+
flush();
|
|
43269
|
+
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
43270
|
+
if (content.length > 0) {
|
|
43271
|
+
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
43272
|
+
}
|
|
43273
|
+
} else if (this.isListTag(name)) {
|
|
43274
|
+
flush();
|
|
43275
|
+
const list = this.listNode(node);
|
|
43276
|
+
if (list) blocks.push(list);
|
|
43277
|
+
} else {
|
|
43278
|
+
inline.push(...this.inlineFromElement(node, []));
|
|
43279
|
+
}
|
|
43280
|
+
}
|
|
43281
|
+
flush();
|
|
43282
|
+
return blocks;
|
|
43283
|
+
}
|
|
43284
|
+
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
43285
|
+
inlineNodes(nodes, marks) {
|
|
43286
|
+
const out = [];
|
|
43287
|
+
for (const node of nodes) {
|
|
43288
|
+
if (!isElement(node)) {
|
|
43289
|
+
out.push(...this.inlineText(node.value, marks));
|
|
43290
|
+
} else {
|
|
43291
|
+
out.push(...this.inlineFromElement(node, marks));
|
|
43292
|
+
}
|
|
43293
|
+
}
|
|
43294
|
+
return out;
|
|
43295
|
+
}
|
|
43296
|
+
inlineFromElement(el, marks) {
|
|
43297
|
+
const name = el.name;
|
|
43298
|
+
if (name === "br") {
|
|
43299
|
+
return [{ type: "hardBreak" }];
|
|
43300
|
+
}
|
|
43301
|
+
if (name === "img") {
|
|
43302
|
+
return [this.imageNode(el, true)];
|
|
43303
|
+
}
|
|
43304
|
+
if (this.isMathTag(name)) {
|
|
43305
|
+
return [this.latexNode(el)];
|
|
43306
|
+
}
|
|
43307
|
+
const markType = MARK_TAGS[name];
|
|
43308
|
+
if (markType) {
|
|
43309
|
+
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
43310
|
+
}
|
|
43311
|
+
if (name === "a") {
|
|
43312
|
+
const linkMark = {
|
|
43313
|
+
type: "link",
|
|
43314
|
+
attrs: {
|
|
43315
|
+
href: el.attrs.href ?? "",
|
|
43316
|
+
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
43317
|
+
}
|
|
43318
|
+
};
|
|
43319
|
+
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
43320
|
+
}
|
|
43321
|
+
if (this.keepUnknownTags) {
|
|
43322
|
+
const open = this.serializeOpenTag(el);
|
|
43323
|
+
const close = `</${name}>`;
|
|
43324
|
+
return [
|
|
43325
|
+
...this.inlineText(open, marks),
|
|
43326
|
+
...this.inlineNodes(el.children, marks),
|
|
43327
|
+
...this.inlineText(close, marks)
|
|
43328
|
+
];
|
|
43329
|
+
}
|
|
43330
|
+
return this.inlineNodes(el.children, marks);
|
|
43331
|
+
}
|
|
43332
|
+
inlineText(raw, marks) {
|
|
43333
|
+
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
43334
|
+
if (text === "") return [];
|
|
43335
|
+
const node = { text, type: "text" };
|
|
43336
|
+
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
43337
|
+
return [node];
|
|
43338
|
+
}
|
|
43339
|
+
serializeOpenTag(el) {
|
|
43340
|
+
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
43341
|
+
return `<${el.name}${attrs}>`;
|
|
43342
|
+
}
|
|
43343
|
+
// --- lists ----------------------------------------------------------------
|
|
43344
|
+
isListTag(name) {
|
|
43345
|
+
return name === "ul" || name === "ol";
|
|
43346
|
+
}
|
|
43347
|
+
listNode(el) {
|
|
43348
|
+
const items = childElements(el, LI_TAGS);
|
|
43349
|
+
if (items.length === 0) return void 0;
|
|
43350
|
+
const isTask = el.name === "ul" && items.some((li) => {
|
|
43351
|
+
const firstEl = li.children.find(isElement);
|
|
43352
|
+
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
43353
|
+
});
|
|
43354
|
+
if (isTask) {
|
|
43355
|
+
return {
|
|
43356
|
+
type: "taskList",
|
|
43357
|
+
content: items.map((li) => this.taskItemNode(li))
|
|
43358
|
+
};
|
|
43359
|
+
}
|
|
43360
|
+
const type = this.listType(el);
|
|
43361
|
+
const node = {
|
|
43362
|
+
type,
|
|
43363
|
+
content: items.map((li) => this.listItemNode(li))
|
|
43364
|
+
};
|
|
43365
|
+
if (el.name === "ol") {
|
|
43366
|
+
const start = intAttr(el.attrs.start);
|
|
43367
|
+
if (start != null) {
|
|
43368
|
+
node.attrs = { start };
|
|
43369
|
+
}
|
|
43370
|
+
}
|
|
43371
|
+
return node;
|
|
43372
|
+
}
|
|
43373
|
+
listType(el) {
|
|
43374
|
+
if (el.name === "ol") {
|
|
43375
|
+
switch (el.attrs.type) {
|
|
43376
|
+
case "i":
|
|
43377
|
+
return "orderedListRomanLower";
|
|
43378
|
+
case "I":
|
|
43379
|
+
return "orderedListRoman";
|
|
43380
|
+
case "a":
|
|
43381
|
+
return "letteredListLower";
|
|
43382
|
+
case "A":
|
|
43383
|
+
return "letteredList";
|
|
43384
|
+
default:
|
|
43385
|
+
return "orderedList";
|
|
43386
|
+
}
|
|
43387
|
+
}
|
|
43388
|
+
const style = el.attrs.style ?? "";
|
|
43389
|
+
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
43390
|
+
return "bulletList";
|
|
43391
|
+
}
|
|
43392
|
+
listItemNode(li) {
|
|
43393
|
+
let content = this.blockNodes(li.children);
|
|
43394
|
+
if (content.length === 0) {
|
|
43395
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43396
|
+
}
|
|
43397
|
+
return { type: "listItem", content };
|
|
43398
|
+
}
|
|
43399
|
+
taskItemNode(li) {
|
|
43400
|
+
const checkbox = li.children.find(
|
|
43401
|
+
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
43402
|
+
);
|
|
43403
|
+
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
43404
|
+
const rest = li.children.filter((c) => c !== checkbox);
|
|
43405
|
+
let content = this.blockNodes(rest);
|
|
43406
|
+
if (content.length === 0) {
|
|
43407
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43408
|
+
}
|
|
43409
|
+
return { type: "taskItem", attrs: { checked }, content };
|
|
43410
|
+
}
|
|
43411
|
+
// --- images ---------------------------------------------------------------
|
|
43412
|
+
imageNode(el, inline) {
|
|
43413
|
+
const attrs = { src: el.attrs.src ?? "" };
|
|
43414
|
+
attrs.alt = el.attrs.alt ?? null;
|
|
43415
|
+
attrs.title = el.attrs.title ?? null;
|
|
43416
|
+
const width = intAttr(el.attrs.width);
|
|
43417
|
+
if (width != null) attrs.width = width;
|
|
43418
|
+
const height = intAttr(el.attrs.height);
|
|
43419
|
+
if (height != null) attrs.height = height;
|
|
43420
|
+
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
43421
|
+
return { type: inline ? "imageInline" : "image", attrs };
|
|
43422
|
+
}
|
|
43423
|
+
// --- formulas -------------------------------------------------------------
|
|
43424
|
+
isMathTag(name) {
|
|
43425
|
+
return this.localName(name) === "math";
|
|
43426
|
+
}
|
|
43427
|
+
latexNode(el) {
|
|
43428
|
+
return {
|
|
43429
|
+
type: "latex",
|
|
43430
|
+
attrs: {
|
|
43431
|
+
formula: this.latexFromMath(el)
|
|
43432
|
+
}
|
|
43433
|
+
};
|
|
43434
|
+
}
|
|
43435
|
+
latexFromMath(el) {
|
|
43436
|
+
const alt = el.attrs.alttext ?? el.attrs.alt ?? el.attrs.title;
|
|
43437
|
+
if (alt != null) return decodeEntities(alt);
|
|
43438
|
+
const annotation = this.findLatexAnnotation(el);
|
|
43439
|
+
if (annotation) return this.textContent(annotation).trim();
|
|
43440
|
+
return this.textContent(el).trim();
|
|
43441
|
+
}
|
|
43442
|
+
findLatexAnnotation(el) {
|
|
43443
|
+
for (const child of el.children) {
|
|
43444
|
+
if (!isElement(child)) continue;
|
|
43445
|
+
const lowerEncoding = (child.attrs.encoding ?? "").toLowerCase();
|
|
43446
|
+
if (this.localName(child.name) === "annotation" && (/\btex\b/.test(lowerEncoding) || /\blatex\b/.test(lowerEncoding))) {
|
|
43447
|
+
return child;
|
|
43448
|
+
}
|
|
43449
|
+
const nested = this.findLatexAnnotation(child);
|
|
43450
|
+
if (nested) return nested;
|
|
43451
|
+
}
|
|
43452
|
+
return void 0;
|
|
43453
|
+
}
|
|
43454
|
+
textContent(el) {
|
|
43455
|
+
return el.children.map((child) => isElement(child) ? this.textContent(child) : decodeEntities(child.value)).join("").replace(/\s+/g, " ");
|
|
43456
|
+
}
|
|
43457
|
+
localName(name) {
|
|
43458
|
+
return name.includes(":") ? name.slice(name.indexOf(":") + 1) : name;
|
|
43459
|
+
}
|
|
43460
|
+
// --- whitespace -----------------------------------------------------------
|
|
43461
|
+
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
43462
|
+
trimInline(nodes) {
|
|
43463
|
+
const out = nodes.slice();
|
|
43464
|
+
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
43465
|
+
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
43466
|
+
if (out.length > 0 && out[0].type === "text") {
|
|
43467
|
+
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
43468
|
+
}
|
|
43469
|
+
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
43470
|
+
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
43471
|
+
const last = out.length - 1;
|
|
43472
|
+
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
43473
|
+
}
|
|
43474
|
+
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
43475
|
+
}
|
|
43476
|
+
};
|
|
43477
|
+
|
|
42383
43478
|
// src/BitmarkParserGenerator.ts
|
|
42384
43479
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
42385
43480
|
var import_fs_extra4 = __toESM(require("fs-extra"), 1);
|
|
@@ -42673,235 +43768,6 @@ var BitmarkFileGenerator = class {
|
|
|
42673
43768
|
}
|
|
42674
43769
|
};
|
|
42675
43770
|
|
|
42676
|
-
// src/generator/html/HtmlTableGenerator.ts
|
|
42677
|
-
var MARK_TO_TAG = {
|
|
42678
|
-
bold: "b",
|
|
42679
|
-
italic: "i",
|
|
42680
|
-
superscript: "sup",
|
|
42681
|
-
subscript: "sub",
|
|
42682
|
-
strike: "s",
|
|
42683
|
-
del: "del",
|
|
42684
|
-
ins: "ins",
|
|
42685
|
-
underline: "u",
|
|
42686
|
-
highlight: "mark",
|
|
42687
|
-
code: "code"
|
|
42688
|
-
};
|
|
42689
|
-
var HtmlTableGenerator = class {
|
|
42690
|
-
constructor() {
|
|
42691
|
-
__publicField(this, "indentUnit", " ");
|
|
42692
|
-
}
|
|
42693
|
-
/**
|
|
42694
|
-
* Generate HTML table fragments from a string or JSON value.
|
|
42695
|
-
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
42696
|
-
*/
|
|
42697
|
-
generate(input) {
|
|
42698
|
-
let data = input;
|
|
42699
|
-
if (typeof data === "string") {
|
|
42700
|
-
try {
|
|
42701
|
-
data = JSON.parse(data);
|
|
42702
|
-
} catch {
|
|
42703
|
-
return "";
|
|
42704
|
-
}
|
|
42705
|
-
}
|
|
42706
|
-
const bits = this.collectBits(data);
|
|
42707
|
-
const fragments = [];
|
|
42708
|
-
for (const bit of bits) {
|
|
42709
|
-
const html = this.renderTableBit(bit);
|
|
42710
|
-
if (html) fragments.push(html);
|
|
42711
|
-
}
|
|
42712
|
-
return fragments.join("\n\n");
|
|
42713
|
-
}
|
|
42714
|
-
// --- bit collection -------------------------------------------------------
|
|
42715
|
-
collectBits(data) {
|
|
42716
|
-
const out = [];
|
|
42717
|
-
const visit = (value) => {
|
|
42718
|
-
if (value == null || typeof value !== "object") return;
|
|
42719
|
-
if (Array.isArray(value)) {
|
|
42720
|
-
value.forEach(visit);
|
|
42721
|
-
return;
|
|
42722
|
-
}
|
|
42723
|
-
const obj = value;
|
|
42724
|
-
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
42725
|
-
out.push(obj.bit);
|
|
42726
|
-
} else if ("type" in obj) {
|
|
42727
|
-
out.push(obj);
|
|
42728
|
-
}
|
|
42729
|
-
};
|
|
42730
|
-
visit(data);
|
|
42731
|
-
return out;
|
|
42732
|
-
}
|
|
42733
|
-
// --- table rendering ------------------------------------------------------
|
|
42734
|
-
renderTableBit(bit) {
|
|
42735
|
-
const table = bit.table;
|
|
42736
|
-
if (!table) return "";
|
|
42737
|
-
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
42738
|
-
const extended = this.toExtended(table);
|
|
42739
|
-
const lines = [];
|
|
42740
|
-
lines.push("<table>");
|
|
42741
|
-
if (bit.caption != null) {
|
|
42742
|
-
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
42743
|
-
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
42744
|
-
}
|
|
42745
|
-
this.renderSection(lines, "thead", extended.header, "header");
|
|
42746
|
-
this.renderSection(lines, "tbody", extended.body, "body");
|
|
42747
|
-
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
42748
|
-
lines.push("</table>");
|
|
42749
|
-
return lines.join("\n");
|
|
42750
|
-
}
|
|
42751
|
-
toExtended(table) {
|
|
42752
|
-
const t = table;
|
|
42753
|
-
if (t.header || t.body || t.footer) return table;
|
|
42754
|
-
return convertBasicToExtendedTableFormat(table);
|
|
42755
|
-
}
|
|
42756
|
-
renderSection(lines, tag, section, key) {
|
|
42757
|
-
if (!section || !section.rows || section.rows.length === 0) return;
|
|
42758
|
-
lines.push(`${this.indentUnit}<${tag}>`);
|
|
42759
|
-
for (const row of section.rows) {
|
|
42760
|
-
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
42761
|
-
for (const cell of row.cells ?? []) {
|
|
42762
|
-
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
42763
|
-
}
|
|
42764
|
-
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
42765
|
-
}
|
|
42766
|
-
lines.push(`${this.indentUnit}</${tag}>`);
|
|
42767
|
-
}
|
|
42768
|
-
renderCell(cell, _key) {
|
|
42769
|
-
const tag = cell.title === true ? "th" : "td";
|
|
42770
|
-
const attrs = [];
|
|
42771
|
-
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
42772
|
-
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
42773
|
-
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
42774
|
-
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
42775
|
-
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
42776
|
-
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
42777
|
-
}
|
|
42778
|
-
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
42779
|
-
asTextAst(content) {
|
|
42780
|
-
if (content == null) return [];
|
|
42781
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
42782
|
-
return content;
|
|
42783
|
-
}
|
|
42784
|
-
cellContentToHtml(blocks) {
|
|
42785
|
-
if (blocks.length === 0) return "";
|
|
42786
|
-
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
42787
|
-
return this.inlineToHtml(blocks[0].content ?? []);
|
|
42788
|
-
}
|
|
42789
|
-
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
42790
|
-
}
|
|
42791
|
-
blockToHtml(node) {
|
|
42792
|
-
switch (node.type) {
|
|
42793
|
-
case "paragraph":
|
|
42794
|
-
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
42795
|
-
case "bulletList":
|
|
42796
|
-
case "noBulletList":
|
|
42797
|
-
case "orderedList":
|
|
42798
|
-
case "orderedListRoman":
|
|
42799
|
-
case "orderedListRomanLower":
|
|
42800
|
-
case "letteredList":
|
|
42801
|
-
case "letteredListLower":
|
|
42802
|
-
case "taskList":
|
|
42803
|
-
return this.listToHtml(node);
|
|
42804
|
-
case "image":
|
|
42805
|
-
case "imageInline":
|
|
42806
|
-
return this.imageToHtml(node);
|
|
42807
|
-
default:
|
|
42808
|
-
return this.inlineToHtml([node]);
|
|
42809
|
-
}
|
|
42810
|
-
}
|
|
42811
|
-
inlineToHtml(nodes) {
|
|
42812
|
-
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
42813
|
-
}
|
|
42814
|
-
inlineNodeToHtml(node) {
|
|
42815
|
-
if (node.type === "hardBreak") return "<br>";
|
|
42816
|
-
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
42817
|
-
if (node.type === "text") {
|
|
42818
|
-
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
42819
|
-
}
|
|
42820
|
-
if (node.content) return this.inlineToHtml(node.content);
|
|
42821
|
-
return this.escapeText(node.text ?? "");
|
|
42822
|
-
}
|
|
42823
|
-
wrapMarks(text, marks) {
|
|
42824
|
-
if (!marks || marks.length === 0) return text;
|
|
42825
|
-
let open = "";
|
|
42826
|
-
let close = "";
|
|
42827
|
-
for (const mark of marks) {
|
|
42828
|
-
if (mark.type === "link") {
|
|
42829
|
-
const href = mark.attrs?.href ?? "";
|
|
42830
|
-
open += `<a href="${this.escapeAttr(href)}">`;
|
|
42831
|
-
close = `</a>${close}`;
|
|
42832
|
-
} else {
|
|
42833
|
-
const tag = MARK_TO_TAG[mark.type];
|
|
42834
|
-
if (tag) {
|
|
42835
|
-
open += `<${tag}>`;
|
|
42836
|
-
close = `</${tag}>${close}`;
|
|
42837
|
-
}
|
|
42838
|
-
}
|
|
42839
|
-
}
|
|
42840
|
-
return `${open}${text}${close}`;
|
|
42841
|
-
}
|
|
42842
|
-
// --- lists ----------------------------------------------------------------
|
|
42843
|
-
listToHtml(node) {
|
|
42844
|
-
const { tag, attrs } = this.listTag(node);
|
|
42845
|
-
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
42846
|
-
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
42847
|
-
}
|
|
42848
|
-
listTag(node) {
|
|
42849
|
-
const start = node.attrs?.start;
|
|
42850
|
-
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
42851
|
-
switch (node.type) {
|
|
42852
|
-
case "orderedList":
|
|
42853
|
-
return { tag: "ol", attrs: startAttr };
|
|
42854
|
-
case "orderedListRoman":
|
|
42855
|
-
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
42856
|
-
case "orderedListRomanLower":
|
|
42857
|
-
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
42858
|
-
case "letteredList":
|
|
42859
|
-
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
42860
|
-
case "letteredListLower":
|
|
42861
|
-
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
42862
|
-
case "noBulletList":
|
|
42863
|
-
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
42864
|
-
case "taskList":
|
|
42865
|
-
case "bulletList":
|
|
42866
|
-
default:
|
|
42867
|
-
return { tag: "ul", attrs: "" };
|
|
42868
|
-
}
|
|
42869
|
-
}
|
|
42870
|
-
listItemToHtml(item, task) {
|
|
42871
|
-
const inner = (item.content ?? []).map((b) => {
|
|
42872
|
-
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
42873
|
-
return this.blockToHtml(b);
|
|
42874
|
-
}).join("");
|
|
42875
|
-
if (task) {
|
|
42876
|
-
const checked = item.attrs?.checked ? " checked" : "";
|
|
42877
|
-
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
42878
|
-
}
|
|
42879
|
-
return `<li>${inner}</li>`;
|
|
42880
|
-
}
|
|
42881
|
-
// --- images ---------------------------------------------------------------
|
|
42882
|
-
imageToHtml(node) {
|
|
42883
|
-
const attrs = node.attrs ?? {};
|
|
42884
|
-
const parts = [];
|
|
42885
|
-
const src = attrs.src;
|
|
42886
|
-
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
42887
|
-
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
42888
|
-
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
42889
|
-
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
42890
|
-
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
42891
|
-
if (typeof attrs.class === "string" && attrs.class) {
|
|
42892
|
-
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
42893
|
-
}
|
|
42894
|
-
return `<img ${parts.join(" ")}>`;
|
|
42895
|
-
}
|
|
42896
|
-
// --- escaping -------------------------------------------------------------
|
|
42897
|
-
escapeText(text) {
|
|
42898
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
42899
|
-
}
|
|
42900
|
-
escapeAttr(text) {
|
|
42901
|
-
return this.escapeText(text).replace(/"/g, """);
|
|
42902
|
-
}
|
|
42903
|
-
};
|
|
42904
|
-
|
|
42905
43771
|
// src/generator/json/JsonFileGenerator.ts
|
|
42906
43772
|
var import_node_fs4 = require("fs");
|
|
42907
43773
|
var JsonFileGenerator = class {
|
|
@@ -43325,6 +44191,7 @@ var ConfigBuilder = class {
|
|
|
43325
44191
|
k = stringUtils.camelToKebab(k);
|
|
43326
44192
|
const resolvedGroups = resolveGroupReferences(k);
|
|
43327
44193
|
const hasOuterExport = Object.prototype.hasOwnProperty.call(tag, "exportJsonKey");
|
|
44194
|
+
const hasOuterHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
43328
44195
|
if (!hasOuterExport && tag.jsonKey != null) {
|
|
43329
44196
|
const headingPath = [...pathStack, `tags.${tag.key}`].join(" / ");
|
|
43330
44197
|
exportJsonKeyErrors.push(
|
|
@@ -43334,6 +44201,8 @@ var ConfigBuilder = class {
|
|
|
43334
44201
|
for (const ref of resolvedGroups) {
|
|
43335
44202
|
const exportJsonKeyChosen = hasOuterExport ? tag.exportJsonKey : ref.exportJsonKey;
|
|
43336
44203
|
const hasExportChosen = hasOuterExport || !!ref.hasExportJsonKey;
|
|
44204
|
+
const htmlKeyChosen = hasOuterHtml ? tag.htmlKey : ref.htmlKey;
|
|
44205
|
+
const hasHtmlChosen = hasOuterHtml || !!ref.hasHtmlKey;
|
|
43337
44206
|
const min = tag.minCount != null ? tag.minCount : ref.min;
|
|
43338
44207
|
const max = tag.maxCount != null ? tag.maxCount : ref.max;
|
|
43339
44208
|
const description = tag.description ? tag.description : ref.description;
|
|
@@ -43341,6 +44210,7 @@ var ConfigBuilder = class {
|
|
|
43341
44210
|
type: "group",
|
|
43342
44211
|
key: ref.key,
|
|
43343
44212
|
...hasExportChosen ? { jsonKey: exportJsonKeyChosen } : {},
|
|
44213
|
+
...hasHtmlChosen ? { htmlKey: htmlKeyChosen } : {},
|
|
43344
44214
|
...min != null ? { min } : {},
|
|
43345
44215
|
...max != null ? { max } : {},
|
|
43346
44216
|
...description ? { description } : {}
|
|
@@ -43369,10 +44239,13 @@ var ConfigBuilder = class {
|
|
|
43369
44239
|
);
|
|
43370
44240
|
exportJsonKeyField = {};
|
|
43371
44241
|
}
|
|
44242
|
+
const hasHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
44243
|
+
const htmlKeyField = hasHtml ? { htmlKey: tag.htmlKey } : {};
|
|
43372
44244
|
const t = {
|
|
43373
44245
|
type: "tag",
|
|
43374
44246
|
key: tagName,
|
|
43375
44247
|
...exportJsonKeyField,
|
|
44248
|
+
...htmlKeyField,
|
|
43376
44249
|
format,
|
|
43377
44250
|
default: tag.defaultValue ?? null,
|
|
43378
44251
|
...tag.nullable ? { nullable: true } : {},
|
|
@@ -43395,6 +44268,13 @@ var ConfigBuilder = class {
|
|
|
43395
44268
|
);
|
|
43396
44269
|
return {};
|
|
43397
44270
|
};
|
|
44271
|
+
const cardHtmlKeyField = (container, htmlExportKey) => {
|
|
44272
|
+
const c = container;
|
|
44273
|
+
if (Object.prototype.hasOwnProperty.call(c, htmlExportKey)) {
|
|
44274
|
+
return { htmlKey: c[htmlExportKey] };
|
|
44275
|
+
}
|
|
44276
|
+
return {};
|
|
44277
|
+
};
|
|
43398
44278
|
const serializeCardSet = (cardSetKey) => {
|
|
43399
44279
|
const variantBodyFormat = (variant) => variant.format ?? TextFormat.bitmarkText;
|
|
43400
44280
|
const cardSetConfig = CARDSETS[cardSetKey];
|
|
@@ -43425,6 +44305,7 @@ var ConfigBuilder = class {
|
|
|
43425
44305
|
}
|
|
43426
44306
|
return {
|
|
43427
44307
|
...cardJsonKeyField(variant, "jsonKey", "exportJsonKey", variantPath),
|
|
44308
|
+
...cardHtmlKeyField(variant, "htmlKey"),
|
|
43428
44309
|
format: variantBodyFormat(variant),
|
|
43429
44310
|
tags: variantTags,
|
|
43430
44311
|
repeatCount: variant.repeatCount ?? 1,
|
|
@@ -43436,6 +44317,7 @@ var ConfigBuilder = class {
|
|
|
43436
44317
|
name: side.name,
|
|
43437
44318
|
...side.repeat ? { repeat: side.repeat } : {},
|
|
43438
44319
|
...cardJsonKeyField(side, "jsonKey", "exportJsonKey", sidePath),
|
|
44320
|
+
...cardHtmlKeyField(side, "htmlKey"),
|
|
43439
44321
|
variants
|
|
43440
44322
|
};
|
|
43441
44323
|
});
|
|
@@ -43443,20 +44325,23 @@ var ConfigBuilder = class {
|
|
|
43443
44325
|
const cards = Object.entries(cardSetConfig.sections).map(([sectionName, section]) => {
|
|
43444
44326
|
const sectionPath = `cardSets.${normalizedKey} / cards.${sectionName}`;
|
|
43445
44327
|
const hasSideExport = Object.prototype.hasOwnProperty.call(section, "sideExportJsonKey");
|
|
44328
|
+
const hasSideHtml = Object.prototype.hasOwnProperty.call(section, "sideHtmlKey");
|
|
43446
44329
|
let cardSides = sides;
|
|
43447
|
-
if (hasSideExport || section.sideJsonKey != null) {
|
|
44330
|
+
if (hasSideExport || section.sideJsonKey != null || hasSideHtml) {
|
|
43448
44331
|
const sideOverride = cardJsonKeyField(
|
|
43449
44332
|
section,
|
|
43450
44333
|
"sideJsonKey",
|
|
43451
44334
|
"sideExportJsonKey",
|
|
43452
44335
|
`${sectionPath} / sides.*`
|
|
43453
44336
|
);
|
|
43454
|
-
|
|
44337
|
+
const sideHtmlOverride = cardHtmlKeyField(section, "sideHtmlKey");
|
|
44338
|
+
cardSides = sides.map((s) => ({ ...s, ...sideOverride, ...sideHtmlOverride }));
|
|
43455
44339
|
}
|
|
43456
44340
|
return {
|
|
43457
44341
|
name: sectionName,
|
|
43458
44342
|
...section.isDefault ? { isDefault: true } : {},
|
|
43459
44343
|
...cardJsonKeyField(section, "jsonKey", "exportJsonKey", sectionPath),
|
|
44344
|
+
...cardHtmlKeyField(section, "htmlKey"),
|
|
43460
44345
|
// PLAN-085: per-section cardinality. Emit only when non-default
|
|
43461
44346
|
// (treat `0` / undefined as "unbounded — omit").
|
|
43462
44347
|
...section.minCount != null && section.minCount !== 0 ? { min: section.minCount } : {},
|
|
@@ -43464,7 +44349,7 @@ var ConfigBuilder = class {
|
|
|
43464
44349
|
sides: cardSides
|
|
43465
44350
|
};
|
|
43466
44351
|
});
|
|
43467
|
-
return { name: normalizedKey, cards };
|
|
44352
|
+
return { name: normalizedKey, ...cardHtmlKeyField(cardSetConfig, "htmlKey"), cards };
|
|
43468
44353
|
}
|
|
43469
44354
|
const cardSetPath = `cardSets.${normalizedKey} / cards.default`;
|
|
43470
44355
|
return {
|
|
@@ -43474,6 +44359,7 @@ var ConfigBuilder = class {
|
|
|
43474
44359
|
name: "default",
|
|
43475
44360
|
isDefault: true,
|
|
43476
44361
|
...cardJsonKeyField(cardSetConfig, "jsonKey", "exportJsonKey", cardSetPath),
|
|
44362
|
+
...cardHtmlKeyField(cardSetConfig, "htmlKey"),
|
|
43477
44363
|
sides
|
|
43478
44364
|
}
|
|
43479
44365
|
]
|
|
@@ -43513,6 +44399,10 @@ var ConfigBuilder = class {
|
|
|
43513
44399
|
ref.exportJsonKey = t.jsonKey;
|
|
43514
44400
|
ref.hasExportJsonKey = true;
|
|
43515
44401
|
}
|
|
44402
|
+
if (Object.prototype.hasOwnProperty.call(t, "htmlKey")) {
|
|
44403
|
+
ref.htmlKey = t.htmlKey;
|
|
44404
|
+
ref.hasHtmlKey = true;
|
|
44405
|
+
}
|
|
43516
44406
|
replacements.push(ref);
|
|
43517
44407
|
}
|
|
43518
44408
|
squashedGroups.set(groupKey, replacements);
|
|
@@ -43547,6 +44437,7 @@ var ConfigBuilder = class {
|
|
|
43547
44437
|
type: "group",
|
|
43548
44438
|
key: ref.key,
|
|
43549
44439
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44440
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43550
44441
|
...ref.min != null ? { min: ref.min } : {},
|
|
43551
44442
|
...ref.max != null ? { max: ref.max } : {},
|
|
43552
44443
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43560,6 +44451,7 @@ var ConfigBuilder = class {
|
|
|
43560
44451
|
type: "group",
|
|
43561
44452
|
key: ref.key,
|
|
43562
44453
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44454
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43563
44455
|
...ref.min != null ? { min: ref.min } : {},
|
|
43564
44456
|
...ref.max != null ? { max: ref.max } : {},
|
|
43565
44457
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43689,6 +44581,7 @@ var ConfigBuilder = class {
|
|
|
43689
44581
|
type: "group",
|
|
43690
44582
|
key: ref.key,
|
|
43691
44583
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
44584
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43692
44585
|
...ref.min != null ? { min: ref.min } : {},
|
|
43693
44586
|
...ref.max != null ? { max: ref.max } : {},
|
|
43694
44587
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43878,499 +44771,6 @@ var ConfigBuilder = class {
|
|
|
43878
44771
|
}
|
|
43879
44772
|
};
|
|
43880
44773
|
|
|
43881
|
-
// src/parser/html/HtmlDom.ts
|
|
43882
|
-
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
43883
|
-
"area",
|
|
43884
|
-
"base",
|
|
43885
|
-
"br",
|
|
43886
|
-
"col",
|
|
43887
|
-
"embed",
|
|
43888
|
-
"hr",
|
|
43889
|
-
"img",
|
|
43890
|
-
"input",
|
|
43891
|
-
"link",
|
|
43892
|
-
"meta",
|
|
43893
|
-
"param",
|
|
43894
|
-
"source",
|
|
43895
|
-
"track",
|
|
43896
|
-
"wbr"
|
|
43897
|
-
]);
|
|
43898
|
-
var IMPLIED_CLOSE = {
|
|
43899
|
-
li: /* @__PURE__ */ new Set(["li"]),
|
|
43900
|
-
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43901
|
-
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43902
|
-
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
43903
|
-
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43904
|
-
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43905
|
-
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43906
|
-
p: /* @__PURE__ */ new Set(["p"]),
|
|
43907
|
-
option: /* @__PURE__ */ new Set(["option"])
|
|
43908
|
-
};
|
|
43909
|
-
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
43910
|
-
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
43911
|
-
function parseAttrs(raw) {
|
|
43912
|
-
const attrs = {};
|
|
43913
|
-
if (!raw) return attrs;
|
|
43914
|
-
ATTR_RE.lastIndex = 0;
|
|
43915
|
-
let m;
|
|
43916
|
-
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
43917
|
-
const name = m[1].toLowerCase();
|
|
43918
|
-
let value = m[2] ?? "";
|
|
43919
|
-
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
43920
|
-
value = value.slice(1, -1);
|
|
43921
|
-
}
|
|
43922
|
-
attrs[name] = value;
|
|
43923
|
-
}
|
|
43924
|
-
return attrs;
|
|
43925
|
-
}
|
|
43926
|
-
function stripNonContent(html) {
|
|
43927
|
-
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, "");
|
|
43928
|
-
}
|
|
43929
|
-
function tokenize(html) {
|
|
43930
|
-
const tokens = [];
|
|
43931
|
-
const clean = stripNonContent(html);
|
|
43932
|
-
TAG_RE.lastIndex = 0;
|
|
43933
|
-
let lastIndex = 0;
|
|
43934
|
-
let m;
|
|
43935
|
-
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
43936
|
-
if (m.index > lastIndex) {
|
|
43937
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
43938
|
-
}
|
|
43939
|
-
lastIndex = TAG_RE.lastIndex;
|
|
43940
|
-
const isClose = m[1] === "/";
|
|
43941
|
-
const name = m[2].toLowerCase();
|
|
43942
|
-
if (isClose) {
|
|
43943
|
-
tokens.push({ kind: "close", name });
|
|
43944
|
-
} else {
|
|
43945
|
-
tokens.push({
|
|
43946
|
-
kind: "open",
|
|
43947
|
-
name,
|
|
43948
|
-
attrs: parseAttrs(m[3]),
|
|
43949
|
-
selfClose: m[4] === "/"
|
|
43950
|
-
});
|
|
43951
|
-
}
|
|
43952
|
-
}
|
|
43953
|
-
if (lastIndex < clean.length) {
|
|
43954
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
43955
|
-
}
|
|
43956
|
-
return tokens;
|
|
43957
|
-
}
|
|
43958
|
-
function parseHtml(html) {
|
|
43959
|
-
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
43960
|
-
const stack = [root];
|
|
43961
|
-
const top = () => stack[stack.length - 1];
|
|
43962
|
-
for (const token of tokenize(html)) {
|
|
43963
|
-
if (token.kind === "text") {
|
|
43964
|
-
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
43965
|
-
continue;
|
|
43966
|
-
}
|
|
43967
|
-
if (token.kind === "open") {
|
|
43968
|
-
const name = token.name;
|
|
43969
|
-
const closes = IMPLIED_CLOSE[name];
|
|
43970
|
-
if (closes) {
|
|
43971
|
-
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
43972
|
-
}
|
|
43973
|
-
const el = {
|
|
43974
|
-
type: "element",
|
|
43975
|
-
name,
|
|
43976
|
-
attrs: token.attrs ?? {},
|
|
43977
|
-
children: []
|
|
43978
|
-
};
|
|
43979
|
-
top().children.push(el);
|
|
43980
|
-
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
43981
|
-
stack.push(el);
|
|
43982
|
-
}
|
|
43983
|
-
continue;
|
|
43984
|
-
}
|
|
43985
|
-
for (let i = stack.length - 1; i > 0; i--) {
|
|
43986
|
-
if (stack[i].name === token.name) {
|
|
43987
|
-
stack.length = i;
|
|
43988
|
-
break;
|
|
43989
|
-
}
|
|
43990
|
-
}
|
|
43991
|
-
}
|
|
43992
|
-
return root.children;
|
|
43993
|
-
}
|
|
43994
|
-
function childElements(el, names) {
|
|
43995
|
-
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43996
|
-
}
|
|
43997
|
-
|
|
43998
|
-
// src/parser/html/HtmlTableParser.ts
|
|
43999
|
-
var MARK_TAGS = {
|
|
44000
|
-
b: "bold",
|
|
44001
|
-
strong: "bold",
|
|
44002
|
-
i: "italic",
|
|
44003
|
-
em: "italic",
|
|
44004
|
-
sup: "superscript",
|
|
44005
|
-
sub: "subscript",
|
|
44006
|
-
s: "strike",
|
|
44007
|
-
strike: "strike",
|
|
44008
|
-
del: "del",
|
|
44009
|
-
ins: "ins",
|
|
44010
|
-
u: "underline",
|
|
44011
|
-
mark: "highlight",
|
|
44012
|
-
code: "code"
|
|
44013
|
-
};
|
|
44014
|
-
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
44015
|
-
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
44016
|
-
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
44017
|
-
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
44018
|
-
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
44019
|
-
var NAMED_ENTITIES = {
|
|
44020
|
-
amp: "&",
|
|
44021
|
-
lt: "<",
|
|
44022
|
-
gt: ">",
|
|
44023
|
-
quot: '"',
|
|
44024
|
-
apos: "'",
|
|
44025
|
-
nbsp: "\xA0"
|
|
44026
|
-
};
|
|
44027
|
-
function decodeEntities(text) {
|
|
44028
|
-
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
44029
|
-
if (body[0] === "#") {
|
|
44030
|
-
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
44031
|
-
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
44032
|
-
try {
|
|
44033
|
-
return String.fromCodePoint(code);
|
|
44034
|
-
} catch {
|
|
44035
|
-
return whole;
|
|
44036
|
-
}
|
|
44037
|
-
}
|
|
44038
|
-
return whole;
|
|
44039
|
-
}
|
|
44040
|
-
return NAMED_ENTITIES[body] ?? whole;
|
|
44041
|
-
});
|
|
44042
|
-
}
|
|
44043
|
-
function intAttr(value) {
|
|
44044
|
-
if (value == null) return void 0;
|
|
44045
|
-
const n = Number.parseInt(value, 10);
|
|
44046
|
-
return Number.isInteger(n) ? n : void 0;
|
|
44047
|
-
}
|
|
44048
|
-
function isElement(node) {
|
|
44049
|
-
return node.type === "element";
|
|
44050
|
-
}
|
|
44051
|
-
var HtmlTableParser = class {
|
|
44052
|
-
constructor() {
|
|
44053
|
-
__publicField(this, "keepUnknownTags", false);
|
|
44054
|
-
}
|
|
44055
|
-
/**
|
|
44056
|
-
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
44057
|
-
*/
|
|
44058
|
-
parse(html, options) {
|
|
44059
|
-
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
44060
|
-
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
44061
|
-
const onWarning = options?.onWarning;
|
|
44062
|
-
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
44063
|
-
const bits = [];
|
|
44064
|
-
for (const table of tables) {
|
|
44065
|
-
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
44066
|
-
if (bit) bits.push(bit);
|
|
44067
|
-
}
|
|
44068
|
-
return bits;
|
|
44069
|
-
}
|
|
44070
|
-
// --- table extraction -----------------------------------------------------
|
|
44071
|
-
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
44072
|
-
collectTopLevelTables(nodes) {
|
|
44073
|
-
const tables = [];
|
|
44074
|
-
const visit = (node) => {
|
|
44075
|
-
if (!isElement(node)) return;
|
|
44076
|
-
if (node.name === "table") {
|
|
44077
|
-
tables.push(node);
|
|
44078
|
-
return;
|
|
44079
|
-
}
|
|
44080
|
-
node.children.forEach(visit);
|
|
44081
|
-
};
|
|
44082
|
-
nodes.forEach(visit);
|
|
44083
|
-
return tables;
|
|
44084
|
-
}
|
|
44085
|
-
tableToBit(table, tableFormat, onWarning) {
|
|
44086
|
-
const header = [];
|
|
44087
|
-
const body = [];
|
|
44088
|
-
const footer = [];
|
|
44089
|
-
let caption;
|
|
44090
|
-
for (const child of table.children) {
|
|
44091
|
-
if (!isElement(child)) continue;
|
|
44092
|
-
if (child.name === "caption") {
|
|
44093
|
-
const capContent = this.inlineNodes(child.children, []);
|
|
44094
|
-
const trimmed = this.trimInline(capContent);
|
|
44095
|
-
if (trimmed.length > 0) caption = trimmed;
|
|
44096
|
-
} else if (SECTION_TAGS.has(child.name)) {
|
|
44097
|
-
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
44098
|
-
for (const tr of childElements(child, ROW_TAGS)) {
|
|
44099
|
-
target.push(this.rowToCells(tr));
|
|
44100
|
-
}
|
|
44101
|
-
} else if (ROW_TAGS.has(child.name)) {
|
|
44102
|
-
body.push(this.rowToCells(child));
|
|
44103
|
-
}
|
|
44104
|
-
}
|
|
44105
|
-
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
44106
|
-
return void 0;
|
|
44107
|
-
}
|
|
44108
|
-
const tableExtended = {};
|
|
44109
|
-
if (header.length > 0) tableExtended.header = { rows: header };
|
|
44110
|
-
if (body.length > 0) tableExtended.body = { rows: body };
|
|
44111
|
-
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
44112
|
-
let tableData = tableExtended;
|
|
44113
|
-
if (tableFormat === "table") {
|
|
44114
|
-
if (this.isLossyAsBasic(tableExtended)) {
|
|
44115
|
-
onWarning?.(
|
|
44116
|
-
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
44117
|
-
);
|
|
44118
|
-
}
|
|
44119
|
-
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
44120
|
-
}
|
|
44121
|
-
const bit = {
|
|
44122
|
-
type: tableFormat,
|
|
44123
|
-
format: "bitmark++",
|
|
44124
|
-
table: tableData
|
|
44125
|
-
};
|
|
44126
|
-
if (caption) bit.caption = caption;
|
|
44127
|
-
return bit;
|
|
44128
|
-
}
|
|
44129
|
-
rowToCells(tr) {
|
|
44130
|
-
const cells = [];
|
|
44131
|
-
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
44132
|
-
cells.push(this.cellToJson(cell));
|
|
44133
|
-
}
|
|
44134
|
-
return { cells };
|
|
44135
|
-
}
|
|
44136
|
-
cellToJson(cell) {
|
|
44137
|
-
const json = {
|
|
44138
|
-
content: this.blockNodes(cell.children)
|
|
44139
|
-
};
|
|
44140
|
-
if (cell.name === "th") json.title = true;
|
|
44141
|
-
const rowspan = intAttr(cell.attrs.rowspan);
|
|
44142
|
-
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
44143
|
-
const colspan = intAttr(cell.attrs.colspan);
|
|
44144
|
-
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
44145
|
-
const scope = cell.attrs.scope?.toLowerCase();
|
|
44146
|
-
if (scope && VALID_SCOPES.has(scope)) {
|
|
44147
|
-
json.scope = scope;
|
|
44148
|
-
}
|
|
44149
|
-
const width = this.widthFromCell(cell);
|
|
44150
|
-
if (width != null) json.colwidth = width;
|
|
44151
|
-
return json;
|
|
44152
|
-
}
|
|
44153
|
-
widthFromCell(cell) {
|
|
44154
|
-
const attrWidth = intAttr(cell.attrs.width);
|
|
44155
|
-
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
44156
|
-
const style = cell.attrs.style;
|
|
44157
|
-
if (style) {
|
|
44158
|
-
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
44159
|
-
if (m) {
|
|
44160
|
-
const n = Number.parseInt(m[1], 10);
|
|
44161
|
-
if (Number.isInteger(n) && n > 0) return n;
|
|
44162
|
-
}
|
|
44163
|
-
}
|
|
44164
|
-
return void 0;
|
|
44165
|
-
}
|
|
44166
|
-
isLossyAsBasic(table) {
|
|
44167
|
-
if (table.footer) return true;
|
|
44168
|
-
if (table.header && table.header.rows.length > 1) return true;
|
|
44169
|
-
const sections = [table.header, table.body, table.footer];
|
|
44170
|
-
for (const section of sections) {
|
|
44171
|
-
if (!section) continue;
|
|
44172
|
-
for (const row of section.rows) {
|
|
44173
|
-
for (const cell of row.cells) {
|
|
44174
|
-
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
44175
|
-
}
|
|
44176
|
-
}
|
|
44177
|
-
}
|
|
44178
|
-
return false;
|
|
44179
|
-
}
|
|
44180
|
-
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
44181
|
-
/**
|
|
44182
|
-
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
44183
|
-
*/
|
|
44184
|
-
blockNodes(nodes) {
|
|
44185
|
-
const blocks = [];
|
|
44186
|
-
let inline = [];
|
|
44187
|
-
const flush = () => {
|
|
44188
|
-
const trimmed = this.trimInline(inline);
|
|
44189
|
-
inline = [];
|
|
44190
|
-
if (trimmed.length === 0) return;
|
|
44191
|
-
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
44192
|
-
blocks.push({ ...trimmed[0], type: "image" });
|
|
44193
|
-
} else {
|
|
44194
|
-
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
44195
|
-
}
|
|
44196
|
-
};
|
|
44197
|
-
for (const node of nodes) {
|
|
44198
|
-
if (!isElement(node)) {
|
|
44199
|
-
inline.push(...this.inlineText(node.value, []));
|
|
44200
|
-
continue;
|
|
44201
|
-
}
|
|
44202
|
-
const name = node.name;
|
|
44203
|
-
if (name === "p") {
|
|
44204
|
-
flush();
|
|
44205
|
-
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
44206
|
-
if (content.length > 0) {
|
|
44207
|
-
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
44208
|
-
}
|
|
44209
|
-
} else if (this.isListTag(name)) {
|
|
44210
|
-
flush();
|
|
44211
|
-
const list = this.listNode(node);
|
|
44212
|
-
if (list) blocks.push(list);
|
|
44213
|
-
} else {
|
|
44214
|
-
inline.push(...this.inlineFromElement(node, []));
|
|
44215
|
-
}
|
|
44216
|
-
}
|
|
44217
|
-
flush();
|
|
44218
|
-
return blocks;
|
|
44219
|
-
}
|
|
44220
|
-
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
44221
|
-
inlineNodes(nodes, marks) {
|
|
44222
|
-
const out = [];
|
|
44223
|
-
for (const node of nodes) {
|
|
44224
|
-
if (!isElement(node)) {
|
|
44225
|
-
out.push(...this.inlineText(node.value, marks));
|
|
44226
|
-
} else {
|
|
44227
|
-
out.push(...this.inlineFromElement(node, marks));
|
|
44228
|
-
}
|
|
44229
|
-
}
|
|
44230
|
-
return out;
|
|
44231
|
-
}
|
|
44232
|
-
inlineFromElement(el, marks) {
|
|
44233
|
-
const name = el.name;
|
|
44234
|
-
if (name === "br") {
|
|
44235
|
-
return [{ type: "hardBreak" }];
|
|
44236
|
-
}
|
|
44237
|
-
if (name === "img") {
|
|
44238
|
-
return [this.imageNode(el, true)];
|
|
44239
|
-
}
|
|
44240
|
-
const markType = MARK_TAGS[name];
|
|
44241
|
-
if (markType) {
|
|
44242
|
-
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
44243
|
-
}
|
|
44244
|
-
if (name === "a") {
|
|
44245
|
-
const linkMark = {
|
|
44246
|
-
type: "link",
|
|
44247
|
-
attrs: {
|
|
44248
|
-
href: el.attrs.href ?? "",
|
|
44249
|
-
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
44250
|
-
}
|
|
44251
|
-
};
|
|
44252
|
-
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
44253
|
-
}
|
|
44254
|
-
if (this.keepUnknownTags) {
|
|
44255
|
-
const open = this.serializeOpenTag(el);
|
|
44256
|
-
const close = `</${name}>`;
|
|
44257
|
-
return [
|
|
44258
|
-
...this.inlineText(open, marks),
|
|
44259
|
-
...this.inlineNodes(el.children, marks),
|
|
44260
|
-
...this.inlineText(close, marks)
|
|
44261
|
-
];
|
|
44262
|
-
}
|
|
44263
|
-
return this.inlineNodes(el.children, marks);
|
|
44264
|
-
}
|
|
44265
|
-
inlineText(raw, marks) {
|
|
44266
|
-
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
44267
|
-
if (text === "") return [];
|
|
44268
|
-
const node = { text, type: "text" };
|
|
44269
|
-
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
44270
|
-
return [node];
|
|
44271
|
-
}
|
|
44272
|
-
serializeOpenTag(el) {
|
|
44273
|
-
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
44274
|
-
return `<${el.name}${attrs}>`;
|
|
44275
|
-
}
|
|
44276
|
-
// --- lists ----------------------------------------------------------------
|
|
44277
|
-
isListTag(name) {
|
|
44278
|
-
return name === "ul" || name === "ol";
|
|
44279
|
-
}
|
|
44280
|
-
listNode(el) {
|
|
44281
|
-
const items = childElements(el, LI_TAGS);
|
|
44282
|
-
if (items.length === 0) return void 0;
|
|
44283
|
-
const isTask = el.name === "ul" && items.some((li) => {
|
|
44284
|
-
const firstEl = li.children.find(isElement);
|
|
44285
|
-
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
44286
|
-
});
|
|
44287
|
-
if (isTask) {
|
|
44288
|
-
return {
|
|
44289
|
-
type: "taskList",
|
|
44290
|
-
content: items.map((li) => this.taskItemNode(li))
|
|
44291
|
-
};
|
|
44292
|
-
}
|
|
44293
|
-
const type = this.listType(el);
|
|
44294
|
-
const node = {
|
|
44295
|
-
type,
|
|
44296
|
-
content: items.map((li) => this.listItemNode(li))
|
|
44297
|
-
};
|
|
44298
|
-
if (el.name === "ol") {
|
|
44299
|
-
const start = intAttr(el.attrs.start);
|
|
44300
|
-
if (start != null) {
|
|
44301
|
-
node.attrs = { start };
|
|
44302
|
-
}
|
|
44303
|
-
}
|
|
44304
|
-
return node;
|
|
44305
|
-
}
|
|
44306
|
-
listType(el) {
|
|
44307
|
-
if (el.name === "ol") {
|
|
44308
|
-
switch (el.attrs.type) {
|
|
44309
|
-
case "i":
|
|
44310
|
-
return "orderedListRomanLower";
|
|
44311
|
-
case "I":
|
|
44312
|
-
return "orderedListRoman";
|
|
44313
|
-
case "a":
|
|
44314
|
-
return "letteredListLower";
|
|
44315
|
-
case "A":
|
|
44316
|
-
return "letteredList";
|
|
44317
|
-
default:
|
|
44318
|
-
return "orderedList";
|
|
44319
|
-
}
|
|
44320
|
-
}
|
|
44321
|
-
const style = el.attrs.style ?? "";
|
|
44322
|
-
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
44323
|
-
return "bulletList";
|
|
44324
|
-
}
|
|
44325
|
-
listItemNode(li) {
|
|
44326
|
-
let content = this.blockNodes(li.children);
|
|
44327
|
-
if (content.length === 0) {
|
|
44328
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
44329
|
-
}
|
|
44330
|
-
return { type: "listItem", content };
|
|
44331
|
-
}
|
|
44332
|
-
taskItemNode(li) {
|
|
44333
|
-
const checkbox = li.children.find(
|
|
44334
|
-
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
44335
|
-
);
|
|
44336
|
-
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
44337
|
-
const rest = li.children.filter((c) => c !== checkbox);
|
|
44338
|
-
let content = this.blockNodes(rest);
|
|
44339
|
-
if (content.length === 0) {
|
|
44340
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
44341
|
-
}
|
|
44342
|
-
return { type: "taskItem", attrs: { checked }, content };
|
|
44343
|
-
}
|
|
44344
|
-
// --- images ---------------------------------------------------------------
|
|
44345
|
-
imageNode(el, inline) {
|
|
44346
|
-
const attrs = { src: el.attrs.src ?? "" };
|
|
44347
|
-
attrs.alt = el.attrs.alt ?? null;
|
|
44348
|
-
attrs.title = el.attrs.title ?? null;
|
|
44349
|
-
const width = intAttr(el.attrs.width);
|
|
44350
|
-
if (width != null) attrs.width = width;
|
|
44351
|
-
const height = intAttr(el.attrs.height);
|
|
44352
|
-
if (height != null) attrs.height = height;
|
|
44353
|
-
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
44354
|
-
return { type: inline ? "imageInline" : "image", attrs };
|
|
44355
|
-
}
|
|
44356
|
-
// --- whitespace -----------------------------------------------------------
|
|
44357
|
-
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
44358
|
-
trimInline(nodes) {
|
|
44359
|
-
const out = nodes.slice();
|
|
44360
|
-
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
44361
|
-
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
44362
|
-
if (out.length > 0 && out[0].type === "text") {
|
|
44363
|
-
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
44364
|
-
}
|
|
44365
|
-
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
44366
|
-
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
44367
|
-
const last = out.length - 1;
|
|
44368
|
-
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
44369
|
-
}
|
|
44370
|
-
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
44371
|
-
}
|
|
44372
|
-
};
|
|
44373
|
-
|
|
44374
44774
|
// src/BitmarkParserGenerator.ts
|
|
44375
44775
|
var Input = {
|
|
44376
44776
|
/**
|
|
@@ -45007,7 +45407,10 @@ var BitmarkParserGenerator = class {
|
|
|
45007
45407
|
outputFile: opts.outputFile,
|
|
45008
45408
|
fileOptions: opts.fileOptions,
|
|
45009
45409
|
jsonOptions: opts.jsonOptions,
|
|
45010
|
-
bitmarkOptions:
|
|
45410
|
+
bitmarkOptions: {
|
|
45411
|
+
...opts.bitmarkOptions,
|
|
45412
|
+
...opts.noBreakscaping ? { noBreakscaping: true } : {}
|
|
45413
|
+
}
|
|
45011
45414
|
});
|
|
45012
45415
|
}
|
|
45013
45416
|
const outputFormat = opts.outputFormat ?? "html";
|