@wdprlib/render 1.4.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/index.cjs +126 -393
  2. package/dist/index.js +117 -384
  3. package/package.json +5 -3
  4. package/src/context.ts +422 -0
  5. package/src/elements/bibliography.ts +123 -0
  6. package/src/elements/clear-float.ts +27 -0
  7. package/src/elements/code.ts +49 -0
  8. package/src/elements/collapsible.ts +105 -0
  9. package/src/elements/color.ts +32 -0
  10. package/src/elements/container.ts +302 -0
  11. package/src/elements/date.ts +59 -0
  12. package/src/elements/embed-block.ts +327 -0
  13. package/src/elements/embed.ts +166 -0
  14. package/src/elements/expr.ts +102 -0
  15. package/src/elements/footnote.ts +76 -0
  16. package/src/elements/html.ts +79 -0
  17. package/src/elements/iframe.ts +44 -0
  18. package/src/elements/iftags.ts +118 -0
  19. package/src/elements/image.ts +154 -0
  20. package/src/elements/include.ts +43 -0
  21. package/src/elements/index.ts +35 -0
  22. package/src/elements/line-break.ts +22 -0
  23. package/src/elements/link.ts +201 -0
  24. package/src/elements/list.ts +241 -0
  25. package/src/elements/math.ts +177 -0
  26. package/src/elements/module/backlinks.ts +28 -0
  27. package/src/elements/module/categories.ts +27 -0
  28. package/src/elements/module/index.ts +67 -0
  29. package/src/elements/module/join.ts +33 -0
  30. package/src/elements/module/listpages.ts +27 -0
  31. package/src/elements/module/listusers.ts +27 -0
  32. package/src/elements/module/page-tree.ts +27 -0
  33. package/src/elements/module/rate.ts +44 -0
  34. package/src/elements/tab-view.ts +75 -0
  35. package/src/elements/table.ts +101 -0
  36. package/src/elements/text.ts +57 -0
  37. package/src/elements/toc.ts +147 -0
  38. package/src/elements/user.ts +79 -0
  39. package/src/escape.ts +829 -0
  40. package/src/hash.ts +62 -0
  41. package/src/index.ts +26 -0
  42. package/src/libs/highlighter/engine.ts +352 -0
  43. package/src/libs/highlighter/index.ts +70 -0
  44. package/src/libs/highlighter/languages/cpp.ts +345 -0
  45. package/src/libs/highlighter/languages/css.ts +104 -0
  46. package/src/libs/highlighter/languages/diff.ts +154 -0
  47. package/src/libs/highlighter/languages/dtd.ts +99 -0
  48. package/src/libs/highlighter/languages/html.ts +59 -0
  49. package/src/libs/highlighter/languages/java.ts +251 -0
  50. package/src/libs/highlighter/languages/javascript.ts +213 -0
  51. package/src/libs/highlighter/languages/php.ts +433 -0
  52. package/src/libs/highlighter/languages/python.ts +308 -0
  53. package/src/libs/highlighter/languages/ruby.ts +360 -0
  54. package/src/libs/highlighter/languages/sql.ts +125 -0
  55. package/src/libs/highlighter/languages/xml.ts +68 -0
  56. package/src/libs/highlighter/types.ts +44 -0
  57. package/src/render.ts +231 -0
  58. package/src/types.ts +140 -0
package/dist/index.cjs CHANGED
@@ -44,14 +44,14 @@ var __export = (target, all) => {
44
44
  var exports_src = {};
45
45
  __export(exports_src, {
46
46
  renderToHtml: () => renderToHtml,
47
- createSettings: () => import_ast4.createSettings,
48
- DEFAULT_SETTINGS: () => import_ast4.DEFAULT_SETTINGS,
47
+ createSettings: () => import_ast5.createSettings,
48
+ DEFAULT_SETTINGS: () => import_ast5.DEFAULT_SETTINGS,
49
49
  DEFAULT_EMBED_ALLOWLIST: () => DEFAULT_EMBED_ALLOWLIST
50
50
  });
51
51
  module.exports = __toCommonJS(exports_src);
52
52
 
53
53
  // packages/render/src/render.ts
54
- var import_ast3 = require("@wdprlib/ast");
54
+ var import_ast4 = require("@wdprlib/ast");
55
55
 
56
56
  // packages/render/src/context.ts
57
57
  var import_ast = require("@wdprlib/ast");
@@ -356,10 +356,76 @@ function normalizeCssValue(value) {
356
356
  result = result.replace(/[\s\u0000-\u001f\u007f-\u009f]/g, "");
357
357
  return result.toLowerCase();
358
358
  }
359
+ function isUrlAllowed(rawUrl) {
360
+ let url = rawUrl;
361
+ if (url.length >= 2) {
362
+ const first = url[0];
363
+ const last = url[url.length - 1];
364
+ if (first === '"' && last === '"' || first === "'" && last === "'") {
365
+ url = url.slice(1, -1);
366
+ }
367
+ }
368
+ if (url === "")
369
+ return true;
370
+ if (url.startsWith("#"))
371
+ return true;
372
+ if (url.startsWith("./") || url.startsWith("../"))
373
+ return true;
374
+ if (url.startsWith("//"))
375
+ return true;
376
+ if (url.startsWith("/"))
377
+ return true;
378
+ if (url.startsWith("http://") || url.startsWith("https://"))
379
+ return true;
380
+ if (url.startsWith("data:image/")) {
381
+ const after = url.slice("data:image/".length);
382
+ const sep = Math.min(after.indexOf(";") === -1 ? after.length : after.indexOf(";"), after.indexOf(",") === -1 ? after.length : after.indexOf(","));
383
+ const mime = after.slice(0, sep);
384
+ if (mime === "png" || mime === "jpeg" || mime === "jpg" || mime === "gif" || mime === "webp") {
385
+ return true;
386
+ }
387
+ }
388
+ return false;
389
+ }
390
+ function* iterateUrls(normalized) {
391
+ let searchPos = 0;
392
+ while (searchPos < normalized.length) {
393
+ const idx = normalized.indexOf("url(", searchPos);
394
+ if (idx === -1)
395
+ return;
396
+ let depth = 1;
397
+ let quoteChar = null;
398
+ let i = idx + 4;
399
+ while (i < normalized.length && depth > 0) {
400
+ const ch = normalized[i];
401
+ if (quoteChar !== null) {
402
+ if (ch === quoteChar)
403
+ quoteChar = null;
404
+ } else if (ch === '"' || ch === "'") {
405
+ quoteChar = ch;
406
+ } else if (ch === "(") {
407
+ depth++;
408
+ } else if (ch === ")") {
409
+ depth--;
410
+ }
411
+ i++;
412
+ }
413
+ if (depth > 0) {
414
+ yield { inner: normalized.slice(idx + 4), malformed: true };
415
+ return;
416
+ }
417
+ yield { inner: normalized.slice(idx + 4, i - 1), malformed: false };
418
+ searchPos = i;
419
+ }
420
+ }
359
421
  function isDangerousCssValue(value) {
360
422
  const normalized = normalizeCssValue(value);
361
- if (normalized.includes("url("))
362
- return true;
423
+ for (const { inner, malformed } of iterateUrls(normalized)) {
424
+ if (malformed)
425
+ return true;
426
+ if (!isUrlAllowed(inner))
427
+ return true;
428
+ }
363
429
  if (normalized.includes("expression("))
364
430
  return true;
365
431
  if (normalized.includes("-moz-binding"))
@@ -370,21 +436,61 @@ function isDangerousCssValue(value) {
370
436
  return true;
371
437
  return false;
372
438
  }
439
+ function splitDeclarations(style) {
440
+ const out = [];
441
+ let buf = "";
442
+ let parenDepth = 0;
443
+ let quoteChar = null;
444
+ for (const ch of style) {
445
+ if (quoteChar !== null) {
446
+ buf += ch;
447
+ if (ch === quoteChar)
448
+ quoteChar = null;
449
+ continue;
450
+ }
451
+ if (ch === '"' || ch === "'") {
452
+ quoteChar = ch;
453
+ buf += ch;
454
+ continue;
455
+ }
456
+ if (ch === "(") {
457
+ parenDepth++;
458
+ buf += ch;
459
+ continue;
460
+ }
461
+ if (ch === ")") {
462
+ if (parenDepth > 0)
463
+ parenDepth--;
464
+ buf += ch;
465
+ continue;
466
+ }
467
+ if (ch === ";" && parenDepth === 0) {
468
+ out.push(buf);
469
+ buf = "";
470
+ continue;
471
+ }
472
+ buf += ch;
473
+ }
474
+ if (buf.length > 0)
475
+ out.push(buf);
476
+ return out;
477
+ }
373
478
  function sanitizeStyleValue(style) {
374
479
  const endsWithSemicolon = style.trimEnd().endsWith(";");
375
- const declarations = style.split(";").map((d) => d.trim()).filter(Boolean);
480
+ const declarations = splitDeclarations(style).map((d) => d.trim()).filter(Boolean);
376
481
  const safe = [];
377
482
  for (const decl of declarations) {
378
483
  const colonIdx = decl.indexOf(":");
379
484
  if (colonIdx === -1)
380
485
  continue;
381
- const property = decl.slice(0, colonIdx).trim().toLowerCase();
486
+ const property = decl.slice(0, colonIdx).trim();
382
487
  const value = decl.slice(colonIdx + 1).trim();
383
488
  if (isDangerousCssValue(value))
384
489
  continue;
385
- if (property.startsWith("-moz-binding"))
490
+ const normalisedProperty = normalizeCssValue(property);
491
+ if (normalisedProperty.startsWith("-moz-binding"))
386
492
  continue;
387
- if (property === "behavior")
493
+ if (normalisedProperty === "behavior")
388
494
  continue;
389
495
  safe.push(decl);
390
496
  }
@@ -4610,6 +4716,9 @@ function generateDefaultUrl(pageName, contents) {
4610
4716
  return path;
4611
4717
  }
4612
4718
  function renderHtmlBlock(ctx, data) {
4719
+ if (ctx.settings.allowHtmlBlocks === false) {
4720
+ return;
4721
+ }
4613
4722
  const index = ctx.nextHtmlBlockIndex();
4614
4723
  const pageName = ctx.page?.pageName ?? "";
4615
4724
  const callbackUrl = ctx.options.resolvers?.htmlBlockUrl?.(index);
@@ -4712,392 +4821,22 @@ function formatDate(date, format) {
4712
4821
  return format.replace(/%Y/g, String(date.getFullYear())).replace(/%m/g, String(date.getMonth() + 1).padStart(2, "0")).replace(/%d/g, String(date.getDate()).padStart(2, "0")).replace(/%H/g, String(date.getHours()).padStart(2, "0")).replace(/%M/g, String(date.getMinutes()).padStart(2, "0")).replace(/%S/g, String(date.getSeconds()).padStart(2, "0"));
4713
4822
  }
4714
4823
 
4715
- // packages/render/src/utils/expr-eval.ts
4716
- var FALSE_VALUES = new Set(["false", "null", "", "0"]);
4717
- function isTruthy(value) {
4718
- return !FALSE_VALUES.has(value.toLowerCase().trim());
4719
- }
4720
- var MAX_EXPRESSION_LENGTH = 256;
4721
- function isTruthyNum(n) {
4722
- return n !== 0 && !Number.isNaN(n);
4723
- }
4724
- function evaluateExpression(expr) {
4725
- try {
4726
- if (expr.length > MAX_EXPRESSION_LENGTH) {
4727
- return { success: false, error: "expression too long" };
4728
- }
4729
- if (expr.trim() === "") {
4730
- return { success: false, error: "empty expression" };
4731
- }
4732
- const tokens = tokenize2(expr);
4733
- if (tokens.length <= 1) {
4734
- return { success: false, error: "empty expression" };
4735
- }
4736
- const parser = new ExprParser(tokens);
4737
- const result = parser.parse();
4738
- if (!Number.isFinite(result)) {
4739
- return { success: false, error: "division by zero" };
4740
- }
4741
- return { success: true, value: result };
4742
- } catch (e) {
4743
- const msg = e instanceof Error ? e.message : "unknown error";
4744
- return { success: false, error: msg };
4745
- }
4746
- }
4747
- function tokenize2(expr) {
4748
- const tokens = [];
4749
- let i = 0;
4750
- while (i < expr.length) {
4751
- const ch = expr[i];
4752
- if (/\s/.test(ch)) {
4753
- i++;
4754
- continue;
4755
- }
4756
- if (/\d/.test(ch) || ch === "." && /\d/.test(expr[i + 1] ?? "")) {
4757
- let numStr = "";
4758
- let hasDot = false;
4759
- while (i < expr.length) {
4760
- const c = expr[i];
4761
- if (c === ".") {
4762
- if (hasDot)
4763
- break;
4764
- hasDot = true;
4765
- } else if (!/\d/.test(c)) {
4766
- break;
4767
- }
4768
- numStr += c;
4769
- i++;
4770
- }
4771
- const num = parseFloat(numStr);
4772
- if (!Number.isFinite(num)) {
4773
- throw new Error("Invalid number");
4774
- }
4775
- tokens.push({ kind: "NUMBER", value: num });
4776
- continue;
4777
- }
4778
- if (/[a-zA-Z_]/.test(ch)) {
4779
- let id = "";
4780
- while (i < expr.length) {
4781
- const c = expr[i];
4782
- if (!/[a-zA-Z0-9_]/.test(c))
4783
- break;
4784
- id += c;
4785
- i++;
4786
- }
4787
- tokens.push({ kind: "IDENTIFIER", value: id.toLowerCase() });
4788
- continue;
4789
- }
4790
- if (ch === "<" && expr[i + 1] === "=") {
4791
- tokens.push({ kind: "LE", value: "<=" });
4792
- i += 2;
4793
- continue;
4794
- }
4795
- if (ch === ">" && expr[i + 1] === "=") {
4796
- tokens.push({ kind: "GE", value: ">=" });
4797
- i += 2;
4798
- continue;
4799
- }
4800
- if (ch === "!" && expr[i + 1] === "=") {
4801
- tokens.push({ kind: "NE", value: "!=" });
4802
- i += 2;
4803
- continue;
4804
- }
4805
- if (ch === "<" && expr[i + 1] === ">") {
4806
- tokens.push({ kind: "NE", value: "<>" });
4807
- i += 2;
4808
- continue;
4809
- }
4810
- switch (ch) {
4811
- case "+":
4812
- tokens.push({ kind: "PLUS", value: "+" });
4813
- break;
4814
- case "-":
4815
- tokens.push({ kind: "MINUS", value: "-" });
4816
- break;
4817
- case "*":
4818
- tokens.push({ kind: "STAR", value: "*" });
4819
- break;
4820
- case "/":
4821
- tokens.push({ kind: "SLASH", value: "/" });
4822
- break;
4823
- case "%":
4824
- tokens.push({ kind: "PERCENT", value: "%" });
4825
- break;
4826
- case "^":
4827
- tokens.push({ kind: "CARET", value: "^" });
4828
- break;
4829
- case "(":
4830
- tokens.push({ kind: "LPAREN", value: "(" });
4831
- break;
4832
- case ")":
4833
- tokens.push({ kind: "RPAREN", value: ")" });
4834
- break;
4835
- case ",":
4836
- tokens.push({ kind: "COMMA", value: "," });
4837
- break;
4838
- case "<":
4839
- tokens.push({ kind: "LT", value: "<" });
4840
- break;
4841
- case ">":
4842
- tokens.push({ kind: "GT", value: ">" });
4843
- break;
4844
- case "=":
4845
- tokens.push({ kind: "EQ", value: "=" });
4846
- break;
4847
- default:
4848
- throw new Error(`Unknown character: ${ch}`);
4849
- }
4850
- i++;
4851
- }
4852
- tokens.push({ kind: "EOF", value: "" });
4853
- return tokens;
4854
- }
4855
-
4856
- class ExprParser {
4857
- tokens;
4858
- pos = 0;
4859
- constructor(tokens) {
4860
- this.tokens = tokens;
4861
- }
4862
- parse() {
4863
- const result = this.parseOr();
4864
- if (this.current().kind !== "EOF") {
4865
- throw new Error("too many values in the stack");
4866
- }
4867
- return result;
4868
- }
4869
- current() {
4870
- return this.tokens[this.pos] ?? { kind: "EOF", value: "" };
4871
- }
4872
- advance() {
4873
- const token = this.current();
4874
- this.pos++;
4875
- return token;
4876
- }
4877
- parseOr() {
4878
- let left = this.parseAnd();
4879
- while (this.current().kind === "IDENTIFIER" && this.current().value === "or") {
4880
- this.advance();
4881
- const right = this.parseAnd();
4882
- left = isTruthyNum(left) || isTruthyNum(right) ? 1 : 0;
4883
- }
4884
- return left;
4885
- }
4886
- parseAnd() {
4887
- let left = this.parseNot();
4888
- while (this.current().kind === "IDENTIFIER" && this.current().value === "and") {
4889
- this.advance();
4890
- const right = this.parseNot();
4891
- left = isTruthyNum(left) && isTruthyNum(right) ? 1 : 0;
4892
- }
4893
- return left;
4894
- }
4895
- parseNot() {
4896
- if (this.current().kind === "IDENTIFIER" && this.current().value === "not") {
4897
- this.advance();
4898
- const value = this.parseNot();
4899
- return isTruthyNum(value) ? 0 : 1;
4900
- }
4901
- return this.parseComparison();
4902
- }
4903
- parseComparison() {
4904
- let left = this.parseAddition();
4905
- const kind = this.current().kind;
4906
- if (kind === "LT" || kind === "GT" || kind === "LE" || kind === "GE" || kind === "EQ" || kind === "NE") {
4907
- this.advance();
4908
- const right = this.parseAddition();
4909
- switch (kind) {
4910
- case "LT":
4911
- return left < right ? 1 : 0;
4912
- case "GT":
4913
- return left > right ? 1 : 0;
4914
- case "LE":
4915
- return left <= right ? 1 : 0;
4916
- case "GE":
4917
- return left >= right ? 1 : 0;
4918
- case "EQ":
4919
- return left === right ? 1 : 0;
4920
- case "NE":
4921
- return left !== right ? 1 : 0;
4922
- }
4923
- }
4924
- return left;
4925
- }
4926
- parseAddition() {
4927
- let left = this.parseMultiplication();
4928
- while (true) {
4929
- const kind = this.current().kind;
4930
- if (kind === "PLUS") {
4931
- this.advance();
4932
- left = left + this.parseMultiplication();
4933
- } else if (kind === "MINUS") {
4934
- this.advance();
4935
- left = left - this.parseMultiplication();
4936
- } else {
4937
- break;
4938
- }
4939
- }
4940
- return left;
4941
- }
4942
- parseMultiplication() {
4943
- let left = this.parsePower();
4944
- while (true) {
4945
- const kind = this.current().kind;
4946
- if (kind === "STAR") {
4947
- this.advance();
4948
- left = left * this.parsePower();
4949
- } else if (kind === "SLASH") {
4950
- this.advance();
4951
- left = left / this.parsePower();
4952
- } else if (kind === "PERCENT") {
4953
- this.advance();
4954
- left = left % this.parsePower();
4955
- } else {
4956
- break;
4957
- }
4958
- }
4959
- return left;
4960
- }
4961
- parsePower() {
4962
- const left = this.parseUnary();
4963
- if (this.current().kind === "CARET") {
4964
- this.advance();
4965
- const right = this.parsePower();
4966
- return Math.pow(left, right);
4967
- }
4968
- return left;
4969
- }
4970
- parseUnary() {
4971
- const kind = this.current().kind;
4972
- if (kind === "MINUS") {
4973
- this.advance();
4974
- return -this.parseUnary();
4975
- }
4976
- if (kind === "PLUS") {
4977
- this.advance();
4978
- return +this.parseUnary();
4979
- }
4980
- return this.parsePrimary();
4981
- }
4982
- parsePrimary() {
4983
- const token = this.current();
4984
- if (token.kind === "NUMBER") {
4985
- this.advance();
4986
- return token.value;
4987
- }
4988
- if (token.kind === "LPAREN") {
4989
- this.advance();
4990
- const value = this.parseOr();
4991
- if (this.current().kind !== "RPAREN") {
4992
- throw new Error("Expected )");
4993
- }
4994
- this.advance();
4995
- return value;
4996
- }
4997
- if (token.kind === "IDENTIFIER") {
4998
- const name = token.value;
4999
- this.advance();
5000
- if (this.current().kind === "LPAREN") {
5001
- return this.parseFunctionCall(name);
5002
- }
5003
- throw new Error(`undefined constant "${name}"`);
5004
- }
5005
- throw new Error("Expected expression");
5006
- }
5007
- parseFunctionCall(name) {
5008
- if (this.current().kind !== "LPAREN") {
5009
- throw new Error("Expected (");
5010
- }
5011
- this.advance();
5012
- const args = [];
5013
- if (this.current().kind !== "RPAREN") {
5014
- args.push(this.parseOr());
5015
- while (this.current().kind === "COMMA") {
5016
- this.advance();
5017
- args.push(this.parseOr());
5018
- }
5019
- }
5020
- if (this.current().kind !== "RPAREN") {
5021
- throw new Error("Expected )");
5022
- }
5023
- this.advance();
5024
- return this.callFunction(name, args);
5025
- }
5026
- callFunction(name, args) {
5027
- switch (name) {
5028
- case "abs":
5029
- this.checkArgs(name, args, 1);
5030
- return Math.abs(args[0]);
5031
- case "min":
5032
- this.checkArgsMin(name, args, 1);
5033
- return Math.min(...args);
5034
- case "max":
5035
- this.checkArgsMin(name, args, 1);
5036
- return Math.max(...args);
5037
- case "floor":
5038
- this.checkArgs(name, args, 1);
5039
- return Math.floor(args[0]);
5040
- case "ceil":
5041
- this.checkArgs(name, args, 1);
5042
- return Math.ceil(args[0]);
5043
- case "round":
5044
- this.checkArgs(name, args, 1);
5045
- return Math.round(args[0]);
5046
- case "sqrt":
5047
- this.checkArgs(name, args, 1);
5048
- return Math.sqrt(args[0]);
5049
- case "sin":
5050
- this.checkArgs(name, args, 1);
5051
- return Math.sin(args[0]);
5052
- case "cos":
5053
- this.checkArgs(name, args, 1);
5054
- return Math.cos(args[0]);
5055
- case "tan":
5056
- this.checkArgs(name, args, 1);
5057
- return Math.tan(args[0]);
5058
- case "ln":
5059
- this.checkArgs(name, args, 1);
5060
- return Math.log(args[0]);
5061
- case "log":
5062
- this.checkArgs(name, args, 1);
5063
- return Math.log10(args[0]);
5064
- case "exp":
5065
- this.checkArgs(name, args, 1);
5066
- return Math.exp(args[0]);
5067
- case "pow":
5068
- this.checkArgs(name, args, 2);
5069
- return Math.pow(args[0], args[1]);
5070
- default:
5071
- throw new Error(`undefined function "${name}"`);
5072
- }
5073
- }
5074
- checkArgs(name, args, expected) {
5075
- if (args.length !== expected) {
5076
- throw new Error(`${name}() expects ${expected} argument(s), got ${args.length}`);
5077
- }
5078
- }
5079
- checkArgsMin(name, args, min) {
5080
- if (args.length < min) {
5081
- throw new Error(`${name}() expects at least ${min} argument(s), got ${args.length}`);
5082
- }
5083
- }
5084
- }
5085
-
5086
4824
  // packages/render/src/elements/expr.ts
4825
+ var import_ast3 = require("@wdprlib/ast");
5087
4826
  function renderExpr(ctx, data) {
5088
- const result = evaluateExpression(data.expression);
4827
+ const result = import_ast3.evaluateExpression(data.expression);
5089
4828
  if (result.success) {
5090
- ctx.pushEscaped(formatNumber(result.value));
4829
+ ctx.pushEscaped(import_ast3.formatExprValue(result.value));
5091
4830
  } else if (result.error !== "empty expression") {
5092
4831
  ctx.pushEscaped(`run-time error: ${result.error}`);
5093
4832
  }
5094
4833
  }
5095
4834
  function renderIf(ctx, data) {
5096
- const elements = isTruthy(data.condition) ? data.then : data.else;
4835
+ const elements = import_ast3.isTruthy(data.condition) ? data.then : data.else;
5097
4836
  renderBranchElements(ctx, elements);
5098
4837
  }
5099
4838
  function renderIfExpr(ctx, data) {
5100
- const result = evaluateExpression(data.expression);
4839
+ const result = import_ast3.evaluateExpression(data.expression);
5101
4840
  if (!result.success) {
5102
4841
  ctx.pushEscaped(`run-time error: ${result.error}`);
5103
4842
  return;
@@ -5117,12 +4856,6 @@ function renderBranchElements(ctx, elements) {
5117
4856
  }
5118
4857
  renderElements(ctx, elements.slice(0, lastIdx + 1));
5119
4858
  }
5120
- function formatNumber(n) {
5121
- if (Number.isInteger(n)) {
5122
- return String(n);
5123
- }
5124
- return n.toFixed(6).replace(/\.?0+$/, "");
5125
- }
5126
4859
 
5127
4860
  // packages/render/src/render.ts
5128
4861
  function renderToHtml(tree, options = {}) {
@@ -5130,8 +4863,8 @@ function renderToHtml(tree, options = {}) {
5130
4863
  renderElements(ctx, tree.elements);
5131
4864
  if (ctx.settings.allowStyleElements && tree.styles?.length) {
5132
4865
  for (const style of tree.styles) {
5133
- if (style.startsWith(import_ast3.STYLE_SLOT_PREFIX)) {
5134
- const slotId = parseInt(style.slice(import_ast3.STYLE_SLOT_PREFIX.length), 10);
4866
+ if (style.startsWith(import_ast4.STYLE_SLOT_PREFIX)) {
4867
+ const slotId = parseInt(style.slice(import_ast4.STYLE_SLOT_PREFIX.length), 10);
5135
4868
  for (const css of ctx.getStyleSlotContents(slotId)) {
5136
4869
  ctx.push(`<style>${escapeStyleContent(css)}</style>`);
5137
4870
  }
@@ -5288,4 +5021,4 @@ function renderElement(ctx, element) {
5288
5021
  }
5289
5022
 
5290
5023
  // packages/render/src/index.ts
5291
- var import_ast4 = require("@wdprlib/ast");
5024
+ var import_ast5 = require("@wdprlib/ast");