@pie-framework/math-validation 1.4.3 → 2.0.0-next.20261110063142

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 (71) hide show
  1. package/LICENSE +233 -0
  2. package/README.md +41 -110
  3. package/dist/conversion/ast-to-mathjs.d.ts +3 -0
  4. package/dist/conversion/error.d.ts +4 -0
  5. package/dist/conversion/flatten.d.ts +1 -0
  6. package/{lib → dist}/conversion/latex-to-ast.d.ts +13 -12
  7. package/{lib → dist}/conversion/lexer.d.ts +5 -5
  8. package/dist/difference.d.ts +1 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +1594 -0
  11. package/dist/latex-equal.d.ts +2 -0
  12. package/dist/literal/index.d.ts +3 -0
  13. package/dist/log.d.ts +1 -0
  14. package/dist/mathjs.d.ts +11 -0
  15. package/{lib → dist}/node-sort.d.ts +1 -1
  16. package/dist/options.d.ts +13 -0
  17. package/{lib → dist}/symbolic/compare-compound-inequations.d.ts +2 -2
  18. package/{lib → dist}/symbolic/compare-equations.d.ts +1 -1
  19. package/dist/symbolic/index.d.ts +1 -0
  20. package/dist/symbolic/simplify.d.ts +2 -0
  21. package/{lib → dist}/symbolic/utils.d.ts +3 -3
  22. package/dist/value.d.ts +6 -0
  23. package/package.json +28 -56
  24. package/lib/conversion/ast-to-mathjs.d.ts +0 -12
  25. package/lib/conversion/ast-to-mathjs.js +0 -329
  26. package/lib/conversion/ast-to-mathjs.js.map +0 -1
  27. package/lib/conversion/error.d.ts +0 -5
  28. package/lib/conversion/error.js +0 -13
  29. package/lib/conversion/error.js.map +0 -1
  30. package/lib/conversion/flatten.d.ts +0 -12
  31. package/lib/conversion/flatten.js +0 -103
  32. package/lib/conversion/flatten.js.map +0 -1
  33. package/lib/conversion/latex-to-ast.js +0 -1479
  34. package/lib/conversion/latex-to-ast.js.map +0 -1
  35. package/lib/conversion/lexer.js +0 -135
  36. package/lib/conversion/lexer.js.map +0 -1
  37. package/lib/conversion/util.d.ts +0 -3
  38. package/lib/conversion/util.js +0 -36
  39. package/lib/conversion/util.js.map +0 -1
  40. package/lib/demo.d.ts +0 -4
  41. package/lib/demo.js +0 -173
  42. package/lib/demo.js.map +0 -1
  43. package/lib/difference.d.ts +0 -2
  44. package/lib/difference.js +0 -24
  45. package/lib/difference.js.map +0 -1
  46. package/lib/index.d.ts +0 -5
  47. package/lib/index.js +0 -9
  48. package/lib/index.js.map +0 -1
  49. package/lib/latex-equal.d.ts +0 -10
  50. package/lib/latex-equal.js +0 -41
  51. package/lib/latex-equal.js.map +0 -1
  52. package/lib/literal/index.d.ts +0 -10
  53. package/lib/literal/index.js +0 -22
  54. package/lib/literal/index.js.map +0 -1
  55. package/lib/log.d.ts +0 -1
  56. package/lib/log.js +0 -14
  57. package/lib/log.js.map +0 -1
  58. package/lib/mathjs.d.ts +0 -3
  59. package/lib/mathjs.js +0 -9
  60. package/lib/mathjs.js.map +0 -1
  61. package/lib/node-sort.js +0 -236
  62. package/lib/node-sort.js.map +0 -1
  63. package/lib/symbolic/compare-compound-inequations.js +0 -68
  64. package/lib/symbolic/compare-compound-inequations.js.map +0 -1
  65. package/lib/symbolic/compare-equations.js +0 -106
  66. package/lib/symbolic/compare-equations.js.map +0 -1
  67. package/lib/symbolic/index.d.ts +0 -4
  68. package/lib/symbolic/index.js +0 -340
  69. package/lib/symbolic/index.js.map +0 -1
  70. package/lib/symbolic/utils.js +0 -323
  71. package/lib/symbolic/utils.js.map +0 -1
@@ -1,1479 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.LatexToAst = exports.DEFAULT_OPTS = exports.latex_rules = exports.whitespace_rule = void 0;
7
- const error_1 = require("./error");
8
- const lexer_1 = __importDefault(require("./lexer"));
9
- const flatten_1 = require("./flatten");
10
- const log_1 = require("../log");
11
- const log = (0, log_1.logger)("mv:latex-to-ast");
12
- // UPDATETHIS: Delete or change to new license & package name
13
- /*
14
- * recursive descent parser for math expressions
15
- *
16
- * Copyright 2014-2017 by
17
- * Jim Fowler <kisonecat@gmail.com>
18
- * Duane Nykamp <nykamp@umn.edu>
19
- *
20
- * This file is part of a math-expressions library
21
- *
22
- * math-expressions is free software: you can redistribute
23
- * it and/or modify it under the terms of the GNU General Public
24
- * License as published by the Free Software Foundation, either
25
- * version 3 of the License, or at your option any later version.
26
- *
27
- * math-expressions is distributed in the hope that it
28
- * will be useful, but WITHOUT ANY WARRANTY; without even the implied
29
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30
- * See the GNU General Public License for more details.
31
- *
32
- */
33
- // UPDATETHIS: Is this grammar still correct?
34
- /* Grammar:
35
-
36
- statement_list =
37
- statement_list ',' statement |
38
- statement
39
-
40
- statement =
41
- '\\dots' |
42
- statement_a '|' statement_a |
43
- statement_a 'MID' statement_a |
44
- statement_a ':' statement_a
45
- **** statement_a '|' statement_a
46
- used with turning off '|' statement '|' in baseFactor
47
- tried only after parse error encountered
48
-
49
- statement_a =
50
- statement_a 'OR' statement_b |
51
- statement_b
52
-
53
- statement_b =
54
- statement_b 'AND' relation |
55
- relation
56
-
57
- relation =
58
- 'NOT' relation |
59
- relation '=' expression |
60
- relation 'NE' expression |
61
- relation '<' expression |
62
- relation '>' expression |
63
- relation 'LE' expression |
64
- relation 'GE' expression |
65
- relation 'IN' expression |
66
- relation 'NOTIN' expression |
67
- relation 'NI' expression |
68
- relation 'NOTNI' expression |
69
- relation 'SUBSET' expression |
70
- relation 'NOTSUBSET' expression |
71
- relation 'SUPERSET' expression |
72
- relation 'NOTSUPERSET' expression |
73
- expression
74
-
75
- expression =
76
- expression '+' term |
77
- expression '-' term |
78
- expression 'UNION' term |
79
- expression 'INTERSECT' term |
80
- '+' term |
81
- term
82
-
83
- term =
84
- term '*' factor |
85
- term nonMinusFactor |
86
- term '/' factor |
87
- factor
88
-
89
- baseFactor =
90
- '(' statement_list ')' |
91
- '[' statement_list ']' |
92
- '{' statement_list '}' |
93
- 'LBRACE' statement_list 'RBRACE' |
94
- '(' statement ',' statement ']' |
95
- '[' statement ',' statement ')' |
96
- '|' statement '|' |
97
- \frac{statement}{statement} |
98
- number |
99
- variable |
100
- modified_function '(' statement_list ')' |
101
- modified_applied_function '(' statement_list ')' |
102
- modified_function '{' statement_list '}' |
103
- modified_applied_function '{' statement_list '}' |
104
- modified_function |
105
- modified_applied_function factor |
106
- sqrt '[' statement ']' '{' statement '}' |
107
- baseFactor '_' baseFactor |
108
- *** modified_applied_function factor
109
- allowed only if allowSimplifiedFunctionApplication==true
110
- *** '|' statement '|'
111
- allowed only at beginning of factor or if not currently in absolute value
112
-
113
- modified_function =
114
- function |
115
- function '_' baseFactor |
116
- function '_' baseFactor '^' factor |
117
- function '^' factor
118
- function "'"
119
- function '_' baseFactor "'"
120
- function '_' baseFactor "'" '^' factor
121
- function "'" '^' factor
122
- *** where the "'" after the functions can be repeated
123
-
124
- modified_applied_function =
125
- applied_function |
126
- applied_function '_' baseFactor |
127
- applied_function '_' baseFactor '^' factor |
128
- applied_function '^' factor
129
- applied_function "'"
130
- applied_function '_' baseFactor "'"
131
- applied_function '_' baseFactor "'" '^' factor
132
- applied_function "'" '^' factor
133
- *** where the "'" after the applied_functions can be repeated
134
-
135
- nonMinusFactor =
136
- baseFactor |
137
- baseFactor '^' factor |
138
- baseFactor '!' and/or "'" |
139
- baseFactor '!' and/or "'" '^' factor|
140
- *** where '!' and/or "'" indicates arbitrary sequence of "!" and/or "'"
141
-
142
- factor =
143
- '-' factor |
144
- nonMinusFactor
145
-
146
- */
147
- // Some of the latex commands that lead to spacing
148
- exports.whitespace_rule = "\\s|\\\\,|\\\\!|\\\\ |\\\\>|\\\\;|\\\\:|\\\\quad\\b|\\\\qquad\\b";
149
- // in order to parse as scientific notation, e.g., 3.2E-12 or .7E+3,
150
- // it must be at the end or followed a comma, &, |, \|, ), }, \}, ], \\, or \end
151
- const sci_notat_exp_regex = "(E[+\\-]?[0-9]+\\s*($|(?=\\,|&|\\||\\\\\\||\\)|\\}|\\\\}|\\]|\\\\\\\\|\\\\end)))?";
152
- // TO-DO: ADD all mathjs built-in units?
153
- const lengthUnit = "(mm|cm|km|ft|yd|mi|mmi|li|rd|angstrom|mil";
154
- const volumeUnit = "|mL|ml|L|m3|in3|ft3|pt|qt|gal|bbl)";
155
- const measurmentUnit = lengthUnit + volumeUnit + "{1}";
156
- const numberWithCommasAsThousandsSeparator = "[0-9]{1,3}(\\,[0-9]{3})+(\\.[0-9]+)*";
157
- // const latex_rules = [["\\\\neq(?![a-zA-Z])", "NE"]];
158
- exports.latex_rules = [
159
- [measurmentUnit, "UNIT"],
160
- ["\\$", "TEXT"],
161
- ["\\\\" + "\\$", "TEXT"],
162
- ["\\\\text{[a-zA-Z0-9\\s\\\\,\\\\.]+?}", "TEXT"],
163
- ["[0-9]+\\s*\\\\frac(?![a-zA-Z])", "MIXED_NUMBER"],
164
- [numberWithCommasAsThousandsSeparator + sci_notat_exp_regex, "NUMBER"],
165
- ["[0-9]+(\\.[0-9]*)?" + sci_notat_exp_regex, "NUMBER"],
166
- ["\\.[0-9]+" + sci_notat_exp_regex, "NUMBER"],
167
- [",", ","],
168
- ["\\*", "*"],
169
- ["\\×", "*"],
170
- ["\\•", "*"],
171
- ["\\·", "*"],
172
- ["\\/", "/"],
173
- ["\\÷", "/"],
174
- ["%", "PERCENT"],
175
- ["\\\\%", "PERCENT"],
176
- ["−", "-"],
177
- ["-", "-"],
178
- ["\\+", "+"],
179
- ["\\^", "^"],
180
- ["\\(", "("],
181
- ["\\\\left\\s*\\(", "("],
182
- ["\\\\bigl\\s*\\(", "("],
183
- ["\\\\Bigl\\s*\\(", "("],
184
- ["\\\\biggl\\s*\\(", "("],
185
- ["\\\\Biggl\\s*\\(", "("],
186
- ["\\)", ")"],
187
- ["\\\\right\\s*\\)", ")"],
188
- ["\\\\bigr\\s*\\)", ")"],
189
- ["\\\\Bigr\\s*\\)", ")"],
190
- ["\\\\biggr\\s*\\)", ")"],
191
- ["\\\\Biggr\\s*\\)", ")"],
192
- ["\\[", "["],
193
- ["\\\\left\\s*\\[", "["],
194
- ["\\\\bigl\\s*\\[", "["],
195
- ["\\\\Bigl\\s*\\[", "["],
196
- ["\\\\biggl\\s*\\[", "["],
197
- ["\\\\Biggl\\s*\\[", "["],
198
- ["\\]", "]"],
199
- ["\\\\right\\s*\\]", "]"],
200
- ["\\\\bigr\\s*\\]", "]"],
201
- ["\\\\Bigr\\s*\\]", "]"],
202
- ["\\\\biggr\\s*\\]", "]"],
203
- ["\\\\Biggr\\s*\\]", "]"],
204
- ["\\|", "|"],
205
- ["\\\\left\\s*\\|", "|L"],
206
- ["\\\\bigl\\s*\\|", "|L"],
207
- ["\\\\Bigl\\s*\\|", "|L"],
208
- ["\\\\biggl\\s*\\|", "|L"],
209
- ["\\\\Biggl\\s*\\|", "|L"],
210
- ["\\\\right\\s*\\|", "|"],
211
- ["\\\\bigr\\s*\\|", "|"],
212
- ["\\\\Bigr\\s*\\|", "|"],
213
- ["\\\\biggr\\s*\\|", "|"],
214
- ["\\\\Biggr\\s*\\|", "|"],
215
- ["\\\\big\\s*\\|", "|"],
216
- ["\\\\Big\\s*\\|", "|"],
217
- ["\\\\bigg\\s*\\|", "|"],
218
- ["\\\\Bigg\\s*\\|", "|"],
219
- ["{", "{"],
220
- ["}", "}"],
221
- ["\\\\{", "LBRACE"],
222
- ["\\\\left\\s*\\\\{", "LBRACE"],
223
- ["\\\\bigl\\s*\\\\{", "LBRACE"],
224
- ["\\\\Bigl\\s*\\\\{", "LBRACE"],
225
- ["\\\\biggl\\s*\\\\{", "LBRACE"],
226
- ["\\\\Biggl\\s*\\\\{", "LBRACE"],
227
- ["\\\\}", "RBRACE"],
228
- ["\\\\right\\s*\\\\}", "RBRACE"],
229
- ["\\\\bigr\\s*\\\\}", "RBRACE"],
230
- ["\\\\Bigr\\s*\\\\}", "RBRACE"],
231
- ["\\\\biggr\\s*\\\\}", "RBRACE"],
232
- ["\\\\Biggr\\s*\\\\}", "RBRACE"],
233
- ["\\\\cdot(?![a-zA-Z])", "*"],
234
- ["\\\\div(?![a-zA-Z])", "/"],
235
- ["\\\\times(?![a-zA-Z])", "*"],
236
- ["\\\\frac(?![a-zA-Z])", "FRAC"],
237
- ["°", "deg"],
238
- ["°", "deg"],
239
- ["\\\\degree", "deg"],
240
- ["\\\\deg", "deg"],
241
- ["\\\\grade", "grad"],
242
- ["\\\\gon", "grad"],
243
- ["\\\\grad", "grad"],
244
- [":", ":"],
245
- ["\\\\mid", "MID"],
246
- ["\\\\vartheta(?![a-zA-Z])", "LATEXCOMMAND", "\\theta"],
247
- ["\\\\π", "LATEXCOMMAND", "\\pi"],
248
- ["\\\\varepsilon(?![a-zA-Z])", "LATEXCOMMAND", "\\epsilon"],
249
- ["\\\\varrho(?![a-zA-Z])", "LATEXCOMMAND", "\\rho"],
250
- ["\\\\varphi(?![a-zA-Z])", "LATEXCOMMAND", "\\phi"],
251
- ["\\\\infty(?![a-zA-Z])", "INFINITY"],
252
- ["\\\\Infinity(?![a-zA-Z])", "INFINITY"],
253
- ["\\\\sqrt(?![a-zA-Z])", "SQRT"],
254
- ["\\\\log(?![a-zA-Z])", "LOG"],
255
- ["\\\\ln(?![a-zA-Z])", "LN"],
256
- ["\\\\cosec", "LATEXCOMMAND", "\\csc"],
257
- // inverse trigonometric functions
258
- ["\\\\sin\\^\\{-1}(?![a-zA-Z])", "LATEXCOMMAND", "\\asin"],
259
- ["\\\\cos\\^\\{-1}(?![a-zA-Z])", "LATEXCOMMAND", "\\acos"],
260
- ["\\\\tan\\^\\{-1}(?![a-zA-Z])", "LATEXCOMMAND", "\\atan"],
261
- ["\\\\cot\\^\\{-1}(?![a-zA-Z])", "LATEXCOMMAND", "\\acot"],
262
- ["\\\\sec\\^\\{-1}(?![a-zA-Z])", "LATEXCOMMAND", "\\asec"],
263
- ["\\\\csc\\^\\{-1}(?![a-zA-Z])", "LATEXCOMMAND", "\\acsc"],
264
- ["\\\\arsin(?![a-zA-Z])", "LATEXCOMMAND", "\\asin"],
265
- ["\\\\arcsin(?![a-zA-Z])", "LATEXCOMMAND", "\\asin"],
266
- ["\\\\arcos(?![a-zA-Z])", "LATEXCOMMAND", "\\acos"],
267
- ["\\\\arccos(?![a-zA-Z])", "LATEXCOMMAND", "\\acos"],
268
- ["\\\\artan(?![a-zA-Z])", "LATEXCOMMAND", "\\atan"],
269
- ["\\\\arctan(?![a-zA-Z])", "LATEXCOMMAND", "\\atan"],
270
- ["\\\\arcot(?![a-zA-Z])", "LATEXCOMMAND", "\\acot"],
271
- ["\\\\arccot(?![a-zA-Z])", "LATEXCOMMAND", "\\acot"],
272
- ["\\\\arsec(?![a-zA-Z])", "LATEXCOMMAND", "\\asec"],
273
- ["\\\\arcsec(?![a-zA-Z])", "LATEXCOMMAND", "\\asec"],
274
- ["\\\\arcsc(?![a-zA-Z])", "LATEXCOMMAND", "\\acsc"],
275
- ["\\\\arccsc(?![a-zA-Z])", "LATEXCOMMAND", "\\acsc"],
276
- ["\\\\land(?![a-zA-Z])", "AND"],
277
- ["\\\\wedge(?![a-zA-Z])", "AND"],
278
- ["\\\\lor(?![a-zA-Z])", "OR"],
279
- ["\\\\vee(?![a-zA-Z])", "OR"],
280
- ["\\\\lnot(?![a-zA-Z])", "NOT"],
281
- ["=", "="],
282
- ["≠", "NE"],
283
- ["\\\\neq(?![a-zA-Z])", "NE"],
284
- ["\\\\ne(?![a-zA-Z])", "NE"],
285
- ["\\\\not\\s*=", "NE"],
286
- ["\\\\leq(?![a-zA-Z])", "LE"],
287
- ["\\\\le(?![a-zA-Z])", "LE"],
288
- ["\\\\geq(?![a-zA-Z])", "GE"],
289
- ["\\\\ge(?![a-zA-Z])", "GE"],
290
- ["<", "<"],
291
- ["≤", "LE"],
292
- ["\\\\lt(?![a-zA-Z])", "<"],
293
- [">", ">"],
294
- ["≥", "GE"],
295
- ["\\\\gt(?![a-zA-Z])", ">"],
296
- // is approximately
297
- ["\\\\approx", "≈"],
298
- ["≈", "≈"],
299
- // not almost equal to
300
- ["\\\\napprox", "≉"],
301
- ["≉", "≉"],
302
- // is similar or equal to
303
- ["\\\\simeq", "≃"],
304
- ["≃", "≃"],
305
- // is similar to
306
- ["\\\\sim", "~"],
307
- ["~", "~"],
308
- // is not similar to
309
- ["\\\\nsim", "≁"],
310
- ["≁", "≁"],
311
- // is congruent to
312
- ["\\\\cong", "≅"],
313
- ["≅", "≅"],
314
- // is not congurent to
315
- ["\\\\ncong", "≆"],
316
- ["≆", "≆"],
317
- // inverse f and g functions are treated as text
318
- ["f\\^\\{-1}", "TEXT"],
319
- ["g\\^\\{-1}", "TEXT"],
320
- ["\\\\in(?![a-zA-Z])", "IN"],
321
- ["\\\\notin(?![a-zA-Z])", "NOTIN"],
322
- ["\\\\not\\s*\\\\in(?![a-zA-Z])", "NOTIN"],
323
- ["\\\\ni(?![a-zA-Z])", "NI"],
324
- ["\\\\not\\s*\\\\ni(?![a-zA-Z])", "NOTNI"],
325
- ["\\\\subset(?![a-zA-Z])", "SUBSET"],
326
- ["\\\\not\\s*\\\\subset(?![a-zA-Z])", "NOTSUBSET"],
327
- ["\\\\supset(?![a-zA-Z])", "SUPERSET"],
328
- ["\\\\not\\s*\\\\supset(?![a-zA-Z])", "NOTSUPERSET"],
329
- ["\\\\cup(?![a-zA-Z])", "UNION"],
330
- ["\\\\cap(?![a-zA-Z])", "INTERSECT"],
331
- ["!", "!"],
332
- ["'", "'"],
333
- ["_", "_"],
334
- ["&", "&"],
335
- ["\\\\ldots", "LDOTS"],
336
- ["\\\\\\\\", "LINEBREAK"],
337
- ["\\\\begin\\s*{\\s*[a-zA-Z0-9]+\\s*}", "BEGINENVIRONMENT"],
338
- ["\\\\end\\s*{\\s*[a-zA-Z0-9]+\\s*}", "ENDENVIRONMENT"],
339
- ["\\\\var\\s*{\\s*[a-zA-Z0-9]+\\s*}", "VARMULTICHAR"],
340
- ["\\\\[a-zA-Z]+(?![a-zA-Z])", "LATEXCOMMAND"],
341
- ["[a-zA-Z]", "VAR"],
342
- ];
343
- // defaults for parsers if not overridden by context
344
- // if true, allowed applied functions to omit parentheses around argument
345
- // if false, omitting parentheses will lead to a Parse Error
346
- const allowSimplifiedFunctionApplicationDefault = true;
347
- // allowed multicharacter latex symbols
348
- // in addition to the below applied function symbols
349
- const allowedLatexSymbolsDefault = [
350
- "alpha",
351
- "beta",
352
- "gamma",
353
- "Gamma",
354
- "delta",
355
- "Delta",
356
- "epsilon",
357
- "zeta",
358
- "eta",
359
- "theta",
360
- "Theta",
361
- "iota",
362
- "kappa",
363
- "lambda",
364
- "Lambda",
365
- "mu",
366
- "nu",
367
- "xi",
368
- "Xi",
369
- "pi",
370
- "Pi",
371
- "rho",
372
- "sigma",
373
- "Sigma",
374
- "tau",
375
- "Tau",
376
- "upsilon",
377
- "Upsilon",
378
- "phi",
379
- "Phi",
380
- "chi",
381
- "psi",
382
- "Psi",
383
- "omega",
384
- "Omega",
385
- "partial",
386
- ];
387
- // Applied functions must be given an argument so that
388
- // they are applied to the argument
389
- const appliedFunctionSymbolsDefault = [
390
- "abs",
391
- "exp",
392
- "log",
393
- "ln",
394
- "log10",
395
- "sign",
396
- "sqrt",
397
- "erf",
398
- "acos",
399
- "acosh",
400
- "acot",
401
- "acoth",
402
- "acsc",
403
- "acsch",
404
- "asec",
405
- "asech",
406
- "asin",
407
- "asinh",
408
- "atan",
409
- "atanh",
410
- "cos",
411
- "cosh",
412
- "cot",
413
- "coth",
414
- "csc",
415
- "csch",
416
- "sec",
417
- "sech",
418
- "sin",
419
- "sinh",
420
- "tan",
421
- "tanh",
422
- "arg",
423
- ];
424
- const missingFactorDefaultBehavior = function (token, e) {
425
- throw e;
426
- };
427
- exports.DEFAULT_OPTS = {
428
- allowSimplifiedFunctionApplication: allowSimplifiedFunctionApplicationDefault,
429
- allowedLatexSymbols: allowedLatexSymbolsDefault,
430
- appliedFunctionSymbols: appliedFunctionSymbolsDefault,
431
- /**
432
- * Functions could have an argument, in which case they are applied
433
- * or, if they don't have an argument in parentheses, then they are treated
434
- * like a variable, except that trailing ^ and ' have higher precedence
435
- */
436
- functionSymbols: ["f", "g"],
437
- parseLeibnizNotation: true,
438
- missingFactor: missingFactorDefaultBehavior,
439
- unknownCommandBehavior: "error",
440
- };
441
- class LatexToAst {
442
- constructor(opts) {
443
- this.opts = Object.assign(Object.assign({}, exports.DEFAULT_OPTS), opts);
444
- if (this.opts.unknownCommandBehavior !== "error" &&
445
- this.opts.unknownCommandBehavior !== "passthrough") {
446
- throw new Error("Unknown behavior for unknown command: " +
447
- this.opts.unknownCommandBehavior);
448
- }
449
- this.lexer = new lexer_1.default(exports.latex_rules, exports.whitespace_rule);
450
- }
451
- advance(params) {
452
- this.token = this.lexer.advance(params);
453
- if (this.token.token_type === "INVALID") {
454
- throw new error_1.ParseError("Invalid symbol '" + this.token.original_text + "'", this.lexer.location);
455
- }
456
- }
457
- return_state() {
458
- return {
459
- lexer_state: this.lexer.return_state(),
460
- token: Object.assign({}, this.token),
461
- };
462
- }
463
- set_state(state) {
464
- this.lexer.set_state(state.lexer_state);
465
- this.token = Object.assign({}, state.token);
466
- }
467
- convert(input, pars) {
468
- this.lexer.set_input(input);
469
- this.advance();
470
- var result = this.statement_list(pars);
471
- if (this.token.token_type !== "EOF") {
472
- throw new error_1.ParseError("Invalid location of '" + this.token.original_text + "'", this.lexer.location);
473
- }
474
- return (0, flatten_1.flatten)(result);
475
- }
476
- statement_list(pars) {
477
- var list = [this.statement(pars)];
478
- while (this.token.token_type === ",") {
479
- this.advance();
480
- list.push(this.statement(pars));
481
- }
482
- if (list.length > 1)
483
- list = ["list"].concat(list);
484
- else
485
- list = list[0];
486
- return list;
487
- }
488
- statement(opts = {}) {
489
- const { inside_absolute_value = 0, unknownCommands = "error" } = opts;
490
- // \ldots can be a statement by itself
491
- if (this.token.token_type === "LDOTS") {
492
- this.advance();
493
- return ["ldots"];
494
- }
495
- var original_state;
496
- try {
497
- original_state = this.return_state();
498
- let lhs = this.statement_a({
499
- inside_absolute_value: inside_absolute_value,
500
- unknownCommands: unknownCommands,
501
- });
502
- //console.log("lhs:", lhs);
503
- if (this.token.token_type !== ":" && this.token.token_type !== "MID")
504
- return lhs;
505
- let operator = this.token.token_type === ":" ? ":" : "|";
506
- this.advance();
507
- let rhs = this.statement_a({ unknownCommands: unknownCommands });
508
- return [operator, lhs, rhs];
509
- }
510
- catch (e) {
511
- try {
512
- // if ran into problem parsing statement
513
- // then try again with ignoring absolute value
514
- // and then interpreting bar as a binary operator
515
- // return state to what it was before attempting to parse statement
516
- this.set_state(original_state);
517
- let lhs = this.statement_a({ parse_absolute_value: false });
518
- //console.log("lhs:", lhs);
519
- if (this.token.token_type[0] !== "|") {
520
- throw e;
521
- }
522
- this.advance();
523
- let rhs = this.statement_a({ parse_absolute_value: false });
524
- return ["|", lhs, rhs];
525
- }
526
- catch (e2) {
527
- throw e; // throw original error
528
- }
529
- }
530
- }
531
- statement_a(opts = {}) {
532
- const { inside_absolute_value = 0, parse_absolute_value = true, unknownCommands, } = opts;
533
- var lhs = this.statement_b({
534
- inside_absolute_value: inside_absolute_value,
535
- parse_absolute_value: parse_absolute_value,
536
- unknownCommands: unknownCommands,
537
- });
538
- while (this.token.token_type === "OR") {
539
- let operation = this.token.token_type.toLowerCase();
540
- this.advance();
541
- let rhs = this.statement_b({
542
- inside_absolute_value: inside_absolute_value,
543
- parse_absolute_value: parse_absolute_value,
544
- unknownCommands: unknownCommands,
545
- });
546
- lhs = [operation, lhs, rhs];
547
- }
548
- return lhs;
549
- }
550
- statement_b(params) {
551
- // split AND into second statement to give higher precedence than OR
552
- var lhs = this.relation(params);
553
- while (this.token.token_type === "AND") {
554
- let operation = this.token.token_type.toLowerCase();
555
- this.advance();
556
- let rhs = this.relation(params);
557
- lhs = [operation, lhs, rhs];
558
- }
559
- return lhs;
560
- }
561
- relation(params) {
562
- if (this.token.token_type === "NOT" || this.token.token_type === "!") {
563
- this.advance();
564
- return ["not", this.relation(params)];
565
- }
566
- var lhs = this.expression(params);
567
- let relationalToken = (token) => token === "<" ||
568
- token === "LE" ||
569
- token === ">" ||
570
- token === "GE" ||
571
- token === "NE";
572
- while (this.token.token_type === "=" ||
573
- this.token.token_type === "NE" ||
574
- this.token.token_type === "<" ||
575
- this.token.token_type === ">" ||
576
- this.token.token_type === "LE" ||
577
- this.token.token_type === "GE" ||
578
- this.token.token_type === "IN" ||
579
- this.token.token_type === "NOTIN" ||
580
- this.token.token_type === "NI" ||
581
- this.token.token_type === "NOTNI" ||
582
- this.token.token_type === "SUBSET" ||
583
- this.token.token_type === "NOTSUBSET" ||
584
- this.token.token_type === "SUPERSET" ||
585
- this.token.token_type === "NOTSUPERSET" ||
586
- this.token.token_type === "≈" ||
587
- this.token.token_type === "≉" ||
588
- this.token.token_type === "~" ||
589
- this.token.token_type === "≃" ||
590
- this.token.token_type === "≁" ||
591
- this.token.token_type === "≅" ||
592
- this.token.token_type === "≆") {
593
- let operation = this.token.token_type.toLowerCase();
594
- let inequality_sequence = relationalToken(this.token.token_type);
595
- this.advance();
596
- let rhs = this.expression(params);
597
- const relationalOperator = (operatorSign) => {
598
- switch (operatorSign) {
599
- case "<":
600
- return "smaller";
601
- case "LE":
602
- case "le":
603
- return "smallerEq";
604
- case ">":
605
- return "larger";
606
- case "GE":
607
- case "ge":
608
- return "largerEq";
609
- case "NE":
610
- case "ne":
611
- return "unequal";
612
- }
613
- };
614
- if (inequality_sequence && relationalToken(this.token.token_type)) {
615
- let strict = ["tuple"];
616
- strict.push(relationalOperator(operation));
617
- let args = ["tuple", lhs, rhs];
618
- while (relationalToken(this.token.token_type)) {
619
- strict.push(relationalOperator(this.token.token_type));
620
- this.advance();
621
- args.push(this.expression(params));
622
- }
623
- lhs = ["relational", args, strict];
624
- }
625
- else if (operation === "=") {
626
- lhs = [operation, lhs, rhs];
627
- // check for sequence of multiple =
628
- while (this.token.token_type === "=") {
629
- this.advance();
630
- lhs.push(this.expression(params));
631
- }
632
- }
633
- else {
634
- lhs = [operation, lhs, rhs];
635
- }
636
- }
637
- return lhs;
638
- }
639
- expression(params) {
640
- if (this.token.token_type === "+")
641
- this.advance();
642
- let negative_begin = false;
643
- if (this.token.token_type === "-") {
644
- negative_begin = true;
645
- this.advance();
646
- }
647
- var lhs = this.term(params);
648
- if (negative_begin) {
649
- lhs = ["-", lhs];
650
- }
651
- while (this.token.token_type === "+" ||
652
- this.token.token_type === "-" ||
653
- this.token.token_type === "UNION" ||
654
- this.token.token_type === "INTERSECT") {
655
- let operation = this.token.token_type.toLowerCase();
656
- let negative = false;
657
- if (this.token.token_type === "-") {
658
- operation = "+";
659
- negative = true;
660
- this.advance();
661
- }
662
- else {
663
- this.advance();
664
- // @ts-ignore
665
- if (operation === "+" && this.token.token_type === "-") {
666
- negative = true;
667
- this.advance();
668
- }
669
- }
670
- let rhs = this.term(params);
671
- if (negative) {
672
- rhs = ["-", rhs];
673
- }
674
- lhs = [operation, lhs, rhs];
675
- }
676
- return lhs;
677
- }
678
- term(params) {
679
- var lhs;
680
- try {
681
- lhs = this.factor(params);
682
- }
683
- catch (e) {
684
- lhs = this.opts.missingFactor(this.token, e);
685
- lhs = Number.isFinite(lhs) ? lhs : 0;
686
- }
687
- var keepGoing = false;
688
- do {
689
- keepGoing = false;
690
- if (this.token.token_type === "PERCENT") {
691
- this.advance();
692
- lhs = ["%", lhs];
693
- keepGoing = true;
694
- }
695
- else if (this.token.token_type === "*") {
696
- this.advance();
697
- lhs = ["*", lhs, this.factor(params)];
698
- keepGoing = true;
699
- }
700
- else if (this.token.token_type === "/") {
701
- this.advance();
702
- lhs = ["/", lhs, this.factor(params)];
703
- keepGoing = true;
704
- }
705
- else {
706
- // this is the one case where a | could indicate a closing absolute value
707
- let params2 = Object.assign({}, params);
708
- params2.allow_absolute_value_closing = true;
709
- let rhs = this.nonMinusFactor(params2);
710
- if (rhs !== false) {
711
- lhs = ["*", lhs, rhs];
712
- keepGoing = true;
713
- }
714
- }
715
- } while (keepGoing);
716
- return lhs;
717
- }
718
- factor(params) {
719
- // console.log("factor:", this.token);
720
- // console.log("before: lexer state:", this.lexer.return_state());
721
- if (this.token.token_type === "-") {
722
- this.advance();
723
- return ["-", this.factor(params)];
724
- }
725
- var result = this.nonMinusFactor(params);
726
- // console.log("result", result);
727
- if (result === false) {
728
- if (this.token.token_type === "EOF") {
729
- throw new error_1.ParseError("Unexpected end of input", this.lexer.location);
730
- }
731
- else {
732
- //console.log("lexer state:", this.lexer.return_state());
733
- throw new error_1.ParseError("Invalid location of '" + this.token.original_text + "'", this.lexer.location);
734
- }
735
- }
736
- else {
737
- return result;
738
- }
739
- }
740
- nonMinusFactor(params) {
741
- let result = this.baseFactor(params);
742
- // allow arbitrary sequence of factorials
743
- if (this.token.token_type === "!" || this.token.token_type === "'") {
744
- if (result === false)
745
- throw new error_1.ParseError("Invalid location of " + this.token.token_type, this.lexer.location);
746
- while (this.token.token_type === "!" || this.token.token_type === "'") {
747
- if (this.token.token_type === "!")
748
- result = ["apply", "factorial", result];
749
- else
750
- result = ["prime", result];
751
- this.advance();
752
- }
753
- }
754
- if (this.token.token_type === "^") {
755
- if (result === false) {
756
- throw new error_1.ParseError("Invalid location of ^", this.lexer.location);
757
- }
758
- this.advance();
759
- // do not allow absolute value closing here
760
- let params2 = Object.assign({}, params);
761
- delete params2.allow_absolute_value_closing;
762
- delete params2.inside_absolute_value;
763
- return ["^", result, this.factor(params2)];
764
- }
765
- return result;
766
- }
767
- fraction({ inside_absolute_value = 0, parse_absolute_value = true, allow_absolute_value_closing = false, unknownCommands = "error", }) {
768
- this.advance();
769
- if (this.token.token_type !== "{") {
770
- throw new error_1.ParseError("Expecting {", this.lexer.location);
771
- }
772
- this.advance();
773
- // determine if may be a derivative in Leibniz notation
774
- if (this.opts.parseLeibnizNotation) {
775
- let original_state = this.return_state();
776
- let r = this.leibniz_notation();
777
- if (r) {
778
- // successfully parsed derivative in Leibniz notation, so return
779
- return r;
780
- }
781
- else {
782
- // didn't find a properly format Leibniz notation
783
- // so reset state and continue
784
- this.set_state(original_state);
785
- }
786
- }
787
- let numerator = this.statement({
788
- parse_absolute_value: parse_absolute_value,
789
- unknownCommands: unknownCommands,
790
- });
791
- // @ts-ignore
792
- if (this.token.token_type !== "}") {
793
- throw new error_1.ParseError("Expecting }", this.lexer.location);
794
- }
795
- this.advance();
796
- if (this.token.token_type !== "{") {
797
- throw new error_1.ParseError("Expecting {", this.lexer.location);
798
- }
799
- this.advance();
800
- let denominator = this.statement({
801
- parse_absolute_value: parse_absolute_value,
802
- unknownCommands: unknownCommands,
803
- });
804
- if (this.token.token_type !== "}") {
805
- throw new error_1.ParseError("Expecting }", this.lexer.location);
806
- }
807
- this.advance();
808
- return ["/", numerator, denominator];
809
- }
810
- baseFactor({ inside_absolute_value = 0, parse_absolute_value = true, allow_absolute_value_closing = false, unknownCommands = "error", } = {}) {
811
- var result = false;
812
- if (this.token.token_type === "MIXED_NUMBER") {
813
- try {
814
- const t = this.token.token_text.split("\\\\frac");
815
- const numberString = t[0].trim();
816
- const number = parseInt(numberString, 10);
817
- const f = this.fraction({});
818
- // this is correct, to convert a mixed number to an improper fraction we have to multiply the demoninator by the whole number and add the result to the numerator
819
- return ["+", number, f];
820
- }
821
- catch (e) {
822
- throw new error_1.ParseError(`Mixed number parsing failed: ${e.message}`);
823
- }
824
- }
825
- if (this.token.token_type === "FRAC") {
826
- return this.fraction({});
827
- }
828
- if (this.token.token_type === "TEXT") {
829
- const text = this.token.original_text.replace(/[[\]\\]/g, "");
830
- this.advance();
831
- return text.toString();
832
- }
833
- if (this.token.token_type === "BEGINENVIRONMENT") {
834
- let environment = /\\begin\s*{\s*([a-zA-Z0-9]+)\s*}/.exec(this.token.token_text)[1];
835
- if (["matrix", "pmatrix", "bmatrix"].includes(environment)) {
836
- let n_rows = 0;
837
- let n_cols = 0;
838
- let all_rows = [];
839
- let row = [];
840
- let n_this_row = 0;
841
- let last_token = this.token.token_type;
842
- this.advance();
843
- //@ts-ignore
844
- while (this.token.token_type !== "ENDENVIRONMENT") {
845
- //@ts-ignore
846
- if (this.token.token_type === "&") {
847
- if (last_token === "&" || last_token === "LINEBREAK") {
848
- // blank entry, let entry be zero
849
- row.push(0);
850
- n_this_row += 1;
851
- }
852
- last_token = this.token.token_type;
853
- this.advance();
854
- //@ts-ignore
855
- }
856
- else if (this.token.token_type === "LINEBREAK") {
857
- if (last_token === "&" || last_token === "LINEBREAK") {
858
- // blank entry, let entry be zero
859
- row.push(0);
860
- n_this_row += 1;
861
- }
862
- all_rows.push(row);
863
- if (n_this_row > n_cols)
864
- n_cols = n_this_row;
865
- n_rows += 1;
866
- n_this_row = 0;
867
- row = [];
868
- last_token = this.token.token_type;
869
- this.advance();
870
- }
871
- else {
872
- if (last_token === "&" ||
873
- last_token === "LINEBREAK" ||
874
- "BEGINENVIRONMENT") {
875
- row.push(this.statement({
876
- parse_absolute_value: parse_absolute_value,
877
- unknownCommands: unknownCommands,
878
- }));
879
- n_this_row += 1;
880
- last_token = " ";
881
- }
882
- else {
883
- throw new error_1.ParseError("Invalid location of " + this.token.original_text, this.lexer.location);
884
- }
885
- }
886
- }
887
- // token is ENDENVIRONMENT
888
- let environment2 = /\\end\s*{\s*([a-zA-Z0-9]+)\s*}/.exec(this.token.token_text)[1];
889
- if (environment2 !== environment) {
890
- throw new error_1.ParseError("Expecting \\end{" + environment + "}", this.lexer.location);
891
- }
892
- // add last row
893
- if (last_token === "&") {
894
- // blank entry, let entry be zero
895
- row.push(0);
896
- n_this_row += 1;
897
- }
898
- all_rows.push(row);
899
- if (n_this_row > n_cols)
900
- n_cols = n_this_row;
901
- n_rows += 1;
902
- this.advance();
903
- // create matrix
904
- // @ts-ignore
905
- result = ["matrix", ["tuple", n_rows, n_cols]];
906
- let body = ["tuple"];
907
- for (let r of all_rows) {
908
- let new_row = ["tuple"].concat(r);
909
- //@ts-ignore
910
- for (let i = r.length; i < n_cols; i += 1)
911
- new_row.push(0);
912
- // @ts-ignore
913
- body.push(new_row);
914
- }
915
- // @ts-ignore
916
- result.push(body);
917
- return result;
918
- }
919
- else {
920
- throw new error_1.ParseError("Unrecognized environment " + environment, this.lexer.location);
921
- }
922
- }
923
- if (this.token.token_type === "NUMBER") {
924
- // @ts-ignore
925
- result = this.token.token_text.replace(/,/g, "");
926
- let removeLeadingZeros = (result) => result.indexOf(".") >= 0
927
- ? result.replace(/^[0]*([0-9])(.*)/, "$1$2")
928
- : result.replace(/0*([1-9]*)/, "$1");
929
- // @ts-ignore
930
- let parsedNumber = result === "0" ? result : removeLeadingZeros(result);
931
- if (parsedNumber.startsWith(".")) {
932
- parsedNumber = "0" + parsedNumber;
933
- }
934
- const number = parseFloat(parsedNumber);
935
- /** trailing zero number ['tzn', number, countOfZeros] */
936
- // @ts-ignore
937
- if (parsedNumber !== number.toString()) {
938
- const p = number.toString();
939
- // @ts-ignore
940
- const sub = parsedNumber
941
- // @ts-ignore
942
- .substring(p.length)
943
- .split("")
944
- .filter((c) => c === "0");
945
- const noOfTrailingZeros = sub.length;
946
- // @ts-ignore
947
- result = ["tzn", number, noOfTrailingZeros];
948
- }
949
- else {
950
- // @ts-ignore
951
- result = number;
952
- }
953
- this.advance();
954
- }
955
- else if (this.token.token_type === "INFINITY") {
956
- // @ts-ignore
957
- result = Infinity;
958
- this.advance();
959
- }
960
- else if (this.token.token_type === "deg") {
961
- // conversion of degrees in radians - angle configuration
962
- const degree = Math.PI / 180;
963
- // @ts-ignore
964
- result = ["*", degree];
965
- this.advance();
966
- }
967
- else if (this.token.token_type === "grad") {
968
- //conversion of gradians in radians - angle configuration
969
- const gradian = Math.PI / 200;
970
- // @ts-ignore
971
- result = ["*", gradian];
972
- this.advance();
973
- }
974
- else if (this.token.token_type === "UNIT") {
975
- // @ts-ignore
976
- result = ["unit", this.token.token_text];
977
- this.advance();
978
- }
979
- else if (this.token.token_type === "SQRT") {
980
- this.advance();
981
- let root = 2;
982
- let parameter;
983
- // @ts-ignore
984
- if (this.token.token_type === "[") {
985
- this.advance();
986
- parameter = this.statement({
987
- parse_absolute_value: parse_absolute_value,
988
- unknownCommands: unknownCommands,
989
- });
990
- if (this.token.token_type !== "]") {
991
- throw new error_1.ParseError("Expecting ]", this.lexer.location);
992
- }
993
- this.advance();
994
- root = parameter;
995
- }
996
- // @ts-ignore
997
- if (this.token.token_type == "{") {
998
- this.advance();
999
- parameter = this.statement({
1000
- parse_absolute_value: parse_absolute_value,
1001
- unknownCommands: unknownCommands,
1002
- });
1003
- // @ts-ignore
1004
- if (this.token.token_type !== "}") {
1005
- throw new error_1.ParseError("Expecting }", this.lexer.location);
1006
- }
1007
- this.advance();
1008
- }
1009
- else {
1010
- parameter = this.statement({
1011
- parse_absolute_value: parse_absolute_value,
1012
- unknownCommands: unknownCommands,
1013
- });
1014
- }
1015
- // @ts-ignore
1016
- if (root === 2)
1017
- result = ["apply", "sqrt", parameter];
1018
- // @ts-ignore
1019
- else
1020
- result = ["^", parameter, ["/", 1, root]];
1021
- }
1022
- else if (this.token.token_type === "LOG" ||
1023
- this.token.token_type === "LN") {
1024
- // function log(x) in JS returns ln(x)
1025
- let base = this.token.token_type === "LOG" ? 10 : "e";
1026
- let parameter;
1027
- this.advance();
1028
- // @ts-ignore
1029
- if (this.token.token_type === "_") {
1030
- this.advance();
1031
- // @ts-ignore
1032
- if (this.token.token_type === "{") {
1033
- this.advance();
1034
- parameter = this.statement({
1035
- parse_absolute_value: parse_absolute_value,
1036
- unknownCommands: unknownCommands,
1037
- });
1038
- if (this.token.token_type !== "}") {
1039
- throw new error_1.ParseError("Expecting }", this.lexer.location);
1040
- }
1041
- this.advance();
1042
- base = parameter;
1043
- }
1044
- }
1045
- // @ts-ignore
1046
- if (this.token.token_type == "(") {
1047
- this.advance();
1048
- parameter = this.statement({
1049
- parse_absolute_value: parse_absolute_value,
1050
- unknownCommands: unknownCommands,
1051
- });
1052
- if (this.token.token_type !== ")") {
1053
- throw new error_1.ParseError("Expecting )", this.lexer.location);
1054
- }
1055
- this.advance();
1056
- }
1057
- else {
1058
- parameter = this.token.token_text;
1059
- this.advance();
1060
- }
1061
- // @ts-ignore
1062
- if (base === 10)
1063
- result = ["apply", "log", ["tuple", parameter, base]];
1064
- // @ts-ignore
1065
- else if (base === "e")
1066
- result = ["apply", "log", parameter];
1067
- // @ts-ignore
1068
- else
1069
- result = ["apply", "log", ["tuple", parameter, base]];
1070
- }
1071
- else if (this.token.token_type === "VAR" ||
1072
- this.token.token_type === "LATEXCOMMAND" ||
1073
- this.token.token_type === "VARMULTICHAR") {
1074
- // @ts-ignore
1075
- result = this.token.token_text;
1076
- if (this.token.token_type === "LATEXCOMMAND") {
1077
- // @ts-ignore
1078
- result = result.slice(1);
1079
- const isKnownCommand =
1080
- // @ts-ignore
1081
- this.opts.appliedFunctionSymbols.includes(result) ||
1082
- // @ts-ignore
1083
- this.opts.functionSymbols.includes(result) ||
1084
- // @ts-ignore
1085
- this.opts.allowedLatexSymbols.includes(result);
1086
- if (!isKnownCommand) {
1087
- if (this.unknownCommandBehavior === "error") {
1088
- throw new error_1.ParseError("Unrecognized latex command " + this.token.original_text, this.lexer.location);
1089
- }
1090
- }
1091
- }
1092
- else if (this.token.token_type === "VARMULTICHAR") {
1093
- // strip out name of variable from \var command
1094
- // @ts-ignore
1095
- result = /\\var\s*\{\s*([a-zA-Z0-9]+)\s*\}/.exec(result)[1];
1096
- }
1097
- if (
1098
- // @ts-ignore
1099
- this.opts.appliedFunctionSymbols.includes(result) ||
1100
- // @ts-ignore
1101
- this.opts.functionSymbols.includes(result)) {
1102
- let must_apply = false;
1103
- // @ts-ignore
1104
- if (this.opts.appliedFunctionSymbols.includes(result))
1105
- must_apply = true;
1106
- this.advance();
1107
- // @ts-ignore
1108
- if (this.token.token_type === "_") {
1109
- this.advance();
1110
- let subresult = this.baseFactor({
1111
- parse_absolute_value: parse_absolute_value,
1112
- });
1113
- // since baseFactor could return false, must check
1114
- if (subresult === false) {
1115
- if (this.token.token_type === "EOF") {
1116
- throw new error_1.ParseError("Unexpected end of input", this.lexer.location);
1117
- }
1118
- else {
1119
- throw new error_1.ParseError("Invalid location of '" + this.token.original_text + "'", this.lexer.location);
1120
- }
1121
- }
1122
- // @ts-ignore
1123
- result = ["_", result, subresult];
1124
- }
1125
- // @ts-ignore
1126
- while (this.token.token_type === "'") {
1127
- // @ts-ignore
1128
- result = ["prime", result];
1129
- this.advance();
1130
- }
1131
- // @ts-ignore
1132
- if (this.token.token_type === "^") {
1133
- this.advance();
1134
- // @ts-ignore
1135
- result = [
1136
- "^",
1137
- result,
1138
- this.factor({ parse_absolute_value: parse_absolute_value }),
1139
- ];
1140
- }
1141
- // @ts-ignore
1142
- if (this.token.token_type === "{" || this.token.token_type === "(") {
1143
- let expected_right;
1144
- if (this.token.token_type === "{")
1145
- expected_right = "}";
1146
- else
1147
- expected_right = ")";
1148
- this.advance();
1149
- let parameters = this.statement_list();
1150
- if (this.token.token_type !== expected_right) {
1151
- throw new error_1.ParseError("Expecting " + expected_right, this.lexer.location);
1152
- }
1153
- this.advance();
1154
- // @ts-ignore
1155
- result = ["apply", result, parameters];
1156
- }
1157
- else {
1158
- // if was an applied function symbol,
1159
- // cannot omit argument
1160
- if (must_apply) {
1161
- // @ts-ignore
1162
- if (!this.opts.allowSimplifiedFunctionApplication)
1163
- throw new error_1.ParseError("Expecting ( after function", this.lexer.location);
1164
- // if allow simplied function application
1165
- // let the argument be the next factor
1166
- // @ts-ignore
1167
- result = [
1168
- "apply",
1169
- result,
1170
- this.factor({ parse_absolute_value: parse_absolute_value }),
1171
- ];
1172
- }
1173
- }
1174
- }
1175
- else {
1176
- this.advance();
1177
- }
1178
- }
1179
- else if (this.token.token_type === "(" ||
1180
- this.token.token_type === "[" ||
1181
- this.token.token_type === "{" ||
1182
- this.token.token_type === "LBRACE") {
1183
- let token_left = this.token.token_type;
1184
- let expected_right, other_right;
1185
- if (this.token.token_type === "(") {
1186
- expected_right = ")";
1187
- other_right = "]";
1188
- }
1189
- else if (this.token.token_type === "[") {
1190
- expected_right = "]";
1191
- other_right = ")";
1192
- }
1193
- else if (this.token.token_type === "{") {
1194
- expected_right = "}";
1195
- other_right = null;
1196
- }
1197
- else {
1198
- expected_right = "RBRACE";
1199
- other_right = null;
1200
- }
1201
- this.advance();
1202
- // @ts-ignore
1203
- result = this.statement_list();
1204
- let n_elements = 1;
1205
- if (result[0] === "list") {
1206
- // @ts-ignore
1207
- n_elements = result.length - 1;
1208
- }
1209
- if (this.token.token_type !== expected_right) {
1210
- if (n_elements !== 2 || other_right === null) {
1211
- throw new error_1.ParseError("Expecting " + expected_right, this.lexer.location);
1212
- }
1213
- else if (this.token.token_type !== other_right) {
1214
- throw new error_1.ParseError("Expecting ) or ]", this.lexer.location);
1215
- }
1216
- // half-open interval
1217
- result[0] = "list";
1218
- // @ts-ignore
1219
- result = ["interval", result];
1220
- let closed;
1221
- if (token_left === "(")
1222
- closed = ["list", false, true];
1223
- else
1224
- closed = ["list", true, false];
1225
- // @ts-ignore
1226
- result.push(closed);
1227
- }
1228
- else if (n_elements >= 2) {
1229
- if (token_left === "(" || token_left === "{") {
1230
- result[0] = "list";
1231
- }
1232
- else if (token_left === "[") {
1233
- result[0] = "list";
1234
- }
1235
- else {
1236
- result[0] = "set";
1237
- }
1238
- }
1239
- else if (token_left === "LBRACE") {
1240
- if (result[0] === "|" || result[0] === ":") {
1241
- // @ts-ignore
1242
- result = ["set", result]; // set builder notation
1243
- }
1244
- else {
1245
- // @ts-ignore
1246
- result = ["set", result]; // singleton set
1247
- }
1248
- }
1249
- this.advance();
1250
- }
1251
- else if (this.token.token_type[0] === "|" &&
1252
- parse_absolute_value &&
1253
- (inside_absolute_value === 0 ||
1254
- !allow_absolute_value_closing ||
1255
- this.token.token_type[1] === "L")) {
1256
- // allow the opening of an absolute value here if either
1257
- // - we aren't already inside an absolute value (inside_absolute_value==0),
1258
- // - we don't allows an absolute value closing, or
1259
- // - the | was marked as a left
1260
- // otherwise, skip this token so that will drop out the factor (and entire statement)
1261
- // to where the absolute value will close
1262
- inside_absolute_value += 1;
1263
- this.advance();
1264
- result = this.statement({
1265
- inside_absolute_value: inside_absolute_value,
1266
- unknownCommands: unknownCommands,
1267
- });
1268
- // @ts-ignore
1269
- result = ["apply", "abs", result];
1270
- if (this.token.token_type !== "|") {
1271
- throw new error_1.ParseError("Expecting |", this.lexer.location);
1272
- }
1273
- this.advance();
1274
- }
1275
- if (this.token.token_type === "_") {
1276
- if (result === false) {
1277
- throw new error_1.ParseError("Invalid location of _", this.lexer.location);
1278
- }
1279
- this.advance();
1280
- let subresult = this.baseFactor({
1281
- parse_absolute_value: parse_absolute_value,
1282
- });
1283
- if (subresult === false) {
1284
- // @ts-ignore
1285
- if (this.token.token_type === "EOF") {
1286
- throw new error_1.ParseError("Unexpected end of input", this.lexer.location);
1287
- }
1288
- else {
1289
- throw new error_1.ParseError("Invalid location of '" + this.token.original_text + "'", this.lexer.location);
1290
- }
1291
- }
1292
- return ["_", result, subresult];
1293
- }
1294
- return result;
1295
- }
1296
- leibniz_notation() {
1297
- // attempt to find and return a derivative in Leibniz notation
1298
- // if unsuccessful, return false
1299
- var result = this.token.token_text;
1300
- let deriv_symbol = "";
1301
- let n_deriv = 1;
1302
- let var1 = "";
1303
- let var2s = [];
1304
- let var2_exponents = [];
1305
- if (this.token.token_type === "LATEXCOMMAND" &&
1306
- result.slice(1) === "partial")
1307
- deriv_symbol = "∂";
1308
- else if (this.token.token_type === "VAR" && result === "d")
1309
- deriv_symbol = "d";
1310
- else
1311
- return false;
1312
- // since have just a d or ∂
1313
- // one option is that have a ^ followed by an integer next possibly in {}
1314
- this.advance();
1315
- // @ts-ignore
1316
- if (this.token.token_type === "^") {
1317
- // so far have d or ∂ followed by ^
1318
- // must be followed by an integer
1319
- this.advance();
1320
- let in_braces = false;
1321
- if (this.token.token_type === "{") {
1322
- in_braces = true;
1323
- this.advance();
1324
- }
1325
- if (this.token.token_type !== "NUMBER") {
1326
- return false;
1327
- }
1328
- n_deriv = parseFloat(this.token.token_text);
1329
- if (!Number.isInteger(n_deriv)) {
1330
- return false;
1331
- }
1332
- // found integer,
1333
- // if in braces, require }
1334
- if (in_braces) {
1335
- this.advance();
1336
- if (this.token.token_type !== "}") {
1337
- return false;
1338
- }
1339
- }
1340
- this.advance();
1341
- }
1342
- // since have a d or ∂, optionally followed by ^ and integer
1343
- // next we must have:
1344
- // a VAR, a VARMULTICHAR, or a LATEXCOMMAND that is in allowedLatexSymbols
1345
- if (this.token.token_type === "VAR")
1346
- var1 = this.token.token_text;
1347
- // @ts-ignore
1348
- else if (this.token.token_type === "VARMULTICHAR") {
1349
- // strip out name of variable from \var command
1350
- var1 = /\\var\s*\{\s*([a-zA-Z0-9]+)\s*\}/.exec(this.token.token_text)[1];
1351
- }
1352
- else if (this.token.token_type === "LATEXCOMMAND") {
1353
- result = this.token.token_text.slice(1);
1354
- // @ts-ignore
1355
- if (this.opts.allowedLatexSymbols.includes(result))
1356
- var1 = result;
1357
- else
1358
- return false;
1359
- }
1360
- // Finished numerator.
1361
- // Next need a } and {
1362
- this.advance();
1363
- // @ts-ignore
1364
- if (this.token.token_type !== "}") {
1365
- return false;
1366
- }
1367
- this.advance();
1368
- if (this.token.token_type !== "{") {
1369
- return false;
1370
- }
1371
- else {
1372
- this.advance();
1373
- }
1374
- // In denominator now
1375
- // find sequence of
1376
- // derivative symbol followed by
1377
- // - a VAR, a VARMULTICHAR, or a LATEXCOMMAND that is in allowedLatexSymbols
1378
- // optionally followed by a ^ and an integer
1379
- // End when sum of exponents meets or exceeds n_deriv
1380
- let exponent_sum = 0;
1381
- while (true) {
1382
- // next must be
1383
- // - a VAR equal to deriv_symbol="d" or \partial when deriv_symbol = "∂"
1384
- if (!((deriv_symbol === "d" &&
1385
- this.token.token_type === "VAR" &&
1386
- this.token.token_text === "d") ||
1387
- (deriv_symbol === "∂" &&
1388
- this.token.token_type === "LATEXCOMMAND" &&
1389
- this.token.token_text.slice(1) === "partial"))) {
1390
- return false;
1391
- }
1392
- // followed by
1393
- // - a VAR, a VARMULTICHAR, or a LATEXCOMMAND that is in allowedLatexSymbols
1394
- this.advance();
1395
- if (this.token.token_type === "VAR")
1396
- var2s.push(this.token.token_text);
1397
- else if (this.token.token_type === "VARMULTICHAR") {
1398
- // strip out name of variable from \var command
1399
- var2s.push(/\\var\s*\{\s*([a-zA-Z0-9]+)\s*\}/.exec(this.token.token_text)[1]);
1400
- }
1401
- else if (this.token.token_type === "LATEXCOMMAND") {
1402
- let r = this.token.token_text.slice(1);
1403
- // @ts-ignore
1404
- if (this.allowedLatexSymbols.includes(r))
1405
- var2s.push(r);
1406
- else {
1407
- return false;
1408
- }
1409
- }
1410
- else {
1411
- return false;
1412
- }
1413
- // have derivative and variable, now check for optional ^ followed by number
1414
- let this_exponent = 1;
1415
- this.advance();
1416
- if (this.token.token_type === "^") {
1417
- this.advance();
1418
- let in_braces = false;
1419
- if (this.token.token_type === "{") {
1420
- in_braces = true;
1421
- this.advance();
1422
- }
1423
- if (this.token.token_type !== "NUMBER") {
1424
- return false;
1425
- }
1426
- this_exponent = parseFloat(this.token.token_text);
1427
- if (!Number.isInteger(this_exponent)) {
1428
- return false;
1429
- }
1430
- // if in braces, require }
1431
- if (in_braces) {
1432
- this.advance();
1433
- if (this.token.token_type !== "}") {
1434
- return false;
1435
- }
1436
- }
1437
- this.advance();
1438
- }
1439
- var2_exponents.push(this_exponent);
1440
- exponent_sum += this_exponent;
1441
- if (exponent_sum > n_deriv) {
1442
- return false;
1443
- }
1444
- // possibly found derivative
1445
- if (exponent_sum === n_deriv) {
1446
- // next token must be a }
1447
- if (this.token.token_type !== "}") {
1448
- return false;
1449
- }
1450
- // found derivative!
1451
- this.advance();
1452
- let result_name = "derivative_leibniz";
1453
- if (deriv_symbol === "∂")
1454
- result_name = "partial_" + result_name;
1455
- // @ts-ignore
1456
- result = [result_name];
1457
- // @ts-ignore
1458
- if (n_deriv === 1)
1459
- result.push(var1);
1460
- // @ts-ignore
1461
- else
1462
- result.push(["tuple", var1, n_deriv]);
1463
- let r2 = [];
1464
- for (let i = 0; i < var2s.length; i += 1) {
1465
- if (var2_exponents[i] === 1)
1466
- r2.push(var2s[i]);
1467
- else
1468
- r2.push(["tuple", var2s[i], var2_exponents[i]]);
1469
- }
1470
- r2 = ["tuple"].concat(r2);
1471
- // @ts-ignore
1472
- result.push(r2);
1473
- return result;
1474
- }
1475
- }
1476
- }
1477
- }
1478
- exports.LatexToAst = LatexToAst;
1479
- //# sourceMappingURL=latex-to-ast.js.map