@knowvah/dot-engine 1.0.0 → 1.1.1
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/README.md +16 -0
- package/dist/api/index.d.ts +2 -2
- package/dist/api.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/gvc/anchor.d.ts.map +1 -1
- package/dist/gvc/device.d.ts +1 -1
- package/dist/gvc/device.d.ts.map +1 -1
- package/dist/index.js +226 -40
- package/dist/index.js.map +3 -3
- package/dist/layout/neato/init.d.ts.map +1 -1
- package/dist/layout/twopi/init.d.ts +0 -7
- package/dist/layout/twopi/init.d.ts.map +1 -1
- package/dist/render/index.d.ts +2 -2
- package/dist/render/map.d.ts +29 -7
- package/dist/render/map.d.ts.map +1 -1
- package/dist/render/public.d.ts +1 -1
- package/dist/render/xdot-public.d.ts +1 -1
- package/dist/render.js +226 -40
- package/dist/render.js.map +3 -3
- package/package.json +3 -1
- package/src/api/index.ts +2 -2
- package/src/common/textmeasure-factory.ts +1 -1
- package/src/errors.ts +1 -1
- package/src/gvc/anchor.ts +10 -2
- package/src/gvc/device.ts +10 -3
- package/src/index.ts +3 -3
- package/src/layout/neato/init.ts +13 -2
- package/src/layout/twopi/init.ts +7 -2
- package/src/render/index.ts +2 -2
- package/src/render/map.ts +295 -32
- package/src/render/public.ts +1 -1
- package/src/render/svg-graph.ts +1 -1
- package/src/render/xdot-public.ts +1 -1
package/dist/gvc/device.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/gvc/device.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAO,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/D,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAmF,MAAM,UAAU,CAAC;AAuBtH,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAE5F;AAcD,OAAO,QAAQ,UAAU,CAAC;IACxB,UAAU,SAAS;QACjB,0EAA0E;QAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;CACF;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,GAAG,KAAK,CAe9D;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,CAI7F;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,CAI1F;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAGtD;AA+DD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAwBnG;AA2BD,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CA8BlF;AAsBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,UAAU,GAAG,SAAS,EAC1B,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/gvc/device.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAO,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/D,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAmF,MAAM,UAAU,CAAC;AAuBtH,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAE5F;AAcD,OAAO,QAAQ,UAAU,CAAC;IACxB,UAAU,SAAS;QACjB,0EAA0E;QAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;CACF;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,GAAG,KAAK,CAe9D;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,CAI7F;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,CAI1F;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAGtD;AA+DD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAwBnG;AA2BD,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CA8BlF;AAsBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,UAAU,GAAG,SAAS,EAC1B,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,SAAS,EACd,UAAU,UAAO,GAChB,IAAI,CA8BN;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAIzF;AAkFD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAQvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CAyBtF;AA8BD;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,MAAM,CA2E9F"}
|
package/dist/index.js
CHANGED
|
@@ -24961,7 +24961,7 @@ function orthoRoundedPolylines(pts, radius) {
|
|
|
24961
24961
|
// src/render/svg-graph.ts
|
|
24962
24962
|
var SVG_XML_DECL = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n';
|
|
24963
24963
|
var SVG_DOCTYPE = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
|
|
24964
|
-
var SVG_GENERATOR_COMMENT = "<!-- Generated by
|
|
24964
|
+
var SVG_GENERATOR_COMMENT = "<!-- Generated by @knowvah/dot-engine -->\n";
|
|
24965
24965
|
var BGCOLOR_TRANSPARENT = "\0transparent";
|
|
24966
24966
|
function formatG(n) {
|
|
24967
24967
|
return String(parseFloat(n.toPrecision(6)));
|
|
@@ -25863,8 +25863,11 @@ function computeNodeUrlMap(n, obj, ctx) {
|
|
|
25863
25863
|
obj.urlMapPts = m.pts.map((p) => mapTransform(p, ctx));
|
|
25864
25864
|
}
|
|
25865
25865
|
function computeGraphUrlMap(obj, ctx) {
|
|
25866
|
-
const ll = { x:
|
|
25867
|
-
const ur = {
|
|
25866
|
+
const ll = { x: -ctx.pad.x, y: -ctx.pad.y };
|
|
25867
|
+
const ur = {
|
|
25868
|
+
x: ctx.bb.ur.x - ctx.bb.ll.x + ctx.pad.x,
|
|
25869
|
+
y: ctx.bb.ur.y - ctx.bb.ll.y + ctx.pad.y
|
|
25870
|
+
};
|
|
25868
25871
|
obj.urlMapShape = 0 /* Rectangle */;
|
|
25869
25872
|
obj.urlMapPts = [mapTransform(ll, ctx), mapTransform(ur, ctx)];
|
|
25870
25873
|
}
|
|
@@ -26101,7 +26104,7 @@ function walkNodesAndEdges(g, renderer, job, info) {
|
|
|
26101
26104
|
|
|
26102
26105
|
// src/gvc/device.ts
|
|
26103
26106
|
function renderClusterLabel(sg, renderer, job) {
|
|
26104
|
-
renderOneLabel(sg.info.label, renderer, job);
|
|
26107
|
+
renderOneLabel(sg.info.label, renderer, job, false);
|
|
26105
26108
|
}
|
|
26106
26109
|
function transformPoint(p, job) {
|
|
26107
26110
|
if ((job.flags & GVRENDER_DOES_TRANSFORM) !== 0) {
|
|
@@ -26208,8 +26211,9 @@ function labelSpanX(lp, just) {
|
|
|
26208
26211
|
if (just === "r") return lp.pos.x + lp.space.x / 2;
|
|
26209
26212
|
return lp.pos.x;
|
|
26210
26213
|
}
|
|
26211
|
-
function renderOneLabel(lp, renderer, job) {
|
|
26212
|
-
if (!lp
|
|
26214
|
+
function renderOneLabel(lp, renderer, job, requireSet = true) {
|
|
26215
|
+
if (!lp) return;
|
|
26216
|
+
if (requireSet && !lp.set) return;
|
|
26213
26217
|
if (lp.html) {
|
|
26214
26218
|
if (lp.u.kind === "html") {
|
|
26215
26219
|
const html = lp.u.html;
|
|
@@ -26232,7 +26236,7 @@ function renderNodeXLabel(n, renderer, job) {
|
|
|
26232
26236
|
}
|
|
26233
26237
|
function renderGraphLabel(g, renderer, job) {
|
|
26234
26238
|
setHtmlAnchorObj(svgGraphId(g, job), labelTextOf2(g.info.label), job.obj ?? void 0);
|
|
26235
|
-
renderOneLabel(g.info.label, renderer, job);
|
|
26239
|
+
renderOneLabel(g.info.label, renderer, job, false);
|
|
26236
26240
|
}
|
|
26237
26241
|
function renderClusterBox(sg, filled, renderer, job) {
|
|
26238
26242
|
const { ll, ur } = sg.info.bb;
|
|
@@ -26357,7 +26361,7 @@ function adviseHostFaithful() {
|
|
|
26357
26361
|
if (process.env?.GV_FONT_QUIET || !process.stderr?.isTTY) return;
|
|
26358
26362
|
adviceShown = true;
|
|
26359
26363
|
process.stderr.write(
|
|
26360
|
-
"
|
|
26364
|
+
"@knowvah/dot-engine: measuring text with built-in metrics (kerning/shaping not applied). For host-faithful sizing matching the rendering font, install `canvas` and call setTextMeasurer(new CanvasTextMeasurer(createCanvas(0,0).getContext('2d'))). Silence with GV_FONT_QUIET=1.\n"
|
|
26361
26365
|
);
|
|
26362
26366
|
}
|
|
26363
26367
|
function createMeasurer() {
|
|
@@ -39022,8 +39026,9 @@ function neatoInitNode(n, dim = DFLT_DIM) {
|
|
|
39022
39026
|
n.info.pos = pos;
|
|
39023
39027
|
}
|
|
39024
39028
|
if (n.info.UF_size === void 0) n.info.UF_size = 1;
|
|
39025
|
-
|
|
39026
|
-
if (!n.info.
|
|
39029
|
+
const plainShaped = n.info.shape?.name === "plain";
|
|
39030
|
+
if (!n.info.width && !plainShaped) n.info.width = 0.75;
|
|
39031
|
+
if (!n.info.height && !plainShaped) n.info.height = 0.5;
|
|
39027
39032
|
}
|
|
39028
39033
|
function userPos(n) {
|
|
39029
39034
|
const p = n.attrs.get("pos");
|
|
@@ -45623,8 +45628,9 @@ function makeRdata(INF) {
|
|
|
45623
45628
|
}
|
|
45624
45629
|
function twopiInitNode(n) {
|
|
45625
45630
|
if (!n.info.pos || n.info.pos.length < 2) n.info.pos = [0, 0];
|
|
45626
|
-
|
|
45627
|
-
if (!n.info.
|
|
45631
|
+
const plainShaped = n.info.shape?.name === "plain";
|
|
45632
|
+
if (!n.info.width && !plainShaped) n.info.width = 0.75;
|
|
45633
|
+
if (!n.info.height && !plainShaped) n.info.height = 0.5;
|
|
45628
45634
|
}
|
|
45629
45635
|
function twopiInitEdge(e) {
|
|
45630
45636
|
const wt = e.attrs.get("weight");
|
|
@@ -52097,73 +52103,253 @@ function createJsonRenderer() {
|
|
|
52097
52103
|
|
|
52098
52104
|
// src/render/map.ts
|
|
52099
52105
|
var DQ = '"';
|
|
52106
|
+
function exactDecimalDigits2(v) {
|
|
52107
|
+
const dv = new DataView(new ArrayBuffer(8));
|
|
52108
|
+
dv.setFloat64(0, Math.abs(v));
|
|
52109
|
+
const bits = dv.getBigUint64(0);
|
|
52110
|
+
const expBits = Number(bits >> 52n & 0x7ffn);
|
|
52111
|
+
const mant = bits & 0xfffffffffffffn;
|
|
52112
|
+
const m = expBits === 0 ? mant : mant | 1n << 52n;
|
|
52113
|
+
const e = (expBits === 0 ? 1 : expBits) - 1075;
|
|
52114
|
+
let intDigits;
|
|
52115
|
+
let fracLen = 0;
|
|
52116
|
+
if (e >= 0) {
|
|
52117
|
+
intDigits = (m << BigInt(e)).toString();
|
|
52118
|
+
} else {
|
|
52119
|
+
intDigits = (m * 5n ** BigInt(-e)).toString();
|
|
52120
|
+
fracLen = -e;
|
|
52121
|
+
}
|
|
52122
|
+
if (intDigits.length <= fracLen) {
|
|
52123
|
+
intDigits = "0".repeat(fracLen - intDigits.length + 1) + intDigits;
|
|
52124
|
+
}
|
|
52125
|
+
const pointPos = intDigits.length - fracLen;
|
|
52126
|
+
const firstSig = intDigits.search(/[1-9]/);
|
|
52127
|
+
return { digits: intDigits.slice(firstSig), exp10: pointPos - firstSig - 1 };
|
|
52128
|
+
}
|
|
52100
52129
|
function printG5(v) {
|
|
52101
|
-
|
|
52102
|
-
|
|
52103
|
-
|
|
52130
|
+
if (v === 0 || !Number.isFinite(v)) return String(v);
|
|
52131
|
+
const P = 5;
|
|
52132
|
+
const { digits, exp10 } = exactDecimalDigits2(v);
|
|
52133
|
+
let sig = digits.slice(0, P);
|
|
52134
|
+
if (sig.length < P) sig += "0".repeat(P - sig.length);
|
|
52135
|
+
const rest = digits.slice(P);
|
|
52136
|
+
const restNonzeroAfterFirst = /[1-9]/.test(rest.slice(1));
|
|
52137
|
+
const roundUp = rest.length > 0 && (rest[0] > "5" || rest[0] === "5" && restNonzeroAfterFirst || rest[0] === "5" && !restNonzeroAfterFirst && (sig.charCodeAt(P - 1) - 48) % 2 === 1);
|
|
52138
|
+
let exp = exp10;
|
|
52139
|
+
if (roundUp) {
|
|
52140
|
+
const n = String(BigInt(sig) + 1n);
|
|
52141
|
+
sig = n.length > P ? (exp++, n.slice(0, P)) : n;
|
|
52104
52142
|
}
|
|
52105
|
-
|
|
52143
|
+
const sign2 = v < 0 ? "-" : "";
|
|
52144
|
+
if (exp < -4 || exp >= P) {
|
|
52145
|
+
const mant = (sig[0] + "." + sig.slice(1)).replace(/\.?0+$/, "");
|
|
52146
|
+
const as = Math.abs(exp);
|
|
52147
|
+
return sign2 + mant + "e" + (exp < 0 ? "-" : "+") + (as < 10 ? "0" : "") + String(as);
|
|
52148
|
+
}
|
|
52149
|
+
let s;
|
|
52150
|
+
if (exp >= sig.length - 1) {
|
|
52151
|
+
s = sig + "0".repeat(exp - sig.length + 1);
|
|
52152
|
+
} else if (exp >= 0) {
|
|
52153
|
+
s = sig.slice(0, exp + 1) + "." + sig.slice(exp + 1);
|
|
52154
|
+
} else {
|
|
52155
|
+
s = "0." + "0".repeat(-exp - 1) + sig;
|
|
52156
|
+
}
|
|
52157
|
+
if (s.includes(".")) s = s.replace(/\.?0+$/, "");
|
|
52158
|
+
return sign2 + s;
|
|
52106
52159
|
}
|
|
52107
52160
|
function plainCoord(v) {
|
|
52108
52161
|
return printG5(v / 72);
|
|
52109
52162
|
}
|
|
52110
|
-
|
|
52111
|
-
|
|
52112
|
-
|
|
52163
|
+
var CANON_KEYWORDS = ["node", "edge", "strict", "graph", "digraph", "subgraph"];
|
|
52164
|
+
var MAX_OUTPUTLINE = 128;
|
|
52165
|
+
function isDigitByte(b) {
|
|
52166
|
+
return b >= 48 && b <= 57;
|
|
52167
|
+
}
|
|
52168
|
+
function isAlnumByte(b) {
|
|
52169
|
+
return isDigitByte(b) || b >= 65 && b <= 90 || b >= 97 && b <= 122;
|
|
52170
|
+
}
|
|
52171
|
+
function isIdCharByte(b) {
|
|
52172
|
+
return isAlnumByte(b) || b === 46 || b === 45 || b >= 128;
|
|
52113
52173
|
}
|
|
52114
|
-
function
|
|
52174
|
+
function isEscapeAt(bytes, i) {
|
|
52175
|
+
if (bytes[i] !== 92) return false;
|
|
52176
|
+
const c = bytes[i + 1];
|
|
52177
|
+
return c !== void 0 && 'EGHLNTlnr\\"'.includes(String.fromCharCode(c));
|
|
52178
|
+
}
|
|
52179
|
+
function agstrcanonText(arg) {
|
|
52180
|
+
if (arg.length === 0) return '""';
|
|
52181
|
+
const bytes = new TextEncoder().encode(arg);
|
|
52182
|
+
const out = [34];
|
|
52183
|
+
let needsQuotes = false;
|
|
52184
|
+
let partOfEscape = false;
|
|
52185
|
+
let backslashPending = false;
|
|
52186
|
+
let cnt = 0;
|
|
52187
|
+
let dotcnt = 0;
|
|
52188
|
+
let maybeNum = isDigitByte(bytes[0]) || bytes[0] === 46 || bytes[0] === 45;
|
|
52189
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
52190
|
+
const uc = bytes[i];
|
|
52191
|
+
if (uc === 34 && !partOfEscape) {
|
|
52192
|
+
out.push(92);
|
|
52193
|
+
needsQuotes = true;
|
|
52194
|
+
} else if (!partOfEscape && isEscapeAt(bytes, i)) {
|
|
52195
|
+
needsQuotes = true;
|
|
52196
|
+
partOfEscape = true;
|
|
52197
|
+
} else if (maybeNum) {
|
|
52198
|
+
if (uc === 45) {
|
|
52199
|
+
if (cnt) {
|
|
52200
|
+
maybeNum = false;
|
|
52201
|
+
needsQuotes = true;
|
|
52202
|
+
}
|
|
52203
|
+
} else if (uc === 46) {
|
|
52204
|
+
if (dotcnt++) {
|
|
52205
|
+
maybeNum = false;
|
|
52206
|
+
needsQuotes = true;
|
|
52207
|
+
}
|
|
52208
|
+
} else if (!isDigitByte(uc)) {
|
|
52209
|
+
maybeNum = false;
|
|
52210
|
+
needsQuotes = true;
|
|
52211
|
+
}
|
|
52212
|
+
partOfEscape = false;
|
|
52213
|
+
} else if (!(isAlnumByte(uc) || uc === 95 || uc >= 128)) {
|
|
52214
|
+
needsQuotes = true;
|
|
52215
|
+
partOfEscape = false;
|
|
52216
|
+
} else {
|
|
52217
|
+
partOfEscape = false;
|
|
52218
|
+
}
|
|
52219
|
+
out.push(uc);
|
|
52220
|
+
cnt++;
|
|
52221
|
+
const next = bytes[i + 1];
|
|
52222
|
+
if (next !== void 0) {
|
|
52223
|
+
const last = out[out.length - 1];
|
|
52224
|
+
const canBreak = !(isIdCharByte(last) || last === 92) && isIdCharByte(next);
|
|
52225
|
+
if (backslashPending && canBreak) {
|
|
52226
|
+
out.push(92, 10);
|
|
52227
|
+
needsQuotes = true;
|
|
52228
|
+
backslashPending = false;
|
|
52229
|
+
cnt = 0;
|
|
52230
|
+
} else if (cnt >= MAX_OUTPUTLINE) {
|
|
52231
|
+
if (canBreak) {
|
|
52232
|
+
out.push(92, 10);
|
|
52233
|
+
needsQuotes = true;
|
|
52234
|
+
cnt = 0;
|
|
52235
|
+
} else {
|
|
52236
|
+
backslashPending = true;
|
|
52237
|
+
}
|
|
52238
|
+
}
|
|
52239
|
+
}
|
|
52240
|
+
}
|
|
52241
|
+
out.push(34);
|
|
52242
|
+
const first = bytes[0];
|
|
52243
|
+
if (needsQuotes || cnt === 1 && (first === 46 || first === 45)) {
|
|
52244
|
+
return new TextDecoder().decode(new Uint8Array(out));
|
|
52245
|
+
}
|
|
52246
|
+
const lower = arg.toLowerCase();
|
|
52247
|
+
for (const tok of CANON_KEYWORDS) {
|
|
52248
|
+
if (tok === lower) return new TextDecoder().decode(new Uint8Array(out));
|
|
52249
|
+
}
|
|
52250
|
+
return arg;
|
|
52251
|
+
}
|
|
52252
|
+
function lateNN(v, def) {
|
|
52253
|
+
return v !== void 0 && v !== "" ? v : def;
|
|
52254
|
+
}
|
|
52255
|
+
function plainNodeFill(n, g) {
|
|
52256
|
+
const fillcolor = lateNN(nodeAttr(n, g, "fillcolor"), "");
|
|
52257
|
+
if (fillcolor !== "") return fillcolor;
|
|
52258
|
+
return lateNN(nodeAttr(n, g, "color"), "lightgrey");
|
|
52259
|
+
}
|
|
52260
|
+
function plainNodeLabel(n, g) {
|
|
52261
|
+
const lbl = n.info.label;
|
|
52262
|
+
const attr2 = nodeAttr(n, g, "label");
|
|
52263
|
+
if (lbl !== void 0 && lbl.u.kind === "html") {
|
|
52264
|
+
const a = attr2 ?? "";
|
|
52265
|
+
return "<" + (isHtmlValue(a) ? htmlValueContent(a) : a) + ">";
|
|
52266
|
+
}
|
|
52267
|
+
if (attr2 !== void 0 && isHtmlValue(attr2) && lbl !== void 0 && lbl.u.kind === "txt") {
|
|
52268
|
+
return agstrcanonText(htmlValueContent(attr2));
|
|
52269
|
+
}
|
|
52270
|
+
const shape = n.info.shape;
|
|
52271
|
+
if (shape !== void 0 && shape.kind === 2 /* SH_RECORD */) {
|
|
52272
|
+
return agstrcanonText(nodeAttr(n, g, "label") ?? "\\N");
|
|
52273
|
+
}
|
|
52274
|
+
const text = lbl !== void 0 ? lbl.text : n.attrs.get("label") ?? n.name;
|
|
52275
|
+
return agstrcanonText(text);
|
|
52276
|
+
}
|
|
52277
|
+
function plainNodeAttrs(n, g) {
|
|
52278
|
+
const shapeAttr = lateNN(nodeAttr(n, g, "shape"), "ellipse");
|
|
52279
|
+
const shapefile = nodeAttr(n, g, "shapefile");
|
|
52280
|
+
const shapeName = shapefile !== void 0 && shapefile !== "" && shapeAttr !== "epsf" ? "custom" : shapeAttr;
|
|
52115
52281
|
return {
|
|
52116
|
-
label:
|
|
52117
|
-
style: n
|
|
52118
|
-
shape:
|
|
52119
|
-
color: n
|
|
52120
|
-
fill: plainNodeFill(n)
|
|
52282
|
+
label: plainNodeLabel(n, g),
|
|
52283
|
+
style: lateNN(nodeAttr(n, g, "style"), "solid"),
|
|
52284
|
+
shape: shapeName,
|
|
52285
|
+
color: lateNN(nodeAttr(n, g, "color"), "black"),
|
|
52286
|
+
fill: plainNodeFill(n, g)
|
|
52121
52287
|
};
|
|
52122
52288
|
}
|
|
52123
|
-
function writePlainNode(n, out) {
|
|
52289
|
+
function writePlainNode(n, g, out) {
|
|
52124
52290
|
const x = plainCoord(n.info.coord.x);
|
|
52125
52291
|
const y = plainCoord(n.info.coord.y);
|
|
52126
52292
|
const w = printG5(n.info.width);
|
|
52127
52293
|
const h = printG5(n.info.height);
|
|
52128
|
-
const a = plainNodeAttrs(n);
|
|
52129
|
-
out.push("node " + n.name + " " + x + " " + y + " " + w + " " + h + " " + a.label + " " + a.style + " " + a.shape + " " + a.color + " " + a.fill + "\n");
|
|
52294
|
+
const a = plainNodeAttrs(n, g);
|
|
52295
|
+
out.push("node " + agstrcanonText(n.name) + " " + x + " " + y + " " + w + " " + h + " " + a.label + " " + a.style + " " + a.shape + " " + a.color + " " + a.fill + "\n");
|
|
52130
52296
|
}
|
|
52131
52297
|
function collectSplinePts(e) {
|
|
52132
52298
|
if (!e.info.spl) return [];
|
|
52133
52299
|
const pts = [];
|
|
52134
52300
|
for (const bz of e.info.spl.list) {
|
|
52135
|
-
for (
|
|
52301
|
+
for (let i = 0; i < bz.size; i++) pts.push(bz.list[i]);
|
|
52136
52302
|
}
|
|
52137
52303
|
return pts;
|
|
52138
52304
|
}
|
|
52139
|
-
function
|
|
52140
|
-
|
|
52305
|
+
function writeNodeAndPort(n, portname, out) {
|
|
52306
|
+
let name = n.name;
|
|
52307
|
+
if (n.info.clustnode) {
|
|
52308
|
+
const i = name.indexOf(":");
|
|
52309
|
+
if (i >= 0) name = name.slice(i + 1);
|
|
52310
|
+
}
|
|
52311
|
+
out.push(" " + agstrcanonText(name));
|
|
52312
|
+
if (portname !== "") out.push(":" + agstrcanonText(portname));
|
|
52141
52313
|
}
|
|
52142
52314
|
function writePlainEdgeHead(e, tport, hport, pts, out) {
|
|
52143
|
-
out.push("edge
|
|
52315
|
+
out.push("edge");
|
|
52316
|
+
writeNodeAndPort(e.tail, tport, out);
|
|
52317
|
+
writeNodeAndPort(e.head, hport, out);
|
|
52318
|
+
out.push(" " + String(pts.length));
|
|
52144
52319
|
for (const pt of pts) {
|
|
52145
52320
|
out.push(" " + plainCoord(pt.x) + " " + plainCoord(pt.y));
|
|
52146
52321
|
}
|
|
52147
52322
|
}
|
|
52148
52323
|
function writePlainEdge(e, extend, out) {
|
|
52149
|
-
const tport = extend ?
|
|
52150
|
-
const hport = extend ?
|
|
52324
|
+
const tport = extend ? e.attrs.get("tailport") ?? "" : "";
|
|
52325
|
+
const hport = extend ? e.attrs.get("headport") ?? "" : "";
|
|
52151
52326
|
const pts = collectSplinePts(e);
|
|
52152
52327
|
if (pts.length > 0) writePlainEdgeHead(e, tport, hport, pts, out);
|
|
52153
|
-
const
|
|
52154
|
-
|
|
52328
|
+
const lbl = e.info.label;
|
|
52329
|
+
if (lbl !== void 0) {
|
|
52330
|
+
out.push(" " + agstrcanonText(lbl.text) + " " + plainCoord(lbl.pos.x) + " " + plainCoord(lbl.pos.y));
|
|
52331
|
+
}
|
|
52332
|
+
const style = lateNN(e.attrs.get("style"), "solid");
|
|
52333
|
+
const color = lateNN(e.attrs.get("color"), "black");
|
|
52155
52334
|
out.push(" " + style + " " + color + "\n");
|
|
52156
52335
|
}
|
|
52157
52336
|
function writePlain(g, job, extend) {
|
|
52158
52337
|
const w = plainCoord(g.info.bb.ur.x);
|
|
52159
52338
|
const h = plainCoord(g.info.bb.ur.y);
|
|
52160
|
-
|
|
52161
|
-
|
|
52339
|
+
const zoom = initJobViewportZoom(
|
|
52340
|
+
job.bb,
|
|
52341
|
+
parseDrawingSize(g.attrs.get("size")),
|
|
52342
|
+
{ x: 0, y: 0 }
|
|
52343
|
+
);
|
|
52344
|
+
job.write("graph " + printG5(zoom) + " " + w + " " + h + "\n");
|
|
52345
|
+
const nodes = nodesInSeq(g);
|
|
52346
|
+
for (const n of nodes) {
|
|
52347
|
+
if (n.info.clustnode) continue;
|
|
52162
52348
|
const buf = [];
|
|
52163
|
-
writePlainNode(n, buf);
|
|
52349
|
+
writePlainNode(n, g, buf);
|
|
52164
52350
|
job.write(buf.join(""));
|
|
52165
52351
|
}
|
|
52166
|
-
for (const
|
|
52352
|
+
for (const n of nodes) {
|
|
52167
52353
|
for (const e of n.outEdges(g)) {
|
|
52168
52354
|
const buf = [];
|
|
52169
52355
|
writePlainEdge(e, extend, buf);
|