@knowvah/dot-engine 2.6.6 → 2.6.8
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/common/htmltable-attr-warn.d.ts +10 -4
- package/dist/common/htmltable-attr-warn.d.ts.map +1 -1
- package/dist/common/htmltable-label.d.ts +37 -0
- package/dist/common/htmltable-label.d.ts.map +1 -0
- package/dist/common/htmltable-lex-attvalue.d.ts +59 -0
- package/dist/common/htmltable-lex-attvalue.d.ts.map +1 -0
- package/dist/common/htmltable-lex-chardata.d.ts +37 -0
- package/dist/common/htmltable-lex-chardata.d.ts.map +1 -0
- package/dist/common/htmltable-lex-expat.d.ts +26 -13
- package/dist/common/htmltable-lex-expat.d.ts.map +1 -1
- package/dist/common/htmltable-lex.d.ts.map +1 -1
- package/dist/common/htmltable-parse-attrs.d.ts +3 -1
- package/dist/common/htmltable-parse-attrs.d.ts.map +1 -1
- package/dist/common/htmltable-parse.d.ts +6 -5
- package/dist/common/htmltable-parse.d.ts.map +1 -1
- package/dist/common/htmltable-pos.d.ts +3 -26
- package/dist/common/htmltable-pos.d.ts.map +1 -1
- package/dist/common/htmltable-types.d.ts +5 -1
- package/dist/common/htmltable-types.d.ts.map +1 -1
- package/dist/common/htmltable.d.ts +3 -2
- package/dist/common/htmltable.d.ts.map +1 -1
- package/dist/common/make-label.d.ts.map +1 -1
- package/dist/index.js +310 -144
- package/dist/index.js.map +4 -4
- package/dist/render.js +310 -144
- package/dist/render.js.map +4 -4
- package/package.json +1 -1
- package/src/common/htmltable-attr-warn.ts +24 -7
- package/src/common/htmltable-label.ts +109 -0
- package/src/common/htmltable-lex-attvalue.ts +141 -0
- package/src/common/htmltable-lex-chardata.ts +95 -0
- package/src/common/htmltable-lex-expat.ts +143 -48
- package/src/common/htmltable-lex.ts +41 -36
- package/src/common/htmltable-parse-attrs.ts +10 -13
- package/src/common/htmltable-parse.ts +46 -61
- package/src/common/htmltable-pos.ts +5 -88
- package/src/common/htmltable-types.ts +6 -1
- package/src/common/htmltable.ts +16 -16
- package/src/common/make-label.ts +8 -3
package/dist/index.js
CHANGED
|
@@ -10358,9 +10358,11 @@ var StderrLines = class {
|
|
|
10358
10358
|
writeLine;
|
|
10359
10359
|
pending = "";
|
|
10360
10360
|
write(text) {
|
|
10361
|
-
|
|
10362
|
-
this.pending
|
|
10363
|
-
|
|
10361
|
+
this.pending += text;
|
|
10362
|
+
if (!this.pending.endsWith("\n")) return;
|
|
10363
|
+
const line = this.pending.slice(0, -1);
|
|
10364
|
+
this.pending = "";
|
|
10365
|
+
this.writeLine(line);
|
|
10364
10366
|
}
|
|
10365
10367
|
flush() {
|
|
10366
10368
|
if (this.pending === "") return;
|
|
@@ -10368,6 +10370,16 @@ var StderrLines = class {
|
|
|
10368
10370
|
this.pending = "";
|
|
10369
10371
|
}
|
|
10370
10372
|
};
|
|
10373
|
+
var consoleLine = (line) => {
|
|
10374
|
+
if (line.startsWith("Warning")) console.warn(line);
|
|
10375
|
+
else console.error(line);
|
|
10376
|
+
};
|
|
10377
|
+
var labelStderr = () => new StderrLines(consoleLine);
|
|
10378
|
+
var agerrLine = (out, msg) => {
|
|
10379
|
+
if (out === void 0) consoleLine(msg);
|
|
10380
|
+
else out.write(`${msg}
|
|
10381
|
+
`);
|
|
10382
|
+
};
|
|
10371
10383
|
|
|
10372
10384
|
// src/common/htmltable-parse-state.ts
|
|
10373
10385
|
var peek = (s) => s.tokens[s.pos];
|
|
@@ -10672,11 +10684,87 @@ function htmlEntityUTF8(s) {
|
|
|
10672
10684
|
});
|
|
10673
10685
|
}
|
|
10674
10686
|
|
|
10687
|
+
// src/common/htmltable-lex-attvalue.ts
|
|
10688
|
+
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
10689
|
+
var XML_ERROR_BAD_CHAR_REF = "reference to invalid character number";
|
|
10690
|
+
var NAME_START = /[A-Za-z_:\u0080-]/;
|
|
10691
|
+
var NAME_CHAR = /[\w.:\u0080--]/;
|
|
10692
|
+
var DEC_DIGIT = /[0-9]/;
|
|
10693
|
+
var HEX_DIGIT = /[0-9A-Fa-f]/;
|
|
10694
|
+
var NON_XML = /[\x00-\x08\x0b\x0c\x0e-\x1f]/;
|
|
10695
|
+
function scanDigits(text, i, digit) {
|
|
10696
|
+
if (i >= text.length) return { partial: true };
|
|
10697
|
+
if (!digit.test(text[i])) return { invalid: i };
|
|
10698
|
+
for (let k = i + 1; k < text.length; k++) {
|
|
10699
|
+
if (text[k] === ";") return k + 1;
|
|
10700
|
+
if (!digit.test(text[k])) return { invalid: k };
|
|
10701
|
+
}
|
|
10702
|
+
return { partial: true };
|
|
10703
|
+
}
|
|
10704
|
+
function scanRef(text, i) {
|
|
10705
|
+
const c = text[i];
|
|
10706
|
+
if (c === void 0) return { partial: true };
|
|
10707
|
+
if (c === "#") return text[i + 1] === "x" ? scanDigits(text, i + 2, HEX_DIGIT) : scanDigits(text, i + 1, DEC_DIGIT);
|
|
10708
|
+
if (!NAME_START.test(c)) return { invalid: i };
|
|
10709
|
+
for (let k = i + 1; k < text.length; k++) {
|
|
10710
|
+
if (text[k] === ";") return k + 1;
|
|
10711
|
+
if (!NAME_CHAR.test(text[k])) return { invalid: k };
|
|
10712
|
+
}
|
|
10713
|
+
return { partial: true };
|
|
10714
|
+
}
|
|
10715
|
+
function scanAttValue(text, j) {
|
|
10716
|
+
const q = text[j];
|
|
10717
|
+
let k = j + 1;
|
|
10718
|
+
for (; ; ) {
|
|
10719
|
+
const c = text[k];
|
|
10720
|
+
if (c === void 0) return { partial: true };
|
|
10721
|
+
if (c === q) return { close: k };
|
|
10722
|
+
if (c === "<" || NON_XML.test(c)) return { invalid: k };
|
|
10723
|
+
if (c !== "&") {
|
|
10724
|
+
k++;
|
|
10725
|
+
continue;
|
|
10726
|
+
}
|
|
10727
|
+
const r = scanRef(text, k + 1);
|
|
10728
|
+
if (typeof r !== "number") return r;
|
|
10729
|
+
k = r;
|
|
10730
|
+
}
|
|
10731
|
+
}
|
|
10732
|
+
function charRefNumber(ref) {
|
|
10733
|
+
const hex = ref.startsWith("&#x");
|
|
10734
|
+
const n = parseInt(ref.slice(hex ? 3 : 2, -1), hex ? 16 : 10);
|
|
10735
|
+
if (n >= 1114112) return -1;
|
|
10736
|
+
if (n >= 55296 && n <= 57343) return -1;
|
|
10737
|
+
if (n < 32 && NON_XML.test(String.fromCharCode(n))) return -1;
|
|
10738
|
+
return n === 65534 || n === 65535 ? -1 : n;
|
|
10739
|
+
}
|
|
10740
|
+
var PREDEFINED = { lt: "<", gt: ">", amp: "&", quot: '"', apos: "'" };
|
|
10741
|
+
var VALUE_PIECE = /&#x?[0-9A-Fa-f]+;|&[^;]+;|\r\n|[\t\n\r]/g;
|
|
10742
|
+
function attValueError(raw, base) {
|
|
10743
|
+
for (const m of raw.matchAll(VALUE_PIECE)) {
|
|
10744
|
+
const ref = m[0];
|
|
10745
|
+
if (!ref.startsWith("&")) continue;
|
|
10746
|
+
if (ref.startsWith("&#")) {
|
|
10747
|
+
if (charRefNumber(ref) < 0) return { message: XML_ERROR_BAD_CHAR_REF, offset: base + m.index };
|
|
10748
|
+
} else if (!Object.hasOwn(PREDEFINED, ref.slice(1, -1))) {
|
|
10749
|
+
return { message: XML_ERROR_UNDEFINED_ENTITY };
|
|
10750
|
+
}
|
|
10751
|
+
}
|
|
10752
|
+
return void 0;
|
|
10753
|
+
}
|
|
10754
|
+
function decodeAttValue(raw) {
|
|
10755
|
+
return raw.replace(VALUE_PIECE, (m) => {
|
|
10756
|
+
if (!m.startsWith("&")) return " ";
|
|
10757
|
+
if (m.startsWith("&#")) return String.fromCodePoint(charRefNumber(m));
|
|
10758
|
+
return PREDEFINED[m.slice(1, -1)];
|
|
10759
|
+
});
|
|
10760
|
+
}
|
|
10761
|
+
|
|
10675
10762
|
// src/common/htmltable-lex-expat.ts
|
|
10676
10763
|
var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
|
|
10677
10764
|
var XML_CONTEXT_BYTES = 1024;
|
|
10678
10765
|
var INIT_BUFFER_SIZE = 1024;
|
|
10679
|
-
var
|
|
10766
|
+
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
10767
|
+
var COMPLETE_END = (end, attError) => attError === void 0 ? { kind: "complete", end } : { kind: "complete", end, attError };
|
|
10680
10768
|
var PARTIAL = { kind: "partial" };
|
|
10681
10769
|
var INVALID = (offset) => ({ kind: "invalid", offset });
|
|
10682
10770
|
var XML_NAME = /^[A-Za-z_:\u0080-\uFFFF][\w.:\u0080-\uFFFF-]*/;
|
|
@@ -10687,25 +10775,25 @@ function skipSpace(text, i) {
|
|
|
10687
10775
|
return j;
|
|
10688
10776
|
}
|
|
10689
10777
|
var byteLength = (s) => new TextEncoder().encode(s).length;
|
|
10690
|
-
function
|
|
10691
|
-
|
|
10692
|
-
let text = unit.replace(/&([^;&<]*);/g, (m, name) => {
|
|
10778
|
+
function fedText(piece, endsUnit) {
|
|
10779
|
+
const text = piece.replace(/&([^;&<]*);/g, (m, name) => {
|
|
10693
10780
|
return name.length >= 2 && Object.hasOwn(HTML_ENTITIES, name) ? `&#${HTML_ENTITIES[name]};` : m;
|
|
10694
10781
|
});
|
|
10695
|
-
|
|
10696
|
-
|
|
10782
|
+
return endsUnit && text.endsWith("]") ? `${text.slice(0, -1)}]` : text;
|
|
10783
|
+
}
|
|
10784
|
+
function fedBytes(unit, isText) {
|
|
10785
|
+
return byteLength(isText ? fedText(unit, true) : unit);
|
|
10697
10786
|
}
|
|
10698
10787
|
function scanValue(text, j) {
|
|
10699
10788
|
const q = text[j];
|
|
10700
10789
|
if (q !== '"' && q !== "'") return INVALID(j);
|
|
10701
|
-
const
|
|
10702
|
-
if (
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
}
|
|
10790
|
+
const v = scanAttValue(text, j);
|
|
10791
|
+
if ("partial" in v) return PARTIAL;
|
|
10792
|
+
if ("invalid" in v) return INVALID(v.invalid);
|
|
10793
|
+
const close = v.close;
|
|
10706
10794
|
const next = skipSpace(text, close + 1);
|
|
10707
10795
|
if (next === close + 1 && !">/".includes(text[next] ?? ">")) return INVALID(next);
|
|
10708
|
-
return
|
|
10796
|
+
return close;
|
|
10709
10797
|
}
|
|
10710
10798
|
function scanPair(text, i) {
|
|
10711
10799
|
const name = XML_NAME.exec(text.slice(i))?.[0];
|
|
@@ -10715,8 +10803,9 @@ function scanPair(text, i) {
|
|
|
10715
10803
|
if (text[eq] !== "=") return INVALID(eq);
|
|
10716
10804
|
const j = skipSpace(text, eq + 1);
|
|
10717
10805
|
if (j >= text.length) return PARTIAL;
|
|
10718
|
-
const
|
|
10719
|
-
|
|
10806
|
+
const close = scanValue(text, j);
|
|
10807
|
+
if (typeof close !== "number") return close;
|
|
10808
|
+
return { name, next: skipSpace(text, close + 1), value: { start: j + 1, end: close } };
|
|
10720
10809
|
}
|
|
10721
10810
|
function tagEdge(text, i) {
|
|
10722
10811
|
const c = text[i];
|
|
@@ -10726,18 +10815,23 @@ function tagEdge(text, i) {
|
|
|
10726
10815
|
if (i + 1 >= text.length) return PARTIAL;
|
|
10727
10816
|
return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
|
|
10728
10817
|
}
|
|
10729
|
-
function
|
|
10818
|
+
function storeAttError(text, p, at, pair, seen) {
|
|
10819
|
+
if (seen.has(pair.name)) return { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: at };
|
|
10820
|
+
seen.add(pair.name);
|
|
10821
|
+
const err = attValueError(text.slice(pair.value.start, pair.value.end), pair.value.start);
|
|
10822
|
+
return err === void 0 ? void 0 : { message: err.message, offset: err.offset ?? p };
|
|
10823
|
+
}
|
|
10824
|
+
function scanAttributes(text, p, from) {
|
|
10730
10825
|
const seen = /* @__PURE__ */ new Set();
|
|
10731
|
-
let
|
|
10826
|
+
let attError;
|
|
10732
10827
|
let i = skipSpace(text, from);
|
|
10733
10828
|
for (; ; ) {
|
|
10734
10829
|
const edge = tagEdge(text, i);
|
|
10735
|
-
if (edge?.kind === "complete") return COMPLETE_END(edge.end,
|
|
10830
|
+
if (edge?.kind === "complete") return COMPLETE_END(edge.end, attError);
|
|
10736
10831
|
if (edge !== void 0) return edge;
|
|
10737
10832
|
const pair = scanPair(text, i);
|
|
10738
10833
|
if ("kind" in pair) return pair;
|
|
10739
|
-
|
|
10740
|
-
seen.add(pair.name);
|
|
10834
|
+
attError ??= storeAttError(text, p, i, pair, seen);
|
|
10741
10835
|
i = pair.next;
|
|
10742
10836
|
}
|
|
10743
10837
|
}
|
|
@@ -10752,7 +10846,7 @@ function scanStartTag(text, p) {
|
|
|
10752
10846
|
const c = text[name.next];
|
|
10753
10847
|
if (c === void 0) return PARTIAL;
|
|
10754
10848
|
if (!isSpace(c) && c !== ">" && c !== "/") return INVALID(name.next);
|
|
10755
|
-
return scanAttributes(text, name.next);
|
|
10849
|
+
return scanAttributes(text, p, name.next);
|
|
10756
10850
|
}
|
|
10757
10851
|
function scanEndTag(text, p) {
|
|
10758
10852
|
const name = scanName(text, p + 2);
|
|
@@ -10795,26 +10889,45 @@ function scanMarkup(text, p) {
|
|
|
10795
10889
|
if (c === "!") return { scan: scanDeclaration(text, p), kind: "tag" };
|
|
10796
10890
|
return { scan: scanStartTag(text, p), kind: "tag" };
|
|
10797
10891
|
}
|
|
10798
|
-
|
|
10892
|
+
var CDATA_OPEN = "<![CDATA[";
|
|
10893
|
+
var CDATA_CLOSE = "]]>";
|
|
10894
|
+
function scanCdata(text, p, base, dataOf, tokens) {
|
|
10895
|
+
const close = text.indexOf(CDATA_CLOSE, p);
|
|
10896
|
+
const end = close < 0 ? text.length : close;
|
|
10897
|
+
if (end > p) tokens.push({ kind: "cdata", start: base + p, end: base + end, data: dataOf(base + p, base + end) });
|
|
10898
|
+
return close < 0 ? -1 : close + CDATA_CLOSE.length;
|
|
10899
|
+
}
|
|
10900
|
+
function scanText(text, p, base, tokens) {
|
|
10901
|
+
const e = text.indexOf("<", p);
|
|
10902
|
+
const end = e < 0 ? text.length : e;
|
|
10903
|
+
tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
10904
|
+
return end;
|
|
10905
|
+
}
|
|
10906
|
+
function scanContent(text, base, inCdata, dataOf) {
|
|
10799
10907
|
const tokens = [];
|
|
10800
10908
|
let p = 0;
|
|
10909
|
+
let inSection = inCdata;
|
|
10801
10910
|
while (p < text.length) {
|
|
10911
|
+
if (inSection || text.startsWith(CDATA_OPEN, p)) {
|
|
10912
|
+
const after2 = scanCdata(text, inSection ? p : p + CDATA_OPEN.length, base, dataOf, tokens);
|
|
10913
|
+
if (after2 < 0) return { tokens, consumed: text.length, inCdata: true };
|
|
10914
|
+
inSection = false;
|
|
10915
|
+
p = after2;
|
|
10916
|
+
continue;
|
|
10917
|
+
}
|
|
10802
10918
|
if (text[p] !== "<") {
|
|
10803
|
-
|
|
10804
|
-
const end = e < 0 ? text.length : e;
|
|
10805
|
-
tokens.push({ kind: "text", start: base + p, end: base + end });
|
|
10806
|
-
p = end;
|
|
10919
|
+
p = scanText(text, p, base, tokens);
|
|
10807
10920
|
continue;
|
|
10808
10921
|
}
|
|
10809
10922
|
const { scan, kind } = scanMarkup(text, p);
|
|
10810
|
-
if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset };
|
|
10811
|
-
if (scan.kind === "partial") return { tokens, consumed: p };
|
|
10923
|
+
if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset, inCdata: false };
|
|
10924
|
+
if (scan.kind === "partial") return { tokens, consumed: p, inCdata: false };
|
|
10812
10925
|
const tok = { kind, start: base + p, end: base + scan.end };
|
|
10813
|
-
if (scan.
|
|
10926
|
+
if (scan.attError !== void 0) tok.attError = { ...scan.attError, offset: base + scan.attError.offset };
|
|
10814
10927
|
tokens.push(tok);
|
|
10815
10928
|
p = scan.end;
|
|
10816
10929
|
}
|
|
10817
|
-
return { tokens, consumed: p };
|
|
10930
|
+
return { tokens, consumed: p, inCdata: inSection };
|
|
10818
10931
|
}
|
|
10819
10932
|
var InputBuffer = class {
|
|
10820
10933
|
size = 0;
|
|
@@ -10865,38 +10978,61 @@ var ExpatFeed = class {
|
|
|
10865
10978
|
buffer = new InputBuffer();
|
|
10866
10979
|
heldStart = 0;
|
|
10867
10980
|
fedEnd = 0;
|
|
10981
|
+
inCdata = false;
|
|
10982
|
+
/** Source ranges of the text units fed so far: their bytes went through findNext's rewrite. */
|
|
10983
|
+
textUnits = [];
|
|
10868
10984
|
/** Start of the token expat still holds, or undefined when it holds nothing. */
|
|
10869
10985
|
get held() {
|
|
10870
10986
|
return this.heldStart < this.fedEnd ? this.heldStart : void 0;
|
|
10871
10987
|
}
|
|
10872
|
-
/** One `XML_Parse(parser, src[start, end), nbytes, 0)
|
|
10873
|
-
feed(start, end,
|
|
10874
|
-
this.
|
|
10988
|
+
/** One `XML_Parse(parser, src[start, end), nbytes, 0)`; `isText` for a text unit. */
|
|
10989
|
+
feed(start, end, isText) {
|
|
10990
|
+
if (isText) this.textUnits.push([start, end]);
|
|
10991
|
+
this.buffer.append(fedBytes(this.src.slice(start, end), isText));
|
|
10875
10992
|
this.fedEnd = end;
|
|
10876
10993
|
if (!this.buffer.enough) return { tokens: [] };
|
|
10877
10994
|
const text = this.src.slice(this.heldStart, end);
|
|
10878
|
-
const scan = scanContent(text, this.heldStart);
|
|
10995
|
+
const scan = scanContent(text, this.heldStart, this.inCdata, (a, b) => this.fedBetween(a, b));
|
|
10879
10996
|
if (scan.invalid !== void 0) {
|
|
10880
10997
|
return { tokens: scan.tokens, invalid: { message: XML_ERROR_INVALID_TOKEN, offset: scan.invalid } };
|
|
10881
10998
|
}
|
|
10999
|
+
this.inCdata = scan.inCdata;
|
|
10882
11000
|
this.heldStart += scan.consumed;
|
|
10883
11001
|
this.buffer.consumedTo(byteLength(this.src.slice(this.heldStart, end)), scan.consumed > 0);
|
|
10884
11002
|
return { tokens: scan.tokens };
|
|
10885
11003
|
}
|
|
11004
|
+
/** What expat read for source offsets [start, end): text-unit pieces as findNext rewrote them. */
|
|
11005
|
+
fedBetween(start, end) {
|
|
11006
|
+
let out = "";
|
|
11007
|
+
let p = start;
|
|
11008
|
+
for (const [us, ue] of this.textUnits) {
|
|
11009
|
+
if (ue <= p || us >= end) continue;
|
|
11010
|
+
if (us > p) out += this.src.slice(p, us);
|
|
11011
|
+
const e = Math.min(ue, end);
|
|
11012
|
+
out += fedText(this.src.slice(Math.max(us, p), e), e === ue);
|
|
11013
|
+
p = e;
|
|
11014
|
+
}
|
|
11015
|
+
return out + this.src.slice(p, end);
|
|
11016
|
+
}
|
|
10886
11017
|
};
|
|
10887
11018
|
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
10888
11019
|
var ENTITY_NAME = /^[A-Za-z_:][\w.:-]*$/;
|
|
10889
|
-
|
|
11020
|
+
var CHAR_REF = /^&#(?:x[0-9A-Fa-f]+|[0-9]+);/;
|
|
11021
|
+
function textRefError(text) {
|
|
10890
11022
|
for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
|
|
10891
|
-
if (text[t + 1] === "#")
|
|
11023
|
+
if (text[t + 1] === "#") {
|
|
11024
|
+
const ref = CHAR_REF.exec(text.slice(t))?.[0];
|
|
11025
|
+
if (ref !== void 0 && charRefNumber(ref) < 0) return { message: XML_ERROR_BAD_CHAR_REF, offset: t };
|
|
11026
|
+
continue;
|
|
11027
|
+
}
|
|
10892
11028
|
const semi = text.indexOf(";", t + 1);
|
|
10893
11029
|
if (semi < 0) continue;
|
|
10894
11030
|
const key = text.slice(t + 1, semi);
|
|
10895
11031
|
if (ENTITY_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
|
|
10896
|
-
return t;
|
|
11032
|
+
return { message: XML_ERROR_UNDEFINED_ENTITY, offset: t };
|
|
10897
11033
|
}
|
|
10898
11034
|
}
|
|
10899
|
-
return
|
|
11035
|
+
return void 0;
|
|
10900
11036
|
}
|
|
10901
11037
|
function parseTagChunk(chunk) {
|
|
10902
11038
|
if (!chunk.endsWith(">")) return void 0;
|
|
@@ -10907,6 +11043,46 @@ function parseTagChunk(chunk) {
|
|
|
10907
11043
|
return { close, selfClose: !close && body.endsWith("/"), name };
|
|
10908
11044
|
}
|
|
10909
11045
|
|
|
11046
|
+
// src/common/htmltable-lex-chardata.ts
|
|
11047
|
+
var initialCharData = () => ({ inCell: true, xb: "" });
|
|
11048
|
+
function startInCell(name, inCell) {
|
|
11049
|
+
if (name === "TABLE" || name === "TR" || name === "TH") return false;
|
|
11050
|
+
return name === "TD" ? true : inCell;
|
|
11051
|
+
}
|
|
11052
|
+
function endInCell(name, inCell) {
|
|
11053
|
+
if (name === "TABLE") return true;
|
|
11054
|
+
return name === "TD" ? false : inCell;
|
|
11055
|
+
}
|
|
11056
|
+
function tagInCell(st, tag) {
|
|
11057
|
+
const name = tag.name.toUpperCase();
|
|
11058
|
+
if (tag.close) {
|
|
11059
|
+
st.inCell = endInCell(name, st.inCell);
|
|
11060
|
+
return;
|
|
11061
|
+
}
|
|
11062
|
+
st.inCell = startInCell(name, st.inCell);
|
|
11063
|
+
if (tag.selfClose) st.inCell = endInCell(name, st.inCell);
|
|
11064
|
+
}
|
|
11065
|
+
function keepLostText(st, lost) {
|
|
11066
|
+
for (const t of lost) if (t.type === "text") st.xb += t.value;
|
|
11067
|
+
}
|
|
11068
|
+
function releaseXb(st, first) {
|
|
11069
|
+
if (st.xb === "") return;
|
|
11070
|
+
if (first.type === "text") first.value = st.xb + first.value;
|
|
11071
|
+
else if (first.type === "open" && first.tag === "TABLE") first.heldText = st.xb;
|
|
11072
|
+
else return;
|
|
11073
|
+
st.xb = "";
|
|
11074
|
+
}
|
|
11075
|
+
function cleanText(decoded) {
|
|
11076
|
+
return decoded.replace(/[\x00-\x1f]/g, "");
|
|
11077
|
+
}
|
|
11078
|
+
function textTokens(raw) {
|
|
11079
|
+
return charDataTokens(htmlEntityUTF8(raw));
|
|
11080
|
+
}
|
|
11081
|
+
function charDataTokens(decoded) {
|
|
11082
|
+
const clean = cleanText(decoded);
|
|
11083
|
+
return clean.length > 0 ? [{ type: "text", value: clean }] : [];
|
|
11084
|
+
}
|
|
11085
|
+
|
|
10910
11086
|
// src/common/htmltable-lex-units.ts
|
|
10911
11087
|
var UNCLOSED_COMMENT = "Warning: Unclosed comment\n";
|
|
10912
11088
|
var LABEL_CLOSED = "Warning: Label closed before end of HTML element\n";
|
|
@@ -10996,7 +11172,7 @@ function parseAttrPairs(raw) {
|
|
|
10996
11172
|
if (q !== '"' && q !== "'") throw new HtmlParseError(name);
|
|
10997
11173
|
const end = raw.indexOf(q, i + 1);
|
|
10998
11174
|
if (end < 0) throw new HtmlParseError(name);
|
|
10999
|
-
out.push([name, raw.slice(i + 1, end)]);
|
|
11175
|
+
out.push([name, decodeAttValue(raw.slice(i + 1, end))]);
|
|
11000
11176
|
i = end + 1;
|
|
11001
11177
|
}
|
|
11002
11178
|
return out;
|
|
@@ -11011,20 +11187,17 @@ function parseCloseToken(inner) {
|
|
|
11011
11187
|
checkTag(tag);
|
|
11012
11188
|
return { type: "close", tag: normalizeTag(tag) };
|
|
11013
11189
|
}
|
|
11014
|
-
|
|
11015
|
-
const isKeep = (c) => c === " " || c === " " || c === "\n" || c === "\r";
|
|
11016
|
-
return raw.replace(/[\x00-\x1f\x7f]/g, (c) => isKeep(c) ? c : "");
|
|
11017
|
-
}
|
|
11018
|
-
function textTokens(raw) {
|
|
11019
|
-
const clean = htmlEntityUTF8(cleanText(raw));
|
|
11020
|
-
return clean.length > 0 ? [{ type: "text", value: clean }] : [];
|
|
11021
|
-
}
|
|
11190
|
+
var EMPTY_ELEMENTS = /* @__PURE__ */ new Set(["BR", "HR", "VR", "IMG"]);
|
|
11022
11191
|
function tagTokens(text) {
|
|
11023
11192
|
const inner = text.slice(1, -1).trim();
|
|
11024
11193
|
if (inner.startsWith("/")) return [parseCloseToken(inner)];
|
|
11025
11194
|
if (inner.endsWith("/")) {
|
|
11026
11195
|
const open = parseOpenToken(inner.slice(0, -1).trim());
|
|
11027
|
-
return [open, { type: "close", tag: open.tag }];
|
|
11196
|
+
if (EMPTY_ELEMENTS.has(open.tag)) return [open, { type: "close", tag: open.tag }];
|
|
11197
|
+
const close = { type: "close", tag: open.tag };
|
|
11198
|
+
if (open.warnings !== void 0) close.warnings = open.warnings;
|
|
11199
|
+
if (open.warn === true) close.warn = true;
|
|
11200
|
+
return [close];
|
|
11028
11201
|
}
|
|
11029
11202
|
return [parseOpenToken(inner)];
|
|
11030
11203
|
}
|
|
@@ -11041,9 +11214,7 @@ function parseOpenToken(inner) {
|
|
|
11041
11214
|
checkTag(tag);
|
|
11042
11215
|
return openToken(normalizeTag(tag), sp === -1 ? "" : inner.slice(sp + 1));
|
|
11043
11216
|
}
|
|
11044
|
-
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
11045
11217
|
var XML_ERROR_TAG_MISMATCH = "mismatched tag";
|
|
11046
|
-
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
11047
11218
|
var SYNTAX_ERROR = "syntax error";
|
|
11048
11219
|
var HtmlLexError = class extends HtmlParseError {
|
|
11049
11220
|
diagnostics;
|
|
@@ -11086,7 +11257,8 @@ function checkTagToken(site) {
|
|
|
11086
11257
|
throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, tok.start), context);
|
|
11087
11258
|
}
|
|
11088
11259
|
} else {
|
|
11089
|
-
|
|
11260
|
+
const err = tok.attError;
|
|
11261
|
+
if (err !== void 0) throw htmlErrorInLine(err.message, lineAt(src, err.offset), context);
|
|
11090
11262
|
if (!tag.selfClose) st.stack.push(tag.name);
|
|
11091
11263
|
}
|
|
11092
11264
|
if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
|
|
@@ -11097,14 +11269,13 @@ function eventTokens(site) {
|
|
|
11097
11269
|
const { src, tok, st } = site;
|
|
11098
11270
|
const text = src.slice(tok.start, tok.end);
|
|
11099
11271
|
if (tok.kind === "comment" || tok.kind === "pi") return [];
|
|
11272
|
+
if (tok.kind === "cdata") return charDataTokens(tok.data ?? "");
|
|
11100
11273
|
if (tok.kind === "tag") {
|
|
11101
11274
|
checkTagToken(site);
|
|
11102
11275
|
return tagTokens(text);
|
|
11103
11276
|
}
|
|
11104
|
-
const
|
|
11105
|
-
if (
|
|
11106
|
-
throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, tok.start + off), st.prev + st.curr);
|
|
11107
|
-
}
|
|
11277
|
+
const err = textRefError(text);
|
|
11278
|
+
if (err !== void 0) throw htmlErrorInLine(err.message, lineAt(src, tok.start + err.offset), st.prev + st.curr);
|
|
11108
11279
|
return textTokens(text);
|
|
11109
11280
|
}
|
|
11110
11281
|
function attachCarry(carry, first) {
|
|
@@ -11122,7 +11293,13 @@ function absorb(carry, lost) {
|
|
|
11122
11293
|
function eventGroups(run, res) {
|
|
11123
11294
|
const groups = [];
|
|
11124
11295
|
for (const tok of res.tokens) {
|
|
11125
|
-
|
|
11296
|
+
let tokens = eventTokens({ src: run.src, tok, st: run.st });
|
|
11297
|
+
if (tok.kind === "tag") {
|
|
11298
|
+
const tag = parseTagChunk(run.src.slice(tok.start, tok.end));
|
|
11299
|
+
if (tag !== void 0) tagInCell(run.cd, tag);
|
|
11300
|
+
} else if (!run.cd.inCell) {
|
|
11301
|
+
tokens = [];
|
|
11302
|
+
}
|
|
11126
11303
|
if (tokens.length > 0) groups.push({ tokens, tok });
|
|
11127
11304
|
}
|
|
11128
11305
|
if (res.invalid !== void 0) {
|
|
@@ -11133,6 +11310,7 @@ function eventGroups(run, res) {
|
|
|
11133
11310
|
}
|
|
11134
11311
|
function deliver(run, last) {
|
|
11135
11312
|
const first = last.tokens[0];
|
|
11313
|
+
releaseXb(run.cd, first);
|
|
11136
11314
|
attachCarry(run.carry, first);
|
|
11137
11315
|
const info = { src: run.src, pos: last.tok.start, end: last.tok.end, context: run.st.prev + run.st.curr };
|
|
11138
11316
|
const prev = run.tokens.at(-1);
|
|
@@ -11147,7 +11325,10 @@ function deliver(run, last) {
|
|
|
11147
11325
|
function runEvents(run, res) {
|
|
11148
11326
|
const groups = eventGroups(run, res);
|
|
11149
11327
|
const last = groups.pop();
|
|
11150
|
-
for (const g of groups)
|
|
11328
|
+
for (const g of groups) {
|
|
11329
|
+
absorb(run.carry, g.tokens);
|
|
11330
|
+
keepLostText(run.cd, g.tokens);
|
|
11331
|
+
}
|
|
11151
11332
|
if (last !== void 0) deliver(run, last);
|
|
11152
11333
|
}
|
|
11153
11334
|
function appendString(into, more) {
|
|
@@ -11178,7 +11359,8 @@ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
|
|
|
11178
11359
|
tokens: [],
|
|
11179
11360
|
st: { stack: [], prev: "", curr: "" },
|
|
11180
11361
|
expat: new ExpatFeed(src),
|
|
11181
|
-
carry: { warnings: [], warn: false }
|
|
11362
|
+
carry: { warnings: [], warn: false },
|
|
11363
|
+
cd: initialCharData()
|
|
11182
11364
|
};
|
|
11183
11365
|
let error;
|
|
11184
11366
|
try {
|
|
@@ -11187,8 +11369,7 @@ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
|
|
|
11187
11369
|
run.st.curr = src.slice(u.start, u.end);
|
|
11188
11370
|
run.carry.warnings.push(...u.warnings);
|
|
11189
11371
|
if (u.warn) run.carry.warn = true;
|
|
11190
|
-
|
|
11191
|
-
runEvents(run, run.expat.feed(u.start, u.end, nbytes));
|
|
11372
|
+
runEvents(run, run.expat.feed(u.start, u.end, !run.st.curr.startsWith("<")));
|
|
11192
11373
|
}
|
|
11193
11374
|
const held = run.expat.held;
|
|
11194
11375
|
if (held !== void 0) error = unfinishedError(run, held);
|
|
@@ -11204,9 +11385,6 @@ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
|
|
|
11204
11385
|
}
|
|
11205
11386
|
|
|
11206
11387
|
// src/common/htmltable-parse-attrs.ts
|
|
11207
|
-
function anchorAttr(v) {
|
|
11208
|
-
return v === void 0 ? void 0 : htmlEntityUTF8(v);
|
|
11209
|
-
}
|
|
11210
11388
|
var parseAlign = (v) => {
|
|
11211
11389
|
const u = v.toUpperCase();
|
|
11212
11390
|
if (u === "LEFT") return "left";
|
|
@@ -11214,6 +11392,7 @@ var parseAlign = (v) => {
|
|
|
11214
11392
|
if (u === "CENTER") return "center";
|
|
11215
11393
|
return void 0;
|
|
11216
11394
|
};
|
|
11395
|
+
var parseCellAlign = (v) => v.toUpperCase() === "TEXT" ? "text" : parseAlign(v);
|
|
11217
11396
|
var parseVAlign = (v) => {
|
|
11218
11397
|
const u = v.toUpperCase();
|
|
11219
11398
|
if (u === "TOP") return "top";
|
|
@@ -11247,7 +11426,7 @@ var buildCell = (content, a) => ({
|
|
|
11247
11426
|
kind: "cell",
|
|
11248
11427
|
content,
|
|
11249
11428
|
port: a["port"],
|
|
11250
|
-
align:
|
|
11429
|
+
align: parseCellAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
11251
11430
|
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
11252
11431
|
balign: parseAlign(a["balign"] !== void 0 ? a["balign"] : ""),
|
|
11253
11432
|
bgcolor: a["bgcolor"],
|
|
@@ -11263,9 +11442,9 @@ var buildCell = (content, a) => ({
|
|
|
11263
11442
|
fixedsize: parseFixedSize(a),
|
|
11264
11443
|
colspan: num(a["colspan"]),
|
|
11265
11444
|
rowspan: num(a["rowspan"]),
|
|
11266
|
-
href:
|
|
11445
|
+
href: a["href"],
|
|
11267
11446
|
title: parseTitle(a),
|
|
11268
|
-
target:
|
|
11447
|
+
target: a["target"],
|
|
11269
11448
|
id: a["id"]
|
|
11270
11449
|
});
|
|
11271
11450
|
var buildTable = (rows, a) => ({
|
|
@@ -11283,9 +11462,9 @@ var buildTable = (rows, a) => ({
|
|
|
11283
11462
|
fixedsize: parseFixedSize(a),
|
|
11284
11463
|
width: num(a["width"]),
|
|
11285
11464
|
height: num(a["height"]),
|
|
11286
|
-
href:
|
|
11465
|
+
href: a["href"],
|
|
11287
11466
|
title: parseTitle(a),
|
|
11288
|
-
target:
|
|
11467
|
+
target: a["target"],
|
|
11289
11468
|
id: a["id"],
|
|
11290
11469
|
port: a["port"],
|
|
11291
11470
|
sides: parseSides(a["sides"]),
|
|
@@ -11353,7 +11532,8 @@ var tableFont = (fontStack) => {
|
|
|
11353
11532
|
var MSG_SYNTAX_ERROR = "syntax error";
|
|
11354
11533
|
var MSG_TEXT_BEFORE_TABLE = "Syntax error: non-space string used before <TABLE>";
|
|
11355
11534
|
var MSG_TEXT_AFTER_TABLE = "Syntax error: non-space string used after </TABLE>";
|
|
11356
|
-
var nonSpace = (text) => /[^
|
|
11535
|
+
var nonSpace = (text) => /[^ ]/.test(text);
|
|
11536
|
+
var heldNonSpace = (tbl) => tbl?.type === "open" && nonSpace(tbl.heldText ?? "");
|
|
11357
11537
|
var parseError = (s, tok, message) => {
|
|
11358
11538
|
if (tok !== void 0) emitWarnings(s, tok);
|
|
11359
11539
|
else emitEof(s);
|
|
@@ -11374,41 +11554,29 @@ var applyBrTag = (s, t, fontStack, items) => {
|
|
|
11374
11554
|
items.push({ br: true, brAlign: parseAlign(t.attrs["align"] ?? ""), ...fontItemProps(font) });
|
|
11375
11555
|
consumeClose(s, "BR");
|
|
11376
11556
|
};
|
|
11377
|
-
var
|
|
11378
|
-
consume(s);
|
|
11379
|
-
const font = fontStack[fontStack.length - 1] ?? {};
|
|
11380
|
-
fontStack.push(mergeFontState(font, {
|
|
11381
|
-
fontColor: t.attrs["color"],
|
|
11382
|
-
fontFace: t.attrs["face"],
|
|
11383
|
-
fontSize: num(t.attrs["point-size"])
|
|
11384
|
-
}));
|
|
11557
|
+
var parseStyledText = (s, tag, fontStack, items) => {
|
|
11385
11558
|
const inner = parseText(s, fontStack);
|
|
11386
11559
|
fontStack.pop();
|
|
11387
|
-
items.push(...inner.items);
|
|
11388
11560
|
const nxt = peek(s);
|
|
11389
|
-
if (nxt?.type
|
|
11561
|
+
if (inner.items.length === 0 || nxt?.type !== "close" || nxt.tag !== tag) {
|
|
11562
|
+
throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
11563
|
+
}
|
|
11564
|
+
items.push(...inner.items);
|
|
11565
|
+
consume(s);
|
|
11390
11566
|
};
|
|
11391
|
-
var
|
|
11567
|
+
var applyStyleTag = (s, t, fontStack, items) => {
|
|
11392
11568
|
consume(s);
|
|
11393
|
-
const
|
|
11394
|
-
fontStack.push(mergeFontState(
|
|
11395
|
-
|
|
11396
|
-
fontStack.pop();
|
|
11397
|
-
items.push(...inner.items);
|
|
11398
|
-
const nxt = peek(s);
|
|
11399
|
-
if (nxt?.type === "close" && nxt.tag === t.tag) consume(s);
|
|
11569
|
+
const own = t.tag === "FONT" ? { fontColor: t.attrs["color"], fontFace: t.attrs["face"], fontSize: num(t.attrs["point-size"]) } : inlineFontState(t.tag, t.attrs);
|
|
11570
|
+
fontStack.push(mergeFontState(fontStack[fontStack.length - 1] ?? {}, own));
|
|
11571
|
+
parseStyledText(s, t.tag, fontStack, items);
|
|
11400
11572
|
};
|
|
11401
11573
|
var applyOpenTag = (s, t, fontStack, items) => {
|
|
11402
11574
|
if (t.tag === "BR") {
|
|
11403
11575
|
applyBrTag(s, t, fontStack, items);
|
|
11404
11576
|
return true;
|
|
11405
11577
|
}
|
|
11406
|
-
if (t.tag === "FONT") {
|
|
11407
|
-
|
|
11408
|
-
return true;
|
|
11409
|
-
}
|
|
11410
|
-
if (isInlineTag(t.tag)) {
|
|
11411
|
-
applyInlineTag(s, t, fontStack, items);
|
|
11578
|
+
if (t.tag === "FONT" || isInlineTag(t.tag)) {
|
|
11579
|
+
applyStyleTag(s, t, fontStack, items);
|
|
11412
11580
|
return true;
|
|
11413
11581
|
}
|
|
11414
11582
|
return false;
|
|
@@ -11451,7 +11619,7 @@ var parseFontTable = (s, open, fontStack) => {
|
|
|
11451
11619
|
fontStack.push(wrapperFont(open, fontStack));
|
|
11452
11620
|
const textBefore = skipStrings(s);
|
|
11453
11621
|
const tblTok = peek(s);
|
|
11454
|
-
if (textBefore && tblTok !== void 0) throw parseError(s, tblTok, MSG_TEXT_BEFORE_TABLE);
|
|
11622
|
+
if ((textBefore || heldNonSpace(tblTok)) && tblTok !== void 0) throw parseError(s, tblTok, MSG_TEXT_BEFORE_TABLE);
|
|
11455
11623
|
const table = parseTable(s, fontStack);
|
|
11456
11624
|
const textAfter = skipStrings(s);
|
|
11457
11625
|
const close = peek(s);
|
|
@@ -11468,11 +11636,11 @@ var rejectTableAfterTag = (s, start) => {
|
|
|
11468
11636
|
throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
11469
11637
|
}
|
|
11470
11638
|
};
|
|
11471
|
-
var parseImgContent = (s, t
|
|
11639
|
+
var parseImgContent = (s, t) => {
|
|
11472
11640
|
consume(s);
|
|
11473
11641
|
const img = {
|
|
11474
11642
|
kind: "image",
|
|
11475
|
-
src:
|
|
11643
|
+
src: t.attrs["src"] ?? "",
|
|
11476
11644
|
scale: t.attrs["scale"]
|
|
11477
11645
|
};
|
|
11478
11646
|
consumeClose(s, "IMG");
|
|
@@ -11480,7 +11648,7 @@ var parseImgContent = (s, t, cellAttrs) => {
|
|
|
11480
11648
|
};
|
|
11481
11649
|
var scanCellTable = (s, t, fontStack, st) => {
|
|
11482
11650
|
if (st.kind === "image" || st.kind === "table") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
11483
|
-
if (st.textNonSpace) throw parseError(s, t, MSG_TEXT_BEFORE_TABLE);
|
|
11651
|
+
if (st.textNonSpace || heldNonSpace(t)) throw parseError(s, t, MSG_TEXT_BEFORE_TABLE);
|
|
11484
11652
|
const tbl = parseTable(s, fontStack);
|
|
11485
11653
|
st.kind = "table";
|
|
11486
11654
|
return [tbl];
|
|
@@ -11500,12 +11668,12 @@ var scanAfterTable = (s, t, st) => {
|
|
|
11500
11668
|
if (nonSpace(t.value)) st.afterNonSpace = true;
|
|
11501
11669
|
return [];
|
|
11502
11670
|
};
|
|
11503
|
-
var scanCellImage = (s, t,
|
|
11671
|
+
var scanCellImage = (s, t, st) => {
|
|
11504
11672
|
if (st.kind !== "none") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
11505
11673
|
st.kind = "image";
|
|
11506
|
-
return [parseImgContent(s, t
|
|
11674
|
+
return [parseImgContent(s, t)];
|
|
11507
11675
|
};
|
|
11508
|
-
var scanCellItem = (s, t,
|
|
11676
|
+
var scanCellItem = (s, t, fontStack, st) => {
|
|
11509
11677
|
if (st.kind === "fonttable") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
11510
11678
|
if (st.kind === "table") return scanAfterTable(s, t, st);
|
|
11511
11679
|
const wrapper = st.kind === "none" ? fontTableWrapper(s) : void 0;
|
|
@@ -11514,7 +11682,7 @@ var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
|
|
|
11514
11682
|
return [parseFontTable(s, wrapper, fontStack)];
|
|
11515
11683
|
}
|
|
11516
11684
|
if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
|
|
11517
|
-
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t,
|
|
11685
|
+
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, st);
|
|
11518
11686
|
if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
11519
11687
|
return scanCellText(s, t, fontStack, st);
|
|
11520
11688
|
};
|
|
@@ -11524,12 +11692,12 @@ var endsCell = (s, t, st) => {
|
|
|
11524
11692
|
if (t.tag === "TD" && !afterText) return true;
|
|
11525
11693
|
throw parseError(s, t, afterText ? MSG_TEXT_AFTER_TABLE : MSG_SYNTAX_ERROR);
|
|
11526
11694
|
};
|
|
11527
|
-
var parseCellContent = (s,
|
|
11695
|
+
var parseCellContent = (s, fontStack) => {
|
|
11528
11696
|
const content = [];
|
|
11529
11697
|
const st = { kind: "none", textNonSpace: false, afterNonSpace: false };
|
|
11530
11698
|
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
11531
11699
|
if (endsCell(s, t, st)) break;
|
|
11532
|
-
content.push(...scanCellItem(s, t,
|
|
11700
|
+
content.push(...scanCellItem(s, t, fontStack, st));
|
|
11533
11701
|
}
|
|
11534
11702
|
const nxt = peek(s);
|
|
11535
11703
|
if (nxt?.type === "close" && nxt.tag === "TD") consume(s);
|
|
@@ -11537,7 +11705,7 @@ var parseCellContent = (s, cellAttrs, fontStack) => {
|
|
|
11537
11705
|
if (tbl !== void 0) return [tbl];
|
|
11538
11706
|
return content;
|
|
11539
11707
|
};
|
|
11540
|
-
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s,
|
|
11708
|
+
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s, fontStack), attrs);
|
|
11541
11709
|
var parseRowVr = (s, t, cells) => {
|
|
11542
11710
|
const prev = cells[cells.length - 1];
|
|
11543
11711
|
if (prev === void 0) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
@@ -11635,14 +11803,14 @@ var consumeRowHr = (s, rows) => {
|
|
|
11635
11803
|
var findFirstRealToken = (tokens, start) => {
|
|
11636
11804
|
for (let i = start; i < tokens.length; i++) {
|
|
11637
11805
|
const tk = tokens[i];
|
|
11638
|
-
if (tk.type !== "text" || tk.value
|
|
11806
|
+
if (tk.type !== "text" || nonSpace(tk.value)) return tk;
|
|
11639
11807
|
}
|
|
11640
11808
|
return void 0;
|
|
11641
11809
|
};
|
|
11642
11810
|
var skipLeadingWs = (s) => {
|
|
11643
11811
|
while (true) {
|
|
11644
11812
|
const nxt = peek(s);
|
|
11645
|
-
if (!nxt || nxt.type !== "text" || nxt.value
|
|
11813
|
+
if (!nxt || nxt.type !== "text" || nonSpace(nxt.value)) break;
|
|
11646
11814
|
consume(s);
|
|
11647
11815
|
}
|
|
11648
11816
|
};
|
|
@@ -11668,6 +11836,7 @@ var parseFontTableLabel = (s, open, fontStack) => {
|
|
|
11668
11836
|
};
|
|
11669
11837
|
var parseTableLabel = (s, fontStack) => {
|
|
11670
11838
|
skipLeadingWs(s);
|
|
11839
|
+
if (heldNonSpace(peek(s))) throw parseError(s, peek(s), MSG_TEXT_BEFORE_TABLE);
|
|
11671
11840
|
const table = parseTable(s, fontStack);
|
|
11672
11841
|
finishTableLabel(s);
|
|
11673
11842
|
return { kind: "table", table };
|
|
@@ -11697,17 +11866,9 @@ var parseTokens = (s) => {
|
|
|
11697
11866
|
if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
|
|
11698
11867
|
return parseTextLabel(s, fontStack);
|
|
11699
11868
|
};
|
|
11700
|
-
var parseHtmlLabelRv = (src,
|
|
11869
|
+
var parseHtmlLabelRv = (src, stderr) => {
|
|
11701
11870
|
const { tokens, error, eof } = tokenizeDeferred(`<HTML>${src}</HTML>`, { start: 6, end: 6 + src.length });
|
|
11702
|
-
const s = {
|
|
11703
|
-
tokens,
|
|
11704
|
-
pos: 0,
|
|
11705
|
-
pending: error,
|
|
11706
|
-
stderr: new StderrLines(writeLine),
|
|
11707
|
-
emitted: /* @__PURE__ */ new WeakSet(),
|
|
11708
|
-
warn: false,
|
|
11709
|
-
eof
|
|
11710
|
-
};
|
|
11871
|
+
const s = { tokens, pos: 0, pending: error, stderr, emitted: /* @__PURE__ */ new WeakSet(), warn: false, eof };
|
|
11711
11872
|
try {
|
|
11712
11873
|
const label = parseTokens(s);
|
|
11713
11874
|
if (error !== void 0) throw error;
|
|
@@ -11718,11 +11879,9 @@ var parseHtmlLabelRv = (src, writeLine = (line) => console.warn(line)) => {
|
|
|
11718
11879
|
throw error;
|
|
11719
11880
|
}
|
|
11720
11881
|
throw e;
|
|
11721
|
-
} finally {
|
|
11722
|
-
s.stderr?.flush();
|
|
11723
11882
|
}
|
|
11724
11883
|
};
|
|
11725
|
-
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, () => void 0).label;
|
|
11884
|
+
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, new StderrLines(() => void 0)).label;
|
|
11726
11885
|
|
|
11727
11886
|
// src/gvc/usershape.ts
|
|
11728
11887
|
var activeSizer = null;
|
|
@@ -11924,7 +12083,7 @@ var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
|
11924
12083
|
return { w, h };
|
|
11925
12084
|
};
|
|
11926
12085
|
var missingImages = /* @__PURE__ */ new WeakSet();
|
|
11927
|
-
var sizeHtmlImg = (img, imageSizer) => {
|
|
12086
|
+
var sizeHtmlImg = (img, { imageSizer, stderr }) => {
|
|
11928
12087
|
if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
|
|
11929
12088
|
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
11930
12089
|
if (sz !== null) {
|
|
@@ -11932,7 +12091,7 @@ var sizeHtmlImg = (img, imageSizer) => {
|
|
|
11932
12091
|
img.height = sz.h;
|
|
11933
12092
|
return 0;
|
|
11934
12093
|
}
|
|
11935
|
-
|
|
12094
|
+
agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
|
|
11936
12095
|
img.width = 0;
|
|
11937
12096
|
img.height = 0;
|
|
11938
12097
|
missingImages.add(img);
|
|
@@ -11945,7 +12104,7 @@ var sizeContentItem = (item, measurer, env) => {
|
|
|
11945
12104
|
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
11946
12105
|
}
|
|
11947
12106
|
if (item.kind === "image") {
|
|
11948
|
-
const rv = sizeHtmlImg(item, env
|
|
12107
|
+
const rv = sizeHtmlImg(item, env);
|
|
11949
12108
|
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
11950
12109
|
}
|
|
11951
12110
|
return { w: 0, h: 0, rv: 0 };
|
|
@@ -11975,14 +12134,14 @@ var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or
|
|
|
11975
12134
|
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
11976
12135
|
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
11977
12136
|
var sizeWarned = /* @__PURE__ */ new WeakSet();
|
|
11978
|
-
var fixedCellCheck = (cell2, sz, warn) => {
|
|
12137
|
+
var fixedCellCheck = (cell2, sz, warn, out) => {
|
|
11979
12138
|
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
11980
12139
|
if (cell2.width && cell2.height) {
|
|
11981
12140
|
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
11982
|
-
if (small && warn)
|
|
12141
|
+
if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
|
|
11983
12142
|
return { rv: small ? 1 : 0, zero: true };
|
|
11984
12143
|
}
|
|
11985
|
-
if (warn)
|
|
12144
|
+
if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
|
|
11986
12145
|
return { rv: 1, zero: false };
|
|
11987
12146
|
};
|
|
11988
12147
|
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
@@ -11998,7 +12157,7 @@ var getCellSize = (cell2, tbl, measurer, env) => {
|
|
|
11998
12157
|
let szy = ch + margin;
|
|
11999
12158
|
const warn = !sizeWarned.has(cell2);
|
|
12000
12159
|
sizeWarned.add(cell2);
|
|
12001
|
-
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn);
|
|
12160
|
+
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
|
|
12002
12161
|
rv |= fixed.rv;
|
|
12003
12162
|
if (fixed.zero) {
|
|
12004
12163
|
szx = 0;
|
|
@@ -12092,22 +12251,22 @@ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
|
|
|
12092
12251
|
const heights = setRowHeights(entries, nrows, spacing);
|
|
12093
12252
|
return { entries, widths, heights, spacing, border: border2, rv };
|
|
12094
12253
|
};
|
|
12095
|
-
var warnFixedTable = (tbl, dims) => {
|
|
12254
|
+
var warnFixedTable = (tbl, dims, out) => {
|
|
12096
12255
|
const warn = !sizeWarned.has(tbl);
|
|
12097
12256
|
sizeWarned.add(tbl);
|
|
12098
12257
|
if (tbl.fixedsize !== true) return 0;
|
|
12099
12258
|
if (tbl.width && tbl.height) {
|
|
12100
12259
|
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
12101
|
-
if (warn)
|
|
12260
|
+
if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
|
|
12102
12261
|
return 1;
|
|
12103
12262
|
}
|
|
12104
|
-
if (warn)
|
|
12263
|
+
if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
|
|
12105
12264
|
return 1;
|
|
12106
12265
|
};
|
|
12107
12266
|
var sizeTableBody = (tbl, measurer, env) => {
|
|
12108
12267
|
const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
12109
12268
|
if (entries.length === 0) {
|
|
12110
|
-
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }));
|
|
12269
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
|
|
12111
12270
|
tbl.dimen = { w: 0, h: 0 };
|
|
12112
12271
|
return rv | fixed2;
|
|
12113
12272
|
}
|
|
@@ -12117,7 +12276,7 @@ var sizeTableBody = (tbl, measurer, env) => {
|
|
|
12117
12276
|
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
|
|
12118
12277
|
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
12119
12278
|
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
12120
|
-
const fixed = warnFixedTable(tbl, { wd, ht });
|
|
12279
|
+
const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
|
|
12121
12280
|
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
12122
12281
|
tbl.dimen = {
|
|
12123
12282
|
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
@@ -17449,7 +17608,7 @@ function placeComplexRuns(runs, box, finfo, measurer) {
|
|
|
17449
17608
|
function alignContentBox(box, cell2, w, h) {
|
|
17450
17609
|
const out = { ll: { ...box.ll }, ur: { ...box.ur } };
|
|
17451
17610
|
const delx = out.ur.x - out.ll.x - w;
|
|
17452
|
-
if (delx > 0) {
|
|
17611
|
+
if (delx > 0 && cell2.align !== "text") {
|
|
17453
17612
|
if (cell2.align === "left") out.ur.x -= delx;
|
|
17454
17613
|
else if (cell2.align === "right") out.ll.x += delx;
|
|
17455
17614
|
else {
|
|
@@ -17704,21 +17863,25 @@ function posHtmlLabel(label, finfo, measurer) {
|
|
|
17704
17863
|
if (label.kind === "table") return withTableFont(env, label.table.font, "emit", () => posHtmlTable(label.table, env, measurer));
|
|
17705
17864
|
return posTextLabel(label, finfo, measurer);
|
|
17706
17865
|
}
|
|
17866
|
+
|
|
17867
|
+
// src/common/htmltable-label.ts
|
|
17707
17868
|
var HTML_PARSE_FATAL = 3;
|
|
17708
|
-
function
|
|
17869
|
+
function makeHtmlLabelTo(content, finfo, measurer, stderr) {
|
|
17709
17870
|
const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
|
|
17710
17871
|
let lbl, lexWarn;
|
|
17711
17872
|
try {
|
|
17712
|
-
({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content));
|
|
17873
|
+
({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content, stderr));
|
|
17713
17874
|
} catch (e) {
|
|
17714
|
-
if (e instanceof HtmlLexError) for (const line of e.diagnostics)
|
|
17875
|
+
if (e instanceof HtmlLexError) for (const line of e.diagnostics) stderr.write(`${line}
|
|
17876
|
+
`);
|
|
17715
17877
|
return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
|
|
17716
17878
|
}
|
|
17717
17879
|
if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
|
|
17718
17880
|
const rv = Number(lexWarn) | sizeHtmlLabel(lbl, measurer, {
|
|
17719
17881
|
fontsize,
|
|
17720
17882
|
fontname,
|
|
17721
|
-
imageSizer
|
|
17883
|
+
imageSizer,
|
|
17884
|
+
stderr
|
|
17722
17885
|
});
|
|
17723
17886
|
const placed = posHtmlLabel(lbl, { fontname, fontsize, fontcolor }, measurer);
|
|
17724
17887
|
const dim = lbl.dimen ?? { w: 0, h: 0 };
|
|
@@ -17917,8 +18080,11 @@ function makeLabel(text, fontname, fontsize, fontcolor, measurer) {
|
|
|
17917
18080
|
function makeAnyLabel(content, isHtml, font, measurer, obj) {
|
|
17918
18081
|
if (isHtml && content !== "") {
|
|
17919
18082
|
const imageSizer = obj !== void 0 ? rootOf(obj).info.gvc?.imageSizer : void 0;
|
|
17920
|
-
const
|
|
17921
|
-
|
|
18083
|
+
const stderr = labelStderr();
|
|
18084
|
+
const { label, rv } = makeHtmlLabelTo(content, { ...font, pencolor: getPenColor(obj), imageSizer }, measurer, stderr);
|
|
18085
|
+
if (rv !== 0 && obj !== void 0) stderr.write(`${inLabelOf(obj)}
|
|
18086
|
+
`);
|
|
18087
|
+
stderr.flush();
|
|
17922
18088
|
return label;
|
|
17923
18089
|
}
|
|
17924
18090
|
const subst2 = obj !== void 0 ? substObj(content, obj, false) : content;
|
|
@@ -24886,7 +25052,7 @@ function renderNodeLabel(n, coord, renderer, job) {
|
|
|
24886
25052
|
renderLabel(label, coord, renderer, job);
|
|
24887
25053
|
}
|
|
24888
25054
|
}
|
|
24889
|
-
function
|
|
25055
|
+
function anchorAttr(n, key) {
|
|
24890
25056
|
const v = nodeAttr(n, n.root, key);
|
|
24891
25057
|
return v !== void 0 && v !== "" ? v : void 0;
|
|
24892
25058
|
}
|
|
@@ -24896,13 +25062,13 @@ function resolveTooltip(n, tooltip) {
|
|
|
24896
25062
|
return label?.text ?? "";
|
|
24897
25063
|
}
|
|
24898
25064
|
function beginNodeAnchor(n, renderer, job) {
|
|
24899
|
-
const url =
|
|
24900
|
-
const tooltip =
|
|
25065
|
+
const url = anchorAttr(n, "href") ?? anchorAttr(n, "URL");
|
|
25066
|
+
const tooltip = anchorAttr(n, "tooltip");
|
|
24901
25067
|
if (url === void 0 && tooltip === void 0) return false;
|
|
24902
25068
|
renderer.beginAnchor?.(
|
|
24903
25069
|
url !== void 0 ? substObjAnchor(url, n) : "",
|
|
24904
25070
|
resolveTooltip(n, tooltip),
|
|
24905
|
-
|
|
25071
|
+
anchorAttr(n, "target") ?? "",
|
|
24906
25072
|
svgNodeId(n, job),
|
|
24907
25073
|
job
|
|
24908
25074
|
);
|