@knowvah/dot-engine 2.6.7 → 2.6.9
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-expat.d.ts +15 -4
- 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 +3 -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/common/subst.d.ts +8 -0
- package/dist/common/subst.d.ts.map +1 -1
- package/dist/gvc/anchor.d.ts.map +1 -1
- package/dist/index.js +308 -105
- package/dist/index.js.map +4 -4
- package/dist/render/xml-escape.d.ts +8 -6
- package/dist/render/xml-escape.d.ts.map +1 -1
- package/dist/render.js +308 -105
- 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-expat.ts +59 -27
- package/src/common/htmltable-lex.ts +9 -10
- package/src/common/htmltable-parse-attrs.ts +10 -13
- package/src/common/htmltable-parse.ts +16 -29
- package/src/common/htmltable-pos.ts +5 -88
- package/src/common/htmltable-types.ts +4 -1
- package/src/common/htmltable.ts +16 -16
- package/src/common/make-label.ts +8 -3
- package/src/common/poly-gencode.ts +2 -2
- package/src/common/subst.ts +12 -0
- package/src/gvc/anchor.ts +6 -5
- package/src/render/xml-escape.ts +23 -33
package/dist/render.js
CHANGED
|
@@ -5653,9 +5653,11 @@ var StderrLines = class {
|
|
|
5653
5653
|
writeLine;
|
|
5654
5654
|
pending = "";
|
|
5655
5655
|
write(text) {
|
|
5656
|
-
|
|
5657
|
-
this.pending
|
|
5658
|
-
|
|
5656
|
+
this.pending += text;
|
|
5657
|
+
if (!this.pending.endsWith("\n")) return;
|
|
5658
|
+
const line = this.pending.slice(0, -1);
|
|
5659
|
+
this.pending = "";
|
|
5660
|
+
this.writeLine(line);
|
|
5659
5661
|
}
|
|
5660
5662
|
flush() {
|
|
5661
5663
|
if (this.pending === "") return;
|
|
@@ -5663,6 +5665,16 @@ var StderrLines = class {
|
|
|
5663
5665
|
this.pending = "";
|
|
5664
5666
|
}
|
|
5665
5667
|
};
|
|
5668
|
+
var consoleLine = (line) => {
|
|
5669
|
+
if (line.startsWith("Warning")) console.warn(line);
|
|
5670
|
+
else console.error(line);
|
|
5671
|
+
};
|
|
5672
|
+
var labelStderr = () => new StderrLines(consoleLine);
|
|
5673
|
+
var agerrLine = (out, msg) => {
|
|
5674
|
+
if (out === void 0) consoleLine(msg);
|
|
5675
|
+
else out.write(`${msg}
|
|
5676
|
+
`);
|
|
5677
|
+
};
|
|
5666
5678
|
|
|
5667
5679
|
// src/common/htmltable-parse-state.ts
|
|
5668
5680
|
var peek = (s) => s.tokens[s.pos];
|
|
@@ -5967,11 +5979,87 @@ function htmlEntityUTF8(s) {
|
|
|
5967
5979
|
});
|
|
5968
5980
|
}
|
|
5969
5981
|
|
|
5982
|
+
// src/common/htmltable-lex-attvalue.ts
|
|
5983
|
+
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
5984
|
+
var XML_ERROR_BAD_CHAR_REF = "reference to invalid character number";
|
|
5985
|
+
var NAME_START = /[A-Za-z_:\u0080-]/;
|
|
5986
|
+
var NAME_CHAR = /[\w.:\u0080--]/;
|
|
5987
|
+
var DEC_DIGIT = /[0-9]/;
|
|
5988
|
+
var HEX_DIGIT = /[0-9A-Fa-f]/;
|
|
5989
|
+
var NON_XML = /[\x00-\x08\x0b\x0c\x0e-\x1f]/;
|
|
5990
|
+
function scanDigits(text, i, digit) {
|
|
5991
|
+
if (i >= text.length) return { partial: true };
|
|
5992
|
+
if (!digit.test(text[i])) return { invalid: i };
|
|
5993
|
+
for (let k = i + 1; k < text.length; k++) {
|
|
5994
|
+
if (text[k] === ";") return k + 1;
|
|
5995
|
+
if (!digit.test(text[k])) return { invalid: k };
|
|
5996
|
+
}
|
|
5997
|
+
return { partial: true };
|
|
5998
|
+
}
|
|
5999
|
+
function scanRef(text, i) {
|
|
6000
|
+
const c = text[i];
|
|
6001
|
+
if (c === void 0) return { partial: true };
|
|
6002
|
+
if (c === "#") return text[i + 1] === "x" ? scanDigits(text, i + 2, HEX_DIGIT) : scanDigits(text, i + 1, DEC_DIGIT);
|
|
6003
|
+
if (!NAME_START.test(c)) return { invalid: i };
|
|
6004
|
+
for (let k = i + 1; k < text.length; k++) {
|
|
6005
|
+
if (text[k] === ";") return k + 1;
|
|
6006
|
+
if (!NAME_CHAR.test(text[k])) return { invalid: k };
|
|
6007
|
+
}
|
|
6008
|
+
return { partial: true };
|
|
6009
|
+
}
|
|
6010
|
+
function scanAttValue(text, j) {
|
|
6011
|
+
const q = text[j];
|
|
6012
|
+
let k = j + 1;
|
|
6013
|
+
for (; ; ) {
|
|
6014
|
+
const c = text[k];
|
|
6015
|
+
if (c === void 0) return { partial: true };
|
|
6016
|
+
if (c === q) return { close: k };
|
|
6017
|
+
if (c === "<" || NON_XML.test(c)) return { invalid: k };
|
|
6018
|
+
if (c !== "&") {
|
|
6019
|
+
k++;
|
|
6020
|
+
continue;
|
|
6021
|
+
}
|
|
6022
|
+
const r = scanRef(text, k + 1);
|
|
6023
|
+
if (typeof r !== "number") return r;
|
|
6024
|
+
k = r;
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
function charRefNumber(ref) {
|
|
6028
|
+
const hex = ref.startsWith("&#x");
|
|
6029
|
+
const n = parseInt(ref.slice(hex ? 3 : 2, -1), hex ? 16 : 10);
|
|
6030
|
+
if (n >= 1114112) return -1;
|
|
6031
|
+
if (n >= 55296 && n <= 57343) return -1;
|
|
6032
|
+
if (n < 32 && NON_XML.test(String.fromCharCode(n))) return -1;
|
|
6033
|
+
return n === 65534 || n === 65535 ? -1 : n;
|
|
6034
|
+
}
|
|
6035
|
+
var PREDEFINED = { lt: "<", gt: ">", amp: "&", quot: '"', apos: "'" };
|
|
6036
|
+
var VALUE_PIECE = /&#x?[0-9A-Fa-f]+;|&[^;]+;|\r\n|[\t\n\r]/g;
|
|
6037
|
+
function attValueError(raw, base) {
|
|
6038
|
+
for (const m of raw.matchAll(VALUE_PIECE)) {
|
|
6039
|
+
const ref = m[0];
|
|
6040
|
+
if (!ref.startsWith("&")) continue;
|
|
6041
|
+
if (ref.startsWith("&#")) {
|
|
6042
|
+
if (charRefNumber(ref) < 0) return { message: XML_ERROR_BAD_CHAR_REF, offset: base + m.index };
|
|
6043
|
+
} else if (!Object.hasOwn(PREDEFINED, ref.slice(1, -1))) {
|
|
6044
|
+
return { message: XML_ERROR_UNDEFINED_ENTITY };
|
|
6045
|
+
}
|
|
6046
|
+
}
|
|
6047
|
+
return void 0;
|
|
6048
|
+
}
|
|
6049
|
+
function decodeAttValue(raw) {
|
|
6050
|
+
return raw.replace(VALUE_PIECE, (m) => {
|
|
6051
|
+
if (!m.startsWith("&")) return " ";
|
|
6052
|
+
if (m.startsWith("&#")) return String.fromCodePoint(charRefNumber(m));
|
|
6053
|
+
return PREDEFINED[m.slice(1, -1)];
|
|
6054
|
+
});
|
|
6055
|
+
}
|
|
6056
|
+
|
|
5970
6057
|
// src/common/htmltable-lex-expat.ts
|
|
5971
6058
|
var XML_ERROR_INVALID_TOKEN = "not well-formed (invalid token)";
|
|
5972
6059
|
var XML_CONTEXT_BYTES = 1024;
|
|
5973
6060
|
var INIT_BUFFER_SIZE = 1024;
|
|
5974
|
-
var
|
|
6061
|
+
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
6062
|
+
var COMPLETE_END = (end, attError) => attError === void 0 ? { kind: "complete", end } : { kind: "complete", end, attError };
|
|
5975
6063
|
var PARTIAL = { kind: "partial" };
|
|
5976
6064
|
var INVALID = (offset) => ({ kind: "invalid", offset });
|
|
5977
6065
|
var XML_NAME = /^[A-Za-z_:\u0080-\uFFFF][\w.:\u0080-\uFFFF-]*/;
|
|
@@ -5994,14 +6082,13 @@ function fedBytes(unit, isText) {
|
|
|
5994
6082
|
function scanValue(text, j) {
|
|
5995
6083
|
const q = text[j];
|
|
5996
6084
|
if (q !== '"' && q !== "'") return INVALID(j);
|
|
5997
|
-
const
|
|
5998
|
-
if (
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
}
|
|
6085
|
+
const v = scanAttValue(text, j);
|
|
6086
|
+
if ("partial" in v) return PARTIAL;
|
|
6087
|
+
if ("invalid" in v) return INVALID(v.invalid);
|
|
6088
|
+
const close = v.close;
|
|
6002
6089
|
const next = skipSpace(text, close + 1);
|
|
6003
6090
|
if (next === close + 1 && !">/".includes(text[next] ?? ">")) return INVALID(next);
|
|
6004
|
-
return
|
|
6091
|
+
return close;
|
|
6005
6092
|
}
|
|
6006
6093
|
function scanPair(text, i) {
|
|
6007
6094
|
const name = XML_NAME.exec(text.slice(i))?.[0];
|
|
@@ -6011,8 +6098,9 @@ function scanPair(text, i) {
|
|
|
6011
6098
|
if (text[eq] !== "=") return INVALID(eq);
|
|
6012
6099
|
const j = skipSpace(text, eq + 1);
|
|
6013
6100
|
if (j >= text.length) return PARTIAL;
|
|
6014
|
-
const
|
|
6015
|
-
|
|
6101
|
+
const close = scanValue(text, j);
|
|
6102
|
+
if (typeof close !== "number") return close;
|
|
6103
|
+
return { name, next: skipSpace(text, close + 1), value: { start: j + 1, end: close } };
|
|
6016
6104
|
}
|
|
6017
6105
|
function tagEdge(text, i) {
|
|
6018
6106
|
const c = text[i];
|
|
@@ -6022,18 +6110,23 @@ function tagEdge(text, i) {
|
|
|
6022
6110
|
if (i + 1 >= text.length) return PARTIAL;
|
|
6023
6111
|
return text[i + 1] === ">" ? COMPLETE_END(i + 2) : void 0;
|
|
6024
6112
|
}
|
|
6025
|
-
function
|
|
6113
|
+
function storeAttError(text, p, at, pair, seen) {
|
|
6114
|
+
if (seen.has(pair.name)) return { message: XML_ERROR_DUPLICATE_ATTRIBUTE, offset: at };
|
|
6115
|
+
seen.add(pair.name);
|
|
6116
|
+
const err = attValueError(text.slice(pair.value.start, pair.value.end), pair.value.start);
|
|
6117
|
+
return err === void 0 ? void 0 : { message: err.message, offset: err.offset ?? p };
|
|
6118
|
+
}
|
|
6119
|
+
function scanAttributes(text, p, from) {
|
|
6026
6120
|
const seen = /* @__PURE__ */ new Set();
|
|
6027
|
-
let
|
|
6121
|
+
let attError;
|
|
6028
6122
|
let i = skipSpace(text, from);
|
|
6029
6123
|
for (; ; ) {
|
|
6030
6124
|
const edge = tagEdge(text, i);
|
|
6031
|
-
if (edge?.kind === "complete") return COMPLETE_END(edge.end,
|
|
6125
|
+
if (edge?.kind === "complete") return COMPLETE_END(edge.end, attError);
|
|
6032
6126
|
if (edge !== void 0) return edge;
|
|
6033
6127
|
const pair = scanPair(text, i);
|
|
6034
6128
|
if ("kind" in pair) return pair;
|
|
6035
|
-
|
|
6036
|
-
seen.add(pair.name);
|
|
6129
|
+
attError ??= storeAttError(text, p, i, pair, seen);
|
|
6037
6130
|
i = pair.next;
|
|
6038
6131
|
}
|
|
6039
6132
|
}
|
|
@@ -6048,7 +6141,7 @@ function scanStartTag(text, p) {
|
|
|
6048
6141
|
const c = text[name.next];
|
|
6049
6142
|
if (c === void 0) return PARTIAL;
|
|
6050
6143
|
if (!isSpace(c) && c !== ">" && c !== "/") return INVALID(name.next);
|
|
6051
|
-
return scanAttributes(text, name.next);
|
|
6144
|
+
return scanAttributes(text, p, name.next);
|
|
6052
6145
|
}
|
|
6053
6146
|
function scanEndTag(text, p) {
|
|
6054
6147
|
const name = scanName(text, p + 2);
|
|
@@ -6125,7 +6218,7 @@ function scanContent(text, base, inCdata, dataOf) {
|
|
|
6125
6218
|
if (scan.kind === "invalid") return { tokens, consumed: p, invalid: base + scan.offset, inCdata: false };
|
|
6126
6219
|
if (scan.kind === "partial") return { tokens, consumed: p, inCdata: false };
|
|
6127
6220
|
const tok = { kind, start: base + p, end: base + scan.end };
|
|
6128
|
-
if (scan.
|
|
6221
|
+
if (scan.attError !== void 0) tok.attError = { ...scan.attError, offset: base + scan.attError.offset };
|
|
6129
6222
|
tokens.push(tok);
|
|
6130
6223
|
p = scan.end;
|
|
6131
6224
|
}
|
|
@@ -6219,17 +6312,22 @@ var ExpatFeed = class {
|
|
|
6219
6312
|
};
|
|
6220
6313
|
var XML_PREDEFINED_ENTITIES = /* @__PURE__ */ new Set(["lt", "gt", "amp", "quot", "apos"]);
|
|
6221
6314
|
var ENTITY_NAME = /^[A-Za-z_:][\w.:-]*$/;
|
|
6222
|
-
|
|
6315
|
+
var CHAR_REF = /^&#(?:x[0-9A-Fa-f]+|[0-9]+);/;
|
|
6316
|
+
function textRefError(text) {
|
|
6223
6317
|
for (let t = text.indexOf("&"); t >= 0; t = text.indexOf("&", t + 1)) {
|
|
6224
|
-
if (text[t + 1] === "#")
|
|
6318
|
+
if (text[t + 1] === "#") {
|
|
6319
|
+
const ref = CHAR_REF.exec(text.slice(t))?.[0];
|
|
6320
|
+
if (ref !== void 0 && charRefNumber(ref) < 0) return { message: XML_ERROR_BAD_CHAR_REF, offset: t };
|
|
6321
|
+
continue;
|
|
6322
|
+
}
|
|
6225
6323
|
const semi = text.indexOf(";", t + 1);
|
|
6226
6324
|
if (semi < 0) continue;
|
|
6227
6325
|
const key = text.slice(t + 1, semi);
|
|
6228
6326
|
if (ENTITY_NAME.test(key) && !Object.hasOwn(HTML_ENTITIES, key) && !XML_PREDEFINED_ENTITIES.has(key)) {
|
|
6229
|
-
return t;
|
|
6327
|
+
return { message: XML_ERROR_UNDEFINED_ENTITY, offset: t };
|
|
6230
6328
|
}
|
|
6231
6329
|
}
|
|
6232
|
-
return
|
|
6330
|
+
return void 0;
|
|
6233
6331
|
}
|
|
6234
6332
|
function parseTagChunk(chunk) {
|
|
6235
6333
|
if (!chunk.endsWith(">")) return void 0;
|
|
@@ -6369,7 +6467,7 @@ function parseAttrPairs(raw) {
|
|
|
6369
6467
|
if (q !== '"' && q !== "'") throw new HtmlParseError(name);
|
|
6370
6468
|
const end = raw.indexOf(q, i + 1);
|
|
6371
6469
|
if (end < 0) throw new HtmlParseError(name);
|
|
6372
|
-
out.push([name, raw.slice(i + 1, end)]);
|
|
6470
|
+
out.push([name, decodeAttValue(raw.slice(i + 1, end))]);
|
|
6373
6471
|
i = end + 1;
|
|
6374
6472
|
}
|
|
6375
6473
|
return out;
|
|
@@ -6411,9 +6509,7 @@ function parseOpenToken(inner) {
|
|
|
6411
6509
|
checkTag(tag);
|
|
6412
6510
|
return openToken(normalizeTag(tag), sp === -1 ? "" : inner.slice(sp + 1));
|
|
6413
6511
|
}
|
|
6414
|
-
var XML_ERROR_UNDEFINED_ENTITY = "undefined entity";
|
|
6415
6512
|
var XML_ERROR_TAG_MISMATCH = "mismatched tag";
|
|
6416
|
-
var XML_ERROR_DUPLICATE_ATTRIBUTE = "duplicate attribute";
|
|
6417
6513
|
var SYNTAX_ERROR = "syntax error";
|
|
6418
6514
|
var HtmlLexError = class extends HtmlParseError {
|
|
6419
6515
|
diagnostics;
|
|
@@ -6456,7 +6552,8 @@ function checkTagToken(site) {
|
|
|
6456
6552
|
throw htmlErrorInLine(XML_ERROR_TAG_MISMATCH, lineAt(src, tok.start), context);
|
|
6457
6553
|
}
|
|
6458
6554
|
} else {
|
|
6459
|
-
|
|
6555
|
+
const err = tok.attError;
|
|
6556
|
+
if (err !== void 0) throw htmlErrorInLine(err.message, lineAt(src, err.offset), context);
|
|
6460
6557
|
if (!tag.selfClose) st.stack.push(tag.name);
|
|
6461
6558
|
}
|
|
6462
6559
|
if (KNOWN_TAGS.has(tag.name.toUpperCase())) return;
|
|
@@ -6472,10 +6569,8 @@ function eventTokens(site) {
|
|
|
6472
6569
|
checkTagToken(site);
|
|
6473
6570
|
return tagTokens(text);
|
|
6474
6571
|
}
|
|
6475
|
-
const
|
|
6476
|
-
if (
|
|
6477
|
-
throw htmlErrorInLine(XML_ERROR_UNDEFINED_ENTITY, lineAt(src, tok.start + off), st.prev + st.curr);
|
|
6478
|
-
}
|
|
6572
|
+
const err = textRefError(text);
|
|
6573
|
+
if (err !== void 0) throw htmlErrorInLine(err.message, lineAt(src, tok.start + err.offset), st.prev + st.curr);
|
|
6479
6574
|
return textTokens(text);
|
|
6480
6575
|
}
|
|
6481
6576
|
function attachCarry(carry, first) {
|
|
@@ -6585,9 +6680,6 @@ function tokenizeDeferred(src, label = { start: 0, end: src.length }) {
|
|
|
6585
6680
|
}
|
|
6586
6681
|
|
|
6587
6682
|
// src/common/htmltable-parse-attrs.ts
|
|
6588
|
-
function anchorAttr(v) {
|
|
6589
|
-
return v === void 0 ? void 0 : htmlEntityUTF8(v);
|
|
6590
|
-
}
|
|
6591
6683
|
var parseAlign = (v) => {
|
|
6592
6684
|
const u = v.toUpperCase();
|
|
6593
6685
|
if (u === "LEFT") return "left";
|
|
@@ -6595,6 +6687,7 @@ var parseAlign = (v) => {
|
|
|
6595
6687
|
if (u === "CENTER") return "center";
|
|
6596
6688
|
return void 0;
|
|
6597
6689
|
};
|
|
6690
|
+
var parseCellAlign = (v) => v.toUpperCase() === "TEXT" ? "text" : parseAlign(v);
|
|
6598
6691
|
var parseVAlign = (v) => {
|
|
6599
6692
|
const u = v.toUpperCase();
|
|
6600
6693
|
if (u === "TOP") return "top";
|
|
@@ -6628,7 +6721,7 @@ var buildCell = (content, a) => ({
|
|
|
6628
6721
|
kind: "cell",
|
|
6629
6722
|
content,
|
|
6630
6723
|
port: a["port"],
|
|
6631
|
-
align:
|
|
6724
|
+
align: parseCellAlign(a["align"] !== void 0 ? a["align"] : ""),
|
|
6632
6725
|
valign: parseVAlign(a["valign"] !== void 0 ? a["valign"] : ""),
|
|
6633
6726
|
balign: parseAlign(a["balign"] !== void 0 ? a["balign"] : ""),
|
|
6634
6727
|
bgcolor: a["bgcolor"],
|
|
@@ -6644,9 +6737,9 @@ var buildCell = (content, a) => ({
|
|
|
6644
6737
|
fixedsize: parseFixedSize(a),
|
|
6645
6738
|
colspan: num(a["colspan"]),
|
|
6646
6739
|
rowspan: num(a["rowspan"]),
|
|
6647
|
-
href:
|
|
6740
|
+
href: a["href"],
|
|
6648
6741
|
title: parseTitle(a),
|
|
6649
|
-
target:
|
|
6742
|
+
target: a["target"],
|
|
6650
6743
|
id: a["id"]
|
|
6651
6744
|
});
|
|
6652
6745
|
var buildTable = (rows, a) => ({
|
|
@@ -6664,9 +6757,9 @@ var buildTable = (rows, a) => ({
|
|
|
6664
6757
|
fixedsize: parseFixedSize(a),
|
|
6665
6758
|
width: num(a["width"]),
|
|
6666
6759
|
height: num(a["height"]),
|
|
6667
|
-
href:
|
|
6760
|
+
href: a["href"],
|
|
6668
6761
|
title: parseTitle(a),
|
|
6669
|
-
target:
|
|
6762
|
+
target: a["target"],
|
|
6670
6763
|
id: a["id"],
|
|
6671
6764
|
port: a["port"],
|
|
6672
6765
|
sides: parseSides(a["sides"]),
|
|
@@ -6838,11 +6931,11 @@ var rejectTableAfterTag = (s, start) => {
|
|
|
6838
6931
|
throw parseError(s, nxt, MSG_SYNTAX_ERROR);
|
|
6839
6932
|
}
|
|
6840
6933
|
};
|
|
6841
|
-
var parseImgContent = (s, t
|
|
6934
|
+
var parseImgContent = (s, t) => {
|
|
6842
6935
|
consume(s);
|
|
6843
6936
|
const img = {
|
|
6844
6937
|
kind: "image",
|
|
6845
|
-
src:
|
|
6938
|
+
src: t.attrs["src"] ?? "",
|
|
6846
6939
|
scale: t.attrs["scale"]
|
|
6847
6940
|
};
|
|
6848
6941
|
consumeClose(s, "IMG");
|
|
@@ -6870,12 +6963,12 @@ var scanAfterTable = (s, t, st) => {
|
|
|
6870
6963
|
if (nonSpace(t.value)) st.afterNonSpace = true;
|
|
6871
6964
|
return [];
|
|
6872
6965
|
};
|
|
6873
|
-
var scanCellImage = (s, t,
|
|
6966
|
+
var scanCellImage = (s, t, st) => {
|
|
6874
6967
|
if (st.kind !== "none") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
6875
6968
|
st.kind = "image";
|
|
6876
|
-
return [parseImgContent(s, t
|
|
6969
|
+
return [parseImgContent(s, t)];
|
|
6877
6970
|
};
|
|
6878
|
-
var scanCellItem = (s, t,
|
|
6971
|
+
var scanCellItem = (s, t, fontStack, st) => {
|
|
6879
6972
|
if (st.kind === "fonttable") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
6880
6973
|
if (st.kind === "table") return scanAfterTable(s, t, st);
|
|
6881
6974
|
const wrapper = st.kind === "none" ? fontTableWrapper(s) : void 0;
|
|
@@ -6884,7 +6977,7 @@ var scanCellItem = (s, t, cellAttrs, fontStack, st) => {
|
|
|
6884
6977
|
return [parseFontTable(s, wrapper, fontStack)];
|
|
6885
6978
|
}
|
|
6886
6979
|
if (t.type === "open" && t.tag === "TABLE") return scanCellTable(s, t, fontStack, st);
|
|
6887
|
-
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t,
|
|
6980
|
+
if (t.type === "open" && t.tag === "IMG") return scanCellImage(s, t, st);
|
|
6888
6981
|
if (st.kind === "image") throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
6889
6982
|
return scanCellText(s, t, fontStack, st);
|
|
6890
6983
|
};
|
|
@@ -6894,12 +6987,12 @@ var endsCell = (s, t, st) => {
|
|
|
6894
6987
|
if (t.tag === "TD" && !afterText) return true;
|
|
6895
6988
|
throw parseError(s, t, afterText ? MSG_TEXT_AFTER_TABLE : MSG_SYNTAX_ERROR);
|
|
6896
6989
|
};
|
|
6897
|
-
var parseCellContent = (s,
|
|
6990
|
+
var parseCellContent = (s, fontStack) => {
|
|
6898
6991
|
const content = [];
|
|
6899
6992
|
const st = { kind: "none", textNonSpace: false, afterNonSpace: false };
|
|
6900
6993
|
for (let t = peek(s); t !== void 0; t = peek(s)) {
|
|
6901
6994
|
if (endsCell(s, t, st)) break;
|
|
6902
|
-
content.push(...scanCellItem(s, t,
|
|
6995
|
+
content.push(...scanCellItem(s, t, fontStack, st));
|
|
6903
6996
|
}
|
|
6904
6997
|
const nxt = peek(s);
|
|
6905
6998
|
if (nxt?.type === "close" && nxt.tag === "TD") consume(s);
|
|
@@ -6907,7 +7000,7 @@ var parseCellContent = (s, cellAttrs, fontStack) => {
|
|
|
6907
7000
|
if (tbl !== void 0) return [tbl];
|
|
6908
7001
|
return content;
|
|
6909
7002
|
};
|
|
6910
|
-
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s,
|
|
7003
|
+
var parseCell = (s, attrs, fontStack) => buildCell(parseCellContent(s, fontStack), attrs);
|
|
6911
7004
|
var parseRowVr = (s, t, cells) => {
|
|
6912
7005
|
const prev = cells[cells.length - 1];
|
|
6913
7006
|
if (prev === void 0) throw parseError(s, t, MSG_SYNTAX_ERROR);
|
|
@@ -7068,17 +7161,9 @@ var parseTokens = (s) => {
|
|
|
7068
7161
|
if (firstReal?.type === "open" && firstReal.tag === "TABLE") return parseTableLabel(s, fontStack);
|
|
7069
7162
|
return parseTextLabel(s, fontStack);
|
|
7070
7163
|
};
|
|
7071
|
-
var parseHtmlLabelRv = (src,
|
|
7164
|
+
var parseHtmlLabelRv = (src, stderr) => {
|
|
7072
7165
|
const { tokens, error, eof } = tokenizeDeferred(`<HTML>${src}</HTML>`, { start: 6, end: 6 + src.length });
|
|
7073
|
-
const s = {
|
|
7074
|
-
tokens,
|
|
7075
|
-
pos: 0,
|
|
7076
|
-
pending: error,
|
|
7077
|
-
stderr: new StderrLines(writeLine),
|
|
7078
|
-
emitted: /* @__PURE__ */ new WeakSet(),
|
|
7079
|
-
warn: false,
|
|
7080
|
-
eof
|
|
7081
|
-
};
|
|
7166
|
+
const s = { tokens, pos: 0, pending: error, stderr, emitted: /* @__PURE__ */ new WeakSet(), warn: false, eof };
|
|
7082
7167
|
try {
|
|
7083
7168
|
const label = parseTokens(s);
|
|
7084
7169
|
if (error !== void 0) throw error;
|
|
@@ -7089,11 +7174,9 @@ var parseHtmlLabelRv = (src, writeLine = (line) => console.warn(line)) => {
|
|
|
7089
7174
|
throw error;
|
|
7090
7175
|
}
|
|
7091
7176
|
throw e;
|
|
7092
|
-
} finally {
|
|
7093
|
-
s.stderr?.flush();
|
|
7094
7177
|
}
|
|
7095
7178
|
};
|
|
7096
|
-
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, () => void 0).label;
|
|
7179
|
+
var parseHtmlLabel = (src) => parseHtmlLabelRv(src, new StderrLines(() => void 0)).label;
|
|
7097
7180
|
|
|
7098
7181
|
// src/gvc/usershape.ts
|
|
7099
7182
|
var activeSizer = null;
|
|
@@ -7289,7 +7372,7 @@ var sizeTextContent = (texts, measurer, env = defaultSizeEnv()) => {
|
|
|
7289
7372
|
return { w, h };
|
|
7290
7373
|
};
|
|
7291
7374
|
var missingImages = /* @__PURE__ */ new WeakSet();
|
|
7292
|
-
var sizeHtmlImg = (img, imageSizer) => {
|
|
7375
|
+
var sizeHtmlImg = (img, { imageSizer, stderr }) => {
|
|
7293
7376
|
if (img.width !== void 0 && img.height !== void 0) return missingImages.has(img) ? 1 : 0;
|
|
7294
7377
|
const sz = imageSizer !== void 0 ? imageSizer(img.src) : findImageSize(img.src);
|
|
7295
7378
|
if (sz !== null) {
|
|
@@ -7297,7 +7380,7 @@ var sizeHtmlImg = (img, imageSizer) => {
|
|
|
7297
7380
|
img.height = sz.h;
|
|
7298
7381
|
return 0;
|
|
7299
7382
|
}
|
|
7300
|
-
|
|
7383
|
+
agerrLine(stderr, `Error: No or improper image file="${img.src}"`);
|
|
7301
7384
|
img.width = 0;
|
|
7302
7385
|
img.height = 0;
|
|
7303
7386
|
missingImages.add(img);
|
|
@@ -7310,7 +7393,7 @@ var sizeContentItem = (item, measurer, env) => {
|
|
|
7310
7393
|
return { ...item.dimen !== void 0 ? item.dimen : { w: 0, h: 0 }, rv };
|
|
7311
7394
|
}
|
|
7312
7395
|
if (item.kind === "image") {
|
|
7313
|
-
const rv = sizeHtmlImg(item, env
|
|
7396
|
+
const rv = sizeHtmlImg(item, env);
|
|
7314
7397
|
return { w: item.width ?? 0, h: item.height ?? 0, rv };
|
|
7315
7398
|
}
|
|
7316
7399
|
return { w: 0, h: 0, rv: 0 };
|
|
@@ -7340,14 +7423,14 @@ var WARN_CELL_UNSPECIFIED = "Warning: fixed cell size with unspecified width or
|
|
|
7340
7423
|
var WARN_TABLE_TOO_SMALL = "Warning: table size too small for content";
|
|
7341
7424
|
var WARN_TABLE_UNSPECIFIED = "Warning: fixed table size with unspecified width or height";
|
|
7342
7425
|
var sizeWarned = /* @__PURE__ */ new WeakSet();
|
|
7343
|
-
var fixedCellCheck = (cell2, sz, warn) => {
|
|
7426
|
+
var fixedCellCheck = (cell2, sz, warn, out) => {
|
|
7344
7427
|
if (!cell2.fixedsize) return { rv: 0, zero: false };
|
|
7345
7428
|
if (cell2.width && cell2.height) {
|
|
7346
7429
|
const small = (cell2.width < sz.w || cell2.height < sz.h) && cell2.content[0]?.kind !== "image";
|
|
7347
|
-
if (small && warn)
|
|
7430
|
+
if (small && warn) agerrLine(out, WARN_CELL_TOO_SMALL);
|
|
7348
7431
|
return { rv: small ? 1 : 0, zero: true };
|
|
7349
7432
|
}
|
|
7350
|
-
if (warn)
|
|
7433
|
+
if (warn) agerrLine(out, WARN_CELL_UNSPECIFIED);
|
|
7351
7434
|
return { rv: 1, zero: false };
|
|
7352
7435
|
};
|
|
7353
7436
|
var getCellSize = (cell2, tbl, measurer, env) => {
|
|
@@ -7363,7 +7446,7 @@ var getCellSize = (cell2, tbl, measurer, env) => {
|
|
|
7363
7446
|
let szy = ch + margin;
|
|
7364
7447
|
const warn = !sizeWarned.has(cell2);
|
|
7365
7448
|
sizeWarned.add(cell2);
|
|
7366
|
-
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn);
|
|
7449
|
+
const fixed = fixedCellCheck(cell2, { w: szx, h: szy }, warn, env.stderr);
|
|
7367
7450
|
rv |= fixed.rv;
|
|
7368
7451
|
if (fixed.zero) {
|
|
7369
7452
|
szx = 0;
|
|
@@ -7457,22 +7540,22 @@ var layoutHtmlTable = (tbl, measurer, env = defaultSizeEnv()) => {
|
|
|
7457
7540
|
const heights = setRowHeights(entries, nrows, spacing);
|
|
7458
7541
|
return { entries, widths, heights, spacing, border: border2, rv };
|
|
7459
7542
|
};
|
|
7460
|
-
var warnFixedTable = (tbl, dims) => {
|
|
7543
|
+
var warnFixedTable = (tbl, dims, out) => {
|
|
7461
7544
|
const warn = !sizeWarned.has(tbl);
|
|
7462
7545
|
sizeWarned.add(tbl);
|
|
7463
7546
|
if (tbl.fixedsize !== true) return 0;
|
|
7464
7547
|
if (tbl.width && tbl.height) {
|
|
7465
7548
|
if (tbl.width >= dims.wd && tbl.height >= dims.ht) return 0;
|
|
7466
|
-
if (warn)
|
|
7549
|
+
if (warn) agerrLine(out, WARN_TABLE_TOO_SMALL);
|
|
7467
7550
|
return 1;
|
|
7468
7551
|
}
|
|
7469
|
-
if (warn)
|
|
7552
|
+
if (warn) agerrLine(out, WARN_TABLE_UNSPECIFIED);
|
|
7470
7553
|
return 1;
|
|
7471
7554
|
};
|
|
7472
7555
|
var sizeTableBody = (tbl, measurer, env) => {
|
|
7473
7556
|
const { entries, widths, heights, spacing, border: border2, rv } = layoutHtmlTable(tbl, measurer, env);
|
|
7474
7557
|
if (entries.length === 0) {
|
|
7475
|
-
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }));
|
|
7558
|
+
const fixed2 = warnFixedTable(tbl, sumTableDims({ widths, heights, ncols: 0, nrows: 0, spacing, border: border2 }), env.stderr);
|
|
7476
7559
|
tbl.dimen = { w: 0, h: 0 };
|
|
7477
7560
|
return rv | fixed2;
|
|
7478
7561
|
}
|
|
@@ -7482,7 +7565,7 @@ var sizeTableBody = (tbl, measurer, env) => {
|
|
|
7482
7565
|
const { wd, ht } = sumTableDims({ widths, heights, ncols, nrows, spacing, border: border2 });
|
|
7483
7566
|
const baseWd = tbl.width !== void 0 ? tbl.width : 0;
|
|
7484
7567
|
const baseHt = tbl.height !== void 0 ? tbl.height : 0;
|
|
7485
|
-
const fixed = warnFixedTable(tbl, { wd, ht });
|
|
7568
|
+
const fixed = warnFixedTable(tbl, { wd, ht }, env.stderr);
|
|
7486
7569
|
const zeroContent = isTblFixed(tbl) && baseWd !== 0 && baseHt !== 0;
|
|
7487
7570
|
tbl.dimen = {
|
|
7488
7571
|
w: Math.max(zeroContent ? 0 : wd, baseWd),
|
|
@@ -7687,7 +7770,7 @@ function placeComplexRuns(runs, box, finfo, measurer) {
|
|
|
7687
7770
|
function alignContentBox(box, cell2, w, h) {
|
|
7688
7771
|
const out = { ll: { ...box.ll }, ur: { ...box.ur } };
|
|
7689
7772
|
const delx = out.ur.x - out.ll.x - w;
|
|
7690
|
-
if (delx > 0) {
|
|
7773
|
+
if (delx > 0 && cell2.align !== "text") {
|
|
7691
7774
|
if (cell2.align === "left") out.ur.x -= delx;
|
|
7692
7775
|
else if (cell2.align === "right") out.ll.x += delx;
|
|
7693
7776
|
else {
|
|
@@ -7942,21 +8025,25 @@ function posHtmlLabel(label, finfo, measurer) {
|
|
|
7942
8025
|
if (label.kind === "table") return withTableFont(env, label.table.font, "emit", () => posHtmlTable(label.table, env, measurer));
|
|
7943
8026
|
return posTextLabel(label, finfo, measurer);
|
|
7944
8027
|
}
|
|
8028
|
+
|
|
8029
|
+
// src/common/htmltable-label.ts
|
|
7945
8030
|
var HTML_PARSE_FATAL = 3;
|
|
7946
|
-
function
|
|
8031
|
+
function makeHtmlLabelTo(content, finfo, measurer, stderr) {
|
|
7947
8032
|
const { fontname, fontsize, fontcolor, imageSizer, pencolor } = finfo;
|
|
7948
8033
|
let lbl, lexWarn;
|
|
7949
8034
|
try {
|
|
7950
|
-
({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content));
|
|
8035
|
+
({ label: lbl, warn: lexWarn } = parseHtmlLabelRv(content, stderr));
|
|
7951
8036
|
} catch (e) {
|
|
7952
|
-
if (e instanceof HtmlLexError) for (const line of e.diagnostics)
|
|
8037
|
+
if (e instanceof HtmlLexError) for (const line of e.diagnostics) stderr.write(`${line}
|
|
8038
|
+
`);
|
|
7953
8039
|
return { label: makeLabel("", fontname, fontsize, fontcolor, measurer), rv: HTML_PARSE_FATAL };
|
|
7954
8040
|
}
|
|
7955
8041
|
if (lbl.kind === "table") inheritTablePenColor(lbl.table, pencolor);
|
|
7956
8042
|
const rv = Number(lexWarn) | sizeHtmlLabel(lbl, measurer, {
|
|
7957
8043
|
fontsize,
|
|
7958
8044
|
fontname,
|
|
7959
|
-
imageSizer
|
|
8045
|
+
imageSizer,
|
|
8046
|
+
stderr
|
|
7960
8047
|
});
|
|
7961
8048
|
const placed = posHtmlLabel(lbl, { fontname, fontsize, fontcolor }, measurer);
|
|
7962
8049
|
const dim = lbl.dimen ?? { w: 0, h: 0 };
|
|
@@ -8349,6 +8436,9 @@ function interpretCRNL(str) {
|
|
|
8349
8436
|
}
|
|
8350
8437
|
return out;
|
|
8351
8438
|
}
|
|
8439
|
+
function preprocessTooltip(s) {
|
|
8440
|
+
return interpretCRNL(htmlEntityUTF8(s));
|
|
8441
|
+
}
|
|
8352
8442
|
|
|
8353
8443
|
// src/model/graphInfo.ts
|
|
8354
8444
|
function makeGraphInfo() {
|
|
@@ -8593,8 +8683,11 @@ function makeLabel(text, fontname, fontsize, fontcolor, measurer) {
|
|
|
8593
8683
|
function makeAnyLabel(content, isHtml, font, measurer, obj) {
|
|
8594
8684
|
if (isHtml && content !== "") {
|
|
8595
8685
|
const imageSizer = obj !== void 0 ? rootOf(obj).info.gvc?.imageSizer : void 0;
|
|
8596
|
-
const
|
|
8597
|
-
|
|
8686
|
+
const stderr = labelStderr();
|
|
8687
|
+
const { label, rv } = makeHtmlLabelTo(content, { ...font, pencolor: getPenColor(obj), imageSizer }, measurer, stderr);
|
|
8688
|
+
if (rv !== 0 && obj !== void 0) stderr.write(`${inLabelOf(obj)}
|
|
8689
|
+
`);
|
|
8690
|
+
stderr.flush();
|
|
8598
8691
|
return label;
|
|
8599
8692
|
}
|
|
8600
8693
|
const subst2 = obj !== void 0 ? substObj(content, obj, false) : content;
|
|
@@ -15608,31 +15701,141 @@ function stripedBox(job, pts, clrs, rotate, renderer) {
|
|
|
15608
15701
|
return error;
|
|
15609
15702
|
}
|
|
15610
15703
|
|
|
15704
|
+
// src/util/xml.ts
|
|
15705
|
+
function gvXmlEscape(s, flags) {
|
|
15706
|
+
return XmlEscaper.escape(s, flags);
|
|
15707
|
+
}
|
|
15708
|
+
var XmlEscaper = class _XmlEscaper {
|
|
15709
|
+
static escape(s, flags) {
|
|
15710
|
+
let result = "";
|
|
15711
|
+
let previous = "";
|
|
15712
|
+
let pos = 0;
|
|
15713
|
+
while (pos < s.length) {
|
|
15714
|
+
const prev = s[pos];
|
|
15715
|
+
const [fragment, consumed] = _XmlEscaper.core(previous, s, pos, flags);
|
|
15716
|
+
result += fragment;
|
|
15717
|
+
previous = prev;
|
|
15718
|
+
pos += consumed;
|
|
15719
|
+
}
|
|
15720
|
+
return result;
|
|
15721
|
+
}
|
|
15722
|
+
/**
|
|
15723
|
+
* Escape one character/codepoint at s[pos].
|
|
15724
|
+
* Returns [escaped_fragment, characters_consumed].
|
|
15725
|
+
* Delegates to focused helpers to stay within CCN limit.
|
|
15726
|
+
* @see lib/util/xml.c:xml_core
|
|
15727
|
+
*/
|
|
15728
|
+
static core(previous, s, pos, flags) {
|
|
15729
|
+
const special = _XmlEscaper.coreSpecial(previous, s, pos, flags);
|
|
15730
|
+
if (special !== null) return special;
|
|
15731
|
+
const code = s.charCodeAt(pos);
|
|
15732
|
+
if (code > 127 && flags.utf8) return _XmlEscaper.utf8Entity(s, pos);
|
|
15733
|
+
return [s[pos], 1];
|
|
15734
|
+
}
|
|
15735
|
+
/**
|
|
15736
|
+
* Handle all the fixed-escape cases (& < > - space " ' \n \r).
|
|
15737
|
+
* Returns null when none of those cases applies.
|
|
15738
|
+
* @see lib/util/xml.c:xml_core
|
|
15739
|
+
*/
|
|
15740
|
+
static coreSpecial(previous, s, pos, flags) {
|
|
15741
|
+
const c = s[pos];
|
|
15742
|
+
if (c === "&" && (flags.raw || !_XmlEscaper.isEntity(s, pos))) {
|
|
15743
|
+
return ["&", 1];
|
|
15744
|
+
}
|
|
15745
|
+
if (c === "<") return ["<", 1];
|
|
15746
|
+
if (c === ">") return [">", 1];
|
|
15747
|
+
if (c === '"') return [""", 1];
|
|
15748
|
+
if (c === "'") return ["'", 1];
|
|
15749
|
+
if (c === "-" && flags.dash) return ["-", 1];
|
|
15750
|
+
if (c === " " && previous === " " && flags.nbsp) return [" ", 1];
|
|
15751
|
+
if (c === "\n" && flags.raw) return [" ", 1];
|
|
15752
|
+
if (c === "\r" && flags.raw) return [" ", 1];
|
|
15753
|
+
return null;
|
|
15754
|
+
}
|
|
15755
|
+
/**
|
|
15756
|
+
* Return true if s[pos] (which is '&') starts a valid XML entity:
|
|
15757
|
+
* &[A-Za-z]+; e.g. Ç
|
|
15758
|
+
* &#[0-9]*; e.g. &
|
|
15759
|
+
* &#x[0-9a-fA-F]*; e.g. 水
|
|
15760
|
+
* @see lib/util/xml.c:xml_isentity
|
|
15761
|
+
*/
|
|
15762
|
+
static isEntity(s, pos) {
|
|
15763
|
+
let i = pos + 1;
|
|
15764
|
+
if (i >= s.length || s[i] === ";") return false;
|
|
15765
|
+
i = s[i] === "#" ? _XmlEscaper.scanNumericRef(s, i) : _XmlEscaper.scanNamedRef(s, i);
|
|
15766
|
+
return i < s.length && s[i] === ";";
|
|
15767
|
+
}
|
|
15768
|
+
/** Scan a numeric entity body starting just after the '#'. */
|
|
15769
|
+
static scanNumericRef(s, hashPos) {
|
|
15770
|
+
let i = hashPos + 1;
|
|
15771
|
+
if (i < s.length && (s[i] === "x" || s[i] === "X")) {
|
|
15772
|
+
i++;
|
|
15773
|
+
while (i < s.length && _XmlEscaper.isXDigit(s[i])) i++;
|
|
15774
|
+
} else {
|
|
15775
|
+
while (i < s.length && _XmlEscaper.isDecDigit(s[i])) i++;
|
|
15776
|
+
}
|
|
15777
|
+
return i;
|
|
15778
|
+
}
|
|
15779
|
+
/** Scan a named entity body (alpha chars after the '&'). */
|
|
15780
|
+
static scanNamedRef(s, start) {
|
|
15781
|
+
let i = start;
|
|
15782
|
+
while (i < s.length && _XmlEscaper.isAlpha(s[i])) i++;
|
|
15783
|
+
return i;
|
|
15784
|
+
}
|
|
15785
|
+
/**
|
|
15786
|
+
* Emit &#xNNNN; for the Unicode code point at s[pos]. JS strings are
|
|
15787
|
+
* UTF-16, so the code point (what C decodes from UTF-8) comes from
|
|
15788
|
+
* codePointAt, and an astral character consumes two units.
|
|
15789
|
+
* @see lib/util/xml.c:xml_core (UTF-8 block)
|
|
15790
|
+
*/
|
|
15791
|
+
static utf8Entity(s, pos) {
|
|
15792
|
+
const cp = _XmlEscaper.decodeUtf8(s, pos);
|
|
15793
|
+
const consumed = _XmlEscaper.utf8ByteLen(cp);
|
|
15794
|
+
return [`&#x${cp.toString(16)};`, consumed];
|
|
15795
|
+
}
|
|
15796
|
+
/**
|
|
15797
|
+
* Return the code point at s[pos]. A lone surrogate is the analogue of
|
|
15798
|
+
* malformed UTF-8, where C reports an error and exits (xml.c:135).
|
|
15799
|
+
* @see lib/util/xml.c:xml_core (fprintf + graphviz_exit at xml.c:135)
|
|
15800
|
+
*/
|
|
15801
|
+
static decodeUtf8(s, pos) {
|
|
15802
|
+
const cp = s.codePointAt(pos);
|
|
15803
|
+
if (cp >= 55296 && cp <= 57343) {
|
|
15804
|
+
throw new RenderError(`gvXmlEscape: malformed UTF-8 at position ${pos}`, "RENDER_ERROR");
|
|
15805
|
+
}
|
|
15806
|
+
return cp;
|
|
15807
|
+
}
|
|
15808
|
+
/**
|
|
15809
|
+
* Return how many UTF-16 units encode the code point (C: the UTF-8 byte
|
|
15810
|
+
* length from the leading byte).
|
|
15811
|
+
* @see lib/util/xml.c:xml_core (length computation)
|
|
15812
|
+
*/
|
|
15813
|
+
static utf8ByteLen(cp) {
|
|
15814
|
+
return cp > 65535 ? 2 : 1;
|
|
15815
|
+
}
|
|
15816
|
+
static isDecDigit(c) {
|
|
15817
|
+
return c >= "0" && c <= "9";
|
|
15818
|
+
}
|
|
15819
|
+
static isAlpha(c) {
|
|
15820
|
+
return c >= "a" && c <= "z" || c >= "A" && c <= "Z";
|
|
15821
|
+
}
|
|
15822
|
+
static isXDigit(c) {
|
|
15823
|
+
return _XmlEscaper.isDecDigit(c) || c >= "a" && c <= "f" || c >= "A" && c <= "F";
|
|
15824
|
+
}
|
|
15825
|
+
};
|
|
15826
|
+
|
|
15611
15827
|
// src/render/xml-escape.ts
|
|
15612
|
-
var
|
|
15613
|
-
var
|
|
15614
|
-
var
|
|
15828
|
+
var FLAGS_BASE = { raw: false, dash: false, nbsp: false, utf8: false };
|
|
15829
|
+
var FLAGS_TITLE = { raw: false, dash: true, nbsp: true, utf8: false };
|
|
15830
|
+
var FLAGS_TEXT = { raw: true, dash: true, nbsp: true, utf8: false };
|
|
15615
15831
|
function escapeXml(s) {
|
|
15616
|
-
|
|
15617
|
-
r = r.replace(/</g, "<");
|
|
15618
|
-
r = r.replace(/>/g, ">");
|
|
15619
|
-
r = r.replace(RE_DQUOTE, """);
|
|
15620
|
-
r = r.replace(RE_SQUOTE, "'");
|
|
15621
|
-
return r;
|
|
15832
|
+
return gvXmlEscape(s, FLAGS_BASE);
|
|
15622
15833
|
}
|
|
15623
15834
|
function escapeXmlTitle(s) {
|
|
15624
|
-
|
|
15625
|
-
r = r.replace(/-/g, "-");
|
|
15626
|
-
r = r.replace(/ {2,}/g, (m) => " " + " ".repeat(m.length - 1));
|
|
15627
|
-
return r;
|
|
15835
|
+
return gvXmlEscape(s, FLAGS_TITLE);
|
|
15628
15836
|
}
|
|
15629
15837
|
function escapeXmlText(s) {
|
|
15630
|
-
|
|
15631
|
-
r = r.replace(/-/g, "-");
|
|
15632
|
-
r = r.replace(/\n/g, " ");
|
|
15633
|
-
r = r.replace(/\r/g, " ");
|
|
15634
|
-
r = r.replace(/ {2,}/g, (m) => " " + " ".repeat(m.length - 1));
|
|
15635
|
-
return r;
|
|
15838
|
+
return gvXmlEscape(s, FLAGS_TEXT);
|
|
15636
15839
|
}
|
|
15637
15840
|
|
|
15638
15841
|
// src/gvc/device-cluster.ts
|
|
@@ -15808,23 +16011,23 @@ function renderNodeLabel(n, coord, renderer, job) {
|
|
|
15808
16011
|
renderLabel(label, coord, renderer, job);
|
|
15809
16012
|
}
|
|
15810
16013
|
}
|
|
15811
|
-
function
|
|
16014
|
+
function anchorAttr(n, key) {
|
|
15812
16015
|
const v = nodeAttr(n, n.root, key);
|
|
15813
16016
|
return v !== void 0 && v !== "" ? v : void 0;
|
|
15814
16017
|
}
|
|
15815
16018
|
function resolveTooltip(n, tooltip) {
|
|
15816
|
-
if (tooltip !== void 0) return substObjAnchor(
|
|
16019
|
+
if (tooltip !== void 0) return substObjAnchor(preprocessTooltip(tooltip), n);
|
|
15817
16020
|
const label = n.info.label;
|
|
15818
16021
|
return label?.text ?? "";
|
|
15819
16022
|
}
|
|
15820
16023
|
function beginNodeAnchor(n, renderer, job) {
|
|
15821
|
-
const url =
|
|
15822
|
-
const tooltip =
|
|
16024
|
+
const url = anchorAttr(n, "href") ?? anchorAttr(n, "URL");
|
|
16025
|
+
const tooltip = anchorAttr(n, "tooltip");
|
|
15823
16026
|
if (url === void 0 && tooltip === void 0) return false;
|
|
15824
16027
|
renderer.beginAnchor?.(
|
|
15825
16028
|
url !== void 0 ? substObjAnchor(url, n) : "",
|
|
15826
16029
|
resolveTooltip(n, tooltip),
|
|
15827
|
-
|
|
16030
|
+
anchorAttr(n, "target") ?? "",
|
|
15828
16031
|
svgNodeId(n, job),
|
|
15829
16032
|
job
|
|
15830
16033
|
);
|
|
@@ -19951,7 +20154,7 @@ function subst(s, obj) {
|
|
|
19951
20154
|
return substObjAnchor(s, obj);
|
|
19952
20155
|
}
|
|
19953
20156
|
function tip(s, obj) {
|
|
19954
|
-
return substObjAnchor(
|
|
20157
|
+
return substObjAnchor(preprocessTooltip(s), obj);
|
|
19955
20158
|
}
|
|
19956
20159
|
function textOf(lp) {
|
|
19957
20160
|
return lp?.text ?? null;
|