@cortex-js/compute-engine 0.12.7 → 0.14.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 (90) hide show
  1. package/dist/compute-engine.esm.js +1586 -998
  2. package/dist/compute-engine.js +1586 -998
  3. package/dist/compute-engine.min.esm.js +1586 -998
  4. package/dist/compute-engine.min.js +1586 -998
  5. package/dist/math-json.esm.js +2 -2
  6. package/dist/math-json.js +2 -2
  7. package/dist/math-json.min.esm.js +2 -2
  8. package/dist/math-json.min.js +2 -2
  9. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  10. package/dist/types/common/signals.d.ts +1 -1
  11. package/dist/types/common/utils.d.ts +1 -1
  12. package/dist/types/compute-engine/assume.d.ts +1 -1
  13. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +4 -1
  14. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  15. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  16. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +1 -1
  17. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +1 -1
  18. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  19. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  20. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  21. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  22. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +1 -1
  23. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
  24. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  25. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  26. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  27. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  28. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  29. package/dist/types/compute-engine/compile.d.ts +10 -0
  30. package/dist/types/compute-engine/compute-engine.d.ts +9 -8
  31. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  32. package/dist/types/compute-engine/domain-utils.d.ts +1 -1
  33. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  34. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  35. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  36. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  37. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-inequalities.d.ts +1 -1
  38. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  39. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  40. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  41. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  42. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  43. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +32 -17
  44. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  45. package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +12 -6
  46. package/dist/types/compute-engine/latex-syntax/parse.d.ts +30 -20
  47. package/dist/types/compute-engine/latex-syntax/public.d.ts +90 -47
  48. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  49. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  50. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +4 -9
  51. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  52. package/dist/types/compute-engine/library/arithmetic-add.d.ts +1 -2
  53. package/dist/types/compute-engine/library/arithmetic-divide.d.ts +1 -1
  54. package/dist/types/compute-engine/library/arithmetic-multiply.d.ts +1 -1
  55. package/dist/types/compute-engine/library/arithmetic-power.d.ts +1 -1
  56. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  57. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  58. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  59. package/dist/types/compute-engine/library/core.d.ts +1 -1
  60. package/dist/types/compute-engine/library/domains.d.ts +1 -1
  61. package/dist/types/compute-engine/library/library.d.ts +1 -1
  62. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  63. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  64. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  65. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  66. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  67. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  68. package/dist/types/compute-engine/library/utils.d.ts +2 -1
  69. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  70. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  71. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  72. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  73. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  74. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  75. package/dist/types/compute-engine/public.d.ts +4 -1
  76. package/dist/types/compute-engine/rules.d.ts +1 -1
  77. package/dist/types/compute-engine/simplify-rules.d.ts +1 -1
  78. package/dist/types/compute-engine/solve.d.ts +1 -1
  79. package/dist/types/compute-engine/symbolic/expand.d.ts +1 -1
  80. package/dist/types/compute-engine/symbolic/flatten.d.ts +1 -1
  81. package/dist/types/compute-engine/symbolic/negate.d.ts +1 -1
  82. package/dist/types/compute-engine/symbolic/polynomials.d.ts +1 -1
  83. package/dist/types/compute-engine/symbolic/product.d.ts +1 -1
  84. package/dist/types/compute-engine/symbolic/sum.d.ts +1 -1
  85. package/dist/types/compute-engine/symbolic/utils.d.ts +1 -1
  86. package/dist/types/compute-engine.d.ts +2 -2
  87. package/dist/types/math-json/math-json-format.d.ts +1 -1
  88. package/dist/types/math-json/utils.d.ts +7 -1
  89. package/dist/types/math-json.d.ts +2 -2
  90. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- /** CortexJS Compute Engine 0.12.7 */
1
+ /** CortexJS Compute Engine 0.14.0 */
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -3744,7 +3744,7 @@ function tokensToString(tokens) {
3744
3744
  var DEFINITIONS_ALGEBRA = [
3745
3745
  {
3746
3746
  name: "To",
3747
- trigger: ["\\to"],
3747
+ latexTrigger: ["\\to"],
3748
3748
  kind: "infix",
3749
3749
  precedence: 270
3750
3750
  // MathML rightwards arrow
@@ -3949,6 +3949,14 @@ function symbol(expr) {
3949
3949
  return null;
3950
3950
  return s;
3951
3951
  }
3952
+ function isListLike(expr) {
3953
+ if (expr === null)
3954
+ return false;
3955
+ const h = head(expr);
3956
+ if (!h || typeof h !== "string")
3957
+ return false;
3958
+ return /^(List|Sequence|Tuple|Single|Pair|Triple)$/.test(h);
3959
+ }
3952
3960
  function keyValuePair(expr) {
3953
3961
  const h = head(expr);
3954
3962
  if (h === "KeyValuePair" || h === "Tuple" || h === "Pair") {
@@ -3998,10 +4006,10 @@ function machineValue(expr) {
3998
4006
  return null;
3999
4007
  if (typeof expr === "number")
4000
4008
  return expr;
4001
- if (isNumberObject(expr))
4002
- return machineValueOfString(expr.num);
4003
4009
  if (typeof expr === "string")
4004
4010
  return machineValueOfString(expr);
4011
+ if (isNumberObject(expr))
4012
+ return machineValue(expr.num);
4005
4013
  return null;
4006
4014
  }
4007
4015
  function rationalValue(expr) {
@@ -4526,7 +4534,7 @@ var DEFINITIONS_ARITHMETIC = [
4526
4534
  { name: "EulerGamma", serialize: "\\gamma" },
4527
4535
  {
4528
4536
  name: "Degrees",
4529
- trigger: ["\\degree"],
4537
+ latexTrigger: ["\\degree"],
4530
4538
  kind: "postfix",
4531
4539
  precedence: 880,
4532
4540
  parse: (_parser, lhs) => ["Degrees", lhs],
@@ -4535,67 +4543,83 @@ var DEFINITIONS_ARITHMETIC = [
4535
4543
  }
4536
4544
  },
4537
4545
  {
4538
- trigger: ["\\degree"],
4546
+ latexTrigger: ["\\degree"],
4539
4547
  kind: "postfix",
4540
4548
  precedence: 880,
4541
4549
  parse: (_parser, lhs) => ["Degrees", lhs]
4542
4550
  },
4543
4551
  {
4544
- trigger: ["^", "<{>", "\\circ", "<}>"],
4552
+ latexTrigger: ["^", "<{>", "\\circ", "<}>"],
4545
4553
  kind: "postfix",
4546
4554
  parse: (_parser, lhs) => ["Degrees", lhs]
4547
4555
  },
4548
4556
  {
4549
- trigger: ["^", "\\circ"],
4557
+ latexTrigger: ["^", "\\circ"],
4550
4558
  kind: "postfix",
4551
4559
  parse: (_parser, lhs) => ["Degrees", lhs]
4552
4560
  },
4553
4561
  {
4554
- trigger: ["\xB0"],
4562
+ latexTrigger: ["\xB0"],
4555
4563
  kind: "postfix",
4556
4564
  precedence: 880,
4557
4565
  parse: (_parser, lhs) => ["Degrees", lhs]
4558
4566
  },
4559
4567
  {
4560
- trigger: ["\\ang"],
4568
+ latexTrigger: ["\\ang"],
4561
4569
  parse: (parser) => {
4562
4570
  const arg = parser.parseGroup();
4563
4571
  return arg === null ? ["Degrees"] : ["Degrees", arg];
4564
4572
  }
4565
4573
  },
4566
4574
  {
4567
- trigger: ["\\infty"],
4575
+ latexTrigger: ["\\infty"],
4568
4576
  parse: { num: "+Infinity" }
4569
4577
  },
4570
4578
  {
4571
4579
  name: "ComplexInfinity",
4572
- trigger: ["\\tilde", "\\infty"],
4580
+ latexTrigger: ["\\tilde", "\\infty"],
4573
4581
  serialize: "\\tilde\\infty"
4574
4582
  },
4575
4583
  {
4576
- trigger: ["\\tilde", "<{>", "\\infty", "<}>"],
4584
+ latexTrigger: ["\\tilde", "<{>", "\\infty", "<}>"],
4577
4585
  parse: "ComplexInfinity"
4578
4586
  },
4579
- { name: "Pi", kind: "symbol", trigger: ["\\pi"] },
4580
- { trigger: ["\u03C0"], parse: "Pi" },
4587
+ { name: "Pi", kind: "symbol", latexTrigger: ["\\pi"] },
4588
+ { latexTrigger: ["\u03C0"], parse: "Pi" },
4581
4589
  {
4582
4590
  name: "ExponentialE",
4583
- trigger: ["\\exponentialE"],
4591
+ latexTrigger: ["\\exponentialE"],
4584
4592
  parse: "ExponentialE",
4585
4593
  serialize: "\\exponentialE"
4586
4594
  },
4595
+ {
4596
+ latexTrigger: "\\operatorname{e}",
4597
+ parse: "ExponentialE"
4598
+ },
4599
+ {
4600
+ latexTrigger: "\\mathrm{e}",
4601
+ parse: "ExponentialE"
4602
+ },
4587
4603
  {
4588
4604
  kind: "function",
4589
- trigger: "exp",
4605
+ identifierTrigger: "exp",
4590
4606
  parse: "Exp"
4591
4607
  },
4592
4608
  {
4593
- trigger: "\\exp",
4609
+ latexTrigger: "\\exp",
4594
4610
  parse: "Exp"
4595
4611
  },
4596
4612
  {
4597
4613
  name: "ImaginaryUnit",
4598
- trigger: ["\\imaginaryI"]
4614
+ latexTrigger: ["\\imaginaryI"]
4615
+ },
4616
+ {
4617
+ latexTrigger: "\\operatorname{i}",
4618
+ parse: "ImaginaryUnit"
4619
+ },
4620
+ {
4621
+ latexTrigger: "\\mathrm{i}",
4622
+ parse: "ImaginaryUnit"
4599
4623
  },
4600
4624
  // Operations
4601
4625
  {
@@ -4605,18 +4629,18 @@ var DEFINITIONS_ARITHMETIC = [
4605
4629
  * replaced with bars */
4606
4630
  name: "Abs",
4607
4631
  kind: "matchfix",
4608
- openDelimiter: "|",
4609
- closeDelimiter: "|",
4610
- parse: (_parser, expr) => isEmptySequence(expr) ? null : ["Abs", expr]
4632
+ openTrigger: "|",
4633
+ closeTrigger: "|",
4634
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Abs", body]
4611
4635
  },
4612
4636
  {
4613
- trigger: "abs",
4637
+ identifierTrigger: "abs",
4614
4638
  kind: "function",
4615
4639
  parse: "Abs"
4616
4640
  },
4617
4641
  {
4618
4642
  name: "Add",
4619
- trigger: ["+"],
4643
+ latexTrigger: ["+"],
4620
4644
  kind: "infix",
4621
4645
  associativity: "both",
4622
4646
  precedence: 275,
@@ -4632,7 +4656,7 @@ var DEFINITIONS_ARITHMETIC = [
4632
4656
  },
4633
4657
  {
4634
4658
  kind: "prefix",
4635
- trigger: ["+"],
4659
+ latexTrigger: ["+"],
4636
4660
  precedence: 275,
4637
4661
  parse: (parser, until) => {
4638
4662
  if (until && 275 < until.minPrec)
@@ -4643,20 +4667,22 @@ var DEFINITIONS_ARITHMETIC = [
4643
4667
  {
4644
4668
  name: "Ceil",
4645
4669
  kind: "matchfix",
4646
- openDelimiter: "\\lceil",
4647
- closeDelimiter: "\\rceil"
4670
+ openTrigger: "\\lceil",
4671
+ closeTrigger: "\\rceil",
4672
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Ceil", body]
4648
4673
  },
4649
4674
  {
4650
4675
  kind: "matchfix",
4651
- openDelimiter: ["\u2308"],
4652
- closeDelimiter: ["\u2309"],
4653
- parse: (_, body) => ["Ceil", body]
4676
+ openTrigger: ["\u2308"],
4677
+ closeTrigger: ["\u2309"],
4678
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Ceil", body]
4654
4679
  },
4655
4680
  {
4656
- trigger: "ceil",
4681
+ identifierTrigger: "ceil",
4657
4682
  kind: "function",
4658
4683
  parse: "Ceil"
4659
4684
  },
4685
+ { name: "Chop", identifierTrigger: "chop", kind: "function", parse: "Chop" },
4660
4686
  {
4661
4687
  name: "Complex",
4662
4688
  precedence: 274,
@@ -4676,7 +4702,7 @@ var DEFINITIONS_ARITHMETIC = [
4676
4702
  },
4677
4703
  {
4678
4704
  name: "Divide",
4679
- trigger: "\\frac",
4705
+ latexTrigger: "\\frac",
4680
4706
  precedence: 660,
4681
4707
  // For \frac specifically, not for \div, etc..
4682
4708
  // handles Leibnitz notation for partial derivatives
@@ -4685,12 +4711,12 @@ var DEFINITIONS_ARITHMETIC = [
4685
4711
  },
4686
4712
  {
4687
4713
  kind: "infix",
4688
- trigger: "\\over",
4714
+ latexTrigger: "\\over",
4689
4715
  precedence: 660,
4690
4716
  parse: "Divide"
4691
4717
  },
4692
4718
  {
4693
- trigger: ["\\/"],
4719
+ latexTrigger: ["\\/"],
4694
4720
  kind: "infix",
4695
4721
  associativity: "non",
4696
4722
  precedence: 660,
@@ -4700,14 +4726,14 @@ var DEFINITIONS_ARITHMETIC = [
4700
4726
  parse: "Divide"
4701
4727
  },
4702
4728
  {
4703
- trigger: ["/"],
4729
+ latexTrigger: ["/"],
4704
4730
  kind: "infix",
4705
4731
  associativity: "non",
4706
4732
  precedence: 660,
4707
4733
  parse: "Divide"
4708
4734
  },
4709
4735
  {
4710
- trigger: ["\\div"],
4736
+ latexTrigger: ["\\div"],
4711
4737
  kind: "infix",
4712
4738
  associativity: "non",
4713
4739
  precedence: 660,
@@ -4725,36 +4751,41 @@ var DEFINITIONS_ARITHMETIC = [
4725
4751
  },
4726
4752
  {
4727
4753
  name: "Factorial",
4728
- trigger: ["!"],
4754
+ latexTrigger: ["!"],
4729
4755
  kind: "postfix",
4730
4756
  precedence: 810
4731
4757
  },
4732
4758
  {
4733
4759
  name: "Factorial2",
4734
- trigger: ["!", "!"],
4760
+ latexTrigger: ["!", "!"],
4735
4761
  kind: "postfix",
4736
4762
  precedence: 810
4737
4763
  },
4738
4764
  {
4739
4765
  name: "Floor",
4740
4766
  kind: "matchfix",
4741
- openDelimiter: "\\lfloor",
4742
- closeDelimiter: "\\rfloor"
4767
+ openTrigger: "\\lfloor",
4768
+ closeTrigger: "\\rfloor",
4769
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Floor", body]
4743
4770
  },
4744
4771
  {
4745
4772
  kind: "matchfix",
4746
- openDelimiter: ["\u230A"],
4747
- closeDelimiter: ["\u230B"],
4748
- parse: (_, body) => ["Floor", body]
4773
+ openTrigger: ["\u230A"],
4774
+ closeTrigger: ["\u230B"],
4775
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Floor", body]
4749
4776
  },
4750
4777
  {
4751
- trigger: "floor",
4778
+ identifierTrigger: "floor",
4752
4779
  kind: "function",
4753
4780
  parse: "Floor"
4754
4781
  },
4782
+ {
4783
+ latexTrigger: ["\\Gamma"],
4784
+ parse: "Gamma"
4785
+ },
4755
4786
  {
4756
4787
  name: "Gcd",
4757
- trigger: "gcd",
4788
+ identifierTrigger: "gcd",
4758
4789
  kind: "function"
4759
4790
  },
4760
4791
  {
@@ -4763,34 +4794,34 @@ var DEFINITIONS_ARITHMETIC = [
4763
4794
  },
4764
4795
  {
4765
4796
  name: "Lg",
4766
- trigger: ["\\lg"],
4797
+ latexTrigger: ["\\lg"],
4767
4798
  serialize: (serializer, expr) => "\\log_{10}" + serializer.wrapArguments(expr),
4768
4799
  parse: (parser) => {
4769
- const arg = parser.parseArguments("implicit");
4770
- if (arg === null)
4800
+ const args = parser.parseArguments("implicit");
4801
+ if (args === null)
4771
4802
  return "Lg";
4772
- return ["Log", ...arg, 10];
4803
+ return ["Log", ...args, 10];
4773
4804
  }
4774
4805
  },
4775
4806
  {
4776
4807
  name: "Lb",
4777
- trigger: "\\lb",
4808
+ latexTrigger: "\\lb",
4778
4809
  parse: (parser) => {
4779
- const arg = parser.parseArguments("implicit");
4780
- if (arg === null)
4810
+ const args = parser.parseArguments("implicit");
4811
+ if (args === null)
4781
4812
  return "Log";
4782
- return ["Log", ...arg, 2];
4813
+ return ["Log", ...args, 2];
4783
4814
  }
4784
4815
  },
4785
4816
  {
4786
4817
  name: "Ln",
4787
- trigger: ["\\ln"],
4818
+ latexTrigger: ["\\ln"],
4788
4819
  serialize: (serializer, expr) => "\\ln" + serializer.wrapArguments(expr),
4789
4820
  parse: (parser) => parseLog("Ln", parser)
4790
4821
  },
4791
4822
  {
4792
4823
  name: "Log",
4793
- trigger: ["\\log"],
4824
+ latexTrigger: ["\\log"],
4794
4825
  parse: (parser) => parseLog("Log", parser),
4795
4826
  serialize: (serializer, expr) => {
4796
4827
  const base = op2(expr);
@@ -4806,32 +4837,32 @@ var DEFINITIONS_ARITHMETIC = [
4806
4837
  },
4807
4838
  {
4808
4839
  name: "Lcm",
4809
- trigger: "lcm",
4840
+ identifierTrigger: "lcm",
4810
4841
  kind: "function"
4811
4842
  },
4843
+ { name: "Max", identifierTrigger: "max", kind: "function" },
4844
+ { name: "Min", identifierTrigger: "min", kind: "function" },
4812
4845
  {
4813
4846
  name: "MinusPlus",
4814
- trigger: ["\\mp"],
4847
+ latexTrigger: ["\\mp"],
4815
4848
  kind: "infix",
4816
4849
  associativity: "both",
4817
4850
  precedence: 270
4818
4851
  },
4819
4852
  {
4820
4853
  name: "Multiply",
4821
- trigger: ["\\times"],
4854
+ latexTrigger: ["\\times"],
4822
4855
  kind: "infix",
4823
4856
  associativity: "both",
4824
4857
  precedence: 390,
4825
4858
  serialize: serializeMultiply
4826
4859
  },
4827
4860
  {
4828
- trigger: ["\\cdot"],
4861
+ latexTrigger: ["\\cdot"],
4829
4862
  kind: "infix",
4830
4863
  associativity: "both",
4831
4864
  precedence: 390,
4832
4865
  parse: (parser, lhs, terminator) => {
4833
- if (terminator && 391 < terminator.minPrec)
4834
- return null;
4835
4866
  const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4836
4867
  if (rhs === null)
4837
4868
  return ["Multiply", lhs, MISSING];
@@ -4839,13 +4870,11 @@ var DEFINITIONS_ARITHMETIC = [
4839
4870
  }
4840
4871
  },
4841
4872
  {
4842
- trigger: ["*"],
4873
+ latexTrigger: ["*"],
4843
4874
  kind: "infix",
4844
4875
  associativity: "both",
4845
4876
  precedence: 390,
4846
4877
  parse: (parser, lhs, terminator) => {
4847
- if (terminator && 391 < terminator.minPrec)
4848
- return null;
4849
4878
  const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4850
4879
  if (rhs === null)
4851
4880
  return ["Multiply", lhs, MISSING];
@@ -4854,11 +4883,9 @@ var DEFINITIONS_ARITHMETIC = [
4854
4883
  },
4855
4884
  {
4856
4885
  name: "Negate",
4857
- trigger: ["-"],
4886
+ latexTrigger: ["-"],
4858
4887
  kind: "prefix",
4859
4888
  parse: (parser, terminator) => {
4860
- if (terminator && 276 < terminator.minPrec)
4861
- return null;
4862
4889
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4863
4890
  return ["Negate", missingIfEmpty(rhs)];
4864
4891
  },
@@ -4884,8 +4911,8 @@ var DEFINITIONS_ARITHMETIC = [
4884
4911
  // /** If the argument is a vector */
4885
4912
  /** @todo: domain check */
4886
4913
  kind: "matchfix",
4887
- openDelimiter: "||",
4888
- closeDelimiter: "||",
4914
+ openTrigger: "||",
4915
+ closeTrigger: "||",
4889
4916
  parse: (_parser, expr) => isEmptySequence(expr) ? null : ["Norm", expr]
4890
4917
  },
4891
4918
  {
@@ -4893,12 +4920,13 @@ var DEFINITIONS_ARITHMETIC = [
4893
4920
  /** @todo: domain check */
4894
4921
  name: "Norm",
4895
4922
  kind: "matchfix",
4896
- openDelimiter: ["\\left", "\\Vert"],
4897
- closeDelimiter: ["\\right", "\\Vert"]
4923
+ openTrigger: ["\\left", "\\Vert"],
4924
+ closeTrigger: ["\\right", "\\Vert"],
4925
+ parse: (_parser, expr) => isEmptySequence(expr) ? null : ["Norm", expr]
4898
4926
  },
4899
4927
  {
4900
4928
  name: "PlusMinus",
4901
- trigger: ["\\pm"],
4929
+ latexTrigger: ["\\pm"],
4902
4930
  kind: "infix",
4903
4931
  associativity: "both",
4904
4932
  precedence: 270,
@@ -4917,47 +4945,41 @@ var DEFINITIONS_ARITHMETIC = [
4917
4945
  }
4918
4946
  },
4919
4947
  {
4920
- trigger: ["\\pm"],
4948
+ latexTrigger: ["\\pm"],
4921
4949
  kind: "prefix",
4922
4950
  precedence: 270,
4923
4951
  parse: (parser, terminator) => {
4924
- if (terminator && 270 < terminator.minPrec)
4925
- return null;
4926
4952
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4927
4953
  return ["PlusMinus", missingIfEmpty(rhs)];
4928
4954
  }
4929
4955
  },
4930
4956
  {
4931
- trigger: ["\\plusmn"],
4957
+ latexTrigger: ["\\plusmn"],
4932
4958
  kind: "infix",
4933
4959
  associativity: "both",
4934
4960
  precedence: 270,
4935
4961
  parse: (parser, lhs, terminator) => {
4936
- if (270 < terminator.minPrec)
4937
- return null;
4938
4962
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4939
4963
  return ["PlusMinus", lhs, missingIfEmpty(rhs)];
4940
4964
  }
4941
4965
  },
4942
4966
  {
4943
- trigger: ["\\plusmn"],
4967
+ latexTrigger: ["\\plusmn"],
4944
4968
  kind: "prefix",
4945
4969
  precedence: 270,
4946
4970
  parse: (parser, terminator) => {
4947
- if (terminator && 270 < terminator.minPrec)
4948
- return null;
4949
4971
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4950
4972
  return ["PlusMinus", missingIfEmpty(rhs)];
4951
4973
  }
4952
4974
  },
4953
4975
  {
4954
4976
  name: "Power",
4955
- trigger: ["^"],
4977
+ latexTrigger: ["^"],
4956
4978
  kind: "infix",
4957
4979
  serialize: serializePower
4958
4980
  },
4959
4981
  {
4960
- trigger: "\\prod",
4982
+ latexTrigger: "\\prod",
4961
4983
  precedence: 390,
4962
4984
  name: "Product",
4963
4985
  parse: parseBigOp("Product", 390),
@@ -4974,7 +4996,7 @@ var DEFINITIONS_ARITHMETIC = [
4974
4996
  precedence: 660,
4975
4997
  serialize: (serializer, expr) => {
4976
4998
  if (expr && nops(expr) === 1)
4977
- return "\\mathrm{Rational}" + serializer.wrapArguments(expr);
4999
+ return "\\operatorname{Rational}" + serializer.wrapArguments(expr);
4978
5000
  return serializeFraction(serializer, expr);
4979
5001
  }
4980
5002
  },
@@ -4984,7 +5006,7 @@ var DEFINITIONS_ARITHMETIC = [
4984
5006
  },
4985
5007
  {
4986
5008
  name: "Round",
4987
- trigger: "round",
5009
+ identifierTrigger: "round",
4988
5010
  kind: "function"
4989
5011
  },
4990
5012
  {
@@ -4993,7 +5015,7 @@ var DEFINITIONS_ARITHMETIC = [
4993
5015
  serialize: (serializer, expr) => serializer.wrapShort(op(expr, 1)) + "^2"
4994
5016
  },
4995
5017
  {
4996
- trigger: "\\sum",
5018
+ latexTrigger: ["\\sum"],
4997
5019
  precedence: 275,
4998
5020
  name: "Sum",
4999
5021
  parse: parseBigOp("Sum", 275),
@@ -5002,24 +5024,22 @@ var DEFINITIONS_ARITHMETIC = [
5002
5024
  {
5003
5025
  name: "Sign",
5004
5026
  // As per ISO 80000-2, "signum" is 'sgn'
5005
- trigger: "sgn",
5027
+ identifierTrigger: "sgn",
5006
5028
  kind: "function"
5007
5029
  },
5008
5030
  {
5009
5031
  name: "Sqrt",
5010
- trigger: ["\\sqrt"],
5032
+ latexTrigger: ["\\sqrt"],
5011
5033
  parse: parseRoot,
5012
5034
  serialize: serializePower
5013
5035
  },
5014
5036
  {
5015
5037
  name: "Subtract",
5016
- trigger: ["-"],
5038
+ latexTrigger: ["-"],
5017
5039
  kind: "infix",
5018
5040
  associativity: "both",
5019
5041
  precedence: 275,
5020
5042
  parse: (parser, lhs, terminator) => {
5021
- if (276 < terminator.minPrec)
5022
- return null;
5023
5043
  const rhs = parser.parseExpression({ ...terminator, minPrec: 277 });
5024
5044
  return ["Subtract", lhs, missingIfEmpty(rhs)];
5025
5045
  }
@@ -5116,16 +5136,16 @@ function parseLog(command, parser) {
5116
5136
  sub2 = parser.parseStringGroup()?.trim() ?? parser.nextToken();
5117
5137
  base = Number.parseFloat(sub2 ?? "10");
5118
5138
  }
5119
- const arg = parser.parseArguments("implicit");
5120
- if (arg === null)
5139
+ const args = parser.parseArguments("implicit");
5140
+ if (args === null)
5121
5141
  return [command];
5122
5142
  if (base === 10)
5123
- return ["Log", arg[0]];
5143
+ return ["Log", args[0]];
5124
5144
  if (base === 2)
5125
- return ["Lb", ...arg];
5145
+ return ["Lb", ...args];
5126
5146
  if (sub2 === null)
5127
- return [command, ...arg];
5128
- return ["Log", ...arg, sub2];
5147
+ return [command, ...args];
5148
+ return ["Log", ...args, sub2];
5129
5149
  }
5130
5150
 
5131
5151
  // src/compute-engine/latex-syntax/dictionary/definitions-core.ts
@@ -5156,7 +5176,7 @@ function parseSequence(parser, terminator, lhs, prec, sep) {
5156
5176
  }
5157
5177
  return result;
5158
5178
  }
5159
- function serializeSequence(sep = "") {
5179
+ function serializeOps(sep = "") {
5160
5180
  return (serializer, expr) => (ops(expr) ?? []).map((x) => serializer.serialize(x)).join(sep);
5161
5181
  }
5162
5182
  var DEFINITIONS_CORE = [
@@ -5164,7 +5184,7 @@ var DEFINITIONS_CORE = [
5164
5184
  // Constants
5165
5185
  //
5166
5186
  {
5167
- trigger: ["\\placeholder"],
5187
+ latexTrigger: ["\\placeholder"],
5168
5188
  kind: "symbol",
5169
5189
  parse: (parser) => {
5170
5190
  while (parser.match("<space>")) {
@@ -5183,6 +5203,27 @@ var DEFINITIONS_CORE = [
5183
5203
  //
5184
5204
  // Functions
5185
5205
  //
5206
+ {
5207
+ name: "Apply",
5208
+ kind: "function",
5209
+ identifierTrigger: "apply",
5210
+ serialize: (serializer, expr) => serializer.serializeFunction(ops(expr))
5211
+ },
5212
+ {
5213
+ latexTrigger: "\\rhd",
5214
+ kind: "infix",
5215
+ precedence: 20,
5216
+ parse: "Apply"
5217
+ },
5218
+ {
5219
+ latexTrigger: "\\lhd",
5220
+ kind: "infix",
5221
+ precedence: 20,
5222
+ parse: (parser, lhs) => {
5223
+ const rhs = parser.parseExpression({ minPrec: 20 }) ?? "Nothing";
5224
+ return ["Apply", rhs, lhs];
5225
+ }
5226
+ },
5186
5227
  {
5187
5228
  name: "BaseForm",
5188
5229
  serialize: (serializer, expr) => {
@@ -5224,22 +5265,19 @@ var DEFINITIONS_CORE = [
5224
5265
  return "";
5225
5266
  const style = serializer.options.groupStyle(expr, serializer.level + 1);
5226
5267
  const arg1 = op(expr, 1);
5227
- if (argCount === 1)
5228
- return serializer.wrapString(serializer.serialize(arg1), style);
5229
- let sep = "";
5230
- let open = "";
5231
- let close = "";
5268
+ const h1 = head(arg1);
5269
+ const defaultFence = { List: "[],", Sequence: "" }[typeof h1 === "string" ? h1 : ""] ?? "(),";
5270
+ let open = defaultFence[0] ?? "";
5271
+ let close = defaultFence[1] ?? "";
5272
+ let sep = defaultFence[2] ?? "";
5232
5273
  if (argCount > 1) {
5233
5274
  const op22 = stringValue(op(expr, 2)) ?? "";
5234
- open = op22[0] ?? "(";
5235
- close = op22[1] ?? ")";
5236
- sep = op22[2] ?? ",";
5275
+ open = op22[0] ?? defaultFence[0];
5276
+ close = op22[1] ?? defaultFence[1];
5277
+ sep = op22[2] ?? defaultFence[2];
5237
5278
  }
5238
- const body = head(arg1) === "List" ? serializeSequence(sep)(serializer, arg1) : serializer.serialize(arg1);
5239
- serializer.wrapString(body, style, stringValue(op(expr, 2)) ?? void 0);
5240
- if (!open || !close)
5241
- return serializer.wrapString(body, style);
5242
- return `${open} ${body} ${close}`;
5279
+ const body = isListLike(arg1) ? serializeOps(sep)(serializer, arg1) : serializer.serialize(arg1);
5280
+ return serializer.wrapString(body, style, open + close);
5243
5281
  }
5244
5282
  },
5245
5283
  {
@@ -5251,7 +5289,7 @@ var DEFINITIONS_CORE = [
5251
5289
  }
5252
5290
  },
5253
5291
  {
5254
- trigger: ["\\mathtip"],
5292
+ latexTrigger: ["\\mathtip"],
5255
5293
  parse: (parser) => {
5256
5294
  const op12 = parser.parseGroup();
5257
5295
  const op22 = parser.parseGroup();
@@ -5259,7 +5297,7 @@ var DEFINITIONS_CORE = [
5259
5297
  }
5260
5298
  },
5261
5299
  {
5262
- trigger: ["\\texttip"],
5300
+ latexTrigger: ["\\texttip"],
5263
5301
  parse: (parser) => {
5264
5302
  const op12 = parser.parseGroup();
5265
5303
  const op22 = parser.parseGroup();
@@ -5267,8 +5305,8 @@ var DEFINITIONS_CORE = [
5267
5305
  }
5268
5306
  },
5269
5307
  {
5270
- trigger: ["\\error"],
5271
- parse: (parser) => parser.parseGroup()
5308
+ latexTrigger: ["\\error"],
5309
+ parse: (parser) => ["Error", parser.parseGroup()]
5272
5310
  },
5273
5311
  {
5274
5312
  name: "Error",
@@ -5328,10 +5366,10 @@ var DEFINITIONS_CORE = [
5328
5366
  {
5329
5367
  name: "List",
5330
5368
  kind: "matchfix",
5331
- openDelimiter: "[",
5332
- closeDelimiter: "]",
5369
+ openTrigger: "[",
5370
+ closeTrigger: "]",
5333
5371
  parse: (_parser, body) => {
5334
- if (body === null)
5372
+ if (body === null || isEmptySequence(body))
5335
5373
  return ["List"];
5336
5374
  if (head(body) !== "Sequence" && head(body) !== "List")
5337
5375
  return ["List", body];
@@ -5340,18 +5378,18 @@ var DEFINITIONS_CORE = [
5340
5378
  serialize: (serializer, expr) => {
5341
5379
  return joinLatex([
5342
5380
  "\\lbrack",
5343
- serializeSequence(", ")(serializer, expr),
5381
+ serializeOps(", ")(serializer, expr),
5344
5382
  "\\rbrack"
5345
5383
  ]);
5346
5384
  }
5347
5385
  },
5348
5386
  {
5349
5387
  kind: "matchfix",
5350
- openDelimiter: "(",
5351
- closeDelimiter: ")",
5388
+ openTrigger: "(",
5389
+ closeTrigger: ")",
5352
5390
  parse: (_parser, body) => {
5353
- if (body === null)
5354
- return null;
5391
+ if (body === null || isEmptySequence(body))
5392
+ return ["Sequence"];
5355
5393
  if (head(body) === "Sequence" || head(body) === "List") {
5356
5394
  if (nops(body) === 0)
5357
5395
  return ["Delimiter"];
@@ -5361,7 +5399,7 @@ var DEFINITIONS_CORE = [
5361
5399
  }
5362
5400
  },
5363
5401
  {
5364
- trigger: [","],
5402
+ latexTrigger: [","],
5365
5403
  kind: "infix",
5366
5404
  precedence: 20,
5367
5405
  // Unlike the matchfix version of List,
@@ -5378,10 +5416,10 @@ var DEFINITIONS_CORE = [
5378
5416
  },
5379
5417
  {
5380
5418
  name: "Sequence",
5381
- serialize: serializeSequence("")
5419
+ serialize: serializeOps("")
5382
5420
  },
5383
5421
  {
5384
- trigger: [";"],
5422
+ latexTrigger: [";"],
5385
5423
  kind: "infix",
5386
5424
  precedence: 19,
5387
5425
  parse: (parser, lhs, terminator) => {
@@ -5398,7 +5436,7 @@ var DEFINITIONS_CORE = [
5398
5436
  },
5399
5437
  {
5400
5438
  name: "String",
5401
- trigger: ["\\text"],
5439
+ latexTrigger: ["\\text"],
5402
5440
  parse: (scanner) => parseTextRun(scanner),
5403
5441
  serialize: (serializer, expr) => {
5404
5442
  const args = ops(expr);
@@ -5413,7 +5451,7 @@ var DEFINITIONS_CORE = [
5413
5451
  },
5414
5452
  {
5415
5453
  name: "Subscript",
5416
- trigger: ["_"],
5454
+ latexTrigger: ["_"],
5417
5455
  kind: "infix",
5418
5456
  serialize: (serializer, expr) => {
5419
5457
  if (nops(expr) === 2) {
@@ -5422,53 +5460,121 @@ var DEFINITIONS_CORE = [
5422
5460
  return "_{" + serializer.serialize(op(expr, 1)) + "}";
5423
5461
  }
5424
5462
  },
5425
- { name: "Superplus", trigger: ["^", "+"], kind: "postfix" },
5426
- { name: "Subplus", trigger: ["_", "+"], kind: "postfix" },
5427
- { name: "Superminus", trigger: ["^", "-"], kind: "postfix" },
5428
- { name: "Subminus", trigger: ["_", "-"], kind: "postfix" },
5463
+ { name: "Superplus", latexTrigger: ["^", "+"], kind: "postfix" },
5464
+ { name: "Subplus", latexTrigger: ["_", "+"], kind: "postfix" },
5465
+ { name: "Superminus", latexTrigger: ["^", "-"], kind: "postfix" },
5466
+ { name: "Subminus", latexTrigger: ["_", "-"], kind: "postfix" },
5429
5467
  {
5430
- trigger: ["^", "*"],
5468
+ latexTrigger: ["^", "*"],
5431
5469
  kind: "postfix",
5432
5470
  parse: (_parser, lhs) => ["Superstar", lhs]
5433
5471
  },
5434
5472
  // @todo: when lhs is a complex number, 'Conjugate'
5435
5473
  // { name: 'Conjugate', trigger: ['\\star'], kind: 'infix' },
5436
- { name: "Superstar", trigger: ["^", "\\star"], kind: "postfix" },
5474
+ { name: "Superstar", latexTrigger: ["^", "\\star"], kind: "postfix" },
5437
5475
  {
5438
- trigger: ["_", "*"],
5476
+ latexTrigger: ["_", "*"],
5439
5477
  kind: "postfix",
5440
5478
  parse: (_parser, lhs) => ["Substar", lhs]
5441
5479
  },
5442
- { name: "Substar", trigger: ["_", "\\star"], kind: "postfix" },
5443
- { name: "Superdagger", trigger: ["^", "\\dagger"], kind: "postfix" },
5480
+ { name: "Substar", latexTrigger: ["_", "\\star"], kind: "postfix" },
5481
+ { name: "Superdagger", latexTrigger: ["^", "\\dagger"], kind: "postfix" },
5444
5482
  {
5445
- trigger: ["^", "\\dag"],
5483
+ latexTrigger: ["^", "\\dag"],
5446
5484
  kind: "postfix",
5447
5485
  parse: (_parser, lhs) => ["Superdagger", lhs]
5448
5486
  },
5449
5487
  {
5450
5488
  name: "Prime",
5451
- trigger: ["^", "\\prime"],
5452
- kind: "postfix"
5489
+ latexTrigger: ["^", "\\prime"],
5490
+ // Note: we don't need a precedence because the trigger is '^'
5491
+ // and '^' (and '_') are treated specially by the parser.
5492
+ kind: "postfix",
5493
+ parse: (parser, lhs) => parsePrime(parser, lhs, 1),
5494
+ serialize: (serializer, expr) => {
5495
+ const n2 = machineValue(op(expr, 2)) ?? 1;
5496
+ const base = serializer.serialize(op(expr, 1));
5497
+ if (n2 === 1)
5498
+ return base + "^\\prime";
5499
+ if (n2 === 2)
5500
+ return base + "^\\doubleprime";
5501
+ if (n2 === 3)
5502
+ return base + "^\\tripleprime";
5503
+ return base + "^{(" + serializer.serialize(op(expr, 2)) + ")}";
5504
+ }
5505
+ },
5506
+ {
5507
+ latexTrigger: "^{\\prime\\prime}",
5508
+ kind: "postfix",
5509
+ parse: (parser, lhs) => parsePrime(parser, lhs, 2)
5510
+ },
5511
+ {
5512
+ latexTrigger: "^{\\prime\\prime\\prime}",
5513
+ kind: "postfix",
5514
+ parse: (parser, lhs) => parsePrime(parser, lhs, 3)
5515
+ },
5516
+ {
5517
+ latexTrigger: ["^", "\\doubleprime"],
5518
+ kind: "postfix",
5519
+ parse: (parser, lhs) => parsePrime(parser, lhs, 2)
5453
5520
  },
5454
5521
  {
5455
- trigger: ["^", "\\doubleprime"],
5522
+ latexTrigger: ["^", "\\tripleprime"],
5456
5523
  kind: "postfix",
5457
- parse: (_parser, lhs) => ["Prime", missingIfEmpty(lhs), 2]
5524
+ parse: (parser, lhs) => parsePrime(parser, lhs, 3)
5458
5525
  },
5459
5526
  {
5460
- trigger: ["^", "\\tripleprime"],
5527
+ latexTrigger: "'",
5461
5528
  kind: "postfix",
5462
- parse: (_parser, lhs) => ["Prime", missingIfEmpty(lhs), 3]
5529
+ precedence: 810,
5530
+ parse: (parser, lhs) => parsePrime(parser, lhs, 1)
5531
+ },
5532
+ {
5533
+ latexTrigger: "\\prime",
5534
+ kind: "postfix",
5535
+ precedence: 810,
5536
+ parse: (parser, lhs) => parsePrime(parser, lhs, 1)
5537
+ },
5538
+ {
5539
+ latexTrigger: "\\doubleprime",
5540
+ kind: "postfix",
5541
+ precedence: 810,
5542
+ parse: (parser, lhs) => parsePrime(parser, lhs, 2)
5543
+ },
5544
+ {
5545
+ latexTrigger: "\\tripleprime",
5546
+ kind: "postfix",
5547
+ precedence: 810,
5548
+ parse: (parser, lhs) => parsePrime(parser, lhs, 3)
5549
+ },
5550
+ {
5551
+ latexTrigger: ["^", "<{>", "("],
5552
+ kind: "postfix",
5553
+ parse: (parser, lhs) => {
5554
+ if (!parser.computeEngine?.box(lhs)?.domain.isFunction)
5555
+ return null;
5556
+ const start = parser.index;
5557
+ parser.addBoundary([")"]);
5558
+ const expr = parser.parseExpression();
5559
+ if (!parser.matchBoundary()) {
5560
+ parser.index = start;
5561
+ return null;
5562
+ }
5563
+ if (!parser.match("<}>")) {
5564
+ parser.index = start;
5565
+ return null;
5566
+ }
5567
+ return ["Derivative", lhs, expr];
5568
+ }
5463
5569
  },
5464
5570
  {
5465
5571
  name: "InverseFunction",
5466
- trigger: "^{-1}",
5572
+ latexTrigger: "^{-1}",
5467
5573
  kind: "postfix",
5468
5574
  parse: (parser, lhs) => {
5469
5575
  if (parser.computeEngine?.box(lhs)?.domain.isFunction)
5470
5576
  return ["InverseFunction", lhs];
5471
- return null;
5577
+ return ["Power", missingIfEmpty(lhs), -1];
5472
5578
  },
5473
5579
  serialize: (serializer, expr) => serializer.serialize(op(expr, 1)) + "^{-1}"
5474
5580
  },
@@ -5483,13 +5589,13 @@ var DEFINITIONS_CORE = [
5483
5589
  return base + "^{\\doubleprime}";
5484
5590
  if (degree === 3)
5485
5591
  return base + "^{\\tripleprime}";
5486
- return base + "^{(" + Number(degree).toString() + ")}";
5592
+ return base + "^{(" + serializer.serialize(op(expr, 2)) + ")}";
5487
5593
  }
5488
5594
  },
5489
5595
  {
5490
- name: "Which",
5491
- trigger: "cases",
5492
5596
  kind: "environment",
5597
+ name: "Which",
5598
+ identifierTrigger: "cases",
5493
5599
  parse: (parser) => {
5494
5600
  const tabular = parser.parseTabular();
5495
5601
  if (!tabular)
@@ -5508,24 +5614,17 @@ var DEFINITIONS_CORE = [
5508
5614
  return result;
5509
5615
  },
5510
5616
  serialize: (serialize2, expr) => {
5511
- if (head(op(expr, 1)) !== "List")
5512
- return "";
5513
- const rows = ops(op(expr, 1)) ?? [];
5514
- const body = [];
5515
- let rowSep = "";
5516
- for (const row of rows) {
5517
- if (head(row) === "Tuple" || head(row) === "Pair") {
5518
- body.push(rowSep);
5519
- if (op(row, 2)) {
5520
- body.push(serialize2.serialize(op(row, 2)));
5521
- const condition = op(row, 1);
5522
- if (condition !== null)
5523
- body.push("&", serialize2.serialize(condition));
5524
- }
5617
+ const rows = [];
5618
+ const args = ops(expr);
5619
+ if (args) {
5620
+ for (let i = 0; i <= args.length - 2; i += 2) {
5621
+ const row = [];
5622
+ row.push(serialize2.serialize(args[i + 1]));
5623
+ row.push(serialize2.serialize(args[i]));
5624
+ rows.push(row.join("&"));
5525
5625
  }
5526
- rowSep = "\\\\";
5527
5626
  }
5528
- return joinLatex(["\\begin{cases}", ...body, "\\end{cases}"]);
5627
+ return joinLatex(["\\begin{cases}", rows.join("\\\\"), "\\end{cases}"]);
5529
5628
  }
5530
5629
  }
5531
5630
  ];
@@ -5639,11 +5738,26 @@ function errorContextAsLatex(serializer, error) {
5639
5738
  return serializer.serialize(op(arg, 1));
5640
5739
  return serializer.serialize(arg);
5641
5740
  }
5741
+ function parsePrime(parser, lhs, order2) {
5742
+ const lhsh = head(lhs);
5743
+ if (lhsh === "Derivative" || lhsh === "Prime") {
5744
+ const n = machineValue(op(lhs, 2)) ?? 1;
5745
+ return [lhsh, missingIfEmpty(op(lhs, 1)), n + order2];
5746
+ }
5747
+ if (parser.computeEngine?.box(lhs)?.domain.isFunction) {
5748
+ if (order2 === 1)
5749
+ return ["Derivative", lhs];
5750
+ return ["Derivative", lhs, order2];
5751
+ }
5752
+ if (order2 === 1)
5753
+ return ["Prime", missingIfEmpty(lhs)];
5754
+ return ["Prime", missingIfEmpty(lhs), order2];
5755
+ }
5642
5756
 
5643
5757
  // src/compute-engine/latex-syntax/dictionary/definitions-inequalities.ts
5644
5758
  var DEFINITIONS_INEQUALITIES = [
5645
5759
  {
5646
- trigger: ["\\not", "<"],
5760
+ latexTrigger: ["\\not", "<"],
5647
5761
  kind: "infix",
5648
5762
  associativity: "right",
5649
5763
  precedence: 246,
@@ -5651,13 +5765,13 @@ var DEFINITIONS_INEQUALITIES = [
5651
5765
  },
5652
5766
  {
5653
5767
  name: "NotLess",
5654
- trigger: ["\\nless"],
5768
+ latexTrigger: ["\\nless"],
5655
5769
  kind: "infix",
5656
5770
  associativity: "right",
5657
5771
  precedence: 246
5658
5772
  },
5659
5773
  {
5660
- trigger: ["<"],
5774
+ latexTrigger: ["<"],
5661
5775
  kind: "infix",
5662
5776
  associativity: "right",
5663
5777
  precedence: 245,
@@ -5665,13 +5779,13 @@ var DEFINITIONS_INEQUALITIES = [
5665
5779
  },
5666
5780
  {
5667
5781
  name: "Less",
5668
- trigger: ["\\lt"],
5782
+ latexTrigger: ["\\lt"],
5669
5783
  kind: "infix",
5670
5784
  associativity: "right",
5671
5785
  precedence: 245
5672
5786
  },
5673
5787
  {
5674
- trigger: ["<", "="],
5788
+ latexTrigger: ["<", "="],
5675
5789
  kind: "infix",
5676
5790
  associativity: "right",
5677
5791
  precedence: 241,
@@ -5679,20 +5793,20 @@ var DEFINITIONS_INEQUALITIES = [
5679
5793
  },
5680
5794
  {
5681
5795
  name: "LessEqual",
5682
- trigger: ["\\le"],
5796
+ latexTrigger: ["\\le"],
5683
5797
  kind: "infix",
5684
5798
  associativity: "right",
5685
5799
  precedence: 241
5686
5800
  },
5687
5801
  {
5688
- trigger: ["\\leq"],
5802
+ latexTrigger: ["\\leq"],
5689
5803
  kind: "infix",
5690
5804
  associativity: "right",
5691
5805
  precedence: 241,
5692
5806
  parse: "LessEqual"
5693
5807
  },
5694
5808
  {
5695
- trigger: ["\\leqslant"],
5809
+ latexTrigger: ["\\leqslant"],
5696
5810
  kind: "infix",
5697
5811
  associativity: "right",
5698
5812
  precedence: 265,
@@ -5701,28 +5815,28 @@ var DEFINITIONS_INEQUALITIES = [
5701
5815
  },
5702
5816
  {
5703
5817
  name: "LessNotEqual",
5704
- trigger: ["\\lneqq"],
5818
+ latexTrigger: ["\\lneqq"],
5705
5819
  kind: "infix",
5706
5820
  associativity: "right",
5707
5821
  precedence: 260
5708
5822
  },
5709
5823
  {
5710
5824
  name: "NotLessNotEqual",
5711
- trigger: ["\\nleqq"],
5825
+ latexTrigger: ["\\nleqq"],
5712
5826
  kind: "infix",
5713
5827
  associativity: "right",
5714
5828
  precedence: 260
5715
5829
  },
5716
5830
  {
5717
5831
  name: "LessOverEqual",
5718
- trigger: ["\\leqq"],
5832
+ latexTrigger: ["\\leqq"],
5719
5833
  kind: "infix",
5720
5834
  associativity: "right",
5721
5835
  precedence: 265
5722
5836
  },
5723
5837
  {
5724
5838
  name: "GreaterOverEqual",
5725
- trigger: ["\\geqq"],
5839
+ latexTrigger: ["\\geqq"],
5726
5840
  kind: "infix",
5727
5841
  associativity: "right",
5728
5842
  precedence: 265,
@@ -5730,13 +5844,13 @@ var DEFINITIONS_INEQUALITIES = [
5730
5844
  },
5731
5845
  {
5732
5846
  name: "Equal",
5733
- trigger: ["="],
5847
+ latexTrigger: ["="],
5734
5848
  kind: "infix",
5735
5849
  associativity: "right",
5736
5850
  precedence: 260
5737
5851
  },
5738
5852
  {
5739
- trigger: ["*", "="],
5853
+ latexTrigger: ["*", "="],
5740
5854
  kind: "infix",
5741
5855
  associativity: "right",
5742
5856
  precedence: 260,
@@ -5744,42 +5858,42 @@ var DEFINITIONS_INEQUALITIES = [
5744
5858
  },
5745
5859
  {
5746
5860
  name: "StarEqual",
5747
- trigger: ["\\star", "="],
5861
+ latexTrigger: ["\\star", "="],
5748
5862
  kind: "infix",
5749
5863
  associativity: "right",
5750
5864
  precedence: 260
5751
5865
  },
5752
5866
  {
5753
5867
  name: "PlusEqual",
5754
- trigger: ["+", "="],
5868
+ latexTrigger: ["+", "="],
5755
5869
  kind: "infix",
5756
5870
  associativity: "right",
5757
5871
  precedence: 260
5758
5872
  },
5759
5873
  {
5760
5874
  name: "MinusEqual",
5761
- trigger: ["-", "="],
5875
+ latexTrigger: ["-", "="],
5762
5876
  kind: "infix",
5763
5877
  associativity: "right",
5764
5878
  precedence: 260
5765
5879
  },
5766
5880
  {
5767
5881
  name: "SlashEqual",
5768
- trigger: ["/", "="],
5882
+ latexTrigger: ["/", "="],
5769
5883
  kind: "infix",
5770
5884
  associativity: "right",
5771
5885
  precedence: 260
5772
5886
  },
5773
5887
  {
5774
5888
  name: "EqualEqual",
5775
- trigger: ["=", "="],
5889
+ latexTrigger: ["=", "="],
5776
5890
  kind: "infix",
5777
5891
  associativity: "right",
5778
5892
  precedence: 260
5779
5893
  },
5780
5894
  {
5781
5895
  name: "EqualEqualEqual",
5782
- trigger: ["=", "=", "="],
5896
+ latexTrigger: ["=", "=", "="],
5783
5897
  kind: "infix",
5784
5898
  associativity: "right",
5785
5899
  precedence: 265
@@ -5787,7 +5901,7 @@ var DEFINITIONS_INEQUALITIES = [
5787
5901
  {
5788
5902
  name: "TildeFullEqual",
5789
5903
  // MathML: approximately equal to
5790
- trigger: ["\\cong"],
5904
+ latexTrigger: ["\\cong"],
5791
5905
  kind: "infix",
5792
5906
  associativity: "right",
5793
5907
  precedence: 260
@@ -5795,13 +5909,13 @@ var DEFINITIONS_INEQUALITIES = [
5795
5909
  {
5796
5910
  name: "NotTildeFullEqual",
5797
5911
  // MathML: approximately but not actually equal to
5798
- trigger: ["\\ncong"],
5912
+ latexTrigger: ["\\ncong"],
5799
5913
  kind: "infix",
5800
5914
  associativity: "right",
5801
5915
  precedence: 260
5802
5916
  },
5803
5917
  {
5804
- trigger: [":", "="],
5918
+ latexTrigger: [":", "="],
5805
5919
  kind: "infix",
5806
5920
  associativity: "right",
5807
5921
  precedence: 260,
@@ -5809,7 +5923,7 @@ var DEFINITIONS_INEQUALITIES = [
5809
5923
  },
5810
5924
  {
5811
5925
  name: "Assign",
5812
- trigger: ["\\coloneq"],
5926
+ latexTrigger: ["\\coloneq"],
5813
5927
  kind: "infix",
5814
5928
  associativity: "right",
5815
5929
  precedence: 260
@@ -5817,7 +5931,7 @@ var DEFINITIONS_INEQUALITIES = [
5817
5931
  {
5818
5932
  name: "Approx",
5819
5933
  // Note: Mathematica TildeTilde
5820
- trigger: ["\\approx"],
5934
+ latexTrigger: ["\\approx"],
5821
5935
  kind: "infix",
5822
5936
  associativity: "right",
5823
5937
  precedence: 247
@@ -5825,7 +5939,7 @@ var DEFINITIONS_INEQUALITIES = [
5825
5939
  {
5826
5940
  name: "NotApprox",
5827
5941
  // Note: Mathematica TildeTilde
5828
- trigger: ["\\not", "\\approx"],
5942
+ latexTrigger: ["\\not", "\\approx"],
5829
5943
  kind: "infix",
5830
5944
  associativity: "right",
5831
5945
  precedence: 247
@@ -5833,7 +5947,7 @@ var DEFINITIONS_INEQUALITIES = [
5833
5947
  {
5834
5948
  name: "ApproxEqual",
5835
5949
  // Note: Mathematica TildeEqual, MathML: `asymptotically equal to`
5836
- trigger: ["\\approxeq"],
5950
+ latexTrigger: ["\\approxeq"],
5837
5951
  kind: "infix",
5838
5952
  associativity: "right",
5839
5953
  precedence: 260
@@ -5841,7 +5955,7 @@ var DEFINITIONS_INEQUALITIES = [
5841
5955
  {
5842
5956
  name: "NotApproxEqual",
5843
5957
  // Note: Mathematica NotTildeEqual
5844
- trigger: ["\\not", "\\approxeq"],
5958
+ latexTrigger: ["\\not", "\\approxeq"],
5845
5959
  kind: "infix",
5846
5960
  // Note: no LaTeX symbol for char U+2249
5847
5961
  associativity: "right",
@@ -5849,14 +5963,14 @@ var DEFINITIONS_INEQUALITIES = [
5849
5963
  },
5850
5964
  {
5851
5965
  name: "NotEqual",
5852
- trigger: ["\\ne"],
5966
+ latexTrigger: ["\\ne"],
5853
5967
  kind: "infix",
5854
5968
  associativity: "right",
5855
5969
  precedence: 255
5856
5970
  },
5857
5971
  {
5858
5972
  name: "Unequal",
5859
- trigger: ["!", "="],
5973
+ latexTrigger: ["!", "="],
5860
5974
  kind: "infix",
5861
5975
  associativity: "right",
5862
5976
  precedence: 260
@@ -5864,14 +5978,14 @@ var DEFINITIONS_INEQUALITIES = [
5864
5978
  },
5865
5979
  {
5866
5980
  name: "GreaterEqual",
5867
- trigger: ["\\ge"],
5981
+ latexTrigger: ["\\ge"],
5868
5982
  kind: "infix",
5869
5983
  associativity: "right",
5870
5984
  precedence: 242
5871
5985
  // Note: different precendence than `>=` as per MathML
5872
5986
  },
5873
5987
  {
5874
- trigger: ["\\geq"],
5988
+ latexTrigger: ["\\geq"],
5875
5989
  kind: "infix",
5876
5990
  associativity: "right",
5877
5991
  precedence: 242,
@@ -5879,14 +5993,14 @@ var DEFINITIONS_INEQUALITIES = [
5879
5993
  parse: "GreaterEqual"
5880
5994
  },
5881
5995
  {
5882
- trigger: [">", "="],
5996
+ latexTrigger: [">", "="],
5883
5997
  kind: "infix",
5884
5998
  associativity: "right",
5885
5999
  precedence: 243,
5886
6000
  parse: "GreaterEqual"
5887
6001
  },
5888
6002
  {
5889
- trigger: ["\\geqslant"],
6003
+ latexTrigger: ["\\geqslant"],
5890
6004
  kind: "infix",
5891
6005
  associativity: "right",
5892
6006
  precedence: 265,
@@ -5895,20 +6009,20 @@ var DEFINITIONS_INEQUALITIES = [
5895
6009
  },
5896
6010
  {
5897
6011
  name: "GreaterNotEqual",
5898
- trigger: ["\\gneqq"],
6012
+ latexTrigger: ["\\gneqq"],
5899
6013
  kind: "infix",
5900
6014
  associativity: "right",
5901
6015
  precedence: 260
5902
6016
  },
5903
6017
  {
5904
6018
  name: "NotGreaterNotEqual",
5905
- trigger: ["\\ngeqq"],
6019
+ latexTrigger: ["\\ngeqq"],
5906
6020
  kind: "infix",
5907
6021
  associativity: "right",
5908
6022
  precedence: 260
5909
6023
  },
5910
6024
  {
5911
- trigger: [">"],
6025
+ latexTrigger: [">"],
5912
6026
  kind: "infix",
5913
6027
  associativity: "right",
5914
6028
  precedence: 245,
@@ -5916,20 +6030,20 @@ var DEFINITIONS_INEQUALITIES = [
5916
6030
  },
5917
6031
  {
5918
6032
  name: "Greater",
5919
- trigger: ["\\gt"],
6033
+ latexTrigger: ["\\gt"],
5920
6034
  kind: "infix",
5921
6035
  associativity: "right",
5922
6036
  precedence: 245
5923
6037
  },
5924
6038
  {
5925
6039
  name: "NotGreater",
5926
- trigger: ["\\ngtr"],
6040
+ latexTrigger: ["\\ngtr"],
5927
6041
  kind: "infix",
5928
6042
  associativity: "right",
5929
6043
  precedence: 244
5930
6044
  },
5931
6045
  {
5932
- trigger: ["\\not", ">"],
6046
+ latexTrigger: ["\\not", ">"],
5933
6047
  kind: "infix",
5934
6048
  associativity: "right",
5935
6049
  precedence: 244,
@@ -5937,7 +6051,7 @@ var DEFINITIONS_INEQUALITIES = [
5937
6051
  },
5938
6052
  {
5939
6053
  name: "RingEqual",
5940
- trigger: ["\\circeq"],
6054
+ latexTrigger: ["\\circeq"],
5941
6055
  kind: "infix",
5942
6056
  associativity: "right",
5943
6057
  precedence: 260
@@ -5945,7 +6059,7 @@ var DEFINITIONS_INEQUALITIES = [
5945
6059
  {
5946
6060
  name: "TriangleEqual",
5947
6061
  // MathML: delta equal to
5948
- trigger: ["\\triangleq"],
6062
+ latexTrigger: ["\\triangleq"],
5949
6063
  kind: "infix",
5950
6064
  associativity: "right",
5951
6065
  precedence: 260
@@ -5953,7 +6067,7 @@ var DEFINITIONS_INEQUALITIES = [
5953
6067
  {
5954
6068
  name: "DotEqual",
5955
6069
  // MathML: approaches the limit
5956
- trigger: ["\\doteq"],
6070
+ latexTrigger: ["\\doteq"],
5957
6071
  kind: "infix",
5958
6072
  associativity: "right",
5959
6073
  precedence: 265
@@ -5961,7 +6075,7 @@ var DEFINITIONS_INEQUALITIES = [
5961
6075
  {
5962
6076
  name: "DotEqualDot",
5963
6077
  // MathML: Geometrically equal
5964
- trigger: ["\\doteqdot"],
6078
+ latexTrigger: ["\\doteqdot"],
5965
6079
  kind: "infix",
5966
6080
  associativity: "right",
5967
6081
  precedence: 265
@@ -5969,7 +6083,7 @@ var DEFINITIONS_INEQUALITIES = [
5969
6083
  {
5970
6084
  name: "FallingDotEqual",
5971
6085
  // MathML: approximately equal to or the image of
5972
- trigger: ["\\fallingdotseq"],
6086
+ latexTrigger: ["\\fallingdotseq"],
5973
6087
  kind: "infix",
5974
6088
  associativity: "right",
5975
6089
  precedence: 265
@@ -5977,92 +6091,77 @@ var DEFINITIONS_INEQUALITIES = [
5977
6091
  {
5978
6092
  name: "RisingDotEqual",
5979
6093
  // MathML: image of or approximately equal to
5980
- trigger: ["\\fallingdotseq"],
6094
+ latexTrigger: ["\\fallingdotseq"],
5981
6095
  kind: "infix",
5982
6096
  associativity: "right",
5983
6097
  precedence: 265
5984
6098
  },
5985
6099
  {
5986
6100
  name: "QuestionEqual",
5987
- trigger: ["\\questeq"],
5988
- kind: "infix",
5989
- associativity: "right",
5990
- precedence: 260
5991
- },
5992
- {
5993
- name: "Equivalent",
5994
- // MathML: identical to, Mathematica: Congruent
5995
- trigger: ["\\equiv"],
5996
- kind: "infix",
5997
- associativity: "right",
5998
- precedence: 260
5999
- },
6000
- {
6001
- trigger: ["\\iff"],
6101
+ latexTrigger: ["\\questeq"],
6002
6102
  kind: "infix",
6003
- parse: "Equivalent",
6004
6103
  associativity: "right",
6005
6104
  precedence: 260
6006
6105
  },
6007
6106
  {
6008
6107
  name: "MuchLess",
6009
- trigger: ["\\ll"],
6108
+ latexTrigger: ["\\ll"],
6010
6109
  kind: "infix",
6011
6110
  associativity: "right",
6012
6111
  precedence: 260
6013
6112
  },
6014
6113
  {
6015
6114
  name: "MuchGreater",
6016
- trigger: ["\\gg"],
6115
+ latexTrigger: ["\\gg"],
6017
6116
  kind: "infix",
6018
6117
  associativity: "right",
6019
6118
  precedence: 260
6020
6119
  },
6021
6120
  {
6022
6121
  name: "Precedes",
6023
- trigger: ["\\prec"],
6122
+ latexTrigger: ["\\prec"],
6024
6123
  kind: "infix",
6025
6124
  associativity: "right",
6026
6125
  precedence: 260
6027
6126
  },
6028
6127
  {
6029
6128
  name: "Succeeds",
6030
- trigger: ["\\succ"],
6129
+ latexTrigger: ["\\succ"],
6031
6130
  kind: "infix",
6032
6131
  associativity: "right",
6033
6132
  precedence: 260
6034
6133
  },
6035
6134
  {
6036
6135
  name: "PrecedesEqual",
6037
- trigger: ["\\preccurlyeq"],
6136
+ latexTrigger: ["\\preccurlyeq"],
6038
6137
  kind: "infix",
6039
6138
  associativity: "right",
6040
6139
  precedence: 260
6041
6140
  },
6042
6141
  {
6043
6142
  name: "SucceedsEqual",
6044
- trigger: ["\\curlyeqprec"],
6143
+ latexTrigger: ["\\curlyeqprec"],
6045
6144
  kind: "infix",
6046
6145
  associativity: "right",
6047
6146
  precedence: 260
6048
6147
  },
6049
6148
  {
6050
6149
  name: "NotPrecedes",
6051
- trigger: ["\\nprec"],
6150
+ latexTrigger: ["\\nprec"],
6052
6151
  kind: "infix",
6053
6152
  associativity: "right",
6054
6153
  precedence: 260
6055
6154
  },
6056
6155
  {
6057
6156
  name: "NotSucceeds",
6058
- trigger: ["\\nsucc"],
6157
+ latexTrigger: ["\\nsucc"],
6059
6158
  kind: "infix",
6060
6159
  associativity: "right",
6061
6160
  precedence: 260
6062
6161
  },
6063
6162
  {
6064
6163
  name: "Between",
6065
- trigger: ["\\between"],
6164
+ latexTrigger: ["\\between"],
6066
6165
  kind: "infix",
6067
6166
  associativity: "right",
6068
6167
  precedence: 265
@@ -6074,18 +6173,187 @@ var DEFINITIONS_LOGIC = [
6074
6173
  // Constants
6075
6174
  {
6076
6175
  name: "True",
6077
- trigger: ["\\mathrm", "<{>", "T", "r", "u", "e", "<}>"],
6078
- serialize: "\\mathrm{True}"
6176
+ kind: "symbol",
6177
+ latexTrigger: ["\\top"]
6178
+ // ⊤ U+22A4
6179
+ },
6180
+ {
6181
+ kind: "symbol",
6182
+ latexTrigger: "\\mathrm{True}",
6183
+ parse: "True"
6184
+ },
6185
+ {
6186
+ kind: "symbol",
6187
+ latexTrigger: "\\operator{True}",
6188
+ parse: "True"
6189
+ },
6190
+ {
6191
+ kind: "symbol",
6192
+ latexTrigger: "\\mathsf{T}",
6193
+ parse: "True"
6079
6194
  },
6080
6195
  {
6081
6196
  name: "False",
6082
- trigger: ["\\mathrm", "<{>", "F", "a", "l", "s", "e", "<}>"],
6083
- serialize: "\\mathrm{False}"
6197
+ kind: "symbol",
6198
+ latexTrigger: ["\\bot"]
6199
+ // ⊥ U+22A5
6200
+ },
6201
+ {
6202
+ kind: "symbol",
6203
+ latexTrigger: "\\operator{False}",
6204
+ parse: "True"
6205
+ },
6206
+ {
6207
+ kind: "symbol",
6208
+ latexTrigger: "\\mathsf{F}",
6209
+ parse: "True"
6084
6210
  },
6085
6211
  {
6086
6212
  name: "Maybe",
6087
- trigger: ["\\mathrm", "<{>", "M", "a", "y", "b", "e", "<}>"],
6088
- serialize: "\\mathrm{Maybe}"
6213
+ kind: "symbol",
6214
+ latexTrigger: "\\operatorname{Maybe}",
6215
+ serialize: "\\operatorname{Maybe}"
6216
+ },
6217
+ {
6218
+ kind: "symbol",
6219
+ latexTrigger: "\\mathrm{Maybe}",
6220
+ parse: "Maybe"
6221
+ },
6222
+ // Operators
6223
+ {
6224
+ name: "And",
6225
+ kind: "infix",
6226
+ latexTrigger: ["\\land"],
6227
+ precedence: 317
6228
+ // serialize: '\\land',
6229
+ },
6230
+ { kind: "infix", latexTrigger: ["\\wedge"], parse: "And", precedence: 317 },
6231
+ { kind: "infix", latexTrigger: "\\&", parse: "And", precedence: 317 },
6232
+ {
6233
+ kind: "infix",
6234
+ latexTrigger: "\\operatorname{and}",
6235
+ parse: "And",
6236
+ precedence: 317
6237
+ },
6238
+ {
6239
+ name: "Or",
6240
+ kind: "infix",
6241
+ latexTrigger: ["\\lor"],
6242
+ precedence: 310
6243
+ },
6244
+ { kind: "infix", latexTrigger: ["\\vee"], parse: "Or", precedence: 310 },
6245
+ { kind: "infix", latexTrigger: "\\parallel", parse: "Or", precedence: 310 },
6246
+ {
6247
+ kind: "infix",
6248
+ latexTrigger: "\\operatorname{or}",
6249
+ parse: "And",
6250
+ precedence: 310
6251
+ },
6252
+ {
6253
+ name: "Xor",
6254
+ kind: "infix",
6255
+ latexTrigger: ["\\veebar"],
6256
+ precedence: 315
6257
+ },
6258
+ // Possible alt: \oplus ⊕ U+2295
6259
+ {
6260
+ name: "Not",
6261
+ kind: "prefix",
6262
+ latexTrigger: ["\\lnot"],
6263
+ precedence: 880
6264
+ },
6265
+ {
6266
+ name: "Nand",
6267
+ kind: "infix",
6268
+ latexTrigger: ["\\barwedge"],
6269
+ precedence: 315
6270
+ // serialize: '\\mid',
6271
+ },
6272
+ {
6273
+ name: "Nor",
6274
+ kind: "infix",
6275
+ latexTrigger: ["\u22BD"],
6276
+ // bar vee
6277
+ precedence: 315
6278
+ // serialize: '\\downarrow',
6279
+ },
6280
+ // Functions
6281
+ {
6282
+ kind: "function",
6283
+ identifierTrigger: "and",
6284
+ parse: "And"
6285
+ },
6286
+ {
6287
+ kind: "function",
6288
+ identifierTrigger: "or",
6289
+ parse: "Or"
6290
+ },
6291
+ {
6292
+ kind: "function",
6293
+ identifierTrigger: "not",
6294
+ parse: "Not"
6295
+ },
6296
+ // Relations
6297
+ {
6298
+ name: "Implies",
6299
+ kind: "infix",
6300
+ precedence: 220,
6301
+ associativity: "right",
6302
+ latexTrigger: ["\\implies"],
6303
+ serialize: "\\implies"
6304
+ },
6305
+ {
6306
+ latexTrigger: ["\\Rightarrow"],
6307
+ kind: "infix",
6308
+ precedence: 220,
6309
+ associativity: "right",
6310
+ parse: "Implies"
6311
+ },
6312
+ {
6313
+ name: "Equivalent",
6314
+ // MathML: identical to, Mathematica: Congruent
6315
+ latexTrigger: ["\\iff"],
6316
+ kind: "infix",
6317
+ associativity: "right",
6318
+ precedence: 219
6319
+ },
6320
+ {
6321
+ latexTrigger: ["\\Leftrightarrow"],
6322
+ kind: "infix",
6323
+ associativity: "right",
6324
+ precedence: 219,
6325
+ parse: "Equivalent"
6326
+ },
6327
+ {
6328
+ latexTrigger: ["\\equiv"],
6329
+ kind: "infix",
6330
+ associativity: "right",
6331
+ precedence: 219,
6332
+ parse: "Equivalent"
6333
+ },
6334
+ {
6335
+ name: "Proves",
6336
+ kind: "infix",
6337
+ latexTrigger: ["\\vdash"],
6338
+ precedence: 220,
6339
+ associativity: "right",
6340
+ serialize: "\\vdash"
6341
+ },
6342
+ {
6343
+ name: "Entails",
6344
+ kind: "infix",
6345
+ latexTrigger: ["\\vDash"],
6346
+ precedence: 220,
6347
+ associativity: "right",
6348
+ serialize: "\\vDash"
6349
+ },
6350
+ {
6351
+ name: "Satisfies",
6352
+ kind: "infix",
6353
+ latexTrigger: ["\\models"],
6354
+ precedence: 220,
6355
+ associativity: "right",
6356
+ serialize: "\\models"
6089
6357
  }
6090
6358
  ];
6091
6359
 
@@ -6099,72 +6367,73 @@ function parseSingleArg(cmd) {
6099
6367
  var DEFINITIONS_OTHERS = [
6100
6368
  {
6101
6369
  name: "Overscript",
6102
- trigger: ["\\overset"],
6370
+ latexTrigger: ["\\overset"],
6103
6371
  kind: "infix",
6104
6372
  precedence: 700
6105
6373
  // @todo: not in MathML
6106
6374
  },
6107
6375
  {
6108
6376
  name: "Underscript",
6109
- trigger: ["\\underset"],
6377
+ latexTrigger: ["\\underset"],
6110
6378
  kind: "infix",
6111
6379
  precedence: 700
6112
6380
  // @todo: not in MathML
6113
6381
  },
6114
6382
  {
6115
6383
  name: "Increment",
6116
- trigger: ["+", "+"],
6384
+ latexTrigger: ["+", "+"],
6117
6385
  kind: "postfix",
6118
6386
  precedence: 880
6119
6387
  },
6120
6388
  {
6121
6389
  name: "Decrement",
6122
- trigger: ["-", "-"],
6390
+ latexTrigger: ["-", "-"],
6123
6391
  kind: "postfix",
6124
6392
  precedence: 880
6125
6393
  },
6126
6394
  {
6127
6395
  name: "PreIncrement",
6128
- trigger: ["+", "+"],
6396
+ latexTrigger: ["+", "+"],
6129
6397
  kind: "prefix",
6130
6398
  precedence: 880
6131
6399
  },
6132
6400
  {
6133
6401
  name: "PreDecrement",
6134
- trigger: ["-", "-"],
6402
+ latexTrigger: ["-", "-"],
6135
6403
  kind: "prefix",
6136
6404
  precedence: 880
6137
6405
  },
6138
6406
  {
6139
6407
  name: "Ring",
6140
6408
  // Aka 'Composition', i.e. function composition
6141
- trigger: ["\\circ"],
6409
+ latexTrigger: ["\\circ"],
6142
6410
  kind: "infix",
6143
6411
  precedence: 265
6412
+ // @todo: MathML is 950
6144
6413
  // @todo: check lhs and rhs are functions
6145
6414
  },
6146
6415
  {
6147
6416
  name: "Transpose",
6148
- trigger: ["^", "T"],
6417
+ latexTrigger: ["^", "T"],
6149
6418
  kind: "postfix"
6150
6419
  // @todo: if lhs is a list/tensor
6151
6420
  },
6152
6421
  {
6153
6422
  // @todo: if lhs is a list/tensor
6154
6423
  name: "ConjugateTranspose",
6155
- trigger: ["^", "H"],
6424
+ latexTrigger: ["^", "H"],
6156
6425
  kind: "postfix"
6157
6426
  },
6158
6427
  {
6159
6428
  name: "StringJoin",
6160
6429
  // @todo From Mathematica...?
6161
- trigger: ["\\lt", "\\gt"],
6430
+ latexTrigger: ["\\lt", "\\gt"],
6162
6431
  kind: "infix",
6163
6432
  precedence: 780
6164
6433
  },
6165
6434
  {
6166
6435
  name: "Starstar",
6167
- trigger: ["\\star", "\\star"],
6436
+ latexTrigger: ["\\star", "\\star"],
6168
6437
  kind: "infix",
6169
6438
  precedence: 780
6170
6439
  },
@@ -6174,7 +6443,7 @@ var DEFINITIONS_OTHERS = [
6174
6443
  // For the Leibniz notation see 'Divide' that handles `∂f/∂x`
6175
6444
  name: "PartialDerivative",
6176
6445
  // PartialDerivative(expr, {lists of vars}, degree)
6177
- trigger: ["\\partial"],
6446
+ latexTrigger: ["\\partial"],
6178
6447
  kind: "prefix",
6179
6448
  parse: (parser) => {
6180
6449
  let done = false;
@@ -6197,8 +6466,8 @@ var DEFINITIONS_OTHERS = [
6197
6466
  return null;
6198
6467
  let rhs = parser.parseGroup() ?? "Nothing";
6199
6468
  if (rhs !== "Nothing" && !isEmptySequence(rhs)) {
6200
- const arg = parser.parseArguments() ?? ["Nothing"];
6201
- rhs = [rhs, ...arg];
6469
+ const args = parser.parseArguments() ?? ["Nothing"];
6470
+ rhs = [rhs, ...args];
6202
6471
  }
6203
6472
  return ["PartialDerivative", rhs, sub2, sup];
6204
6473
  },
@@ -6224,128 +6493,128 @@ var DEFINITIONS_OTHERS = [
6224
6493
  },
6225
6494
  {
6226
6495
  name: "OverBar",
6227
- trigger: ["\\overline"],
6496
+ latexTrigger: ["\\overline"],
6228
6497
  parse: parseSingleArg("OverBar")
6229
6498
  },
6230
6499
  {
6231
6500
  name: "UnderBar",
6232
- trigger: ["\\underline"],
6501
+ latexTrigger: ["\\underline"],
6233
6502
  parse: parseSingleArg("UnderBar")
6234
6503
  },
6235
6504
  {
6236
6505
  name: "OverVector",
6237
- trigger: ["\\vec"],
6506
+ latexTrigger: ["\\vec"],
6238
6507
  parse: parseSingleArg("OverVector")
6239
6508
  },
6240
6509
  {
6241
6510
  name: "OverTilde",
6242
- trigger: ["\\tilde"],
6511
+ latexTrigger: ["\\tilde"],
6243
6512
  parse: parseSingleArg("OverTilde")
6244
6513
  },
6245
6514
  {
6246
6515
  name: "OverHat",
6247
- trigger: ["\\hat"],
6516
+ latexTrigger: ["\\hat"],
6248
6517
  parse: parseSingleArg("OverHat")
6249
6518
  },
6250
6519
  {
6251
6520
  name: "OverRightArrow",
6252
- trigger: ["\\overrightarrow"],
6521
+ latexTrigger: ["\\overrightarrow"],
6253
6522
  parse: parseSingleArg("OverRightArrow")
6254
6523
  },
6255
6524
  {
6256
6525
  name: "OverLeftArrow",
6257
- trigger: ["\\overleftarrow"],
6526
+ latexTrigger: ["\\overleftarrow"],
6258
6527
  parse: parseSingleArg("OverLeftArrow")
6259
6528
  },
6260
6529
  {
6261
6530
  name: "OverRightDoubleArrow",
6262
- trigger: ["\\Overrightarrow"],
6531
+ latexTrigger: ["\\Overrightarrow"],
6263
6532
  parse: parseSingleArg("OverRightDoubleArrow")
6264
6533
  },
6265
6534
  {
6266
6535
  name: "OverLeftHarpoon",
6267
- trigger: ["\\overleftharpoon"],
6536
+ latexTrigger: ["\\overleftharpoon"],
6268
6537
  parse: parseSingleArg("OverLeftHarpoon")
6269
6538
  },
6270
6539
  {
6271
6540
  name: "OverRightHarpoon",
6272
- trigger: ["\\overrightharpoon"],
6541
+ latexTrigger: ["\\overrightharpoon"],
6273
6542
  parse: parseSingleArg("OverRightHarpoon")
6274
6543
  },
6275
6544
  {
6276
6545
  name: "OverLeftRightArrow",
6277
- trigger: ["\\overleftrightarrow"],
6546
+ latexTrigger: ["\\overleftrightarrow"],
6278
6547
  parse: parseSingleArg("OverLeftRightArrow")
6279
6548
  },
6280
6549
  {
6281
6550
  name: "OverBrace",
6282
- trigger: ["\\overbrace"],
6551
+ latexTrigger: ["\\overbrace"],
6283
6552
  parse: parseSingleArg("OverBrace")
6284
6553
  },
6285
6554
  {
6286
6555
  name: "OverLineSegment",
6287
- trigger: ["\\overlinesegment"],
6556
+ latexTrigger: ["\\overlinesegment"],
6288
6557
  parse: parseSingleArg("OverLineSegment")
6289
6558
  },
6290
6559
  {
6291
6560
  name: "OverGroup",
6292
- trigger: ["\\overgroup"],
6561
+ latexTrigger: ["\\overgroup"],
6293
6562
  parse: parseSingleArg("OverGroup")
6294
6563
  },
6295
6564
  {
6296
- trigger: ["\\displaystyle"],
6565
+ latexTrigger: ["\\displaystyle"],
6297
6566
  parse: () => ["Sequence"]
6298
6567
  },
6299
6568
  {
6300
- trigger: ["\\textstyle"],
6569
+ latexTrigger: ["\\textstyle"],
6301
6570
  parse: () => ["Sequence"]
6302
6571
  },
6303
6572
  {
6304
- trigger: ["\\scriptstyle"],
6573
+ latexTrigger: ["\\scriptstyle"],
6305
6574
  parse: () => ["Sequence"]
6306
6575
  },
6307
6576
  {
6308
- trigger: ["\\scriptscriptstyle"],
6577
+ latexTrigger: ["\\scriptscriptstyle"],
6309
6578
  parse: () => ["Sequence"]
6310
6579
  },
6311
6580
  {
6312
- trigger: ["\\tiny"],
6581
+ latexTrigger: ["\\tiny"],
6313
6582
  parse: () => ["Sequence"]
6314
6583
  },
6315
6584
  {
6316
- trigger: ["\\scriptsize"],
6585
+ latexTrigger: ["\\scriptsize"],
6317
6586
  parse: () => ["Sequence"]
6318
6587
  },
6319
6588
  {
6320
- trigger: ["\\footnotesize"],
6589
+ latexTrigger: ["\\footnotesize"],
6321
6590
  parse: () => ["Sequence"]
6322
6591
  },
6323
6592
  {
6324
- trigger: ["\\small"],
6593
+ latexTrigger: ["\\small"],
6325
6594
  parse: () => ["Sequence"]
6326
6595
  },
6327
6596
  {
6328
- trigger: ["\\normalsize"],
6597
+ latexTrigger: ["\\normalsize"],
6329
6598
  parse: () => ["Sequence"]
6330
6599
  },
6331
6600
  {
6332
- trigger: ["\\large"],
6601
+ latexTrigger: ["\\large"],
6333
6602
  parse: () => ["Sequence"]
6334
6603
  },
6335
6604
  {
6336
- trigger: ["\\Large"],
6605
+ latexTrigger: ["\\Large"],
6337
6606
  parse: () => ["Sequence"]
6338
6607
  },
6339
6608
  {
6340
- trigger: ["\\LARGE"],
6609
+ latexTrigger: ["\\LARGE"],
6341
6610
  parse: () => ["Sequence"]
6342
6611
  },
6343
6612
  {
6344
- trigger: ["\\huge"],
6613
+ latexTrigger: ["\\huge"],
6345
6614
  parse: () => ["Sequence"]
6346
6615
  },
6347
6616
  {
6348
- trigger: ["\\Huge"],
6617
+ latexTrigger: ["\\Huge"],
6349
6618
  parse: () => ["Sequence"]
6350
6619
  },
6351
6620
  {
@@ -6387,39 +6656,39 @@ var DEFINITIONS_OTHERS = [
6387
6656
  }
6388
6657
  },
6389
6658
  {
6390
- trigger: ["\\!"],
6659
+ latexTrigger: ["\\!"],
6391
6660
  parse: () => ["HorizontalSpacing", -3]
6392
6661
  },
6393
6662
  {
6394
- trigger: ["\\ "],
6663
+ latexTrigger: ["\\ "],
6395
6664
  parse: () => ["HorizontalSpacing", 6]
6396
6665
  },
6397
6666
  {
6398
- trigger: ["\\:"],
6667
+ latexTrigger: ["\\:"],
6399
6668
  parse: () => ["HorizontalSpacing", 4]
6400
6669
  },
6401
6670
  {
6402
- trigger: ["\\enskip"],
6671
+ latexTrigger: ["\\enskip"],
6403
6672
  parse: () => ["HorizontalSpacing", 9]
6404
6673
  },
6405
6674
  {
6406
- trigger: ["\\quad"],
6675
+ latexTrigger: ["\\quad"],
6407
6676
  parse: () => ["HorizontalSpacing", 18]
6408
6677
  },
6409
6678
  {
6410
- trigger: ["\\qquad"],
6679
+ latexTrigger: ["\\qquad"],
6411
6680
  parse: () => ["HorizontalSpacing", 36]
6412
6681
  },
6413
6682
  {
6414
- trigger: ["\\,"],
6683
+ latexTrigger: ["\\,"],
6415
6684
  parse: () => ["HorizontalSpacing", 3]
6416
6685
  },
6417
6686
  {
6418
- trigger: ["\\;"],
6687
+ latexTrigger: ["\\;"],
6419
6688
  parse: () => ["HorizontalSpacing", 5]
6420
6689
  },
6421
6690
  {
6422
- trigger: ["\\enspace"],
6691
+ latexTrigger: ["\\enspace"],
6423
6692
  parse: () => ["HorizontalSpacing", 9]
6424
6693
  },
6425
6694
  {
@@ -6519,146 +6788,146 @@ function parseTrig(op3) {
6519
6788
  var DEFINITIONS_TRIGONOMETRY = [
6520
6789
  {
6521
6790
  name: "Arcsin",
6522
- trigger: ["\\arcsin"],
6791
+ latexTrigger: ["\\arcsin"],
6523
6792
  parse: parseTrig("Arcsin")
6524
6793
  },
6525
6794
  {
6526
6795
  name: "Arccos",
6527
- trigger: ["\\arccos"],
6796
+ latexTrigger: ["\\arccos"],
6528
6797
  parse: parseTrig("Arccos")
6529
6798
  },
6530
6799
  {
6531
6800
  name: "Arctan",
6532
- trigger: ["\\arctan"],
6801
+ latexTrigger: ["\\arctan"],
6533
6802
  parse: parseTrig("Arctan")
6534
6803
  },
6535
6804
  {
6536
- trigger: ["\\arctg"],
6805
+ latexTrigger: ["\\arctg"],
6537
6806
  parse: parseTrig("Arctan")
6538
6807
  },
6539
6808
  {
6540
6809
  name: "Arccot",
6541
- trigger: ["\\arcctg"],
6810
+ latexTrigger: ["\\arcctg"],
6542
6811
  parse: parseTrig("Arccot")
6543
6812
  },
6544
6813
  {
6545
6814
  name: "Arcsec",
6546
- trigger: "arcsec",
6815
+ latexTrigger: "arcsec",
6547
6816
  parse: parseTrig("Arcsec")
6548
6817
  },
6549
6818
  {
6550
6819
  name: "Arccsc",
6551
- trigger: ["\\arccsc"],
6820
+ latexTrigger: ["\\arccsc"],
6552
6821
  parse: parseTrig("Arccsc")
6553
6822
  },
6554
6823
  {
6555
6824
  name: "Arsinh",
6556
- trigger: ["\\arsinh"],
6825
+ latexTrigger: ["\\arsinh"],
6557
6826
  parse: parseTrig("Arsinh")
6558
6827
  },
6559
6828
  {
6560
6829
  name: "Arcosh",
6561
- trigger: ["\\arcosh"],
6830
+ latexTrigger: ["\\arcosh"],
6562
6831
  parse: parseTrig("Arcosh")
6563
6832
  },
6564
6833
  {
6565
6834
  name: "Artanh",
6566
- trigger: ["\\artanh"],
6835
+ latexTrigger: ["\\artanh"],
6567
6836
  parse: parseTrig("Artanh")
6568
6837
  },
6569
6838
  {
6570
6839
  name: "Arsech",
6571
- trigger: ["\\arsech"],
6840
+ latexTrigger: ["\\arsech"],
6572
6841
  parse: parseTrig("Arsech")
6573
6842
  },
6574
6843
  {
6575
6844
  name: "Arcsch",
6576
- trigger: ["\\arcsch"],
6845
+ latexTrigger: ["\\arcsch"],
6577
6846
  parse: parseTrig("Arcsch")
6578
6847
  },
6579
6848
  {
6580
6849
  // Rusian hyperbolic cosine
6581
- trigger: ["\\ch"],
6850
+ latexTrigger: ["\\ch"],
6582
6851
  parse: parseTrig("Cosh")
6583
6852
  },
6584
6853
  {
6585
6854
  name: "Cosec",
6586
- trigger: ["\\cosec"],
6855
+ latexTrigger: ["\\cosec"],
6587
6856
  parse: parseTrig("Cosec")
6588
6857
  },
6589
6858
  {
6590
6859
  name: "Cosh",
6591
- trigger: ["\\cosh"],
6860
+ latexTrigger: ["\\cosh"],
6592
6861
  parse: parseTrig("Cosh")
6593
6862
  },
6594
6863
  {
6595
6864
  name: "Cot",
6596
- trigger: ["\\cot"],
6865
+ latexTrigger: ["\\cot"],
6597
6866
  parse: parseTrig("Cot")
6598
6867
  },
6599
6868
  {
6600
- trigger: ["\\cotg"],
6869
+ latexTrigger: ["\\cotg"],
6601
6870
  parse: parseTrig("Cot")
6602
6871
  },
6603
6872
  {
6604
6873
  name: "Coth",
6605
- trigger: ["\\coth"],
6874
+ latexTrigger: ["\\coth"],
6606
6875
  parse: parseTrig("Coth")
6607
6876
  },
6608
6877
  {
6609
6878
  name: "Csc",
6610
- trigger: ["\\csc"],
6879
+ latexTrigger: ["\\csc"],
6611
6880
  parse: parseTrig("Csc")
6612
6881
  },
6613
6882
  {
6614
6883
  // Rusian cotangent
6615
- trigger: ["\\ctg"],
6884
+ latexTrigger: ["\\ctg"],
6616
6885
  parse: parseTrig("Cot")
6617
6886
  },
6618
6887
  {
6619
- trigger: ["\\cth"],
6888
+ latexTrigger: ["\\cth"],
6620
6889
  parse: parseTrig("Cotanh")
6621
6890
  },
6622
6891
  {
6623
6892
  name: "Sec",
6624
- trigger: ["\\sec"],
6893
+ latexTrigger: ["\\sec"],
6625
6894
  parse: parseTrig("Sec")
6626
6895
  },
6627
6896
  {
6628
6897
  name: "Sinh",
6629
- trigger: ["\\sinh"],
6898
+ latexTrigger: ["\\sinh"],
6630
6899
  parse: parseTrig("Sinh")
6631
6900
  },
6632
6901
  {
6633
- trigger: ["\\sh"],
6902
+ latexTrigger: ["\\sh"],
6634
6903
  parse: parseTrig("Sinh")
6635
6904
  },
6636
6905
  {
6637
6906
  name: "Tan",
6638
- trigger: ["\\tan"],
6907
+ latexTrigger: ["\\tan"],
6639
6908
  parse: parseTrig("Tan")
6640
6909
  },
6641
6910
  {
6642
- trigger: ["\\tg"],
6911
+ latexTrigger: ["\\tg"],
6643
6912
  parse: parseTrig("Tan")
6644
6913
  },
6645
6914
  {
6646
6915
  name: "Tanh",
6647
- trigger: ["\\tanh"],
6916
+ latexTrigger: ["\\tanh"],
6648
6917
  parse: parseTrig("Tanh")
6649
6918
  },
6650
6919
  {
6651
- trigger: ["\\th"],
6920
+ latexTrigger: ["\\th"],
6652
6921
  parse: parseTrig("Tanh")
6653
6922
  },
6654
6923
  {
6655
6924
  name: "Cos",
6656
- trigger: ["\\cos"],
6925
+ latexTrigger: ["\\cos"],
6657
6926
  parse: parseTrig("Cos")
6658
6927
  },
6659
6928
  {
6660
6929
  name: "Sin",
6661
- trigger: ["\\sin"],
6930
+ latexTrigger: ["\\sin"],
6662
6931
  parse: parseTrig("Sin")
6663
6932
  }
6664
6933
  ];
@@ -6666,77 +6935,77 @@ var DEFINITIONS_TRIGONOMETRY = [
6666
6935
  // src/compute-engine/latex-syntax/dictionary/definitions-sets.ts
6667
6936
  var DEFINITIONS_SETS = [
6668
6937
  // Constants
6669
- { name: "AlgebraicNumber", trigger: "\\bar\\Q" },
6670
- { name: "ComplexNumber", trigger: ["\\C"] },
6671
- { trigger: "\\mathbb{C}", parse: "ComplexNumber" },
6672
- { name: "ImaginaryNumber", trigger: ["\\imaginaryI\\R"] },
6673
- { name: "ExtendedComplexNumber", trigger: ["\\bar\\C"] },
6674
- { name: "EmptySet", trigger: ["\\emptyset"] },
6675
- { trigger: ["\\varnothing"], parse: "EmptySet" },
6938
+ { name: "AlgebraicNumber", latexTrigger: "\\bar\\Q" },
6939
+ { name: "ComplexNumber", latexTrigger: ["\\C"] },
6940
+ { latexTrigger: "\\mathbb{C}", parse: "ComplexNumber" },
6941
+ { name: "ImaginaryNumber", latexTrigger: ["\\imaginaryI", "\\R"] },
6942
+ { name: "ExtendedComplexNumber", latexTrigger: ["\\bar", "\\C"] },
6943
+ { name: "EmptySet", latexTrigger: ["\\emptyset"] },
6944
+ { latexTrigger: ["\\varnothing"], parse: "EmptySet" },
6676
6945
  // Parsing only
6677
- { name: "Integer", trigger: ["\\Z"] },
6678
- { trigger: "\\mathbb{Z}", parse: "Integer" },
6679
- { name: "RationalNumber", trigger: ["\\Q"] },
6680
- { name: "RealNumber", trigger: ["\\R"] },
6681
- { trigger: "\\mathbb{R}", parse: "RealNumber" },
6682
- { name: "ExtendedRealNumber", trigger: ["\\bar\\R"] },
6683
- { name: "TranscendentalNumber", trigger: "\\R-\\bar\\Q" },
6684
- { trigger: "\\R\\backslash\\bar\\Q", parse: "TranscendentalNumber" },
6946
+ { name: "Integer", latexTrigger: ["\\Z"] },
6947
+ { latexTrigger: "\\mathbb{Z}", parse: "Integer" },
6948
+ { name: "RationalNumber", latexTrigger: ["\\Q"] },
6949
+ { name: "RealNumber", latexTrigger: ["\\R"] },
6950
+ { latexTrigger: "\\mathbb{R}", parse: "RealNumber" },
6951
+ { name: "ExtendedRealNumber", latexTrigger: ["\\bar", "\\R"] },
6952
+ { name: "TranscendentalNumber", latexTrigger: "\\R-\\bar\\Q" },
6953
+ { latexTrigger: "\\R\\backslash\\bar\\Q", parse: "TranscendentalNumber" },
6685
6954
  // Real numbers < 0
6686
- { name: "NegativeNumber", trigger: "\\R^-" },
6687
- { trigger: "\\R^{-}", parse: "NegativeNumber" },
6688
- { trigger: "\\R_-", parse: "NegativeNumber" },
6689
- { trigger: "\\R_{-}", parse: "NegativeNumber" },
6690
- { trigger: "\\R^{\\lt}", parse: "NegativeNumber" },
6955
+ { name: "NegativeNumber", latexTrigger: "\\R^-" },
6956
+ { latexTrigger: "\\R^{-}", parse: "NegativeNumber" },
6957
+ { latexTrigger: "\\R_-", parse: "NegativeNumber" },
6958
+ { latexTrigger: "\\R_{-}", parse: "NegativeNumber" },
6959
+ { latexTrigger: "\\R^{\\lt}", parse: "NegativeNumber" },
6691
6960
  // Real numbers > 0
6692
- { name: "PositiveNumber", trigger: "\\R^+" },
6693
- { trigger: "\\R^{+}", parse: "PositiveNumber" },
6694
- { trigger: "\\R_+", parse: "PositiveNumber" },
6695
- { trigger: "\\R_{+}", parse: "PositiveNumber" },
6696
- { trigger: "\\R^{\\gt}", parse: "PositiveNumber" },
6961
+ { name: "PositiveNumber", latexTrigger: "\\R^+" },
6962
+ { latexTrigger: "\\R^{+}", parse: "PositiveNumber" },
6963
+ { latexTrigger: "\\R_+", parse: "PositiveNumber" },
6964
+ { latexTrigger: "\\R_{+}", parse: "PositiveNumber" },
6965
+ { latexTrigger: "\\R^{\\gt}", parse: "PositiveNumber" },
6697
6966
  // Real numbers <= 0
6698
- { name: "NonPositiveNumber", trigger: "\\R^{0-}" },
6699
- { trigger: "\\R^{-0}", parse: "NonPositiveNumber" },
6700
- { trigger: "\\R^{\\leq}", parse: "NonPositiveNumber" },
6967
+ { name: "NonPositiveNumber", latexTrigger: "\\R^{0-}" },
6968
+ { latexTrigger: "\\R^{-0}", parse: "NonPositiveNumber" },
6969
+ { latexTrigger: "\\R^{\\leq}", parse: "NonPositiveNumber" },
6701
6970
  // Integers < 0
6702
- { name: "NegativeInteger", trigger: "\\Z^-" },
6703
- { trigger: "\\Z^-", parse: "NegativeInteger" },
6704
- { trigger: "\\Z^{-}", parse: "NegativeInteger" },
6705
- { trigger: "\\Z_-", parse: "NegativeInteger" },
6706
- { trigger: "\\Z_{-}", parse: "NegativeInteger" },
6707
- { trigger: "\\Z^{\\lt}", parse: "NegativeInteger" },
6971
+ { name: "NegativeInteger", latexTrigger: "\\Z^-" },
6972
+ { latexTrigger: "\\Z^-", parse: "NegativeInteger" },
6973
+ { latexTrigger: "\\Z^{-}", parse: "NegativeInteger" },
6974
+ { latexTrigger: "\\Z_-", parse: "NegativeInteger" },
6975
+ { latexTrigger: "\\Z_{-}", parse: "NegativeInteger" },
6976
+ { latexTrigger: "\\Z^{\\lt}", parse: "NegativeInteger" },
6708
6977
  // Integers > 0
6709
- { name: "PositiveInteger", trigger: "\\Z^+" },
6710
- { trigger: "\\Z^{+}", parse: "PositiveInteger" },
6711
- { trigger: "\\Z_+", parse: "PositiveInteger" },
6712
- { trigger: "\\Z_{+}", parse: "PositiveInteger" },
6713
- { trigger: "\\Z^{\\gt}", parse: "PositiveInteger" },
6714
- { trigger: "\\Z^{\\gt0}", parse: "PositiveInteger" },
6715
- { trigger: "\\N^+", parse: "PositiveInteger" },
6716
- { trigger: "\\N^{+}", parse: "PositiveInteger" },
6717
- { trigger: "\\N^*", parse: "PositiveInteger" },
6718
- { trigger: "\\N^{*}", parse: "PositiveInteger" },
6719
- { trigger: "\\N^\\star", parse: "PositiveInteger" },
6720
- { trigger: "\\N^{\\star}", parse: "PositiveInteger" },
6721
- { trigger: "\\N_1", parse: "PositiveInteger" },
6722
- { trigger: "\\N_{1}", parse: "PositiveInteger" },
6978
+ { name: "PositiveInteger", latexTrigger: "\\Z^+" },
6979
+ { latexTrigger: "\\Z^{+}", parse: "PositiveInteger" },
6980
+ { latexTrigger: "\\Z_+", parse: "PositiveInteger" },
6981
+ { latexTrigger: "\\Z_{+}", parse: "PositiveInteger" },
6982
+ { latexTrigger: "\\Z^{\\gt}", parse: "PositiveInteger" },
6983
+ { latexTrigger: "\\Z^{\\gt0}", parse: "PositiveInteger" },
6984
+ { latexTrigger: "\\N^+", parse: "PositiveInteger" },
6985
+ { latexTrigger: "\\N^{+}", parse: "PositiveInteger" },
6986
+ { latexTrigger: "\\N^*", parse: "PositiveInteger" },
6987
+ { latexTrigger: "\\N^{*}", parse: "PositiveInteger" },
6988
+ { latexTrigger: "\\N^\\star", parse: "PositiveInteger" },
6989
+ { latexTrigger: "\\N^{\\star}", parse: "PositiveInteger" },
6990
+ { latexTrigger: "\\N_1", parse: "PositiveInteger" },
6991
+ { latexTrigger: "\\N_{1}", parse: "PositiveInteger" },
6723
6992
  // https://mathvault.ca/hub/higher-math/math-symbols/algebra-symbols/
6724
6993
  // Integers >= 0
6725
- { name: "NonNegativeInteger", trigger: ["\\N"] },
6726
- { trigger: "\\Z^{+0}", parse: "NonNegativeInteger" },
6727
- { trigger: "\\Z^{\\geq}", parse: "NonNegativeInteger" },
6728
- { trigger: "\\Z^{\\geq0}", parse: "NonNegativeInteger" },
6729
- { trigger: "\\Z^{0+}", parse: "NonNegativeInteger" },
6730
- { trigger: "\\mathbb{N}", parse: "NonNegativeInteger" },
6731
- { trigger: "\\N_0", parse: "NonNegativeInteger" },
6732
- { trigger: "\\N_{0}", parse: "NonNegativeInteger" },
6994
+ { name: "NonNegativeInteger", latexTrigger: ["\\N"] },
6995
+ { latexTrigger: "\\Z^{+0}", parse: "NonNegativeInteger" },
6996
+ { latexTrigger: "\\Z^{\\geq}", parse: "NonNegativeInteger" },
6997
+ { latexTrigger: "\\Z^{\\geq0}", parse: "NonNegativeInteger" },
6998
+ { latexTrigger: "\\Z^{0+}", parse: "NonNegativeInteger" },
6999
+ { latexTrigger: "\\mathbb{N}", parse: "NonNegativeInteger" },
7000
+ { latexTrigger: "\\N_0", parse: "NonNegativeInteger" },
7001
+ { latexTrigger: "\\N_{0}", parse: "NonNegativeInteger" },
6733
7002
  //
6734
7003
  // Set Expressions
6735
7004
  //
6736
7005
  // @todo: could also have a `CartesianPower` function with a number `rhs`
6737
7006
  {
6738
7007
  name: "CartesianProduct",
6739
- trigger: ["\\times"],
7008
+ latexTrigger: ["\\times"],
6740
7009
  kind: "infix",
6741
7010
  associativity: "right",
6742
7011
  // Caution: cartesian product is not associative
@@ -6758,7 +7027,7 @@ var DEFINITIONS_SETS = [
6758
7027
  }
6759
7028
  },
6760
7029
  {
6761
- trigger: ["^", "\\complement"],
7030
+ latexTrigger: ["^", "\\complement"],
6762
7031
  kind: "postfix",
6763
7032
  parse: (_parser, lhs) => {
6764
7033
  return ["Complement", lhs];
@@ -6768,14 +7037,14 @@ var DEFINITIONS_SETS = [
6768
7037
  },
6769
7038
  {
6770
7039
  name: "Complement",
6771
- trigger: ["^", "<{>", "\\complement", "<}>"],
7040
+ latexTrigger: ["^", "<{>", "\\complement", "<}>"],
6772
7041
  kind: "postfix"
6773
7042
  // precedence: 240,
6774
7043
  // @todo: serialize for the multiple argument case
6775
7044
  },
6776
7045
  {
6777
7046
  name: "Intersection",
6778
- trigger: ["\\cap"],
7047
+ latexTrigger: ["\\cap"],
6779
7048
  kind: "infix",
6780
7049
  precedence: 350
6781
7050
  },
@@ -6791,7 +7060,7 @@ var DEFINITIONS_SETS = [
6791
7060
  },
6792
7061
  {
6793
7062
  name: "Union",
6794
- trigger: ["\\cup"],
7063
+ latexTrigger: ["\\cup"],
6795
7064
  kind: "infix",
6796
7065
  precedence: 350
6797
7066
  },
@@ -6810,13 +7079,13 @@ var DEFINITIONS_SETS = [
6810
7079
  // },
6811
7080
  {
6812
7081
  name: "SetMinus",
6813
- trigger: ["\\setminus"],
7082
+ latexTrigger: ["\\setminus"],
6814
7083
  kind: "infix",
6815
7084
  precedence: 650
6816
7085
  },
6817
7086
  {
6818
7087
  name: "SymmetricDifference",
6819
- trigger: ["\\triangle"],
7088
+ latexTrigger: ["\\triangle"],
6820
7089
  // or \\ominus
6821
7090
  kind: "infix",
6822
7091
  // @todo: parser could check that lhs and rhs are sets
@@ -6824,7 +7093,7 @@ var DEFINITIONS_SETS = [
6824
7093
  },
6825
7094
  // Predicates/Relations
6826
7095
  {
6827
- trigger: ["\\ni"],
7096
+ latexTrigger: ["\\ni"],
6828
7097
  kind: "infix",
6829
7098
  associativity: "right",
6830
7099
  precedence: 160,
@@ -6836,40 +7105,40 @@ var DEFINITIONS_SETS = [
6836
7105
  },
6837
7106
  {
6838
7107
  name: "Element",
6839
- trigger: ["\\in"],
7108
+ latexTrigger: ["\\in"],
6840
7109
  kind: "infix",
6841
7110
  precedence: 240
6842
7111
  },
6843
7112
  {
6844
7113
  name: "NotElement",
6845
- trigger: ["\\notin"],
7114
+ latexTrigger: ["\\notin"],
6846
7115
  kind: "infix",
6847
7116
  precedence: 240
6848
7117
  },
6849
7118
  {
6850
7119
  name: "NotSubset",
6851
- trigger: ["\\nsubset"],
7120
+ latexTrigger: ["\\nsubset"],
6852
7121
  kind: "infix",
6853
7122
  associativity: "right",
6854
7123
  precedence: 240
6855
7124
  },
6856
7125
  {
6857
7126
  name: "NotSuperset",
6858
- trigger: ["\\nsupset"],
7127
+ latexTrigger: ["\\nsupset"],
6859
7128
  kind: "infix",
6860
7129
  associativity: "right",
6861
7130
  precedence: 240
6862
7131
  },
6863
7132
  {
6864
7133
  name: "NotSubsetNotEqual",
6865
- trigger: ["\\nsubseteq"],
7134
+ latexTrigger: ["\\nsubseteq"],
6866
7135
  kind: "infix",
6867
7136
  associativity: "right",
6868
7137
  precedence: 240
6869
7138
  },
6870
7139
  {
6871
7140
  name: "NotSupersetNotEqual",
6872
- trigger: ["\\nsupseteq"],
7141
+ latexTrigger: ["\\nsupseteq"],
6873
7142
  kind: "infix",
6874
7143
  associativity: "right",
6875
7144
  precedence: 240
@@ -6877,7 +7146,7 @@ var DEFINITIONS_SETS = [
6877
7146
  {
6878
7147
  name: "SquareSubset",
6879
7148
  // MathML: square image of
6880
- trigger: ["\\sqsubset"],
7149
+ latexTrigger: ["\\sqsubset"],
6881
7150
  kind: "infix",
6882
7151
  associativity: "right",
6883
7152
  precedence: 265
@@ -6885,7 +7154,7 @@ var DEFINITIONS_SETS = [
6885
7154
  {
6886
7155
  name: "SquareSubsetEqual",
6887
7156
  // MathML: square image of or equal to
6888
- trigger: ["\\sqsubseteq"],
7157
+ latexTrigger: ["\\sqsubseteq"],
6889
7158
  kind: "infix",
6890
7159
  associativity: "right",
6891
7160
  precedence: 265
@@ -6893,7 +7162,7 @@ var DEFINITIONS_SETS = [
6893
7162
  {
6894
7163
  name: "SquareSuperset",
6895
7164
  // MathML: square original of
6896
- trigger: ["\\sqsupset"],
7165
+ latexTrigger: ["\\sqsupset"],
6897
7166
  kind: "infix",
6898
7167
  associativity: "right",
6899
7168
  precedence: 265
@@ -6901,27 +7170,27 @@ var DEFINITIONS_SETS = [
6901
7170
  {
6902
7171
  name: "SquareSupersetEqual",
6903
7172
  // MathML: square original of or equal
6904
- trigger: ["\\sqsupseteq"],
7173
+ latexTrigger: ["\\sqsupseteq"],
6905
7174
  kind: "infix",
6906
7175
  associativity: "right",
6907
7176
  precedence: 265
6908
7177
  },
6909
7178
  {
6910
7179
  name: "Subset",
6911
- trigger: ["\\subset"],
7180
+ latexTrigger: ["\\subset"],
6912
7181
  kind: "infix",
6913
7182
  associativity: "right",
6914
7183
  precedence: 240
6915
7184
  },
6916
7185
  {
6917
- trigger: ["\\subsetneq"],
7186
+ latexTrigger: ["\\subsetneq"],
6918
7187
  kind: "infix",
6919
7188
  associativity: "right",
6920
7189
  precedence: 240,
6921
7190
  parse: "Subset"
6922
7191
  },
6923
7192
  {
6924
- trigger: ["\\varsubsetneqq"],
7193
+ latexTrigger: ["\\varsubsetneqq"],
6925
7194
  kind: "infix",
6926
7195
  associativity: "right",
6927
7196
  precedence: 240,
@@ -6929,26 +7198,26 @@ var DEFINITIONS_SETS = [
6929
7198
  },
6930
7199
  {
6931
7200
  name: "SubsetEqual",
6932
- trigger: ["\\subseteq"],
7201
+ latexTrigger: ["\\subseteq"],
6933
7202
  kind: "infix",
6934
7203
  precedence: 240
6935
7204
  },
6936
7205
  {
6937
7206
  name: "Superset",
6938
- trigger: ["\\supset"],
7207
+ latexTrigger: ["\\supset"],
6939
7208
  kind: "infix",
6940
7209
  associativity: "right",
6941
7210
  precedence: 240
6942
7211
  },
6943
7212
  {
6944
- trigger: ["\\supsetneq"],
7213
+ latexTrigger: ["\\supsetneq"],
6945
7214
  kind: "infix",
6946
7215
  associativity: "right",
6947
7216
  precedence: 240,
6948
7217
  parse: "Superset"
6949
7218
  },
6950
7219
  {
6951
- trigger: ["\\varsupsetneq"],
7220
+ latexTrigger: ["\\varsupsetneq"],
6952
7221
  kind: "infix",
6953
7222
  associativity: "right",
6954
7223
  precedence: 240,
@@ -6956,7 +7225,7 @@ var DEFINITIONS_SETS = [
6956
7225
  },
6957
7226
  {
6958
7227
  name: "SupersetEqual",
6959
- trigger: ["\\supseteq"],
7228
+ latexTrigger: ["\\supseteq"],
6960
7229
  kind: "infix",
6961
7230
  associativity: "right",
6962
7231
  precedence: 240
@@ -7119,6 +7388,8 @@ function parseIntegralBody(parser, n = 1) {
7119
7388
  condition: () => {
7120
7389
  if (parser.matchAll(["\\mathrm", "<{>", "d", "<}>"]))
7121
7390
  found = true;
7391
+ else if (parser.matchAll(["\\operatorname", "<{>", "d", "<}>"]))
7392
+ found = true;
7122
7393
  return found;
7123
7394
  }
7124
7395
  });
@@ -7236,7 +7507,7 @@ function serializeIntegral(command) {
7236
7507
  command,
7237
7508
  "\\!",
7238
7509
  serializer.serialize(fn),
7239
- "\\,\\mathrm{d}",
7510
+ "\\,\\operatorname{d}",
7240
7511
  serializer.serialize(index)
7241
7512
  ]);
7242
7513
  }
@@ -7254,7 +7525,7 @@ function serializeIntegral(command) {
7254
7525
  sub2,
7255
7526
  "\\!",
7256
7527
  serializer.serialize(fn),
7257
- ...index && symbol(index) !== "Nothing" ? ["\\,\\mathrm{d}", serializer.serialize(index)] : []
7528
+ ...index && symbol(index) !== "Nothing" ? ["\\,\\operatorname{d}", serializer.serialize(index)] : []
7258
7529
  ]);
7259
7530
  };
7260
7531
  }
@@ -7262,35 +7533,35 @@ var DEFINITIONS_CALCULUS = [
7262
7533
  {
7263
7534
  kind: "expression",
7264
7535
  name: "Integrate",
7265
- trigger: ["\\int"],
7536
+ latexTrigger: ["\\int"],
7266
7537
  parse: parseIntegral("Integrate"),
7267
7538
  serialize: serializeIntegral("\\int")
7268
7539
  },
7269
7540
  {
7270
7541
  kind: "expression",
7271
- trigger: ["\\iint"],
7542
+ latexTrigger: ["\\iint"],
7272
7543
  parse: parseIntegral("Integrate", 2)
7273
7544
  },
7274
7545
  {
7275
7546
  kind: "expression",
7276
- trigger: ["\\iiint"],
7547
+ latexTrigger: ["\\iiint"],
7277
7548
  parse: parseIntegral("Integrate", 3)
7278
7549
  },
7279
7550
  {
7280
7551
  kind: "expression",
7281
7552
  name: "CircularIntegrate",
7282
- trigger: ["\\oint"],
7553
+ latexTrigger: ["\\oint"],
7283
7554
  parse: parseIntegral("CircularIntegrate"),
7284
7555
  serialize: serializeIntegral("\\oint")
7285
7556
  },
7286
7557
  {
7287
7558
  kind: "expression",
7288
- trigger: ["\\oiint"],
7559
+ latexTrigger: ["\\oiint"],
7289
7560
  parse: parseIntegral("CircularIntegrate", 2)
7290
7561
  },
7291
7562
  {
7292
7563
  kind: "expression",
7293
- trigger: ["\\oiiint"],
7564
+ latexTrigger: ["\\oiiint"],
7294
7565
  parse: parseIntegral("CircularIntegrate", 3)
7295
7566
  }
7296
7567
  ];
@@ -7397,14 +7668,14 @@ var DEFINITIONS_SYMBOLS = [
7397
7668
  return {
7398
7669
  kind: "symbol",
7399
7670
  name: symbol2,
7400
- trigger: [latex],
7671
+ latexTrigger: [latex],
7401
7672
  parse: symbol2
7402
7673
  };
7403
7674
  }),
7404
7675
  ...SYMBOLS.map(([symbol2, _latex, codepoint]) => {
7405
7676
  return {
7406
7677
  kind: "symbol",
7407
- trigger: [String.fromCodePoint(codepoint)],
7678
+ latexTrigger: [String.fromCodePoint(codepoint)],
7408
7679
  parse: symbol2
7409
7680
  };
7410
7681
  })
@@ -7427,293 +7698,350 @@ var DEFAULT_DELIMITER = {
7427
7698
  "\\rceil": "\\rceil",
7428
7699
  "\\rfloor": "\\rfloor"
7429
7700
  };
7430
- function triggerLength(trigger) {
7431
- if (Array.isArray(trigger))
7432
- return trigger.length;
7433
- return 1;
7434
- }
7435
7701
  function addEntry(result, entry, onError) {
7436
- const [trigger, indexedEntry] = makeIndexedEntry(entry, onError);
7702
+ const indexedEntry = makeIndexedEntry(entry, onError);
7437
7703
  if (indexedEntry === null)
7438
7704
  return;
7439
7705
  const kind = "kind" in entry ? entry.kind : "expression";
7440
- if (trigger && trigger.length === 2 && /[_^]/.test(trigger[0]) && trigger[1] !== "<{>" && kind !== "function" && entry.name) {
7706
+ const latexTrigger = indexedEntry.latexTrigger;
7707
+ if (typeof latexTrigger === "string")
7708
+ result.lookahead = Math.max(result.lookahead, countTokens(latexTrigger));
7709
+ const tokensTrigger = tokenize(latexTrigger ?? "", []);
7710
+ if (latexTrigger?.[1] === "\\prime")
7711
+ debugger;
7712
+ if (tokensTrigger.length === 2 && /[_^]/.test(tokensTrigger[0]) && tokensTrigger[1] !== "<{>" && kind !== "function" && kind !== "environment" && kind !== "matchfix") {
7441
7713
  let parse = entry.parse;
7442
- if (parse === void 0) {
7443
- if (kind === "symbol")
7444
- parse = entry.name;
7714
+ if (!parse && entry.name) {
7445
7715
  if (kind === "postfix" || kind === "prefix")
7446
7716
  parse = (_parser, expr) => [entry.name, expr];
7717
+ else
7718
+ parse = entry.name;
7447
7719
  }
7448
7720
  addEntry(
7449
7721
  result,
7450
7722
  {
7451
7723
  ...entry,
7452
7724
  kind,
7453
- parse,
7454
7725
  name: void 0,
7455
- trigger: [trigger[0], "<{>", trigger[1], "<}>"]
7726
+ serialize: void 0,
7727
+ parse,
7728
+ latexTrigger: [tokensTrigger[0], "<{>", tokensTrigger[1], "<}>"]
7456
7729
  },
7457
7730
  onError
7458
7731
  );
7459
7732
  }
7733
+ result.defs.push(indexedEntry);
7460
7734
  if (indexedEntry.name !== void 0) {
7461
- if (result.name.has(indexedEntry.name)) {
7735
+ if (result.ids.has(indexedEntry.name)) {
7462
7736
  onError({
7463
7737
  severity: "warning",
7464
7738
  message: [
7465
7739
  "invalid-dictionary-entry",
7466
7740
  indexedEntry.name,
7467
- "Duplicate definition. The name must be unique, but a trigger can be used by multiple definitions."
7468
- ]
7469
- });
7470
- }
7471
- result.name.set(indexedEntry.name, indexedEntry);
7472
- }
7473
- if (indexedEntry.kind === "matchfix") {
7474
- result.matchfix.push(indexedEntry);
7475
- } else if (indexedEntry.kind === "environment") {
7476
- const triggerString = tokensToString(entry.trigger ?? "");
7477
- if (result.environment.has(triggerString)) {
7478
- onError({
7479
- severity: "warning",
7480
- message: [
7481
- "invalid-dictionary-entry",
7482
- triggerString,
7483
- "Duplicate environment definition"
7741
+ "Duplicate definition. The name (MathJSON identifier) must be unique, but triggers can be shared by multiple definitions."
7484
7742
  ]
7485
7743
  });
7486
7744
  }
7487
- result.environment.set(triggerString, indexedEntry);
7488
- } else if (trigger) {
7489
- console.assert(entry.trigger);
7490
- const triggerString = tokensToString(entry.trigger ?? "");
7491
- const n = triggerLength(trigger);
7492
- result.lookahead = Math.max(result.lookahead, n);
7493
- if (indexedEntry.kind === "function") {
7494
- if (!result.function.has(triggerString))
7495
- result.function.set(triggerString, [indexedEntry]);
7496
- else
7497
- result.function.set(triggerString, [
7498
- ...result.function.get(triggerString),
7499
- indexedEntry
7500
- ]);
7501
- } else {
7502
- const kind2 = indexedEntry.kind;
7503
- if (result[kind2][n] === void 0)
7504
- result[kind2][n] = /* @__PURE__ */ new Map();
7505
- const list = result[kind2][n];
7506
- if (list.has(triggerString))
7507
- list.get(triggerString).push(indexedEntry);
7508
- else
7509
- list.set(triggerString, [indexedEntry]);
7510
- }
7745
+ result.ids.set(indexedEntry.name, indexedEntry);
7511
7746
  }
7512
7747
  }
7513
7748
  function indexLatexDictionary(dic, onError) {
7514
7749
  const result = {
7515
7750
  lookahead: 1,
7516
- name: /* @__PURE__ */ new Map(),
7517
- expression: [],
7518
- symbol: [],
7519
- infix: [],
7520
- prefix: [],
7521
- postfix: [],
7522
- function: /* @__PURE__ */ new Map(),
7523
- environment: /* @__PURE__ */ new Map(),
7524
- matchfix: []
7751
+ ids: /* @__PURE__ */ new Map(),
7752
+ defs: []
7525
7753
  };
7526
7754
  for (const entry of dic)
7527
7755
  addEntry(result, entry, onError);
7528
7756
  return result;
7529
7757
  }
7530
7758
  function makeIndexedEntry(entry, onError) {
7531
- if (!entryIsValid(entry, onError))
7532
- return [null, null];
7759
+ if (!isValidEntry(entry, onError))
7760
+ return null;
7533
7761
  const result = {
7534
- name: entry.name,
7535
7762
  kind: "kind" in entry ? entry.kind : "expression"
7536
7763
  };
7764
+ let tokensTrigger = null;
7765
+ if ("latexTrigger" in entry) {
7766
+ if (typeof entry.latexTrigger === "string")
7767
+ tokensTrigger = tokenize(entry.latexTrigger, []);
7768
+ else
7769
+ tokensTrigger = entry.latexTrigger;
7770
+ }
7771
+ let idTrigger = null;
7772
+ if ("identifierTrigger" in entry) {
7773
+ idTrigger = entry.identifierTrigger;
7774
+ }
7775
+ if (tokensTrigger !== null)
7776
+ result.latexTrigger = tokensToString(tokensTrigger);
7777
+ if (idTrigger !== null)
7778
+ result.identifierTrigger = idTrigger;
7779
+ if (entry.name) {
7780
+ result.name = entry.name;
7781
+ result.serialize = makeSerializeHandler(entry, tokensTrigger, idTrigger);
7782
+ }
7537
7783
  if (result.kind === "matchfix" && isMatchfixEntry(entry)) {
7538
- result.openDelimiter = entry.openDelimiter;
7539
- result.closeDelimiter = entry.closeDelimiter;
7540
- if (typeof entry.serialize === "function")
7541
- result.serialize = entry.serialize;
7542
- else {
7543
- const openDelim = typeof result.openDelimiter === "string" ? DEFAULT_DELIMITER[result.openDelimiter] : tokensToString(result.openDelimiter);
7544
- const closeDelim = typeof result.closeDelimiter === "string" ? DEFAULT_DELIMITER[result.closeDelimiter] : tokensToString(result.closeDelimiter);
7545
- result.serialize = (serializer, expr) => joinLatex([openDelim, serializer.serialize(op(expr, 1)), closeDelim]);
7546
- }
7547
- if (typeof entry.parse === "function")
7548
- result.parse = entry.parse;
7549
- else {
7550
- console.assert(entry.parse || entry.name);
7551
- const head2 = entry.parse ?? entry.name;
7552
- result.parse = (_parser, expr) => [head2, expr];
7553
- }
7554
- return [null, result];
7555
- }
7556
- if (result.kind === "environment" && isEnvironmentEntry(entry)) {
7557
- const envName = entry.trigger;
7558
- result.serialize = entry.serialize ?? ((serializer, expr) => `\\begin{${envName}}${serializer.serialize(
7559
- op(expr, 1)
7560
- )}\\end{${envName}}`);
7561
- result.parse = entry.parse ?? (() => null);
7562
- return [envName, result];
7563
- }
7564
- const trigger = typeof entry.trigger === "string" ? tokenize(entry.trigger, []) : entry.trigger;
7565
- const triggerString = trigger ? tokensToString(trigger) : "";
7566
- if (result.kind === "function" && isFunctionEntry(entry)) {
7567
- result.serialize = entry.serialize;
7568
- if (triggerString && !entry.serialize) {
7569
- if (triggerString.startsWith("\\")) {
7570
- result.serialize = (serializer, expr) => `${triggerString}${serializer.wrapArguments(expr)}`;
7571
- } else
7572
- result.serialize = (serializer, expr) => `\\mathrm{${triggerString}}${serializer.wrapArguments(expr)}`;
7573
- }
7574
- if (typeof entry.parse === "function")
7575
- result.parse = entry.parse;
7576
- else if (typeof entry.parse === "string")
7577
- result.parse = () => entry.parse;
7578
- else if (entry.name)
7579
- result.parse = () => entry.name;
7580
- return [triggerString, result];
7581
- }
7582
- if (result.kind === "expression" && isExpressionEntry(entry)) {
7583
- result.serialize = entry.serialize ?? triggerString;
7584
- if (typeof result.serialize === "string") {
7585
- const serializeExpr = result.serialize;
7586
- result.serialize = (serializer, expr) => {
7587
- if (!head(expr))
7588
- return serializer.serialize(serializeExpr);
7589
- return `${serializer.serialize(
7590
- serializeExpr
7591
- )}${serializer.wrapArguments(expr)}`;
7592
- };
7593
- }
7594
- {
7595
- if (typeof entry.parse === "function") {
7596
- result.parse = entry.parse;
7597
- } else {
7598
- const parseResult = entry.parse ?? entry.name;
7599
- result.parse = () => parseResult;
7600
- }
7601
- }
7602
- return [triggerString, result];
7784
+ result.openDelimiter = entry.openTrigger;
7785
+ result.closeDelimiter = entry.closeTrigger;
7603
7786
  }
7604
- console.assert(
7605
- typeof entry.trigger !== "string" || entry.parse || trigger.length > 1 || "kind" in entry && entry.kind === "function",
7606
- `Trigger shortcuts should produce more than one token. Otherwise, not worth using them. (${triggerString})`
7607
- );
7608
7787
  if (result.kind === "symbol" && isSymbolEntry(entry)) {
7609
7788
  result.precedence = entry.precedence ?? 1e4;
7610
7789
  }
7611
- if ((result.kind === "infix" || result.kind === "prefix" || result.kind === "postfix") && (isInfixEntry(entry) || isPrefixEntry(entry) || isPostfixEntry(entry))) {
7612
- if (trigger && (trigger[0] === "^" || trigger[0] === "_")) {
7790
+ if ((result.kind === "prefix" || result.kind === "postfix") && (isPrefixEntry(entry) || isPostfixEntry(entry))) {
7791
+ if (tokensTrigger && (tokensTrigger[0] === "^" || tokensTrigger[0] === "_")) {
7613
7792
  result.precedence = 720;
7614
7793
  console.assert(
7615
7794
  entry.precedence === void 0,
7616
- "'precedence' not allowed with ^ and _ triggers"
7795
+ "'precedence' is fixed and cannot be modified with ^ and _ triggers"
7617
7796
  );
7618
7797
  } else
7619
7798
  result.precedence = entry.precedence ?? 1e4;
7620
7799
  }
7621
7800
  if (result.kind === "infix" && isInfixEntry(entry)) {
7622
7801
  console.assert(
7623
- !trigger || trigger[0] !== "^" && trigger[0] !== "_" || !entry.associativity || entry.associativity === "non"
7802
+ !tokensTrigger || tokensTrigger[0] !== "^" && tokensTrigger[0] !== "_" || !entry.associativity || entry.associativity === "non"
7624
7803
  );
7625
7804
  result.associativity = entry.associativity ?? "non";
7626
- if (typeof entry.parse === "function") {
7627
- result.parse = entry.parse;
7628
- } else if (trigger && (trigger[0] === "^" || trigger[0] === "_")) {
7629
- console.assert(!entry.parse);
7630
- const name = entry.parse ?? entry.name;
7631
- result.parse = (_scanner, arg, _terminator) => [
7632
- name,
7805
+ result.precedence = entry.precedence ?? 1e4;
7806
+ }
7807
+ const parse = makeParseHandler(entry, tokensTrigger, idTrigger);
7808
+ if (parse)
7809
+ result.parse = parse;
7810
+ return result;
7811
+ }
7812
+ function makeSerializeHandler(entry, latexTrigger, idTrigger) {
7813
+ if (typeof entry.serialize === "function")
7814
+ return entry.serialize;
7815
+ const kind = entry["kind"] ?? "expression";
7816
+ if (kind === "environment") {
7817
+ const envName = entry["identifierTrigger"] ?? entry.name ?? "unknown";
7818
+ return (serializer, expr) => joinLatex([
7819
+ `\\begin{${envName}}`,
7820
+ serializer.serialize(op(expr, 1)),
7821
+ `\\end{${envName}}`
7822
+ ]);
7823
+ }
7824
+ if (isMatchfixEntry(entry)) {
7825
+ const openDelim = typeof entry.openTrigger === "string" ? DEFAULT_DELIMITER[entry.openTrigger] : tokensToString(entry["openDelimiter"]);
7826
+ const closeDelim = typeof entry.closeTrigger === "string" ? DEFAULT_DELIMITER[entry.closeTrigger] : tokensToString(entry["closeDelimiter"]);
7827
+ return (serializer, expr) => joinLatex([openDelim, serializer.serialize(op(expr, 1)), closeDelim]);
7828
+ }
7829
+ let latex = entry.serialize;
7830
+ if (latex === void 0 && latexTrigger)
7831
+ latex = tokensToString(latexTrigger);
7832
+ if (latex) {
7833
+ if (kind === "postfix")
7834
+ return (serializer, expr) => joinLatex([serializer.serialize(op(expr, 1)), latex]);
7835
+ if (kind === "prefix")
7836
+ return (serializer, expr) => joinLatex([latex, serializer.serialize(op(expr, 1))]);
7837
+ if (kind === "infix") {
7838
+ return (serializer, expr) => joinLatex(
7839
+ (ops(expr) ?? []).flatMap(
7840
+ (val, i) => i < nops(expr) - 1 ? [serializer.serialize(val), latex] : [serializer.serialize(val)]
7841
+ )
7842
+ );
7843
+ }
7844
+ return (serializer, expr) => head(expr) ? joinLatex([latex, serializer.wrapArguments(expr)]) : latex;
7845
+ }
7846
+ const id = idTrigger ?? entry.name ?? "unknown";
7847
+ if (kind === "postfix")
7848
+ return (serializer, expr) => joinLatex([
7849
+ serializer.serialize(op(expr, 1)),
7850
+ serializer.serializeSymbol(id)
7851
+ ]);
7852
+ if (kind === "prefix")
7853
+ return (serializer, expr) => joinLatex([
7854
+ serializer.serializeSymbol(id),
7855
+ serializer.serialize(op(expr, 1))
7856
+ ]);
7857
+ if (kind === "infix")
7858
+ return (serializer, expr) => joinLatex([
7859
+ serializer.serialize(op(expr, 1)),
7860
+ serializer.serializeSymbol(id),
7861
+ serializer.serialize(op(expr, 2))
7862
+ ]);
7863
+ return (serializer, expr) => head(expr) ? joinLatex([
7864
+ serializer.serializeSymbol(id),
7865
+ serializer.wrapArguments(expr)
7866
+ ]) : serializer.serializeSymbol(id);
7867
+ }
7868
+ function makeParseHandler(entry, latexTrigger, idTrigger) {
7869
+ if ("parse" in entry && typeof entry.parse === "function")
7870
+ return entry.parse;
7871
+ const kind = "kind" in entry ? entry.kind : "expression";
7872
+ if (kind === "environment") {
7873
+ const envName = entry.parse ?? idTrigger ?? entry.name;
7874
+ if (envName)
7875
+ return (parser, _until) => {
7876
+ const array = parser.parseTabular();
7877
+ if (array === null)
7878
+ return null;
7879
+ return [envName, ["List", array.map((row) => ["List", ...row])]];
7880
+ };
7881
+ }
7882
+ if (kind === "function") {
7883
+ const fnName = entry.parse ?? idTrigger ?? entry.name;
7884
+ if (fnName)
7885
+ return (parser, until) => {
7886
+ const args = parser.parseArguments("enclosure", until);
7887
+ return args === null ? fnName : [fnName, ...args];
7888
+ };
7889
+ }
7890
+ if (kind === "symbol") {
7891
+ const symName = entry.parse ?? idTrigger ?? entry.name;
7892
+ if (symName)
7893
+ return (_parser, _terminator) => symName;
7894
+ }
7895
+ if (kind === "prefix") {
7896
+ const h = entry.parse ?? idTrigger ?? entry.name;
7897
+ if (h) {
7898
+ const prec = entry["precedence"] ?? 1e4;
7899
+ return (parser, until) => {
7900
+ const rhs = parser.parseExpression({
7901
+ ...until ?? [],
7902
+ minPrec: prec
7903
+ });
7904
+ return rhs === null ? null : [h, rhs];
7905
+ };
7906
+ }
7907
+ }
7908
+ if (kind === "postfix") {
7909
+ const h = entry.parse ?? entry.name;
7910
+ if (h)
7911
+ return (_parser, lhs) => lhs === null ? null : [h, lhs];
7912
+ }
7913
+ if (kind === "infix") {
7914
+ if (/[_^]/.test(latexTrigger?.[0] ?? "")) {
7915
+ const h2 = entry.name ?? entry.parse;
7916
+ return (_parser, arg) => [
7917
+ h2,
7633
7918
  missingIfEmpty(op(arg, 1)),
7634
7919
  missingIfEmpty(op(arg, 2))
7635
7920
  ];
7636
- } else {
7637
- const head2 = entry.parse ?? entry.name;
7638
- const prec = result.precedence;
7639
- const associativity = result.associativity;
7640
- result.parse = (scanner, lhs, terminator) => {
7641
- if (prec < terminator.minPrec)
7921
+ }
7922
+ const h = entry.parse ?? idTrigger ?? entry.name;
7923
+ const prec = entry["precedence"] ?? 1e4;
7924
+ const associativity = entry["associativity"] ?? "non";
7925
+ if (h)
7926
+ return (parser, lhs, until) => {
7927
+ if (lhs === null)
7928
+ return null;
7929
+ if (prec < until.minPrec)
7642
7930
  return null;
7643
7931
  const rhs = missingIfEmpty(
7644
- scanner.parseExpression({
7645
- ...terminator,
7646
- minPrec: prec
7647
- })
7932
+ parser.parseExpression({ ...until, minPrec: prec })
7648
7933
  );
7649
- return typeof head2 === "string" ? applyAssociativeOperator(head2, lhs, rhs, associativity) : [head2, lhs, rhs];
7934
+ return typeof h === "string" ? applyAssociativeOperator(h, lhs, rhs, associativity) : [h, lhs, rhs];
7650
7935
  };
7651
- }
7652
- } else {
7653
- if (typeof entry.parse === "function") {
7654
- result.parse = entry.parse;
7655
- } else if (entry.parse !== void 0) {
7656
- console.assert(result.kind === "symbol" || result.kind === "expression");
7657
- result.parse = () => entry.parse;
7658
- } else if (entry.parse === void 0 && entry.name !== void 0) {
7659
- if (result.kind === "postfix") {
7660
- result.parse = (_parser, lhs) => lhs ? [entry.name, lhs] : null;
7661
- } else if (result.kind === "prefix") {
7662
- const prec = result.precedence;
7663
- console.assert(entry.name);
7664
- const head2 = entry.name;
7665
- result.parse = (parser, terminator) => {
7666
- if (terminator && prec < terminator.minPrec)
7667
- return null;
7668
- const rhs = parser.parseExpression({ ...terminator, minPrec: prec });
7669
- return rhs === null ? null : [head2, rhs];
7670
- };
7671
- }
7672
- }
7673
- }
7674
- if (typeof entry.serialize === "function" || typeof entry.serialize === "string") {
7675
- result.serialize = entry.serialize;
7676
- } else if (trigger) {
7677
- if (result.kind === "postfix") {
7678
- result.serialize = "#1" + triggerString;
7679
- } else if (result.kind === "prefix") {
7680
- result.serialize = triggerString + "#1";
7681
- } else if (result.kind === "infix") {
7682
- result.serialize = "#1" + triggerString + "#2";
7683
- } else if (result.kind === "symbol") {
7684
- result.serialize = triggerString;
7685
- } else {
7686
- result.serialize = "";
7687
- }
7688
7936
  }
7689
- return [trigger ?? null, result];
7937
+ if (kind === "matchfix") {
7938
+ const h = entry.parse ?? entry.name;
7939
+ if (h)
7940
+ return (_parser, body) => {
7941
+ if (body === null || isEmptySequence(body))
7942
+ return null;
7943
+ return [h, body];
7944
+ };
7945
+ }
7946
+ if (kind === "expression") {
7947
+ const parseResult = entry.parse ?? idTrigger ?? entry.name;
7948
+ if (parseResult)
7949
+ return () => parseResult;
7950
+ }
7951
+ if ("parse" in entry) {
7952
+ const parseResult = entry.parse;
7953
+ return () => parseResult;
7954
+ }
7955
+ return void 0;
7690
7956
  }
7691
- function entryIsValid(entry, onError) {
7692
- const subject = entry.name ?? entry.trigger ?? entry["openDelimiter"];
7957
+ function isValidEntry(entry, onError) {
7958
+ let subject = entry.name ?? entry["latexTrigger"] ?? entry["identifierTrigger"] ?? entry["openDelimiter"];
7959
+ if (!subject) {
7960
+ try {
7961
+ subject = JSON.stringify(entry);
7962
+ } catch (e) {
7963
+ subject = "???";
7964
+ }
7965
+ }
7966
+ if (Array.isArray(subject))
7967
+ subject = tokensToString(subject);
7968
+ if ("kind" in entry && ![
7969
+ "expression",
7970
+ "symbol",
7971
+ "function",
7972
+ "infix",
7973
+ "postfix",
7974
+ "prefix",
7975
+ "matchfix",
7976
+ "environment"
7977
+ ].includes(entry.kind)) {
7978
+ onError({
7979
+ severity: "warning",
7980
+ message: [
7981
+ "invalid-dictionary-entry",
7982
+ subject,
7983
+ `The 'kind' property must be one of 'expression', 'symbol', 'function', 'infix', 'postfix', 'prefix', 'matchfix', 'environment'`
7984
+ ]
7985
+ });
7986
+ }
7693
7987
  if (entry.serialize !== void 0 && !entry.name) {
7694
7988
  onError({
7695
7989
  severity: "warning",
7696
7990
  message: [
7697
7991
  "invalid-dictionary-entry",
7698
7992
  subject,
7699
- `Unexpected serialize property without a name property`
7993
+ `A 'name' property must be provided if a 'serialize' handler is provided`
7700
7994
  ]
7701
7995
  });
7702
7996
  return false;
7703
7997
  }
7998
+ if ("identifierTrigger" in entry) {
7999
+ if (typeof entry.identifierTrigger !== "string" || !isValidIdentifier(entry.identifierTrigger)) {
8000
+ onError({
8001
+ severity: "warning",
8002
+ message: [
8003
+ "invalid-dictionary-entry",
8004
+ subject,
8005
+ `The 'identifierTrigger' property must be a valid identifier`
8006
+ ]
8007
+ });
8008
+ }
8009
+ }
8010
+ if ("name" in entry) {
8011
+ if (typeof entry.name !== "string") {
8012
+ if (entry.name !== void 0)
8013
+ onError({
8014
+ severity: "warning",
8015
+ message: [
8016
+ "invalid-dictionary-entry",
8017
+ subject,
8018
+ `The 'name' property must be a string`
8019
+ ]
8020
+ });
8021
+ } else if (!isValidIdentifier(entry.name)) {
8022
+ onError({
8023
+ severity: "warning",
8024
+ message: [
8025
+ "invalid-dictionary-entry",
8026
+ entry.name,
8027
+ `The 'name' property must be a valid identifier`
8028
+ ]
8029
+ });
8030
+ }
8031
+ }
7704
8032
  if (isMatchfixEntry(entry)) {
7705
- if (entry.trigger) {
8033
+ if ("latexTrigger" in entry || "identifierTrigger" in isPrefixEntry) {
7706
8034
  onError({
7707
8035
  severity: "warning",
7708
8036
  message: [
7709
8037
  "invalid-dictionary-entry",
7710
8038
  subject,
7711
- `Unexpected 'trigger' "${entry.trigger}". 'matchfix' operators use a 'openDelimiter' and 'closeDelimiter' instead of a trigger. `
8039
+ `'matchfix' operators use a 'openDelimiter' and 'closeDelimiter' instead of a 'latexTrigger' or 'identifierTrigger'. `
7712
8040
  ]
7713
8041
  });
7714
8042
  return false;
7715
8043
  }
7716
- if (!entry.openDelimiter || !entry.closeDelimiter) {
8044
+ if (!entry.openTrigger || !entry.closeTrigger) {
7717
8045
  onError({
7718
8046
  severity: "warning",
7719
8047
  message: [
@@ -7724,7 +8052,7 @@ function entryIsValid(entry, onError) {
7724
8052
  });
7725
8053
  return false;
7726
8054
  }
7727
- if (typeof entry.openDelimiter !== typeof entry.closeDelimiter) {
8055
+ if (typeof entry.openTrigger !== typeof entry.closeTrigger) {
7728
8056
  onError({
7729
8057
  severity: "warning",
7730
8058
  message: [
@@ -7737,7 +8065,7 @@ function entryIsValid(entry, onError) {
7737
8065
  }
7738
8066
  }
7739
8067
  if (isInfixEntry(entry) || isPostfixEntry(entry) || isPrefixEntry(entry)) {
7740
- if (Array.isArray(entry.trigger) && (entry.trigger[0] === "_" || entry.trigger[0] === "^") || typeof entry.trigger === "string" && (entry.trigger.startsWith("^") || entry.trigger.startsWith("_"))) {
8068
+ if (Array.isArray(entry.latexTrigger) && (entry.latexTrigger[0] === "_" || entry.latexTrigger[0] === "^") || typeof entry.latexTrigger === "string" && (entry.latexTrigger.startsWith("^") || entry.latexTrigger.startsWith("_"))) {
7741
8069
  if (entry.precedence !== void 0 || entry["associativity"] !== void 0) {
7742
8070
  onError({
7743
8071
  severity: "warning",
@@ -7773,14 +8101,14 @@ function entryIsValid(entry, onError) {
7773
8101
  return false;
7774
8102
  }
7775
8103
  }
7776
- if (!isMatchfixEntry(entry)) {
7777
- if (!entry.trigger && !entry.name) {
8104
+ if (!isMatchfixEntry(entry) && !isEnvironmentEntry(entry)) {
8105
+ if (!entry.latexTrigger && !entry.identifierTrigger && !entry.name) {
7778
8106
  onError({
7779
8107
  severity: "warning",
7780
8108
  message: [
7781
8109
  "invalid-dictionary-entry",
7782
8110
  subject,
7783
- `Expected at least a 'trigger' or a 'name'`
8111
+ `Expected a 'name', a 'latexTrigger' or a 'identifierTrigger'`
7784
8112
  ]
7785
8113
  });
7786
8114
  return false;
@@ -7811,7 +8139,7 @@ var DEFAULT_LATEX_DICTIONARY = {
7811
8139
  {
7812
8140
  name: "mu0",
7813
8141
  kind: "symbol",
7814
- trigger: "\\mu_0"
8142
+ latexTrigger: "\\mu_0"
7815
8143
  }
7816
8144
  ],
7817
8145
  sets: DEFINITIONS_SETS,
@@ -7821,7 +8149,24 @@ var DEFAULT_LATEX_DICTIONARY = {
7821
8149
 
7822
8150
  // src/compute-engine/latex-syntax/parse-identifier.ts
7823
8151
  var IDENTIFIER_PREFIX = {
7824
- "\\operatorname": "_operator",
8152
+ // Those are "grouping" prefix that also specify spacing
8153
+ // around the symbol. We ignore the spacing, though.
8154
+ "\\mathord": "",
8155
+ "\\mathop": "",
8156
+ "\\mathbin": "",
8157
+ "\\mathrel": "",
8158
+ "\\mathopen": "",
8159
+ "\\mathclose": "",
8160
+ "\\mathpunct": "",
8161
+ "\\mathinner": "",
8162
+ // This is the preferred way to specify an identifier
8163
+ // it defines both spacing and font. By default, identifiers
8164
+ // are wrapper with `\\operatorname{}`.
8165
+ "\\operatorname": "",
8166
+ // These styling commands are used to change the font of an identifier
8167
+ // They may be problematic, as adjacent identifiers may be merged
8168
+ // into a single identifier when used in editors, such a MathLive.
8169
+ // For example `\mathrm{speed}\mathrm{sound}` can be confused with `\mathrm{speedsound}`
7825
8170
  "\\mathrm": "_upright",
7826
8171
  "\\mathit": "_italic",
7827
8172
  "\\mathbf": "_bold",
@@ -7848,7 +8193,7 @@ var IDENTIFIER_MODIFIER = {
7848
8193
  "\\breve": "_breve",
7849
8194
  "\\check": "_check"
7850
8195
  };
7851
- function matchIdentifierToken(parser, options) {
8196
+ function parseIdentifierToken(parser, options) {
7852
8197
  if (parser.atEnd)
7853
8198
  return null;
7854
8199
  const token = parser.peek;
@@ -7886,7 +8231,7 @@ function matchIdentifierToken(parser, options) {
7886
8231
  }
7887
8232
  return parser.matchChar() ?? parser.nextToken();
7888
8233
  }
7889
- function matchIdentifierBody(parser) {
8234
+ function parseIdentifierBody(parser) {
7890
8235
  let id = matchPrefixedIdentifier(parser);
7891
8236
  const start = parser.index;
7892
8237
  const prefix = IDENTIFIER_MODIFIER[parser.peek] ?? null;
@@ -7896,7 +8241,7 @@ function matchIdentifierBody(parser) {
7896
8241
  parser.index = start;
7897
8242
  return null;
7898
8243
  }
7899
- const body = matchIdentifierBody(parser);
8244
+ const body = parseIdentifierBody(parser);
7900
8245
  if (body === null || !parser.match("<}>")) {
7901
8246
  parser.index = start;
7902
8247
  return null;
@@ -7909,7 +8254,7 @@ function matchIdentifierBody(parser) {
7909
8254
  const token = parser.peek;
7910
8255
  if (token === "<}>" || token === "_" || token === "^")
7911
8256
  break;
7912
- const next = matchIdentifierToken(parser, { toplevel: false });
8257
+ const next = parseIdentifierToken(parser, { toplevel: false });
7913
8258
  if (next === null) {
7914
8259
  parser.index = start;
7915
8260
  return null;
@@ -7938,7 +8283,7 @@ function matchIdentifierBody(parser) {
7938
8283
  while (!parser.atEnd) {
7939
8284
  if (parser.match("_")) {
7940
8285
  const hasBrace = parser.match("<{>");
7941
- const sub2 = matchIdentifierBody(parser);
8286
+ const sub2 = parseIdentifierBody(parser);
7942
8287
  if (hasBrace && !parser.match("<}>") || sub2 === null) {
7943
8288
  parser.index = start;
7944
8289
  return null;
@@ -7946,7 +8291,7 @@ function matchIdentifierBody(parser) {
7946
8291
  subs2.push(sub2);
7947
8292
  } else if (parser.match("^")) {
7948
8293
  const hasBrace = parser.match("<{>");
7949
- const sup = matchIdentifierBody(parser);
8294
+ const sup = parseIdentifierBody(parser);
7950
8295
  if (hasBrace && !parser.match("<}>") || sup === null) {
7951
8296
  parser.index = start;
7952
8297
  return null;
@@ -7985,7 +8330,7 @@ function matchPrefixedIdentifier(parser) {
7985
8330
  body = digit;
7986
8331
  parser.nextToken();
7987
8332
  }
7988
- body += matchIdentifierBody(parser);
8333
+ body += parseIdentifierBody(parser);
7989
8334
  if (body === null || !parser.match("<}>")) {
7990
8335
  parser.index = start;
7991
8336
  return null;
@@ -8009,7 +8354,7 @@ function parseInvalidIdentifier(parser) {
8009
8354
  start
8010
8355
  );
8011
8356
  }
8012
- function matchIdentifier(parser) {
8357
+ function parseIdentifier(parser) {
8013
8358
  if (/^[a-zA-Z]$/.test(parser.peek) || /^\p{XIDS}$/u.test(parser.peek))
8014
8359
  return parser.nextToken();
8015
8360
  const start = parser.index;
@@ -8018,19 +8363,14 @@ function matchIdentifier(parser) {
8018
8363
  id = "";
8019
8364
  while (!parser.atEnd && ONLY_EMOJIS.test(id + parser.peek))
8020
8365
  id += parser.nextToken();
8366
+ if (!id)
8367
+ id = null;
8021
8368
  }
8369
+ id ?? (id = parseIdentifierToken(parser, { toplevel: true }));
8022
8370
  if (id) {
8023
8371
  id = id.normalize();
8024
8372
  if (isValidIdentifier(id))
8025
8373
  return id;
8026
- parser.index = start;
8027
- return null;
8028
- }
8029
- let next = matchIdentifierToken(parser, { toplevel: true });
8030
- if (next) {
8031
- next = next.normalize();
8032
- if (isValidIdentifier(next))
8033
- return next;
8034
8374
  }
8035
8375
  parser.index = start;
8036
8376
  return null;
@@ -8099,7 +8439,7 @@ var DEFAULT_LATEX_NUMBER_OPTIONS = {
8099
8439
  // with machine numbers, up to 15 assuming 2^53 bits floating points
8100
8440
  positiveInfinity: "\\infty",
8101
8441
  negativeInfinity: "-\\infty",
8102
- notANumber: "\\mathrm{NaN}",
8442
+ notANumber: "\\operatorname{NaN}",
8103
8443
  decimalMarker: ".",
8104
8444
  // Use `{,}` for comma as a decimal marker
8105
8445
  groupSeparator: "\\,",
@@ -8239,13 +8579,12 @@ var _Parser = class {
8239
8579
  * Note: the `minPrec` condition is not checked. It should be checked separately.
8240
8580
  */
8241
8581
  atTerminator(t) {
8242
- if (this.atBoundary)
8243
- return true;
8244
- if (t?.condition && t.condition(this))
8245
- return true;
8246
- return false;
8582
+ return this.atBoundary || ((t?.condition && t.condition(this)) ?? false);
8247
8583
  }
8248
- /** True if the current token matches any of the boundaries we are waiting for */
8584
+ /**
8585
+ * True if the current token matches any of the boundaries we are
8586
+ * waiting for.
8587
+ */
8249
8588
  get atBoundary() {
8250
8589
  if (this.atEnd)
8251
8590
  return true;
@@ -8307,42 +8646,32 @@ var _Parser = class {
8307
8646
  this._dictionary.lookahead,
8308
8647
  this._tokens.length - this.index
8309
8648
  );
8310
- if (n < 0)
8649
+ if (n <= 0)
8311
8650
  return [];
8312
- const result = Array(n + 1);
8651
+ const result = [];
8313
8652
  while (n > 0)
8314
- result[n] = this.latexAhead(n--);
8653
+ result.push([n, this.latexAhead(n--)]);
8315
8654
  return result;
8316
8655
  }
8317
8656
  peekDefinitions(kind) {
8318
- let defs;
8319
- if (kind === "function") {
8320
- const start = this.index;
8321
- if (this.match("\\operatorname") || this.match("\\mathrm") || this.match("\\mathit")) {
8322
- const fn = this.parseStringGroup()?.trim();
8323
- const n = this.index - start;
8324
- this.index = start;
8325
- if (!fn || !this._dictionary.function.has(fn))
8326
- return null;
8327
- return this._dictionary.function.get(fn).map((x) => [x, n]);
8328
- }
8329
- return null;
8330
- } else if (kind === "operator") {
8331
- defs = this.lookAhead().map(
8332
- (x, n) => this._dictionary.infix[n]?.get(x) ?? this._dictionary.postfix[n]?.get(x) ?? this._dictionary.prefix[n]?.get(x)
8333
- );
8334
- } else {
8335
- defs = this.lookAhead().map((x, n) => this._dictionary[kind][n]?.get(x));
8336
- }
8337
8657
  const result = [];
8338
- for (let i = defs.length; i > 0; i--) {
8339
- if (defs[i] !== void 0) {
8340
- console.assert(Array.isArray(defs[i]));
8341
- for (const def of defs[i])
8342
- result.push([def, i]);
8658
+ const defs = [...this.getDefs(kind)];
8659
+ for (const def of defs)
8660
+ if (def.latexTrigger === "")
8661
+ result.push([def, 0]);
8662
+ for (const [n, tokens] of this.lookAhead()) {
8663
+ for (const def of defs)
8664
+ if (def.latexTrigger === tokens)
8665
+ result.push([def, n]);
8666
+ }
8667
+ for (const def of defs) {
8668
+ if (def.identifierTrigger) {
8669
+ const n = peekComplexId(this, def.identifierTrigger);
8670
+ if (n > 0)
8671
+ result.push([def, n]);
8343
8672
  }
8344
8673
  }
8345
- return result.length === 0 ? null : result;
8674
+ return result;
8346
8675
  }
8347
8676
  /** Skip strictly `<space>` tokens.
8348
8677
  * To also skip `{}` see `skipSpace()`.
@@ -8456,9 +8785,8 @@ var _Parser = class {
8456
8785
  digits += digit;
8457
8786
  n += 1;
8458
8787
  }
8459
- if (digits.length === caretCount) {
8788
+ if (digits.length === caretCount)
8460
8789
  return String.fromCodePoint(Number.parseInt(digits, 16));
8461
- }
8462
8790
  } else if (this.match("\\char")) {
8463
8791
  let codepoint = Math.floor(this.matchLatexNumber() ?? Number.NaN);
8464
8792
  if (!Number.isFinite(codepoint) || codepoint < 0 || codepoint > 1114111) {
@@ -8467,17 +8795,15 @@ var _Parser = class {
8467
8795
  return String.fromCodePoint(codepoint);
8468
8796
  } else if (this.match("\\unicode")) {
8469
8797
  this.skipSpaceTokens();
8470
- if (this.peek === "<{>") {
8471
- this.nextToken();
8798
+ if (this.match("<{>")) {
8472
8799
  const codepoint = this.matchLatexNumber();
8473
8800
  if (this.match("<}>") && codepoint !== null && codepoint >= 0 && codepoint <= 1114111) {
8474
8801
  return String.fromCodePoint(codepoint);
8475
8802
  }
8476
8803
  } else {
8477
8804
  const codepoint = this.matchLatexNumber();
8478
- if (codepoint !== null && codepoint >= 0 && codepoint <= 1114111) {
8805
+ if (codepoint !== null && codepoint >= 0 && codepoint <= 1114111)
8479
8806
  return String.fromCodePoint(codepoint);
8480
- }
8481
8807
  }
8482
8808
  }
8483
8809
  this.index = index;
@@ -8504,7 +8830,7 @@ var _Parser = class {
8504
8830
  // Some LaTeX commands (but not all) can accept an argument without braces,
8505
8831
  // for example `^` , `\sqrt` or `\frac`.
8506
8832
  // This argument will usually be a single token, but can be a sequence of
8507
- // tokens (e.g. `\sqrt\frac12` or `\sqrt\mathrm{speed}`).
8833
+ // tokens (e.g. `\sqrt\frac12` or `\sqrt\operatorname{speed}`).
8508
8834
  parseToken() {
8509
8835
  const excluding = [
8510
8836
  ...'!"#$%&(),/;:?@[]\\`|~'.split(""),
@@ -8563,6 +8889,7 @@ var _Parser = class {
8563
8889
  let peek = this.peek;
8564
8890
  while (peek !== "&" && peek !== "\\\\" && peek !== "\\cr" && !this.atBoundary) {
8565
8891
  expr = this.parseExpression({
8892
+ minPrec: 0,
8566
8893
  condition: (p) => {
8567
8894
  const peek2 = p.peek;
8568
8895
  return peek2 === "&" || peek2 === "\\\\" || peek2 === "\\cr";
@@ -8606,7 +8933,7 @@ var _Parser = class {
8606
8933
  }
8607
8934
  /** Parse an environment: `\begin{env}...\end{end}`
8608
8935
  */
8609
- parseEnvironment() {
8936
+ parseEnvironment(until) {
8610
8937
  const index = this.index;
8611
8938
  if (!this.match("\\begin"))
8612
8939
  return null;
@@ -8614,22 +8941,22 @@ var _Parser = class {
8614
8941
  if (!name)
8615
8942
  return this.error("expected-environment-name", index);
8616
8943
  this.addBoundary(["\\end", "<{>", ...name.split(""), "<}>"]);
8617
- const def = this._dictionary.environment.get(name);
8618
- if (!def) {
8619
- this.parseTabular();
8620
- this.skipSpace();
8621
- if (!this.matchBoundary())
8622
- return this.boundaryError("unbalanced-environment");
8623
- return this.error(["unknown-environment", { str: name }], index);
8624
- }
8625
- const expr = def.parse(this, [], []);
8944
+ for (const def of this.getDefs("environment"))
8945
+ if (def.identifierTrigger === name) {
8946
+ const expr = def.parse(this, until);
8947
+ this.skipSpace();
8948
+ if (!this.matchBoundary())
8949
+ return this.boundaryError("unbalanced-environment");
8950
+ if (expr !== null)
8951
+ return this.decorate(expr, index);
8952
+ this.index = index;
8953
+ return null;
8954
+ }
8955
+ this.parseTabular();
8626
8956
  this.skipSpace();
8627
8957
  if (!this.matchBoundary())
8628
8958
  return this.boundaryError("unbalanced-environment");
8629
- if (expr !== null)
8630
- return this.decorate(expr, index);
8631
- this.index = index;
8632
- return null;
8959
+ return this.error(["unknown-environment", { str: name }], index);
8633
8960
  }
8634
8961
  /** If the next token matches a `+` or `-` sign, return it and advance the index.
8635
8962
  * Otherwise return `''` and do not advance */
@@ -8873,11 +9200,8 @@ var _Parser = class {
8873
9200
  until = { minPrec: 0 };
8874
9201
  if (!until.minPrec)
8875
9202
  until = { ...until, minPrec: 0 };
8876
- const defs = this.peekDefinitions("prefix");
8877
- if (defs === null)
8878
- return null;
8879
9203
  const start = this.index;
8880
- for (const [def, n] of defs) {
9204
+ for (const [def, n] of this.peekDefinitions("prefix")) {
8881
9205
  this.index = start + n;
8882
9206
  const rhs = def.parse(this, until);
8883
9207
  if (rhs)
@@ -8888,13 +9212,11 @@ var _Parser = class {
8888
9212
  }
8889
9213
  parseInfixOperator(lhs, until) {
8890
9214
  until ?? (until = { minPrec: 0 });
9215
+ console.assert(until.minPrec !== void 0);
8891
9216
  if (until.minPrec === void 0)
8892
9217
  until = { ...until, minPrec: 0 };
8893
- const defs = this.peekDefinitions("infix");
8894
- if (defs === null)
8895
- return null;
8896
9218
  const start = this.index;
8897
- for (const [def, n] of defs) {
9219
+ for (const [def, n] of this.peekDefinitions("infix")) {
8898
9220
  if (def.precedence >= until.minPrec) {
8899
9221
  this.index = start + n;
8900
9222
  const rhs = def.parse(this, lhs, until);
@@ -8936,44 +9258,6 @@ var _Parser = class {
8936
9258
  this.index = savedIndex;
8937
9259
  return null;
8938
9260
  }
8939
- /** A prime suffix is a sequence of `'`, `\prime` or `\doubleprime`
8940
- * after a function or in a superscript.
8941
- */
8942
- // matchPrimeSuffix(): number {
8943
- // this.skipSpace();
8944
- // const start = this.index;
8945
- // let count = 0;
8946
- // if (this.match('^')) {
8947
- // if (this.match('<{>')) {
8948
- // if (this.match('(')) {
8949
- // const n = this.parseNumber();
8950
- // if (n && this.match(')')) return parseInt(n);
8951
- // this.index = start;
8952
- // return 0;
8953
- // }
8954
- // do {
8955
- // const c = countPrimeLevel(this);
8956
- // if (c === 0) break;
8957
- // count += c;
8958
- // } while (true);
8959
- // if (count !== 0 && this.match('<}>')) return count;
8960
- // this.index = start;
8961
- // return 0;
8962
- // }
8963
- // count = countPrimeLevel(this);
8964
- // if (count !== 0) return count;
8965
- // this.index = start;
8966
- // return 0;
8967
- // }
8968
- // do {
8969
- // const c = countPrimeLevel(this);
8970
- // if (c === 0) break;
8971
- // count += c;
8972
- // } while (true);
8973
- // if (count !== 0) return count;
8974
- // this.index = start;
8975
- // return 0;
8976
- // }
8977
9261
  /** If matches the normalized open delimiter, return the
8978
9262
  * expected closing delimiter.
8979
9263
  *
@@ -9029,9 +9313,7 @@ var _Parser = class {
9029
9313
  * @internal
9030
9314
  */
9031
9315
  matchEnclosureOpen() {
9032
- const defs = this._dictionary.matchfix;
9033
- if (defs.length === 0)
9034
- return null;
9316
+ const defs = this.getDefs("matchfix");
9035
9317
  const start = this.index;
9036
9318
  for (const def of defs) {
9037
9319
  this.index = start;
@@ -9054,9 +9336,7 @@ var _Parser = class {
9054
9336
  * Used for error handling
9055
9337
  * @internal */
9056
9338
  matchEnclosureClose() {
9057
- const defs = this._dictionary.matchfix;
9058
- if (defs.length === 0)
9059
- return null;
9339
+ const defs = this.getDefs("matchfix");
9060
9340
  const start = this.index;
9061
9341
  for (const def of defs) {
9062
9342
  this.index = start;
@@ -9095,9 +9375,7 @@ var _Parser = class {
9095
9375
  * and finally a closing matching operator.
9096
9376
  */
9097
9377
  parseEnclosure() {
9098
- const defs = this._dictionary.matchfix;
9099
- if (defs.length === 0)
9100
- return null;
9378
+ const defs = this.getDefs("matchfix");
9101
9379
  const start = this.index;
9102
9380
  for (const def of defs) {
9103
9381
  this.index = start;
@@ -9184,8 +9462,7 @@ var _Parser = class {
9184
9462
  return null;
9185
9463
  const start = this.index;
9186
9464
  let fn = null;
9187
- const fnDefs = this.peekDefinitions("function") ?? [];
9188
- for (const [def, tokenCount] of fnDefs) {
9465
+ for (const [def, tokenCount] of this.peekDefinitions("function")) {
9189
9466
  this.index = start + tokenCount;
9190
9467
  if (typeof def.parse === "function") {
9191
9468
  fn = def.parse(this, until);
@@ -9198,7 +9475,7 @@ var _Parser = class {
9198
9475
  }
9199
9476
  if (fn === null) {
9200
9477
  this.index = start;
9201
- fn = matchIdentifier(this);
9478
+ fn = parseIdentifier(this);
9202
9479
  if (!this.isFunctionHead(fn)) {
9203
9480
  this.index = start;
9204
9481
  return null;
@@ -9217,20 +9494,17 @@ var _Parser = class {
9217
9494
  if (this.atTerminator(until))
9218
9495
  return null;
9219
9496
  const start = this.index;
9220
- const defs = this.peekDefinitions("symbol");
9221
- if (defs) {
9222
- for (const [def, tokenCount] of defs) {
9223
- this.index = start + tokenCount;
9224
- if (typeof def.parse === "function") {
9225
- const result = def.parse(this, until);
9226
- if (result)
9227
- return result;
9228
- } else
9229
- return def.name;
9230
- }
9497
+ for (const [def, tokenCount] of this.peekDefinitions("symbol")) {
9498
+ this.index = start + tokenCount;
9499
+ if (typeof def.parse === "function") {
9500
+ const result = def.parse(this, until);
9501
+ if (result)
9502
+ return result;
9503
+ } else
9504
+ return def.name;
9231
9505
  }
9232
9506
  this.index = start;
9233
- const id = matchIdentifier(this);
9507
+ const id = parseIdentifier(this);
9234
9508
  if (id === null)
9235
9509
  return null;
9236
9510
  if (this.options.parseUnknownIdentifier?.(id, this) === "symbol")
@@ -9287,7 +9561,9 @@ var _Parser = class {
9287
9561
  }
9288
9562
  let result = lhs;
9289
9563
  if (subscripts.length > 0) {
9290
- const defs = this._dictionary.infix[1]?.get("_");
9564
+ const defs = [...this.getDefs("infix")].filter(
9565
+ (x) => x.latexTrigger === "_"
9566
+ );
9291
9567
  if (defs) {
9292
9568
  const arg = [
9293
9569
  "Subscript",
@@ -9305,7 +9581,9 @@ var _Parser = class {
9305
9581
  }
9306
9582
  }
9307
9583
  if (superscripts.length > 0) {
9308
- const defs = this._dictionary.infix[1]?.get("^");
9584
+ const defs = [...this.getDefs("infix")].filter(
9585
+ (x) => x.latexTrigger === "^"
9586
+ );
9309
9587
  if (defs) {
9310
9588
  const arg = [
9311
9589
  "Superscript",
@@ -9330,11 +9608,8 @@ var _Parser = class {
9330
9608
  console.assert(lhs !== null);
9331
9609
  if (lhs === null)
9332
9610
  return null;
9333
- const defs = this.peekDefinitions("postfix");
9334
- if (defs === null)
9335
- return null;
9336
9611
  const start = this.index;
9337
- for (const [def, n] of defs) {
9612
+ for (const [def, n] of this.peekDefinitions("postfix")) {
9338
9613
  this.index = start + n;
9339
9614
  const result = def.parse(this, lhs, until);
9340
9615
  if (result !== null)
@@ -9398,14 +9673,14 @@ var _Parser = class {
9398
9673
  applyInvisibleOperator(until, lhs) {
9399
9674
  if (lhs === null || this.options.applyInvisibleOperator === null || head(lhs) === "Error" || symbol(lhs) === "Nothing" || isEmptySequence(lhs) || this.atTerminator(until))
9400
9675
  return null;
9676
+ if (this.peekDefinitions("operator").length > 0)
9677
+ return null;
9401
9678
  if (this.isFunctionHead(lhs)) {
9402
- const args = this.parseArguments("enclosure", until);
9679
+ const args = this.parseArguments("enclosure", { ...until, minPrec: 0 });
9403
9680
  if (args === null)
9404
9681
  return null;
9405
9682
  return [lhs, ...args];
9406
9683
  }
9407
- if (this.peekDefinitions("operator") !== null)
9408
- return null;
9409
9684
  const start = this.index;
9410
9685
  const rhs = this.parseExpression({ ...until, minPrec: 390 });
9411
9686
  if (rhs === null || symbol(rhs) === "Nothing" || isEmptySequence(rhs)) {
@@ -9452,9 +9727,9 @@ var _Parser = class {
9452
9727
  parseUnexpectedLatexCommand() {
9453
9728
  const start = this.index;
9454
9729
  let opDefs = this.peekDefinitions("operator");
9455
- if (opDefs) {
9730
+ if (opDefs.length > 0) {
9456
9731
  opDefs = this.peekDefinitions("postfix");
9457
- if (opDefs) {
9732
+ if (opDefs.length > 0) {
9458
9733
  const [def, n] = opDefs[0];
9459
9734
  this.index += n;
9460
9735
  if (typeof def.parse === "function") {
@@ -9467,7 +9742,7 @@ var _Parser = class {
9467
9742
  return this.error("unexpected-operator", start);
9468
9743
  }
9469
9744
  opDefs = this.peekDefinitions("prefix");
9470
- if (opDefs) {
9745
+ if (opDefs.length > 0) {
9471
9746
  const [def, n] = opDefs[0];
9472
9747
  this.index += n;
9473
9748
  if (typeof def.parse === "function") {
@@ -9478,12 +9753,13 @@ var _Parser = class {
9478
9753
  if (def.name)
9479
9754
  return [
9480
9755
  def.name,
9756
+ // @todo: pass a precedence?
9481
9757
  this.parseExpression() ?? this.error("missing", start)
9482
9758
  ];
9483
9759
  return this.error("unexpected-operator", start);
9484
9760
  }
9485
9761
  opDefs = this.peekDefinitions("infix");
9486
- if (opDefs) {
9762
+ if (opDefs.length > 0) {
9487
9763
  const [def, n] = opDefs[0];
9488
9764
  this.index += n;
9489
9765
  if (typeof def.parse === "function") {
@@ -9577,7 +9853,10 @@ var _Parser = class {
9577
9853
  if (this.match("<}>"))
9578
9854
  return this.error("unexpected-closing-delimiter", start);
9579
9855
  if (this.match("<{>")) {
9580
- result = this.parseExpression({ condition: (p) => p.peek === "<}>" });
9856
+ result = this.parseExpression({
9857
+ minPrec: 0,
9858
+ condition: (p) => p.peek === "<}>"
9859
+ });
9581
9860
  if (result === null)
9582
9861
  return this.error("expected-expression", start);
9583
9862
  if (!this.match("<}>")) {
@@ -9593,7 +9872,7 @@ var _Parser = class {
9593
9872
  result = { num };
9594
9873
  }
9595
9874
  result ?? (result = this.parseEnclosure());
9596
- result ?? (result = this.parseEnvironment());
9875
+ result ?? (result = this.parseEnvironment(until));
9597
9876
  if (result === null && this.matchAll(this._positiveInfinityTokens))
9598
9877
  result = { num: "+Infinity" };
9599
9878
  if (result === null && this.matchAll(this._negativeInfinityTokens))
@@ -9638,8 +9917,9 @@ var _Parser = class {
9638
9917
  return null;
9639
9918
  }
9640
9919
  until ?? (until = { minPrec: 0 });
9920
+ console.assert(until.minPrec !== void 0);
9641
9921
  if (until.minPrec === void 0)
9642
- until.minPrec = 0;
9922
+ until = { ...until, minPrec: 0 };
9643
9923
  let lhs = this.parsePrefixOperator({ ...until, minPrec: 0 });
9644
9924
  if (lhs === null) {
9645
9925
  lhs = this.parsePrimary(until);
@@ -9708,7 +9988,28 @@ var _Parser = class {
9708
9988
  return true;
9709
9989
  return false;
9710
9990
  }
9991
+ /** Return all defs of the specified kind */
9992
+ *getDefs(kind) {
9993
+ if (kind === "operator") {
9994
+ for (const def of this._dictionary.defs)
9995
+ if (/^prefix|infix|postfix/.test(def.kind))
9996
+ yield def;
9997
+ } else {
9998
+ for (const def of this._dictionary.defs)
9999
+ if (def.kind === kind)
10000
+ yield def;
10001
+ }
10002
+ }
9711
10003
  };
10004
+ function peekComplexId(parser, id) {
10005
+ const start = parser.index;
10006
+ const candidate = parseIdentifier(parser)?.trim();
10007
+ if (candidate === null)
10008
+ return 0;
10009
+ const result = candidate !== id ? 0 : parser.index - start;
10010
+ parser.index = start;
10011
+ return result;
10012
+ }
9712
10013
 
9713
10014
  // src/compute-engine/latex-syntax/serialize-number.ts
9714
10015
  function formatFractionalPart(m, options) {
@@ -9948,68 +10249,11 @@ var STYLE_MODIFIERS = {
9948
10249
  // Unicode uses 'double-struck' for 'blackboard'
9949
10250
  // Supplemental
9950
10251
  blackboard: (s) => `\\mathbb{${s}}`,
9951
- // boldItalic: (s) => `\\mathbf{\\mathit{${s}}}`,
9952
10252
  calligraphic: (s) => `\\mathcal{${s}}`,
9953
- // scriptBold: (s) => `\\mathbf{\\mathscr{${s}}}`,
9954
- // calligraphicBold: (s) => `\\mathbf{\\mathcal{${s}}}`,
9955
10253
  gothic: (s) => `\\mathfrak{${s}}`,
9956
- // gothicBold: (s) => `\\mathbf{\\mathfrak{${s}}}`,
9957
- // frakturBold: (s) => `\\mathbf{\\mathfrak{${s}}}`,
9958
- sansSerif: (s) => `\\mathsf{${s}}`,
9959
- // sansSerifBold: (s) => `\\mathbf{\\mathsf{${s}}}`,
9960
- // sansSerifItalic: (s) => `\\mathit{\\mathsf{${s}}}`,
10254
+ sansserif: (s) => `\\mathsf{${s}}`,
9961
10255
  monospace: (s) => `\\mathtt{${s}}`
9962
10256
  };
9963
- function serializeOperator(serializer, expr, def) {
9964
- let result = "";
9965
- const count = nops(expr);
9966
- const name = headName(expr);
9967
- if (def.kind === "postfix") {
9968
- if (count !== 1) {
9969
- serializer.onError([
9970
- {
9971
- severity: "warning",
9972
- message: [
9973
- "postfix-operator-requires-one-operand",
9974
- serializer.serializeSymbol(name)
9975
- ]
9976
- }
9977
- ]);
9978
- }
9979
- return replaceLatex(def.serialize, [
9980
- serializer.wrap(op(expr, 1), def.precedence)
9981
- ]);
9982
- }
9983
- if (def.kind === "prefix") {
9984
- if (count !== 1) {
9985
- serializer.onError([
9986
- {
9987
- severity: "warning",
9988
- message: [
9989
- "prefix-operator-requires-one-operand",
9990
- serializer.serializeSymbol(name)
9991
- ]
9992
- }
9993
- ]);
9994
- }
9995
- return replaceLatex(def.serialize, [
9996
- serializer.wrap(op(expr, 1), def.precedence + 1)
9997
- ]);
9998
- }
9999
- if (def.kind === "infix") {
10000
- result = serializer.wrap(op(expr, 1), def.precedence);
10001
- for (let i = 2; i < count + 1; i++) {
10002
- const arg = op(expr, i);
10003
- if (arg !== null) {
10004
- result = replaceLatex(def.serialize, [
10005
- result,
10006
- serializer.wrap(arg, def.precedence)
10007
- ]);
10008
- }
10009
- }
10010
- }
10011
- return result;
10012
- }
10013
10257
  var Serializer = class {
10014
10258
  constructor(options, dictionary2, onError) {
10015
10259
  this.level = -1;
@@ -10051,7 +10295,7 @@ var Serializer = class {
10051
10295
  }
10052
10296
  const name = head(expr);
10053
10297
  if (typeof name === "string" && name !== "Delimiter" && name !== "Subscript") {
10054
- const def = this.dictionary.name.get(name);
10298
+ const def = this.dictionary.ids.get(name);
10055
10299
  if (def && (def.kind === "symbol" || def.kind === "prefix" || def.kind === "infix" || def.kind === "postfix") && def.precedence < prec)
10056
10300
  return this.wrapString(
10057
10301
  this.serialize(expr),
@@ -10089,14 +10333,16 @@ var Serializer = class {
10089
10333
  wrapString(s, style, fence) {
10090
10334
  if (style === "none")
10091
10335
  return s;
10092
- const openFence = fence?.[0] ?? "(";
10093
- const closeFence = fence?.[1] ?? ")";
10336
+ if (fence === void 0)
10337
+ fence = "()";
10338
+ const openFence = fence?.[0] ?? ".";
10339
+ const closeFence = fence?.[1] ?? ".";
10094
10340
  if ((openFence === "." || closeFence === ".") && style === "paren")
10095
10341
  style = "leftright";
10096
10342
  if (style === "leftright")
10097
- return `${openFence === "." ? "" : `\\left(${openFence}`}${s}${closeFence === "." ? "" : `\\right(${closeFence}`})`;
10343
+ return `\\left${openFence}${s}\\right${closeFence}}`;
10098
10344
  if (style === "big")
10099
- return `${openFence === "." ? "" : `\\Bigl(${openFence}`}${s}${closeFence === "." ? "" : `\\Bigr(${closeFence}`})`;
10345
+ return `${openFence === "." ? "" : `\\Bigl${openFence}`}${s}${closeFence === "." ? "" : `\\Bigr${closeFence}`})`;
10100
10346
  return openFence + s + closeFence;
10101
10347
  }
10102
10348
  wrapArguments(expr) {
@@ -10106,42 +10352,37 @@ var Serializer = class {
10106
10352
  );
10107
10353
  }
10108
10354
  serializeSymbol(expr, def) {
10109
- const h = head(expr);
10110
- if (h)
10111
- return this.serializeFunction(expr, def);
10112
10355
  console.assert(typeof expr === "string" || isSymbolObject(expr));
10113
- if (typeof def?.serialize === "string")
10114
- return def.serialize;
10115
- else if (typeof def?.serialize === "function")
10116
- return def.serialize(this, expr);
10117
- return serializeIdentifier(symbol(expr)) ?? "";
10356
+ if (def?.kind === "function") {
10357
+ return serializeIdentifier(symbol(expr) ?? "") ?? "";
10358
+ }
10359
+ return def?.serialize?.(this, expr) ?? serializeIdentifier(symbol(expr)) ?? "";
10118
10360
  }
10119
10361
  serializeFunction(expr, def) {
10362
+ if (def?.serialize)
10363
+ return def.serialize(this, expr);
10120
10364
  const h = head(expr);
10121
- if (!h)
10122
- return this.serializeSymbol(expr, def);
10365
+ if (typeof h === "string")
10366
+ return serializeIdentifier(h, "auto") + this.wrapArguments(expr);
10123
10367
  const args = ops(expr) ?? [];
10124
- if (def) {
10125
- if (typeof def.serialize === "function")
10126
- return def.serialize(this, expr);
10368
+ if (args.length === 1) {
10127
10369
  return joinLatex([
10128
- def.serialize ?? h,
10129
- this.wrapArguments(expr)
10370
+ this.serialize(args[0]),
10371
+ "\\rhd",
10372
+ this.wrapString(
10373
+ this.serialize(h),
10374
+ this.options.applyFunctionStyle(expr, this.level)
10375
+ )
10130
10376
  ]);
10131
10377
  }
10132
- if (typeof h === "string" && h.length > 0 && h[0] === "\\") {
10133
- return joinLatex([h, ...args.map((x) => `{${this.serialize(x)}}`)]);
10134
- }
10135
- if (typeof h === "string") {
10136
- if (h.length === 1)
10137
- return serializeIdentifier(h) + this.wrapArguments(expr);
10138
- return serializeIdentifier(h, "upright") + this.wrapArguments(expr);
10139
- }
10140
10378
  const style = this.options.applyFunctionStyle(expr, this.level);
10141
- return "\\mathrm{Apply}" + this.wrapString(
10142
- this.serialize(h) + ", " + this.serialize(["List", ...args]),
10143
- style
10144
- );
10379
+ return joinLatex([
10380
+ "\\operatorname{apply}",
10381
+ this.wrapString(
10382
+ this.serialize(h) + ", " + this.serialize(["List", ...args]),
10383
+ style
10384
+ )
10385
+ ]);
10145
10386
  }
10146
10387
  serializeDictionary(dict) {
10147
10388
  return `\\left\\lbrack\\begin{array}{lll}${Object.keys(dict).map((x) => {
@@ -10160,37 +10401,22 @@ var Serializer = class {
10160
10401
  const s = stringValue(expr);
10161
10402
  if (s !== null)
10162
10403
  return `\\text{${s}}`;
10163
- const symbolName = symbol(expr);
10164
- if (symbolName !== null) {
10165
- const def = this.dictionary.name.get(symbolName);
10166
- if (def?.kind === "symbol")
10167
- return this.serializeSymbol(expr, def);
10168
- if (def?.kind === "function")
10169
- return this.serializeFunction(expr, def);
10170
- if (typeof def?.serialize === "function")
10171
- return def.serialize(this, expr);
10172
- }
10173
10404
  const dict = dictionary(expr);
10174
10405
  if (dict !== null)
10175
10406
  return this.serializeDictionary(dict);
10407
+ const symbolName = symbol(expr);
10408
+ if (symbolName !== null) {
10409
+ return this.serializeSymbol(
10410
+ expr,
10411
+ this.dictionary.ids.get(symbolName)
10412
+ );
10413
+ }
10176
10414
  const fnName = headName(expr);
10177
10415
  if (fnName) {
10178
- const def = this.dictionary.name.get(fnName);
10179
- if (def) {
10180
- if (typeof def.serialize === "function")
10181
- return def.serialize(this, expr);
10182
- if (def.kind === "infix" || def.kind === "postfix" || def.kind === "prefix")
10183
- return serializeOperator(this, expr, def);
10184
- if (def.kind === "symbol")
10185
- return this.serializeSymbol(expr, def);
10186
- if (def.kind === "function")
10187
- return this.serializeFunction(expr, def);
10188
- return "";
10189
- }
10190
- }
10191
- if (symbolName !== null || Array.isArray(expr) || isFunctionObject(expr)) {
10192
- return this.serializeSymbol(expr);
10416
+ return this.serializeFunction(expr, this.dictionary.ids.get(fnName));
10193
10417
  }
10418
+ if (head(expr) !== null)
10419
+ return this.serializeFunction(expr);
10194
10420
  this.onError([
10195
10421
  {
10196
10422
  severity: "warning",
@@ -10230,22 +10456,6 @@ var Serializer = class {
10230
10456
  return this.options.numericSetStyle(expr, level);
10231
10457
  }
10232
10458
  };
10233
- function replaceLatex(template, replacement) {
10234
- console.assert(typeof template === "string");
10235
- console.assert(template.length > 0);
10236
- let result = template;
10237
- for (let i = 0; i < replacement.length; i++) {
10238
- let s = replacement[i] ?? "";
10239
- if (/[a-zA-Z*]/.test(s[0])) {
10240
- const m = result.match(new RegExp("(.*)#" + Number(i + 1).toString()));
10241
- if (m && /\\[a-zA-Z*]+/.test(m[1])) {
10242
- s = " " + s;
10243
- }
10244
- }
10245
- result = result.replace("#" + Number(i + 1).toString(), s);
10246
- }
10247
- return result;
10248
- }
10249
10459
  function specialName(s) {
10250
10460
  const prefix = s.match(/^([^_]+)/)?.[1] ?? "";
10251
10461
  let i = SYMBOLS.findIndex((x) => prefix === x[0]);
@@ -10321,7 +10531,7 @@ function parseModifiers(s) {
10321
10531
  }
10322
10532
  return [body, accent, styles, rest];
10323
10533
  }
10324
- function parseIdentifierBody(s, topLevel = true, style = "auto") {
10534
+ function parseIdentifierBody2(s, topLevel = true, style = "auto") {
10325
10535
  let [body, accents, styles, rest] = parseModifiers(s);
10326
10536
  for (const accent of accents) {
10327
10537
  if (ACCENT_MODIFIERS[accent])
@@ -10337,7 +10547,7 @@ function parseIdentifierBody(s, topLevel = true, style = "auto") {
10337
10547
  }
10338
10548
  while (rest.length > 0) {
10339
10549
  if (rest.startsWith("__")) {
10340
- const [sup, rest2] = parseIdentifierBody(
10550
+ const [sup, rest2] = parseIdentifierBody2(
10341
10551
  rest.substring(2),
10342
10552
  false,
10343
10553
  "none"
@@ -10345,7 +10555,7 @@ function parseIdentifierBody(s, topLevel = true, style = "auto") {
10345
10555
  sups.push(sup);
10346
10556
  rest = rest2;
10347
10557
  } else if (rest.startsWith("_")) {
10348
- const [sub2, rest2] = parseIdentifierBody(
10558
+ const [sub2, rest2] = parseIdentifierBody2(
10349
10559
  rest.substring(1),
10350
10560
  false,
10351
10561
  "none"
@@ -10384,19 +10594,19 @@ function parseIdentifierBody(s, topLevel = true, style = "auto") {
10384
10594
  }
10385
10595
  return [body, rest];
10386
10596
  }
10387
- function serializeIdentifier(s, defaultMulticharStyle = "auto") {
10597
+ function serializeIdentifier(s, style = "auto") {
10388
10598
  if (s === null)
10389
10599
  return null;
10390
10600
  if (ONLY_EMOJIS.test(s))
10391
10601
  return s;
10392
10602
  const m = s.match(/^(_+)(.*)/);
10393
10603
  if (m) {
10394
- const [body2, rest2] = parseIdentifierBody(m[2], true, "none");
10395
- return `\\mathrm{${"\\_".repeat(m[1].length) + body2 + rest2}}`;
10604
+ const [body2, rest2] = parseIdentifierBody2(m[2], true, "none");
10605
+ return `\\operatorname{${"\\_".repeat(m[1].length) + body2 + rest2}}`;
10396
10606
  }
10397
- const [body, rest] = parseIdentifierBody(s, true, defaultMulticharStyle);
10607
+ const [body, rest] = parseIdentifierBody2(s, true, style);
10398
10608
  if (rest.length > 0)
10399
- return `\\mathrm{${s}}`;
10609
+ return `\\operatorname{${s}}`;
10400
10610
  return body;
10401
10611
  }
10402
10612
 
@@ -10486,7 +10696,7 @@ var LatexSyntax = class _LatexSyntax {
10486
10696
  let expr = parser.parseExpression();
10487
10697
  if (!parser.atEnd) {
10488
10698
  const opDefs = parser.peekDefinitions("infix");
10489
- if (opDefs) {
10699
+ if (opDefs.length > 0) {
10490
10700
  const start = parser.index;
10491
10701
  const [def, n] = opDefs[0];
10492
10702
  parser.index += n;
@@ -10507,20 +10717,23 @@ var LatexSyntax = class _LatexSyntax {
10507
10717
  parser.index = start;
10508
10718
  }
10509
10719
  const index = parser.index;
10510
- const id = matchIdentifier(parser);
10720
+ const id = parseIdentifier(parser);
10511
10721
  if (id) {
10512
10722
  const idError = parser.error(["unexpected-identifier", id], index);
10513
10723
  return expr ? ["Sequence", expr, idError] : idError;
10514
10724
  }
10725
+ let openDelimiter = parser.peek;
10515
10726
  const closeDelimiter = parser.matchEnclosureOpen();
10516
10727
  if (closeDelimiter) {
10728
+ parser.parseExpression();
10729
+ parser.match(closeDelimiter);
10517
10730
  const enclosureError = parser.error(
10518
- ["expected-close-delimiter", { str: closeDelimiter }],
10731
+ ["unexpected-open-delimiter", { str: openDelimiter }],
10519
10732
  index
10520
10733
  );
10521
10734
  return expr ? ["Sequence", expr, enclosureError] : enclosureError;
10522
10735
  }
10523
- const openDelimiter = parser.matchEnclosureClose();
10736
+ openDelimiter = parser.matchEnclosureClose();
10524
10737
  if (openDelimiter) {
10525
10738
  const enclosureError = parser.error(
10526
10739
  ["expected-open-delimiter", { str: openDelimiter }],
@@ -11668,6 +11881,9 @@ function gcd(a, b) {
11668
11881
  [a, b] = [b, a % b];
11669
11882
  return a < 0 ? -a : a;
11670
11883
  }
11884
+ function lcm(a, b) {
11885
+ return a * b / gcd(a, b);
11886
+ }
11671
11887
  function factorial(n) {
11672
11888
  if (!Number.isInteger(n) || n < 0)
11673
11889
  return NaN;
@@ -13149,6 +13365,362 @@ function domainSetsLibrary() {
13149
13365
 
13150
13366
  // src/compute-engine/boxed-expression/abstract-boxed-expression.ts
13151
13367
  var import_complex6 = __toESM(require_complex());
13368
+
13369
+ // src/compute-engine/library/utils.ts
13370
+ function isSymbolDefinition(def) {
13371
+ return !!def && typeof def === "object" && ("domain" in def || "value" in def || "constant" in def);
13372
+ }
13373
+ function isFunctionDefinition(def) {
13374
+ if (def === void 0 || def === null)
13375
+ return false;
13376
+ if (typeof def !== "object")
13377
+ return false;
13378
+ if ("complexity" in def || "numeric" in def || "signature" in def)
13379
+ return true;
13380
+ if (!("domain" in def))
13381
+ return false;
13382
+ if (def.domain === void 0)
13383
+ return false;
13384
+ if (typeof def.domain === "string")
13385
+ return def.domain === "Function";
13386
+ return def.domain.isFunction;
13387
+ }
13388
+ function normalizeLimits(range) {
13389
+ let lower = 1;
13390
+ let upper = lower + MAX_ITERATION;
13391
+ let index = "Nothing";
13392
+ let isFinite2 = true;
13393
+ if (range.head === "Tuple" || range.head === "Triple" || range.head === "Pair" || range.head === "Single") {
13394
+ index = (range.op1.head === "Hold" ? range.op1.op1.symbol : range.op1.symbol) ?? "Nothing";
13395
+ lower = asSmallInteger(range.op2) ?? 1;
13396
+ if (!Number.isFinite(lower))
13397
+ isFinite2 = false;
13398
+ if (range.op3.isNothing || range.op3.isInfinity) {
13399
+ isFinite2 = false;
13400
+ } else {
13401
+ const u = asSmallInteger(range.op3);
13402
+ if (u === null)
13403
+ isFinite2 = false;
13404
+ else {
13405
+ upper = u;
13406
+ if (!Number.isFinite(upper))
13407
+ isFinite2 = false;
13408
+ }
13409
+ }
13410
+ if (!isFinite2 && Number.isFinite(lower))
13411
+ upper = lower + MAX_ITERATION;
13412
+ }
13413
+ return [index, lower, upper, isFinite2];
13414
+ }
13415
+
13416
+ // src/compute-engine/compile.ts
13417
+ var ComputeEngineFunction = class extends Function {
13418
+ constructor(body) {
13419
+ super("_SYS", "_", `return ${body}`);
13420
+ this.sys = {
13421
+ factorial,
13422
+ gamma,
13423
+ lngamma,
13424
+ gcd,
13425
+ lcm,
13426
+ chop
13427
+ };
13428
+ return new Proxy(this, {
13429
+ apply: (target, thisArg, argumentsList) => super.apply(thisArg, [this.sys, ...argumentsList]),
13430
+ get: (target, prop) => {
13431
+ if (prop === "toString")
13432
+ return () => body;
13433
+ return target[prop];
13434
+ }
13435
+ });
13436
+ }
13437
+ };
13438
+ function compileToJavascript(expr) {
13439
+ const js = compile(expr, expr.freeVars);
13440
+ try {
13441
+ return new ComputeEngineFunction(js);
13442
+ } catch (e) {
13443
+ console.error(`${e}
13444
+ ${expr.latex}
13445
+ ${js}`);
13446
+ }
13447
+ return void 0;
13448
+ }
13449
+ function compile(expr, freeVars = [], prec = 0) {
13450
+ const f = asFloat(expr);
13451
+ if (f !== null)
13452
+ return f.toString();
13453
+ const s = expr.symbol;
13454
+ if (s !== null) {
13455
+ const result = {
13456
+ True: "true",
13457
+ False: "false",
13458
+ Pi: "Math.PI",
13459
+ ExponentialE: "Math.E",
13460
+ I: "Math.I",
13461
+ NaN: "Number.NaN",
13462
+ ImaginaryUnit: "NaN",
13463
+ Half: "0.5",
13464
+ MachineEpsilon: "Number.EPSILON",
13465
+ GoldenRatio: "((1 + Math.sqrt(5)) / 2)",
13466
+ CatalanConstant: "0.91596559417721901",
13467
+ EulerGamma: "0.57721566490153286"
13468
+ }[s];
13469
+ if (result !== void 0)
13470
+ return result;
13471
+ if (freeVars.includes(s))
13472
+ return `_.${s}`;
13473
+ return s;
13474
+ }
13475
+ const str = expr.string;
13476
+ if (str !== null)
13477
+ return JSON.stringify(str);
13478
+ const keys = expr.keys;
13479
+ if (keys !== null) {
13480
+ const result = [];
13481
+ for (const key of keys) {
13482
+ const value = expr.getKey(key);
13483
+ if (value)
13484
+ result.push(`${key}: ${compile(value, freeVars, 0)}`);
13485
+ }
13486
+ return `{${result.join(", ")}}`;
13487
+ }
13488
+ const h = expr.head;
13489
+ if (typeof h === "string") {
13490
+ if (h === "Negate") {
13491
+ const arg = expr.op1;
13492
+ if (arg === null)
13493
+ return "";
13494
+ return `-${compile(arg, freeVars, 3)}`;
13495
+ }
13496
+ if (h === "Error")
13497
+ throw new Error("Error");
13498
+ if (h === "Sum")
13499
+ return compileLoop(expr, "+");
13500
+ if (h === "Product")
13501
+ return compileLoop(expr, "*");
13502
+ if (h === "Root") {
13503
+ const arg = expr.op1;
13504
+ if (arg === null)
13505
+ throw new Error("Root: no argument");
13506
+ const exp2 = expr.op2;
13507
+ if (exp2 === null)
13508
+ return `Math.sqrt(${compile(arg, freeVars, 0)})`;
13509
+ return `Math.pow(${compile(arg, freeVars)}, 1/${compile(exp2, freeVars)}`;
13510
+ }
13511
+ if (h === "Factorial") {
13512
+ const arg = expr.op1;
13513
+ if (arg === null)
13514
+ throw new Error("Factorial: no argument");
13515
+ return `_SYS.factorial(${compile(arg, freeVars)})`;
13516
+ }
13517
+ if (h === "Power") {
13518
+ const arg = expr.op1;
13519
+ if (arg === null)
13520
+ throw new Error("Power: no argument");
13521
+ const exp2 = asFloat(expr.op2);
13522
+ if (exp2 === 0.5)
13523
+ return `Math.sqrt(${compile(arg, freeVars)})`;
13524
+ if (exp2 === 1 / 3)
13525
+ return `Math.cbrt(${compile(arg, freeVars)})`;
13526
+ if (exp2 === 1)
13527
+ return compile(arg, freeVars);
13528
+ if (exp2 === -1)
13529
+ return `1 / ${compile(arg, freeVars)}`;
13530
+ if (exp2 === -0.5)
13531
+ return `1 / Math.sqrt(${compile(arg, freeVars)})`;
13532
+ }
13533
+ if (h === "Square") {
13534
+ const arg = expr.op1;
13535
+ if (arg === null)
13536
+ throw new Error("Square: no argument");
13537
+ return `Math.pow(${compile(arg, freeVars)}, 2)`;
13538
+ }
13539
+ const OPS = {
13540
+ Add: ["+", 11],
13541
+ Negate: ["-", 14],
13542
+ // Unary operator
13543
+ Subtract: ["-", 11],
13544
+ Multiply: ["*", 12],
13545
+ Divide: ["/", 13],
13546
+ Equal: ["===", 8],
13547
+ NotEqual: ["!==", 8],
13548
+ LessEqual: ["<=", 9],
13549
+ GreaterEqual: [">=", 9],
13550
+ Less: ["<", 9],
13551
+ Greater: [">", 9],
13552
+ And: ["&&", 4],
13553
+ Or: ["||", 3],
13554
+ Not: ["!", 14]
13555
+ // Unary operator
13556
+ // Xor: ['^', 6], // That's bitwise XOR, not logical XOR
13557
+ // Possible solution is to use `a ? !b : b` instead of `a ^ b`
13558
+ };
13559
+ const op3 = OPS[h];
13560
+ if (op3 !== void 0) {
13561
+ const args2 = expr.ops;
13562
+ if (args2 === null)
13563
+ return "";
13564
+ let resultStr;
13565
+ if (args2.length === 1) {
13566
+ resultStr = `${op3[0]}${compile(args2[0], freeVars, op3[1])}`;
13567
+ } else {
13568
+ resultStr = args2.map((arg) => compile(arg, freeVars, op3[1])).join(` ${op3[0]} `);
13569
+ }
13570
+ return op3[1] < prec ? `(${resultStr})` : resultStr;
13571
+ }
13572
+ const fn = {
13573
+ Abs: "Math.abs",
13574
+ Arccos: "Math.acos",
13575
+ Arcosh: "Math.acosh",
13576
+ Arsin: "Math.asin",
13577
+ Arsinh: "Math.asinh",
13578
+ Arctan: "Math.atan",
13579
+ Artanh: "Math.atanh",
13580
+ // Math.cbrt
13581
+ Ceiling: "Math.ceil",
13582
+ Chop: "_SYS.chop",
13583
+ Cos: "Math.cos",
13584
+ Cosh: "Math.cosh",
13585
+ Exp: "Math.exp",
13586
+ Floor: "Math.floor",
13587
+ Gamma: "_SYS.gamma",
13588
+ Gcd: "_SYS.gcd",
13589
+ // Math.hypot
13590
+ Lcm: "_SYS.lcm",
13591
+ Ln: "Math.log",
13592
+ Log: "Math.log10",
13593
+ LogGamma: "_SYS.lngamma",
13594
+ Lb: "Math.log2",
13595
+ Max: "Math.max",
13596
+ Min: "Math.min",
13597
+ Power: "Math.pow",
13598
+ Random: "Math.random",
13599
+ Round: "Math.round",
13600
+ Sgn: "Math.sign",
13601
+ Sin: "Math.sin",
13602
+ Sinh: "Math.sinh",
13603
+ Sqrt: "Math.sqrt",
13604
+ Tan: "Math.tan",
13605
+ Tanh: "Math.tanh"
13606
+ // Factorial: 'factorial', // TODO: implement
13607
+ // Hallucinated by Copilot, but interesting ideas...
13608
+ // Cot: 'Math.cot',
13609
+ // Sec: 'Math.sec',
13610
+ // Csc: 'Math.csc',
13611
+ // ArcCot: 'Math.acot',
13612
+ // ArcSec: 'Math.asec',
13613
+ // ArcCsc: 'Math.acsc',
13614
+ // Coth: 'Math.coth',
13615
+ // Sech: 'Math.sech',
13616
+ // Csch: 'Math.csch',
13617
+ // ArcCoth: 'Math.acoth',
13618
+ // ArcSech: 'Math.asech',
13619
+ // ArcCsch: 'Math.acsch',
13620
+ // Root: 'Math.root',
13621
+ // Gamma: 'Math.gamma',
13622
+ // Erf: 'Math.erf',
13623
+ // Erfc: 'Math.erfc',
13624
+ // Erfi: 'Math.erfi',
13625
+ // Zeta: 'Math.zeta',
13626
+ // PolyGamma: 'Math.polygamma',
13627
+ // HurwitzZeta: 'Math.hurwitzZeta', $$\zeta (s,a)=\sum _{n=0}^{\infty }{\frac {1}{(n+a)^{s}}}$$
13628
+ // DirichletEta: 'Math.dirichletEta',
13629
+ // Beta: 'Math.beta',
13630
+ // Binomial: 'Math.binomial',
13631
+ // Mod: 'Math.mod',
13632
+ // Quotient: 'Math.quotient',
13633
+ // GCD: 'Math.gcd',
13634
+ // LCM: 'Math.lcm',
13635
+ // Divisors: 'Math.divisors',
13636
+ // PrimeQ: 'Math.isPrime',
13637
+ // PrimePi: 'Math.primePi',
13638
+ // Prime: 'Math.prime',
13639
+ // NextPrime: 'Math.nextPrime',
13640
+ // PreviousPrime: 'Math.prevPrime',
13641
+ // PrimePowerQ: 'Math.isPrimePower',
13642
+ // PrimePowerPi: 'Math.primePowerPi',
13643
+ // PrimePower: 'Math.primePower',
13644
+ // NextPrimePower: 'Math.nextPrimePower',
13645
+ // PreviousPrimePower: 'Math.prevPrimePower',
13646
+ // PrimeFactors: 'Math.primeFactors',
13647
+ // DivisorSigma: 'Math.divisorSigma',
13648
+ // DivisorSigma0: 'Math.divisorSigma0',
13649
+ // DivisorSigma1: 'Math.divisorSigma1',
13650
+ // DivisorSigma2: 'Math.divisorSigma2',
13651
+ // DivisorSigma3: 'Math.divisorSigma3',
13652
+ // DivisorSigma4: 'Math.divisorSigma4',
13653
+ // DivisorCount: 'Math.divisorCount',
13654
+ // DivisorSum: 'Math.divisorSum',
13655
+ // MoebiusMu: 'Math.moebiusMu',
13656
+ // LiouvilleLambda: 'Math.liouvilleLambda',
13657
+ // CarmichaelLambda: 'Math.carmichaelLambda',
13658
+ // EulerPhi: 'Math.eulerPhi',
13659
+ // EulerPsi: 'Math.eulerPsi',
13660
+ // EulerGamma: 'Math.eulerGamma',
13661
+ // HarmonicNumber: 'Math.harmonicNumber',
13662
+ // BernoulliB: 'Math.bernoulliB',
13663
+ // StirlingS1: 'Math.stirlingS1',
13664
+ // StirlingS2: 'Math.stirlingS2',
13665
+ // BellB: 'Math.bellB',
13666
+ // BellNumber: 'Math.bellNumber',
13667
+ // LahS: 'Math.lahS',
13668
+ // LahL: 'Math.lahL',
13669
+ // RiemannR: 'Math.riemannR',
13670
+ // RiemannZeta: 'Math.riemannZeta',
13671
+ // RiemannXi: 'Math.riemannXi',
13672
+ // RiemannH: 'Math.riemannH',
13673
+ // RiemannZ: 'Math.riemannZ',
13674
+ // RiemannS: 'Math.riemannS',
13675
+ // RiemannXiZero: 'Math.riemannXiZero',
13676
+ // RiemannZetaZero: 'Math.riemannZetaZero',
13677
+ // RiemannHZero: 'Math.riemannHZero',
13678
+ // RiemannSZero: 'Math.riemannSZero',
13679
+ // RiemannPrimeCount: 'Math.riemannPrimeCount',
13680
+ // RiemannRLog: 'Math.riemannRLog',
13681
+ // RiemannRLogDerivative: 'Math.riemannRLogDerivative',
13682
+ // RiemannRLogZero: 'Math.riemannRLogZero',
13683
+ // RiemannRLogZeroDerivative: 'Math.riemannRLogZeroDerivative',
13684
+ // RiemannRZero: 'Math.riemannRZero',
13685
+ // RiemannRDerivative: 'Math.riemannRDerivative',
13686
+ // RiemannXiZeroDerivative: 'Math.riemannXiZeroDerivative',
13687
+ // RiemannZetaZeroDerivative: 'Math.riemannZetaZeroDerivative',
13688
+ // RiemannHZeroDerivative: 'Math.riemannHZeroDerivative',
13689
+ // RiemannSZeroDerivative: 'Math.riemannSZeroDerivative',
13690
+ // RiemannSZeroDerivative2: 'Math.riemannSZeroDerivative2',
13691
+ // RiemannSZeroDerivative3: 'Math.riemannSZeroDerivative3',
13692
+ // RiemannSZeroDerivative4: 'Math.riemannSZeroDerivative4',
13693
+ // RiemannSZeroDerivative5: 'Math.riemannSZeroDerivative5',
13694
+ // RiemannSZeroDerivative6: 'Math.riemannSZeroDerivative6',
13695
+ }[h] ?? h;
13696
+ const args = expr.ops;
13697
+ if (args !== null) {
13698
+ const result = [];
13699
+ for (const arg of args)
13700
+ result.push(compile(arg, freeVars));
13701
+ return `${fn}(${result.join(", ")})`;
13702
+ }
13703
+ }
13704
+ return "";
13705
+ }
13706
+ function compileLoop(expr, op3) {
13707
+ const args = expr.ops;
13708
+ if (args === null)
13709
+ throw new Error("Sum: no arguments");
13710
+ if (!expr.op1 || !expr.op2)
13711
+ throw new Error("Sum: no limits");
13712
+ const [index, lower, upper, isFinite2] = normalizeLimits(expr.op2);
13713
+ const fn = compile(expr.op1, [...expr.op1.freeVars, index], 0);
13714
+ return `(() => {
13715
+ let acc = ${op3 === "+" ? "0" : "1"};
13716
+ const fn = (_) => ${fn};
13717
+ for (let i = ${lower}; i <= ${upper}; i++)
13718
+ acc ${op3}= fn({ ..._, ${index}: i });
13719
+ return acc;
13720
+ })()`;
13721
+ }
13722
+
13723
+ // src/compute-engine/boxed-expression/abstract-boxed-expression.ts
13152
13724
  var AbstractBoxedExpression = class {
13153
13725
  constructor(ce, metadata) {
13154
13726
  this.engine = ce;
@@ -13473,6 +14045,21 @@ var AbstractBoxedExpression = class {
13473
14045
  N(_options) {
13474
14046
  return this.evaluate();
13475
14047
  }
14048
+ compile(to = "javascript", options) {
14049
+ if (to !== "javascript")
14050
+ return void 0;
14051
+ options ?? (options = { optimize: ["simplify", "evaluate"] });
14052
+ let expr = this;
14053
+ if (options.optimize.includes("simplify"))
14054
+ expr = expr.simplify();
14055
+ if (options.optimize.includes("evaluate"))
14056
+ expr = expr.evaluate();
14057
+ try {
14058
+ return compileToJavascript(expr);
14059
+ } catch (e) {
14060
+ }
14061
+ return void 0;
14062
+ }
13476
14063
  };
13477
14064
 
13478
14065
  // src/compute-engine/boxed-expression/serialize.ts
@@ -14935,7 +15522,7 @@ function validateNumericArgs(ce, ops2, count) {
14935
15522
  }
14936
15523
  }
14937
15524
  return xs.map(
14938
- (op3) => !op3.isValid || op3.isNumber ? op3 : ce.error(["incompatible-domain", "Number", op3.domain], op3)
15525
+ (op3) => op3 && !op3.isValid || op3.isNumber ? op3 : ce.error(["incompatible-domain", "Number", op3.domain], op3)
14939
15526
  );
14940
15527
  }
14941
15528
  function validateSignature(sig, ops2, codomain) {
@@ -15304,33 +15891,6 @@ function evalSummation(ce, expr, range, mode) {
15304
15891
  ce.context = savedContext;
15305
15892
  return result ?? void 0;
15306
15893
  }
15307
- function normalizeLimits(range) {
15308
- let lower = 1;
15309
- let upper = lower + MAX_ITERATION;
15310
- let index = "Nothing";
15311
- let isFinite2 = true;
15312
- if (range.head === "Tuple" || range.head === "Triple" || range.head === "Pair" || range.head === "Single") {
15313
- index = (range.op1.head === "Hold" ? range.op1.op1.symbol : range.op1.symbol) ?? "Nothing";
15314
- lower = asSmallInteger(range.op2) ?? 1;
15315
- if (!Number.isFinite(lower))
15316
- isFinite2 = false;
15317
- if (range.op3.isNothing || range.op3.isInfinity) {
15318
- isFinite2 = false;
15319
- } else {
15320
- const u = asSmallInteger(range.op3);
15321
- if (u === null)
15322
- isFinite2 = false;
15323
- else {
15324
- upper = u;
15325
- if (!Number.isFinite(upper))
15326
- isFinite2 = false;
15327
- }
15328
- }
15329
- if (!isFinite2 && Number.isFinite(lower))
15330
- upper = lower + MAX_ITERATION;
15331
- }
15332
- return [index, lower, upper, isFinite2];
15333
- }
15334
15894
 
15335
15895
  // src/compute-engine/symbolic/negate.ts
15336
15896
  var import_complex9 = __toESM(require_complex());
@@ -15643,7 +16203,6 @@ var UNIVARIATE_ROOTS = [
15643
16203
  // ],
15644
16204
  ];
15645
16205
  function findUnivariateRoots(expr, x) {
15646
- console.log("findUnivariateRoots", expr.toString(), x);
15647
16206
  const ce = expr.engine;
15648
16207
  if (expr.head === "Equal") {
15649
16208
  expr = ce.add([expr.op1.canonical, ce.neg(expr.op2.canonical)]).simplify();
@@ -18787,7 +19346,7 @@ var ARITHMETIC_LIBRARY = [
18787
19346
  }
18788
19347
  },
18789
19348
  Erf: {
18790
- description: "Complementary Error Function",
19349
+ description: "Error Function",
18791
19350
  complexity: 7500
18792
19351
  },
18793
19352
  Erfc: {
@@ -18795,7 +19354,7 @@ var ARITHMETIC_LIBRARY = [
18795
19354
  complexity: 7500
18796
19355
  },
18797
19356
  Factorial: {
18798
- description: "The factorial function",
19357
+ description: "Factorial Function",
18799
19358
  wikidata: "Q120976",
18800
19359
  complexity: 9e3,
18801
19360
  signature: {
@@ -18834,7 +19393,7 @@ var ARITHMETIC_LIBRARY = [
18834
19393
  wikidata: "Q190573",
18835
19394
  complexity: 8e3,
18836
19395
  signature: {
18837
- domain: ["Function", "Number", "Number", "Number"],
19396
+ domain: ["Function", "Number", "Number"],
18838
19397
  N: (ce, ops2) => applyN(
18839
19398
  ops2[0],
18840
19399
  (x) => gamma(x),
@@ -18846,7 +19405,7 @@ var ARITHMETIC_LIBRARY = [
18846
19405
  LogGamma: {
18847
19406
  complexity: 8e3,
18848
19407
  signature: {
18849
- domain: ["Function", "Number", "Number", "Number"],
19408
+ domain: ["Function", "Number", "Number"],
18850
19409
  N: (ce, ops2) => applyN(
18851
19410
  ops2[0],
18852
19411
  (x) => lngamma(x),
@@ -19582,6 +20141,18 @@ function randomExpression(level) {
19582
20141
  level ?? (level = 1);
19583
20142
  if (level === 1) {
19584
20143
  const h = oneOf([
20144
+ [
20145
+ "Sqrt",
20146
+ [
20147
+ "Multiply",
20148
+ 6,
20149
+ [
20150
+ "Sum",
20151
+ ["Divide", 1, ["Power", "n", 2]],
20152
+ ["Triple", ["Hold", "n"], 1, { num: "+Infinity" }]
20153
+ ]
20154
+ ]
20155
+ ],
19585
20156
  "Add",
19586
20157
  "Add",
19587
20158
  "Add",
@@ -19600,13 +20171,16 @@ function randomExpression(level) {
19600
20171
  "Negate",
19601
20172
  "trig"
19602
20173
  ]);
19603
- return randomExpressionWithHead(h, 1);
20174
+ if (typeof h === "string")
20175
+ return randomExpressionWithHead(h, 1);
20176
+ return h;
19604
20177
  }
19605
20178
  if (level === 2) {
19606
- if (Math.random() > 0.5)
19607
- return randomExpression(3);
19608
- if (Math.random() > 0.75)
20179
+ const r = Math.random();
20180
+ if (r > 0.75)
19609
20181
  return randomExpression(1);
20182
+ if (r > 0.5)
20183
+ return randomExpression(3);
19610
20184
  const h = oneOf([
19611
20185
  "Multiply",
19612
20186
  "Multiply",
@@ -19660,7 +20234,7 @@ function randomExpression(level) {
19660
20234
  ["Rational", 12, 15],
19661
20235
  ["Rational", 15, 12],
19662
20236
  "ExponentialE",
19663
- "ImaginaryUnit",
20237
+ // 'ImaginaryUnit',
19664
20238
  ["Sqrt", 3],
19665
20239
  ["Sqrt", 5],
19666
20240
  ["Sqrt", 15],
@@ -19678,8 +20252,8 @@ function randomExpression(level) {
19678
20252
  ["Power", "x", 4],
19679
20253
  ["Subtract", "x", 1],
19680
20254
  ["Add", "x", 1],
19681
- "a",
19682
- "b",
20255
+ // 'a',
20256
+ // 'b',
19683
20257
  "Pi"
19684
20258
  ]);
19685
20259
  }
@@ -19874,7 +20448,7 @@ var CORE_LIBRARY = [
19874
20448
  Apply: {
19875
20449
  signature: {
19876
20450
  domain: "Function",
19877
- evaluate: (ce, ops2) => apply(ops2[0], ops2.slice(1))
20451
+ evaluate: (_ce, ops2) => apply(ops2[0], ops2.slice(1))
19878
20452
  }
19879
20453
  },
19880
20454
  About: { signature: { domain: "Function" } },
@@ -19886,6 +20460,11 @@ var CORE_LIBRARY = [
19886
20460
  */
19887
20461
  signature: { domain: "Function" }
19888
20462
  },
20463
+ Derivative: {
20464
+ signature: {
20465
+ domain: ["Function", "Function", ["Maybe", "Number"], "Function"]
20466
+ }
20467
+ },
19889
20468
  Domain: {
19890
20469
  /** Return the domain of an expression */
19891
20470
  signature: {
@@ -20261,7 +20840,7 @@ var LOGIC_LIBRARY = {
20261
20840
  // expressions into CNF (Conjunctive Normal Form)
20262
20841
  // https://en.wikipedia.org/wiki/Conjunctive_normal_form
20263
20842
  // using rules (with a rule set that's kinda the inverse of the
20264
- // logic rules for simplify
20843
+ // logic rules for simplify)
20265
20844
  And: {
20266
20845
  wikidata: "Q191081",
20267
20846
  threadable: true,
@@ -20335,6 +20914,10 @@ var LOGIC_LIBRARY = {
20335
20914
  return ops2[1] ? ops2[1].evaluate() : ce.box("Nothing");
20336
20915
  return ops2[2] ? ops2[2].evaluate() : ce.box("Nothing");
20337
20916
  },
20917
+ // @todo: probably don't need a N() handler. Doesn't make a difference
20918
+ // for the evaluation of booleans. Also, don't need to call N() on the
20919
+ // arguments, the caller should have done that. Same for evaluate()
20920
+ // and simplify() above
20338
20921
  N: (ce, ops2) => {
20339
20922
  const cond = ops2[0];
20340
20923
  if (cond && cond.symbol === "True")
@@ -22507,26 +23090,6 @@ function makeFunctionDefinition(engine, name, def) {
22507
23090
  );
22508
23091
  }
22509
23092
 
22510
- // src/compute-engine/library/utils.ts
22511
- function isSymbolDefinition(def) {
22512
- return !!def && typeof def === "object" && ("domain" in def || "value" in def || "constant" in def);
22513
- }
22514
- function isFunctionDefinition(def) {
22515
- if (def === void 0 || def === null)
22516
- return false;
22517
- if (typeof def !== "object")
22518
- return false;
22519
- if ("complexity" in def || "numeric" in def || "signature" in def)
22520
- return true;
22521
- if (!("domain" in def))
22522
- return false;
22523
- if (def.domain === void 0)
22524
- return false;
22525
- if (typeof def.domain === "string")
22526
- return def.domain === "Function";
22527
- return def.domain.isFunction;
22528
- }
22529
-
22530
23093
  // src/compute-engine/library/library.ts
22531
23094
  function getStandardLibrary(categories) {
22532
23095
  if (categories === "all") {
@@ -23557,14 +24120,15 @@ var ComputeEngine = class _ComputeEngine {
23557
24120
  * perform calculations using arbitrary precision floating point numbers.
23558
24121
  * Use `"auto"` or `"complex"` to allow calculations on complex numbers.
23559
24122
  *
23560
- * @param options.numericPrecision Specific how many digits of precision for the
23561
- * numeric calculations. Default is 100.
24123
+ * @param options.numericPrecision Specific how many digits of precision
24124
+ * for the numeric calculations. Default is 100.
23562
24125
  *
23563
- * @param options.tolerance If the absolute value of the difference of two numbers
23564
- * is less than `tolerance`, they are considered equal. Used by `chop()` as well.
24126
+ * @param options.tolerance If the absolute value of the difference of two
24127
+ * numbers is less than `tolerance`, they are considered equal. Used by
24128
+ * `chop()` as well.
23565
24129
  *
23566
- * @param options.defaultDomain If an unknown symbol is encountered, assume it should
23567
- * be a variable in this domain. **Default** `ExtendedRealNumber`
24130
+ * @param options.defaultDomain If an unknown symbol is encountered, assume
24131
+ * this is its domain. **Default** `ExtendedRealNumber`
23568
24132
  */
23569
24133
  constructor(options) {
23570
24134
  /** @internal */
@@ -23925,6 +24489,10 @@ var ComputeEngine = class _ComputeEngine {
23925
24489
  return new this._bignum(a);
23926
24490
  }
23927
24491
  complex(a, b) {
24492
+ if (a instanceof Decimal)
24493
+ a = a.toNumber();
24494
+ if (b instanceof Decimal)
24495
+ b = b.toNumber();
23928
24496
  return new import_complex19.Complex(a, b);
23929
24497
  }
23930
24498
  isBignum(a) {
@@ -24502,9 +25070,29 @@ var ComputeEngine = class _ComputeEngine {
24502
25070
  this.latexSyntax.updateOptions(opts);
24503
25071
  }
24504
25072
  get jsonSerializationOptions() {
24505
- if (this._useRawJsonSerializationOptions)
24506
- return this._rawJsonSerializationOptions;
24507
- return this._jsonSerializationOptions;
25073
+ if (this._useRawJsonSerializationOptions) {
25074
+ return new Proxy(this._rawJsonSerializationOptions, {
25075
+ get(options, prop) {
25076
+ if (!(prop in options))
25077
+ return void 0;
25078
+ return options[prop];
25079
+ }
25080
+ });
25081
+ }
25082
+ const self = this;
25083
+ return new Proxy(this._jsonSerializationOptions, {
25084
+ get(options, prop) {
25085
+ if (!(prop in options))
25086
+ return void 0;
25087
+ return options[prop];
25088
+ },
25089
+ set(options, prop, value) {
25090
+ if (!(prop in options))
25091
+ return false;
25092
+ self.jsonSerializationOptions = { [prop]: value };
25093
+ return true;
25094
+ }
25095
+ });
24508
25096
  }
24509
25097
  set jsonSerializationOptions(val) {
24510
25098
  if (val.exclude)
@@ -24620,10 +25208,10 @@ var ComputeEngine = class _ComputeEngine {
24620
25208
  };
24621
25209
 
24622
25210
  // src/compute-engine.ts
24623
- var version = "0.12.7";
25211
+ var version = "0.14.0";
24624
25212
  globalThis[Symbol.for("io.cortexjs.compute-engine")] = {
24625
25213
  ComputeEngine: ComputeEngine.prototype.constructor,
24626
- version: "0.12.7"
25214
+ version: "0.14.0"
24627
25215
  };
24628
25216
  export {
24629
25217
  ComputeEngine,