Skip to content

Commit e431116

Browse files
committed
feature: next gen MathJSON, first pass, WIP
1 parent 1433bef commit e431116

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+9705
-1870
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ examples/basic/index.debug.html
1414

1515
# OS generated files #
1616
######################
17+
**/.DS_Store
1718
.DS_Store
1819
.DS_Store?
1920
._*

.npmignore

-3
This file was deleted.

.vscode/launch.json

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"runtimeArgs": [
1212
"--inspect-brk",
1313
"${workspaceRoot}/node_modules/.bin/jest",
14+
"test/math-json.test.ts",
1415
"--runInBand"
1516
],
1617
"console": "integratedTerminal",

dist/math-json/domains.d.ts

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* 0.53.2 */export declare const DOMAIN_NONE = 0;
2+
export declare const DOMAIN_ZERO = 1;
3+
export declare const DOMAIN_PRIME_NUMBER = 256;
4+
export declare const DOMAIN_POSITIVE_INTEGER: number;
5+
export declare const DOMAIN_NEGATIVE_INTEGER = 4;
6+
export declare const DOMAIN_EVEN_NUMBER: number;
7+
export declare const DOMAIN_INTEGER: number;
8+
export declare const DOMAIN_POSITIVE_REAL: number;
9+
export declare const DOMAIN_NEGATIVE_REAL: number;
10+
export declare const DOMAIN_REAL: number;
11+
export declare const DOMAIN_POSITIVE_IMAGINARY = 32;
12+
export declare const DOMAIN_NEGATIVE_IMAGINARY = 64;
13+
export declare const DOMAIN_COMPLEX: number;
14+
export declare const DOMAIN_FINITE_NUMBER = 512;
15+
export declare const DOMAIN_NUMBER = 4095;
16+
export declare const DOMAIN_BOOLEAN = 4096;
17+
export declare const DOMAIN_SYMBOL = 8192;
18+
export declare const DOMAIN_STRING = 16384;
19+
/** Functions, except those used to represent list-like data structures and rules */
20+
export declare const DOMAIN_FUNCTION = 32768;
21+
export declare const DOMAIN_RULE = 65536;
22+
export declare const DOMAIN_VECTOR = 2097152;
23+
export declare const DOMAIN_MATRIX = 4194304;
24+
export declare const DOMAIN_ARRAY: number;
25+
export declare const DOMAIN_TABLE = 16777216;
26+
export declare const DOMAIN_DICTIONARY = 2097152;
27+
export declare const DOMAIN_SET: number;
28+
export declare const DOMAIN_LIST: number;
29+
export declare const DOMAIN_ANY_FUNCTION: number;
30+
export declare const DOMAIN_EXPRESSION: number;
31+
export declare const DOMAIN_ANY = 4503599627370495;
32+
/**
33+
*
34+
* - "any" any domain, no checking is done
35+
* - "N" Q28920044 Natural numbers (positive integers): 1, 2, 3, 4, ...
36+
* - "N0" Q28920052 Non-negative integers: 0, 1, 2, 3, 4
37+
* - "Z*" Non-Zero integers: -2, -1, 1, 2, 3, ...
38+
* - "Z" Q47007735 Integers: ...-3, -2, -1, 0, 1, 2, 3, 4, ...
39+
* - "R-": Q200227 Negative real number <0
40+
* - "R+" Q3176558 Positive real numbers (JS float) >0
41+
* - "R0-": Q47341108 Non-positive real number <= 0
42+
* - "R0+" Q13896108 Non-negative real numbers (JS float) >=0
43+
* - "R" Real numbers (JS float)
44+
* - "I" Q47310259 Imaginary numbers (complex numbers on the imaginary line)
45+
* - "C" Q26851286 Complex numbers
46+
* - "boolean" JS boolean
47+
* - "symbol" JS string
48+
* - "string" JS string
49+
* - "list" JS array
50+
* - "array" JS array
51+
* - "expression" Math JSON node
52+
* - "table" JS object literal, key (string)/ value (any) pairs
53+
*/
54+
export declare const DOMAINS: {
55+
[domain: string]: number;
56+
};
57+
export declare type Domain = keyof typeof DOMAINS;

dist/math-json/public.d.ts

+225
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/* 0.53.2 */import { Domain } from './domains';
2+
export declare type FunctionDefinition = {
3+
/**
4+
* A short string indicating an entry in a wikibase. For example
5+
* `"Q167"` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
6+
* for the Pi constant.
7+
*/
8+
wikidata?: string;
9+
/** The domain of the result */
10+
domain?: Domain;
11+
/** If true, the function will be automatically mapped to a list argument */
12+
isListable?: boolean;
13+
/** If true, [f, [f, a], b] is equivalent to [f, a, b] */
14+
isAssociative?: boolean;
15+
/** If true, [f, a, b] is equivalent to [f, b, a] */
16+
isCommutative?: boolean;
17+
/** If true, [f, [f, a]] is equivalent to [f, a] */
18+
isIdempotent?: boolean;
19+
/** If true, invoking the function wiht a given set of arguments will
20+
* always return the same value, i.e. 'sin()' is pure, 'random()' isn't.
21+
* This is used to cache the result of the function.
22+
*/
23+
isPure?: boolean;
24+
/**
25+
* - **'all'**: The arguments will not be evaluated and will be passed as is
26+
* - **'none'**: eval() is invoked for each argument.
27+
* The function will be passed the result of the evaluation
28+
* - **'first'**: The first argument is not evaluated, the others are
29+
* - **'rest'**: The first argument is evaluated, the others aren't
30+
*/
31+
hold?: 'none' | 'all' | 'first' | 'rest';
32+
/**
33+
* Number of arguments, or minimum or minimum and maximum number of arguments.
34+
*
35+
* These are the arguments in the expr representation (i.e. ["f", 1, 2])
36+
* and if `requiredLatexArg` is 0 (or undefined), these are also the expected
37+
* arguments in the latex stream, i.e. "f(1, 2)".
38+
*
39+
*/
40+
argCount?: number | [number] | [number, number];
41+
argDomain?: Domain[];
42+
};
43+
export declare type SymbolDefinition = {
44+
/**
45+
* If true the value of the symbol is constant
46+
* If false, the symbol is a variable
47+
*/
48+
isConstant: boolean;
49+
/**
50+
* A short string indicating an entry in a wikibase. For example
51+
* `"Q167"` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
52+
* for the Pi constant.
53+
*/
54+
wikidata?: string;
55+
domain?: Domain;
56+
value?: Expression;
57+
unit?: Expression;
58+
};
59+
/**
60+
* A dictionary maps a MathJSON name to a defition.
61+
*
62+
* A name can be a symbol name, as in the expression `"pi"`,
63+
* or the name of a function: "add" in the expression `["add", 2, 3]`.
64+
*
65+
* The name can be an arbitrary string of Unicode characters, however
66+
* the following conventions are recommended:
67+
*
68+
* - Use only letters, digits and `-`, and the first character should be
69+
* a letter: `/^[a-zA-Z][a-zA-Z0-9-]* /`
70+
* - Functions and symbols should start with a lowercase letter
71+
* - During parsing, camel-case names are converted to kebab-case, so that
72+
* `"polynomialFactor"` becomes `"polynomial-factor"`
73+
*
74+
*/
75+
export declare type Dictionary = {
76+
[name: string]: SymbolDefinition | FunctionDefinition;
77+
};
78+
/**
79+
* * `unknown-symbol`: a symbol was encountered which does not have a
80+
* definition.
81+
*
82+
* * `unknown-operator`: a presumed operator was encountered which does not
83+
* have a definition.
84+
*
85+
* * `unknown-function`: a latex command was encountered which does not
86+
* have a definition.
87+
*
88+
* * `unbalanced-braces`: some latex braces (`{`, `}`) were not balanced
89+
*
90+
* * `unexpected-superscript`: a superscript was encountered in an unexpected
91+
* context, or no `powerFunction` was defined. By default, superscript can
92+
* be applied to numbers, symbols or expressions, but not to operators (e.g.
93+
* `2+^34`) or to punctuation.
94+
*
95+
* * `unexpected-subscript`: a subscript was encountered in an unexpected
96+
* context or no 'subscriptFunction` was defined. By default, subscripts
97+
* are not expected on numbers, operators or symbols. Some commands (e.g. `\sum`)
98+
* do expected a subscript.
99+
*
100+
* * `unexpected-sequence`: some adjacents elements were encountered ( for
101+
* example `xy`), but no `invisibleOperator` is defined, therefore the elements
102+
* can't be combined. The default `invisibleOperator` is `multiply`, but you
103+
* can also use `list`.
104+
*
105+
* * `expected-argument`: a Latex command that requires one or more argument
106+
* was encountered without the required arguments.
107+
*
108+
* * `expected-operand`: an operator was encountered without its required
109+
* operands.
110+
*
111+
* * `non-associative-operator`: an operator which is not associative was
112+
* encountered in an associative context, for example: 'a < b < c' (assuming
113+
* `<` is defined as non-associative)
114+
*
115+
* * `postfix-operator-requires-one-argument`: a postfix operator which requires
116+
* a single argument was encountered with no arguments or more than one argument
117+
*
118+
* * `prefix-operator-requires-one-argument`: a prefix operator which requires
119+
* a single argument was encountered with no arguments or more than one argument
120+
*
121+
*/
122+
export declare type ErrorCode = 'expected-argument' | 'unexpected-argument' | 'expected-operator' | 'expected-operand' | 'invalid-name' | 'unknown-symbol' | 'unknown-operator' | 'unknown-function' | 'unknown-command' | 'unbalanced-braces' | 'unbalanced-matchfix-operator' | 'unexpected-superscript' | 'unexpected-subscript' | 'unexpected-sequence' | 'non-associative-operator' | 'function-has-too-many-arguments' | 'function-has-too-few-arguments' | 'operator-requires-one-operand' | 'infix-operator-requires-two-operands' | 'prefix-operator-requires-one-operand' | 'postfix-operator-requires-one-operand' | 'associative-function-has-too-few-arguments' | 'commutative-function-has-too-few-arguments' | 'listable-function-has-too-few-arguments' | 'hold-first-function-has-too-few-arguments' | 'hold-rest-function-has-too-few-arguments' | 'syntax-error';
123+
export declare type Attributes = {
124+
/** A human readable string to annotate an expression, since JSON does not
125+
* allow comments in its encoding */
126+
comment?: string;
127+
/** A human readable string that can be used to indicate a syntax error or
128+
*other problem when parsing or evaluating an expression.
129+
*/
130+
error?: string;
131+
/** A visual representation in LaTeX of the expression. This can be useful
132+
to preserve non-semantic details, for example parentheses in an expression
133+
or styling attributes */
134+
latex?: string;
135+
/**
136+
* A short string indicating an entry in a wikibase. For example
137+
* `"Q167"` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
138+
* for the Pi constant.
139+
*/
140+
wikidata?: string;
141+
/** A base URL for the `wikidata` key. A full URL can be produced by
142+
concatenating this key with the `wikidata` key. This key applies to this
143+
node and all its children. The default value is
144+
"https://www.wikidata.org/wiki/"
145+
*/
146+
wikibase?: string;
147+
/** A short string indicating an entry in an OpenMath Content
148+
Dictionary. For example: `arith1/#abs`. */
149+
openmathSymbol?: string;
150+
/** A base URL for an OpenMath content dictionary. This key applies to this
151+
node and all its children. The default value is
152+
"http://www.openmath.org/cd".
153+
*/
154+
openmathCd?: string;
155+
};
156+
export declare type MathJsonBasicNumber = 'NaN' | '-Infinity' | '+Infinity' | string;
157+
export declare type MathJsonRealNumber = {
158+
num: MathJsonBasicNumber;
159+
} & Attributes;
160+
export declare type MathJsonSymbol = {
161+
sym: string;
162+
} & Attributes;
163+
export declare type MathJsonFunction = {
164+
fn: Expression[];
165+
} & Attributes;
166+
export declare type Expression = MathJsonRealNumber | number | MathJsonSymbol | string | MathJsonFunction | (Expression | string | null)[];
167+
/**
168+
* A given mathematical expression can be represented in multiple equivalent
169+
* ways as a MathJSON expression. `Form` is used to specify a
170+
* representation:
171+
* - **`'full'`**: only transformations applied are those necessary to make it
172+
* valid JSON (for example making sure that `Infinity` and `NaN` are
173+
* represented as strings)
174+
* - **`'flatten-associative'`**: associative functions are combined, e.g.
175+
* f(f(a, b), c) -> f(a, b, c)
176+
* - **`'sorted'`**: the arguments of commutative functions are sorted such that:
177+
* - numbers are first, sorted numerically
178+
* - complex numbers are next, sorted numerically by imaginary value
179+
* - symbols are next, sorted lexicographically
180+
* - `add` functions are next
181+
* - `multiply` functions are next
182+
* - `power` functions are next, sorted by their first argument,
183+
* then by their second argument
184+
* - other functions follow, sorted lexicographically
185+
* - **`'stripped-metadata'`**: any metadata associated with elements of the
186+
* expression is removed.
187+
* - *`'canonical-add'`**: `addition of 0 is simplified, associativity rules
188+
* are applied, unnecessary groups are moved, single argument 'add' are simplified
189+
* - *`'canonical-divide'`**: `divide` is replaced with `multiply` and `power',
190+
* division by 1 is simplified,
191+
* - *`'canonical-exp'`**: `exp` is replaced with `power`
192+
* - *`'canonical-multiply'`**: multiplication by 1 or -1 is simplified
193+
* - *`'canonical-power'`**: `power` with a first or second argument of 1 is
194+
* simplified
195+
* - *`'canonical-negate'`**: real or complex number is replaced by the
196+
* negative of that number. Negation of negation is simplified.
197+
* - *`'canonical-number'`**: complex numbers with no imaginary compnents are
198+
* simplified
199+
* - *`'canonical-root'`**: `root` is replaced with `power`
200+
* - *`'canonical-subtract'`**: `subtract` is replaced with `add` and `negate`
201+
* - **`'canonical'`**: the following transformations are performed, in this order:
202+
* - 'canonical-number', // -> simplify number
203+
* - 'canonical-exp', // -> power
204+
* - 'canonical-root', // -> power, divide
205+
* - 'canonical-subtract', // -> add, negate, multiply,
206+
* - 'canonical-divide', // -> multiply, power
207+
* - 'canonical-power', // simplify power
208+
* - 'canonical-multiply', // -> multiply, power
209+
* - 'canonical-negate', // simplify negate
210+
* - 'canonical-add', // simplify add
211+
* - 'flatten', // simplify associative, idempotent and groups
212+
* - 'sorted',
213+
* - 'full',
214+
*/
215+
export declare type Form = 'canonical' | 'canonical-add' | 'canonical-divide' | 'canonical-exp' | 'canonical-list' | 'canonical-multiply' | 'canonical-power' | 'canonical-negate' | 'canonical-number' | 'canonical-root' | 'canonical-subtract' | 'flatten' | 'full' | 'sorted' | 'stripped-metadata' | 'sum-product';
216+
export declare type DictionaryCategory = 'algebra' | 'arithmetic' | 'calculus' | 'complex' | 'combinatorics' | 'dimensions' | 'intervals' | 'linear-algebra' | 'lists' | 'logic' | 'numeric' | 'quantifiers' | 'physics' | 'polynomials' | 'relations' | 'sets' | 'statistics' | 'core' | 'transcendentals' | 'trigonometry' | 'rounding' | 'units';
217+
/**
218+
* Return a dictionary suitable for the specified category, or `"all"`
219+
* for all categories (`"arithmetic"`, `"algebra"`, etc...).
220+
*
221+
* The dictionary defines how the symbols and function names in a MathJSON
222+
* expression should be interpreted, i.e. how to evaluate and manipulate them.
223+
*
224+
*/
225+
export declare function getDefaultDictionary(domain: DictionaryCategory | 'all'): Dictionary;

dist/mathlive.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/mathlive.mjs

+1-1
Large diffs are not rendered by default.
File renamed without changes.

dist/config.d.ts dist/public/config.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* 0.53.2 */import { ErrorListener, MacroDictionary, ParseMode } from './core';
1+
/* 0.53.2 */import { ErrorListener, MacroDictionary, ParseMode, ParserErrorCode, MathfieldErrorCode } from './core';
22
import type { Mathfield } from './mathfield';
33
import type { Selector } from './commands';
44
/**
@@ -634,7 +634,7 @@ export declare type MathfieldConfig = LayoutOptions & EditingOptions & Localizat
634634
* This could also be another kind of error, such as an invalid keybinding.
635635
*
636636
*/
637-
onError?: ErrorListener;
637+
onError?: ErrorListener<ParserErrorCode | MathfieldErrorCode>;
638638
/**
639639
* This function provides the option of substituting the focusable DOM
640640
* element used to capture keyboard input.

dist/core.d.ts dist/public/core.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export declare type ParseMode = 'math' | 'text' | 'command';
3131
*/
3232
export declare type ParserErrorCode = 'unknown-command' | 'invalid-command' | 'unbalanced-braces' | 'unknown-environment' | 'unbalanced-environment' | 'unbalanced-mode-shift' | 'missing-argument' | 'too-many-infix-commands' | 'unexpected-command-in-string' | 'missing-unit' | 'unexpected-delimiter' | 'unexpected-token' | 'unexpected-end-of-string' | 'improper-alphabetic-constant';
3333
export declare type MathfieldErrorCode = 'invalid-keybinding' | 'font-not-found';
34-
export declare type ErrorListener = (err: {
35-
code: ParserErrorCode | MathfieldErrorCode;
34+
export declare type ErrorListener<T> = (err: {
35+
code: T;
3636
arg?: string;
3737
latex?: string;
3838
before?: string;
File renamed without changes.

dist/mathlive.d.ts dist/public/mathlive.d.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
*/
2020
import { Mathfield } from './mathfield';
2121
import { MathfieldConfig, TextToSpeechOptions } from './config';
22-
import { MacroDictionary, ErrorListener } from './core';
22+
import { MacroDictionary, ErrorListener, ParserErrorCode } from './core';
23+
import { ErrorCode as MathJsonErrorCode } from '../math-json/public';
2324
export { Mathfield };
2425
export { MathfieldConfig };
2526
/**
@@ -60,7 +61,7 @@ export declare function latexToMarkup(text: string, options: {
6061
mathstyle?: 'displaystyle' | 'textstyle';
6162
letterShapeStyle?: 'tex' | 'french' | 'iso' | 'upright' | 'auto';
6263
macros?: MacroDictionary;
63-
onError?: ErrorListener;
64+
onError?: ErrorListener<ParserErrorCode>;
6465
}): string;
6566
/**
6667
* Convert a DOM element into an editable mathfield.
@@ -98,7 +99,7 @@ export declare function makeMathField(element: HTMLElement | string, config: Mat
9899
export declare function latexToMathML(latex: string, options: {
99100
macros?: MacroDictionary;
100101
generateID: boolean;
101-
onError?: ErrorListener;
102+
onError?: ErrorListener<ParserErrorCode>;
102103
}): string;
103104
/**
104105
* Convert a LaTeX string to a {@tutorial math-json | MathJSON } Abstract Syntax Tree
@@ -117,7 +118,7 @@ export declare function latexToMathML(latex: string, options: {
117118
*/
118119
export declare function latexToAST(latex: string, options?: {
119120
macros?: MacroDictionary;
120-
onError?: ErrorListener;
121+
onError?: ErrorListener<ParserErrorCode | MathJsonErrorCode>;
121122
}): any;
122123
/**
123124
* Converts a {@tutorial math-json | MathJSON } Abstract Syntax Tree to a LaTeX string.
@@ -167,7 +168,7 @@ export declare function astToLatex(mathJson: any, options?: {
167168
*/
168169
export declare function latexToSpeakableText(latex: string, options: TextToSpeechOptions & {
169170
macros?: MacroDictionary;
170-
onError?: ErrorListener;
171+
onError?: ErrorListener<ParserErrorCode>;
171172
}): string;
172173
export declare type AutoRenderOptions = {
173174
/** Namespace that is added to `data-` attributes to avoid collisions with other libraries.
File renamed without changes.

0 commit comments

Comments
 (0)