@gmb/bitmark-parser-generator 5.26.0 → 5.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/bitmark-parser-generator.min.js +1 -1
- package/dist/browser/bundle-report.html +2 -2
- package/dist/browser/cjs/index.cjs +976 -743
- package/dist/browser/cjs/index.cjs.map +1 -1
- package/dist/browser/cjs/index.d.cts +120 -62
- package/dist/browser/esm/index.d.ts +120 -62
- package/dist/browser/esm/index.js +976 -743
- package/dist/browser/esm/index.js.map +1 -1
- package/dist/cli/main.js +1014 -754
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +1016 -756
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -62
- package/dist/index.d.ts +120 -62
- package/dist/index.js +1016 -756
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.js
CHANGED
|
@@ -545,6 +545,14 @@ var BitType = {
|
|
|
545
545
|
smartStandardRemarkNonNormativeCollapsible: "smart-standard-remark-non-normative-collapsible",
|
|
546
546
|
smartStandardRemarkNormative: "smart-standard-remark-normative",
|
|
547
547
|
smartStandardRemarkNormativeCollapsible: "smart-standard-remark-normative-collapsible",
|
|
548
|
+
smartStandardRemarkTableExtendedImageNonNormative: "smart-standard-remark-table-extended-image-non-normative",
|
|
549
|
+
smartStandardRemarkTableExtendedImageNonNormativeCollapsible: "smart-standard-remark-table-extended-image-non-normative-collapsible",
|
|
550
|
+
smartStandardRemarkTableExtendedImageNormative: "smart-standard-remark-table-extended-image-normative",
|
|
551
|
+
smartStandardRemarkTableExtendedImageNormativeCollapsible: "smart-standard-remark-table-extended-image-normative-collapsible",
|
|
552
|
+
smartStandardRemarkTableExtendedNonNormative: "smart-standard-remark-table-extended-non-normative",
|
|
553
|
+
smartStandardRemarkTableExtendedNonNormativeCollapsible: "smart-standard-remark-table-extended-non-normative-collapsible",
|
|
554
|
+
smartStandardRemarkTableExtendedNormative: "smart-standard-remark-table-extended-normative",
|
|
555
|
+
smartStandardRemarkTableExtendedNormativeCollapsible: "smart-standard-remark-table-extended-normative-collapsible",
|
|
548
556
|
smartStandardRemarkTableImageNonNormative: "smart-standard-remark-table-image-non-normative",
|
|
549
557
|
smartStandardRemarkTableImageNonNormativeCollapsible: "smart-standard-remark-table-image-non-normative-collapsible",
|
|
550
558
|
smartStandardRemarkTableImageNormative: "smart-standard-remark-table-image-normative",
|
|
@@ -553,6 +561,14 @@ var BitType = {
|
|
|
553
561
|
smartStandardRemarkTableNonNormativeCollapsible: "smart-standard-remark-table-non-normative-collapsible",
|
|
554
562
|
smartStandardRemarkTableNormative: "smart-standard-remark-table-normative",
|
|
555
563
|
smartStandardRemarkTableNormativeCollapsible: "smart-standard-remark-table-normative-collapsible",
|
|
564
|
+
smartStandardTableExtendedImageNonNormative: "smart-standard-table-extended-image-non-normative",
|
|
565
|
+
smartStandardTableExtendedImageNonNormativeCollapsible: "smart-standard-table-extended-image-non-normative-collapsible",
|
|
566
|
+
smartStandardTableExtendedImageNormative: "smart-standard-table-extended-image-normative",
|
|
567
|
+
smartStandardTableExtendedImageNormativeCollapsible: "smart-standard-table-extended-image-normative-collapsible",
|
|
568
|
+
smartStandardTableExtendedNonNormative: "smart-standard-table-extended-non-normative",
|
|
569
|
+
smartStandardTableExtendedNonNormativeCollapsible: "smart-standard-table-extended-non-normative-collapsible",
|
|
570
|
+
smartStandardTableExtendedNormative: "smart-standard-table-extended-normative",
|
|
571
|
+
smartStandardTableExtendedNormativeCollapsible: "smart-standard-table-extended-normative-collapsible",
|
|
556
572
|
smartStandardTableImageNonNormative: "smart-standard-table-image-non-normative",
|
|
557
573
|
smartStandardTableImageNonNormativeCollapsible: "smart-standard-table-image-non-normative-collapsible",
|
|
558
574
|
smartStandardTableImageNormative: "smart-standard-table-image-normative",
|
|
@@ -575,10 +591,18 @@ var BitType = {
|
|
|
575
591
|
standardNoteNormative: "standard-note-normative",
|
|
576
592
|
standardRemarkNonNormative: "standard-remark-non-normative",
|
|
577
593
|
standardRemarkNormative: "standard-remark-normative",
|
|
594
|
+
standardRemarkTableExtendedImageNonNormative: "standard-remark-table-extended-image-non-normative",
|
|
595
|
+
standardRemarkTableExtendedImageNormative: "standard-remark-table-extended-image-normative",
|
|
596
|
+
standardRemarkTableExtendedNonNormative: "standard-remark-table-extended-non-normative",
|
|
597
|
+
standardRemarkTableExtendedNormative: "standard-remark-table-extended-normative",
|
|
578
598
|
standardRemarkTableImageNonNormative: "standard-remark-table-image-non-normative",
|
|
579
599
|
standardRemarkTableImageNormative: "standard-remark-table-image-normative",
|
|
580
600
|
standardRemarkTableNonNormative: "standard-remark-table-non-normative",
|
|
581
601
|
standardRemarkTableNormative: "standard-remark-table-normative",
|
|
602
|
+
standardTableExtendedImageNonNormative: "standard-table-extended-image-non-normative",
|
|
603
|
+
standardTableExtendedImageNormative: "standard-table-extended-image-normative",
|
|
604
|
+
standardTableExtendedNonNormative: "standard-table-extended-non-normative",
|
|
605
|
+
standardTableExtendedNormative: "standard-table-extended-normative",
|
|
582
606
|
standardTableImageNonNormative: "standard-table-image-non-normative",
|
|
583
607
|
standardTableImageNormative: "standard-table-image-normative",
|
|
584
608
|
standardTableNonNormative: "standard-table-non-normative",
|
|
@@ -777,6 +801,10 @@ var AbstractTagConfig = class {
|
|
|
777
801
|
// New JSON-pattern jsonKey (export-only)
|
|
778
802
|
hasExportJsonKey;
|
|
779
803
|
// True iff exportJsonKey was explicitly set
|
|
804
|
+
htmlKey;
|
|
805
|
+
// HTML key-pattern (export-only)
|
|
806
|
+
hasHtmlKey;
|
|
807
|
+
// True iff htmlKey was explicitly set
|
|
780
808
|
deprecated;
|
|
781
809
|
// Deprecated version
|
|
782
810
|
constructor(params) {
|
|
@@ -789,6 +817,8 @@ var AbstractTagConfig = class {
|
|
|
789
817
|
this.jsonKey = params.jsonKey;
|
|
790
818
|
this.exportJsonKey = params.exportJsonKey;
|
|
791
819
|
this.hasExportJsonKey = params.hasExportJsonKey;
|
|
820
|
+
this.htmlKey = params.htmlKey;
|
|
821
|
+
this.hasHtmlKey = params.hasHtmlKey;
|
|
792
822
|
this.deprecated = params.deprecated;
|
|
793
823
|
}
|
|
794
824
|
};
|
|
@@ -922,9 +952,12 @@ var CardVariantConfig = class {
|
|
|
922
952
|
exportJsonKey;
|
|
923
953
|
// New JSON-pattern jsonKey
|
|
924
954
|
hasExportJsonKey;
|
|
955
|
+
htmlKey;
|
|
956
|
+
// HTML key-pattern
|
|
957
|
+
hasHtmlKey;
|
|
925
958
|
format;
|
|
926
959
|
// Body text format. Default: bitmark++
|
|
927
|
-
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format) {
|
|
960
|
+
constructor(tags2, bodyAllowed, bodyRequired, repeatCount, jsonKey, exportJsonKey, hasExportJsonKey = false, format, htmlKey, hasHtmlKey = false) {
|
|
928
961
|
this.tags = tags2;
|
|
929
962
|
this.bodyAllowed = bodyAllowed == null ? true : bodyAllowed;
|
|
930
963
|
this.bodyRequired = bodyRequired;
|
|
@@ -932,6 +965,8 @@ var CardVariantConfig = class {
|
|
|
932
965
|
this.jsonKey = jsonKey;
|
|
933
966
|
this.exportJsonKey = exportJsonKey;
|
|
934
967
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
968
|
+
this.htmlKey = htmlKey;
|
|
969
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
935
970
|
this.format = format;
|
|
936
971
|
}
|
|
937
972
|
toString(options) {
|
|
@@ -961,13 +996,17 @@ var CardSideConfig = class {
|
|
|
961
996
|
jsonKey;
|
|
962
997
|
exportJsonKey;
|
|
963
998
|
hasExportJsonKey;
|
|
999
|
+
htmlKey;
|
|
1000
|
+
hasHtmlKey;
|
|
964
1001
|
variants;
|
|
965
|
-
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false) {
|
|
1002
|
+
constructor(name, repeat, variants, jsonKey, exportJsonKey, hasExportJsonKey = false, htmlKey, hasHtmlKey = false) {
|
|
966
1003
|
this.name = name;
|
|
967
1004
|
this.repeat = repeat;
|
|
968
1005
|
this.jsonKey = jsonKey;
|
|
969
1006
|
this.exportJsonKey = exportJsonKey;
|
|
970
1007
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1008
|
+
this.htmlKey = htmlKey;
|
|
1009
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
971
1010
|
this.variants = variants;
|
|
972
1011
|
}
|
|
973
1012
|
toString(options) {
|
|
@@ -993,6 +1032,8 @@ var CardSetConfig = class {
|
|
|
993
1032
|
jsonKey;
|
|
994
1033
|
exportJsonKey;
|
|
995
1034
|
hasExportJsonKey;
|
|
1035
|
+
htmlKey;
|
|
1036
|
+
hasHtmlKey;
|
|
996
1037
|
sections;
|
|
997
1038
|
sides;
|
|
998
1039
|
// Legacy accessor — provides the same shape as the old `variants: CardVariantConfig[][]`
|
|
@@ -1000,11 +1041,13 @@ var CardSetConfig = class {
|
|
|
1000
1041
|
get variants() {
|
|
1001
1042
|
return this.sides.map((side) => side.variants);
|
|
1002
1043
|
}
|
|
1003
|
-
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides) {
|
|
1044
|
+
constructor(configKey, jsonKey, exportJsonKey, hasExportJsonKey, sections, sides, htmlKey = void 0, hasHtmlKey = false) {
|
|
1004
1045
|
this.configKey = configKey;
|
|
1005
1046
|
this.jsonKey = jsonKey;
|
|
1006
1047
|
this.exportJsonKey = exportJsonKey;
|
|
1007
1048
|
this.hasExportJsonKey = hasExportJsonKey;
|
|
1049
|
+
this.htmlKey = htmlKey;
|
|
1050
|
+
this.hasHtmlKey = hasHtmlKey;
|
|
1008
1051
|
this.sections = sections;
|
|
1009
1052
|
this.sides = sides;
|
|
1010
1053
|
}
|
|
@@ -3661,6 +3704,16 @@ var CARDSETS = {
|
|
|
3661
3704
|
[CardSetConfigKey.table]: {
|
|
3662
3705
|
jsonKey: null,
|
|
3663
3706
|
exportJsonKey: null,
|
|
3707
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping. The classic (non-extended)
|
|
3708
|
+
// table produces the same `<table>`/`<thead>`/`<tbody>`/`<tfoot>` structure as
|
|
3709
|
+
// table-extended, so the structural htmlKeys mirror that cardSet. NOTE: the
|
|
3710
|
+
// JSON side routes the FIRST header card → `columns` (header) and SUBSEQUENT
|
|
3711
|
+
// header cards → `data` (body); HTML uses a uniform `<thead>` for the whole
|
|
3712
|
+
// `table-header` section, so a multi-card header (e.g. a second header card
|
|
3713
|
+
// that JSON sends to `data`) renders as additional `<thead>` rows rather than
|
|
3714
|
+
// moving to `<tbody>`. Per-card header/body splitting needs engine-level
|
|
3715
|
+
// routing not yet expressible in the pattern vocabulary — see PLAN-109.
|
|
3716
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3664
3717
|
sections: {
|
|
3665
3718
|
"table-header": {
|
|
3666
3719
|
// First header card's row of cells → `columns`. Subsequent header
|
|
@@ -3679,25 +3732,36 @@ var CARDSETS = {
|
|
|
3679
3732
|
},
|
|
3680
3733
|
{ "@cardIndex=0": { "@bit": { table: { columns: "$" } } } },
|
|
3681
3734
|
{ "@bit": { table: { data: ["$"] } } }
|
|
3682
|
-
]
|
|
3735
|
+
],
|
|
3736
|
+
// Header section → `<thead>` rows of `<th>`; `@tableColWidth` bubbles a
|
|
3737
|
+
// `width` attr onto the enclosing `<th>` (HTML-C2).
|
|
3738
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3739
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3683
3740
|
},
|
|
3684
3741
|
"table-body": {
|
|
3685
3742
|
// Batched emission: `$` is the entire 2D array of body card rows.
|
|
3686
3743
|
// This is the default section (no qualifier → cards land here).
|
|
3687
3744
|
jsonKey: "table.data",
|
|
3688
3745
|
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3746
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3689
3747
|
isDefault: true
|
|
3690
3748
|
},
|
|
3691
3749
|
"table-footer": {
|
|
3692
3750
|
// Batched emission: `$` is the entire 2D array of footer rows.
|
|
3693
3751
|
jsonKey: "table.data",
|
|
3694
|
-
exportJsonKey: { "@bit": { table: { data: "$" } } }
|
|
3752
|
+
exportJsonKey: { "@bit": { table: { data: "$" } } },
|
|
3753
|
+
// Footer cells route to `data` (not `columns`), so they are `<td>` (no
|
|
3754
|
+
// sideHtmlKey override — the cell side default applies).
|
|
3755
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } }
|
|
3695
3756
|
}
|
|
3696
3757
|
},
|
|
3697
3758
|
sides: [
|
|
3698
3759
|
{
|
|
3699
3760
|
name: "cell",
|
|
3700
3761
|
repeat: true,
|
|
3762
|
+
// Default (body/footer) cell → `<td>`; the header section overrides to
|
|
3763
|
+
// `<th>` via its sideHtmlKey (HTML.md §8).
|
|
3764
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3701
3765
|
variants: [
|
|
3702
3766
|
{
|
|
3703
3767
|
jsonKey: null,
|
|
@@ -3714,6 +3778,8 @@ var CARDSETS = {
|
|
|
3714
3778
|
},
|
|
3715
3779
|
{
|
|
3716
3780
|
key: ConfigKey.property_tableCellType,
|
|
3781
|
+
// HTML.md §8: first-match predicate selecting `<th>` vs `<td>`.
|
|
3782
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3717
3783
|
description: "Table cell type (th/td).",
|
|
3718
3784
|
format: TagFormat.plainText
|
|
3719
3785
|
},
|
|
@@ -3736,6 +3802,9 @@ var CARDSETS = {
|
|
|
3736
3802
|
key: ConfigKey.property_tableColWidth,
|
|
3737
3803
|
jsonKey: "^table.columnWidths[{s}]",
|
|
3738
3804
|
exportJsonKey: { "@bit": { table: { columnWidths: { $s: "$" } } } },
|
|
3805
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3806
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3807
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3739
3808
|
description: "Width for the column.",
|
|
3740
3809
|
format: TagFormat.number
|
|
3741
3810
|
}
|
|
@@ -3751,6 +3820,12 @@ var CARDSETS = {
|
|
|
3751
3820
|
//
|
|
3752
3821
|
[CardSetConfigKey.tableExtended]: {
|
|
3753
3822
|
jsonKey: null,
|
|
3823
|
+
// PLAN-109 / HTML.md §8 — idiomatic HTML mapping for the extended table.
|
|
3824
|
+
// The card-set container is the `<table>` element; each section is a
|
|
3825
|
+
// table section element (`<thead>`/`<tbody>`/`<tfoot>`) whose children are
|
|
3826
|
+
// `<tr>` rows, and each cell side is a `<td>` (body) or `<th>` (header /
|
|
3827
|
+
// footer, via the section sideHtmlKey override).
|
|
3828
|
+
htmlKey: { "@el": "table", "@children": "$" },
|
|
3754
3829
|
sections: {
|
|
3755
3830
|
"table-header": {
|
|
3756
3831
|
jsonKey: "table.header.rows",
|
|
@@ -3770,19 +3845,29 @@ var CARDSETS = {
|
|
|
3770
3845
|
},
|
|
3771
3846
|
{ table: { header: { rows: ["$"] } } }
|
|
3772
3847
|
],
|
|
3848
|
+
htmlKey: { "@el": "thead", "@children": { "@el": "tr", "@children": "$" } },
|
|
3773
3849
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3774
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3850
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3851
|
+
// Header cells are `<th>`. The `width` attribute is contributed by the
|
|
3852
|
+
// `@tableColWidth` tag, which bubbles it onto the enclosing `<th>`
|
|
3853
|
+
// (HTML-C2) — so it is not repeated here.
|
|
3854
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3775
3855
|
},
|
|
3776
3856
|
"table-body": {
|
|
3777
3857
|
jsonKey: "table.body.rows",
|
|
3778
3858
|
exportJsonKey: { table: { body: { rows: "$" } } },
|
|
3859
|
+
htmlKey: { "@el": "tbody", "@children": { "@el": "tr", "@children": "$" } },
|
|
3779
3860
|
isDefault: true
|
|
3780
3861
|
},
|
|
3781
3862
|
"table-footer": {
|
|
3782
3863
|
jsonKey: "table.footer.rows",
|
|
3783
3864
|
exportJsonKey: { table: { footer: { rows: "$" } } },
|
|
3865
|
+
htmlKey: { "@el": "tfoot", "@children": { "@el": "tr", "@children": "$" } },
|
|
3784
3866
|
sideJsonKey: "cells[{s}]|set(title=true)",
|
|
3785
|
-
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } }
|
|
3867
|
+
sideExportJsonKey: { cells: { $s: { title: true, $: "$" } } },
|
|
3868
|
+
// Footer cells render as `<th>` (mirrors the header `title: true`
|
|
3869
|
+
// mapping); §8 lists only the header side, so this parallels it.
|
|
3870
|
+
sideHtmlKey: { "@el": "th", "@children": "$" }
|
|
3786
3871
|
}
|
|
3787
3872
|
},
|
|
3788
3873
|
sides: [
|
|
@@ -3791,6 +3876,9 @@ var CARDSETS = {
|
|
|
3791
3876
|
repeat: true,
|
|
3792
3877
|
jsonKey: "cells[{s}]",
|
|
3793
3878
|
exportJsonKey: { cells: { $s: "$" } },
|
|
3879
|
+
// Default (body) cell → `<td>`; the header/footer sections override the
|
|
3880
|
+
// side to `<th>` via their sideHtmlKey (HTML.md §8).
|
|
3881
|
+
htmlKey: { "@el": "td", "@children": "$" },
|
|
3794
3882
|
variants: [
|
|
3795
3883
|
{
|
|
3796
3884
|
jsonKey: "content",
|
|
@@ -3814,6 +3902,9 @@ var CARDSETS = {
|
|
|
3814
3902
|
key: ConfigKey.property_tableCellType,
|
|
3815
3903
|
jsonKey: "title|bool(th)",
|
|
3816
3904
|
exportJsonKey: [{ "@value=th": { title: true } }],
|
|
3905
|
+
// HTML.md §8: same first-match predicate machinery selecting
|
|
3906
|
+
// `<th>` vs `<td>` instead of `title:true` vs nothing.
|
|
3907
|
+
htmlKey: [{ "@value=th": { "@el": "th" } }, { "@absent": { "@el": "td" } }],
|
|
3817
3908
|
description: "Table cell type (th/td).",
|
|
3818
3909
|
format: TagFormat.plainText
|
|
3819
3910
|
},
|
|
@@ -3843,6 +3934,9 @@ var CARDSETS = {
|
|
|
3843
3934
|
// PLAN-080: write to the cell's `colwidth` field.
|
|
3844
3935
|
jsonKey: "colwidth",
|
|
3845
3936
|
exportJsonKey: { colwidth: "$" },
|
|
3937
|
+
// HTML.md §8 + HTML-C2: contribute a `width` attribute onto the
|
|
3938
|
+
// enclosing cell element (`<th>`/`<td>`).
|
|
3939
|
+
htmlKey: { "@el": { "@attr": { width: "$" } } },
|
|
3846
3940
|
description: "Width for the column.",
|
|
3847
3941
|
format: TagFormat.number
|
|
3848
3942
|
}
|
|
@@ -6771,7 +6865,9 @@ var ConfigHydrator = class {
|
|
|
6771
6865
|
variantsOfSide,
|
|
6772
6866
|
_side.jsonKey,
|
|
6773
6867
|
_side.exportJsonKey,
|
|
6774
|
-
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey")
|
|
6868
|
+
Object.prototype.hasOwnProperty.call(_side, "exportJsonKey"),
|
|
6869
|
+
_side.htmlKey,
|
|
6870
|
+
Object.prototype.hasOwnProperty.call(_side, "htmlKey")
|
|
6775
6871
|
);
|
|
6776
6872
|
sides.push(sideConfig);
|
|
6777
6873
|
}
|
|
@@ -6781,7 +6877,9 @@ var ConfigHydrator = class {
|
|
|
6781
6877
|
_cardSetConfig.exportJsonKey,
|
|
6782
6878
|
Object.prototype.hasOwnProperty.call(_cardSetConfig, "exportJsonKey"),
|
|
6783
6879
|
this.hydrateCardSections(_cardSetConfig.sections),
|
|
6784
|
-
sides
|
|
6880
|
+
sides,
|
|
6881
|
+
_cardSetConfig.htmlKey,
|
|
6882
|
+
Object.prototype.hasOwnProperty.call(_cardSetConfig, "htmlKey")
|
|
6785
6883
|
);
|
|
6786
6884
|
return cardSetConfig;
|
|
6787
6885
|
}
|
|
@@ -6793,10 +6891,14 @@ var ConfigHydrator = class {
|
|
|
6793
6891
|
jsonKey: v.jsonKey,
|
|
6794
6892
|
exportJsonKey: v.exportJsonKey,
|
|
6795
6893
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(v, "exportJsonKey"),
|
|
6894
|
+
htmlKey: v.htmlKey,
|
|
6895
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(v, "htmlKey"),
|
|
6796
6896
|
isDefault: v.isDefault,
|
|
6797
6897
|
sideJsonKey: v.sideJsonKey,
|
|
6798
6898
|
sideExportJsonKey: v.sideExportJsonKey,
|
|
6799
6899
|
hasSideExportJsonKey: Object.prototype.hasOwnProperty.call(v, "sideExportJsonKey"),
|
|
6900
|
+
sideHtmlKey: v.sideHtmlKey,
|
|
6901
|
+
hasSideHtmlKey: Object.prototype.hasOwnProperty.call(v, "sideHtmlKey"),
|
|
6800
6902
|
// PLAN-085: cardinality fields pass through; defaults applied
|
|
6801
6903
|
// downstream by the config consumer (Rust treats `0` / undefined
|
|
6802
6904
|
// as unbounded).
|
|
@@ -6814,7 +6916,8 @@ var ConfigHydrator = class {
|
|
|
6814
6916
|
chain: _chain,
|
|
6815
6917
|
deprecated,
|
|
6816
6918
|
jsonKey,
|
|
6817
|
-
exportJsonKey
|
|
6919
|
+
exportJsonKey,
|
|
6920
|
+
htmlKey
|
|
6818
6921
|
} = _tag;
|
|
6819
6922
|
const configKey = Enum(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6820
6923
|
if (!configKey) throw new Error(`No tag key found for config key '${configKey}'`);
|
|
@@ -6833,6 +6936,8 @@ var ConfigHydrator = class {
|
|
|
6833
6936
|
jsonKey,
|
|
6834
6937
|
exportJsonKey,
|
|
6835
6938
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
6939
|
+
htmlKey,
|
|
6940
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6836
6941
|
deprecated
|
|
6837
6942
|
});
|
|
6838
6943
|
return {
|
|
@@ -6852,7 +6957,8 @@ var ConfigHydrator = class {
|
|
|
6852
6957
|
values,
|
|
6853
6958
|
defaultValue,
|
|
6854
6959
|
jsonKey,
|
|
6855
|
-
exportJsonKey
|
|
6960
|
+
exportJsonKey,
|
|
6961
|
+
htmlKey
|
|
6856
6962
|
} = _tag;
|
|
6857
6963
|
const configKey = Enum(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6858
6964
|
if (!configKey) throw new Error(`No property key found for config key '${configKey}'`);
|
|
@@ -6870,6 +6976,8 @@ var ConfigHydrator = class {
|
|
|
6870
6976
|
jsonKey,
|
|
6871
6977
|
exportJsonKey,
|
|
6872
6978
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
6979
|
+
htmlKey,
|
|
6980
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6873
6981
|
format,
|
|
6874
6982
|
values,
|
|
6875
6983
|
defaultValue,
|
|
@@ -6889,7 +6997,8 @@ var ConfigHydrator = class {
|
|
|
6889
6997
|
chain: _chain,
|
|
6890
6998
|
deprecated,
|
|
6891
6999
|
jsonKey,
|
|
6892
|
-
exportJsonKey
|
|
7000
|
+
exportJsonKey,
|
|
7001
|
+
htmlKey
|
|
6893
7002
|
} = _tag;
|
|
6894
7003
|
const configKey = Enum(ConfigKey).fromValue(_configKey) || ConfigKey._unknown;
|
|
6895
7004
|
if (!configKey) throw new Error(`No resource key found for config key '${configKey}'`);
|
|
@@ -6907,6 +7016,8 @@ var ConfigHydrator = class {
|
|
|
6907
7016
|
jsonKey,
|
|
6908
7017
|
exportJsonKey,
|
|
6909
7018
|
hasExportJsonKey: Object.prototype.hasOwnProperty.call(_tag, "exportJsonKey"),
|
|
7019
|
+
htmlKey,
|
|
7020
|
+
hasHtmlKey: Object.prototype.hasOwnProperty.call(_tag, "htmlKey"),
|
|
6910
7021
|
deprecated
|
|
6911
7022
|
});
|
|
6912
7023
|
return {
|
|
@@ -6945,6 +7056,7 @@ var ConfigHydrator = class {
|
|
|
6945
7056
|
repeatCount,
|
|
6946
7057
|
jsonKey,
|
|
6947
7058
|
exportJsonKey,
|
|
7059
|
+
htmlKey,
|
|
6948
7060
|
format
|
|
6949
7061
|
} = _variant;
|
|
6950
7062
|
const tags2 = this.hydrateTagsConfig(_tags);
|
|
@@ -6956,7 +7068,9 @@ var ConfigHydrator = class {
|
|
|
6956
7068
|
jsonKey,
|
|
6957
7069
|
exportJsonKey,
|
|
6958
7070
|
Object.prototype.hasOwnProperty.call(_variant, "exportJsonKey"),
|
|
6959
|
-
format
|
|
7071
|
+
format,
|
|
7072
|
+
htmlKey,
|
|
7073
|
+
Object.prototype.hasOwnProperty.call(_variant, "htmlKey")
|
|
6960
7074
|
);
|
|
6961
7075
|
return cardSetConfig;
|
|
6962
7076
|
}
|
|
@@ -10089,11 +10203,6 @@ var BITS = {
|
|
|
10089
10203
|
baseBitType: BitType._standard,
|
|
10090
10204
|
description: "Extractor rule bit, used to define extraction rules with reference images and instructions",
|
|
10091
10205
|
tags: [
|
|
10092
|
-
{
|
|
10093
|
-
exportJsonKey: { title: "$" },
|
|
10094
|
-
key: ConfigKey.tag_title,
|
|
10095
|
-
description: "The name of the extraction rule"
|
|
10096
|
-
},
|
|
10097
10206
|
{
|
|
10098
10207
|
key: ConfigKey.group_resourceBitTags,
|
|
10099
10208
|
description: "Resource bit tags for extraction rule images"
|
|
@@ -10772,6 +10881,26 @@ var BITS = {
|
|
|
10772
10881
|
baseBitType: BitType.tableImage,
|
|
10773
10882
|
description: "Standard non-normative remark table image bit, used to create non-normative remark images in tables in articles or books"
|
|
10774
10883
|
},
|
|
10884
|
+
[BitType.standardTableExtendedImageNormative]: {
|
|
10885
|
+
since: "1.16.0",
|
|
10886
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10887
|
+
description: "Standard normative extended table image bit, used to create normative extended images in tables in articles or books"
|
|
10888
|
+
},
|
|
10889
|
+
[BitType.standardTableExtendedImageNonNormative]: {
|
|
10890
|
+
since: "1.16.0",
|
|
10891
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10892
|
+
description: "Standard non-normative extended table image bit, used to create non-normative extended images in tables in articles or books"
|
|
10893
|
+
},
|
|
10894
|
+
[BitType.standardRemarkTableExtendedImageNormative]: {
|
|
10895
|
+
since: "1.17.0",
|
|
10896
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10897
|
+
description: "Standard normative remark extended table image bit, used to create normative remark extended images in tables in articles or books"
|
|
10898
|
+
},
|
|
10899
|
+
[BitType.standardRemarkTableExtendedImageNonNormative]: {
|
|
10900
|
+
since: "1.17.0",
|
|
10901
|
+
baseBitType: BitType.tableExtendedImage,
|
|
10902
|
+
description: "Standard non-normative remark extended table image bit, used to create non-normative remark extended images in tables in articles or books"
|
|
10903
|
+
},
|
|
10775
10904
|
[BitType.smartStandardTableImageNormative]: {
|
|
10776
10905
|
since: "1.28.0",
|
|
10777
10906
|
baseBitType: BitType.standardTableImageNormative,
|
|
@@ -10792,6 +10921,26 @@ var BITS = {
|
|
|
10792
10921
|
baseBitType: BitType.standardRemarkTableImageNonNormative,
|
|
10793
10922
|
description: "Smart standard non-normative remark table image bit, used to create smart standard non-normative remark images in tables in articles or books"
|
|
10794
10923
|
},
|
|
10924
|
+
[BitType.smartStandardTableExtendedImageNormative]: {
|
|
10925
|
+
since: "1.28.0",
|
|
10926
|
+
baseBitType: BitType.standardTableExtendedImageNormative,
|
|
10927
|
+
description: "Smart standard normative extended table image bit, used to create smart standard normative extended images in tables in articles or books"
|
|
10928
|
+
},
|
|
10929
|
+
[BitType.smartStandardTableExtendedImageNonNormative]: {
|
|
10930
|
+
since: "1.28.0",
|
|
10931
|
+
baseBitType: BitType.standardTableExtendedImageNonNormative,
|
|
10932
|
+
description: "Smart standard non-normative extended table image bit, used to create smart standard non-normative extended images in tables in articles or books"
|
|
10933
|
+
},
|
|
10934
|
+
[BitType.smartStandardRemarkTableExtendedImageNormative]: {
|
|
10935
|
+
since: "1.28.0",
|
|
10936
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNormative,
|
|
10937
|
+
description: "Smart standard normative remark extended table image bit, used to create smart standard normative remark extended images in tables in articles or books"
|
|
10938
|
+
},
|
|
10939
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormative]: {
|
|
10940
|
+
since: "1.28.0",
|
|
10941
|
+
baseBitType: BitType.standardRemarkTableExtendedImageNonNormative,
|
|
10942
|
+
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"
|
|
10943
|
+
},
|
|
10795
10944
|
[BitType.smartStandardTableImageNormativeCollapsible]: {
|
|
10796
10945
|
since: "1.28.0",
|
|
10797
10946
|
baseBitType: BitType.smartStandardTableImageNormative,
|
|
@@ -10812,6 +10961,26 @@ var BITS = {
|
|
|
10812
10961
|
baseBitType: BitType.smartStandardRemarkTableImageNonNormative,
|
|
10813
10962
|
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"
|
|
10814
10963
|
},
|
|
10964
|
+
[BitType.smartStandardTableExtendedImageNormativeCollapsible]: {
|
|
10965
|
+
since: "1.28.0",
|
|
10966
|
+
baseBitType: BitType.smartStandardTableExtendedImageNormative,
|
|
10967
|
+
description: "Collapsible smart standard normative extended table image bit, used to create collapsible smart standard normative extended images in tables in articles or books"
|
|
10968
|
+
},
|
|
10969
|
+
[BitType.smartStandardTableExtendedImageNonNormativeCollapsible]: {
|
|
10970
|
+
since: "1.28.0",
|
|
10971
|
+
baseBitType: BitType.smartStandardTableExtendedImageNonNormative,
|
|
10972
|
+
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"
|
|
10973
|
+
},
|
|
10974
|
+
[BitType.smartStandardRemarkTableExtendedImageNormativeCollapsible]: {
|
|
10975
|
+
since: "1.28.0",
|
|
10976
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNormative,
|
|
10977
|
+
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"
|
|
10978
|
+
},
|
|
10979
|
+
[BitType.smartStandardRemarkTableExtendedImageNonNormativeCollapsible]: {
|
|
10980
|
+
since: "1.28.0",
|
|
10981
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedImageNonNormative,
|
|
10982
|
+
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"
|
|
10983
|
+
},
|
|
10815
10984
|
[BitType.imageLink]: {
|
|
10816
10985
|
since: "1.3.0",
|
|
10817
10986
|
baseBitType: BitType._standard,
|
|
@@ -12488,6 +12657,26 @@ var BITS = {
|
|
|
12488
12657
|
baseBitType: BitType.table,
|
|
12489
12658
|
description: "Standard non-normative remark table bit, used to create standard non-normative remark tables in articles or books"
|
|
12490
12659
|
},
|
|
12660
|
+
[BitType.standardTableExtendedNormative]: {
|
|
12661
|
+
since: "1.16.0",
|
|
12662
|
+
baseBitType: BitType.tableExtended,
|
|
12663
|
+
description: "Standard normative extended table bit, used to create standard normative extended tables in articles or books"
|
|
12664
|
+
},
|
|
12665
|
+
[BitType.standardTableExtendedNonNormative]: {
|
|
12666
|
+
since: "1.16.0",
|
|
12667
|
+
baseBitType: BitType.tableExtended,
|
|
12668
|
+
description: "Standard non-normative extended table bit, used to create standard non-normative extended tables in articles or books"
|
|
12669
|
+
},
|
|
12670
|
+
[BitType.standardRemarkTableExtendedNormative]: {
|
|
12671
|
+
since: "1.17.0",
|
|
12672
|
+
baseBitType: BitType.tableExtended,
|
|
12673
|
+
description: "Standard normative remark extended table bit, used to create standard normative remark extended tables in articles or books"
|
|
12674
|
+
},
|
|
12675
|
+
[BitType.standardRemarkTableExtendedNonNormative]: {
|
|
12676
|
+
since: "1.17.0",
|
|
12677
|
+
baseBitType: BitType.tableExtended,
|
|
12678
|
+
description: "Standard non-normative remark extended table bit, used to create standard non-normative remark extended tables in articles or books"
|
|
12679
|
+
},
|
|
12491
12680
|
[BitType.smartStandardTableNormative]: {
|
|
12492
12681
|
since: "1.28.0",
|
|
12493
12682
|
baseBitType: BitType.standardTableNormative,
|
|
@@ -12508,6 +12697,26 @@ var BITS = {
|
|
|
12508
12697
|
baseBitType: BitType.standardRemarkTableNonNormative,
|
|
12509
12698
|
description: "Smart standard non-normative remark table bit, used to create smart standard non-normative remark tables in articles or books"
|
|
12510
12699
|
},
|
|
12700
|
+
[BitType.smartStandardTableExtendedNormative]: {
|
|
12701
|
+
since: "1.28.0",
|
|
12702
|
+
baseBitType: BitType.standardTableExtendedNormative,
|
|
12703
|
+
description: "Smart standard normative extended table bit, used to create smart standard normative extended tables in articles or books"
|
|
12704
|
+
},
|
|
12705
|
+
[BitType.smartStandardTableExtendedNonNormative]: {
|
|
12706
|
+
since: "1.28.0",
|
|
12707
|
+
baseBitType: BitType.standardTableExtendedNonNormative,
|
|
12708
|
+
description: "Smart standard non-normative extended table bit, used to create smart standard non-normative extended tables in articles or books"
|
|
12709
|
+
},
|
|
12710
|
+
[BitType.smartStandardRemarkTableExtendedNormative]: {
|
|
12711
|
+
since: "1.28.0",
|
|
12712
|
+
baseBitType: BitType.standardRemarkTableExtendedNormative,
|
|
12713
|
+
description: "Smart standard normative remark extended table bit, used to create smart standard normative remark extended tables in articles or books"
|
|
12714
|
+
},
|
|
12715
|
+
[BitType.smartStandardRemarkTableExtendedNonNormative]: {
|
|
12716
|
+
since: "1.28.0",
|
|
12717
|
+
baseBitType: BitType.standardRemarkTableExtendedNonNormative,
|
|
12718
|
+
description: "Smart standard non-normative remark extended table bit, used to create smart standard non-normative remark extended tables in articles or books"
|
|
12719
|
+
},
|
|
12511
12720
|
[BitType.smartStandardTableNormativeCollapsible]: {
|
|
12512
12721
|
since: "1.28.0",
|
|
12513
12722
|
baseBitType: BitType.smartStandardTableNormative,
|
|
@@ -12528,6 +12737,26 @@ var BITS = {
|
|
|
12528
12737
|
baseBitType: BitType.smartStandardRemarkTableNonNormative,
|
|
12529
12738
|
description: "Collapsible smart standard non-normative remark table bit, used to create collapsible smart standard non-normative remark tables in articles or books"
|
|
12530
12739
|
},
|
|
12740
|
+
[BitType.smartStandardTableExtendedNormativeCollapsible]: {
|
|
12741
|
+
since: "1.28.0",
|
|
12742
|
+
baseBitType: BitType.smartStandardTableExtendedNormative,
|
|
12743
|
+
description: "Collapsible smart standard normative extended table bit, used to create collapsible smart standard normative extended tables in articles or books"
|
|
12744
|
+
},
|
|
12745
|
+
[BitType.smartStandardTableExtendedNonNormativeCollapsible]: {
|
|
12746
|
+
since: "1.28.0",
|
|
12747
|
+
baseBitType: BitType.smartStandardTableExtendedNonNormative,
|
|
12748
|
+
description: "Collapsible smart standard non-normative extended table bit, used to create collapsible smart standard non-normative extended tables in articles or books"
|
|
12749
|
+
},
|
|
12750
|
+
[BitType.smartStandardRemarkTableExtendedNormativeCollapsible]: {
|
|
12751
|
+
since: "1.28.0",
|
|
12752
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNormative,
|
|
12753
|
+
description: "Collapsible smart standard normative remark extended table bit, used to create collapsible smart standard normative remark extended tables in articles or books"
|
|
12754
|
+
},
|
|
12755
|
+
[BitType.smartStandardRemarkTableExtendedNonNormativeCollapsible]: {
|
|
12756
|
+
since: "1.28.0",
|
|
12757
|
+
baseBitType: BitType.smartStandardRemarkTableExtendedNonNormative,
|
|
12758
|
+
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"
|
|
12759
|
+
},
|
|
12531
12760
|
[BitType.parameters]: {
|
|
12532
12761
|
since: "1.18.0",
|
|
12533
12762
|
baseBitType: BitType.table,
|
|
@@ -13469,6 +13698,8 @@ var Config = class {
|
|
|
13469
13698
|
jsonKey: tag.jsonKey,
|
|
13470
13699
|
exportJsonKey: tag.exportJsonKey,
|
|
13471
13700
|
hasExportJsonKey: tag.hasExportJsonKey,
|
|
13701
|
+
htmlKey: tag.htmlKey,
|
|
13702
|
+
hasHtmlKey: tag.hasHtmlKey,
|
|
13472
13703
|
deprecated: tag.deprecated
|
|
13473
13704
|
});
|
|
13474
13705
|
finalResourceTags[k] = newTag;
|
|
@@ -13573,7 +13804,7 @@ var instance2 = new Config();
|
|
|
13573
13804
|
// src/generated/package_info.ts
|
|
13574
13805
|
var PACKAGE_INFO = {
|
|
13575
13806
|
"name": "@gmb/bitmark-parser-generator",
|
|
13576
|
-
"version": "5.
|
|
13807
|
+
"version": "5.27.0",
|
|
13577
13808
|
"license": "ISC"};
|
|
13578
13809
|
var Environment = {
|
|
13579
13810
|
unknown: "",
|
|
@@ -32692,6 +32923,233 @@ var BitmarkStringGenerator = class {
|
|
|
32692
32923
|
return this.writer.getString();
|
|
32693
32924
|
}
|
|
32694
32925
|
};
|
|
32926
|
+
|
|
32927
|
+
// src/generator/html/HtmlTableGenerator.ts
|
|
32928
|
+
var MARK_TO_TAG = {
|
|
32929
|
+
bold: "b",
|
|
32930
|
+
italic: "i",
|
|
32931
|
+
superscript: "sup",
|
|
32932
|
+
subscript: "sub",
|
|
32933
|
+
strike: "s",
|
|
32934
|
+
del: "del",
|
|
32935
|
+
ins: "ins",
|
|
32936
|
+
underline: "u",
|
|
32937
|
+
highlight: "mark",
|
|
32938
|
+
code: "code"
|
|
32939
|
+
};
|
|
32940
|
+
var HtmlTableGenerator = class {
|
|
32941
|
+
indentUnit = " ";
|
|
32942
|
+
/**
|
|
32943
|
+
* Generate HTML table fragments from a string or JSON value.
|
|
32944
|
+
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
32945
|
+
*/
|
|
32946
|
+
generate(input) {
|
|
32947
|
+
let data = input;
|
|
32948
|
+
if (typeof data === "string") {
|
|
32949
|
+
try {
|
|
32950
|
+
data = JSON.parse(data);
|
|
32951
|
+
} catch {
|
|
32952
|
+
return "";
|
|
32953
|
+
}
|
|
32954
|
+
}
|
|
32955
|
+
const bits = this.collectBits(data);
|
|
32956
|
+
const fragments = [];
|
|
32957
|
+
for (const bit of bits) {
|
|
32958
|
+
const html = this.renderTableBit(bit);
|
|
32959
|
+
if (html) fragments.push(html);
|
|
32960
|
+
}
|
|
32961
|
+
return fragments.join("\n\n");
|
|
32962
|
+
}
|
|
32963
|
+
// --- bit collection -------------------------------------------------------
|
|
32964
|
+
collectBits(data) {
|
|
32965
|
+
const out = [];
|
|
32966
|
+
const visit = (value) => {
|
|
32967
|
+
if (value == null || typeof value !== "object") return;
|
|
32968
|
+
if (Array.isArray(value)) {
|
|
32969
|
+
value.forEach(visit);
|
|
32970
|
+
return;
|
|
32971
|
+
}
|
|
32972
|
+
const obj = value;
|
|
32973
|
+
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
32974
|
+
out.push(obj.bit);
|
|
32975
|
+
} else if ("type" in obj) {
|
|
32976
|
+
out.push(obj);
|
|
32977
|
+
}
|
|
32978
|
+
};
|
|
32979
|
+
visit(data);
|
|
32980
|
+
return out;
|
|
32981
|
+
}
|
|
32982
|
+
// --- table rendering ------------------------------------------------------
|
|
32983
|
+
renderTableBit(bit) {
|
|
32984
|
+
const table = bit.table;
|
|
32985
|
+
if (!table) return "";
|
|
32986
|
+
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
32987
|
+
const extended = this.toExtended(table);
|
|
32988
|
+
const lines = [];
|
|
32989
|
+
lines.push("<table>");
|
|
32990
|
+
if (bit.caption != null) {
|
|
32991
|
+
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
32992
|
+
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
32993
|
+
}
|
|
32994
|
+
this.renderSection(lines, "thead", extended.header, "header");
|
|
32995
|
+
this.renderSection(lines, "tbody", extended.body, "body");
|
|
32996
|
+
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
32997
|
+
lines.push("</table>");
|
|
32998
|
+
return lines.join("\n");
|
|
32999
|
+
}
|
|
33000
|
+
toExtended(table) {
|
|
33001
|
+
const t = table;
|
|
33002
|
+
if (t.header || t.body || t.footer) return table;
|
|
33003
|
+
return convertBasicToExtendedTableFormat(table);
|
|
33004
|
+
}
|
|
33005
|
+
renderSection(lines, tag, section, key) {
|
|
33006
|
+
if (!section || !section.rows || section.rows.length === 0) return;
|
|
33007
|
+
lines.push(`${this.indentUnit}<${tag}>`);
|
|
33008
|
+
for (const row of section.rows) {
|
|
33009
|
+
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
33010
|
+
for (const cell of row.cells ?? []) {
|
|
33011
|
+
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
33012
|
+
}
|
|
33013
|
+
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
33014
|
+
}
|
|
33015
|
+
lines.push(`${this.indentUnit}</${tag}>`);
|
|
33016
|
+
}
|
|
33017
|
+
renderCell(cell, _key) {
|
|
33018
|
+
const tag = cell.title === true ? "th" : "td";
|
|
33019
|
+
const attrs = [];
|
|
33020
|
+
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
33021
|
+
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
33022
|
+
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
33023
|
+
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
33024
|
+
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
33025
|
+
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
33026
|
+
}
|
|
33027
|
+
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
33028
|
+
asTextAst(content) {
|
|
33029
|
+
if (content == null) return [];
|
|
33030
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
33031
|
+
return content;
|
|
33032
|
+
}
|
|
33033
|
+
cellContentToHtml(blocks) {
|
|
33034
|
+
if (blocks.length === 0) return "";
|
|
33035
|
+
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
33036
|
+
return this.inlineToHtml(blocks[0].content ?? []);
|
|
33037
|
+
}
|
|
33038
|
+
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
33039
|
+
}
|
|
33040
|
+
blockToHtml(node) {
|
|
33041
|
+
switch (node.type) {
|
|
33042
|
+
case "paragraph":
|
|
33043
|
+
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
33044
|
+
case "bulletList":
|
|
33045
|
+
case "noBulletList":
|
|
33046
|
+
case "orderedList":
|
|
33047
|
+
case "orderedListRoman":
|
|
33048
|
+
case "orderedListRomanLower":
|
|
33049
|
+
case "letteredList":
|
|
33050
|
+
case "letteredListLower":
|
|
33051
|
+
case "taskList":
|
|
33052
|
+
return this.listToHtml(node);
|
|
33053
|
+
case "image":
|
|
33054
|
+
case "imageInline":
|
|
33055
|
+
return this.imageToHtml(node);
|
|
33056
|
+
default:
|
|
33057
|
+
return this.inlineToHtml([node]);
|
|
33058
|
+
}
|
|
33059
|
+
}
|
|
33060
|
+
inlineToHtml(nodes) {
|
|
33061
|
+
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
33062
|
+
}
|
|
33063
|
+
inlineNodeToHtml(node) {
|
|
33064
|
+
if (node.type === "hardBreak") return "<br>";
|
|
33065
|
+
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
33066
|
+
if (node.type === "text") {
|
|
33067
|
+
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
33068
|
+
}
|
|
33069
|
+
if (node.content) return this.inlineToHtml(node.content);
|
|
33070
|
+
return this.escapeText(node.text ?? "");
|
|
33071
|
+
}
|
|
33072
|
+
wrapMarks(text, marks) {
|
|
33073
|
+
if (!marks || marks.length === 0) return text;
|
|
33074
|
+
let open = "";
|
|
33075
|
+
let close = "";
|
|
33076
|
+
for (const mark of marks) {
|
|
33077
|
+
if (mark.type === "link") {
|
|
33078
|
+
const href = mark.attrs?.href ?? "";
|
|
33079
|
+
open += `<a href="${this.escapeAttr(href)}">`;
|
|
33080
|
+
close = `</a>${close}`;
|
|
33081
|
+
} else {
|
|
33082
|
+
const tag = MARK_TO_TAG[mark.type];
|
|
33083
|
+
if (tag) {
|
|
33084
|
+
open += `<${tag}>`;
|
|
33085
|
+
close = `</${tag}>${close}`;
|
|
33086
|
+
}
|
|
33087
|
+
}
|
|
33088
|
+
}
|
|
33089
|
+
return `${open}${text}${close}`;
|
|
33090
|
+
}
|
|
33091
|
+
// --- lists ----------------------------------------------------------------
|
|
33092
|
+
listToHtml(node) {
|
|
33093
|
+
const { tag, attrs } = this.listTag(node);
|
|
33094
|
+
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
33095
|
+
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
33096
|
+
}
|
|
33097
|
+
listTag(node) {
|
|
33098
|
+
const start = node.attrs?.start;
|
|
33099
|
+
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
33100
|
+
switch (node.type) {
|
|
33101
|
+
case "orderedList":
|
|
33102
|
+
return { tag: "ol", attrs: startAttr };
|
|
33103
|
+
case "orderedListRoman":
|
|
33104
|
+
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
33105
|
+
case "orderedListRomanLower":
|
|
33106
|
+
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
33107
|
+
case "letteredList":
|
|
33108
|
+
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
33109
|
+
case "letteredListLower":
|
|
33110
|
+
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
33111
|
+
case "noBulletList":
|
|
33112
|
+
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
33113
|
+
case "taskList":
|
|
33114
|
+
case "bulletList":
|
|
33115
|
+
default:
|
|
33116
|
+
return { tag: "ul", attrs: "" };
|
|
33117
|
+
}
|
|
33118
|
+
}
|
|
33119
|
+
listItemToHtml(item, task) {
|
|
33120
|
+
const inner = (item.content ?? []).map((b) => {
|
|
33121
|
+
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
33122
|
+
return this.blockToHtml(b);
|
|
33123
|
+
}).join("");
|
|
33124
|
+
if (task) {
|
|
33125
|
+
const checked = item.attrs?.checked ? " checked" : "";
|
|
33126
|
+
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
33127
|
+
}
|
|
33128
|
+
return `<li>${inner}</li>`;
|
|
33129
|
+
}
|
|
33130
|
+
// --- images ---------------------------------------------------------------
|
|
33131
|
+
imageToHtml(node) {
|
|
33132
|
+
const attrs = node.attrs ?? {};
|
|
33133
|
+
const parts = [];
|
|
33134
|
+
const src = attrs.src;
|
|
33135
|
+
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
33136
|
+
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
33137
|
+
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
33138
|
+
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
33139
|
+
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
33140
|
+
if (typeof attrs.class === "string" && attrs.class) {
|
|
33141
|
+
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
33142
|
+
}
|
|
33143
|
+
return `<img ${parts.join(" ")}>`;
|
|
33144
|
+
}
|
|
33145
|
+
// --- escaping -------------------------------------------------------------
|
|
33146
|
+
escapeText(text) {
|
|
33147
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
33148
|
+
}
|
|
33149
|
+
escapeAttr(text) {
|
|
33150
|
+
return this.escapeText(text).replace(/"/g, """);
|
|
33151
|
+
}
|
|
33152
|
+
};
|
|
32695
33153
|
var MOVE_BODY_RECURSION_LIMIT = 5e3;
|
|
32696
33154
|
var DEFAULT_OPTIONS3 = {
|
|
32697
33155
|
// debugGenerationInline: true,
|
|
@@ -37538,6 +37996,8 @@ function propertyContentProcessor(context, contentDepth, tagsConfig, content, ta
|
|
|
37538
37996
|
jsonKey: void 0,
|
|
37539
37997
|
exportJsonKey: void 0,
|
|
37540
37998
|
hasExportJsonKey: false,
|
|
37999
|
+
htmlKey: void 0,
|
|
38000
|
+
hasHtmlKey: false,
|
|
37541
38001
|
format: TagFormat.bitmarkText,
|
|
37542
38002
|
values: void 0,
|
|
37543
38003
|
defaultValue: void 0,
|
|
@@ -41892,6 +42352,497 @@ var BitmarkParser = class {
|
|
|
41892
42352
|
return parse2(bitmark);
|
|
41893
42353
|
}
|
|
41894
42354
|
};
|
|
42355
|
+
|
|
42356
|
+
// src/parser/html/HtmlDom.ts
|
|
42357
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
42358
|
+
"area",
|
|
42359
|
+
"base",
|
|
42360
|
+
"br",
|
|
42361
|
+
"col",
|
|
42362
|
+
"embed",
|
|
42363
|
+
"hr",
|
|
42364
|
+
"img",
|
|
42365
|
+
"input",
|
|
42366
|
+
"link",
|
|
42367
|
+
"meta",
|
|
42368
|
+
"param",
|
|
42369
|
+
"source",
|
|
42370
|
+
"track",
|
|
42371
|
+
"wbr"
|
|
42372
|
+
]);
|
|
42373
|
+
var IMPLIED_CLOSE = {
|
|
42374
|
+
li: /* @__PURE__ */ new Set(["li"]),
|
|
42375
|
+
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42376
|
+
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
42377
|
+
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
42378
|
+
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42379
|
+
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42380
|
+
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
42381
|
+
p: /* @__PURE__ */ new Set(["p"]),
|
|
42382
|
+
option: /* @__PURE__ */ new Set(["option"])
|
|
42383
|
+
};
|
|
42384
|
+
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
42385
|
+
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
42386
|
+
function parseAttrs(raw) {
|
|
42387
|
+
const attrs = {};
|
|
42388
|
+
if (!raw) return attrs;
|
|
42389
|
+
ATTR_RE.lastIndex = 0;
|
|
42390
|
+
let m;
|
|
42391
|
+
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
42392
|
+
const name = m[1].toLowerCase();
|
|
42393
|
+
let value = m[2] ?? "";
|
|
42394
|
+
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
42395
|
+
value = value.slice(1, -1);
|
|
42396
|
+
}
|
|
42397
|
+
attrs[name] = value;
|
|
42398
|
+
}
|
|
42399
|
+
return attrs;
|
|
42400
|
+
}
|
|
42401
|
+
function stripNonContent(html) {
|
|
42402
|
+
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, "");
|
|
42403
|
+
}
|
|
42404
|
+
function tokenize(html) {
|
|
42405
|
+
const tokens = [];
|
|
42406
|
+
const clean = stripNonContent(html);
|
|
42407
|
+
TAG_RE.lastIndex = 0;
|
|
42408
|
+
let lastIndex = 0;
|
|
42409
|
+
let m;
|
|
42410
|
+
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
42411
|
+
if (m.index > lastIndex) {
|
|
42412
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
42413
|
+
}
|
|
42414
|
+
lastIndex = TAG_RE.lastIndex;
|
|
42415
|
+
const isClose = m[1] === "/";
|
|
42416
|
+
const name = m[2].toLowerCase();
|
|
42417
|
+
if (isClose) {
|
|
42418
|
+
tokens.push({ kind: "close", name });
|
|
42419
|
+
} else {
|
|
42420
|
+
tokens.push({
|
|
42421
|
+
kind: "open",
|
|
42422
|
+
name,
|
|
42423
|
+
attrs: parseAttrs(m[3]),
|
|
42424
|
+
selfClose: m[4] === "/"
|
|
42425
|
+
});
|
|
42426
|
+
}
|
|
42427
|
+
}
|
|
42428
|
+
if (lastIndex < clean.length) {
|
|
42429
|
+
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
42430
|
+
}
|
|
42431
|
+
return tokens;
|
|
42432
|
+
}
|
|
42433
|
+
function parseHtml(html) {
|
|
42434
|
+
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
42435
|
+
const stack = [root];
|
|
42436
|
+
const top = () => stack[stack.length - 1];
|
|
42437
|
+
for (const token of tokenize(html)) {
|
|
42438
|
+
if (token.kind === "text") {
|
|
42439
|
+
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
42440
|
+
continue;
|
|
42441
|
+
}
|
|
42442
|
+
if (token.kind === "open") {
|
|
42443
|
+
const name = token.name;
|
|
42444
|
+
const closes = IMPLIED_CLOSE[name];
|
|
42445
|
+
if (closes) {
|
|
42446
|
+
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
42447
|
+
}
|
|
42448
|
+
const el = {
|
|
42449
|
+
type: "element",
|
|
42450
|
+
name,
|
|
42451
|
+
attrs: token.attrs ?? {},
|
|
42452
|
+
children: []
|
|
42453
|
+
};
|
|
42454
|
+
top().children.push(el);
|
|
42455
|
+
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
42456
|
+
stack.push(el);
|
|
42457
|
+
}
|
|
42458
|
+
continue;
|
|
42459
|
+
}
|
|
42460
|
+
for (let i = stack.length - 1; i > 0; i--) {
|
|
42461
|
+
if (stack[i].name === token.name) {
|
|
42462
|
+
stack.length = i;
|
|
42463
|
+
break;
|
|
42464
|
+
}
|
|
42465
|
+
}
|
|
42466
|
+
}
|
|
42467
|
+
return root.children;
|
|
42468
|
+
}
|
|
42469
|
+
function childElements(el, names) {
|
|
42470
|
+
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
42471
|
+
}
|
|
42472
|
+
|
|
42473
|
+
// src/parser/html/HtmlTableParser.ts
|
|
42474
|
+
var MARK_TAGS = {
|
|
42475
|
+
b: "bold",
|
|
42476
|
+
strong: "bold",
|
|
42477
|
+
i: "italic",
|
|
42478
|
+
em: "italic",
|
|
42479
|
+
sup: "superscript",
|
|
42480
|
+
sub: "subscript",
|
|
42481
|
+
s: "strike",
|
|
42482
|
+
strike: "strike",
|
|
42483
|
+
del: "del",
|
|
42484
|
+
ins: "ins",
|
|
42485
|
+
u: "underline",
|
|
42486
|
+
mark: "highlight",
|
|
42487
|
+
code: "code"
|
|
42488
|
+
};
|
|
42489
|
+
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
42490
|
+
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
42491
|
+
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
42492
|
+
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
42493
|
+
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
42494
|
+
var NAMED_ENTITIES = {
|
|
42495
|
+
amp: "&",
|
|
42496
|
+
lt: "<",
|
|
42497
|
+
gt: ">",
|
|
42498
|
+
quot: '"',
|
|
42499
|
+
apos: "'",
|
|
42500
|
+
nbsp: "\xA0"
|
|
42501
|
+
};
|
|
42502
|
+
function decodeEntities(text) {
|
|
42503
|
+
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
42504
|
+
if (body[0] === "#") {
|
|
42505
|
+
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
42506
|
+
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
42507
|
+
try {
|
|
42508
|
+
return String.fromCodePoint(code);
|
|
42509
|
+
} catch {
|
|
42510
|
+
return whole;
|
|
42511
|
+
}
|
|
42512
|
+
}
|
|
42513
|
+
return whole;
|
|
42514
|
+
}
|
|
42515
|
+
return NAMED_ENTITIES[body] ?? whole;
|
|
42516
|
+
});
|
|
42517
|
+
}
|
|
42518
|
+
function intAttr(value) {
|
|
42519
|
+
if (value == null) return void 0;
|
|
42520
|
+
const n = Number.parseInt(value, 10);
|
|
42521
|
+
return Number.isInteger(n) ? n : void 0;
|
|
42522
|
+
}
|
|
42523
|
+
function isElement(node) {
|
|
42524
|
+
return node.type === "element";
|
|
42525
|
+
}
|
|
42526
|
+
var HtmlTableParser = class {
|
|
42527
|
+
keepUnknownTags = false;
|
|
42528
|
+
/**
|
|
42529
|
+
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
42530
|
+
*/
|
|
42531
|
+
parse(html, options) {
|
|
42532
|
+
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
42533
|
+
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
42534
|
+
const onWarning = options?.onWarning;
|
|
42535
|
+
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
42536
|
+
const bits = [];
|
|
42537
|
+
for (const table of tables) {
|
|
42538
|
+
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
42539
|
+
if (bit) bits.push(bit);
|
|
42540
|
+
}
|
|
42541
|
+
return bits;
|
|
42542
|
+
}
|
|
42543
|
+
// --- table extraction -----------------------------------------------------
|
|
42544
|
+
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
42545
|
+
collectTopLevelTables(nodes) {
|
|
42546
|
+
const tables = [];
|
|
42547
|
+
const visit = (node) => {
|
|
42548
|
+
if (!isElement(node)) return;
|
|
42549
|
+
if (node.name === "table") {
|
|
42550
|
+
tables.push(node);
|
|
42551
|
+
return;
|
|
42552
|
+
}
|
|
42553
|
+
node.children.forEach(visit);
|
|
42554
|
+
};
|
|
42555
|
+
nodes.forEach(visit);
|
|
42556
|
+
return tables;
|
|
42557
|
+
}
|
|
42558
|
+
tableToBit(table, tableFormat, onWarning) {
|
|
42559
|
+
const header = [];
|
|
42560
|
+
const body = [];
|
|
42561
|
+
const footer = [];
|
|
42562
|
+
let caption;
|
|
42563
|
+
for (const child of table.children) {
|
|
42564
|
+
if (!isElement(child)) continue;
|
|
42565
|
+
if (child.name === "caption") {
|
|
42566
|
+
const capContent = this.inlineNodes(child.children, []);
|
|
42567
|
+
const trimmed = this.trimInline(capContent);
|
|
42568
|
+
if (trimmed.length > 0) caption = trimmed;
|
|
42569
|
+
} else if (SECTION_TAGS.has(child.name)) {
|
|
42570
|
+
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
42571
|
+
for (const tr of childElements(child, ROW_TAGS)) {
|
|
42572
|
+
target.push(this.rowToCells(tr));
|
|
42573
|
+
}
|
|
42574
|
+
} else if (ROW_TAGS.has(child.name)) {
|
|
42575
|
+
body.push(this.rowToCells(child));
|
|
42576
|
+
}
|
|
42577
|
+
}
|
|
42578
|
+
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
42579
|
+
return void 0;
|
|
42580
|
+
}
|
|
42581
|
+
const tableExtended = {};
|
|
42582
|
+
if (header.length > 0) tableExtended.header = { rows: header };
|
|
42583
|
+
if (body.length > 0) tableExtended.body = { rows: body };
|
|
42584
|
+
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
42585
|
+
let tableData = tableExtended;
|
|
42586
|
+
if (tableFormat === "table") {
|
|
42587
|
+
if (this.isLossyAsBasic(tableExtended)) {
|
|
42588
|
+
onWarning?.(
|
|
42589
|
+
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
42590
|
+
);
|
|
42591
|
+
}
|
|
42592
|
+
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
42593
|
+
}
|
|
42594
|
+
const bit = {
|
|
42595
|
+
type: tableFormat,
|
|
42596
|
+
format: "bitmark++",
|
|
42597
|
+
table: tableData
|
|
42598
|
+
};
|
|
42599
|
+
if (caption) bit.caption = caption;
|
|
42600
|
+
return bit;
|
|
42601
|
+
}
|
|
42602
|
+
rowToCells(tr) {
|
|
42603
|
+
const cells = [];
|
|
42604
|
+
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
42605
|
+
cells.push(this.cellToJson(cell));
|
|
42606
|
+
}
|
|
42607
|
+
return { cells };
|
|
42608
|
+
}
|
|
42609
|
+
cellToJson(cell) {
|
|
42610
|
+
const json = {
|
|
42611
|
+
content: this.blockNodes(cell.children)
|
|
42612
|
+
};
|
|
42613
|
+
if (cell.name === "th") json.title = true;
|
|
42614
|
+
const rowspan = intAttr(cell.attrs.rowspan);
|
|
42615
|
+
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
42616
|
+
const colspan = intAttr(cell.attrs.colspan);
|
|
42617
|
+
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
42618
|
+
const scope = cell.attrs.scope?.toLowerCase();
|
|
42619
|
+
if (scope && VALID_SCOPES.has(scope)) {
|
|
42620
|
+
json.scope = scope;
|
|
42621
|
+
}
|
|
42622
|
+
const width = this.widthFromCell(cell);
|
|
42623
|
+
if (width != null) json.colwidth = width;
|
|
42624
|
+
return json;
|
|
42625
|
+
}
|
|
42626
|
+
widthFromCell(cell) {
|
|
42627
|
+
const attrWidth = intAttr(cell.attrs.width);
|
|
42628
|
+
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
42629
|
+
const style = cell.attrs.style;
|
|
42630
|
+
if (style) {
|
|
42631
|
+
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
42632
|
+
if (m) {
|
|
42633
|
+
const n = Number.parseInt(m[1], 10);
|
|
42634
|
+
if (Number.isInteger(n) && n > 0) return n;
|
|
42635
|
+
}
|
|
42636
|
+
}
|
|
42637
|
+
return void 0;
|
|
42638
|
+
}
|
|
42639
|
+
isLossyAsBasic(table) {
|
|
42640
|
+
if (table.footer) return true;
|
|
42641
|
+
if (table.header && table.header.rows.length > 1) return true;
|
|
42642
|
+
const sections = [table.header, table.body, table.footer];
|
|
42643
|
+
for (const section of sections) {
|
|
42644
|
+
if (!section) continue;
|
|
42645
|
+
for (const row of section.rows) {
|
|
42646
|
+
for (const cell of row.cells) {
|
|
42647
|
+
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
42648
|
+
}
|
|
42649
|
+
}
|
|
42650
|
+
}
|
|
42651
|
+
return false;
|
|
42652
|
+
}
|
|
42653
|
+
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
42654
|
+
/**
|
|
42655
|
+
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
42656
|
+
*/
|
|
42657
|
+
blockNodes(nodes) {
|
|
42658
|
+
const blocks = [];
|
|
42659
|
+
let inline = [];
|
|
42660
|
+
const flush = () => {
|
|
42661
|
+
const trimmed = this.trimInline(inline);
|
|
42662
|
+
inline = [];
|
|
42663
|
+
if (trimmed.length === 0) return;
|
|
42664
|
+
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
42665
|
+
blocks.push({ ...trimmed[0], type: "image" });
|
|
42666
|
+
} else {
|
|
42667
|
+
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
42668
|
+
}
|
|
42669
|
+
};
|
|
42670
|
+
for (const node of nodes) {
|
|
42671
|
+
if (!isElement(node)) {
|
|
42672
|
+
inline.push(...this.inlineText(node.value, []));
|
|
42673
|
+
continue;
|
|
42674
|
+
}
|
|
42675
|
+
const name = node.name;
|
|
42676
|
+
if (name === "p") {
|
|
42677
|
+
flush();
|
|
42678
|
+
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
42679
|
+
if (content.length > 0) {
|
|
42680
|
+
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
42681
|
+
}
|
|
42682
|
+
} else if (this.isListTag(name)) {
|
|
42683
|
+
flush();
|
|
42684
|
+
const list = this.listNode(node);
|
|
42685
|
+
if (list) blocks.push(list);
|
|
42686
|
+
} else {
|
|
42687
|
+
inline.push(...this.inlineFromElement(node, []));
|
|
42688
|
+
}
|
|
42689
|
+
}
|
|
42690
|
+
flush();
|
|
42691
|
+
return blocks;
|
|
42692
|
+
}
|
|
42693
|
+
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
42694
|
+
inlineNodes(nodes, marks) {
|
|
42695
|
+
const out = [];
|
|
42696
|
+
for (const node of nodes) {
|
|
42697
|
+
if (!isElement(node)) {
|
|
42698
|
+
out.push(...this.inlineText(node.value, marks));
|
|
42699
|
+
} else {
|
|
42700
|
+
out.push(...this.inlineFromElement(node, marks));
|
|
42701
|
+
}
|
|
42702
|
+
}
|
|
42703
|
+
return out;
|
|
42704
|
+
}
|
|
42705
|
+
inlineFromElement(el, marks) {
|
|
42706
|
+
const name = el.name;
|
|
42707
|
+
if (name === "br") {
|
|
42708
|
+
return [{ type: "hardBreak" }];
|
|
42709
|
+
}
|
|
42710
|
+
if (name === "img") {
|
|
42711
|
+
return [this.imageNode(el, true)];
|
|
42712
|
+
}
|
|
42713
|
+
const markType = MARK_TAGS[name];
|
|
42714
|
+
if (markType) {
|
|
42715
|
+
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
42716
|
+
}
|
|
42717
|
+
if (name === "a") {
|
|
42718
|
+
const linkMark = {
|
|
42719
|
+
type: "link",
|
|
42720
|
+
attrs: {
|
|
42721
|
+
href: el.attrs.href ?? "",
|
|
42722
|
+
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
42723
|
+
}
|
|
42724
|
+
};
|
|
42725
|
+
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
42726
|
+
}
|
|
42727
|
+
if (this.keepUnknownTags) {
|
|
42728
|
+
const open = this.serializeOpenTag(el);
|
|
42729
|
+
const close = `</${name}>`;
|
|
42730
|
+
return [
|
|
42731
|
+
...this.inlineText(open, marks),
|
|
42732
|
+
...this.inlineNodes(el.children, marks),
|
|
42733
|
+
...this.inlineText(close, marks)
|
|
42734
|
+
];
|
|
42735
|
+
}
|
|
42736
|
+
return this.inlineNodes(el.children, marks);
|
|
42737
|
+
}
|
|
42738
|
+
inlineText(raw, marks) {
|
|
42739
|
+
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
42740
|
+
if (text === "") return [];
|
|
42741
|
+
const node = { text, type: "text" };
|
|
42742
|
+
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
42743
|
+
return [node];
|
|
42744
|
+
}
|
|
42745
|
+
serializeOpenTag(el) {
|
|
42746
|
+
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
42747
|
+
return `<${el.name}${attrs}>`;
|
|
42748
|
+
}
|
|
42749
|
+
// --- lists ----------------------------------------------------------------
|
|
42750
|
+
isListTag(name) {
|
|
42751
|
+
return name === "ul" || name === "ol";
|
|
42752
|
+
}
|
|
42753
|
+
listNode(el) {
|
|
42754
|
+
const items = childElements(el, LI_TAGS);
|
|
42755
|
+
if (items.length === 0) return void 0;
|
|
42756
|
+
const isTask = el.name === "ul" && items.some((li) => {
|
|
42757
|
+
const firstEl = li.children.find(isElement);
|
|
42758
|
+
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
42759
|
+
});
|
|
42760
|
+
if (isTask) {
|
|
42761
|
+
return {
|
|
42762
|
+
type: "taskList",
|
|
42763
|
+
content: items.map((li) => this.taskItemNode(li))
|
|
42764
|
+
};
|
|
42765
|
+
}
|
|
42766
|
+
const type = this.listType(el);
|
|
42767
|
+
const node = {
|
|
42768
|
+
type,
|
|
42769
|
+
content: items.map((li) => this.listItemNode(li))
|
|
42770
|
+
};
|
|
42771
|
+
if (el.name === "ol") {
|
|
42772
|
+
const start = intAttr(el.attrs.start);
|
|
42773
|
+
if (start != null) {
|
|
42774
|
+
node.attrs = { start };
|
|
42775
|
+
}
|
|
42776
|
+
}
|
|
42777
|
+
return node;
|
|
42778
|
+
}
|
|
42779
|
+
listType(el) {
|
|
42780
|
+
if (el.name === "ol") {
|
|
42781
|
+
switch (el.attrs.type) {
|
|
42782
|
+
case "i":
|
|
42783
|
+
return "orderedListRomanLower";
|
|
42784
|
+
case "I":
|
|
42785
|
+
return "orderedListRoman";
|
|
42786
|
+
case "a":
|
|
42787
|
+
return "letteredListLower";
|
|
42788
|
+
case "A":
|
|
42789
|
+
return "letteredList";
|
|
42790
|
+
default:
|
|
42791
|
+
return "orderedList";
|
|
42792
|
+
}
|
|
42793
|
+
}
|
|
42794
|
+
const style = el.attrs.style ?? "";
|
|
42795
|
+
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
42796
|
+
return "bulletList";
|
|
42797
|
+
}
|
|
42798
|
+
listItemNode(li) {
|
|
42799
|
+
let content = this.blockNodes(li.children);
|
|
42800
|
+
if (content.length === 0) {
|
|
42801
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
42802
|
+
}
|
|
42803
|
+
return { type: "listItem", content };
|
|
42804
|
+
}
|
|
42805
|
+
taskItemNode(li) {
|
|
42806
|
+
const checkbox = li.children.find(
|
|
42807
|
+
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
42808
|
+
);
|
|
42809
|
+
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
42810
|
+
const rest = li.children.filter((c) => c !== checkbox);
|
|
42811
|
+
let content = this.blockNodes(rest);
|
|
42812
|
+
if (content.length === 0) {
|
|
42813
|
+
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
42814
|
+
}
|
|
42815
|
+
return { type: "taskItem", attrs: { checked }, content };
|
|
42816
|
+
}
|
|
42817
|
+
// --- images ---------------------------------------------------------------
|
|
42818
|
+
imageNode(el, inline) {
|
|
42819
|
+
const attrs = { src: el.attrs.src ?? "" };
|
|
42820
|
+
attrs.alt = el.attrs.alt ?? null;
|
|
42821
|
+
attrs.title = el.attrs.title ?? null;
|
|
42822
|
+
const width = intAttr(el.attrs.width);
|
|
42823
|
+
if (width != null) attrs.width = width;
|
|
42824
|
+
const height = intAttr(el.attrs.height);
|
|
42825
|
+
if (height != null) attrs.height = height;
|
|
42826
|
+
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
42827
|
+
return { type: inline ? "imageInline" : "image", attrs };
|
|
42828
|
+
}
|
|
42829
|
+
// --- whitespace -----------------------------------------------------------
|
|
42830
|
+
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
42831
|
+
trimInline(nodes) {
|
|
42832
|
+
const out = nodes.slice();
|
|
42833
|
+
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
42834
|
+
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
42835
|
+
if (out.length > 0 && out[0].type === "text") {
|
|
42836
|
+
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
42837
|
+
}
|
|
42838
|
+
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
42839
|
+
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
42840
|
+
const last = out.length - 1;
|
|
42841
|
+
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
42842
|
+
}
|
|
42843
|
+
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
42844
|
+
}
|
|
42845
|
+
};
|
|
41895
42846
|
var StreamWriter = class {
|
|
41896
42847
|
_stream;
|
|
41897
42848
|
endOfLineString = os.EOL;
|
|
@@ -42145,248 +43096,21 @@ var BitmarkFileGenerator = class {
|
|
|
42145
43096
|
/**
|
|
42146
43097
|
* Generate bitmark markup from bitmark AST as a file
|
|
42147
43098
|
*
|
|
42148
|
-
* @param ast bitmark AST
|
|
42149
|
-
*/
|
|
42150
|
-
async generate(ast) {
|
|
42151
|
-
return this.generator.generate(ast);
|
|
42152
|
-
}
|
|
42153
|
-
/**
|
|
42154
|
-
* Generate bitmark markup from bitmark AST as a file synchronously
|
|
42155
|
-
*
|
|
42156
|
-
* @param ast bitmark AST
|
|
42157
|
-
*/
|
|
42158
|
-
generateSync(_ast) {
|
|
42159
|
-
if (this.async) {
|
|
42160
|
-
throw new Error("Sync operation not supported");
|
|
42161
|
-
}
|
|
42162
|
-
this.generator.generateSync(_ast);
|
|
42163
|
-
}
|
|
42164
|
-
};
|
|
42165
|
-
|
|
42166
|
-
// src/generator/html/HtmlTableGenerator.ts
|
|
42167
|
-
var MARK_TO_TAG = {
|
|
42168
|
-
bold: "b",
|
|
42169
|
-
italic: "i",
|
|
42170
|
-
superscript: "sup",
|
|
42171
|
-
subscript: "sub",
|
|
42172
|
-
strike: "s",
|
|
42173
|
-
del: "del",
|
|
42174
|
-
ins: "ins",
|
|
42175
|
-
underline: "u",
|
|
42176
|
-
highlight: "mark",
|
|
42177
|
-
code: "code"
|
|
42178
|
-
};
|
|
42179
|
-
var HtmlTableGenerator = class {
|
|
42180
|
-
indentUnit = " ";
|
|
42181
|
-
/**
|
|
42182
|
-
* Generate HTML table fragments from a string or JSON value.
|
|
42183
|
-
* @returns the concatenated `<table>` fragments, blank-line separated (empty string if none).
|
|
42184
|
-
*/
|
|
42185
|
-
generate(input) {
|
|
42186
|
-
let data = input;
|
|
42187
|
-
if (typeof data === "string") {
|
|
42188
|
-
try {
|
|
42189
|
-
data = JSON.parse(data);
|
|
42190
|
-
} catch {
|
|
42191
|
-
return "";
|
|
42192
|
-
}
|
|
42193
|
-
}
|
|
42194
|
-
const bits = this.collectBits(data);
|
|
42195
|
-
const fragments = [];
|
|
42196
|
-
for (const bit of bits) {
|
|
42197
|
-
const html = this.renderTableBit(bit);
|
|
42198
|
-
if (html) fragments.push(html);
|
|
42199
|
-
}
|
|
42200
|
-
return fragments.join("\n\n");
|
|
42201
|
-
}
|
|
42202
|
-
// --- bit collection -------------------------------------------------------
|
|
42203
|
-
collectBits(data) {
|
|
42204
|
-
const out = [];
|
|
42205
|
-
const visit = (value) => {
|
|
42206
|
-
if (value == null || typeof value !== "object") return;
|
|
42207
|
-
if (Array.isArray(value)) {
|
|
42208
|
-
value.forEach(visit);
|
|
42209
|
-
return;
|
|
42210
|
-
}
|
|
42211
|
-
const obj = value;
|
|
42212
|
-
if ("bit" in obj && obj.bit && typeof obj.bit === "object") {
|
|
42213
|
-
out.push(obj.bit);
|
|
42214
|
-
} else if ("type" in obj) {
|
|
42215
|
-
out.push(obj);
|
|
42216
|
-
}
|
|
42217
|
-
};
|
|
42218
|
-
visit(data);
|
|
42219
|
-
return out;
|
|
42220
|
-
}
|
|
42221
|
-
// --- table rendering ------------------------------------------------------
|
|
42222
|
-
renderTableBit(bit) {
|
|
42223
|
-
const table = bit.table;
|
|
42224
|
-
if (!table) return "";
|
|
42225
|
-
if (bit.type !== "table" && bit.type !== "table-extended") return "";
|
|
42226
|
-
const extended = this.toExtended(table);
|
|
42227
|
-
const lines = [];
|
|
42228
|
-
lines.push("<table>");
|
|
42229
|
-
if (bit.caption != null) {
|
|
42230
|
-
const caption = this.cellContentToHtml(this.asTextAst(bit.caption));
|
|
42231
|
-
if (caption) lines.push(`${this.indentUnit}<caption>${caption}</caption>`);
|
|
42232
|
-
}
|
|
42233
|
-
this.renderSection(lines, "thead", extended.header, "header");
|
|
42234
|
-
this.renderSection(lines, "tbody", extended.body, "body");
|
|
42235
|
-
this.renderSection(lines, "tfoot", extended.footer, "footer");
|
|
42236
|
-
lines.push("</table>");
|
|
42237
|
-
return lines.join("\n");
|
|
42238
|
-
}
|
|
42239
|
-
toExtended(table) {
|
|
42240
|
-
const t = table;
|
|
42241
|
-
if (t.header || t.body || t.footer) return table;
|
|
42242
|
-
return convertBasicToExtendedTableFormat(table);
|
|
42243
|
-
}
|
|
42244
|
-
renderSection(lines, tag, section, key) {
|
|
42245
|
-
if (!section || !section.rows || section.rows.length === 0) return;
|
|
42246
|
-
lines.push(`${this.indentUnit}<${tag}>`);
|
|
42247
|
-
for (const row of section.rows) {
|
|
42248
|
-
lines.push(`${this.indentUnit.repeat(2)}<tr>`);
|
|
42249
|
-
for (const cell of row.cells ?? []) {
|
|
42250
|
-
lines.push(`${this.indentUnit.repeat(3)}${this.renderCell(cell, key)}`);
|
|
42251
|
-
}
|
|
42252
|
-
lines.push(`${this.indentUnit.repeat(2)}</tr>`);
|
|
42253
|
-
}
|
|
42254
|
-
lines.push(`${this.indentUnit}</${tag}>`);
|
|
42255
|
-
}
|
|
42256
|
-
renderCell(cell, _key) {
|
|
42257
|
-
const tag = cell.title === true ? "th" : "td";
|
|
42258
|
-
const attrs = [];
|
|
42259
|
-
if (cell.rowspan && cell.rowspan > 1) attrs.push(`rowspan="${cell.rowspan}"`);
|
|
42260
|
-
if (cell.colspan && cell.colspan > 1) attrs.push(`colspan="${cell.colspan}"`);
|
|
42261
|
-
if (cell.scope) attrs.push(`scope="${cell.scope}"`);
|
|
42262
|
-
if (cell.colwidth && cell.colwidth > 0) attrs.push(`width="${cell.colwidth}"`);
|
|
42263
|
-
const open = attrs.length > 0 ? `<${tag} ${attrs.join(" ")}>` : `<${tag}>`;
|
|
42264
|
-
return `${open}${this.cellContentToHtml(this.asTextAst(cell.content))}</${tag}>`;
|
|
42265
|
-
}
|
|
42266
|
-
// --- cell content (TextAst -> HTML) ---------------------------------------
|
|
42267
|
-
asTextAst(content) {
|
|
42268
|
-
if (content == null) return [];
|
|
42269
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
42270
|
-
return content;
|
|
42271
|
-
}
|
|
42272
|
-
cellContentToHtml(blocks) {
|
|
42273
|
-
if (blocks.length === 0) return "";
|
|
42274
|
-
if (blocks.length === 1 && blocks[0].type === "paragraph") {
|
|
42275
|
-
return this.inlineToHtml(blocks[0].content ?? []);
|
|
42276
|
-
}
|
|
42277
|
-
return blocks.map((b) => this.blockToHtml(b)).join("");
|
|
42278
|
-
}
|
|
42279
|
-
blockToHtml(node) {
|
|
42280
|
-
switch (node.type) {
|
|
42281
|
-
case "paragraph":
|
|
42282
|
-
return `<p>${this.inlineToHtml(node.content ?? [])}</p>`;
|
|
42283
|
-
case "bulletList":
|
|
42284
|
-
case "noBulletList":
|
|
42285
|
-
case "orderedList":
|
|
42286
|
-
case "orderedListRoman":
|
|
42287
|
-
case "orderedListRomanLower":
|
|
42288
|
-
case "letteredList":
|
|
42289
|
-
case "letteredListLower":
|
|
42290
|
-
case "taskList":
|
|
42291
|
-
return this.listToHtml(node);
|
|
42292
|
-
case "image":
|
|
42293
|
-
case "imageInline":
|
|
42294
|
-
return this.imageToHtml(node);
|
|
42295
|
-
default:
|
|
42296
|
-
return this.inlineToHtml([node]);
|
|
42297
|
-
}
|
|
42298
|
-
}
|
|
42299
|
-
inlineToHtml(nodes) {
|
|
42300
|
-
return nodes.map((n) => this.inlineNodeToHtml(n)).join("");
|
|
42301
|
-
}
|
|
42302
|
-
inlineNodeToHtml(node) {
|
|
42303
|
-
if (node.type === "hardBreak") return "<br>";
|
|
42304
|
-
if (node.type === "image" || node.type === "imageInline") return this.imageToHtml(node);
|
|
42305
|
-
if (node.type === "text") {
|
|
42306
|
-
return this.wrapMarks(this.escapeText(node.text ?? ""), node.marks);
|
|
42307
|
-
}
|
|
42308
|
-
if (node.content) return this.inlineToHtml(node.content);
|
|
42309
|
-
return this.escapeText(node.text ?? "");
|
|
42310
|
-
}
|
|
42311
|
-
wrapMarks(text, marks) {
|
|
42312
|
-
if (!marks || marks.length === 0) return text;
|
|
42313
|
-
let open = "";
|
|
42314
|
-
let close = "";
|
|
42315
|
-
for (const mark of marks) {
|
|
42316
|
-
if (mark.type === "link") {
|
|
42317
|
-
const href = mark.attrs?.href ?? "";
|
|
42318
|
-
open += `<a href="${this.escapeAttr(href)}">`;
|
|
42319
|
-
close = `</a>${close}`;
|
|
42320
|
-
} else {
|
|
42321
|
-
const tag = MARK_TO_TAG[mark.type];
|
|
42322
|
-
if (tag) {
|
|
42323
|
-
open += `<${tag}>`;
|
|
42324
|
-
close = `</${tag}>${close}`;
|
|
42325
|
-
}
|
|
42326
|
-
}
|
|
42327
|
-
}
|
|
42328
|
-
return `${open}${text}${close}`;
|
|
42329
|
-
}
|
|
42330
|
-
// --- lists ----------------------------------------------------------------
|
|
42331
|
-
listToHtml(node) {
|
|
42332
|
-
const { tag, attrs } = this.listTag(node);
|
|
42333
|
-
const items = (node.content ?? []).map((item) => this.listItemToHtml(item, node.type === "taskList")).join("");
|
|
42334
|
-
return `<${tag}${attrs}>${items}</${tag}>`;
|
|
42335
|
-
}
|
|
42336
|
-
listTag(node) {
|
|
42337
|
-
const start = node.attrs?.start;
|
|
42338
|
-
const startAttr = typeof start === "number" && start !== 1 ? ` start="${start}"` : "";
|
|
42339
|
-
switch (node.type) {
|
|
42340
|
-
case "orderedList":
|
|
42341
|
-
return { tag: "ol", attrs: startAttr };
|
|
42342
|
-
case "orderedListRoman":
|
|
42343
|
-
return { tag: "ol", attrs: ` type="I"${startAttr}` };
|
|
42344
|
-
case "orderedListRomanLower":
|
|
42345
|
-
return { tag: "ol", attrs: ` type="i"${startAttr}` };
|
|
42346
|
-
case "letteredList":
|
|
42347
|
-
return { tag: "ol", attrs: ` type="A"${startAttr}` };
|
|
42348
|
-
case "letteredListLower":
|
|
42349
|
-
return { tag: "ol", attrs: ` type="a"${startAttr}` };
|
|
42350
|
-
case "noBulletList":
|
|
42351
|
-
return { tag: "ul", attrs: ' style="list-style:none"' };
|
|
42352
|
-
case "taskList":
|
|
42353
|
-
case "bulletList":
|
|
42354
|
-
default:
|
|
42355
|
-
return { tag: "ul", attrs: "" };
|
|
42356
|
-
}
|
|
42357
|
-
}
|
|
42358
|
-
listItemToHtml(item, task) {
|
|
42359
|
-
const inner = (item.content ?? []).map((b) => {
|
|
42360
|
-
if (b.type === "paragraph") return this.inlineToHtml(b.content ?? []);
|
|
42361
|
-
return this.blockToHtml(b);
|
|
42362
|
-
}).join("");
|
|
42363
|
-
if (task) {
|
|
42364
|
-
const checked = item.attrs?.checked ? " checked" : "";
|
|
42365
|
-
return `<li><input type="checkbox"${checked}>${inner}</li>`;
|
|
42366
|
-
}
|
|
42367
|
-
return `<li>${inner}</li>`;
|
|
42368
|
-
}
|
|
42369
|
-
// --- images ---------------------------------------------------------------
|
|
42370
|
-
imageToHtml(node) {
|
|
42371
|
-
const attrs = node.attrs ?? {};
|
|
42372
|
-
const parts = [];
|
|
42373
|
-
const src = attrs.src;
|
|
42374
|
-
parts.push(`src="${this.escapeAttr(typeof src === "string" ? src : "")}"`);
|
|
42375
|
-
if (typeof attrs.alt === "string") parts.push(`alt="${this.escapeAttr(attrs.alt)}"`);
|
|
42376
|
-
if (typeof attrs.title === "string") parts.push(`title="${this.escapeAttr(attrs.title)}"`);
|
|
42377
|
-
if (attrs.width != null) parts.push(`width="${attrs.width}"`);
|
|
42378
|
-
if (attrs.height != null) parts.push(`height="${attrs.height}"`);
|
|
42379
|
-
if (typeof attrs.class === "string" && attrs.class) {
|
|
42380
|
-
parts.push(`class="${this.escapeAttr(attrs.class)}"`);
|
|
42381
|
-
}
|
|
42382
|
-
return `<img ${parts.join(" ")}>`;
|
|
42383
|
-
}
|
|
42384
|
-
// --- escaping -------------------------------------------------------------
|
|
42385
|
-
escapeText(text) {
|
|
42386
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
43099
|
+
* @param ast bitmark AST
|
|
43100
|
+
*/
|
|
43101
|
+
async generate(ast) {
|
|
43102
|
+
return this.generator.generate(ast);
|
|
42387
43103
|
}
|
|
42388
|
-
|
|
42389
|
-
|
|
43104
|
+
/**
|
|
43105
|
+
* Generate bitmark markup from bitmark AST as a file synchronously
|
|
43106
|
+
*
|
|
43107
|
+
* @param ast bitmark AST
|
|
43108
|
+
*/
|
|
43109
|
+
generateSync(_ast) {
|
|
43110
|
+
if (this.async) {
|
|
43111
|
+
throw new Error("Sync operation not supported");
|
|
43112
|
+
}
|
|
43113
|
+
this.generator.generateSync(_ast);
|
|
42390
43114
|
}
|
|
42391
43115
|
};
|
|
42392
43116
|
var JsonFileGenerator = class {
|
|
@@ -42805,6 +43529,7 @@ var ConfigBuilder = class {
|
|
|
42805
43529
|
k = stringUtils.camelToKebab(k);
|
|
42806
43530
|
const resolvedGroups = resolveGroupReferences(k);
|
|
42807
43531
|
const hasOuterExport = Object.prototype.hasOwnProperty.call(tag, "exportJsonKey");
|
|
43532
|
+
const hasOuterHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
42808
43533
|
if (!hasOuterExport && tag.jsonKey != null) {
|
|
42809
43534
|
const headingPath = [...pathStack, `tags.${tag.key}`].join(" / ");
|
|
42810
43535
|
exportJsonKeyErrors.push(
|
|
@@ -42814,6 +43539,8 @@ var ConfigBuilder = class {
|
|
|
42814
43539
|
for (const ref of resolvedGroups) {
|
|
42815
43540
|
const exportJsonKeyChosen = hasOuterExport ? tag.exportJsonKey : ref.exportJsonKey;
|
|
42816
43541
|
const hasExportChosen = hasOuterExport || !!ref.hasExportJsonKey;
|
|
43542
|
+
const htmlKeyChosen = hasOuterHtml ? tag.htmlKey : ref.htmlKey;
|
|
43543
|
+
const hasHtmlChosen = hasOuterHtml || !!ref.hasHtmlKey;
|
|
42817
43544
|
const min = tag.minCount != null ? tag.minCount : ref.min;
|
|
42818
43545
|
const max = tag.maxCount != null ? tag.maxCount : ref.max;
|
|
42819
43546
|
const description = tag.description ? tag.description : ref.description;
|
|
@@ -42821,6 +43548,7 @@ var ConfigBuilder = class {
|
|
|
42821
43548
|
type: "group",
|
|
42822
43549
|
key: ref.key,
|
|
42823
43550
|
...hasExportChosen ? { jsonKey: exportJsonKeyChosen } : {},
|
|
43551
|
+
...hasHtmlChosen ? { htmlKey: htmlKeyChosen } : {},
|
|
42824
43552
|
...min != null ? { min } : {},
|
|
42825
43553
|
...max != null ? { max } : {},
|
|
42826
43554
|
...description ? { description } : {}
|
|
@@ -42849,10 +43577,13 @@ var ConfigBuilder = class {
|
|
|
42849
43577
|
);
|
|
42850
43578
|
exportJsonKeyField = {};
|
|
42851
43579
|
}
|
|
43580
|
+
const hasHtml = Object.prototype.hasOwnProperty.call(tag, "htmlKey");
|
|
43581
|
+
const htmlKeyField = hasHtml ? { htmlKey: tag.htmlKey } : {};
|
|
42852
43582
|
const t = {
|
|
42853
43583
|
type: "tag",
|
|
42854
43584
|
key: tagName,
|
|
42855
43585
|
...exportJsonKeyField,
|
|
43586
|
+
...htmlKeyField,
|
|
42856
43587
|
format,
|
|
42857
43588
|
default: tag.defaultValue ?? null,
|
|
42858
43589
|
...tag.nullable ? { nullable: true } : {},
|
|
@@ -42875,6 +43606,13 @@ var ConfigBuilder = class {
|
|
|
42875
43606
|
);
|
|
42876
43607
|
return {};
|
|
42877
43608
|
};
|
|
43609
|
+
const cardHtmlKeyField = (container, htmlExportKey) => {
|
|
43610
|
+
const c = container;
|
|
43611
|
+
if (Object.prototype.hasOwnProperty.call(c, htmlExportKey)) {
|
|
43612
|
+
return { htmlKey: c[htmlExportKey] };
|
|
43613
|
+
}
|
|
43614
|
+
return {};
|
|
43615
|
+
};
|
|
42878
43616
|
const serializeCardSet = (cardSetKey) => {
|
|
42879
43617
|
const variantBodyFormat = (variant) => variant.format ?? TextFormat.bitmarkText;
|
|
42880
43618
|
const cardSetConfig = CARDSETS[cardSetKey];
|
|
@@ -42905,6 +43643,7 @@ var ConfigBuilder = class {
|
|
|
42905
43643
|
}
|
|
42906
43644
|
return {
|
|
42907
43645
|
...cardJsonKeyField(variant, "jsonKey", "exportJsonKey", variantPath),
|
|
43646
|
+
...cardHtmlKeyField(variant, "htmlKey"),
|
|
42908
43647
|
format: variantBodyFormat(variant),
|
|
42909
43648
|
tags: variantTags,
|
|
42910
43649
|
repeatCount: variant.repeatCount ?? 1,
|
|
@@ -42916,6 +43655,7 @@ var ConfigBuilder = class {
|
|
|
42916
43655
|
name: side.name,
|
|
42917
43656
|
...side.repeat ? { repeat: side.repeat } : {},
|
|
42918
43657
|
...cardJsonKeyField(side, "jsonKey", "exportJsonKey", sidePath),
|
|
43658
|
+
...cardHtmlKeyField(side, "htmlKey"),
|
|
42919
43659
|
variants
|
|
42920
43660
|
};
|
|
42921
43661
|
});
|
|
@@ -42923,20 +43663,23 @@ var ConfigBuilder = class {
|
|
|
42923
43663
|
const cards = Object.entries(cardSetConfig.sections).map(([sectionName, section]) => {
|
|
42924
43664
|
const sectionPath = `cardSets.${normalizedKey} / cards.${sectionName}`;
|
|
42925
43665
|
const hasSideExport = Object.prototype.hasOwnProperty.call(section, "sideExportJsonKey");
|
|
43666
|
+
const hasSideHtml = Object.prototype.hasOwnProperty.call(section, "sideHtmlKey");
|
|
42926
43667
|
let cardSides = sides;
|
|
42927
|
-
if (hasSideExport || section.sideJsonKey != null) {
|
|
43668
|
+
if (hasSideExport || section.sideJsonKey != null || hasSideHtml) {
|
|
42928
43669
|
const sideOverride = cardJsonKeyField(
|
|
42929
43670
|
section,
|
|
42930
43671
|
"sideJsonKey",
|
|
42931
43672
|
"sideExportJsonKey",
|
|
42932
43673
|
`${sectionPath} / sides.*`
|
|
42933
43674
|
);
|
|
42934
|
-
|
|
43675
|
+
const sideHtmlOverride = cardHtmlKeyField(section, "sideHtmlKey");
|
|
43676
|
+
cardSides = sides.map((s) => ({ ...s, ...sideOverride, ...sideHtmlOverride }));
|
|
42935
43677
|
}
|
|
42936
43678
|
return {
|
|
42937
43679
|
name: sectionName,
|
|
42938
43680
|
...section.isDefault ? { isDefault: true } : {},
|
|
42939
43681
|
...cardJsonKeyField(section, "jsonKey", "exportJsonKey", sectionPath),
|
|
43682
|
+
...cardHtmlKeyField(section, "htmlKey"),
|
|
42940
43683
|
// PLAN-085: per-section cardinality. Emit only when non-default
|
|
42941
43684
|
// (treat `0` / undefined as "unbounded — omit").
|
|
42942
43685
|
...section.minCount != null && section.minCount !== 0 ? { min: section.minCount } : {},
|
|
@@ -42944,7 +43687,7 @@ var ConfigBuilder = class {
|
|
|
42944
43687
|
sides: cardSides
|
|
42945
43688
|
};
|
|
42946
43689
|
});
|
|
42947
|
-
return { name: normalizedKey, cards };
|
|
43690
|
+
return { name: normalizedKey, ...cardHtmlKeyField(cardSetConfig, "htmlKey"), cards };
|
|
42948
43691
|
}
|
|
42949
43692
|
const cardSetPath = `cardSets.${normalizedKey} / cards.default`;
|
|
42950
43693
|
return {
|
|
@@ -42954,6 +43697,7 @@ var ConfigBuilder = class {
|
|
|
42954
43697
|
name: "default",
|
|
42955
43698
|
isDefault: true,
|
|
42956
43699
|
...cardJsonKeyField(cardSetConfig, "jsonKey", "exportJsonKey", cardSetPath),
|
|
43700
|
+
...cardHtmlKeyField(cardSetConfig, "htmlKey"),
|
|
42957
43701
|
sides
|
|
42958
43702
|
}
|
|
42959
43703
|
]
|
|
@@ -42993,6 +43737,10 @@ var ConfigBuilder = class {
|
|
|
42993
43737
|
ref.exportJsonKey = t.jsonKey;
|
|
42994
43738
|
ref.hasExportJsonKey = true;
|
|
42995
43739
|
}
|
|
43740
|
+
if (Object.prototype.hasOwnProperty.call(t, "htmlKey")) {
|
|
43741
|
+
ref.htmlKey = t.htmlKey;
|
|
43742
|
+
ref.hasHtmlKey = true;
|
|
43743
|
+
}
|
|
42996
43744
|
replacements.push(ref);
|
|
42997
43745
|
}
|
|
42998
43746
|
squashedGroups.set(groupKey, replacements);
|
|
@@ -43027,6 +43775,7 @@ var ConfigBuilder = class {
|
|
|
43027
43775
|
type: "group",
|
|
43028
43776
|
key: ref.key,
|
|
43029
43777
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
43778
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43030
43779
|
...ref.min != null ? { min: ref.min } : {},
|
|
43031
43780
|
...ref.max != null ? { max: ref.max } : {},
|
|
43032
43781
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43040,6 +43789,7 @@ var ConfigBuilder = class {
|
|
|
43040
43789
|
type: "group",
|
|
43041
43790
|
key: ref.key,
|
|
43042
43791
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
43792
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43043
43793
|
...ref.min != null ? { min: ref.min } : {},
|
|
43044
43794
|
...ref.max != null ? { max: ref.max } : {},
|
|
43045
43795
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43169,6 +43919,7 @@ var ConfigBuilder = class {
|
|
|
43169
43919
|
type: "group",
|
|
43170
43920
|
key: ref.key,
|
|
43171
43921
|
...ref.hasExportJsonKey ? { jsonKey: ref.exportJsonKey } : {},
|
|
43922
|
+
...ref.hasHtmlKey ? { htmlKey: ref.htmlKey } : {},
|
|
43172
43923
|
...ref.min != null ? { min: ref.min } : {},
|
|
43173
43924
|
...ref.max != null ? { max: ref.max } : {},
|
|
43174
43925
|
...ref.description ? { description: ref.description } : {}
|
|
@@ -43358,497 +44109,6 @@ var ConfigBuilder = class {
|
|
|
43358
44109
|
}
|
|
43359
44110
|
};
|
|
43360
44111
|
|
|
43361
|
-
// src/parser/html/HtmlDom.ts
|
|
43362
|
-
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
43363
|
-
"area",
|
|
43364
|
-
"base",
|
|
43365
|
-
"br",
|
|
43366
|
-
"col",
|
|
43367
|
-
"embed",
|
|
43368
|
-
"hr",
|
|
43369
|
-
"img",
|
|
43370
|
-
"input",
|
|
43371
|
-
"link",
|
|
43372
|
-
"meta",
|
|
43373
|
-
"param",
|
|
43374
|
-
"source",
|
|
43375
|
-
"track",
|
|
43376
|
-
"wbr"
|
|
43377
|
-
]);
|
|
43378
|
-
var IMPLIED_CLOSE = {
|
|
43379
|
-
li: /* @__PURE__ */ new Set(["li"]),
|
|
43380
|
-
td: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43381
|
-
th: /* @__PURE__ */ new Set(["td", "th"]),
|
|
43382
|
-
tr: /* @__PURE__ */ new Set(["td", "th", "tr"]),
|
|
43383
|
-
thead: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43384
|
-
tbody: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43385
|
-
tfoot: /* @__PURE__ */ new Set(["td", "th", "tr", "thead", "tbody", "tfoot"]),
|
|
43386
|
-
p: /* @__PURE__ */ new Set(["p"]),
|
|
43387
|
-
option: /* @__PURE__ */ new Set(["option"])
|
|
43388
|
-
};
|
|
43389
|
-
var TAG_RE = /<(\/)?([a-zA-Z][a-zA-Z0-9-]*)((?:\s+(?:"[^"]*"|'[^']*'|[^<>"'])*)?)(\/)?>/g;
|
|
43390
|
-
var ATTR_RE = /([a-zA-Z_:][a-zA-Z0-9:._-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>]+))?/g;
|
|
43391
|
-
function parseAttrs(raw) {
|
|
43392
|
-
const attrs = {};
|
|
43393
|
-
if (!raw) return attrs;
|
|
43394
|
-
ATTR_RE.lastIndex = 0;
|
|
43395
|
-
let m;
|
|
43396
|
-
while ((m = ATTR_RE.exec(raw)) !== null) {
|
|
43397
|
-
const name = m[1].toLowerCase();
|
|
43398
|
-
let value = m[2] ?? "";
|
|
43399
|
-
if (value.length >= 2 && (value[0] === '"' || value[0] === "'")) {
|
|
43400
|
-
value = value.slice(1, -1);
|
|
43401
|
-
}
|
|
43402
|
-
attrs[name] = value;
|
|
43403
|
-
}
|
|
43404
|
-
return attrs;
|
|
43405
|
-
}
|
|
43406
|
-
function stripNonContent(html) {
|
|
43407
|
-
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, "");
|
|
43408
|
-
}
|
|
43409
|
-
function tokenize(html) {
|
|
43410
|
-
const tokens = [];
|
|
43411
|
-
const clean = stripNonContent(html);
|
|
43412
|
-
TAG_RE.lastIndex = 0;
|
|
43413
|
-
let lastIndex = 0;
|
|
43414
|
-
let m;
|
|
43415
|
-
while ((m = TAG_RE.exec(clean)) !== null) {
|
|
43416
|
-
if (m.index > lastIndex) {
|
|
43417
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex, m.index) });
|
|
43418
|
-
}
|
|
43419
|
-
lastIndex = TAG_RE.lastIndex;
|
|
43420
|
-
const isClose = m[1] === "/";
|
|
43421
|
-
const name = m[2].toLowerCase();
|
|
43422
|
-
if (isClose) {
|
|
43423
|
-
tokens.push({ kind: "close", name });
|
|
43424
|
-
} else {
|
|
43425
|
-
tokens.push({
|
|
43426
|
-
kind: "open",
|
|
43427
|
-
name,
|
|
43428
|
-
attrs: parseAttrs(m[3]),
|
|
43429
|
-
selfClose: m[4] === "/"
|
|
43430
|
-
});
|
|
43431
|
-
}
|
|
43432
|
-
}
|
|
43433
|
-
if (lastIndex < clean.length) {
|
|
43434
|
-
tokens.push({ kind: "text", text: clean.slice(lastIndex) });
|
|
43435
|
-
}
|
|
43436
|
-
return tokens;
|
|
43437
|
-
}
|
|
43438
|
-
function parseHtml(html) {
|
|
43439
|
-
const root = { type: "element", name: "#root", attrs: {}, children: [] };
|
|
43440
|
-
const stack = [root];
|
|
43441
|
-
const top = () => stack[stack.length - 1];
|
|
43442
|
-
for (const token of tokenize(html)) {
|
|
43443
|
-
if (token.kind === "text") {
|
|
43444
|
-
if (token.text) top().children.push({ type: "text", value: token.text });
|
|
43445
|
-
continue;
|
|
43446
|
-
}
|
|
43447
|
-
if (token.kind === "open") {
|
|
43448
|
-
const name = token.name;
|
|
43449
|
-
const closes = IMPLIED_CLOSE[name];
|
|
43450
|
-
if (closes) {
|
|
43451
|
-
while (stack.length > 1 && closes.has(top().name)) stack.pop();
|
|
43452
|
-
}
|
|
43453
|
-
const el = {
|
|
43454
|
-
type: "element",
|
|
43455
|
-
name,
|
|
43456
|
-
attrs: token.attrs ?? {},
|
|
43457
|
-
children: []
|
|
43458
|
-
};
|
|
43459
|
-
top().children.push(el);
|
|
43460
|
-
if (!token.selfClose && !VOID_ELEMENTS.has(name)) {
|
|
43461
|
-
stack.push(el);
|
|
43462
|
-
}
|
|
43463
|
-
continue;
|
|
43464
|
-
}
|
|
43465
|
-
for (let i = stack.length - 1; i > 0; i--) {
|
|
43466
|
-
if (stack[i].name === token.name) {
|
|
43467
|
-
stack.length = i;
|
|
43468
|
-
break;
|
|
43469
|
-
}
|
|
43470
|
-
}
|
|
43471
|
-
}
|
|
43472
|
-
return root.children;
|
|
43473
|
-
}
|
|
43474
|
-
function childElements(el, names) {
|
|
43475
|
-
return el.children.filter((c) => c.type === "element" && names.has(c.name));
|
|
43476
|
-
}
|
|
43477
|
-
|
|
43478
|
-
// src/parser/html/HtmlTableParser.ts
|
|
43479
|
-
var MARK_TAGS = {
|
|
43480
|
-
b: "bold",
|
|
43481
|
-
strong: "bold",
|
|
43482
|
-
i: "italic",
|
|
43483
|
-
em: "italic",
|
|
43484
|
-
sup: "superscript",
|
|
43485
|
-
sub: "subscript",
|
|
43486
|
-
s: "strike",
|
|
43487
|
-
strike: "strike",
|
|
43488
|
-
del: "del",
|
|
43489
|
-
ins: "ins",
|
|
43490
|
-
u: "underline",
|
|
43491
|
-
mark: "highlight",
|
|
43492
|
-
code: "code"
|
|
43493
|
-
};
|
|
43494
|
-
var SECTION_TAGS = /* @__PURE__ */ new Set(["thead", "tbody", "tfoot"]);
|
|
43495
|
-
var ROW_TAGS = /* @__PURE__ */ new Set(["tr"]);
|
|
43496
|
-
var CELL_TAGS = /* @__PURE__ */ new Set(["td", "th"]);
|
|
43497
|
-
var LI_TAGS = /* @__PURE__ */ new Set(["li"]);
|
|
43498
|
-
var VALID_SCOPES = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
43499
|
-
var NAMED_ENTITIES = {
|
|
43500
|
-
amp: "&",
|
|
43501
|
-
lt: "<",
|
|
43502
|
-
gt: ">",
|
|
43503
|
-
quot: '"',
|
|
43504
|
-
apos: "'",
|
|
43505
|
-
nbsp: "\xA0"
|
|
43506
|
-
};
|
|
43507
|
-
function decodeEntities(text) {
|
|
43508
|
-
return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]*);/g, (whole, body) => {
|
|
43509
|
-
if (body[0] === "#") {
|
|
43510
|
-
const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
|
|
43511
|
-
if (Number.isFinite(code) && code >= 0 && code <= 1114111) {
|
|
43512
|
-
try {
|
|
43513
|
-
return String.fromCodePoint(code);
|
|
43514
|
-
} catch {
|
|
43515
|
-
return whole;
|
|
43516
|
-
}
|
|
43517
|
-
}
|
|
43518
|
-
return whole;
|
|
43519
|
-
}
|
|
43520
|
-
return NAMED_ENTITIES[body] ?? whole;
|
|
43521
|
-
});
|
|
43522
|
-
}
|
|
43523
|
-
function intAttr(value) {
|
|
43524
|
-
if (value == null) return void 0;
|
|
43525
|
-
const n = Number.parseInt(value, 10);
|
|
43526
|
-
return Number.isInteger(n) ? n : void 0;
|
|
43527
|
-
}
|
|
43528
|
-
function isElement(node) {
|
|
43529
|
-
return node.type === "element";
|
|
43530
|
-
}
|
|
43531
|
-
var HtmlTableParser = class {
|
|
43532
|
-
keepUnknownTags = false;
|
|
43533
|
-
/**
|
|
43534
|
-
* Parse an HTML string and return one table bit per top-level `<table>`.
|
|
43535
|
-
*/
|
|
43536
|
-
parse(html, options) {
|
|
43537
|
-
this.keepUnknownTags = options?.keepUnknownTags ?? false;
|
|
43538
|
-
const tableFormat = options?.tableFormat ?? "table-extended";
|
|
43539
|
-
const onWarning = options?.onWarning;
|
|
43540
|
-
const tables = this.collectTopLevelTables(parseHtml(html));
|
|
43541
|
-
const bits = [];
|
|
43542
|
-
for (const table of tables) {
|
|
43543
|
-
const bit = this.tableToBit(table, tableFormat, onWarning);
|
|
43544
|
-
if (bit) bits.push(bit);
|
|
43545
|
-
}
|
|
43546
|
-
return bits;
|
|
43547
|
-
}
|
|
43548
|
-
// --- table extraction -----------------------------------------------------
|
|
43549
|
-
/** Collect every `<table>` element, NOT descending into nested tables. */
|
|
43550
|
-
collectTopLevelTables(nodes) {
|
|
43551
|
-
const tables = [];
|
|
43552
|
-
const visit = (node) => {
|
|
43553
|
-
if (!isElement(node)) return;
|
|
43554
|
-
if (node.name === "table") {
|
|
43555
|
-
tables.push(node);
|
|
43556
|
-
return;
|
|
43557
|
-
}
|
|
43558
|
-
node.children.forEach(visit);
|
|
43559
|
-
};
|
|
43560
|
-
nodes.forEach(visit);
|
|
43561
|
-
return tables;
|
|
43562
|
-
}
|
|
43563
|
-
tableToBit(table, tableFormat, onWarning) {
|
|
43564
|
-
const header = [];
|
|
43565
|
-
const body = [];
|
|
43566
|
-
const footer = [];
|
|
43567
|
-
let caption;
|
|
43568
|
-
for (const child of table.children) {
|
|
43569
|
-
if (!isElement(child)) continue;
|
|
43570
|
-
if (child.name === "caption") {
|
|
43571
|
-
const capContent = this.inlineNodes(child.children, []);
|
|
43572
|
-
const trimmed = this.trimInline(capContent);
|
|
43573
|
-
if (trimmed.length > 0) caption = trimmed;
|
|
43574
|
-
} else if (SECTION_TAGS.has(child.name)) {
|
|
43575
|
-
const target = child.name === "thead" ? header : child.name === "tfoot" ? footer : body;
|
|
43576
|
-
for (const tr of childElements(child, ROW_TAGS)) {
|
|
43577
|
-
target.push(this.rowToCells(tr));
|
|
43578
|
-
}
|
|
43579
|
-
} else if (ROW_TAGS.has(child.name)) {
|
|
43580
|
-
body.push(this.rowToCells(child));
|
|
43581
|
-
}
|
|
43582
|
-
}
|
|
43583
|
-
if (header.length === 0 && body.length === 0 && footer.length === 0) {
|
|
43584
|
-
return void 0;
|
|
43585
|
-
}
|
|
43586
|
-
const tableExtended = {};
|
|
43587
|
-
if (header.length > 0) tableExtended.header = { rows: header };
|
|
43588
|
-
if (body.length > 0) tableExtended.body = { rows: body };
|
|
43589
|
-
if (footer.length > 0) tableExtended.footer = { rows: footer };
|
|
43590
|
-
let tableData = tableExtended;
|
|
43591
|
-
if (tableFormat === "table") {
|
|
43592
|
-
if (this.isLossyAsBasic(tableExtended)) {
|
|
43593
|
-
onWarning?.(
|
|
43594
|
-
"Converting an HTML table to [.table] loses rowspan/colspan/scope and multi-section structure; use --tableFormat table-extended to preserve them."
|
|
43595
|
-
);
|
|
43596
|
-
}
|
|
43597
|
-
tableData = convertExtendedToBasicTableFormat(tableExtended);
|
|
43598
|
-
}
|
|
43599
|
-
const bit = {
|
|
43600
|
-
type: tableFormat,
|
|
43601
|
-
format: "bitmark++",
|
|
43602
|
-
table: tableData
|
|
43603
|
-
};
|
|
43604
|
-
if (caption) bit.caption = caption;
|
|
43605
|
-
return bit;
|
|
43606
|
-
}
|
|
43607
|
-
rowToCells(tr) {
|
|
43608
|
-
const cells = [];
|
|
43609
|
-
for (const cell of childElements(tr, CELL_TAGS)) {
|
|
43610
|
-
cells.push(this.cellToJson(cell));
|
|
43611
|
-
}
|
|
43612
|
-
return { cells };
|
|
43613
|
-
}
|
|
43614
|
-
cellToJson(cell) {
|
|
43615
|
-
const json = {
|
|
43616
|
-
content: this.blockNodes(cell.children)
|
|
43617
|
-
};
|
|
43618
|
-
if (cell.name === "th") json.title = true;
|
|
43619
|
-
const rowspan = intAttr(cell.attrs.rowspan);
|
|
43620
|
-
if (rowspan != null && rowspan >= 2) json.rowspan = rowspan;
|
|
43621
|
-
const colspan = intAttr(cell.attrs.colspan);
|
|
43622
|
-
if (colspan != null && colspan >= 2) json.colspan = colspan;
|
|
43623
|
-
const scope = cell.attrs.scope?.toLowerCase();
|
|
43624
|
-
if (scope && VALID_SCOPES.has(scope)) {
|
|
43625
|
-
json.scope = scope;
|
|
43626
|
-
}
|
|
43627
|
-
const width = this.widthFromCell(cell);
|
|
43628
|
-
if (width != null) json.colwidth = width;
|
|
43629
|
-
return json;
|
|
43630
|
-
}
|
|
43631
|
-
widthFromCell(cell) {
|
|
43632
|
-
const attrWidth = intAttr(cell.attrs.width);
|
|
43633
|
-
if (attrWidth != null && attrWidth > 0) return attrWidth;
|
|
43634
|
-
const style = cell.attrs.style;
|
|
43635
|
-
if (style) {
|
|
43636
|
-
const m = style.match(/width\s*:\s*(\d+)\s*px/i);
|
|
43637
|
-
if (m) {
|
|
43638
|
-
const n = Number.parseInt(m[1], 10);
|
|
43639
|
-
if (Number.isInteger(n) && n > 0) return n;
|
|
43640
|
-
}
|
|
43641
|
-
}
|
|
43642
|
-
return void 0;
|
|
43643
|
-
}
|
|
43644
|
-
isLossyAsBasic(table) {
|
|
43645
|
-
if (table.footer) return true;
|
|
43646
|
-
if (table.header && table.header.rows.length > 1) return true;
|
|
43647
|
-
const sections = [table.header, table.body, table.footer];
|
|
43648
|
-
for (const section of sections) {
|
|
43649
|
-
if (!section) continue;
|
|
43650
|
-
for (const row of section.rows) {
|
|
43651
|
-
for (const cell of row.cells) {
|
|
43652
|
-
if (cell.rowspan || cell.colspan || cell.scope) return true;
|
|
43653
|
-
}
|
|
43654
|
-
}
|
|
43655
|
-
}
|
|
43656
|
-
return false;
|
|
43657
|
-
}
|
|
43658
|
-
// --- content conversion (HTML -> TextAst) ---------------------------------
|
|
43659
|
-
/**
|
|
43660
|
-
* Convert a cell/li's child nodes into block-level TextAst nodes (paragraphs, lists, images).
|
|
43661
|
-
*/
|
|
43662
|
-
blockNodes(nodes) {
|
|
43663
|
-
const blocks = [];
|
|
43664
|
-
let inline = [];
|
|
43665
|
-
const flush = () => {
|
|
43666
|
-
const trimmed = this.trimInline(inline);
|
|
43667
|
-
inline = [];
|
|
43668
|
-
if (trimmed.length === 0) return;
|
|
43669
|
-
if (trimmed.length === 1 && trimmed[0].type === "imageInline") {
|
|
43670
|
-
blocks.push({ ...trimmed[0], type: "image" });
|
|
43671
|
-
} else {
|
|
43672
|
-
blocks.push({ type: "paragraph", content: trimmed, attrs: {} });
|
|
43673
|
-
}
|
|
43674
|
-
};
|
|
43675
|
-
for (const node of nodes) {
|
|
43676
|
-
if (!isElement(node)) {
|
|
43677
|
-
inline.push(...this.inlineText(node.value, []));
|
|
43678
|
-
continue;
|
|
43679
|
-
}
|
|
43680
|
-
const name = node.name;
|
|
43681
|
-
if (name === "p") {
|
|
43682
|
-
flush();
|
|
43683
|
-
const content = this.trimInline(this.inlineNodes(node.children, []));
|
|
43684
|
-
if (content.length > 0) {
|
|
43685
|
-
blocks.push({ type: "paragraph", content, attrs: {} });
|
|
43686
|
-
}
|
|
43687
|
-
} else if (this.isListTag(name)) {
|
|
43688
|
-
flush();
|
|
43689
|
-
const list = this.listNode(node);
|
|
43690
|
-
if (list) blocks.push(list);
|
|
43691
|
-
} else {
|
|
43692
|
-
inline.push(...this.inlineFromElement(node, []));
|
|
43693
|
-
}
|
|
43694
|
-
}
|
|
43695
|
-
flush();
|
|
43696
|
-
return blocks;
|
|
43697
|
-
}
|
|
43698
|
-
/** Convert child nodes to a flat list of inline TextNodes, applying the given marks. */
|
|
43699
|
-
inlineNodes(nodes, marks) {
|
|
43700
|
-
const out = [];
|
|
43701
|
-
for (const node of nodes) {
|
|
43702
|
-
if (!isElement(node)) {
|
|
43703
|
-
out.push(...this.inlineText(node.value, marks));
|
|
43704
|
-
} else {
|
|
43705
|
-
out.push(...this.inlineFromElement(node, marks));
|
|
43706
|
-
}
|
|
43707
|
-
}
|
|
43708
|
-
return out;
|
|
43709
|
-
}
|
|
43710
|
-
inlineFromElement(el, marks) {
|
|
43711
|
-
const name = el.name;
|
|
43712
|
-
if (name === "br") {
|
|
43713
|
-
return [{ type: "hardBreak" }];
|
|
43714
|
-
}
|
|
43715
|
-
if (name === "img") {
|
|
43716
|
-
return [this.imageNode(el, true)];
|
|
43717
|
-
}
|
|
43718
|
-
const markType = MARK_TAGS[name];
|
|
43719
|
-
if (markType) {
|
|
43720
|
-
return this.inlineNodes(el.children, [...marks, { type: markType }]);
|
|
43721
|
-
}
|
|
43722
|
-
if (name === "a") {
|
|
43723
|
-
const linkMark = {
|
|
43724
|
-
type: "link",
|
|
43725
|
-
attrs: {
|
|
43726
|
-
href: el.attrs.href ?? "",
|
|
43727
|
-
...el.attrs.target ? { target: el.attrs.target } : {}
|
|
43728
|
-
}
|
|
43729
|
-
};
|
|
43730
|
-
return this.inlineNodes(el.children, [...marks, linkMark]);
|
|
43731
|
-
}
|
|
43732
|
-
if (this.keepUnknownTags) {
|
|
43733
|
-
const open = this.serializeOpenTag(el);
|
|
43734
|
-
const close = `</${name}>`;
|
|
43735
|
-
return [
|
|
43736
|
-
...this.inlineText(open, marks),
|
|
43737
|
-
...this.inlineNodes(el.children, marks),
|
|
43738
|
-
...this.inlineText(close, marks)
|
|
43739
|
-
];
|
|
43740
|
-
}
|
|
43741
|
-
return this.inlineNodes(el.children, marks);
|
|
43742
|
-
}
|
|
43743
|
-
inlineText(raw, marks) {
|
|
43744
|
-
const text = decodeEntities(raw).replace(/\s+/g, " ");
|
|
43745
|
-
if (text === "") return [];
|
|
43746
|
-
const node = { text, type: "text" };
|
|
43747
|
-
if (marks.length > 0) node.marks = marks.map((m) => ({ ...m }));
|
|
43748
|
-
return [node];
|
|
43749
|
-
}
|
|
43750
|
-
serializeOpenTag(el) {
|
|
43751
|
-
const attrs = Object.entries(el.attrs).map(([k, v]) => v === "" ? ` ${k}` : ` ${k}="${v}"`).join("");
|
|
43752
|
-
return `<${el.name}${attrs}>`;
|
|
43753
|
-
}
|
|
43754
|
-
// --- lists ----------------------------------------------------------------
|
|
43755
|
-
isListTag(name) {
|
|
43756
|
-
return name === "ul" || name === "ol";
|
|
43757
|
-
}
|
|
43758
|
-
listNode(el) {
|
|
43759
|
-
const items = childElements(el, LI_TAGS);
|
|
43760
|
-
if (items.length === 0) return void 0;
|
|
43761
|
-
const isTask = el.name === "ul" && items.some((li) => {
|
|
43762
|
-
const firstEl = li.children.find(isElement);
|
|
43763
|
-
return firstEl?.name === "input" && firstEl.attrs.type?.toLowerCase() === "checkbox";
|
|
43764
|
-
});
|
|
43765
|
-
if (isTask) {
|
|
43766
|
-
return {
|
|
43767
|
-
type: "taskList",
|
|
43768
|
-
content: items.map((li) => this.taskItemNode(li))
|
|
43769
|
-
};
|
|
43770
|
-
}
|
|
43771
|
-
const type = this.listType(el);
|
|
43772
|
-
const node = {
|
|
43773
|
-
type,
|
|
43774
|
-
content: items.map((li) => this.listItemNode(li))
|
|
43775
|
-
};
|
|
43776
|
-
if (el.name === "ol") {
|
|
43777
|
-
const start = intAttr(el.attrs.start);
|
|
43778
|
-
if (start != null) {
|
|
43779
|
-
node.attrs = { start };
|
|
43780
|
-
}
|
|
43781
|
-
}
|
|
43782
|
-
return node;
|
|
43783
|
-
}
|
|
43784
|
-
listType(el) {
|
|
43785
|
-
if (el.name === "ol") {
|
|
43786
|
-
switch (el.attrs.type) {
|
|
43787
|
-
case "i":
|
|
43788
|
-
return "orderedListRomanLower";
|
|
43789
|
-
case "I":
|
|
43790
|
-
return "orderedListRoman";
|
|
43791
|
-
case "a":
|
|
43792
|
-
return "letteredListLower";
|
|
43793
|
-
case "A":
|
|
43794
|
-
return "letteredList";
|
|
43795
|
-
default:
|
|
43796
|
-
return "orderedList";
|
|
43797
|
-
}
|
|
43798
|
-
}
|
|
43799
|
-
const style = el.attrs.style ?? "";
|
|
43800
|
-
if (/list-style(-type)?\s*:\s*none/i.test(style)) return "noBulletList";
|
|
43801
|
-
return "bulletList";
|
|
43802
|
-
}
|
|
43803
|
-
listItemNode(li) {
|
|
43804
|
-
let content = this.blockNodes(li.children);
|
|
43805
|
-
if (content.length === 0) {
|
|
43806
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43807
|
-
}
|
|
43808
|
-
return { type: "listItem", content };
|
|
43809
|
-
}
|
|
43810
|
-
taskItemNode(li) {
|
|
43811
|
-
const checkbox = li.children.find(
|
|
43812
|
-
(c) => isElement(c) && c.name === "input" && c.attrs.type?.toLowerCase() === "checkbox"
|
|
43813
|
-
);
|
|
43814
|
-
const checked = checkbox ? "checked" in checkbox.attrs : false;
|
|
43815
|
-
const rest = li.children.filter((c) => c !== checkbox);
|
|
43816
|
-
let content = this.blockNodes(rest);
|
|
43817
|
-
if (content.length === 0) {
|
|
43818
|
-
content = [{ type: "paragraph", content: [], attrs: {} }];
|
|
43819
|
-
}
|
|
43820
|
-
return { type: "taskItem", attrs: { checked }, content };
|
|
43821
|
-
}
|
|
43822
|
-
// --- images ---------------------------------------------------------------
|
|
43823
|
-
imageNode(el, inline) {
|
|
43824
|
-
const attrs = { src: el.attrs.src ?? "" };
|
|
43825
|
-
attrs.alt = el.attrs.alt ?? null;
|
|
43826
|
-
attrs.title = el.attrs.title ?? null;
|
|
43827
|
-
const width = intAttr(el.attrs.width);
|
|
43828
|
-
if (width != null) attrs.width = width;
|
|
43829
|
-
const height = intAttr(el.attrs.height);
|
|
43830
|
-
if (height != null) attrs.height = height;
|
|
43831
|
-
if (el.attrs.class) attrs.class = el.attrs.class;
|
|
43832
|
-
return { type: inline ? "imageInline" : "image", attrs };
|
|
43833
|
-
}
|
|
43834
|
-
// --- whitespace -----------------------------------------------------------
|
|
43835
|
-
/** Trim leading/trailing whitespace from inline content (edges only). */
|
|
43836
|
-
trimInline(nodes) {
|
|
43837
|
-
const out = nodes.slice();
|
|
43838
|
-
const isWs = (n) => n.type === "text" && /^\s*$/.test(n.text ?? "");
|
|
43839
|
-
while (out.length > 0 && isWs(out[0])) out.shift();
|
|
43840
|
-
if (out.length > 0 && out[0].type === "text") {
|
|
43841
|
-
out[0] = { ...out[0], text: (out[0].text ?? "").replace(/^\s+/, "") };
|
|
43842
|
-
}
|
|
43843
|
-
while (out.length > 0 && isWs(out[out.length - 1])) out.pop();
|
|
43844
|
-
if (out.length > 0 && out[out.length - 1].type === "text") {
|
|
43845
|
-
const last = out.length - 1;
|
|
43846
|
-
out[last] = { ...out[last], text: (out[last].text ?? "").replace(/\s+$/, "") };
|
|
43847
|
-
}
|
|
43848
|
-
return out.filter((n) => !(n.type === "text" && n.text === ""));
|
|
43849
|
-
}
|
|
43850
|
-
};
|
|
43851
|
-
|
|
43852
44112
|
// src/BitmarkParserGenerator.ts
|
|
43853
44113
|
var Input = {
|
|
43854
44114
|
/**
|