@lofcz/tikz 0.3.0 → 0.3.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/dist/worker.js CHANGED
@@ -802,21 +802,21 @@ var require_color_string = __commonJS({
802
802
  to: {},
803
803
  get: {}
804
804
  };
805
- cs.get = function(string2) {
806
- var prefix = string2.substring(0, 3).toLowerCase();
805
+ cs.get = function(string3) {
806
+ var prefix = string3.substring(0, 3).toLowerCase();
807
807
  var val;
808
808
  var model;
809
809
  switch (prefix) {
810
810
  case "hsl":
811
- val = cs.get.hsl(string2);
811
+ val = cs.get.hsl(string3);
812
812
  model = "hsl";
813
813
  break;
814
814
  case "hwb":
815
- val = cs.get.hwb(string2);
815
+ val = cs.get.hwb(string3);
816
816
  model = "hwb";
817
817
  break;
818
818
  default:
819
- val = cs.get.rgb(string2);
819
+ val = cs.get.rgb(string3);
820
820
  model = "rgb";
821
821
  break;
822
822
  }
@@ -825,8 +825,8 @@ var require_color_string = __commonJS({
825
825
  }
826
826
  return { model, value: val };
827
827
  };
828
- cs.get.rgb = function(string2) {
829
- if (!string2) {
828
+ cs.get.rgb = function(string3) {
829
+ if (!string3) {
830
830
  return null;
831
831
  }
832
832
  var abbr = /^#([a-f0-9]{3,4})$/i;
@@ -838,7 +838,7 @@ var require_color_string = __commonJS({
838
838
  var match2;
839
839
  var i;
840
840
  var hexAlpha;
841
- if (match2 = string2.match(hex)) {
841
+ if (match2 = string3.match(hex)) {
842
842
  hexAlpha = match2[2];
843
843
  match2 = match2[1];
844
844
  for (i = 0; i < 3; i++) {
@@ -848,7 +848,7 @@ var require_color_string = __commonJS({
848
848
  if (hexAlpha) {
849
849
  rgb[3] = parseInt(hexAlpha, 16) / 255;
850
850
  }
851
- } else if (match2 = string2.match(abbr)) {
851
+ } else if (match2 = string3.match(abbr)) {
852
852
  match2 = match2[1];
853
853
  hexAlpha = match2[3];
854
854
  for (i = 0; i < 3; i++) {
@@ -857,7 +857,7 @@ var require_color_string = __commonJS({
857
857
  if (hexAlpha) {
858
858
  rgb[3] = parseInt(hexAlpha + hexAlpha, 16) / 255;
859
859
  }
860
- } else if (match2 = string2.match(rgba)) {
860
+ } else if (match2 = string3.match(rgba)) {
861
861
  for (i = 0; i < 3; i++) {
862
862
  rgb[i] = parseInt(match2[i + 1], 0);
863
863
  }
@@ -868,7 +868,7 @@ var require_color_string = __commonJS({
868
868
  rgb[3] = parseFloat(match2[4]);
869
869
  }
870
870
  }
871
- } else if (match2 = string2.match(per)) {
871
+ } else if (match2 = string3.match(per)) {
872
872
  for (i = 0; i < 3; i++) {
873
873
  rgb[i] = Math.round(parseFloat(match2[i + 1]) * 2.55);
874
874
  }
@@ -879,7 +879,7 @@ var require_color_string = __commonJS({
879
879
  rgb[3] = parseFloat(match2[4]);
880
880
  }
881
881
  }
882
- } else if (match2 = string2.match(keyword)) {
882
+ } else if (match2 = string3.match(keyword)) {
883
883
  if (match2[1] === "transparent") {
884
884
  return [0, 0, 0, 0];
885
885
  }
@@ -898,12 +898,12 @@ var require_color_string = __commonJS({
898
898
  rgb[3] = clamp(rgb[3], 0, 1);
899
899
  return rgb;
900
900
  };
901
- cs.get.hsl = function(string2) {
902
- if (!string2) {
901
+ cs.get.hsl = function(string3) {
902
+ if (!string3) {
903
903
  return null;
904
904
  }
905
905
  var hsl = /^hsla?\(\s*([+-]?(?:\d{0,3}\.)?\d+)(?:deg)?\s*,?\s*([+-]?[\d\.]+)%\s*,?\s*([+-]?[\d\.]+)%\s*(?:[,|\/]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/;
906
- var match2 = string2.match(hsl);
906
+ var match2 = string3.match(hsl);
907
907
  if (match2) {
908
908
  var alpha = parseFloat(match2[4]);
909
909
  var h = (parseFloat(match2[1]) % 360 + 360) % 360;
@@ -914,12 +914,12 @@ var require_color_string = __commonJS({
914
914
  }
915
915
  return null;
916
916
  };
917
- cs.get.hwb = function(string2) {
918
- if (!string2) {
917
+ cs.get.hwb = function(string3) {
918
+ if (!string3) {
919
919
  return null;
920
920
  }
921
921
  var hwb = /^hwb\(\s*([+-]?\d{0,3}(?:\.\d+)?)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/;
922
- var match2 = string2.match(hwb);
922
+ var match2 = string3.match(hwb);
923
923
  if (match2) {
924
924
  var alpha = parseFloat(match2[4]);
925
925
  var h = (parseFloat(match2[1]) % 360 + 360) % 360;
@@ -1450,8 +1450,8 @@ var require_conversions = __commonJS({
1450
1450
  };
1451
1451
  convert.rgb.hex = function(args) {
1452
1452
  const integer = ((Math.round(args[0]) & 255) << 16) + ((Math.round(args[1]) & 255) << 8) + (Math.round(args[2]) & 255);
1453
- const string2 = integer.toString(16).toUpperCase();
1454
- return "000000".substring(string2.length) + string2;
1453
+ const string3 = integer.toString(16).toUpperCase();
1454
+ return "000000".substring(string3.length) + string3;
1455
1455
  };
1456
1456
  convert.hex.rgb = function(args) {
1457
1457
  const match2 = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
@@ -1631,8 +1631,8 @@ var require_conversions = __commonJS({
1631
1631
  convert.gray.hex = function(gray) {
1632
1632
  const val = Math.round(gray[0] / 100 * 255) & 255;
1633
1633
  const integer = (val << 16) + (val << 8) + val;
1634
- const string2 = integer.toString(16).toUpperCase();
1635
- return "000000".substring(string2.length) + string2;
1634
+ const string3 = integer.toString(16).toUpperCase();
1635
+ return "000000".substring(string3.length) + string3;
1636
1636
  };
1637
1637
  convert.rgb.gray = function(rgb) {
1638
1638
  const val = (rgb[0] + rgb[1] + rgb[2]) / 3;
@@ -3350,14 +3350,14 @@ function visit(tree, visitor, options) {
3350
3350
  enter = visitor.enter;
3351
3351
  leave = visitor.leave;
3352
3352
  }
3353
- walk(tree, {
3353
+ walk2(tree, {
3354
3354
  key: void 0,
3355
3355
  index: void 0,
3356
3356
  parents: [],
3357
3357
  containingArray: void 0,
3358
3358
  context: { ...startingContext }
3359
3359
  });
3360
- function walk(node, { key, index: index2, parents, context, containingArray }) {
3360
+ function walk2(node, { key, index: index2, parents, context, containingArray }) {
3361
3361
  const nodePassesTest = includeArrays ? test(node, {
3362
3362
  key,
3363
3363
  index: index2,
@@ -3388,7 +3388,7 @@ function visit(tree, visitor, options) {
3388
3388
  })) : result;
3389
3389
  if (Array.isArray(node)) for (let index3 = 0; index3 > -1 && index3 < node.length; index3++) {
3390
3390
  const item = node[index3];
3391
- const result2 = walk(item, {
3391
+ const result2 = walk2(item, {
3392
3392
  key,
3393
3393
  index: index3,
3394
3394
  parents,
@@ -3423,7 +3423,7 @@ function visit(tree, visitor, options) {
3423
3423
  newContext.inMathMode = true;
3424
3424
  newContext.hasMathModeAncestor = true;
3425
3425
  } else if (mathModeProps.leave.includes(key2)) newContext.inMathMode = false;
3426
- const result2 = walk(value, {
3426
+ const result2 = walk2(value, {
3427
3427
  key: key2,
3428
3428
  index: void 0,
3429
3429
  parents: grandparents,
@@ -11298,10 +11298,10 @@ var pgfkeys_default = (function() {
11298
11298
  function peg$f8(x) {
11299
11299
  return x;
11300
11300
  }
11301
- function peg$f9(space, x) {
11301
+ function peg$f9(space2, x) {
11302
11302
  return {
11303
11303
  trailingComment: x,
11304
- leadingParbreak: space.parbreak > 0
11304
+ leadingParbreak: space2.parbreak > 0
11305
11305
  };
11306
11306
  }
11307
11307
  function peg$f10(list) {
@@ -24330,9 +24330,9 @@ function buildWordRegex(allowedSet) {
24330
24330
  function hasReparsableMacroNamesInArray(tree, allowedTokens) {
24331
24331
  for (let i = 0; i < tree.length; i++) {
24332
24332
  const macro3 = tree[i];
24333
- const string2 = tree[i + 1];
24334
- if (match.anyMacro(macro3) && match.anyString(string2)) {
24335
- if (allowedTokens.has(macro3.content.charAt(macro3.content.length - 1)) || allowedTokens.has(string2.content.charAt(0))) return true;
24333
+ const string3 = tree[i + 1];
24334
+ if (match.anyMacro(macro3) && match.anyString(string3)) {
24335
+ if (allowedTokens.has(macro3.content.charAt(macro3.content.length - 1)) || allowedTokens.has(string3.content.charAt(0))) return true;
24336
24336
  }
24337
24337
  }
24338
24338
  return false;
@@ -24358,24 +24358,24 @@ function reparseMacroNamesInArray(tree, allowedTokens) {
24358
24358
  let i = 0;
24359
24359
  while (i < tree.length) {
24360
24360
  const macro3 = tree[i];
24361
- const string2 = tree[i + 1];
24362
- if (match.anyMacro(macro3) && (macro3.escapeToken == null || macro3.escapeToken === "\\") && match.anyString(string2) && (allowedTokens.has(macro3.content.charAt(macro3.content.length - 1)) || allowedTokens.has(string2.content.charAt(0)))) {
24363
- const match2 = string2.content.match(regex);
24361
+ const string3 = tree[i + 1];
24362
+ if (match.anyMacro(macro3) && (macro3.escapeToken == null || macro3.escapeToken === "\\") && match.anyString(string3) && (allowedTokens.has(macro3.content.charAt(macro3.content.length - 1)) || allowedTokens.has(string3.content.charAt(0)))) {
24363
+ const match2 = string3.content.match(regex);
24364
24364
  const takeable = match2 ? match2[0] : "";
24365
- if (takeable.length > 0) if (takeable.length === string2.content.length) {
24366
- macro3.content += string2.content;
24365
+ if (takeable.length > 0) if (takeable.length === string3.content.length) {
24366
+ macro3.content += string3.content;
24367
24367
  tree.splice(i + 1, 1);
24368
- if (macro3.position && string2.position?.end) macro3.position.end = string2.position.end;
24368
+ if (macro3.position && string3.position?.end) macro3.position.end = string3.position.end;
24369
24369
  } else {
24370
24370
  macro3.content += takeable;
24371
- string2.content = string2.content.slice(takeable.length);
24371
+ string3.content = string3.content.slice(takeable.length);
24372
24372
  if (macro3.position?.end) {
24373
24373
  macro3.position.end.offset += takeable.length;
24374
24374
  macro3.position.end.column += takeable.length;
24375
24375
  }
24376
- if (string2.position?.start) {
24377
- string2.position.start.offset += takeable.length;
24378
- string2.position.start.column += takeable.length;
24376
+ if (string3.position?.start) {
24377
+ string3.position.start.offset += takeable.length;
24378
+ string3.position.start.column += takeable.length;
24379
24379
  }
24380
24380
  }
24381
24381
  else i++;
@@ -24803,7 +24803,7 @@ var AUTO_PACKAGES = [
24803
24803
  ];
24804
24804
  var AUTO_LIBRARIES = [
24805
24805
  [/\bmatrix of (?:math )?nodes\b|\\matrix\b/, "matrix"],
24806
- [/\b(?:regular polygon|trapezium|semicircle|isosceles triangle|kite|dart|circular sector|cylinder|diamond|star|ellipse)\s*[,\]=]/, "shapes.geometric"],
24806
+ [/\b(?:regular polygon|trapezium|parallelogram|semicircle|isosceles triangle|kite|dart|circular sector|cylinder|diamond|star|ellipse)\s*[,\]=]/, "shapes.geometric"],
24807
24807
  [/\b(?:cross out|strike out|rounded rectangle|chamfered rectangle)\b/, "shapes.misc"],
24808
24808
  [/\b(?:cloud|forbidden sign|magnifying glass|starburst|signal|tape|magnetic tape|correct forbidden sign)\s*[,\]=]/, "shapes.symbols"],
24809
24809
  [/\b(?:rectangle split|circle split|ellipse split)\b/, "shapes.multipart"],
@@ -25266,6 +25266,265 @@ var TEXT_ARG_MACROS = /* @__PURE__ */ new Set(["textbf", "textit", "emph", "unde
25266
25266
  var SHAPE_NAMES = /* @__PURE__ */ new Set(["rectangle", "circle", "coordinate", "ellipse", "diamond", "trapezium", "semicircle", "regular polygon", "star", "isosceles triangle", "kite", "dart", "circular sector", "cylinder", "cloud", "starburst", "signal", "tape", "magnifying glass", "forbidden sign", "magnetic tape", "cross out", "strike out", "rounded rectangle", "chamfered rectangle", "rectangle split", "circle split", "circle solidus", "ellipse split", "rectangle callout", "ellipse callout", "cloud callout", "arrow box", "single arrow", "double arrow", "circle ee", "circle wee", "cross", "ground", "generic circle IEC", "generic diode IEC", "and gate", "or gate", "nand gate", "nor gate", "xor gate", "xnor gate", "not gate", "buffer gate"]);
25267
25267
  var MACRO_TYPOS = { circC: "\\circ\\mathrm{C}", degreeC: "^\\circ\\mathrm{C}", textcelsius: "\\celsius", textdegreeC: "\\textdegree C" };
25268
25268
 
25269
+ // src/recover.js
25270
+ var string2 = (content) => ({ type: "string", content });
25271
+ var group2 = (content) => ({ type: "group", content });
25272
+ var is = (node, text) => node?.type === "string" && node.content === text;
25273
+ var space = (node) => node?.type === "whitespace" || node?.type === "parbreak";
25274
+ var skip = (nodes, i) => {
25275
+ while (space(nodes[i])) i++;
25276
+ return i;
25277
+ };
25278
+ function walk(nodes, visit2) {
25279
+ visit2(nodes);
25280
+ for (const node of nodes) if (Array.isArray(node.content)) walk(node.content, visit2);
25281
+ }
25282
+ function closeAt(nodes, start, open, close) {
25283
+ let depth = 0;
25284
+ for (let i = start; i < nodes.length; i++) {
25285
+ if (is(nodes[i], open)) depth++;
25286
+ else if (is(nodes[i], close) && --depth === 0) return i;
25287
+ }
25288
+ return -1;
25289
+ }
25290
+ var DEFINITIONS = /* @__PURE__ */ new Set(["def", "gdef", "edef", "xdef", "let", "newcommand", "renewcommand", "providecommand", "pgfmathsetmacro", "pgfmathtruncatemacro", "pgfmathsetlengthmacro"]);
25291
+ function extendedIdentifiers(root, source2) {
25292
+ const bindings = /* @__PURE__ */ new Map();
25293
+ const names = /* @__PURE__ */ new Set();
25294
+ walk(root, (nodes) => {
25295
+ for (const node of nodes) if (node.type === "macro") names.add(node.content);
25296
+ });
25297
+ walk(root, (nodes) => {
25298
+ for (let i = 0; i < nodes.length; i++) {
25299
+ if (nodes[i].type !== "macro" || !DEFINITIONS.has(nodes[i].content)) continue;
25300
+ const at = skip(nodes, i + 1);
25301
+ const target = nodes[at]?.type === "group" ? nodes[at].content : nodes.slice(at, at + 3);
25302
+ const [macro3, tail, end] = target;
25303
+ if (macro3?.type !== "macro" || tail?.type !== "string" || !/^(?:_[A-Za-z0-9_]+|[0-9][A-Za-z0-9_]*)$/.test(tail.content)) continue;
25304
+ if (end && end.type !== "group" && !(nodes[i].content === "let" && end.type === "macro")) continue;
25305
+ if (macro3.position?.end.offset !== tail.position?.start.offset) continue;
25306
+ const key = macro3.content + tail.content;
25307
+ if (bindings.has(key)) continue;
25308
+ let name = "tikzRecoveredVariable";
25309
+ let n = bindings.size;
25310
+ do {
25311
+ name += String.fromCharCode(65 + n % 26);
25312
+ n = Math.floor(n / 26);
25313
+ } while (n);
25314
+ while (names.has(name)) name += "X";
25315
+ names.add(name);
25316
+ bindings.set(key, { base: macro3.content, suffix: tail.content, name });
25317
+ }
25318
+ });
25319
+ if (!bindings.size) return;
25320
+ walk(root, (nodes) => {
25321
+ for (let i = 0; i + 1 < nodes.length; i++) {
25322
+ const node = nodes[i];
25323
+ if (node.type !== "macro") continue;
25324
+ for (const binding of bindings.values()) {
25325
+ const offset = node.position?.end.offset;
25326
+ if (node.content !== binding.base || !source2.startsWith(binding.suffix, offset)) continue;
25327
+ const end = offset + binding.suffix.length;
25328
+ if (/[A-Za-z0-9_]/.test(source2[end] ?? "")) continue;
25329
+ let j = i + 1;
25330
+ while (j < nodes.length && nodes[j].position?.end.offset <= end) j++;
25331
+ if (nodes[j - 1]?.position?.end.offset !== end) continue;
25332
+ node.content = binding.name;
25333
+ nodes.splice(i + 1, j - i - 1);
25334
+ break;
25335
+ }
25336
+ }
25337
+ });
25338
+ }
25339
+ function nestedOptions(nodes) {
25340
+ for (let i = 0; i < nodes.length; i++) {
25341
+ if (!is(nodes[i], "[")) continue;
25342
+ let close = closeAt(nodes, i, "[", "]");
25343
+ if (close < 0) continue;
25344
+ for (let j = i + 1; j < close; j++) {
25345
+ if (!is(nodes[j], "[")) continue;
25346
+ const end = closeAt(nodes, j, "[", "]");
25347
+ let start = j - 1;
25348
+ while (start > i && !is(nodes[start], "=") && !is(nodes[start], ",")) start--;
25349
+ if (end < 0 || !is(nodes[start], "=")) continue;
25350
+ const value = nodes.slice(start + 1, end + 1);
25351
+ nodes.splice(start + 1, end - start, group2(value));
25352
+ close -= end - start - 1;
25353
+ j = start + 1;
25354
+ }
25355
+ i = close;
25356
+ }
25357
+ }
25358
+ function coordinateComponent(nodes, alreadyGrouped = false) {
25359
+ const significant2 = nodes.filter((node) => !space(node));
25360
+ if (significant2.length === 1 && significant2[0].type === "group") {
25361
+ significant2[0].content = coordinateComponent(significant2[0].content, true);
25362
+ return nodes;
25363
+ }
25364
+ let unitStart = significant2.length - 1;
25365
+ let unit = significant2[unitStart]?.type === "string" ? significant2[unitStart].content : "";
25366
+ if (unit.length === 1 && significant2[unitStart - 1]?.type === "string") {
25367
+ unitStart--;
25368
+ unit = significant2[unitStart].content + unit;
25369
+ }
25370
+ if (!/^(?:cm|mm|pt|bp|in|em|ex)$/.test(unit)) unit = null;
25371
+ if (unit && significant2.length > 1 && (significant2[0].type === "group" || significant2.some((node) => is(node, "(")))) {
25372
+ const expr = significant2.slice(0, unitStart).flatMap((node) => node.type === "group" ? [string2("("), ...node.content, string2(")")] : [node]);
25373
+ const repaired = [string2("("), ...expr, string2(")*1" + unit)];
25374
+ return alreadyGrouped ? repaired : [group2(repaired)];
25375
+ }
25376
+ if (!alreadyGrouped && nodes.some((node) => is(node, "("))) return [group2(nodes)];
25377
+ return nodes;
25378
+ }
25379
+ function coordinates(nodes) {
25380
+ for (let i = 0; i < nodes.length; i++) {
25381
+ if (nodes[i].type === "inlinemath") {
25382
+ coordinates(nodes[i].content);
25383
+ continue;
25384
+ }
25385
+ if (!is(nodes[i], "(")) continue;
25386
+ const end = closeAt(nodes, i, "(", ")");
25387
+ if (end < 0) continue;
25388
+ const inside = nodes.slice(i + 1, end);
25389
+ if (inside.some((node) => node.type === "inlinemath")) {
25390
+ for (const node of inside) if (node.type === "inlinemath") coordinates(node.content);
25391
+ i = end;
25392
+ continue;
25393
+ }
25394
+ let depth = 0, start = 0;
25395
+ const segments = [], delimiters = [];
25396
+ for (let j = 0; j < inside.length; j++) {
25397
+ if (is(inside[j], "(")) depth++;
25398
+ else if (is(inside[j], ")")) depth--;
25399
+ else if (!depth && (is(inside[j], ",") || is(inside[j], ":") || is(inside[j], "and"))) {
25400
+ segments.push(inside.slice(start, j));
25401
+ delimiters.push(is(inside[j], "and") ? string2(" and ") : inside[j]);
25402
+ start = j + 1;
25403
+ }
25404
+ }
25405
+ segments.push(inside.slice(start));
25406
+ if (inside.some((node) => is(node, "=") || is(node, "|") || is(node, "cs"))) {
25407
+ i = end;
25408
+ continue;
25409
+ }
25410
+ const rebuilt = segments.flatMap((part, j) => [...coordinateComponent(part), ...delimiters[j] ? [delimiters[j]] : []]);
25411
+ nodes.splice(i + 1, end - i - 1, ...rebuilt);
25412
+ i += rebuilt.length + 1;
25413
+ }
25414
+ }
25415
+ var PATHS = /* @__PURE__ */ new Set(["draw", "fill", "filldraw", "shade", "shadedraw", "path", "coordinate", "node", "clip", "pic"]);
25416
+ function delimited(nodes, at, open, close) {
25417
+ at = skip(nodes, at);
25418
+ if (!is(nodes[at], open)) return null;
25419
+ const end = closeAt(nodes, at, open, close);
25420
+ return end < 0 ? null : { start: at, end: end + 1, content: nodes.slice(at + 1, end) };
25421
+ }
25422
+ function tkzCommands(nodes) {
25423
+ for (let i = 0; i < nodes.length; i++) {
25424
+ const node = nodes[i];
25425
+ if (node.type !== "macro" || !node.content.startsWith("tkz")) continue;
25426
+ const options = delimited(nodes, i + 1, "[", "]");
25427
+ const point2 = delimited(nodes, options?.end ?? i + 1, "(", ")");
25428
+ if (!point2) continue;
25429
+ if (node.content === "tkzDefLine" && options) {
25430
+ const first = skip(options.content, 0);
25431
+ const through = skip(options.content, first + 1);
25432
+ if (["orthogonal", "perpendicular", "parallel"].some((key) => is(options.content[first], key)) && is(options.content[through], "through")) {
25433
+ nodes.splice(options.start + 1 + first + 1, 0, string2("="));
25434
+ }
25435
+ }
25436
+ if (node.content === "tkzMidPoint") node.content = "tkzDefMidPoint";
25437
+ if (["tkzDefMidPoint", "tkzDefPointBy", "tkzDefPointWith"].includes(node.content)) {
25438
+ const out = skip(nodes, point2.end);
25439
+ if (nodes[out]?.type === "group") nodes.splice(out, 0, { type: "macro", content: "tkzGetPoint" });
25440
+ if (node.content === "tkzDefPointBy" && options) {
25441
+ const onto = options.content.findIndex((token) => is(token, "onto"));
25442
+ const line = skip(options.content, onto + 1);
25443
+ if (onto >= 0 && is(options.content[line], "line")) {
25444
+ options.content.splice(line, 1);
25445
+ nodes.splice(options.start + 1, options.end - options.start - 2, ...options.content);
25446
+ }
25447
+ }
25448
+ }
25449
+ if (node.content === "tkzInter" && options && printRaw(options.content).trim() === "R" && delimited(nodes, point2.end, "(", ")")) node.content = "tkzInterCC";
25450
+ if (node.content === "tkzDrawCircle" && options) {
25451
+ const keys2 = parsePgfkeys(options.content).map((item) => (item.itemParts ?? []).map((part) => printRaw(part).trim()).join("="));
25452
+ const mode = keys2.find((key) => ["circum", "in", "diameter", "R"].includes(key));
25453
+ const count = point2.content.filter((token) => is(token, ",")).length + 1;
25454
+ if (!mode || count !== (["circum", "in"].includes(mode) ? 3 : 2)) continue;
25455
+ const rest = keys2.filter((key) => key !== mode).join(",");
25456
+ if (mode === "R") {
25457
+ const comma = point2.content.findIndex((token) => is(token, ","));
25458
+ nodes.splice(i, point2.end - i, string2(String.raw`\draw[circle style,${rest}] (${printRaw(point2.content.slice(0, comma))}) circle (${printRaw(point2.content.slice(comma + 1))});`));
25459
+ continue;
25460
+ }
25461
+ const replacement = String.raw`{\tkzDefCircle[${mode}](${printRaw(point2.content)})\tkzGetPoints{tikzRecoveredCircleCenter}{tikzRecoveredCirclePoint}\tkzDrawCircle[${rest}](tikzRecoveredCircleCenter,tikzRecoveredCirclePoint)}`;
25462
+ nodes.splice(i, point2.end - i, string2(replacement));
25463
+ }
25464
+ }
25465
+ }
25466
+ function numberExpressions(nodes) {
25467
+ for (let i = 0; i < nodes.length; i++) {
25468
+ const node = nodes[i];
25469
+ if (node.type !== "macro") continue;
25470
+ if (["pgfmathparse", "pgfmathsetmacro", "pgfmathtruncatemacro"].includes(node.content)) {
25471
+ let at2 = skip(nodes, i + 1);
25472
+ if (node.content !== "pgfmathparse") at2 = skip(nodes, at2 + 1);
25473
+ const expr2 = nodes[at2];
25474
+ if (expr2?.type !== "group") continue;
25475
+ const mod = expr2.content.findIndex((token) => is(token, "mod"));
25476
+ const atom = (tokens) => {
25477
+ const value = tokens.filter((token) => !space(token));
25478
+ return value.length === 1 && (value[0].type === "macro" || value[0].type === "group" || value[0].type === "string" && /^-?\d+(?:\.\d+)?$/.test(value[0].content));
25479
+ };
25480
+ if (mod > 0 && atom(expr2.content.slice(0, mod)) && atom(expr2.content.slice(mod + 1))) expr2.content = [string2("mod("), ...expr2.content.slice(0, mod), string2(","), ...expr2.content.slice(mod + 1), string2(")")];
25481
+ }
25482
+ if (node.content !== "pgfmathprintnumber") continue;
25483
+ const options = delimited(nodes, i + 1, "[", "]");
25484
+ const at = skip(nodes, options?.end ?? i + 1);
25485
+ const expr = nodes[at];
25486
+ if (expr?.type !== "group" || !expr.content.some((token) => token.type === "string" && ["*", "/", "+", "("].includes(token.content))) continue;
25487
+ nodes.splice(i, at - i + 1, string2(String.raw`{\pgfmathparse{${printRaw(expr.content)}}\pgfmathprintnumber${options ? `[${printRaw(options.content)}]` : ""}{\pgfmathresult}}`));
25488
+ }
25489
+ }
25490
+ function relativeNodePosition(nodes) {
25491
+ for (let i = 0; i < nodes.length; i++) {
25492
+ if (nodes[i].type !== "macro" || nodes[i].content !== "node") continue;
25493
+ let at = i + 1;
25494
+ while (at < nodes.length && !is(nodes[at], "at") && !is(nodes[at], ";")) at++;
25495
+ if (!is(nodes[at], "at")) continue;
25496
+ const base2 = delimited(nodes, at + 1, "(", ")");
25497
+ if (!base2) continue;
25498
+ let plus = skip(nodes, base2.end);
25499
+ if (!is(nodes[plus], "+")) continue;
25500
+ plus++;
25501
+ if (is(nodes[plus], "+")) plus++;
25502
+ const offset = delimited(nodes, plus, "(", ")");
25503
+ if (!offset) continue;
25504
+ nodes.splice(base2.start, offset.end - base2.start, string2(`($(${printRaw(base2.content)})+(${printRaw(offset.content)})$)`));
25505
+ }
25506
+ }
25507
+ function recoverGeneratedSyntax(source2) {
25508
+ const root = parseMinimal(source2).content;
25509
+ extendedIdentifiers(root, source2);
25510
+ walk(root, nestedOptions);
25511
+ walk(root, tkzCommands);
25512
+ walk(root, numberExpressions);
25513
+ walk(root, relativeNodePosition);
25514
+ walk(root, (nodes) => {
25515
+ for (let i = 0; i < nodes.length; i++) {
25516
+ if (nodes[i].type !== "macro" || !PATHS.has(nodes[i].content)) continue;
25517
+ let end = i + 1;
25518
+ while (end < nodes.length && !is(nodes[end], ";")) end++;
25519
+ const tokens = nodes.slice(i + 1, end);
25520
+ coordinates(tokens);
25521
+ nodes.splice(i + 1, end - i - 1, ...tokens);
25522
+ i += tokens.length;
25523
+ }
25524
+ });
25525
+ return printRaw(root);
25526
+ }
25527
+
25269
25528
  // src/source.js
25270
25529
  var DEFAULT_LIBRARIES = ["calc", "intersections", "angles", "quotes", "arrows.meta", "positioning"];
25271
25530
  var TikzSourceError = class extends Error {
@@ -25305,8 +25564,8 @@ function definedMacroNames(text) {
25305
25564
  if (isMacro(array[j])) names.add(array[j].content);
25306
25565
  }
25307
25566
  } else if (node.content === "tikzmath") {
25308
- const group2 = array[skipSpace(array, i + 1)];
25309
- if (isGroup(group2)) walkArrays(group2.content, (tokens) => {
25567
+ const group3 = array[skipSpace(array, i + 1)];
25568
+ if (isGroup(group3)) walkArrays(group3.content, (tokens) => {
25310
25569
  for (let j = 0; j < tokens.length; j++) if (isMacro(tokens[j]) && isString(tokens[skipSpace(tokens, j + 1)], "=")) names.add(tokens[j].content);
25311
25570
  });
25312
25571
  } else if (node.content === "pgfkeysgetvalue") {
@@ -25719,13 +25978,29 @@ function processKeyList(nodes, context) {
25719
25978
  for (const item of items) {
25720
25979
  const parts = item.itemParts ?? [];
25721
25980
  if (!parts.length) continue;
25722
- const key = printRaw(parts[0]).trim();
25981
+ let key = printRaw(parts[0]).trim();
25723
25982
  const value = parts[1];
25983
+ if (context.tikz && !key.includes("/") && key.endsWith(" style") && value?.some(isGroup)) {
25984
+ key += "/.style";
25985
+ parts[0] = [str(key)];
25986
+ }
25724
25987
  if (value && TEXT_KEYS.has(key)) repairTextNodes(value, context);
25725
25988
  if (value && /^(?:xtick|ytick|ztick)labels$|^legend entries$/.test(key)) {
25726
25989
  for (const node of value) if (isGroup(node)) repairTextNodes(node.content, context);
25727
25990
  }
25728
25991
  const styleName = /^(.+?)\/\.(?:style|append style)$/.exec(key)?.[1];
25992
+ if (styleName && ["name", "label"].includes(styleName)) {
25993
+ const alias = `tikz recovered ${styleName} style`;
25994
+ context.styleAliases?.set(styleName, alias);
25995
+ parts[0] = [str(key.replace(styleName, alias))];
25996
+ } else if (!value && context.styleAliases?.has(key)) parts[0] = [str(context.styleAliases.get(key))];
25997
+ if (value && /^(above|below|left|right)( left| right)?$/.test(key)) {
25998
+ const target = value.findIndex((node) => isString(node, "of"));
25999
+ const point2 = target >= 0 ? skipSpace(value, target + 1) : -1;
26000
+ if (point2 >= 0 && value[point2]?.type === "inlinemath") {
26001
+ parts[1] = [{ type: "group", content: value }];
26002
+ }
26003
+ }
25729
26004
  if (styleName && value) {
25730
26005
  for (const node of value) if (isGroup(node)) unloopStyle(node.content, styleName);
25731
26006
  }
@@ -25775,6 +26050,16 @@ function mergeParenthesisedValues(items) {
25775
26050
  for (let i = 0; i < items.length; i++) {
25776
26051
  const item = items[i];
25777
26052
  const parts = item.itemParts ?? [];
26053
+ if (parts.length === 2 && /^(above|below|left|right)( left| right)?$/.test(printRaw(parts[0]).trim())) {
26054
+ const of = parts[1].findIndex((node) => isString(node, "of"));
26055
+ const number = (tokens) => /^-?\d+(?:\.\d+)?(?:cm|mm|pt)?$/.test(printRaw(tokens).trim());
26056
+ const next = items[i + 1]?.itemParts;
26057
+ if (of >= 0 && number(parts[1].slice(of + 1)) && next?.length === 1 && number(next[0])) {
26058
+ out.push({ ...item, itemParts: [parts[0], [{ type: "group", content: [...parts[1], str(","), ...next[0]] }]] });
26059
+ i++;
26060
+ continue;
26061
+ }
26062
+ }
25778
26063
  if (parts.length !== 2 || balance(parts[1]) <= 0) {
25779
26064
  out.push(item);
25780
26065
  continue;
@@ -25869,7 +26154,7 @@ function processKeyLists(root, context) {
25869
26154
  continue;
25870
26155
  }
25871
26156
  if (node?.type === "environment" && Array.isArray(node.args)) {
25872
- for (const argument2 of node.args) if (argument2.openMark === "[") processKeyList(argument2.content, context);
26157
+ for (const argument2 of node.args) if (argument2.openMark === "[") processKeyList(argument2.content, { ...context, tikz: ["tikzpicture", "scope", "circuitikz"].includes(node.env) });
25873
26158
  }
25874
26159
  if (isMacro(node) && KEY_LIST_MACROS.has(node.content) && hasArgs(node)) {
25875
26160
  for (const argument2 of node.args) if (argument2.openMark === "{") processKeyList(argument2.content, context);
@@ -26136,6 +26421,25 @@ function repairForeachLists(root) {
26136
26421
  }
26137
26422
  });
26138
26423
  }
26424
+ function repairBoldMath(root) {
26425
+ walkArrays(root, (array) => {
26426
+ if (!array.some((node) => node.type === "inlinemath")) return;
26427
+ let bold = false;
26428
+ for (let i = 0; i < array.length; i++) {
26429
+ if (isMacro(array[i], "boldmath")) {
26430
+ bold = true;
26431
+ array.splice(i--, 1);
26432
+ continue;
26433
+ }
26434
+ if (isMacro(array[i], "unboldmath")) {
26435
+ bold = false;
26436
+ array.splice(i--, 1);
26437
+ continue;
26438
+ }
26439
+ if (bold && array[i].type === "inlinemath") array[i].content = [macro2("boldsymbol", [{ type: "argument", openMark: "{", closeMark: "}", content: array[i].content }])];
26440
+ }
26441
+ });
26442
+ }
26139
26443
  function mathOnly(nodes) {
26140
26444
  if (nodes.some((node) => node.type === "inlinemath" || node.type === "displaymath")) return false;
26141
26445
  return needsMath(nodes.filter((node) => !isSpace(node)));
@@ -26158,7 +26462,7 @@ function stripOverlayKeys(root) {
26158
26462
  }
26159
26463
  }
26160
26464
  function prepareTikzDocument(code) {
26161
- const cleaned = cleanInput(code);
26465
+ const cleaned = recoverGeneratedSyntax(cleanInput(code));
26162
26466
  if (!cleaned) throw new TikzSourceError("TikZ source is empty.");
26163
26467
  const state = {
26164
26468
  packages: /* @__PURE__ */ new Map(),
@@ -26180,15 +26484,17 @@ function prepareTikzDocument(code) {
26180
26484
  const unicodeSeen = /* @__PURE__ */ new Set();
26181
26485
  const colorsDefined = /* @__PURE__ */ new Set();
26182
26486
  const colorsSeen = /* @__PURE__ */ new Set();
26183
- for (const root of [body, statementsRoot]) {
26487
+ const keyContext = { styleAliases: /* @__PURE__ */ new Map() };
26488
+ for (const root of [statementsRoot, body]) {
26184
26489
  rewriteHexColors(root);
26185
26490
  replaceUnavailableMacros(root, state);
26186
- processKeyLists(root, {});
26491
+ processKeyLists(root, keyContext);
26187
26492
  }
26188
26493
  stripOverlayKeys(body);
26189
26494
  protectAndDelimiter(body);
26190
26495
  repairForeachLists(body);
26191
26496
  replaceTypos(body);
26497
+ repairBoldMath(body);
26192
26498
  repairNodeTexts(body);
26193
26499
  unicodeSupport(body, unicodeSeen, unicode);
26194
26500
  unicodeSupport(statementsRoot, unicodeSeen, unicode);
@@ -26223,6 +26529,12 @@ ${declarations}`);
26223
26529
  if (state.gdLibraries.size) lines.push(`\\usegdlibrary{${[...state.gdLibraries].join(",")}}`);
26224
26530
  if (state.packages.has("pgfplots") && !state.compat) lines.push("\\pgfplotsset{compat=1.18}");
26225
26531
  lines.push(...unicode, ...colors, COMPAT_SHIM);
26532
+ if (!excluded.has("pgfmathdistance") && /\\pgfmathdistance\b/.test(everything)) lines.push(String.raw`\makeatletter
26533
+ \providecommand{\pgfmathdistance}[2]{\pgfpointdiff{#1}{#2}\pgfmathveclen{\the\pgf@x}{\the\pgf@y}}
26534
+ \makeatother`);
26535
+ if (/\bparallelogram\b/.test(everything)) lines.push(String.raw`\pgfkeysifdefined{/tikz/parallelogram/.@cmd}{}{\tikzset{parallelogram/.style={shape=trapezium,trapezium left angle=70,trapezium right angle=110}}}`);
26536
+ lines.push(String.raw`\pgfkeysifdefined{/tikz/rounded cap/.@cmd}{}{\tikzset{rounded cap/.style={line cap=round}}}
26537
+ \pgfkeysifdefined{/tikz/final/.@cmd}{}{\tikzset{final/.style={accepting}}}`);
26226
26538
  if (state.shims.has("siunitx")) lines.push(siunitxShim());
26227
26539
  if (state.shims.has("physics")) lines.push(PHYSICS_SHIM);
26228
26540
  if (state.shims.has("upgreek")) lines.push(...GREEK_NAMES.map((name) => `\\providecommand{\\up${name}}{\\ensuremath{\\${name}}}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lofcz/tikz",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Self-contained, process-isolated TikZ to SVG rendering powered by mp-tikz-wasm.",
5
5
  "type": "module",
6
6
  "license": "GPL-3.0-or-later",