@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
|
@@ -34,8 +34,8 @@ __export(index_exports, {
|
|
|
34
34
|
BoundingBoxIndex: () => BoundingBoxIndex,
|
|
35
35
|
Builder: () => Builder,
|
|
36
36
|
CardSetVersion: () => CardSetVersion,
|
|
37
|
-
HtmlTableGenerator: () =>
|
|
38
|
-
HtmlTableParser: () =>
|
|
37
|
+
HtmlTableGenerator: () => HtmlTableGenerator,
|
|
38
|
+
HtmlTableParser: () => HtmlTableParser,
|
|
39
39
|
InfoFormat: () => InfoFormat,
|
|
40
40
|
InfoType: () => InfoType,
|
|
41
41
|
Input: () => Input,
|
|
@@ -596,6 +596,14 @@ var BitType2 = {
|
|
|
596
596
|
smartStandardRemarkNonNormativeCollapsible: "smart-standard-remark-non-normative-collapsible",
|
|
597
597
|
smartStandardRemarkNormative: "smart-standard-remark-normative",
|
|
598
598
|
smartStandardRemarkNormativeCollapsible: "smart-standard-remark-normative-collapsible",
|
|
599
|
+
smartStandardRemarkTableExtendedImageNonNormative: "smart-standard-remark-table-extended-image-non-normative",
|
|
600
|
+
smartStandardRemarkTableExtendedImageNonNormativeCollapsible: "smart-standard-remark-table-extended-image-non-normative-collapsible",
|
|
601
|
+
smartStandardRemarkTableExtendedImageNormative: "smart-standard-remark-table-extended-image-normative",
|
|
602
|
+
smartStandardRemarkTableExtendedImageNormativeCollapsible: "smart-standard-remark-table-extended-image-normative-collapsible",
|
|
603
|
+
smartStandardRemarkTableExtendedNonNormative: "smart-standard-remark-table-extended-non-normative",
|
|
604
|
+
smartStandardRemarkTableExtendedNonNormativeCollapsible: "smart-standard-remark-table-extended-non-normative-collapsible",
|
|
605
|
+
smartStandardRemarkTableExtendedNormative: "smart-standard-remark-table-extended-normative",
|
|
606
|
+
smartStandardRemarkTableExtendedNormativeCollapsible: "smart-standard-remark-table-extended-normative-collapsible",
|
|
599
607
|
smartStandardRemarkTableImageNonNormative: "smart-standard-remark-table-image-non-normative",
|
|
600
608
|
smartStandardRemarkTableImageNonNormativeCollapsible: "smart-standard-remark-table-image-non-normative-collapsible",
|
|
601
609
|
smartStandardRemarkTableImageNormative: "smart-standard-remark-table-image-normative",
|
|
@@ -604,6 +612,14 @@ var BitType2 = {
|
|
|
604
612
|
smartStandardRemarkTableNonNormativeCollapsible: "smart-standard-remark-table-non-normative-collapsible",
|
|
605
613
|
smartStandardRemarkTableNormative: "smart-standard-remark-table-normative",
|
|
606
614
|
smartStandardRemarkTableNormativeCollapsible: "smart-standard-remark-table-normative-collapsible",
|
|
615
|
+
smartStandardTableExtendedImageNonNormative: "smart-standard-table-extended-image-non-normative",
|
|
616
|
+
smartStandardTableExtendedImageNonNormativeCollapsible: "smart-standard-table-extended-image-non-normative-collapsible",
|
|
617
|
+
smartStandardTableExtendedImageNormative: "smart-standard-table-extended-image-normative",
|
|
618
|
+
smartStandardTableExtendedImageNormativeCollapsible: "smart-standard-table-extended-image-normative-collapsible",
|
|
619
|
+
smartStandardTableExtendedNonNormative: "smart-standard-table-extended-non-normative",
|
|
620
|
+
smartStandardTableExtendedNonNormativeCollapsible: "smart-standard-table-extended-non-normative-collapsible",
|
|
621
|
+
smartStandardTableExtendedNormative: "smart-standard-table-extended-normative",
|
|
622
|
+
smartStandardTableExtendedNormativeCollapsible: "smart-standard-table-extended-normative-collapsible",
|
|
607
623
|
smartStandardTableImageNonNormative: "smart-standard-table-image-non-normative",
|
|
608
624
|
smartStandardTableImageNonNormativeCollapsible: "smart-standard-table-image-non-normative-collapsible",
|
|
609
625
|
smartStandardTableImageNormative: "smart-standard-table-image-normative",
|
|
@@ -626,10 +642,18 @@ var BitType2 = {
|
|
|
626
642
|
standardNoteNormative: "standard-note-normative",
|
|
627
643
|
standardRemarkNonNormative: "standard-remark-non-normative",
|
|
628
644
|
standardRemarkNormative: "standard-remark-normative",
|
|
645
|
+
standardRemarkTableExtendedImageNonNormative: "standard-remark-table-extended-image-non-normative",
|
|
646
|
+
standardRemarkTableExtendedImageNormative: "standard-remark-table-extended-image-normative",
|
|
647
|
+
standardRemarkTableExtendedNonNormative: "standard-remark-table-extended-non-normative",
|
|
648
|
+
standardRemarkTableExtendedNormative: "standard-remark-table-extended-normative",
|
|
629
649
|
standardRemarkTableImageNonNormative: "standard-remark-table-image-non-normative",
|
|
630
650
|
standardRemarkTableImageNormative: "standard-remark-table-image-normative",
|
|
631
651
|
standardRemarkTableNonNormative: "standard-remark-table-non-normative",
|
|
632
652
|
standardRemarkTableNormative: "standard-remark-table-normative",
|
|
653
|
+
standardTableExtendedImageNonNormative: "standard-table-extended-image-non-normative",
|
|
654
|
+
standardTableExtendedImageNormative: "standard-table-extended-image-normative",
|
|
655
|
+
standardTableExtendedNonNormative: "standard-table-extended-non-normative",
|
|
656
|
+
standardTableExtendedNormative: "standard-table-extended-normative",
|
|
633
657
|
standardTableImageNonNormative: "standard-table-image-non-normative",
|
|
634
658
|
standardTableImageNormative: "standard-table-image-normative",
|
|
635
659
|
standardTableNonNormative: "standard-table-non-normative",
|
|
@@ -856,6 +880,10 @@ var AbstractTagConfig = class {
|
|
|
856
880
|
// New JSON-pattern jsonKey (export-only)
|
|
857
881
|
__publicField(this, "hasExportJsonKey");
|
|
858
882
|
// True iff exportJsonKey was explicitly set
|
|
883
|
+
__publicField(this, "htmlKey");
|
|
884
|
+
// HTML key-pattern (export-only)
|
|
885
|
+
__publicField(this, "hasHtmlKey");
|
|
886
|
+
// True iff htmlKey was explicitly set
|
|
859
887
|
__publicField(this, "deprecated");
|
|
860
888
|
this.type = params.type;
|
|
861
889
|
this.configKey = params.configKey;
|
|
@@ -866,6 +894,8 @@ var AbstractTagConfig = class {
|
|
|
866
894
|
this.jsonKey = params.jsonKey;
|
|
867
895
|
this.exportJsonKey = params.exportJsonKey;
|
|
868
896
|
this.hasExportJsonKey = params.hasExportJsonKey;
|
|
897
|
+
this.htmlKey = params.htmlKey;
|
|
898
|
+
this.hasHtmlKey = params.hasHtmlKey;
|
|
869
899
|
this.deprecated = params.deprecated;
|
|
870
900
|
}
|
|
871
901
|
};
|
|
@@ -987,7 +1017,7 @@ var ResourceTagConfig = class extends AbstractTagConfig {
|
|
|
987
1017
|
// src/model/config/CardVariantConfig.ts
|
|
988
1018
|
var CardVariantConfig = class {
|
|
989
1019
|
// Body text format. Default: bitmark++
|
|
990
|
-
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
|
|
1020
|
+
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format, htmlKey, hasHtmlKey = false) {
|
|
991
1021
|
__publicField(this, "tags");
|
|
992
1022
|
__publicField(this, "bodyAllowed");
|
|
993
1023
|
// Default: true
|
|
@@ -1001,6 +1031,9 @@ var CardVariantConfig = class {
|
|
|
1001
1031
|
__publicField(this, "exportJsonKey");
|
|
1002
1032
|
// New JSON-pattern jsonKey
|
|
1003
1033
|
__publicField(this, "hasExportJsonKey");
|
|
1034
|
+
__publicField(this, "htmlKey");
|
|
1035
|
+
// HTML key-pattern
|
|
1036
|
+
__publicField(this, "hasHtmlKey");
|
|
1004
1037
|
__publicField(this, "format");
|
|
1005
1038
|
this.tags = tags2;
|
|
1006
1039
|
this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
|
|
@@ -1009,6 +1042,8 @@ var CardVariantConfig = class {
|
|
|
1009
1042
|
this.jsonKey = jsonKey;
|
|
1010
1043
|
this.exportJsonKey = exportJsonKey;
|
|
1011
1044
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1045
|
+
this.htmlKey = htmlKey;
|
|
1046
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1012
1047
|
this.format = format;
|
|
1013
1048
|
}
|
|
1014
1049
|
toString(options) {
|
|
@@ -1033,18 +1068,22 @@ ${tag.toString(opts)}`;
|
|
|
1033
1068
|
|
|
1034
1069
|
// src/model/config/CardSideConfig.ts
|
|
1035
1070
|
var CardSideConfig = class {
|
|
1036
|
-
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
|
|
1071
|
+
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false, htmlKey, hasHtmlKey = false) {
|
|
1037
1072
|
__publicField(this, "name");
|
|
1038
1073
|
__publicField(this, "repeat");
|
|
1039
1074
|
__publicField(this, "jsonKey");
|
|
1040
1075
|
__publicField(this, "exportJsonKey");
|
|
1041
1076
|
__publicField(this, "hasExportJsonKey");
|
|
1077
|
+
__publicField(this, "htmlKey");
|
|
1078
|
+
__publicField(this, "hasHtmlKey");
|
|
1042
1079
|
__publicField(this, "variants");
|
|
1043
1080
|
this.name = name;
|
|
1044
1081
|
this.repeat = repeat;
|
|
1045
1082
|
this.jsonKey = jsonKey;
|
|
1046
1083
|
this.exportJsonKey = exportJsonKey;
|
|
1047
1084
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1085
|
+
this.htmlKey = htmlKey;
|
|
1086
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1048
1087
|
this.variants = variants;
|
|
1049
1088
|
}
|
|
1050
1089
|
toString(options) {
|
|
@@ -1066,17 +1105,21 @@ var CardSideConfig = class {
|
|
|
1066
1105
|
|
|
1067
1106
|
// src/model/config/CardSetConfig.ts
|
|
1068
1107
|
var CardSetConfig = class {
|
|
1069
|
-
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
|
|
1108
|
+
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides, htmlKey = void 0, hasHtmlKey = false) {
|
|
1070
1109
|
__publicField(this, "configKey");
|
|
1071
1110
|
__publicField(this, "jsonKey");
|
|
1072
1111
|
__publicField(this, "exportJsonKey");
|
|
1073
1112
|
__publicField(this, "hasExportJsonKey");
|
|
1113
|
+
__publicField(this, "htmlKey");
|
|
1114
|
+
__publicField(this, "hasHtmlKey");
|
|
1074
1115
|
__publicField(this, "sections");
|
|
1075
1116
|
__publicField(this, "sides");
|
|
1076
1117
|
this.configKey = configKey;
|
|
1077
1118
|
this.jsonKey = jsonKey;
|
|
1078
1119
|
this.exportJsonKey = exportJsonKey;
|
|
1079
1120
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1121
|
+
this.htmlKey = htmlKey;
|
|
1122
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1080
1123
|
this.sections = sections;
|
|
1081
1124
|
this.sides = sides;
|
|
1082
1125
|
}
|
|
@@ -1373,6 +1416,8 @@ var propertyKeys = {
|
|
|
1373
1416
|
property_externalLinkText: "@externalLinkText",
|
|
1374
1417
|
property_feedbackEngine: "@feedbackEngine",
|
|
1375
1418
|
property_feedbackType: "@feedbackType",
|
|
1419
|
+
property_userFeedbackTranslationUrl: "@userFeedbackTranslationUrl",
|
|
1420
|
+
property_userFeedbackContentUrl: "@userFeedbackContentUrl",
|
|
1376
1421
|
property_flashcardSet: "@flashcardSet",
|
|
1377
1422
|
property_focusX: "@focusX",
|
|
1378
1423
|
property_focusY: "@focusY",
|
|
@@ -3756,6 +3801,16 @@ var CARDSETS = {
|
|
|
3756
3801
|
[CardSetConfigKey.table]: {
|
|
3757
3802
|
jsonKey: null,
|
|
3758
3803
|
exportJsonKey: null,
|
|
3804
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping. The classic (non-extended)
|
|
3805
|
+
// table produces the same `<table>`/`<thead>`/`<tbody>`/`<tfoot>` structure as
|
|
3806
|
+
// table-extended, so the structural htmlKeys mirror that cardSet. NOTE: the
|
|
3807
|
+
// JSON side routes the FIRST header card → `columns` (header) and SUBSEQUENT
|
|
3808
|
+
// header cards → `data` (body); HTML uses a uniform `<thead>` for the whole
|
|
3809
|
+
// `table-header` section, so a multi-card header (e.g. a second header card
|
|
3810
|
+
// that JSON sends to `data`) renders as additional `<thead>` rows rather than
|
|
3811
|
+
// moving to `<tbody>`. Per-card header/body splitting needs engine-level
|
|
3812
|
+
// routing not yet expressible in the pattern vocabulary — see PLAN-109.
|
|
3813
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3759
3814
|
sections: {
|
|
3760
3815
|
"table-header": {
|
|
3761
3816
|
// First header card's row of cells → `columns`. Subsequent header
|
|
@@ -3774,25 +3829,36 @@ var CARDSETS = {
|
|
|
3774
3829
|
},
|
|
3775
3830
|
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3776
3831
|
{ "@bit": { table: { data: ["$"] } } }
|
|
3777
|
-
]
|
|
3832
|
+
],
|
|
3833
|
+
// Header section → `<thead>` rows of `<th>`; `@tableColWidth` bubbles a
|
|
3834
|
+
// `width` attr onto the enclosing `<th>` (HTML-C2).
|
|
3835
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3836
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3778
3837
|
},
|
|
3779
3838
|
"table-body": {
|
|
3780
3839
|
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3781
3840
|
// This is the default section (no qualifier → cards land here).
|
|
3782
3841
|
jsonKey: "table.data",
|
|
3783
3842
|
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3843
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3784
3844
|
isDefault: true
|
|
3785
3845
|
},
|
|
3786
3846
|
"table-footer": {
|
|
3787
3847
|
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3788
3848
|
jsonKey: "table.data",
|
|
3789
|
-
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3849
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3850
|
+
// Footer cells route to `data` (not `columns`), so they are `<td>` (no
|
|
3851
|
+
// sideHtmlKey override — the cell side default applies).
|
|
3852
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } }
|
|
3790
3853
|
}
|
|
3791
3854
|
},
|
|
3792
3855
|
sides: [
|
|
3793
3856
|
{
|
|
3794
3857
|
name: "cell",
|
|
3795
3858
|
repeat: true,
|
|
3859
|
+
// Default (body/footer) cell → `<td>`; the header section overrides to
|
|
3860
|
+
// `<th>` via its sideHtmlKey (HTML.md §8).
|
|
3861
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3796
3862
|
variants: [
|
|
3797
3863
|
{
|
|
3798
3864
|
jsonKey: null,
|
|
@@ -3809,21 +3875,32 @@ var CARDSETS = {
|
|
|
3809
3875
|
},
|
|
3810
3876
|
{
|
|
3811
3877
|
key: ConfigKey.property_tableCellType,
|
|
3878
|
+
// HTML.md §8: first-match predicate selecting `<th>` vs `<td>`.
|
|
3879
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3812
3880
|
description: "Table cell type (th/td).",
|
|
3813
3881
|
format: TagFormat.plainText
|
|
3814
3882
|
},
|
|
3815
3883
|
{
|
|
3816
3884
|
key: ConfigKey.property_tableRowSpan,
|
|
3885
|
+
// HTML-C2: contribute a `rowspan` attribute onto the enclosing
|
|
3886
|
+
// cell element (`<th>`/`<td>`).
|
|
3887
|
+
htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
|
|
3817
3888
|
description: "Number of rows the cell spans.",
|
|
3818
3889
|
format: TagFormat.number
|
|
3819
3890
|
},
|
|
3820
3891
|
{
|
|
3821
3892
|
key: ConfigKey.property_tableColSpan,
|
|
3893
|
+
// HTML-C2: contribute a `colspan` attribute onto the enclosing
|
|
3894
|
+
// cell element (`<th>`/`<td>`).
|
|
3895
|
+
htmlKey: { "@el": { "@attr": { colspan: "$" } } },
|
|
3822
3896
|
description: "Number of columns the cell spans.",
|
|
3823
3897
|
format: TagFormat.number
|
|
3824
3898
|
},
|
|
3825
3899
|
{
|
|
3826
3900
|
key: ConfigKey.property_tableScope,
|
|
3901
|
+
// HTML-C2: contribute a `scope` attribute onto the enclosing
|
|
3902
|
+
// cell element (`<th>`/`<td>`).
|
|
3903
|
+
htmlKey: { "@el": { "@attr": { scope: "$" } } },
|
|
3827
3904
|
description: "Scope attribute for header cells.",
|
|
3828
3905
|
format: TagFormat.plainText
|
|
3829
3906
|
},
|
|
@@ -3831,6 +3908,9 @@ var CARDSETS = {
|
|
|
3831
3908
|
key: ConfigKey.property_tableColWidth,
|
|
3832
3909
|
jsonKey: "^table.columnWidths[{s}]",
|
|
3833
3910
|
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
3911
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3912
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3913
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3834
3914
|
description: "Width for the column.",
|
|
3835
3915
|
format: TagFormat.number
|
|
3836
3916
|
}
|
|
@@ -3846,6 +3926,12 @@ var CARDSETS = {
|
|
|
3846
3926
|
//
|
|
3847
3927
|
[CardSetConfigKey.tableExtended]: {
|
|
3848
3928
|
jsonKey: null,
|
|
3929
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping for the extended table.
|
|
3930
|
+
// The card-set container is the `<table>` element; each section is a
|
|
3931
|
+
// table section element (`<thead>`/`<tbody>`/`<tfoot>`) whose children are
|
|
3932
|
+
// `<tr>` rows, and each cell side is a `<td>` (body) or `<th>` (header /
|
|
3933
|
+
// footer, via the section sideHtmlKey override).
|
|
3934
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3849
3935
|
sections: {
|
|
3850
3936
|
"table-header": {
|
|
3851
3937
|
jsonKey: "table.header.rows",
|
|
@@ -3865,19 +3951,29 @@ var CARDSETS = {
|
|
|
3865
3951
|
},
|
|
3866
3952
|
{ table: { header: { rows: ["$"] } } }
|
|
3867
3953
|
],
|
|
3954
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3868
3955
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3869
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3956
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3957
|
+
// Header cells are `<th>`. The `width` attribute is contributed by the
|
|
3958
|
+
// `@tableColWidth` tag, which bubbles it onto the enclosing `<th>`
|
|
3959
|
+
// (HTML-C2) — so it is not repeated here.
|
|
3960
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3870
3961
|
},
|
|
3871
3962
|
"table-body": {
|
|
3872
3963
|
jsonKey: "table.body.rows",
|
|
3873
3964
|
exportJsonKey: { table: { body: { rows: "$" } } },
|
|
3965
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3874
3966
|
isDefault: true
|
|
3875
3967
|
},
|
|
3876
3968
|
"table-footer": {
|
|
3877
3969
|
jsonKey: "table.footer.rows",
|
|
3878
3970
|
exportJsonKey: { table: { footer: { rows: "$" } } },
|
|
3971
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
|
|
3879
3972
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3880
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3973
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3974
|
+
// Footer cells render as `<th>` (mirrors the header `title: true`
|
|
3975
|
+
// mapping); §8 lists only the header side, so this parallels it.
|
|
3976
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3881
3977
|
}
|
|
3882
3978
|
},
|
|
3883
3979
|
sides: [
|
|
@@ -3886,6 +3982,9 @@ var CARDSETS = {
|
|
|
3886
3982
|
repeat: true,
|
|
3887
3983
|
jsonKey: "cells[{s}]",
|
|
3888
3984
|
exportJsonKey: { cells: { $s: "$" } },
|
|
3985
|
+
// Default (body) cell → `<td>`; the header/footer sections override the
|
|
3986
|
+
// side to `<th>` via their sideHtmlKey (HTML.md §8).
|
|
3987
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3889
3988
|
variants: [
|
|
3890
3989
|
{
|
|
3891
3990
|
jsonKey: "content",
|
|
@@ -3909,6 +4008,9 @@ var CARDSETS = {
|
|
|
3909
4008
|
key: ConfigKey.property_tableCellType,
|
|
3910
4009
|
jsonKey: "title|bool(th)",
|
|
3911
4010
|
exportJsonKey: [{ "@value=th": { title: true } }],
|
|
4011
|
+
// HTML.md §8: same first-match predicate machinery selecting
|
|
4012
|
+
// `<th>` vs `<td>` instead of `title:true` vs nothing.
|
|
4013
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3912
4014
|
description: "Table cell type (th/td).",
|
|
3913
4015
|
format: TagFormat.plainText
|
|
3914
4016
|
},
|
|
@@ -3916,6 +4018,9 @@ var CARDSETS = {
|
|
|
3916
4018
|
key: ConfigKey.property_tableRowSpan,
|
|
3917
4019
|
jsonKey: "rowspan",
|
|
3918
4020
|
exportJsonKey: { rowspan: "$" },
|
|
4021
|
+
// HTML-C2: contribute a `rowspan` attribute onto the enclosing
|
|
4022
|
+
// cell element (`<th>`/`<td>`).
|
|
4023
|
+
htmlKey: { "@el": { "@attr": { rowspan: "$" } } },
|
|
3919
4024
|
description: "Number of rows the cell spans.",
|
|
3920
4025
|
format: TagFormat.number
|
|
3921
4026
|
},
|
|
@@ -3923,6 +4028,9 @@ var CARDSETS = {
|
|
|
3923
4028
|
key: ConfigKey.property_tableColSpan,
|
|
3924
4029
|
jsonKey: "colspan",
|
|
3925
4030
|
exportJsonKey: { colspan: "$" },
|
|
4031
|
+
// HTML-C2: contribute a `colspan` attribute onto the enclosing
|
|
4032
|
+
// cell element (`<th>`/`<td>`).
|
|
4033
|
+
htmlKey: { "@el": { "@attr": { colspan: "$" } } },
|
|
3926
4034
|
description: "Number of columns the cell spans.",
|
|
3927
4035
|
format: TagFormat.number
|
|
3928
4036
|
},
|
|
@@ -3930,6 +4038,9 @@ var CARDSETS = {
|
|
|
3930
4038
|
key: ConfigKey.property_tableScope,
|
|
3931
4039
|
jsonKey: "scope",
|
|
3932
4040
|
exportJsonKey: { scope: "$" },
|
|
4041
|
+
// HTML-C2: contribute a `scope` attribute onto the enclosing
|
|
4042
|
+
// cell element (`<th>`/`<td>`).
|
|
4043
|
+
htmlKey: { "@el": { "@attr": { scope: "$" } } },
|
|
3933
4044
|
description: "Scope attribute for header cells.",
|
|
3934
4045
|
format: TagFormat.plainText
|
|
3935
4046
|
},
|
|
@@ -3938,6 +4049,9 @@ var CARDSETS = {
|
|
|
3938
4049
|
// PLAN-080: write to the cell's `colwidth` field.
|
|
3939
4050
|
jsonKey: "colwidth",
|
|
3940
4051
|
exportJsonKey: { colwidth: "$" },
|
|
4052
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
4053
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
4054
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3941
4055
|
description: "Width for the column.",
|
|
3942
4056
|
format: TagFormat.number
|
|
3943
4057
|
}
|
|
@@ -5737,6 +5851,16 @@ var GROUPS = {
|
|
|
5737
5851
|
description: "External Id of the translated book",
|
|
5738
5852
|
format: TagFormat.plainText
|
|
5739
5853
|
},
|
|
5854
|
+
{
|
|
5855
|
+
key: ConfigKey.property_userFeedbackTranslationUrl,
|
|
5856
|
+
description: "URL to an external feedback form for book translation feedback",
|
|
5857
|
+
format: TagFormat.plainText
|
|
5858
|
+
},
|
|
5859
|
+
{
|
|
5860
|
+
key: ConfigKey.property_userFeedbackContentUrl,
|
|
5861
|
+
description: "URL to an external feedback form for book content feedback",
|
|
5862
|
+
format: TagFormat.plainText
|
|
5863
|
+
},
|
|
5740
5864
|
{
|
|
5741
5865
|
key: ConfigKey.property_duration,
|
|
5742
5866
|
description: "The duration of the book",
|
|
@@ -6866,7 +6990,9 @@ var ConfigHydrator = class {
|
|
|
6866
6990
|
variantsOfSide,
|
|
6867
6991
|
_side.jsonKey,
|
|
6868
6992
|
_side.exportJsonKey,
|
|
6869
|
-
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
|
|
6993
|
+
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey"),
|
|
6994
|
+
_side.htmlKey,
|
|
6995
|
+
Object.prototype.hasOwnProperty.call(_side, "htmlKey")
|
|
6870
6996
|
);
|
|
6871
6997
|
sides.push(sideConfig);
|
|
6872
6998
|
}
|
|
@@ -6876,7 +7002,9 @@ var ConfigHydrator = class {
|
|
|
6876
7002
|
_cardSetConfig.exportJsonKey,
|
|
6877
7003
|
Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
|
|
6878
7004
|
this.hydrateCardSections(_cardSetConfig.sections),
|
|
6879
|
-
sides
|
|
7005
|
+
sides,
|
|
7006
|
+
_cardSetConfig.htmlKey,
|
|
7007
|
+
Object.prototype.hasOwnProperty.call(_cardSetConfig, "htmlKey")
|
|
6880
7008
|
);
|
|
6881
7009
|
return cardSetConfig;
|
|
6882
7010
|
}
|
|
@@ -6888,10 +7016,14 @@ var ConfigHydrator = class {
|
|
|
6888
7016
|
jsonKey: v.jsonKey,
|
|
6889
7017
|
exportJsonKey: v.exportJsonKey,
|
|
6890
7018
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
|
|
7019
|
+
htmlKey: v.htmlKey,
|
|
7020
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(v, "htmlKey"),
|
|
6891
7021
|
isDefault: v.isDefault,
|
|
6892
7022
|
sideJsonKey: v.sideJsonKey,
|
|
6893
7023
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
6894
7024
|
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
7025
|
+
sideHtmlKey: v.sideHtmlKey,
|
|
7026
|
+
hasSideHtmlKey: Object.prototype.hasOwnProperty.call(v, "sideHtmlKey"),
|
|
6895
7027
|
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6896
7028
|
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6897
7029
|
// as unbounded).
|
|
@@ -6909,7 +7041,8 @@ var ConfigHydrator = class {
|
|
|
6909
7041
|
chain: _chain,
|
|
6910
7042
|
deprecated,
|
|
6911
7043
|
jsonKey,
|
|
6912
|
-
exportJsonKey
|
|
7044
|
+
exportJsonKey,
|
|
7045
|
+
htmlKey
|
|
6913
7046
|
} = _tag;
|
|
6914
7047
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6915
7048
|
if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
|
|
@@ -6928,6 +7061,8 @@ var ConfigHydrator = class {
|
|
|
6928
7061
|
jsonKey,
|
|
6929
7062
|
exportJsonKey,
|
|
6930
7063
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7064
|
+
htmlKey,
|
|
7065
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6931
7066
|
deprecated
|
|
6932
7067
|
});
|
|
6933
7068
|
return {
|
|
@@ -6947,7 +7082,8 @@ var ConfigHydrator = class {
|
|
|
6947
7082
|
values,
|
|
6948
7083
|
defaultValue,
|
|
6949
7084
|
jsonKey,
|
|
6950
|
-
exportJsonKey
|
|
7085
|
+
exportJsonKey,
|
|
7086
|
+
htmlKey
|
|
6951
7087
|
} = _tag;
|
|
6952
7088
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6953
7089
|
if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
|
|
@@ -6965,6 +7101,8 @@ var ConfigHydrator = class {
|
|
|
6965
7101
|
jsonKey,
|
|
6966
7102
|
exportJsonKey,
|
|
6967
7103
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7104
|
+
htmlKey,
|
|
7105
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6968
7106
|
format,
|
|
6969
7107
|
values,
|
|
6970
7108
|
defaultValue,
|
|
@@ -6984,7 +7122,8 @@ var ConfigHydrator = class {
|
|
|
6984
7122
|
chain: _chain,
|
|
6985
7123
|
deprecated,
|
|
6986
7124
|
jsonKey,
|
|
6987
|
-
exportJsonKey
|
|
7125
|
+
exportJsonKey,
|
|
7126
|
+
htmlKey
|
|
6988
7127
|
} = _tag;
|
|
6989
7128
|
const configKey = (0, import_superenum15.Enum)(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6990
7129
|
if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
|
|
@@ -7002,6 +7141,8 @@ var ConfigHydrator = class {
|
|
|
7002
7141
|
jsonKey,
|
|
7003
7142
|
exportJsonKey,
|
|
7004
7143
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7144
|
+
htmlKey,
|
|
7145
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
7005
7146
|
deprecated
|
|
7006
7147
|
});
|
|
7007
7148
|
return {
|
|
@@ -7040,6 +7181,7 @@ var ConfigHydrator = class {
|
|
|
7040
7181
|
repeatCount,
|
|
7041
7182
|
jsonKey,
|
|
7042
7183
|
exportJsonKey,
|
|
7184
|
+
htmlKey,
|
|
7043
7185
|
format
|
|
7044
7186
|
} = _variant;
|
|
7045
7187
|
const tags2 = this.hydrateTagsConfig(_tags);
|
|
@@ -7051,7 +7193,9 @@ var ConfigHydrator = class {
|
|
|
7051
7193
|
jsonKey,
|
|
7052
7194
|
exportJsonKey,
|
|
7053
7195
|
Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
|
|
7054
|
-
format
|
|
7196
|
+
format,
|
|
7197
|
+
htmlKey,
|
|
7198
|
+
Object.prototype.hasOwnProperty.call(_variant, "htmlKey")
|
|
7055
7199
|
);
|
|
7056
7200
|
return cardSetConfig;
|
|
7057
7201
|
}
|
|
@@ -10184,11 +10328,6 @@ var BITS = {
|
|
|
10184
10328
|
baseBitType: BitType2._standard,
|
|
10185
10329
|
description: "Extractor rule bit, used to define extraction rules with reference images and instructions",
|
|
10186
10330
|
tags: [
|
|
10187
|
-
{
|
|
10188
|
-
exportJsonKey: { title: "$" },
|
|
10189
|
-
key: ConfigKey.tag_title,
|
|
10190
|
-
description: "The name of the extraction rule"
|
|
10191
|
-
},
|
|
10192
10331
|
{
|
|
10193
10332
|
key: ConfigKey.group_resourceBitTags,
|
|
10194
10333
|
description: "Resource bit tags for extraction rule images"
|
|
@@ -10824,7 +10963,9 @@ var BITS = {
|
|
|
10824
10963
|
{
|
|
10825
10964
|
key: ConfigKey.property_caption,
|
|
10826
10965
|
description: "Caption for the table image, used to provide a description for the image",
|
|
10827
|
-
format: TagFormat.bitmarkText
|
|
10966
|
+
format: TagFormat.bitmarkText,
|
|
10967
|
+
// HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
|
|
10968
|
+
htmlKey: { "@el": "caption", "@children": "$" }
|
|
10828
10969
|
},
|
|
10829
10970
|
{
|
|
10830
10971
|
key: ConfigKey.group_backgroundWallpaper,
|
|
@@ -10867,6 +11008,26 @@ var BITS = {
|
|
|
10867
11008
|
baseBitType: BitType2.tableImage,
|
|
10868
11009
|
description: "Standard non-normative remark table image bit, used to create non-normative remark images in tables in articles or books"
|
|
10869
11010
|
},
|
|
11011
|
+
[BitType2.standardTableExtendedImageNormative]: {
|
|
11012
|
+
since: "1.16.0",
|
|
11013
|
+
baseBitType: BitType2.tableExtendedImage,
|
|
11014
|
+
description: "Standard normative extended table image bit, used to create normative extended images in tables in articles or books"
|
|
11015
|
+
},
|
|
11016
|
+
[BitType2.standardTableExtendedImageNonNormative]: {
|
|
11017
|
+
since: "1.16.0",
|
|
11018
|
+
baseBitType: BitType2.tableExtendedImage,
|
|
11019
|
+
description: "Standard non-normative extended table image bit, used to create non-normative extended images in tables in articles or books"
|
|
11020
|
+
},
|
|
11021
|
+
[BitType2.standardRemarkTableExtendedImageNormative]: {
|
|
11022
|
+
since: "1.17.0",
|
|
11023
|
+
baseBitType: BitType2.tableExtendedImage,
|
|
11024
|
+
description: "Standard normative remark extended table image bit, used to create normative remark extended images in tables in articles or books"
|
|
11025
|
+
},
|
|
11026
|
+
[BitType2.standardRemarkTableExtendedImageNonNormative]: {
|
|
11027
|
+
since: "1.17.0",
|
|
11028
|
+
baseBitType: BitType2.tableExtendedImage,
|
|
11029
|
+
description: "Standard non-normative remark extended table image bit, used to create non-normative remark extended images in tables in articles or books"
|
|
11030
|
+
},
|
|
10870
11031
|
[BitType2.smartStandardTableImageNormative]: {
|
|
10871
11032
|
since: "1.28.0",
|
|
10872
11033
|
baseBitType: BitType2.standardTableImageNormative,
|
|
@@ -10887,6 +11048,26 @@ var BITS = {
|
|
|
10887
11048
|
baseBitType: BitType2.standardRemarkTableImageNonNormative,
|
|
10888
11049
|
description: "Smart standard non-normative remark table image bit, used to create smart standard non-normative remark images in tables in articles or books"
|
|
10889
11050
|
},
|
|
11051
|
+
[BitType2.smartStandardTableExtendedImageNormative]: {
|
|
11052
|
+
since: "1.28.0",
|
|
11053
|
+
baseBitType: BitType2.standardTableExtendedImageNormative,
|
|
11054
|
+
description: "Smart standard normative extended table image bit, used to create smart standard normative extended images in tables in articles or books"
|
|
11055
|
+
},
|
|
11056
|
+
[BitType2.smartStandardTableExtendedImageNonNormative]: {
|
|
11057
|
+
since: "1.28.0",
|
|
11058
|
+
baseBitType: BitType2.standardTableExtendedImageNonNormative,
|
|
11059
|
+
description: "Smart standard non-normative extended table image bit, used to create smart standard non-normative extended images in tables in articles or books"
|
|
11060
|
+
},
|
|
11061
|
+
[BitType2.smartStandardRemarkTableExtendedImageNormative]: {
|
|
11062
|
+
since: "1.28.0",
|
|
11063
|
+
baseBitType: BitType2.standardRemarkTableExtendedImageNormative,
|
|
11064
|
+
description: "Smart standard normative remark extended table image bit, used to create smart standard normative remark extended images in tables in articles or books"
|
|
11065
|
+
},
|
|
11066
|
+
[BitType2.smartStandardRemarkTableExtendedImageNonNormative]: {
|
|
11067
|
+
since: "1.28.0",
|
|
11068
|
+
baseBitType: BitType2.standardRemarkTableExtendedImageNonNormative,
|
|
11069
|
+
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"
|
|
11070
|
+
},
|
|
10890
11071
|
[BitType2.smartStandardTableImageNormativeCollapsible]: {
|
|
10891
11072
|
since: "1.28.0",
|
|
10892
11073
|
baseBitType: BitType2.smartStandardTableImageNormative,
|
|
@@ -10907,6 +11088,26 @@ var BITS = {
|
|
|
10907
11088
|
baseBitType: BitType2.smartStandardRemarkTableImageNonNormative,
|
|
10908
11089
|
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"
|
|
10909
11090
|
},
|
|
11091
|
+
[BitType2.smartStandardTableExtendedImageNormativeCollapsible]: {
|
|
11092
|
+
since: "1.28.0",
|
|
11093
|
+
baseBitType: BitType2.smartStandardTableExtendedImageNormative,
|
|
11094
|
+
description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
|
|
11095
|
+
},
|
|
11096
|
+
[BitType2.smartStandardTableExtendedImageNonNormativeCollapsible]: {
|
|
11097
|
+
since: "1.28.0",
|
|
11098
|
+
baseBitType: BitType2.smartStandardTableExtendedImageNonNormative,
|
|
11099
|
+
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"
|
|
11100
|
+
},
|
|
11101
|
+
[BitType2.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
|
|
11102
|
+
since: "1.28.0",
|
|
11103
|
+
baseBitType: BitType2.smartStandardRemarkTableExtendedImageNormative,
|
|
11104
|
+
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"
|
|
11105
|
+
},
|
|
11106
|
+
[BitType2.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
|
|
11107
|
+
since: "1.28.0",
|
|
11108
|
+
baseBitType: BitType2.smartStandardRemarkTableExtendedImageNonNormative,
|
|
11109
|
+
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"
|
|
11110
|
+
},
|
|
10910
11111
|
[BitType2.imageLink]: {
|
|
10911
11112
|
since: "1.3.0",
|
|
10912
11113
|
baseBitType: BitType2._standard,
|
|
@@ -12455,7 +12656,12 @@ var BITS = {
|
|
|
12455
12656
|
{
|
|
12456
12657
|
key: ConfigKey.property_caption,
|
|
12457
12658
|
description: "Caption for the table, used to define the title of the table",
|
|
12458
|
-
format: TagFormat.bitmarkText
|
|
12659
|
+
format: TagFormat.bitmarkText,
|
|
12660
|
+
// HTML-10 / HTML-C2: a bit-level caption renders as the table's
|
|
12661
|
+
// `<caption>` — placed inside the idiomatic `<table>` container as
|
|
12662
|
+
// its first child. Outside a table context it falls back to the
|
|
12663
|
+
// residual carrier.
|
|
12664
|
+
htmlKey: { "@el": "caption", "@children": "$" }
|
|
12459
12665
|
},
|
|
12460
12666
|
{
|
|
12461
12667
|
key: ConfigKey.property_tableFixedHeader,
|
|
@@ -12540,7 +12746,9 @@ var BITS = {
|
|
|
12540
12746
|
{
|
|
12541
12747
|
key: ConfigKey.property_caption,
|
|
12542
12748
|
description: "Caption for the table image, used to provide a description for the image",
|
|
12543
|
-
format: TagFormat.bitmarkText
|
|
12749
|
+
format: TagFormat.bitmarkText,
|
|
12750
|
+
// HTML-10 / HTML-C2: render as the table's `<caption>` (see table bit).
|
|
12751
|
+
htmlKey: { "@el": "caption", "@children": "$" }
|
|
12544
12752
|
},
|
|
12545
12753
|
{
|
|
12546
12754
|
key: ConfigKey.group_backgroundWallpaper,
|
|
@@ -12583,6 +12791,26 @@ var BITS = {
|
|
|
12583
12791
|
baseBitType: BitType2.table,
|
|
12584
12792
|
description: "Standard non-normative remark table bit, used to create standard non-normative remark tables in articles or books"
|
|
12585
12793
|
},
|
|
12794
|
+
[BitType2.standardTableExtendedNormative]: {
|
|
12795
|
+
since: "1.16.0",
|
|
12796
|
+
baseBitType: BitType2.tableExtended,
|
|
12797
|
+
description: "Standard normative extended table bit, used to create standard normative extended tables in articles or books"
|
|
12798
|
+
},
|
|
12799
|
+
[BitType2.standardTableExtendedNonNormative]: {
|
|
12800
|
+
since: "1.16.0",
|
|
12801
|
+
baseBitType: BitType2.tableExtended,
|
|
12802
|
+
description: "Standard non-normative extended table bit, used to create standard non-normative extended tables in articles or books"
|
|
12803
|
+
},
|
|
12804
|
+
[BitType2.standardRemarkTableExtendedNormative]: {
|
|
12805
|
+
since: "1.17.0",
|
|
12806
|
+
baseBitType: BitType2.tableExtended,
|
|
12807
|
+
description: "Standard normative remark extended table bit, used to create standard normative remark extended tables in articles or books"
|
|
12808
|
+
},
|
|
12809
|
+
[BitType2.standardRemarkTableExtendedNonNormative]: {
|
|
12810
|
+
since: "1.17.0",
|
|
12811
|
+
baseBitType: BitType2.tableExtended,
|
|
12812
|
+
description: "Standard non-normative remark extended table bit, used to create standard non-normative remark extended tables in articles or books"
|
|
12813
|
+
},
|
|
12586
12814
|
[BitType2.smartStandardTableNormative]: {
|
|
12587
12815
|
since: "1.28.0",
|
|
12588
12816
|
baseBitType: BitType2.standardTableNormative,
|
|
@@ -12603,6 +12831,26 @@ var BITS = {
|
|
|
12603
12831
|
baseBitType: BitType2.standardRemarkTableNonNormative,
|
|
12604
12832
|
description: "Smart standard non-normative remark table bit, used to create smart standard non-normative remark tables in articles or books"
|
|
12605
12833
|
},
|
|
12834
|
+
[BitType2.smartStandardTableExtendedNormative]: {
|
|
12835
|
+
since: "1.28.0",
|
|
12836
|
+
baseBitType: BitType2.standardTableExtendedNormative,
|
|
12837
|
+
description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
|
|
12838
|
+
},
|
|
12839
|
+
[BitType2.smartStandardTableExtendedNonNormative]: {
|
|
12840
|
+
since: "1.28.0",
|
|
12841
|
+
baseBitType: BitType2.standardTableExtendedNonNormative,
|
|
12842
|
+
description: "Smart standard non-normative extended table bit, used to create smart standard non-normative extended tables in articles or books"
|
|
12843
|
+
},
|
|
12844
|
+
[BitType2.smartStandardRemarkTableExtendedNormative]: {
|
|
12845
|
+
since: "1.28.0",
|
|
12846
|
+
baseBitType: BitType2.standardRemarkTableExtendedNormative,
|
|
12847
|
+
description: "Smart standard normative remark extended table bit, used to create smart standard normative remark extended tables in articles or books"
|
|
12848
|
+
},
|
|
12849
|
+
[BitType2.smartStandardRemarkTableExtendedNonNormative]: {
|
|
12850
|
+
since: "1.28.0",
|
|
12851
|
+
baseBitType: BitType2.standardRemarkTableExtendedNonNormative,
|
|
12852
|
+
description: "Smart standard non-normative remark extended table bit, used to create smart standard non-normative remark extended tables in articles or books"
|
|
12853
|
+
},
|
|
12606
12854
|
[BitType2.smartStandardTableNormativeCollapsible]: {
|
|
12607
12855
|
since: "1.28.0",
|
|
12608
12856
|
baseBitType: BitType2.smartStandardTableNormative,
|
|
@@ -12623,6 +12871,26 @@ var BITS = {
|
|
|
12623
12871
|
baseBitType: BitType2.smartStandardRemarkTableNonNormative,
|
|
12624
12872
|
description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
|
|
12625
12873
|
},
|
|
12874
|
+
[BitType2.smartStandardTableExtendedNormativeCollapsible]: {
|
|
12875
|
+
since: "1.28.0",
|
|
12876
|
+
baseBitType: BitType2.smartStandardTableExtendedNormative,
|
|
12877
|
+
description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
|
|
12878
|
+
},
|
|
12879
|
+
[BitType2.smartStandardTableExtendedNonNormativeCollapsible]: {
|
|
12880
|
+
since: "1.28.0",
|
|
12881
|
+
baseBitType: BitType2.smartStandardTableExtendedNonNormative,
|
|
12882
|
+
description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
|
|
12883
|
+
},
|
|
12884
|
+
[BitType2.smartStandardRemarkTableExtendedNormativeCollapsible]: {
|
|
12885
|
+
since: "1.28.0",
|
|
12886
|
+
baseBitType: BitType2.smartStandardRemarkTableExtendedNormative,
|
|
12887
|
+
description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
|
|
12888
|
+
},
|
|
12889
|
+
[BitType2.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
|
|
12890
|
+
since: "1.28.0",
|
|
12891
|
+
baseBitType: BitType2.smartStandardRemarkTableExtendedNonNormative,
|
|
12892
|
+
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"
|
|
12893
|
+
},
|
|
12626
12894
|
[BitType2.parameters]: {
|
|
12627
12895
|
since: "1.18.0",
|
|
12628
12896
|
baseBitType: BitType2.table,
|
|
@@ -13564,6 +13832,8 @@ var Config = class {
|
|
|
13564
13832
|
jsonKey: tag.jsonKey,
|
|
13565
13833
|
exportJsonKey: tag.exportJsonKey,
|
|
13566
13834
|
hasExportJsonKey: tag.hasExportJsonKey,
|
|
13835
|
+
htmlKey: tag.htmlKey,
|
|
13836
|
+
hasHtmlKey: tag.hasHtmlKey,
|
|
13567
13837
|
deprecated: tag.deprecated
|
|
13568
13838
|
});
|
|
13569
13839
|
finalResourceTags[k] = newTag;
|
|
@@ -13668,7 +13938,7 @@ var instance2 = new Config();
|
|
|
13668
13938
|
// src/generated/package_info.ts
|
|
13669
13939
|
var PACKAGE_INFO = {
|
|
13670
13940
|
"name": "@gmb/bitmark-parser-generator",
|
|
13671
|
-
"version": "5.
|
|
13941
|
+
"version": "5.28.0",
|
|
13672
13942
|
"author": "Get More Brain Ltd",
|
|
13673
13943
|
"license": "ISC",
|
|
13674
13944
|
"description": "A bitmark parser and generator using Peggy.js"
|
|
@@ -14558,6 +14828,10 @@ var NodeType = {
|
|
|
14558
14828
|
relatedBookValue: "relatedBookValue",
|
|
14559
14829
|
translationOfBook: "translationOfBook",
|
|
14560
14830
|
translationOfBookValue: "translationOfBookValue",
|
|
14831
|
+
userFeedbackTranslationUrl: "userFeedbackTranslationUrl",
|
|
14832
|
+
userFeedbackTranslationUrlValue: "userFeedbackTranslationUrlValue",
|
|
14833
|
+
userFeedbackContentUrl: "userFeedbackContentUrl",
|
|
14834
|
+
userFeedbackContentUrlValue: "userFeedbackContentUrlValue",
|
|
14561
14835
|
releaseDate: "releaseDate",
|
|
14562
14836
|
releaseDateValue: "releaseDateValue",
|
|
14563
14837
|
releaseKind: "releaseKind",
|
|
@@ -27767,6 +28041,18 @@ var Builder = class extends BaseBuilder {
|
|
|
27767
28041
|
data.translationOfBook,
|
|
27768
28042
|
options
|
|
27769
28043
|
),
|
|
28044
|
+
userFeedbackTranslationUrl: this.toAstProperty(
|
|
28045
|
+
bitType,
|
|
28046
|
+
ConfigKey.property_userFeedbackTranslationUrl,
|
|
28047
|
+
data.userFeedbackTranslationUrl,
|
|
28048
|
+
options
|
|
28049
|
+
),
|
|
28050
|
+
userFeedbackContentUrl: this.toAstProperty(
|
|
28051
|
+
bitType,
|
|
28052
|
+
ConfigKey.property_userFeedbackContentUrl,
|
|
28053
|
+
data.userFeedbackContentUrl,
|
|
28054
|
+
options
|
|
28055
|
+
),
|
|
27770
28056
|
author: this.toAstProperty(bitType, ConfigKey.property_author, data.author, options),
|
|
27771
28057
|
subject: this.toAstProperty(bitType, ConfigKey.property_subject, data.subject, options),
|
|
27772
28058
|
date: this.toAstProperty(bitType, ConfigKey.property_date, data.date, options),
|
|
@@ -31558,7 +31844,8 @@ var BitmarkGenerator = class extends AstWalkerGenerator {
|
|
|
31558
31844
|
this.writeNL();
|
|
31559
31845
|
}
|
|
31560
31846
|
const content = cell.content ?? instance3.EMPTY_STRING;
|
|
31561
|
-
|
|
31847
|
+
const options = this.options.noBreakscaping ? { noBreakscaping: true } : void 0;
|
|
31848
|
+
this.writeTextOrValue(content, this.textFormat, TextLocation2.body, options);
|
|
31562
31849
|
}
|
|
31563
31850
|
writeTableCellProperty(name, value) {
|
|
31564
31851
|
this.writeOPA();
|
|
@@ -33024,6 +33311,278 @@ var BitmarkStringGenerator = class {
|
|
|
33024
33311
|
}
|
|
33025
33312
|
};
|
|
33026
33313
|
|
|
33314
|
+
// src/generator/html/HtmlTableGenerator.ts
|
|
33315
|
+
var MARK_TO_TAG = {
|
|
33316
|
+
bold: "b",
|
|
33317
|
+
italic: "i",
|
|
33318
|
+
superscript: "sup",
|
|
33319
|
+
subscript: "sub",
|
|
33320
|
+
strike: "s",
|
|
33321
|
+
del: "del",
|
|
33322
|
+
ins: "ins",
|
|
33323
|
+
underline: "u",
|
|
33324
|
+
highlight: "mark",
|
|
33325
|
+
code: "code"
|
|
33326
|
+
};
|
|
33327
|
+
var INLINE_IMAGE_RE = /==([^=]*(?:=(?!=)[^=]*)*)==\|imageInline:([^|\s]+)((?:\|(?:@?[A-Za-z][A-Za-z0-9_-]*:[^|\s]+|#[^|\s]*))*)\|?/g;
|
|
33328
|
+
var MAX_IMAGE_DIMENSION = 9999;
|
|
33329
|
+
var HtmlTableGenerator = class {
|
|
33330
|
+
constructor() {
|
|
33331
|
+
__publicField(this, "indentUnit", " ");
|
|
33332
|
+
}
|
|
33333
|
+
/**
|
|
33334
|
+
* Generate HTML table fragments from a string or JSON value.
|
|
33335
|
+
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
33336
|
+
*/
|
|
33337
|
+
generate(input) {
|
|
33338
|
+
let data = input;
|
|
33339
|
+
if (typeof data === "string") {
|
|
33340
|
+
try {
|
|
33341
|
+
data = JSON.parse(data);
|
|
33342
|
+
} catch {
|
|
33343
|
+
return "";
|
|
33344
|
+
}
|
|
33345
|
+
}
|
|
33346
|
+
const bits = this.collectBits(data);
|
|
33347
|
+
const fragments = [];
|
|
33348
|
+
for (const bit of bits) {
|
|
33349
|
+
const html = this.renderTableBit(bit);
|
|
33350
|
+
if (html) fragments.push(html);
|
|
33351
|
+
}
|
|
33352
|
+
return fragments.join("\n\n");
|
|
33353
|
+
}
|
|
33354
|
+
// --- bit collection -------------------------------------------------------
|
|
33355
|
+
collectBits(data) {
|
|
33356
|
+
const out = [];
|
|
33357
|
+
const visit = (value) => {
|
|
33358
|
+
if (value == null || typeof value !== "object") return;
|
|
33359
|
+
if (Array.isArray(value)) {
|
|
33360
|
+
value.forEach(visit);
|
|
33361
|
+
return;
|
|
33362
|
+
}
|
|
33363
|
+
const obj = value;
|
|
33364
|
+
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
33365
|
+
out.push(obj.bit);
|
|
33366
|
+
} else if ("type" in obj) {
|
|
33367
|
+
out.push(obj);
|
|
33368
|
+
}
|
|
33369
|
+
};
|
|
33370
|
+
visit(data);
|
|
33371
|
+
return out;
|
|
33372
|
+
}
|
|
33373
|
+
// --- table rendering ------------------------------------------------------
|
|
33374
|
+
renderTableBit(bit) {
|
|
33375
|
+
const table = bit.table;
|
|
33376
|
+
if (!table) return "";
|
|
33377
|
+
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
33378
|
+
const extended = this.toExtended(table);
|
|
33379
|
+
const lines = [];
|
|
33380
|
+
lines.push("<table>");
|
|
33381
|
+
if (bit.caption != null) {
|
|
33382
|
+
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
33383
|
+
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
33384
|
+
}
|
|
33385
|
+
this.renderSection(lines, "thead", extended.header, "header");
|
|
33386
|
+
this.renderSection(lines, "tbody", extended.body, "body");
|
|
33387
|
+
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
33388
|
+
lines.push("</table>");
|
|
33389
|
+
return lines.join("\n");
|
|
33390
|
+
}
|
|
33391
|
+
toExtended(table) {
|
|
33392
|
+
const t = table;
|
|
33393
|
+
if (t.header || t.body || t.footer) return table;
|
|
33394
|
+
return convertBasicToExtendedTableFormat(table);
|
|
33395
|
+
}
|
|
33396
|
+
renderSection(lines, tag, section, key) {
|
|
33397
|
+
if (!section || !section.rows || section.rows.length === 0) return;
|
|
33398
|
+
lines.push(`${this.indentUnit}<${tag}>`);
|
|
33399
|
+
for (const row of section.rows) {
|
|
33400
|
+
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
33401
|
+
for (const cell of row.cells ?? []) {
|
|
33402
|
+
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
33403
|
+
}
|
|
33404
|
+
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
33405
|
+
}
|
|
33406
|
+
lines.push(`${this.indentUnit}</${tag}>`);
|
|
33407
|
+
}
|
|
33408
|
+
renderCell(cell, _key) {
|
|
33409
|
+
const tag = cell.title === true ? "th" : "td";
|
|
33410
|
+
const attrs = [];
|
|
33411
|
+
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
33412
|
+
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
33413
|
+
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
33414
|
+
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
33415
|
+
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
33416
|
+
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
33417
|
+
}
|
|
33418
|
+
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
33419
|
+
asTextAst(content) {
|
|
33420
|
+
if (content == null) return [];
|
|
33421
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
33422
|
+
return content;
|
|
33423
|
+
}
|
|
33424
|
+
cellContentToHtml(blocks) {
|
|
33425
|
+
if (blocks.length === 0) return "";
|
|
33426
|
+
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
33427
|
+
return this.inlineToHtml(blocks[0].content ?? []);
|
|
33428
|
+
}
|
|
33429
|
+
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
33430
|
+
}
|
|
33431
|
+
blockToHtml(node) {
|
|
33432
|
+
switch (node.type) {
|
|
33433
|
+
case "paragraph":
|
|
33434
|
+
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
33435
|
+
case "bulletList":
|
|
33436
|
+
case "noBulletList":
|
|
33437
|
+
case "orderedList":
|
|
33438
|
+
case "orderedListRoman":
|
|
33439
|
+
case "orderedListRomanLower":
|
|
33440
|
+
case "letteredList":
|
|
33441
|
+
case "letteredListLower":
|
|
33442
|
+
case "taskList":
|
|
33443
|
+
return this.listToHtml(node);
|
|
33444
|
+
case "image":
|
|
33445
|
+
case "imageInline":
|
|
33446
|
+
return this.imageToHtml(node);
|
|
33447
|
+
case "latex":
|
|
33448
|
+
return this.latexToHtml(node);
|
|
33449
|
+
default:
|
|
33450
|
+
return this.inlineToHtml([node]);
|
|
33451
|
+
}
|
|
33452
|
+
}
|
|
33453
|
+
inlineToHtml(nodes) {
|
|
33454
|
+
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
33455
|
+
}
|
|
33456
|
+
inlineNodeToHtml(node) {
|
|
33457
|
+
if (node.type === "hardBreak") return "<br>";
|
|
33458
|
+
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
33459
|
+
if (node.type === "latex") return this.latexToHtml(node);
|
|
33460
|
+
if (node.type === "text") {
|
|
33461
|
+
return this.wrapMarks(this.textToHtml(node.text ?? ""), node.marks);
|
|
33462
|
+
}
|
|
33463
|
+
if (node.content) return this.inlineToHtml(node.content);
|
|
33464
|
+
return this.escapeText(node.text ?? "");
|
|
33465
|
+
}
|
|
33466
|
+
wrapMarks(text, marks) {
|
|
33467
|
+
if (!marks || marks.length === 0) return text;
|
|
33468
|
+
let open = "";
|
|
33469
|
+
let close = "";
|
|
33470
|
+
for (const mark of marks) {
|
|
33471
|
+
if (mark.type === "link") {
|
|
33472
|
+
const href = mark.attrs?.href ?? "";
|
|
33473
|
+
open += `<a href="${this.escapeAttr(href)}">`;
|
|
33474
|
+
close = `</a>${close}`;
|
|
33475
|
+
} else {
|
|
33476
|
+
const tag = MARK_TO_TAG[mark.type];
|
|
33477
|
+
if (tag) {
|
|
33478
|
+
open += `<${tag}>`;
|
|
33479
|
+
close = `</${tag}>${close}`;
|
|
33480
|
+
}
|
|
33481
|
+
}
|
|
33482
|
+
}
|
|
33483
|
+
return `${open}${text}${close}`;
|
|
33484
|
+
}
|
|
33485
|
+
// --- lists ----------------------------------------------------------------
|
|
33486
|
+
listToHtml(node) {
|
|
33487
|
+
const { tag, attrs } = this.listTag(node);
|
|
33488
|
+
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
33489
|
+
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
33490
|
+
}
|
|
33491
|
+
listTag(node) {
|
|
33492
|
+
const start = node.attrs?.start;
|
|
33493
|
+
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
33494
|
+
switch (node.type) {
|
|
33495
|
+
case "orderedList":
|
|
33496
|
+
return { tag: "ol", attrs: startAttr };
|
|
33497
|
+
case "orderedListRoman":
|
|
33498
|
+
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
33499
|
+
case "orderedListRomanLower":
|
|
33500
|
+
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
33501
|
+
case "letteredList":
|
|
33502
|
+
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
33503
|
+
case "letteredListLower":
|
|
33504
|
+
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
33505
|
+
case "noBulletList":
|
|
33506
|
+
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
33507
|
+
case "taskList":
|
|
33508
|
+
case "bulletList":
|
|
33509
|
+
default:
|
|
33510
|
+
return { tag: "ul", attrs: "" };
|
|
33511
|
+
}
|
|
33512
|
+
}
|
|
33513
|
+
listItemToHtml(item, task) {
|
|
33514
|
+
const inner = (item.content ?? []).map((b) => {
|
|
33515
|
+
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
33516
|
+
return this.blockToHtml(b);
|
|
33517
|
+
}).join("");
|
|
33518
|
+
if (task) {
|
|
33519
|
+
const checked = item.attrs?.checked ? " checked" : "";
|
|
33520
|
+
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
33521
|
+
}
|
|
33522
|
+
return `<li>${inner}</li>`;
|
|
33523
|
+
}
|
|
33524
|
+
// --- images ---------------------------------------------------------------
|
|
33525
|
+
imageToHtml(node) {
|
|
33526
|
+
const attrs = node.attrs ?? {};
|
|
33527
|
+
const parts = [];
|
|
33528
|
+
const src = attrs.src;
|
|
33529
|
+
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
33530
|
+
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
33531
|
+
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
33532
|
+
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
33533
|
+
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
33534
|
+
if (typeof attrs.class === "string" && attrs.class) {
|
|
33535
|
+
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
33536
|
+
}
|
|
33537
|
+
return `<img ${parts.join(" ")}>`;
|
|
33538
|
+
}
|
|
33539
|
+
textToHtml(text) {
|
|
33540
|
+
let html = "";
|
|
33541
|
+
let lastIndex = 0;
|
|
33542
|
+
for (const match of text.matchAll(INLINE_IMAGE_RE)) {
|
|
33543
|
+
const index = match.index ?? 0;
|
|
33544
|
+
html += this.escapeText(text.slice(lastIndex, index));
|
|
33545
|
+
html += this.inlineImageTokenToHtml(match);
|
|
33546
|
+
lastIndex = index + match[0].length;
|
|
33547
|
+
}
|
|
33548
|
+
html += this.escapeText(text.slice(lastIndex));
|
|
33549
|
+
return html;
|
|
33550
|
+
}
|
|
33551
|
+
inlineImageTokenToHtml(match) {
|
|
33552
|
+
const attrs = {
|
|
33553
|
+
alt: match[1],
|
|
33554
|
+
src: match[2]
|
|
33555
|
+
};
|
|
33556
|
+
const rawAttrs = match[3] ?? "";
|
|
33557
|
+
for (const attr of rawAttrs.split("|")) {
|
|
33558
|
+
if (!attr || attr.startsWith("#")) continue;
|
|
33559
|
+
const colon = attr.indexOf(":");
|
|
33560
|
+
if (colon < 1) continue;
|
|
33561
|
+
const key = attr.slice(0, colon).replace(/^@/, "");
|
|
33562
|
+
const value = attr.slice(colon + 1);
|
|
33563
|
+
if (key === "width" || key === "height") {
|
|
33564
|
+
const n = Number.parseInt(value, 10);
|
|
33565
|
+
if (!Number.isNaN(n) && n > 0 && n <= MAX_IMAGE_DIMENSION) attrs[key] = n;
|
|
33566
|
+
} else if (key === "class" || key === "title") {
|
|
33567
|
+
attrs[key] = value;
|
|
33568
|
+
}
|
|
33569
|
+
}
|
|
33570
|
+
return this.imageToHtml({ type: "imageInline", attrs });
|
|
33571
|
+
}
|
|
33572
|
+
// --- formulas -------------------------------------------------------------
|
|
33573
|
+
latexToHtml(node) {
|
|
33574
|
+
const formula = node.attrs?.formula ?? "";
|
|
33575
|
+
return `<math alttext="${this.escapeAttr(formula)}"></math>`;
|
|
33576
|
+
}
|
|
33577
|
+
// --- escaping -------------------------------------------------------------
|
|
33578
|
+
escapeText(text) {
|
|
33579
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
33580
|
+
}
|
|
33581
|
+
escapeAttr(text) {
|
|
33582
|
+
return this.escapeText(text).replace(/"/g, """);
|
|
33583
|
+
}
|
|
33584
|
+
};
|
|
33585
|
+
|
|
33027
33586
|
// src/generator/json/JsonGenerator.ts
|
|
33028
33587
|
var import_superenum33 = require("@ncoderz/superenum");
|
|
33029
33588
|
var MOVE_BODY_RECURSION_LIMIT = 5e3;
|
|
@@ -33326,6 +33885,7 @@ var JsonGenerator = class extends AstWalkerGenerator {
|
|
|
33326
33885
|
this.addProperty(this.bitJson, k, values, { array: true });
|
|
33327
33886
|
}
|
|
33328
33887
|
}
|
|
33888
|
+
return false;
|
|
33329
33889
|
}
|
|
33330
33890
|
// bitmarkAst -> bits -> bitsValue -> cardNode -> cardBits -> cardBitsValue
|
|
33331
33891
|
enter_cardBitsValue(node, route) {
|
|
@@ -37951,6 +38511,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
|
|
|
37951
38511
|
jsonKey: void 0,
|
|
37952
38512
|
exportJsonKey: void 0,
|
|
37953
38513
|
hasExportJsonKey: false,
|
|
38514
|
+
htmlKey: void 0,
|
|
38515
|
+
hasHtmlKey: false,
|
|
37954
38516
|
format: TagFormat.bitmarkText,
|
|
37955
38517
|
values: void 0,
|
|
37956
38518
|
defaultValue: void 0,
|
|
@@ -42330,6 +42892,539 @@ var BitmarkParser = class {
|
|
|
42330
42892
|
}
|
|
42331
42893
|
};
|
|
42332
42894
|
|
|
42895
|
+
// src/parser/html/HtmlDom.ts
|
|
42896
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
42897
|
+
"area",
|
|
42898
|
+
"base",
|
|
42899
|
+
"br",
|
|
42900
|
+
"col",
|
|
42901
|
+
"embed",
|
|
42902
|
+
"hr",
|
|
42903
|
+
"img",
|
|
42904
|
+
"input",
|
|
42905
|
+
"link",
|
|
42906
|
+
"meta",
|
|
42907
|
+
"param",
|
|
42908
|
+
"source",
|
|
42909
|
+
"track",
|
|
42910
|
+
"wbr"
|
|
42911
|
+
]);
|
|
42912
|
+
var IMPLIED_CLOSE = {
|
|
42913
|
+
li: /* @__PURE__ */ new Set(["li"]),
|
|
42914
|
+
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42915
|
+
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42916
|
+
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
42917
|
+
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42918
|
+
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42919
|
+
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42920
|
+
p: /* @__PURE__ */ new Set(["p"]),
|
|
42921
|
+
option: /* @__PURE__ */ new Set(["option"])
|
|
42922
|
+
};
|
|
42923
|
+
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9:-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
42924
|
+
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
42925
|
+
function parseAttrs(raw) {
|
|
42926
|
+
const attrs = {};
|
|
42927
|
+
if (!raw) return attrs;
|
|
42928
|
+
ATTR_RE.lastIndex = 0;
|
|
42929
|
+
let m;
|
|
42930
|
+
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
42931
|
+
const name = m[1].toLowerCase();
|
|
42932
|
+
let value = m[2] ?? "";
|
|
42933
|
+
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
42934
|
+
value = value.slice(1, -1);
|
|
42935
|
+
}
|
|
42936
|
+
attrs[name] = value;
|
|
42937
|
+
}
|
|
42938
|
+
return attrs;
|
|
42939
|
+
}
|
|
42940
|
+
function stripNonContent(html) {
|
|
42941
|
+
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, "");
|
|
42942
|
+
}
|
|
42943
|
+
function tokenize(html) {
|
|
42944
|
+
const tokens = [];
|
|
42945
|
+
const clean = stripNonContent(html);
|
|
42946
|
+
TAG_RE.lastIndex = 0;
|
|
42947
|
+
let lastIndex = 0;
|
|
42948
|
+
let m;
|
|
42949
|
+
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
42950
|
+
if (m.index > lastIndex) {
|
|
42951
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
42952
|
+
}
|
|
42953
|
+
lastIndex = TAG_RE.lastIndex;
|
|
42954
|
+
const isClose = m[1] === "/";
|
|
42955
|
+
const name = m[2].toLowerCase();
|
|
42956
|
+
if (isClose) {
|
|
42957
|
+
tokens.push({ kind: "close", name });
|
|
42958
|
+
} else {
|
|
42959
|
+
tokens.push({
|
|
42960
|
+
kind: "open",
|
|
42961
|
+
name,
|
|
42962
|
+
attrs: parseAttrs(m[3]),
|
|
42963
|
+
selfClose: m[4] === "/"
|
|
42964
|
+
});
|
|
42965
|
+
}
|
|
42966
|
+
}
|
|
42967
|
+
if (lastIndex < clean.length) {
|
|
42968
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
42969
|
+
}
|
|
42970
|
+
return tokens;
|
|
42971
|
+
}
|
|
42972
|
+
function parseHtml(html) {
|
|
42973
|
+
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
42974
|
+
const stack = [root];
|
|
42975
|
+
const top = () => stack[stack.length - 1];
|
|
42976
|
+
for (const token of tokenize(html)) {
|
|
42977
|
+
if (token.kind === "text") {
|
|
42978
|
+
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
42979
|
+
continue;
|
|
42980
|
+
}
|
|
42981
|
+
if (token.kind === "open") {
|
|
42982
|
+
const name = token.name;
|
|
42983
|
+
const closes = IMPLIED_CLOSE[name];
|
|
42984
|
+
if (closes) {
|
|
42985
|
+
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
42986
|
+
}
|
|
42987
|
+
const el = {
|
|
42988
|
+
type: "element",
|
|
42989
|
+
name,
|
|
42990
|
+
attrs: token.attrs ?? {},
|
|
42991
|
+
children: []
|
|
42992
|
+
};
|
|
42993
|
+
top().children.push(el);
|
|
42994
|
+
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
42995
|
+
stack.push(el);
|
|
42996
|
+
}
|
|
42997
|
+
continue;
|
|
42998
|
+
}
|
|
42999
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
43000
|
+
if (stack[i].name === token.name) {
|
|
43001
|
+
stack.length = i;
|
|
43002
|
+
break;
|
|
43003
|
+
}
|
|
43004
|
+
}
|
|
43005
|
+
}
|
|
43006
|
+
return root.children;
|
|
43007
|
+
}
|
|
43008
|
+
function childElements(el, names) {
|
|
43009
|
+
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43010
|
+
}
|
|
43011
|
+
|
|
43012
|
+
// src/parser/html/HtmlTableParser.ts
|
|
43013
|
+
var MARK_TAGS = {
|
|
43014
|
+
b: "bold",
|
|
43015
|
+
strong: "bold",
|
|
43016
|
+
i: "italic",
|
|
43017
|
+
em: "italic",
|
|
43018
|
+
sup: "superscript",
|
|
43019
|
+
sub: "subscript",
|
|
43020
|
+
s: "strike",
|
|
43021
|
+
strike: "strike",
|
|
43022
|
+
del: "del",
|
|
43023
|
+
ins: "ins",
|
|
43024
|
+
u: "underline",
|
|
43025
|
+
mark: "highlight",
|
|
43026
|
+
code: "code"
|
|
43027
|
+
};
|
|
43028
|
+
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
43029
|
+
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
43030
|
+
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
43031
|
+
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
43032
|
+
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
43033
|
+
var NAMED_ENTITIES = {
|
|
43034
|
+
amp: "&",
|
|
43035
|
+
lt: "<",
|
|
43036
|
+
gt: ">",
|
|
43037
|
+
quot: '"',
|
|
43038
|
+
apos: "'",
|
|
43039
|
+
nbsp: "\xA0"
|
|
43040
|
+
};
|
|
43041
|
+
function decodeEntities(text) {
|
|
43042
|
+
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
43043
|
+
if (body[0] === "#") {
|
|
43044
|
+
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
43045
|
+
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
43046
|
+
try {
|
|
43047
|
+
return String.fromCodePoint(code);
|
|
43048
|
+
} catch {
|
|
43049
|
+
return whole;
|
|
43050
|
+
}
|
|
43051
|
+
}
|
|
43052
|
+
return whole;
|
|
43053
|
+
}
|
|
43054
|
+
return NAMED_ENTITIES[body] ?? whole;
|
|
43055
|
+
});
|
|
43056
|
+
}
|
|
43057
|
+
function intAttr(value) {
|
|
43058
|
+
if (value == null) return void 0;
|
|
43059
|
+
const n = Number.parseInt(value, 10);
|
|
43060
|
+
return Number.isInteger(n) ? n : void 0;
|
|
43061
|
+
}
|
|
43062
|
+
function isElement(node) {
|
|
43063
|
+
return node.type === "element";
|
|
43064
|
+
}
|
|
43065
|
+
var HtmlTableParser = class {
|
|
43066
|
+
constructor() {
|
|
43067
|
+
__publicField(this, "keepUnknownTags", false);
|
|
43068
|
+
}
|
|
43069
|
+
/**
|
|
43070
|
+
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
43071
|
+
*/
|
|
43072
|
+
parse(html, options) {
|
|
43073
|
+
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
43074
|
+
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
43075
|
+
const onWarning = options?.onWarning;
|
|
43076
|
+
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
43077
|
+
const bits = [];
|
|
43078
|
+
for (const table of tables) {
|
|
43079
|
+
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
43080
|
+
if (bit) bits.push(bit);
|
|
43081
|
+
}
|
|
43082
|
+
return bits;
|
|
43083
|
+
}
|
|
43084
|
+
// --- table extraction -----------------------------------------------------
|
|
43085
|
+
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
43086
|
+
collectTopLevelTables(nodes) {
|
|
43087
|
+
const tables = [];
|
|
43088
|
+
const visit = (node) => {
|
|
43089
|
+
if (!isElement(node)) return;
|
|
43090
|
+
if (node.name === "table") {
|
|
43091
|
+
tables.push(node);
|
|
43092
|
+
return;
|
|
43093
|
+
}
|
|
43094
|
+
node.children.forEach(visit);
|
|
43095
|
+
};
|
|
43096
|
+
nodes.forEach(visit);
|
|
43097
|
+
return tables;
|
|
43098
|
+
}
|
|
43099
|
+
tableToBit(table, tableFormat, onWarning) {
|
|
43100
|
+
const header = [];
|
|
43101
|
+
const body = [];
|
|
43102
|
+
const footer = [];
|
|
43103
|
+
let caption;
|
|
43104
|
+
for (const child of table.children) {
|
|
43105
|
+
if (!isElement(child)) continue;
|
|
43106
|
+
if (child.name === "caption") {
|
|
43107
|
+
const capContent = this.inlineNodes(child.children, []);
|
|
43108
|
+
const trimmed = this.trimInline(capContent);
|
|
43109
|
+
if (trimmed.length > 0) caption = trimmed;
|
|
43110
|
+
} else if (SECTION_TAGS.has(child.name)) {
|
|
43111
|
+
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
43112
|
+
for (const tr of childElements(child, ROW_TAGS)) {
|
|
43113
|
+
target.push(this.rowToCells(tr));
|
|
43114
|
+
}
|
|
43115
|
+
} else if (ROW_TAGS.has(child.name)) {
|
|
43116
|
+
body.push(this.rowToCells(child));
|
|
43117
|
+
}
|
|
43118
|
+
}
|
|
43119
|
+
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
43120
|
+
return void 0;
|
|
43121
|
+
}
|
|
43122
|
+
const tableExtended = {};
|
|
43123
|
+
if (header.length > 0) tableExtended.header = { rows: header };
|
|
43124
|
+
if (body.length > 0) tableExtended.body = { rows: body };
|
|
43125
|
+
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
43126
|
+
let tableData = tableExtended;
|
|
43127
|
+
if (tableFormat === "table") {
|
|
43128
|
+
if (this.isLossyAsBasic(tableExtended)) {
|
|
43129
|
+
onWarning?.(
|
|
43130
|
+
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
43131
|
+
);
|
|
43132
|
+
}
|
|
43133
|
+
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
43134
|
+
}
|
|
43135
|
+
const bit = {
|
|
43136
|
+
type: tableFormat,
|
|
43137
|
+
format: "bitmark++",
|
|
43138
|
+
table: tableData
|
|
43139
|
+
};
|
|
43140
|
+
if (caption) bit.caption = caption;
|
|
43141
|
+
return bit;
|
|
43142
|
+
}
|
|
43143
|
+
rowToCells(tr) {
|
|
43144
|
+
const cells = [];
|
|
43145
|
+
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
43146
|
+
cells.push(this.cellToJson(cell));
|
|
43147
|
+
}
|
|
43148
|
+
return { cells };
|
|
43149
|
+
}
|
|
43150
|
+
cellToJson(cell) {
|
|
43151
|
+
const json = {
|
|
43152
|
+
content: this.blockNodes(cell.children)
|
|
43153
|
+
};
|
|
43154
|
+
if (cell.name === "th") json.title = true;
|
|
43155
|
+
const rowspan = intAttr(cell.attrs.rowspan);
|
|
43156
|
+
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
43157
|
+
const colspan = intAttr(cell.attrs.colspan);
|
|
43158
|
+
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
43159
|
+
const scope = cell.attrs.scope?.toLowerCase();
|
|
43160
|
+
if (scope && VALID_SCOPES.has(scope)) {
|
|
43161
|
+
json.scope = scope;
|
|
43162
|
+
}
|
|
43163
|
+
const width = this.widthFromCell(cell);
|
|
43164
|
+
if (width != null) json.colwidth = width;
|
|
43165
|
+
return json;
|
|
43166
|
+
}
|
|
43167
|
+
widthFromCell(cell) {
|
|
43168
|
+
const attrWidth = intAttr(cell.attrs.width);
|
|
43169
|
+
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
43170
|
+
const style = cell.attrs.style;
|
|
43171
|
+
if (style) {
|
|
43172
|
+
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
43173
|
+
if (m) {
|
|
43174
|
+
const n = Number.parseInt(m[1], 10);
|
|
43175
|
+
if (Number.isInteger(n) && n > 0) return n;
|
|
43176
|
+
}
|
|
43177
|
+
}
|
|
43178
|
+
return void 0;
|
|
43179
|
+
}
|
|
43180
|
+
isLossyAsBasic(table) {
|
|
43181
|
+
if (table.footer) return true;
|
|
43182
|
+
if (table.header && table.header.rows.length > 1) return true;
|
|
43183
|
+
const sections = [table.header, table.body, table.footer];
|
|
43184
|
+
for (const section of sections) {
|
|
43185
|
+
if (!section) continue;
|
|
43186
|
+
for (const row of section.rows) {
|
|
43187
|
+
for (const cell of row.cells) {
|
|
43188
|
+
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
43189
|
+
}
|
|
43190
|
+
}
|
|
43191
|
+
}
|
|
43192
|
+
return false;
|
|
43193
|
+
}
|
|
43194
|
+
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
43195
|
+
/**
|
|
43196
|
+
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
43197
|
+
*/
|
|
43198
|
+
blockNodes(nodes) {
|
|
43199
|
+
const blocks = [];
|
|
43200
|
+
let inline = [];
|
|
43201
|
+
const flush = () => {
|
|
43202
|
+
const trimmed = this.trimInline(inline);
|
|
43203
|
+
inline = [];
|
|
43204
|
+
if (trimmed.length === 0) return;
|
|
43205
|
+
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
43206
|
+
blocks.push({ ...trimmed[0], type: "image" });
|
|
43207
|
+
} else {
|
|
43208
|
+
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
43209
|
+
}
|
|
43210
|
+
};
|
|
43211
|
+
for (const node of nodes) {
|
|
43212
|
+
if (!isElement(node)) {
|
|
43213
|
+
inline.push(...this.inlineText(node.value, []));
|
|
43214
|
+
continue;
|
|
43215
|
+
}
|
|
43216
|
+
const name = node.name;
|
|
43217
|
+
if (name === "p") {
|
|
43218
|
+
flush();
|
|
43219
|
+
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
43220
|
+
if (content.length > 0) {
|
|
43221
|
+
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
43222
|
+
}
|
|
43223
|
+
} else if (this.isListTag(name)) {
|
|
43224
|
+
flush();
|
|
43225
|
+
const list = this.listNode(node);
|
|
43226
|
+
if (list) blocks.push(list);
|
|
43227
|
+
} else {
|
|
43228
|
+
inline.push(...this.inlineFromElement(node, []));
|
|
43229
|
+
}
|
|
43230
|
+
}
|
|
43231
|
+
flush();
|
|
43232
|
+
return blocks;
|
|
43233
|
+
}
|
|
43234
|
+
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
43235
|
+
inlineNodes(nodes, marks) {
|
|
43236
|
+
const out = [];
|
|
43237
|
+
for (const node of nodes) {
|
|
43238
|
+
if (!isElement(node)) {
|
|
43239
|
+
out.push(...this.inlineText(node.value, marks));
|
|
43240
|
+
} else {
|
|
43241
|
+
out.push(...this.inlineFromElement(node, marks));
|
|
43242
|
+
}
|
|
43243
|
+
}
|
|
43244
|
+
return out;
|
|
43245
|
+
}
|
|
43246
|
+
inlineFromElement(el, marks) {
|
|
43247
|
+
const name = el.name;
|
|
43248
|
+
if (name === "br") {
|
|
43249
|
+
return [{ type: "hardBreak" }];
|
|
43250
|
+
}
|
|
43251
|
+
if (name === "img") {
|
|
43252
|
+
return [this.imageNode(el, true)];
|
|
43253
|
+
}
|
|
43254
|
+
if (this.isMathTag(name)) {
|
|
43255
|
+
return [this.latexNode(el)];
|
|
43256
|
+
}
|
|
43257
|
+
const markType = MARK_TAGS[name];
|
|
43258
|
+
if (markType) {
|
|
43259
|
+
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
43260
|
+
}
|
|
43261
|
+
if (name === "a") {
|
|
43262
|
+
const linkMark = {
|
|
43263
|
+
type: "link",
|
|
43264
|
+
attrs: {
|
|
43265
|
+
href: el.attrs.href ?? "",
|
|
43266
|
+
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
43267
|
+
}
|
|
43268
|
+
};
|
|
43269
|
+
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
43270
|
+
}
|
|
43271
|
+
if (this.keepUnknownTags) {
|
|
43272
|
+
const open = this.serializeOpenTag(el);
|
|
43273
|
+
const close = `</${name}>`;
|
|
43274
|
+
return [
|
|
43275
|
+
...this.inlineText(open, marks),
|
|
43276
|
+
...this.inlineNodes(el.children, marks),
|
|
43277
|
+
...this.inlineText(close, marks)
|
|
43278
|
+
];
|
|
43279
|
+
}
|
|
43280
|
+
return this.inlineNodes(el.children, marks);
|
|
43281
|
+
}
|
|
43282
|
+
inlineText(raw, marks) {
|
|
43283
|
+
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
43284
|
+
if (text === "") return [];
|
|
43285
|
+
const node = { text, type: "text" };
|
|
43286
|
+
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
43287
|
+
return [node];
|
|
43288
|
+
}
|
|
43289
|
+
serializeOpenTag(el) {
|
|
43290
|
+
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
43291
|
+
return `<${el.name}${attrs}>`;
|
|
43292
|
+
}
|
|
43293
|
+
// --- lists ----------------------------------------------------------------
|
|
43294
|
+
isListTag(name) {
|
|
43295
|
+
return name === "ul" || name === "ol";
|
|
43296
|
+
}
|
|
43297
|
+
listNode(el) {
|
|
43298
|
+
const items = childElements(el, LI_TAGS);
|
|
43299
|
+
if (items.length === 0) return void 0;
|
|
43300
|
+
const isTask = el.name === "ul" && items.some((li) => {
|
|
43301
|
+
const firstEl = li.children.find(isElement);
|
|
43302
|
+
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
43303
|
+
});
|
|
43304
|
+
if (isTask) {
|
|
43305
|
+
return {
|
|
43306
|
+
type: "taskList",
|
|
43307
|
+
content: items.map((li) => this.taskItemNode(li))
|
|
43308
|
+
};
|
|
43309
|
+
}
|
|
43310
|
+
const type = this.listType(el);
|
|
43311
|
+
const node = {
|
|
43312
|
+
type,
|
|
43313
|
+
content: items.map((li) => this.listItemNode(li))
|
|
43314
|
+
};
|
|
43315
|
+
if (el.name === "ol") {
|
|
43316
|
+
const start = intAttr(el.attrs.start);
|
|
43317
|
+
if (start != null) {
|
|
43318
|
+
node.attrs = { start };
|
|
43319
|
+
}
|
|
43320
|
+
}
|
|
43321
|
+
return node;
|
|
43322
|
+
}
|
|
43323
|
+
listType(el) {
|
|
43324
|
+
if (el.name === "ol") {
|
|
43325
|
+
switch (el.attrs.type) {
|
|
43326
|
+
case "i":
|
|
43327
|
+
return "orderedListRomanLower";
|
|
43328
|
+
case "I":
|
|
43329
|
+
return "orderedListRoman";
|
|
43330
|
+
case "a":
|
|
43331
|
+
return "letteredListLower";
|
|
43332
|
+
case "A":
|
|
43333
|
+
return "letteredList";
|
|
43334
|
+
default:
|
|
43335
|
+
return "orderedList";
|
|
43336
|
+
}
|
|
43337
|
+
}
|
|
43338
|
+
const style = el.attrs.style ?? "";
|
|
43339
|
+
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
43340
|
+
return "bulletList";
|
|
43341
|
+
}
|
|
43342
|
+
listItemNode(li) {
|
|
43343
|
+
let content = this.blockNodes(li.children);
|
|
43344
|
+
if (content.length === 0) {
|
|
43345
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43346
|
+
}
|
|
43347
|
+
return { type: "listItem", content };
|
|
43348
|
+
}
|
|
43349
|
+
taskItemNode(li) {
|
|
43350
|
+
const checkbox = li.children.find(
|
|
43351
|
+
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
43352
|
+
);
|
|
43353
|
+
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
43354
|
+
const rest = li.children.filter((c) => c !== checkbox);
|
|
43355
|
+
let content = this.blockNodes(rest);
|
|
43356
|
+
if (content.length === 0) {
|
|
43357
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43358
|
+
}
|
|
43359
|
+
return { type: "taskItem", attrs: { checked }, content };
|
|
43360
|
+
}
|
|
43361
|
+
// --- images ---------------------------------------------------------------
|
|
43362
|
+
imageNode(el, inline) {
|
|
43363
|
+
const attrs = { src: el.attrs.src ?? "" };
|
|
43364
|
+
attrs.alt = el.attrs.alt ?? null;
|
|
43365
|
+
attrs.title = el.attrs.title ?? null;
|
|
43366
|
+
const width = intAttr(el.attrs.width);
|
|
43367
|
+
if (width != null) attrs.width = width;
|
|
43368
|
+
const height = intAttr(el.attrs.height);
|
|
43369
|
+
if (height != null) attrs.height = height;
|
|
43370
|
+
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
43371
|
+
return { type: inline ? "imageInline" : "image", attrs };
|
|
43372
|
+
}
|
|
43373
|
+
// --- formulas -------------------------------------------------------------
|
|
43374
|
+
isMathTag(name) {
|
|
43375
|
+
return this.localName(name) === "math";
|
|
43376
|
+
}
|
|
43377
|
+
latexNode(el) {
|
|
43378
|
+
return {
|
|
43379
|
+
type: "latex",
|
|
43380
|
+
attrs: {
|
|
43381
|
+
formula: this.latexFromMath(el)
|
|
43382
|
+
}
|
|
43383
|
+
};
|
|
43384
|
+
}
|
|
43385
|
+
latexFromMath(el) {
|
|
43386
|
+
const alt = el.attrs.alttext ?? el.attrs.alt ?? el.attrs.title;
|
|
43387
|
+
if (alt != null) return decodeEntities(alt);
|
|
43388
|
+
const annotation = this.findLatexAnnotation(el);
|
|
43389
|
+
if (annotation) return this.textContent(annotation).trim();
|
|
43390
|
+
return this.textContent(el).trim();
|
|
43391
|
+
}
|
|
43392
|
+
findLatexAnnotation(el) {
|
|
43393
|
+
for (const child of el.children) {
|
|
43394
|
+
if (!isElement(child)) continue;
|
|
43395
|
+
const lowerEncoding = (child.attrs.encoding ?? "").toLowerCase();
|
|
43396
|
+
if (this.localName(child.name) === "annotation" && (/\btex\b/.test(lowerEncoding) || /\blatex\b/.test(lowerEncoding))) {
|
|
43397
|
+
return child;
|
|
43398
|
+
}
|
|
43399
|
+
const nested = this.findLatexAnnotation(child);
|
|
43400
|
+
if (nested) return nested;
|
|
43401
|
+
}
|
|
43402
|
+
return void 0;
|
|
43403
|
+
}
|
|
43404
|
+
textContent(el) {
|
|
43405
|
+
return el.children.map((child) => isElement(child) ? this.textContent(child) : decodeEntities(child.value)).join("").replace(/\s+/g, " ");
|
|
43406
|
+
}
|
|
43407
|
+
localName(name) {
|
|
43408
|
+
return name.includes(":") ? name.slice(name.indexOf(":") + 1) : name;
|
|
43409
|
+
}
|
|
43410
|
+
// --- whitespace -----------------------------------------------------------
|
|
43411
|
+
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
43412
|
+
trimInline(nodes) {
|
|
43413
|
+
const out = nodes.slice();
|
|
43414
|
+
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
43415
|
+
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
43416
|
+
if (out.length > 0 && out[0].type === "text") {
|
|
43417
|
+
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
43418
|
+
}
|
|
43419
|
+
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
43420
|
+
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
43421
|
+
const last = out.length - 1;
|
|
43422
|
+
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
43423
|
+
}
|
|
43424
|
+
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
43425
|
+
}
|
|
43426
|
+
};
|
|
43427
|
+
|
|
42333
43428
|
// src/BitmarkParserGenerator.ts
|
|
42334
43429
|
var Input = {
|
|
42335
43430
|
/**
|
|
@@ -42966,7 +44061,10 @@ var BitmarkParserGenerator = class {
|
|
|
42966
44061
|
outputFile: opts.outputFile,
|
|
42967
44062
|
fileOptions: opts.fileOptions,
|
|
42968
44063
|
jsonOptions: opts.jsonOptions,
|
|
42969
|
-
bitmarkOptions:
|
|
44064
|
+
bitmarkOptions: {
|
|
44065
|
+
...opts.bitmarkOptions,
|
|
44066
|
+
...opts.noBreakscaping ? { noBreakscaping: true } : {}
|
|
44067
|
+
}
|
|
42970
44068
|
});
|
|
42971
44069
|
}
|
|
42972
44070
|
const outputFormat = opts.outputFormat ?? "html";
|
|
@@ -43269,728 +44367,6 @@ var BoundingBoxIndex = class _BoundingBoxIndex {
|
|
|
43269
44367
|
}
|
|
43270
44368
|
};
|
|
43271
44369
|
|
|
43272
|
-
// src/generator/html/HtmlTableGenerator.ts
|
|
43273
|
-
var MARK_TO_TAG = {
|
|
43274
|
-
bold: "b",
|
|
43275
|
-
italic: "i",
|
|
43276
|
-
superscript: "sup",
|
|
43277
|
-
subscript: "sub",
|
|
43278
|
-
strike: "s",
|
|
43279
|
-
del: "del",
|
|
43280
|
-
ins: "ins",
|
|
43281
|
-
underline: "u",
|
|
43282
|
-
highlight: "mark",
|
|
43283
|
-
code: "code"
|
|
43284
|
-
};
|
|
43285
|
-
var HtmlTableGenerator2 = class {
|
|
43286
|
-
constructor() {
|
|
43287
|
-
__publicField(this, "indentUnit", " ");
|
|
43288
|
-
}
|
|
43289
|
-
/**
|
|
43290
|
-
* Generate HTML table fragments from a string or JSON value.
|
|
43291
|
-
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
43292
|
-
*/
|
|
43293
|
-
generate(input) {
|
|
43294
|
-
let data = input;
|
|
43295
|
-
if (typeof data === "string") {
|
|
43296
|
-
try {
|
|
43297
|
-
data = JSON.parse(data);
|
|
43298
|
-
} catch {
|
|
43299
|
-
return "";
|
|
43300
|
-
}
|
|
43301
|
-
}
|
|
43302
|
-
const bits = this.collectBits(data);
|
|
43303
|
-
const fragments = [];
|
|
43304
|
-
for (const bit of bits) {
|
|
43305
|
-
const html = this.renderTableBit(bit);
|
|
43306
|
-
if (html) fragments.push(html);
|
|
43307
|
-
}
|
|
43308
|
-
return fragments.join("\n\n");
|
|
43309
|
-
}
|
|
43310
|
-
// --- bit collection -------------------------------------------------------
|
|
43311
|
-
collectBits(data) {
|
|
43312
|
-
const out = [];
|
|
43313
|
-
const visit = (value) => {
|
|
43314
|
-
if (value == null || typeof value !== "object") return;
|
|
43315
|
-
if (Array.isArray(value)) {
|
|
43316
|
-
value.forEach(visit);
|
|
43317
|
-
return;
|
|
43318
|
-
}
|
|
43319
|
-
const obj = value;
|
|
43320
|
-
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
43321
|
-
out.push(obj.bit);
|
|
43322
|
-
} else if ("type" in obj) {
|
|
43323
|
-
out.push(obj);
|
|
43324
|
-
}
|
|
43325
|
-
};
|
|
43326
|
-
visit(data);
|
|
43327
|
-
return out;
|
|
43328
|
-
}
|
|
43329
|
-
// --- table rendering ------------------------------------------------------
|
|
43330
|
-
renderTableBit(bit) {
|
|
43331
|
-
const table = bit.table;
|
|
43332
|
-
if (!table) return "";
|
|
43333
|
-
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
43334
|
-
const extended = this.toExtended(table);
|
|
43335
|
-
const lines = [];
|
|
43336
|
-
lines.push("<table>");
|
|
43337
|
-
if (bit.caption != null) {
|
|
43338
|
-
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
43339
|
-
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
43340
|
-
}
|
|
43341
|
-
this.renderSection(lines, "thead", extended.header, "header");
|
|
43342
|
-
this.renderSection(lines, "tbody", extended.body, "body");
|
|
43343
|
-
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
43344
|
-
lines.push("</table>");
|
|
43345
|
-
return lines.join("\n");
|
|
43346
|
-
}
|
|
43347
|
-
toExtended(table) {
|
|
43348
|
-
const t = table;
|
|
43349
|
-
if (t.header || t.body || t.footer) return table;
|
|
43350
|
-
return convertBasicToExtendedTableFormat(table);
|
|
43351
|
-
}
|
|
43352
|
-
renderSection(lines, tag, section, key) {
|
|
43353
|
-
if (!section || !section.rows || section.rows.length === 0) return;
|
|
43354
|
-
lines.push(`${this.indentUnit}<${tag}>`);
|
|
43355
|
-
for (const row of section.rows) {
|
|
43356
|
-
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
43357
|
-
for (const cell of row.cells ?? []) {
|
|
43358
|
-
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
43359
|
-
}
|
|
43360
|
-
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
43361
|
-
}
|
|
43362
|
-
lines.push(`${this.indentUnit}</${tag}>`);
|
|
43363
|
-
}
|
|
43364
|
-
renderCell(cell, _key) {
|
|
43365
|
-
const tag = cell.title === true ? "th" : "td";
|
|
43366
|
-
const attrs = [];
|
|
43367
|
-
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
43368
|
-
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
43369
|
-
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
43370
|
-
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
43371
|
-
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
43372
|
-
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
43373
|
-
}
|
|
43374
|
-
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
43375
|
-
asTextAst(content) {
|
|
43376
|
-
if (content == null) return [];
|
|
43377
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
43378
|
-
return content;
|
|
43379
|
-
}
|
|
43380
|
-
cellContentToHtml(blocks) {
|
|
43381
|
-
if (blocks.length === 0) return "";
|
|
43382
|
-
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
43383
|
-
return this.inlineToHtml(blocks[0].content ?? []);
|
|
43384
|
-
}
|
|
43385
|
-
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
43386
|
-
}
|
|
43387
|
-
blockToHtml(node) {
|
|
43388
|
-
switch (node.type) {
|
|
43389
|
-
case "paragraph":
|
|
43390
|
-
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
43391
|
-
case "bulletList":
|
|
43392
|
-
case "noBulletList":
|
|
43393
|
-
case "orderedList":
|
|
43394
|
-
case "orderedListRoman":
|
|
43395
|
-
case "orderedListRomanLower":
|
|
43396
|
-
case "letteredList":
|
|
43397
|
-
case "letteredListLower":
|
|
43398
|
-
case "taskList":
|
|
43399
|
-
return this.listToHtml(node);
|
|
43400
|
-
case "image":
|
|
43401
|
-
case "imageInline":
|
|
43402
|
-
return this.imageToHtml(node);
|
|
43403
|
-
default:
|
|
43404
|
-
return this.inlineToHtml([node]);
|
|
43405
|
-
}
|
|
43406
|
-
}
|
|
43407
|
-
inlineToHtml(nodes) {
|
|
43408
|
-
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
43409
|
-
}
|
|
43410
|
-
inlineNodeToHtml(node) {
|
|
43411
|
-
if (node.type === "hardBreak") return "<br>";
|
|
43412
|
-
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
43413
|
-
if (node.type === "text") {
|
|
43414
|
-
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
43415
|
-
}
|
|
43416
|
-
if (node.content) return this.inlineToHtml(node.content);
|
|
43417
|
-
return this.escapeText(node.text ?? "");
|
|
43418
|
-
}
|
|
43419
|
-
wrapMarks(text, marks) {
|
|
43420
|
-
if (!marks || marks.length === 0) return text;
|
|
43421
|
-
let open = "";
|
|
43422
|
-
let close = "";
|
|
43423
|
-
for (const mark of marks) {
|
|
43424
|
-
if (mark.type === "link") {
|
|
43425
|
-
const href = mark.attrs?.href ?? "";
|
|
43426
|
-
open += `<a href="${this.escapeAttr(href)}">`;
|
|
43427
|
-
close = `</a>${close}`;
|
|
43428
|
-
} else {
|
|
43429
|
-
const tag = MARK_TO_TAG[mark.type];
|
|
43430
|
-
if (tag) {
|
|
43431
|
-
open += `<${tag}>`;
|
|
43432
|
-
close = `</${tag}>${close}`;
|
|
43433
|
-
}
|
|
43434
|
-
}
|
|
43435
|
-
}
|
|
43436
|
-
return `${open}${text}${close}`;
|
|
43437
|
-
}
|
|
43438
|
-
// --- lists ----------------------------------------------------------------
|
|
43439
|
-
listToHtml(node) {
|
|
43440
|
-
const { tag, attrs } = this.listTag(node);
|
|
43441
|
-
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
43442
|
-
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
43443
|
-
}
|
|
43444
|
-
listTag(node) {
|
|
43445
|
-
const start = node.attrs?.start;
|
|
43446
|
-
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
43447
|
-
switch (node.type) {
|
|
43448
|
-
case "orderedList":
|
|
43449
|
-
return { tag: "ol", attrs: startAttr };
|
|
43450
|
-
case "orderedListRoman":
|
|
43451
|
-
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
43452
|
-
case "orderedListRomanLower":
|
|
43453
|
-
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
43454
|
-
case "letteredList":
|
|
43455
|
-
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
43456
|
-
case "letteredListLower":
|
|
43457
|
-
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
43458
|
-
case "noBulletList":
|
|
43459
|
-
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
43460
|
-
case "taskList":
|
|
43461
|
-
case "bulletList":
|
|
43462
|
-
default:
|
|
43463
|
-
return { tag: "ul", attrs: "" };
|
|
43464
|
-
}
|
|
43465
|
-
}
|
|
43466
|
-
listItemToHtml(item, task) {
|
|
43467
|
-
const inner = (item.content ?? []).map((b) => {
|
|
43468
|
-
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
43469
|
-
return this.blockToHtml(b);
|
|
43470
|
-
}).join("");
|
|
43471
|
-
if (task) {
|
|
43472
|
-
const checked = item.attrs?.checked ? " checked" : "";
|
|
43473
|
-
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
43474
|
-
}
|
|
43475
|
-
return `<li>${inner}</li>`;
|
|
43476
|
-
}
|
|
43477
|
-
// --- images ---------------------------------------------------------------
|
|
43478
|
-
imageToHtml(node) {
|
|
43479
|
-
const attrs = node.attrs ?? {};
|
|
43480
|
-
const parts = [];
|
|
43481
|
-
const src = attrs.src;
|
|
43482
|
-
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
43483
|
-
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
43484
|
-
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
43485
|
-
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
43486
|
-
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
43487
|
-
if (typeof attrs.class === "string" && attrs.class) {
|
|
43488
|
-
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
43489
|
-
}
|
|
43490
|
-
return `<img ${parts.join(" ")}>`;
|
|
43491
|
-
}
|
|
43492
|
-
// --- escaping -------------------------------------------------------------
|
|
43493
|
-
escapeText(text) {
|
|
43494
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
43495
|
-
}
|
|
43496
|
-
escapeAttr(text) {
|
|
43497
|
-
return this.escapeText(text).replace(/"/g, """);
|
|
43498
|
-
}
|
|
43499
|
-
};
|
|
43500
|
-
|
|
43501
|
-
// src/parser/html/HtmlDom.ts
|
|
43502
|
-
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
43503
|
-
"area",
|
|
43504
|
-
"base",
|
|
43505
|
-
"br",
|
|
43506
|
-
"col",
|
|
43507
|
-
"embed",
|
|
43508
|
-
"hr",
|
|
43509
|
-
"img",
|
|
43510
|
-
"input",
|
|
43511
|
-
"link",
|
|
43512
|
-
"meta",
|
|
43513
|
-
"param",
|
|
43514
|
-
"source",
|
|
43515
|
-
"track",
|
|
43516
|
-
"wbr"
|
|
43517
|
-
]);
|
|
43518
|
-
var IMPLIED_CLOSE = {
|
|
43519
|
-
li: /* @__PURE__ */ new Set(["li"]),
|
|
43520
|
-
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43521
|
-
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43522
|
-
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
43523
|
-
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43524
|
-
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43525
|
-
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43526
|
-
p: /* @__PURE__ */ new Set(["p"]),
|
|
43527
|
-
option: /* @__PURE__ */ new Set(["option"])
|
|
43528
|
-
};
|
|
43529
|
-
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
43530
|
-
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
43531
|
-
function parseAttrs(raw) {
|
|
43532
|
-
const attrs = {};
|
|
43533
|
-
if (!raw) return attrs;
|
|
43534
|
-
ATTR_RE.lastIndex = 0;
|
|
43535
|
-
let m;
|
|
43536
|
-
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
43537
|
-
const name = m[1].toLowerCase();
|
|
43538
|
-
let value = m[2] ?? "";
|
|
43539
|
-
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
43540
|
-
value = value.slice(1, -1);
|
|
43541
|
-
}
|
|
43542
|
-
attrs[name] = value;
|
|
43543
|
-
}
|
|
43544
|
-
return attrs;
|
|
43545
|
-
}
|
|
43546
|
-
function stripNonContent(html) {
|
|
43547
|
-
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, "");
|
|
43548
|
-
}
|
|
43549
|
-
function tokenize(html) {
|
|
43550
|
-
const tokens = [];
|
|
43551
|
-
const clean = stripNonContent(html);
|
|
43552
|
-
TAG_RE.lastIndex = 0;
|
|
43553
|
-
let lastIndex = 0;
|
|
43554
|
-
let m;
|
|
43555
|
-
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
43556
|
-
if (m.index > lastIndex) {
|
|
43557
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
43558
|
-
}
|
|
43559
|
-
lastIndex = TAG_RE.lastIndex;
|
|
43560
|
-
const isClose = m[1] === "/";
|
|
43561
|
-
const name = m[2].toLowerCase();
|
|
43562
|
-
if (isClose) {
|
|
43563
|
-
tokens.push({ kind: "close", name });
|
|
43564
|
-
} else {
|
|
43565
|
-
tokens.push({
|
|
43566
|
-
kind: "open",
|
|
43567
|
-
name,
|
|
43568
|
-
attrs: parseAttrs(m[3]),
|
|
43569
|
-
selfClose: m[4] === "/"
|
|
43570
|
-
});
|
|
43571
|
-
}
|
|
43572
|
-
}
|
|
43573
|
-
if (lastIndex < clean.length) {
|
|
43574
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
43575
|
-
}
|
|
43576
|
-
return tokens;
|
|
43577
|
-
}
|
|
43578
|
-
function parseHtml(html) {
|
|
43579
|
-
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
43580
|
-
const stack = [root];
|
|
43581
|
-
const top = () => stack[stack.length - 1];
|
|
43582
|
-
for (const token of tokenize(html)) {
|
|
43583
|
-
if (token.kind === "text") {
|
|
43584
|
-
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
43585
|
-
continue;
|
|
43586
|
-
}
|
|
43587
|
-
if (token.kind === "open") {
|
|
43588
|
-
const name = token.name;
|
|
43589
|
-
const closes = IMPLIED_CLOSE[name];
|
|
43590
|
-
if (closes) {
|
|
43591
|
-
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
43592
|
-
}
|
|
43593
|
-
const el = {
|
|
43594
|
-
type: "element",
|
|
43595
|
-
name,
|
|
43596
|
-
attrs: token.attrs ?? {},
|
|
43597
|
-
children: []
|
|
43598
|
-
};
|
|
43599
|
-
top().children.push(el);
|
|
43600
|
-
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
43601
|
-
stack.push(el);
|
|
43602
|
-
}
|
|
43603
|
-
continue;
|
|
43604
|
-
}
|
|
43605
|
-
for (let i = stack.length - 1; i > 0; i--) {
|
|
43606
|
-
if (stack[i].name === token.name) {
|
|
43607
|
-
stack.length = i;
|
|
43608
|
-
break;
|
|
43609
|
-
}
|
|
43610
|
-
}
|
|
43611
|
-
}
|
|
43612
|
-
return root.children;
|
|
43613
|
-
}
|
|
43614
|
-
function childElements(el, names) {
|
|
43615
|
-
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43616
|
-
}
|
|
43617
|
-
|
|
43618
|
-
// src/parser/html/HtmlTableParser.ts
|
|
43619
|
-
var MARK_TAGS = {
|
|
43620
|
-
b: "bold",
|
|
43621
|
-
strong: "bold",
|
|
43622
|
-
i: "italic",
|
|
43623
|
-
em: "italic",
|
|
43624
|
-
sup: "superscript",
|
|
43625
|
-
sub: "subscript",
|
|
43626
|
-
s: "strike",
|
|
43627
|
-
strike: "strike",
|
|
43628
|
-
del: "del",
|
|
43629
|
-
ins: "ins",
|
|
43630
|
-
u: "underline",
|
|
43631
|
-
mark: "highlight",
|
|
43632
|
-
code: "code"
|
|
43633
|
-
};
|
|
43634
|
-
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
43635
|
-
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
43636
|
-
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
43637
|
-
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
43638
|
-
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
43639
|
-
var NAMED_ENTITIES = {
|
|
43640
|
-
amp: "&",
|
|
43641
|
-
lt: "<",
|
|
43642
|
-
gt: ">",
|
|
43643
|
-
quot: '"',
|
|
43644
|
-
apos: "'",
|
|
43645
|
-
nbsp: "\xA0"
|
|
43646
|
-
};
|
|
43647
|
-
function decodeEntities(text) {
|
|
43648
|
-
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
43649
|
-
if (body[0] === "#") {
|
|
43650
|
-
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
43651
|
-
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
43652
|
-
try {
|
|
43653
|
-
return String.fromCodePoint(code);
|
|
43654
|
-
} catch {
|
|
43655
|
-
return whole;
|
|
43656
|
-
}
|
|
43657
|
-
}
|
|
43658
|
-
return whole;
|
|
43659
|
-
}
|
|
43660
|
-
return NAMED_ENTITIES[body] ?? whole;
|
|
43661
|
-
});
|
|
43662
|
-
}
|
|
43663
|
-
function intAttr(value) {
|
|
43664
|
-
if (value == null) return void 0;
|
|
43665
|
-
const n = Number.parseInt(value, 10);
|
|
43666
|
-
return Number.isInteger(n) ? n : void 0;
|
|
43667
|
-
}
|
|
43668
|
-
function isElement(node) {
|
|
43669
|
-
return node.type === "element";
|
|
43670
|
-
}
|
|
43671
|
-
var HtmlTableParser2 = class {
|
|
43672
|
-
constructor() {
|
|
43673
|
-
__publicField(this, "keepUnknownTags", false);
|
|
43674
|
-
}
|
|
43675
|
-
/**
|
|
43676
|
-
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
43677
|
-
*/
|
|
43678
|
-
parse(html, options) {
|
|
43679
|
-
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
43680
|
-
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
43681
|
-
const onWarning = options?.onWarning;
|
|
43682
|
-
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
43683
|
-
const bits = [];
|
|
43684
|
-
for (const table of tables) {
|
|
43685
|
-
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
43686
|
-
if (bit) bits.push(bit);
|
|
43687
|
-
}
|
|
43688
|
-
return bits;
|
|
43689
|
-
}
|
|
43690
|
-
// --- table extraction -----------------------------------------------------
|
|
43691
|
-
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
43692
|
-
collectTopLevelTables(nodes) {
|
|
43693
|
-
const tables = [];
|
|
43694
|
-
const visit = (node) => {
|
|
43695
|
-
if (!isElement(node)) return;
|
|
43696
|
-
if (node.name === "table") {
|
|
43697
|
-
tables.push(node);
|
|
43698
|
-
return;
|
|
43699
|
-
}
|
|
43700
|
-
node.children.forEach(visit);
|
|
43701
|
-
};
|
|
43702
|
-
nodes.forEach(visit);
|
|
43703
|
-
return tables;
|
|
43704
|
-
}
|
|
43705
|
-
tableToBit(table, tableFormat, onWarning) {
|
|
43706
|
-
const header = [];
|
|
43707
|
-
const body = [];
|
|
43708
|
-
const footer = [];
|
|
43709
|
-
let caption;
|
|
43710
|
-
for (const child of table.children) {
|
|
43711
|
-
if (!isElement(child)) continue;
|
|
43712
|
-
if (child.name === "caption") {
|
|
43713
|
-
const capContent = this.inlineNodes(child.children, []);
|
|
43714
|
-
const trimmed = this.trimInline(capContent);
|
|
43715
|
-
if (trimmed.length > 0) caption = trimmed;
|
|
43716
|
-
} else if (SECTION_TAGS.has(child.name)) {
|
|
43717
|
-
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
43718
|
-
for (const tr of childElements(child, ROW_TAGS)) {
|
|
43719
|
-
target.push(this.rowToCells(tr));
|
|
43720
|
-
}
|
|
43721
|
-
} else if (ROW_TAGS.has(child.name)) {
|
|
43722
|
-
body.push(this.rowToCells(child));
|
|
43723
|
-
}
|
|
43724
|
-
}
|
|
43725
|
-
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
43726
|
-
return void 0;
|
|
43727
|
-
}
|
|
43728
|
-
const tableExtended = {};
|
|
43729
|
-
if (header.length > 0) tableExtended.header = { rows: header };
|
|
43730
|
-
if (body.length > 0) tableExtended.body = { rows: body };
|
|
43731
|
-
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
43732
|
-
let tableData = tableExtended;
|
|
43733
|
-
if (tableFormat === "table") {
|
|
43734
|
-
if (this.isLossyAsBasic(tableExtended)) {
|
|
43735
|
-
onWarning?.(
|
|
43736
|
-
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
43737
|
-
);
|
|
43738
|
-
}
|
|
43739
|
-
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
43740
|
-
}
|
|
43741
|
-
const bit = {
|
|
43742
|
-
type: tableFormat,
|
|
43743
|
-
format: "bitmark++",
|
|
43744
|
-
table: tableData
|
|
43745
|
-
};
|
|
43746
|
-
if (caption) bit.caption = caption;
|
|
43747
|
-
return bit;
|
|
43748
|
-
}
|
|
43749
|
-
rowToCells(tr) {
|
|
43750
|
-
const cells = [];
|
|
43751
|
-
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
43752
|
-
cells.push(this.cellToJson(cell));
|
|
43753
|
-
}
|
|
43754
|
-
return { cells };
|
|
43755
|
-
}
|
|
43756
|
-
cellToJson(cell) {
|
|
43757
|
-
const json = {
|
|
43758
|
-
content: this.blockNodes(cell.children)
|
|
43759
|
-
};
|
|
43760
|
-
if (cell.name === "th") json.title = true;
|
|
43761
|
-
const rowspan = intAttr(cell.attrs.rowspan);
|
|
43762
|
-
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
43763
|
-
const colspan = intAttr(cell.attrs.colspan);
|
|
43764
|
-
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
43765
|
-
const scope = cell.attrs.scope?.toLowerCase();
|
|
43766
|
-
if (scope && VALID_SCOPES.has(scope)) {
|
|
43767
|
-
json.scope = scope;
|
|
43768
|
-
}
|
|
43769
|
-
const width = this.widthFromCell(cell);
|
|
43770
|
-
if (width != null) json.colwidth = width;
|
|
43771
|
-
return json;
|
|
43772
|
-
}
|
|
43773
|
-
widthFromCell(cell) {
|
|
43774
|
-
const attrWidth = intAttr(cell.attrs.width);
|
|
43775
|
-
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
43776
|
-
const style = cell.attrs.style;
|
|
43777
|
-
if (style) {
|
|
43778
|
-
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
43779
|
-
if (m) {
|
|
43780
|
-
const n = Number.parseInt(m[1], 10);
|
|
43781
|
-
if (Number.isInteger(n) && n > 0) return n;
|
|
43782
|
-
}
|
|
43783
|
-
}
|
|
43784
|
-
return void 0;
|
|
43785
|
-
}
|
|
43786
|
-
isLossyAsBasic(table) {
|
|
43787
|
-
if (table.footer) return true;
|
|
43788
|
-
if (table.header && table.header.rows.length > 1) return true;
|
|
43789
|
-
const sections = [table.header, table.body, table.footer];
|
|
43790
|
-
for (const section of sections) {
|
|
43791
|
-
if (!section) continue;
|
|
43792
|
-
for (const row of section.rows) {
|
|
43793
|
-
for (const cell of row.cells) {
|
|
43794
|
-
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
43795
|
-
}
|
|
43796
|
-
}
|
|
43797
|
-
}
|
|
43798
|
-
return false;
|
|
43799
|
-
}
|
|
43800
|
-
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
43801
|
-
/**
|
|
43802
|
-
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
43803
|
-
*/
|
|
43804
|
-
blockNodes(nodes) {
|
|
43805
|
-
const blocks = [];
|
|
43806
|
-
let inline = [];
|
|
43807
|
-
const flush = () => {
|
|
43808
|
-
const trimmed = this.trimInline(inline);
|
|
43809
|
-
inline = [];
|
|
43810
|
-
if (trimmed.length === 0) return;
|
|
43811
|
-
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
43812
|
-
blocks.push({ ...trimmed[0], type: "image" });
|
|
43813
|
-
} else {
|
|
43814
|
-
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
43815
|
-
}
|
|
43816
|
-
};
|
|
43817
|
-
for (const node of nodes) {
|
|
43818
|
-
if (!isElement(node)) {
|
|
43819
|
-
inline.push(...this.inlineText(node.value, []));
|
|
43820
|
-
continue;
|
|
43821
|
-
}
|
|
43822
|
-
const name = node.name;
|
|
43823
|
-
if (name === "p") {
|
|
43824
|
-
flush();
|
|
43825
|
-
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
43826
|
-
if (content.length > 0) {
|
|
43827
|
-
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
43828
|
-
}
|
|
43829
|
-
} else if (this.isListTag(name)) {
|
|
43830
|
-
flush();
|
|
43831
|
-
const list = this.listNode(node);
|
|
43832
|
-
if (list) blocks.push(list);
|
|
43833
|
-
} else {
|
|
43834
|
-
inline.push(...this.inlineFromElement(node, []));
|
|
43835
|
-
}
|
|
43836
|
-
}
|
|
43837
|
-
flush();
|
|
43838
|
-
return blocks;
|
|
43839
|
-
}
|
|
43840
|
-
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
43841
|
-
inlineNodes(nodes, marks) {
|
|
43842
|
-
const out = [];
|
|
43843
|
-
for (const node of nodes) {
|
|
43844
|
-
if (!isElement(node)) {
|
|
43845
|
-
out.push(...this.inlineText(node.value, marks));
|
|
43846
|
-
} else {
|
|
43847
|
-
out.push(...this.inlineFromElement(node, marks));
|
|
43848
|
-
}
|
|
43849
|
-
}
|
|
43850
|
-
return out;
|
|
43851
|
-
}
|
|
43852
|
-
inlineFromElement(el, marks) {
|
|
43853
|
-
const name = el.name;
|
|
43854
|
-
if (name === "br") {
|
|
43855
|
-
return [{ type: "hardBreak" }];
|
|
43856
|
-
}
|
|
43857
|
-
if (name === "img") {
|
|
43858
|
-
return [this.imageNode(el, true)];
|
|
43859
|
-
}
|
|
43860
|
-
const markType = MARK_TAGS[name];
|
|
43861
|
-
if (markType) {
|
|
43862
|
-
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
43863
|
-
}
|
|
43864
|
-
if (name === "a") {
|
|
43865
|
-
const linkMark = {
|
|
43866
|
-
type: "link",
|
|
43867
|
-
attrs: {
|
|
43868
|
-
href: el.attrs.href ?? "",
|
|
43869
|
-
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
43870
|
-
}
|
|
43871
|
-
};
|
|
43872
|
-
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
43873
|
-
}
|
|
43874
|
-
if (this.keepUnknownTags) {
|
|
43875
|
-
const open = this.serializeOpenTag(el);
|
|
43876
|
-
const close = `</${name}>`;
|
|
43877
|
-
return [
|
|
43878
|
-
...this.inlineText(open, marks),
|
|
43879
|
-
...this.inlineNodes(el.children, marks),
|
|
43880
|
-
...this.inlineText(close, marks)
|
|
43881
|
-
];
|
|
43882
|
-
}
|
|
43883
|
-
return this.inlineNodes(el.children, marks);
|
|
43884
|
-
}
|
|
43885
|
-
inlineText(raw, marks) {
|
|
43886
|
-
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
43887
|
-
if (text === "") return [];
|
|
43888
|
-
const node = { text, type: "text" };
|
|
43889
|
-
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
43890
|
-
return [node];
|
|
43891
|
-
}
|
|
43892
|
-
serializeOpenTag(el) {
|
|
43893
|
-
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
43894
|
-
return `<${el.name}${attrs}>`;
|
|
43895
|
-
}
|
|
43896
|
-
// --- lists ----------------------------------------------------------------
|
|
43897
|
-
isListTag(name) {
|
|
43898
|
-
return name === "ul" || name === "ol";
|
|
43899
|
-
}
|
|
43900
|
-
listNode(el) {
|
|
43901
|
-
const items = childElements(el, LI_TAGS);
|
|
43902
|
-
if (items.length === 0) return void 0;
|
|
43903
|
-
const isTask = el.name === "ul" && items.some((li) => {
|
|
43904
|
-
const firstEl = li.children.find(isElement);
|
|
43905
|
-
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
43906
|
-
});
|
|
43907
|
-
if (isTask) {
|
|
43908
|
-
return {
|
|
43909
|
-
type: "taskList",
|
|
43910
|
-
content: items.map((li) => this.taskItemNode(li))
|
|
43911
|
-
};
|
|
43912
|
-
}
|
|
43913
|
-
const type = this.listType(el);
|
|
43914
|
-
const node = {
|
|
43915
|
-
type,
|
|
43916
|
-
content: items.map((li) => this.listItemNode(li))
|
|
43917
|
-
};
|
|
43918
|
-
if (el.name === "ol") {
|
|
43919
|
-
const start = intAttr(el.attrs.start);
|
|
43920
|
-
if (start != null) {
|
|
43921
|
-
node.attrs = { start };
|
|
43922
|
-
}
|
|
43923
|
-
}
|
|
43924
|
-
return node;
|
|
43925
|
-
}
|
|
43926
|
-
listType(el) {
|
|
43927
|
-
if (el.name === "ol") {
|
|
43928
|
-
switch (el.attrs.type) {
|
|
43929
|
-
case "i":
|
|
43930
|
-
return "orderedListRomanLower";
|
|
43931
|
-
case "I":
|
|
43932
|
-
return "orderedListRoman";
|
|
43933
|
-
case "a":
|
|
43934
|
-
return "letteredListLower";
|
|
43935
|
-
case "A":
|
|
43936
|
-
return "letteredList";
|
|
43937
|
-
default:
|
|
43938
|
-
return "orderedList";
|
|
43939
|
-
}
|
|
43940
|
-
}
|
|
43941
|
-
const style = el.attrs.style ?? "";
|
|
43942
|
-
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
43943
|
-
return "bulletList";
|
|
43944
|
-
}
|
|
43945
|
-
listItemNode(li) {
|
|
43946
|
-
let content = this.blockNodes(li.children);
|
|
43947
|
-
if (content.length === 0) {
|
|
43948
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43949
|
-
}
|
|
43950
|
-
return { type: "listItem", content };
|
|
43951
|
-
}
|
|
43952
|
-
taskItemNode(li) {
|
|
43953
|
-
const checkbox = li.children.find(
|
|
43954
|
-
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
43955
|
-
);
|
|
43956
|
-
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
43957
|
-
const rest = li.children.filter((c) => c !== checkbox);
|
|
43958
|
-
let content = this.blockNodes(rest);
|
|
43959
|
-
if (content.length === 0) {
|
|
43960
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43961
|
-
}
|
|
43962
|
-
return { type: "taskItem", attrs: { checked }, content };
|
|
43963
|
-
}
|
|
43964
|
-
// --- images ---------------------------------------------------------------
|
|
43965
|
-
imageNode(el, inline) {
|
|
43966
|
-
const attrs = { src: el.attrs.src ?? "" };
|
|
43967
|
-
attrs.alt = el.attrs.alt ?? null;
|
|
43968
|
-
attrs.title = el.attrs.title ?? null;
|
|
43969
|
-
const width = intAttr(el.attrs.width);
|
|
43970
|
-
if (width != null) attrs.width = width;
|
|
43971
|
-
const height = intAttr(el.attrs.height);
|
|
43972
|
-
if (height != null) attrs.height = height;
|
|
43973
|
-
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
43974
|
-
return { type: inline ? "imageInline" : "image", attrs };
|
|
43975
|
-
}
|
|
43976
|
-
// --- whitespace -----------------------------------------------------------
|
|
43977
|
-
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
43978
|
-
trimInline(nodes) {
|
|
43979
|
-
const out = nodes.slice();
|
|
43980
|
-
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
43981
|
-
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
43982
|
-
if (out.length > 0 && out[0].type === "text") {
|
|
43983
|
-
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
43984
|
-
}
|
|
43985
|
-
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
43986
|
-
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
43987
|
-
const last = out.length - 1;
|
|
43988
|
-
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
43989
|
-
}
|
|
43990
|
-
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
43991
|
-
}
|
|
43992
|
-
};
|
|
43993
|
-
|
|
43994
44370
|
// src/index.ts
|
|
43995
44371
|
init();
|
|
43996
44372
|
// Annotate the CommonJS export names for ESM import in node:
|