docx 9.7.2 → 9.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/math.mjs ADDED
@@ -0,0 +1,2537 @@
1
+ import { BuilderElement, Math as Math$1, Math as Math$2, MathAngledBrackets, MathCurlyBrackets, MathDegree, MathDenominator, MathFraction, MathFraction as MathFraction$1, MathFunction, MathFunction as MathFunction$1, MathFunctionName, MathFunctionProperties, MathIntegral, MathLimit, MathLimitLower, MathLimitLower as MathLimitLower$1, MathLimitUpper, MathLimitUpper as MathLimitUpper$1, MathNumerator, MathPreSubSuperScript, MathRadical, MathRadical as MathRadical$1, MathRadicalProperties, MathRoundBrackets, MathRun, MathRun as MathRun$1, MathSquareBrackets, MathSubScript, MathSubScript as MathSubScript$1, MathSubSuperScript, MathSubSuperScript as MathSubSuperScript$1, MathSum, MathSuperScript, MathSuperScript as MathSuperScript$1, Paragraph, Run, createMathAccentCharacter, createMathBase, createMathBase as createMathBase$1, createMathLimitLocation, createMathNAryProperties, createMathNAryProperties as createMathNAryProperties$1, createMathPreSubSuperScriptProperties, createMathSubScriptElement, createMathSubScriptElement as createMathSubScriptElement$1, createMathSubScriptProperties, createMathSubSuperScriptProperties, createMathSuperScriptElement, createMathSuperScriptElement as createMathSuperScriptElement$1, createMathSuperScriptProperties } from "docx";
2
+ //#region src/math/math-elements.ts
3
+ /**
4
+ * What docx/math's components share: the checks on their arguments, and the elements they are made of. Nothing here is
5
+ * exported from docx/math.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * A count of things, such as "1 column" or "3 columns".
11
+ */
12
+ var plural = (count, thing) => `${count} ${thing}${count === 1 ? "" : "s"}`;
13
+ /**
14
+ * An element whose value is its `m:val`, such as `<m:begChr m:val="("/>`.
15
+ */
16
+ var createValueElement = (name, value) => new BuilderElement({
17
+ name,
18
+ attributes: { value: {
19
+ key: "m:val",
20
+ value
21
+ } }
22
+ });
23
+ /**
24
+ * Throws for what can't go in an argument: a `Math`, which Word won't open inside math, and a paragraph or a run of
25
+ * document text, which the schema doesn't allow there. Only an argument's own children can be checked.
26
+ */
27
+ var checkArgument = (owner, where, children) => {
28
+ for (const child of children) {
29
+ if (child instanceof Math$2) throw new Error(`${owner}: ${where} holds a Math. Word won't open math inside math, so give the Math's children instead`);
30
+ if (child instanceof Paragraph) throw new Error(`${owner}: ${where} holds a Paragraph. Math goes in a paragraph, not a paragraph in math`);
31
+ if (child instanceof Run) throw new Error(`${owner}: ${where} holds a TextRun or another run of document text, which can't go in math. Use a MathRun`);
32
+ }
33
+ };
34
+ /**
35
+ * Throws unless a bracket or separator is one character, or none. Characters are counted as code points, so `𝒜` is one.
36
+ */
37
+ var checkCharacter = (owner, option, value) => {
38
+ if ([...value].length > 1) throw new Error(`${owner}: ${option} is "${value}", which is more than one character. Give one character, or "" for none`);
39
+ };
40
+ /**
41
+ * Throws unless a value is one of those allowed, for code that isn't type checked.
42
+ */
43
+ var checkOneOf = (owner, option, value, allowed) => {
44
+ if (!allowed.includes(value)) throw new Error(`${owner}: ${option} is "${value}", which isn't one of ${allowed.map((one) => `"${one}"`).join(", ")}`);
45
+ };
46
+ /**
47
+ * An argument of any name, such as a limit (`m:lim`). An empty one gets a zero-width space, as LibreOffice can't read
48
+ * an equation with an empty argument, and draws "¿" in its place.
49
+ */
50
+ var createNamedArgument = (name, children) => new BuilderElement({
51
+ name,
52
+ children: children.length === 0 ? [new MathRun$1("​")] : children
53
+ });
54
+ /**
55
+ * An argument (`m:e`). An empty one gets a zero-width space, as {@link createNamedArgument} says.
56
+ */
57
+ var createArgument = (children) => createNamedArgument("m:e", children);
58
+ /**
59
+ * Brackets (`m:d`) around arguments, with a separator between them. They grow with their content unless `grow` is
60
+ * false, as Word's do when `m:grow` isn't written.
61
+ */
62
+ var bracketsElement = ({ open, close, separator, grow }, args) => ({
63
+ name: "m:d",
64
+ children: [new BuilderElement({
65
+ name: "m:dPr",
66
+ children: [
67
+ createValueElement("m:begChr", open),
68
+ ...separator === void 0 ? [] : [createValueElement("m:sepChr", separator)],
69
+ createValueElement("m:endChr", close),
70
+ ...grow === false ? [createValueElement("m:grow", 0)] : []
71
+ ]
72
+ }), ...args]
73
+ });
74
+ //#endregion
75
+ //#region src/math/math-accent.ts
76
+ /**
77
+ * Accents over math, such as a hat, a tilde, dots or a vector's arrow.
78
+ *
79
+ * @module
80
+ */
81
+ var ACCENTS = {
82
+ hat: "̂",
83
+ check: "̌",
84
+ tilde: "̃",
85
+ acute: "́",
86
+ grave: "̀",
87
+ dot: "̇",
88
+ doubleDot: "̈",
89
+ tripleDot: "⃛",
90
+ breve: "̆",
91
+ bar: "̅",
92
+ ring: "̊",
93
+ rightArrow: "⃗",
94
+ leftArrow: "⃖",
95
+ leftRightArrow: "⃡",
96
+ rightHarpoon: "⃑",
97
+ leftHarpoon: "⃐"
98
+ };
99
+ /**
100
+ * An accent over math (`m:acc`), such as a hat, a tilde, dots or a vector's arrow, as LaTeX's `\hat`, `\tilde`,
101
+ * `\dot` and `\vec`. Word stretches the accent over what it goes over.
102
+ *
103
+ * For a line over or under math, as LaTeX's `\overline` and `\underline`, use a `MathBar`.
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * new MathAccent({ accent: "rightArrow", children: [new MathRun("v")] });
108
+ * ```
109
+ */
110
+ var MathAccent = class extends BuilderElement {
111
+ constructor({ accent = "hat", children }) {
112
+ checkOneOf("MathAccent", "accent", accent, Object.keys(ACCENTS));
113
+ checkArgument("MathAccent", "children", children);
114
+ super({
115
+ name: "m:acc",
116
+ children: [new BuilderElement({
117
+ name: "m:accPr",
118
+ children: [createValueElement("m:chr", ACCENTS[accent])]
119
+ }), createArgument(children)]
120
+ });
121
+ }
122
+ };
123
+ //#endregion
124
+ //#region src/math/math-bar.ts
125
+ /**
126
+ * Lines over or under math, such as LaTeX's `\overline` and `\underline`.
127
+ *
128
+ * @module
129
+ */
130
+ var POSITIONS = ["above", "below"];
131
+ /**
132
+ * A line over or under math (`m:bar`), as LaTeX's `\overline` and `\underline`, as long as what it goes over.
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * new MathBar({ children: [new MathRun("AB")] });
137
+ * new MathBar({ position: "below", children: [new MathRun("x")] });
138
+ * ```
139
+ */
140
+ var MathBar = class extends BuilderElement {
141
+ constructor({ position = "above", children }) {
142
+ checkOneOf("MathBar", "position", position, POSITIONS);
143
+ checkArgument("MathBar", "children", children);
144
+ super({
145
+ name: "m:bar",
146
+ children: [new BuilderElement({
147
+ name: "m:barPr",
148
+ children: [createValueElement("m:pos", position === "above" ? "top" : "bot")]
149
+ }), createArgument(children)]
150
+ });
151
+ }
152
+ };
153
+ //#endregion
154
+ //#region src/math/math-box.ts
155
+ /**
156
+ * Boxes around math, and lines struck through it, such as LaTeX's `\boxed` and `\cancel`.
157
+ *
158
+ * @module
159
+ */
160
+ var SIDES = {
161
+ top: "m:hideTop",
162
+ bottom: "m:hideBot",
163
+ left: "m:hideLeft",
164
+ right: "m:hideRight"
165
+ };
166
+ var STRIKES = {
167
+ horizontal: "m:strikeH",
168
+ vertical: "m:strikeV",
169
+ diagonalUp: "m:strikeBLTR",
170
+ diagonalDown: "m:strikeTLBR"
171
+ };
172
+ /**
173
+ * A box around math (`m:borderBox`), as LaTeX's `\boxed`, with lines struck through it, as `\cancel`, `\bcancel` and
174
+ * `\xcancel`. Any of its sides can be left out.
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * new MathBox({ children: [new MathRun("E=mc²")] });
179
+ * new MathBox({ borders: [], strikes: ["diagonalUp"], children: [new MathRun("x")] });
180
+ * ```
181
+ */
182
+ var MathBox = class extends BuilderElement {
183
+ constructor({ children, borders = [
184
+ "top",
185
+ "bottom",
186
+ "left",
187
+ "right"
188
+ ], strikes = [] }) {
189
+ borders.forEach((side) => checkOneOf("MathBox", "borders", side, Object.keys(SIDES)));
190
+ strikes.forEach((strike) => checkOneOf("MathBox", "strikes", strike, Object.keys(STRIKES)));
191
+ checkArgument("MathBox", "children", children);
192
+ const properties = [...Object.entries(SIDES).filter(([side]) => !borders.includes(side)).map(([, name]) => createValueElement(name, 1)), ...Object.entries(STRIKES).filter(([strike]) => strikes.includes(strike)).map(([, name]) => createValueElement(name, 1))];
193
+ super({
194
+ name: "m:borderBox",
195
+ children: [...properties.length === 0 ? [] : [new BuilderElement({
196
+ name: "m:borderBoxPr",
197
+ children: properties
198
+ })], createArgument(children)]
199
+ });
200
+ }
201
+ };
202
+ //#endregion
203
+ //#region src/math/math-brace.ts
204
+ /**
205
+ * Braces over or under math, with a label, such as LaTeX's `\overbrace` and `\underbrace`.
206
+ *
207
+ * @module
208
+ */
209
+ var BRACES = {
210
+ curly: {
211
+ above: "⏞",
212
+ below: "⏟"
213
+ },
214
+ square: {
215
+ above: "⎴",
216
+ below: "⎵"
217
+ },
218
+ round: {
219
+ above: "⏜",
220
+ below: "⏝"
221
+ }
222
+ };
223
+ /**
224
+ * A brace over or under math (`m:groupChr`), as long as what it goes over, as LaTeX's `\overbrace` and
225
+ * `\underbrace`. A label goes on the brace's other side, as Word writes it: in a limit above (`m:limUpp`) or below
226
+ * (`m:limLow`).
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * new MathBrace({
231
+ * position: "below",
232
+ * children: [new MathRun("1+2+⋯+n")],
233
+ * label: [new MathRun("n terms")],
234
+ * });
235
+ * ```
236
+ */
237
+ var MathBrace = class extends BuilderElement {
238
+ constructor({ position = "above", brace = "curly", children, label }) {
239
+ checkOneOf("MathBrace", "position", position, POSITIONS);
240
+ checkOneOf("MathBrace", "brace", brace, Object.keys(BRACES));
241
+ checkArgument("MathBrace", "children", children);
242
+ if (label !== void 0) checkArgument("MathBrace", "label", label);
243
+ const above = position === "above";
244
+ const group = {
245
+ name: "m:groupChr",
246
+ children: [new BuilderElement({
247
+ name: "m:groupChrPr",
248
+ children: [
249
+ createValueElement("m:chr", BRACES[brace][position]),
250
+ createValueElement("m:pos", above ? "top" : "bot"),
251
+ createValueElement("m:vertJc", above ? "bot" : "top")
252
+ ]
253
+ }), createArgument(children)]
254
+ };
255
+ super(label === void 0 ? group : {
256
+ name: above ? "m:limUpp" : "m:limLow",
257
+ children: [createMathBase$1({ children: [new BuilderElement(group)] }), createNamedArgument("m:lim", label)]
258
+ });
259
+ }
260
+ };
261
+ //#endregion
262
+ //#region src/math/math-brackets.ts
263
+ /**
264
+ * Brackets of any characters around math, such as |x|, ‖v‖, ⟨a|b⟩ or a brace on one side.
265
+ *
266
+ * @module
267
+ */
268
+ /**
269
+ * Brackets of any characters around math (`m:d`), such as |x|, ‖v‖, ⟨a|b⟩ or a brace on one side only. They grow
270
+ * with what they hold.
271
+ *
272
+ * `MathRoundBrackets`, `MathSquareBrackets`, `MathCurlyBrackets` and `MathAngledBrackets` are fixed pairs of these.
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * new MathBrackets({ open: "|", close: "|", children: [new MathRun("x")] });
277
+ * new MathBrackets({ open: "⟨", close: "⟩", items: [[new MathRun("a")], [new MathRun("b")]] });
278
+ * new MathBrackets({ open: "{", close: "", children: [new MathRun("x")] });
279
+ * ```
280
+ */
281
+ var MathBrackets = class extends BuilderElement {
282
+ constructor(options) {
283
+ var _options$items;
284
+ const { open = "(", close = ")", separator, grow } = options;
285
+ const items = (_options$items = options.items) !== null && _options$items !== void 0 ? _options$items : [options.children];
286
+ checkCharacter("MathBrackets", "open", open);
287
+ checkCharacter("MathBrackets", "close", close);
288
+ if (separator !== void 0) checkCharacter("MathBrackets", "separator", separator);
289
+ if (items.length === 0) throw new Error("MathBrackets: items is empty. Give at least one item, or use children");
290
+ items.forEach((item, index) => checkArgument("MathBrackets", options.items ? `item ${index + 1}` : "children", item));
291
+ super(bracketsElement({
292
+ open,
293
+ close,
294
+ separator,
295
+ grow
296
+ }, items.map(createArgument)));
297
+ }
298
+ };
299
+ //#endregion
300
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/objectWithoutPropertiesLoose.js
301
+ function _objectWithoutPropertiesLoose(r, e) {
302
+ if (null == r) return {};
303
+ var t = {};
304
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
305
+ if (e.includes(n)) continue;
306
+ t[n] = r[n];
307
+ }
308
+ return t;
309
+ }
310
+ //#endregion
311
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/objectWithoutProperties.js
312
+ function _objectWithoutProperties(e, t) {
313
+ if (null == e) return {};
314
+ var o, r, i = _objectWithoutPropertiesLoose(e, t);
315
+ if (Object.getOwnPropertySymbols) {
316
+ var s = Object.getOwnPropertySymbols(e);
317
+ for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
318
+ }
319
+ return i;
320
+ }
321
+ //#endregion
322
+ //#region src/math/math-matrix.ts
323
+ /**
324
+ * Matrices, such as LaTeX's `pmatrix`, `bmatrix`, `vmatrix` and `Vmatrix`.
325
+ *
326
+ * @module
327
+ */
328
+ var _excluded = ["brackets"];
329
+ var BRACKETS = {
330
+ round: ["(", ")"],
331
+ square: ["[", "]"],
332
+ curly: ["{", "}"],
333
+ angled: ["⟨", "⟩"],
334
+ verticalBars: ["|", "|"],
335
+ doubleVerticalBars: ["‖", "‖"]
336
+ };
337
+ var COLUMN_ALIGNMENTS$1 = [
338
+ "left",
339
+ "center",
340
+ "right"
341
+ ];
342
+ var VERTICAL_ALIGNMENTS = [
343
+ "top",
344
+ "center",
345
+ "bottom"
346
+ ];
347
+ /**
348
+ * A matrix (`m:m`), without brackets. Its errors name `owner`, its rows as `rowsName`, and each cell as `cellName` does.
349
+ */
350
+ var matrixElement = (owner, { rows, columnAlignment = "center", verticalAlignment = "center" }, { rowsName = "rows", cellName = (row, column) => `row ${row + 1}, cell ${column + 1}` } = {}) => {
351
+ if (rows.length === 0) throw new Error(`${owner}: there are no ${rowsName}. Give at least one`);
352
+ if (rows.length > 256) throw new Error(`${owner}: there are ${rows.length} ${rowsName}, but Word allows at most 256`);
353
+ const columns = Math.max(...rows.map((row) => row.length));
354
+ if (columns === 0) throw new Error(`${owner}: every row is empty. Give at least one cell`);
355
+ if (columns > 64) throw new Error(`${owner}: a row has ${columns} cells, but Word allows at most 64`);
356
+ const alignments = typeof columnAlignment === "string" ? Array.from({ length: columns }, () => columnAlignment) : columnAlignment;
357
+ if (alignments.length !== columns) throw new Error(`${owner}: columnAlignment has ${plural(alignments.length, "alignment")}, but the rows have ${plural(columns, "column")}. Give one for each`);
358
+ alignments.forEach((alignment) => checkOneOf(owner, "columnAlignment", alignment, COLUMN_ALIGNMENTS$1));
359
+ checkOneOf(owner, "verticalAlignment", verticalAlignment, VERTICAL_ALIGNMENTS);
360
+ rows.forEach((row, rowIndex) => row.forEach((cell, column) => checkArgument(owner, cellName(rowIndex, column), cell)));
361
+ const groups = alignments.reduce((all, alignment) => all.length > 0 && all[all.length - 1].alignment === alignment ? [...all.slice(0, -1), {
362
+ alignment,
363
+ count: all[all.length - 1].count + 1
364
+ }] : [...all, {
365
+ alignment,
366
+ count: 1
367
+ }], []);
368
+ return {
369
+ name: "m:m",
370
+ children: [new BuilderElement({
371
+ name: "m:mPr",
372
+ children: [
373
+ createValueElement("m:baseJc", verticalAlignment),
374
+ createValueElement("m:plcHide", 1),
375
+ new BuilderElement({
376
+ name: "m:mcs",
377
+ children: groups.map(({ alignment, count }) => new BuilderElement({
378
+ name: "m:mc",
379
+ children: [new BuilderElement({
380
+ name: "m:mcPr",
381
+ children: [createValueElement("m:count", count), createValueElement("m:mcJc", alignment)]
382
+ })]
383
+ }))
384
+ })
385
+ ]
386
+ }), ...rows.map((row) => new BuilderElement({
387
+ name: "m:mr",
388
+ children: Array.from({ length: columns }, (_, column) => {
389
+ var _row$column;
390
+ return createArgument((_row$column = row[column]) !== null && _row$column !== void 0 ? _row$column : []);
391
+ })
392
+ }))]
393
+ };
394
+ };
395
+ /**
396
+ * A matrix (`m:m`), in brackets or none (`m:d`): LaTeX's `matrix`, `pmatrix`, `bmatrix`, `Bmatrix`, `vmatrix` and
397
+ * `Vmatrix`.
398
+ *
399
+ * Word lines up each column's cells as `columnAlignment` says, and hides the placeholders of empty cells. LibreOffice
400
+ * and Pages centre every column.
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * new MathMatrix({
405
+ * brackets: "round",
406
+ * rows: [
407
+ * [[new MathRun("1")], [new MathRun("2")]],
408
+ * [[new MathRun("3")], [new MathRun("4")]],
409
+ * ],
410
+ * });
411
+ * ```
412
+ */
413
+ var MathMatrix = class extends BuilderElement {
414
+ constructor(_ref) {
415
+ let { brackets = "none" } = _ref, options = _objectWithoutProperties(_ref, _excluded);
416
+ checkOneOf("MathMatrix", "brackets", brackets, ["none", ...Object.keys(BRACKETS)]);
417
+ const matrix = matrixElement("MathMatrix", options);
418
+ super(brackets === "none" ? matrix : bracketsElement({
419
+ open: BRACKETS[brackets][0],
420
+ close: BRACKETS[brackets][1]
421
+ }, [createMathBase$1({ children: [new BuilderElement(matrix)] })]));
422
+ }
423
+ };
424
+ //#endregion
425
+ //#region src/math/math-cases.ts
426
+ /**
427
+ * Cases, such as LaTeX's `cases`: values, each with its condition, in a brace.
428
+ *
429
+ * @module
430
+ */
431
+ /**
432
+ * Cases, as LaTeX's `cases`: values, each with its condition, one to a line, in a brace on the left. The values and
433
+ * the conditions each line up on the left.
434
+ *
435
+ * They are written as pandoc writes them: a matrix of two columns in a brace with no closing bracket. Word's own
436
+ * equation editor lines the conditions up with an `&` instead, which LibreOffice draws.
437
+ *
438
+ * @example
439
+ * ```typescript
440
+ * new MathCases({
441
+ * cases: [
442
+ * { value: [new MathRun("x,")], condition: [new MathRun({ text: "if ", normalText: true }), new MathRun("x≥0")] },
443
+ * { value: [new MathRun("−x,")], condition: [new MathRun({ text: "otherwise", normalText: true })] },
444
+ * ],
445
+ * });
446
+ * ```
447
+ */
448
+ var MathCases = class extends BuilderElement {
449
+ constructor({ cases }) {
450
+ const conditions = cases.some((one) => one.condition !== void 0);
451
+ const matrix = matrixElement("MathCases", {
452
+ rows: cases.map(({ value, condition }) => conditions ? [value, condition !== null && condition !== void 0 ? condition : []] : [value]),
453
+ columnAlignment: "left"
454
+ }, {
455
+ rowsName: "cases",
456
+ cellName: (row, column) => `case ${row + 1}'s ${column === 0 ? "value" : "condition"}`
457
+ });
458
+ super(bracketsElement({
459
+ open: "{",
460
+ close: ""
461
+ }, [createMathBase$1({ children: [new BuilderElement(matrix)] })]));
462
+ }
463
+ };
464
+ //#endregion
465
+ //#region src/math/math-equation-array.ts
466
+ /**
467
+ * Equation arrays: rows of math lined up at points, such as LaTeX's `align` and `aligned`, with equation numbers.
468
+ *
469
+ * @module
470
+ */
471
+ /**
472
+ * An equation array (`m:eqArr`): rows of math, one to a line, lined up at the points between their parts, as LaTeX's
473
+ * `align` and `aligned`, with an equation number at the end of any row.
474
+ *
475
+ * Word marks the points with an `&`, and the number with a `#`, in the text. So an `&` or a `#` in a `MathRun` in the
476
+ * array is taken as one too. LibreOffice shows the `&` and `#`, and centres the rows; Pages lines them up, but shows
477
+ * the `#`.
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * new MathEquationArray({
482
+ * rows: [
483
+ * { parts: [[new MathRun("y")], [new MathRun("=mx+b")]], equationNumber: "(1)" },
484
+ * { parts: [[new MathRun("y′")], [new MathRun("=m")]], equationNumber: "(2)" },
485
+ * ],
486
+ * });
487
+ * ```
488
+ */
489
+ var MathEquationArray = class extends BuilderElement {
490
+ constructor({ rows, verticalAlignment }) {
491
+ if (rows.length === 0) throw new Error("MathEquationArray: there are no rows. Give at least one");
492
+ if (rows.length > 64) throw new Error(`MathEquationArray: there are ${rows.length} rows, but Word allows at most 64`);
493
+ if (verticalAlignment !== void 0) checkOneOf("MathEquationArray", "verticalAlignment", verticalAlignment, VERTICAL_ALIGNMENTS);
494
+ rows.forEach(({ parts }, row) => {
495
+ if (parts.length === 0) throw new Error(`MathEquationArray: row ${row + 1} has no parts. Give at least one, which can be empty`);
496
+ parts.forEach((part, index) => checkArgument("MathEquationArray", `row ${row + 1}, part ${index + 1}`, part));
497
+ });
498
+ super({
499
+ name: "m:eqArr",
500
+ children: [...verticalAlignment === void 0 ? [] : [new BuilderElement({
501
+ name: "m:eqArrPr",
502
+ children: [createValueElement("m:baseJc", verticalAlignment)]
503
+ })], ...rows.map(({ parts, equationNumber }) => createArgument([...parts.flatMap((part, index) => index === 0 ? part : [new MathRun$1("&"), ...part]), ...equationNumber ? [new MathRun$1("#"), new MathRun$1(equationNumber)] : []]))]
504
+ });
505
+ }
506
+ };
507
+ //#endregion
508
+ //#region src/math/math-large-operator.ts
509
+ /**
510
+ * Large operators with limits, such as products, unions and contour integrals, as well as sums and integrals.
511
+ *
512
+ * @module
513
+ */
514
+ var LARGE_OPERATORS = {
515
+ sum: "∑",
516
+ product: "∏",
517
+ coproduct: "∐",
518
+ union: "⋃",
519
+ intersection: "⋂",
520
+ squareUnion: "⨆",
521
+ multisetUnion: "⨄",
522
+ logicalOr: "⋁",
523
+ logicalAnd: "⋀",
524
+ directSum: "⨁",
525
+ tensorProduct: "⨂",
526
+ circledDot: "⨀",
527
+ integral: "∫",
528
+ doubleIntegral: "∬",
529
+ tripleIntegral: "∭",
530
+ quadrupleIntegral: "⨌",
531
+ contourIntegral: "∮",
532
+ surfaceIntegral: "∯",
533
+ volumeIntegral: "∰"
534
+ };
535
+ var LIMITS = ["aboveBelow", "side"];
536
+ /**
537
+ * A large operator with limits (`m:nary`), such as ∏, ⋃ or ∮, as LaTeX's `\prod`, `\bigcup` and `\oint`, over what
538
+ * it applies to. `MathSum` and `MathIntegral` are two of these.
539
+ *
540
+ * @example
541
+ * ```typescript
542
+ * new MathLargeOperator({
543
+ * operator: "product",
544
+ * subScript: [new MathRun("i=1")],
545
+ * superScript: [new MathRun("n")],
546
+ * children: [new MathRun("i")],
547
+ * });
548
+ * ```
549
+ */
550
+ var MathLargeOperator = class extends BuilderElement {
551
+ constructor({ operator, children, subScript, superScript, limits }) {
552
+ checkOneOf("MathLargeOperator", "operator", operator, Object.keys(LARGE_OPERATORS));
553
+ if (limits !== void 0) checkOneOf("MathLargeOperator", "limits", limits, LIMITS);
554
+ checkArgument("MathLargeOperator", "children", children);
555
+ if (subScript !== void 0) checkArgument("MathLargeOperator", "subScript", subScript);
556
+ if (superScript !== void 0) checkArgument("MathLargeOperator", "superScript", superScript);
557
+ const side = limits === void 0 ? operator.endsWith("ntegral") : limits === "side";
558
+ super({
559
+ name: "m:nary",
560
+ children: [
561
+ createMathNAryProperties$1({
562
+ accent: LARGE_OPERATORS[operator],
563
+ hasSubScript: subScript !== void 0,
564
+ hasSuperScript: superScript !== void 0,
565
+ limitLocationVal: side ? "subSup" : "undOvr"
566
+ }),
567
+ createMathSubScriptElement$1({ children: subScript !== null && subScript !== void 0 ? subScript : [] }),
568
+ createMathSuperScriptElement$1({ children: superScript !== null && superScript !== void 0 ? superScript : [] }),
569
+ createArgument(children)
570
+ ]
571
+ });
572
+ }
573
+ };
574
+ //#endregion
575
+ //#region src/math/math-phantom.ts
576
+ /**
577
+ * Phantoms: math that takes up room without being seen, or is seen without taking up room, such as LaTeX's
578
+ * `\phantom` and `\smash`.
579
+ *
580
+ * @module
581
+ */
582
+ /**
583
+ * A phantom (`m:phant`): math that takes up room without being seen, as LaTeX's `\phantom`, to leave space for it or
584
+ * line things up with it. Or math that is seen but takes up no room, or less, as `\smash`.
585
+ *
586
+ * @example
587
+ * ```typescript
588
+ * // As much space as "x+y" takes up
589
+ * new MathPhantom({ children: [new MathRun("x+y")] });
590
+ *
591
+ * // A tall fraction that doesn't push its line apart
592
+ * new MathPhantom({ visible: true, height: false, depth: false, children: [fraction] });
593
+ * ```
594
+ */
595
+ var MathPhantom = class extends BuilderElement {
596
+ constructor({ children, visible = false, width = true, height = true, depth = true }) {
597
+ checkArgument("MathPhantom", "children", children);
598
+ super({
599
+ name: "m:phant",
600
+ children: [new BuilderElement({
601
+ name: "m:phantPr",
602
+ children: [
603
+ createValueElement("m:show", visible ? 1 : 0),
604
+ ...width ? [] : [createValueElement("m:zeroWid", 1)],
605
+ ...height ? [] : [createValueElement("m:zeroAsc", 1)],
606
+ ...depth ? [] : [createValueElement("m:zeroDesc", 1)]
607
+ ]
608
+ }), createArgument(children)]
609
+ });
610
+ }
611
+ };
612
+ //#endregion
613
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/typeof.js
614
+ function _typeof(o) {
615
+ "@babel/helpers - typeof";
616
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
617
+ return typeof o;
618
+ } : function(o) {
619
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
620
+ }, _typeof(o);
621
+ }
622
+ //#endregion
623
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/toPrimitive.js
624
+ function toPrimitive(t, r) {
625
+ if ("object" != _typeof(t) || !t) return t;
626
+ var e = t[Symbol.toPrimitive];
627
+ if (void 0 !== e) {
628
+ var i = e.call(t, r || "default");
629
+ if ("object" != _typeof(i)) return i;
630
+ throw new TypeError("@@toPrimitive must return a primitive value.");
631
+ }
632
+ return ("string" === r ? String : Number)(t);
633
+ }
634
+ //#endregion
635
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/toPropertyKey.js
636
+ function toPropertyKey(t) {
637
+ var i = toPrimitive(t, "string");
638
+ return "symbol" == _typeof(i) ? i : i + "";
639
+ }
640
+ //#endregion
641
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/defineProperty.js
642
+ function _defineProperty(e, r, t) {
643
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
644
+ value: t,
645
+ enumerable: !0,
646
+ configurable: !0,
647
+ writable: !0
648
+ }) : e[r] = t, e;
649
+ }
650
+ //#endregion
651
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/objectSpread2.js
652
+ function ownKeys(e, r) {
653
+ var t = Object.keys(e);
654
+ if (Object.getOwnPropertySymbols) {
655
+ var o = Object.getOwnPropertySymbols(e);
656
+ r && (o = o.filter(function(r) {
657
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
658
+ })), t.push.apply(t, o);
659
+ }
660
+ return t;
661
+ }
662
+ function _objectSpread2(e) {
663
+ for (var r = 1; r < arguments.length; r++) {
664
+ var t = null != arguments[r] ? arguments[r] : {};
665
+ r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
666
+ _defineProperty(e, r, t[r]);
667
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
668
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
669
+ });
670
+ }
671
+ return e;
672
+ }
673
+ //#endregion
674
+ //#region src/math/latex/latex-atoms.ts
675
+ /**
676
+ * What the LaTeX parser reads an equation into, and how that becomes docx's math: runs of text that share a font are
677
+ * joined, scripts go on their bases, and large operators and functions take the math after them as their argument.
678
+ *
679
+ * @module
680
+ */
681
+ var ZERO_WIDTH_SPACE = "​";
682
+ /**
683
+ * The part an atom plays, which says where an operator's argument ends. A script's is its base's, so the bracket in
684
+ * `)^2` still closes.
685
+ */
686
+ var roleOf$1 = (atom) => {
687
+ switch (atom.kind) {
688
+ case "text": return atom.role;
689
+ case "built":
690
+ var _atom$role;
691
+ return (_atom$role = atom.role) !== null && _atom$role !== void 0 ? _atom$role : "ordinary";
692
+ case "scripts": return atom.base.length === 1 ? roleOf$1(atom.base[0]) : "ordinary";
693
+ default: return "ordinary";
694
+ }
695
+ };
696
+ /**
697
+ * Where the argument of the operator or function before `start` ends. LaTeX doesn't say, so it goes as far as TeX's
698
+ * spacing suggests: to a relation, a + or −, or punctuation, or to another operator or function, outside brackets.
699
+ * So ∑ᵢ aᵢ + b takes aᵢ, ∫ f(x) dx takes f(x) dx, and sin(x + y) takes (x + y). An operator that comes first is part
700
+ * of the argument, as in ∑ᵢ ∑ⱼ aᵢⱼ, and so is a sign, as in sin −x.
701
+ */
702
+ var argumentEnd = (atoms, start) => {
703
+ let depth = 0;
704
+ for (let index = start; index < atoms.length; index++) {
705
+ const atom = atoms[index];
706
+ const role = roleOf$1(atom);
707
+ if (depth === 0) {
708
+ if (role === "relation" || role === "punctuation" || role === "close") return index;
709
+ if (index > start && (role === "additive" || atom.kind === "operator" || atom.kind === "function")) return index;
710
+ }
711
+ if (role === "open") depth++;
712
+ else if (role === "close") depth--;
713
+ }
714
+ return atoms.length;
715
+ };
716
+ /** An argument's math, with a zero-width space when it is empty, which LibreOffice needs to read the equation */
717
+ var orSpace = (children) => children.length === 0 ? [new MathRun$1(ZERO_WIDTH_SPACE)] : children;
718
+ var isPlain = (font) => Object.values(font).every((value) => value === void 0 || value === false);
719
+ var sameFont = (one, other) => one.style === other.style && one.script === other.script && !!one.normalText === !!other.normalText && !!one.literal === !!other.literal;
720
+ var createRun = (text, font) => new MathRun$1(isPlain(font) ? text : _objectSpread2({ text }, font));
721
+ var withScripts = (base, sub, sup) => {
722
+ const children = orSpace(base);
723
+ if (sub !== void 0 && sup !== void 0) return new MathSubSuperScript$1({
724
+ children,
725
+ subScript: orSpace(atomsToMath(sub)),
726
+ superScript: orSpace(atomsToMath(sup))
727
+ });
728
+ if (sub !== void 0) return new MathSubScript$1({
729
+ children,
730
+ subScript: orSpace(atomsToMath(sub))
731
+ });
732
+ return new MathSuperScript$1({
733
+ children,
734
+ superScript: orSpace(atomsToMath(sup))
735
+ });
736
+ };
737
+ var createOperator = (atom, argument) => {
738
+ if (atom.kind === "operator") return new MathLargeOperator({
739
+ operator: atom.operator,
740
+ limits: atom.limits,
741
+ subScript: atom.sub && orSpace(atomsToMath(atom.sub)),
742
+ superScript: atom.sup && orSpace(atomsToMath(atom.sup)),
743
+ children: argument
744
+ });
745
+ const name = atomsToMath(atom.name);
746
+ const hasScripts = atom.sub !== void 0 || atom.sup !== void 0;
747
+ const below = atom.sub === void 0 ? name : [new MathLimitLower$1({
748
+ children: name,
749
+ limit: orSpace(atomsToMath(atom.sub))
750
+ })];
751
+ const limited = atom.sup === void 0 ? below : [new MathLimitUpper$1({
752
+ children: below,
753
+ limit: orSpace(atomsToMath(atom.sup))
754
+ })];
755
+ const scripted = hasScripts ? [withScripts(name, atom.sub, atom.sup)] : name;
756
+ return new MathFunction$1({
757
+ name: atom.limitsBelow ? limited : scripted,
758
+ children: orSpace(argument)
759
+ });
760
+ };
761
+ /**
762
+ * Turns atoms into pieces of math. A group's pieces are among those around it, so its text can join theirs, as in
763
+ * `a{b}c`.
764
+ */
765
+ var atomsToPieces = (atoms) => {
766
+ const pieces = [];
767
+ for (let index = 0; index < atoms.length; index++) {
768
+ const atom = atoms[index];
769
+ switch (atom.kind) {
770
+ case "text":
771
+ pieces.push({
772
+ kind: "text",
773
+ text: atom.text,
774
+ font: atom.font
775
+ });
776
+ break;
777
+ case "group":
778
+ pieces.push(...atomsToPieces(atom.atoms));
779
+ break;
780
+ case "built":
781
+ pieces.push({
782
+ kind: "component",
783
+ component: atom.component
784
+ });
785
+ break;
786
+ case "scripts":
787
+ pieces.push({
788
+ kind: "component",
789
+ component: withScripts(atomsToMath(atom.base), atom.sub, atom.sup)
790
+ });
791
+ break;
792
+ case "operator":
793
+ case "function": {
794
+ const end = argumentEnd(atoms, index + 1);
795
+ pieces.push({
796
+ kind: "component",
797
+ component: createOperator(atom, atomsToMath(atoms.slice(index + 1, end)))
798
+ });
799
+ index = end - 1;
800
+ break;
801
+ }
802
+ }
803
+ }
804
+ return pieces;
805
+ };
806
+ /**
807
+ * Turns atoms into docx's math, with text next to text in the same font joined in one run.
808
+ */
809
+ var atomsToMath = (atoms) => atomsToPieces(atoms).reduce((joined, piece) => {
810
+ const last = joined[joined.length - 1];
811
+ return piece.kind === "text" && (last === null || last === void 0 ? void 0 : last.kind) === "text" && sameFont(last.font, piece.font) ? [...joined.slice(0, -1), _objectSpread2(_objectSpread2({}, last), {}, { text: last.text + piece.text })] : [...joined, piece];
812
+ }, []).map((piece) => piece.kind === "text" ? createRun(piece.text, piece.font) : piece.component);
813
+ //#endregion
814
+ //#region src/math/latex/latex-symbols.ts
815
+ /**
816
+ * Whether a table has an entry of its own for a key. Unlike `in`, it isn't fooled by the names every object has, such as
817
+ * `\constructor`.
818
+ */
819
+ var hasEntry = (table, key) => Object.prototype.hasOwnProperty.call(table, key);
820
+ var withRole = (role, symbols) => Object.entries(symbols).map(([name, text]) => [name, {
821
+ text,
822
+ role
823
+ }]);
824
+ var GREEK = {
825
+ alpha: "α",
826
+ beta: "β",
827
+ gamma: "γ",
828
+ delta: "δ",
829
+ epsilon: "ϵ",
830
+ varepsilon: "ε",
831
+ zeta: "ζ",
832
+ eta: "η",
833
+ theta: "θ",
834
+ vartheta: "ϑ",
835
+ iota: "ι",
836
+ kappa: "κ",
837
+ varkappa: "ϰ",
838
+ lambda: "λ",
839
+ mu: "μ",
840
+ nu: "ν",
841
+ xi: "ξ",
842
+ omicron: "ο",
843
+ pi: "π",
844
+ varpi: "ϖ",
845
+ rho: "ρ",
846
+ varrho: "ϱ",
847
+ sigma: "σ",
848
+ varsigma: "ς",
849
+ tau: "τ",
850
+ upsilon: "υ",
851
+ phi: "ϕ",
852
+ varphi: "φ",
853
+ chi: "χ",
854
+ psi: "ψ",
855
+ omega: "ω",
856
+ digamma: "ϝ"
857
+ };
858
+ /** Capital Greek letters, which LaTeX draws upright */
859
+ var UPRIGHT_GREEK = {
860
+ Gamma: "Γ",
861
+ Delta: "Δ",
862
+ Theta: "Θ",
863
+ Lambda: "Λ",
864
+ Xi: "Ξ",
865
+ Pi: "Π",
866
+ Sigma: "Σ",
867
+ Upsilon: "Υ",
868
+ Phi: "Φ",
869
+ Psi: "Ψ",
870
+ Omega: "Ω"
871
+ };
872
+ /** Capital Greek letters in italic, as amsmath's `\varGamma` */
873
+ var ITALIC_GREEK = Object.fromEntries(Object.entries(UPRIGHT_GREEK).map(([name, text]) => [`var${name}`, text]));
874
+ var ORDINARY = _objectSpread2(_objectSpread2({}, GREEK), {}, {
875
+ infty: "∞",
876
+ partial: "∂",
877
+ nabla: "∇",
878
+ forall: "∀",
879
+ exists: "∃",
880
+ nexists: "∄",
881
+ emptyset: "∅",
882
+ varnothing: "∅",
883
+ neg: "¬",
884
+ lnot: "¬",
885
+ angle: "∠",
886
+ measuredangle: "∡",
887
+ sphericalangle: "∢",
888
+ triangle: "△",
889
+ hbar: "ℏ",
890
+ hslash: "ℏ",
891
+ ell: "ℓ",
892
+ wp: "℘",
893
+ Re: "ℜ",
894
+ Im: "ℑ",
895
+ aleph: "ℵ",
896
+ beth: "ℶ",
897
+ gimel: "ℷ",
898
+ daleth: "ℸ",
899
+ imath: "ı",
900
+ jmath: "ȷ",
901
+ prime: "′",
902
+ backprime: "‵",
903
+ top: "⊤",
904
+ bot: "⊥",
905
+ ldots: "…",
906
+ dots: "…",
907
+ dotsc: "…",
908
+ dotso: "…",
909
+ cdots: "⋯",
910
+ dotsb: "⋯",
911
+ dotsm: "⋯",
912
+ dotsi: "⋯",
913
+ vdots: "⋮",
914
+ ddots: "⋱",
915
+ iddots: "⋰",
916
+ square: "□",
917
+ Box: "□",
918
+ blacksquare: "■",
919
+ Diamond: "◇",
920
+ lozenge: "◊",
921
+ blacklozenge: "⧫",
922
+ clubsuit: "♣",
923
+ diamondsuit: "♢",
924
+ heartsuit: "♡",
925
+ spadesuit: "♠",
926
+ flat: "♭",
927
+ natural: "♮",
928
+ sharp: "♯",
929
+ surd: "√",
930
+ mho: "℧",
931
+ complement: "∁",
932
+ dag: "†",
933
+ ddag: "‡",
934
+ S: "§",
935
+ P: "¶",
936
+ copyright: "©",
937
+ pounds: "£",
938
+ euro: "€",
939
+ yen: "¥",
940
+ degree: "°",
941
+ bigstar: "★",
942
+ checkmark: "✓",
943
+ maltese: "✠",
944
+ backslash: "\\",
945
+ Vert: "‖",
946
+ vert: "|"
947
+ });
948
+ var BINARY = {
949
+ times: "×",
950
+ div: "÷",
951
+ cdot: "⋅",
952
+ centerdot: "⋅",
953
+ ast: "∗",
954
+ star: "⋆",
955
+ circ: "∘",
956
+ bullet: "∙",
957
+ oplus: "⊕",
958
+ ominus: "⊖",
959
+ otimes: "⊗",
960
+ oslash: "⊘",
961
+ odot: "⊙",
962
+ circledast: "⊛",
963
+ circledcirc: "⊚",
964
+ boxplus: "⊞",
965
+ boxminus: "⊟",
966
+ boxtimes: "⊠",
967
+ boxdot: "⊡",
968
+ cup: "∪",
969
+ cap: "∩",
970
+ sqcup: "⊔",
971
+ sqcap: "⊓",
972
+ uplus: "⊎",
973
+ vee: "∨",
974
+ lor: "∨",
975
+ wedge: "∧",
976
+ land: "∧",
977
+ setminus: "∖",
978
+ smallsetminus: "∖",
979
+ wr: "≀",
980
+ amalg: "⨿",
981
+ diamond: "⋄",
982
+ triangleleft: "◁",
983
+ triangleright: "▷",
984
+ bigtriangleup: "△",
985
+ bigtriangledown: "▽",
986
+ lhd: "⊲",
987
+ rhd: "⊳",
988
+ unlhd: "⊴",
989
+ unrhd: "⊵",
990
+ ltimes: "⋉",
991
+ rtimes: "⋊",
992
+ dotplus: "∔",
993
+ Cup: "⋓",
994
+ Cap: "⋒",
995
+ intercal: "⊺",
996
+ barwedge: "⌅",
997
+ veebar: "⊻",
998
+ divideontimes: "⋇",
999
+ leftthreetimes: "⋋",
1000
+ rightthreetimes: "⋌",
1001
+ curlyvee: "⋎",
1002
+ curlywedge: "⋏",
1003
+ bigcirc: "◯",
1004
+ dagger: "†",
1005
+ ddagger: "‡"
1006
+ };
1007
+ var ADDITIVE = {
1008
+ pm: "±",
1009
+ mp: "∓"
1010
+ };
1011
+ var RELATION = {
1012
+ le: "≤",
1013
+ leq: "≤",
1014
+ ge: "≥",
1015
+ geq: "≥",
1016
+ leqslant: "⩽",
1017
+ geqslant: "⩾",
1018
+ leqq: "≦",
1019
+ geqq: "≧",
1020
+ ne: "≠",
1021
+ neq: "≠",
1022
+ equiv: "≡",
1023
+ approx: "≈",
1024
+ approxeq: "≊",
1025
+ sim: "∼",
1026
+ simeq: "≃",
1027
+ backsim: "∽",
1028
+ cong: "≅",
1029
+ propto: "∝",
1030
+ varpropto: "∝",
1031
+ in: "∈",
1032
+ notin: "∉",
1033
+ ni: "∋",
1034
+ owns: "∋",
1035
+ subset: "⊂",
1036
+ subseteq: "⊆",
1037
+ supset: "⊃",
1038
+ supseteq: "⊇",
1039
+ subsetneq: "⊊",
1040
+ supsetneq: "⊋",
1041
+ subseteqq: "⫅",
1042
+ supseteqq: "⫆",
1043
+ nsubseteq: "⊈",
1044
+ nsupseteq: "⊉",
1045
+ sqsubset: "⊏",
1046
+ sqsupset: "⊐",
1047
+ sqsubseteq: "⊑",
1048
+ sqsupseteq: "⊒",
1049
+ mid: "∣",
1050
+ nmid: "∤",
1051
+ shortmid: "∣",
1052
+ parallel: "∥",
1053
+ nparallel: "∦",
1054
+ shortparallel: "∥",
1055
+ perp: "⊥",
1056
+ models: "⊨",
1057
+ vdash: "⊢",
1058
+ dashv: "⊣",
1059
+ vDash: "⊨",
1060
+ Vdash: "⊩",
1061
+ ll: "≪",
1062
+ gg: "≫",
1063
+ lll: "⋘",
1064
+ ggg: "⋙",
1065
+ prec: "≺",
1066
+ succ: "≻",
1067
+ preceq: "⪯",
1068
+ succeq: "⪰",
1069
+ doteq: "≐",
1070
+ asymp: "≍",
1071
+ bowtie: "⋈",
1072
+ Join: "⨝",
1073
+ smile: "⌣",
1074
+ frown: "⌢",
1075
+ coloneqq: "≔",
1076
+ coloneq: "≔",
1077
+ eqqcolon: "≕",
1078
+ triangleq: "≜",
1079
+ lesssim: "≲",
1080
+ gtrsim: "≳",
1081
+ lessgtr: "≶",
1082
+ gtrless: "≷",
1083
+ nless: "≮",
1084
+ ngtr: "≯",
1085
+ nleq: "≰",
1086
+ ngeq: "≱",
1087
+ nsim: "≁",
1088
+ ncong: "≇",
1089
+ lneq: "⪇",
1090
+ gneq: "⪈",
1091
+ lneqq: "≨",
1092
+ gneqq: "≩",
1093
+ therefore: "∴",
1094
+ because: "∵",
1095
+ circeq: "≗",
1096
+ bumpeq: "≏",
1097
+ Bumpeq: "≎",
1098
+ risingdotseq: "≓",
1099
+ fallingdotseq: "≒",
1100
+ vartriangleleft: "⊲",
1101
+ vartriangleright: "⊳",
1102
+ trianglelefteq: "⊴",
1103
+ trianglerighteq: "⊵",
1104
+ between: "≬",
1105
+ pitchfork: "⋔",
1106
+ colon: ":",
1107
+ to: "→",
1108
+ rightarrow: "→",
1109
+ leftarrow: "←",
1110
+ gets: "←",
1111
+ leftrightarrow: "↔",
1112
+ Rightarrow: "⇒",
1113
+ Leftarrow: "⇐",
1114
+ Leftrightarrow: "⇔",
1115
+ implies: "⟹",
1116
+ impliedby: "⟸",
1117
+ iff: "⟺",
1118
+ longrightarrow: "⟶",
1119
+ longleftarrow: "⟵",
1120
+ longleftrightarrow: "⟷",
1121
+ Longrightarrow: "⟹",
1122
+ Longleftarrow: "⟸",
1123
+ Longleftrightarrow: "⟺",
1124
+ mapsto: "↦",
1125
+ longmapsto: "⟼",
1126
+ hookrightarrow: "↪",
1127
+ hookleftarrow: "↩",
1128
+ uparrow: "↑",
1129
+ downarrow: "↓",
1130
+ updownarrow: "↕",
1131
+ Uparrow: "⇑",
1132
+ Downarrow: "⇓",
1133
+ Updownarrow: "⇕",
1134
+ nearrow: "↗",
1135
+ searrow: "↘",
1136
+ swarrow: "↙",
1137
+ nwarrow: "↖",
1138
+ rightharpoonup: "⇀",
1139
+ rightharpoondown: "⇁",
1140
+ leftharpoonup: "↼",
1141
+ leftharpoondown: "↽",
1142
+ rightleftharpoons: "⇌",
1143
+ leftrightharpoons: "⇋",
1144
+ upharpoonright: "↾",
1145
+ upharpoonleft: "↿",
1146
+ downharpoonright: "⇂",
1147
+ downharpoonleft: "⇃",
1148
+ twoheadrightarrow: "↠",
1149
+ twoheadleftarrow: "↞",
1150
+ rightarrowtail: "↣",
1151
+ leftarrowtail: "↢",
1152
+ leadsto: "⇝",
1153
+ rightsquigarrow: "⇝",
1154
+ leftrightsquigarrow: "↭",
1155
+ curvearrowright: "↷",
1156
+ curvearrowleft: "↶",
1157
+ circlearrowright: "↻",
1158
+ circlearrowleft: "↺",
1159
+ rightrightarrows: "⇉",
1160
+ leftleftarrows: "⇇",
1161
+ rightleftarrows: "⇄",
1162
+ leftrightarrows: "⇆",
1163
+ Rrightarrow: "⇛",
1164
+ Lleftarrow: "⇚",
1165
+ nrightarrow: "↛",
1166
+ nleftarrow: "↚",
1167
+ nRightarrow: "⇏",
1168
+ nLeftarrow: "⇍",
1169
+ nleftrightarrow: "↮",
1170
+ nLeftrightarrow: "⇎",
1171
+ looparrowright: "↬",
1172
+ looparrowleft: "↫",
1173
+ multimap: "⊸"
1174
+ };
1175
+ /** Brackets, which `\left`, `\right`, `\middle` and `\big` take too */
1176
+ var OPENING = {
1177
+ langle: "⟨",
1178
+ lceil: "⌈",
1179
+ lfloor: "⌊",
1180
+ lvert: "|",
1181
+ lVert: "‖",
1182
+ lbrace: "{",
1183
+ lbrack: "[",
1184
+ ulcorner: "⌜",
1185
+ llcorner: "⌞",
1186
+ lgroup: "⟮",
1187
+ lmoustache: "⎰",
1188
+ llbracket: "⟦"
1189
+ };
1190
+ var CLOSING = {
1191
+ rangle: "⟩",
1192
+ rceil: "⌉",
1193
+ rfloor: "⌋",
1194
+ rvert: "|",
1195
+ rVert: "‖",
1196
+ rbrace: "}",
1197
+ rbrack: "]",
1198
+ urcorner: "⌝",
1199
+ lrcorner: "⌟",
1200
+ rgroup: "⟯",
1201
+ rmoustache: "⎱",
1202
+ rrbracket: "⟧"
1203
+ };
1204
+ var ESCAPED_ORDINARY = Object.fromEntries([
1205
+ ["%", "%"],
1206
+ ["$", "$"],
1207
+ ["_", "_"],
1208
+ ["|", "‖"]
1209
+ ]);
1210
+ /** The symbols LaTeX writes with a command, by the command's name without its backslash */
1211
+ var SYMBOLS = new Map([
1212
+ ...withRole("ordinary", _objectSpread2(_objectSpread2({}, ORDINARY), ESCAPED_ORDINARY)),
1213
+ ...withRole("binary", BINARY),
1214
+ ...withRole("additive", ADDITIVE),
1215
+ ...withRole("relation", RELATION),
1216
+ ...withRole("open", _objectSpread2(_objectSpread2({}, OPENING), Object.fromEntries([["{", "{"]]))),
1217
+ ...withRole("close", _objectSpread2(_objectSpread2({}, CLOSING), Object.fromEntries([["}", "}"]])))
1218
+ ]);
1219
+ /** Characters typed as they are, which Word writes as another character or which play a part */
1220
+ var CHARACTERS = /* @__PURE__ */ new Map([
1221
+ ["+", {
1222
+ text: "+",
1223
+ role: "additive"
1224
+ }],
1225
+ ["-", {
1226
+ text: "−",
1227
+ role: "additive"
1228
+ }],
1229
+ ["*", {
1230
+ text: "∗",
1231
+ role: "binary"
1232
+ }],
1233
+ ["=", {
1234
+ text: "=",
1235
+ role: "relation"
1236
+ }],
1237
+ ["<", {
1238
+ text: "<",
1239
+ role: "relation"
1240
+ }],
1241
+ [">", {
1242
+ text: ">",
1243
+ role: "relation"
1244
+ }],
1245
+ [":", {
1246
+ text: ":",
1247
+ role: "relation"
1248
+ }],
1249
+ [",", {
1250
+ text: ",",
1251
+ role: "punctuation"
1252
+ }],
1253
+ [";", {
1254
+ text: ";",
1255
+ role: "punctuation"
1256
+ }],
1257
+ ["(", {
1258
+ text: "(",
1259
+ role: "open"
1260
+ }],
1261
+ ["[", {
1262
+ text: "[",
1263
+ role: "open"
1264
+ }],
1265
+ [")", {
1266
+ text: ")",
1267
+ role: "close"
1268
+ }],
1269
+ ["]", {
1270
+ text: "]",
1271
+ role: "close"
1272
+ }]
1273
+ ]);
1274
+ var ROLES_OF_CHARACTERS = new Map([...SYMBOLS.values(), ...CHARACTERS.values()].filter(({ text, role }) => role !== "ordinary" && text !== "|" && text !== "‖").map(({ text, role }) => [text, role]));
1275
+ /** The part a character plays, whether it was typed as it is or written with a command */
1276
+ var roleOf = (character) => {
1277
+ var _ROLES_OF_CHARACTERS$;
1278
+ return (_ROLES_OF_CHARACTERS$ = ROLES_OF_CHARACTERS.get(character)) !== null && _ROLES_OF_CHARACTERS$ !== void 0 ? _ROLES_OF_CHARACTERS$ : "ordinary";
1279
+ };
1280
+ /** The delimiters typed as they are, which `\left`, `\right`, `\middle` and `\big` take. A dot is none */
1281
+ var DELIMITER_CHARACTERS = /* @__PURE__ */ new Map([
1282
+ ["(", "("],
1283
+ [")", ")"],
1284
+ ["[", "["],
1285
+ ["]", "]"],
1286
+ ["|", "|"],
1287
+ ["/", "/"],
1288
+ ["<", "⟨"],
1289
+ [">", "⟩"],
1290
+ [".", ""]
1291
+ ]);
1292
+ /** The delimiters `\left`, `\right`, `\middle` and `\big` take, by their command's name */
1293
+ var DELIMITER_COMMANDS = new Map([
1294
+ ...Object.entries(OPENING),
1295
+ ...Object.entries(CLOSING),
1296
+ ["{", "{"],
1297
+ ["}", "}"],
1298
+ ["|", "‖"],
1299
+ ...Object.entries({
1300
+ vert: "|",
1301
+ Vert: "‖",
1302
+ backslash: "\\",
1303
+ uparrow: "↑",
1304
+ downarrow: "↓",
1305
+ updownarrow: "↕",
1306
+ Uparrow: "⇑",
1307
+ Downarrow: "⇓",
1308
+ Updownarrow: "⇕"
1309
+ })
1310
+ ]);
1311
+ /** Relations with a line through them, for `\not`: the character Unicode has for each */
1312
+ var NEGATIONS = /* @__PURE__ */ new Map([
1313
+ ["=", "≠"],
1314
+ ["<", "≮"],
1315
+ [">", "≯"],
1316
+ ["≤", "≰"],
1317
+ ["≥", "≱"],
1318
+ ["≡", "≢"],
1319
+ ["∼", "≁"],
1320
+ ["≃", "≄"],
1321
+ ["≈", "≉"],
1322
+ ["≅", "≇"],
1323
+ ["∈", "∉"],
1324
+ ["∋", "∌"],
1325
+ ["⊂", "⊄"],
1326
+ ["⊃", "⊅"],
1327
+ ["⊆", "⊈"],
1328
+ ["⊇", "⊉"],
1329
+ ["∣", "∤"],
1330
+ ["∥", "∦"],
1331
+ ["≺", "⊀"],
1332
+ ["≻", "⊁"],
1333
+ ["⊢", "⊬"],
1334
+ ["⊨", "⊭"],
1335
+ ["∃", "∄"],
1336
+ ["→", "↛"],
1337
+ ["←", "↚"],
1338
+ ["↔", "↮"],
1339
+ ["⇒", "⇏"],
1340
+ ["⇐", "⇍"],
1341
+ ["⇔", "⇎"]
1342
+ ]);
1343
+ /** Spaces, by their command's name */
1344
+ var SPACES = /* @__PURE__ */ new Map([
1345
+ [",", " "],
1346
+ ["thinspace", " "],
1347
+ [":", " "],
1348
+ [">", " "],
1349
+ ["medspace", " "],
1350
+ [";", " "],
1351
+ ["thickspace", " "],
1352
+ [" ", " "],
1353
+ ["space", " "],
1354
+ ["enspace", " "],
1355
+ ["quad", " "],
1356
+ ["qquad", "  "],
1357
+ ["!", ""],
1358
+ ["negthinspace", ""],
1359
+ ["negmedspace", ""],
1360
+ ["negthickspace", ""]
1361
+ ]);
1362
+ /** Functions, which LaTeX writes upright with a thin space after them */
1363
+ var FUNCTIONS = {
1364
+ arccos: "arccos",
1365
+ arcsin: "arcsin",
1366
+ arctan: "arctan",
1367
+ arg: "arg",
1368
+ cos: "cos",
1369
+ cosh: "cosh",
1370
+ cot: "cot",
1371
+ coth: "coth",
1372
+ csc: "csc",
1373
+ deg: "deg",
1374
+ dim: "dim",
1375
+ exp: "exp",
1376
+ hom: "hom",
1377
+ ker: "ker",
1378
+ lg: "lg",
1379
+ ln: "ln",
1380
+ log: "log",
1381
+ sec: "sec",
1382
+ sin: "sin",
1383
+ sinh: "sinh",
1384
+ tan: "tan",
1385
+ tanh: "tanh"
1386
+ };
1387
+ /** Functions whose limits go below them in a display, such as lim with x → 0 below it */
1388
+ var FUNCTIONS_WITH_LIMITS = {
1389
+ det: "det",
1390
+ gcd: "gcd",
1391
+ inf: "inf",
1392
+ lim: "lim",
1393
+ liminf: "lim inf",
1394
+ limsup: "lim sup",
1395
+ max: "max",
1396
+ min: "min",
1397
+ Pr: "Pr",
1398
+ sup: "sup"
1399
+ };
1400
+ /** Large operators, by their command's name */
1401
+ var LARGE_OPERATOR_COMMANDS = {
1402
+ sum: "sum",
1403
+ prod: "product",
1404
+ coprod: "coproduct",
1405
+ bigcup: "union",
1406
+ bigcap: "intersection",
1407
+ bigsqcup: "squareUnion",
1408
+ biguplus: "multisetUnion",
1409
+ bigvee: "logicalOr",
1410
+ bigwedge: "logicalAnd",
1411
+ bigoplus: "directSum",
1412
+ bigotimes: "tensorProduct",
1413
+ bigodot: "circledDot",
1414
+ int: "integral",
1415
+ iint: "doubleIntegral",
1416
+ iiint: "tripleIntegral",
1417
+ iiiint: "quadrupleIntegral",
1418
+ oint: "contourIntegral",
1419
+ oiint: "surfaceIntegral",
1420
+ oiiint: "volumeIntegral"
1421
+ };
1422
+ /** Accents, by their command's name */
1423
+ var ACCENT_COMMANDS = {
1424
+ hat: "hat",
1425
+ widehat: "hat",
1426
+ check: "check",
1427
+ widecheck: "check",
1428
+ tilde: "tilde",
1429
+ widetilde: "tilde",
1430
+ acute: "acute",
1431
+ grave: "grave",
1432
+ dot: "dot",
1433
+ ddot: "doubleDot",
1434
+ dddot: "tripleDot",
1435
+ breve: "breve",
1436
+ bar: "bar",
1437
+ mathring: "ring",
1438
+ vec: "rightArrow",
1439
+ overrightarrow: "rightArrow",
1440
+ overleftarrow: "leftArrow",
1441
+ overleftrightarrow: "leftRightArrow",
1442
+ overrightharpoon: "rightHarpoon",
1443
+ overleftharpoon: "leftHarpoon"
1444
+ };
1445
+ /** Braces over and under math, by their command's name */
1446
+ var BRACE_COMMANDS = {
1447
+ overbrace: {
1448
+ brace: "curly",
1449
+ position: "above"
1450
+ },
1451
+ underbrace: {
1452
+ brace: "curly",
1453
+ position: "below"
1454
+ },
1455
+ overbracket: {
1456
+ brace: "square",
1457
+ position: "above"
1458
+ },
1459
+ underbracket: {
1460
+ brace: "square",
1461
+ position: "below"
1462
+ },
1463
+ overparen: {
1464
+ brace: "round",
1465
+ position: "above"
1466
+ },
1467
+ underparen: {
1468
+ brace: "round",
1469
+ position: "below"
1470
+ }
1471
+ };
1472
+ /** Arrows that stretch to fit text above and below them, by their command's name */
1473
+ var EXTENSIBLE_ARROWS = {
1474
+ xrightarrow: "→",
1475
+ xleftarrow: "←",
1476
+ xleftrightarrow: "↔",
1477
+ xRightarrow: "⇒",
1478
+ xLeftarrow: "⇐",
1479
+ xLeftrightarrow: "⇔",
1480
+ xmapsto: "↦",
1481
+ xhookrightarrow: "↪",
1482
+ xhookleftarrow: "↩",
1483
+ xrightharpoonup: "⇀",
1484
+ xrightleftharpoons: "⇌"
1485
+ };
1486
+ //#endregion
1487
+ //#region src/math/latex/latex-parser.ts
1488
+ /**
1489
+ * Reads LaTeX math into atoms: rows of cells, as a matrix or aligned equations have them, or one row of one cell.
1490
+ *
1491
+ * @module
1492
+ */
1493
+ /** The commands that end a list of atoms, for what comes before it to take */
1494
+ var LIST_ENDS = /* @__PURE__ */ new Set([
1495
+ "right",
1496
+ "middle",
1497
+ "end",
1498
+ "\\"
1499
+ ]);
1500
+ var TEXT_COMMANDS = /* @__PURE__ */ new Set([
1501
+ "text",
1502
+ "textrm",
1503
+ "textnormal",
1504
+ "textup",
1505
+ "textmd",
1506
+ "textbf",
1507
+ "textit",
1508
+ "textsl",
1509
+ "textsf",
1510
+ "texttt",
1511
+ "emph",
1512
+ "mbox",
1513
+ "hbox"
1514
+ ]);
1515
+ var plainOrBold = (font) => font.style === "bold" || font.style === "boldItalic" ? "bold" : "plain";
1516
+ /** Commands that write their argument in a font, and what each does to the font around it */
1517
+ var FONT_COMMANDS = {
1518
+ mathrm: () => ({ style: "plain" }),
1519
+ mathup: () => ({ style: "plain" }),
1520
+ mathnormal: () => ({}),
1521
+ mathit: () => ({ style: "italic" }),
1522
+ mathbf: (font) => ({
1523
+ script: font.script,
1524
+ style: "bold"
1525
+ }),
1526
+ bold: (font) => ({
1527
+ script: font.script,
1528
+ style: "bold"
1529
+ }),
1530
+ boldsymbol: (font) => ({
1531
+ script: font.script,
1532
+ style: "boldItalic"
1533
+ }),
1534
+ bm: (font) => ({
1535
+ script: font.script,
1536
+ style: "boldItalic"
1537
+ }),
1538
+ pmb: (font) => ({
1539
+ script: font.script,
1540
+ style: "boldItalic"
1541
+ }),
1542
+ mathbb: (font) => ({
1543
+ script: "doubleStruck",
1544
+ style: plainOrBold(font)
1545
+ }),
1546
+ Bbb: (font) => ({
1547
+ script: "doubleStruck",
1548
+ style: plainOrBold(font)
1549
+ }),
1550
+ mathcal: (font) => ({
1551
+ script: "script",
1552
+ style: plainOrBold(font)
1553
+ }),
1554
+ mathscr: (font) => ({
1555
+ script: "script",
1556
+ style: plainOrBold(font)
1557
+ }),
1558
+ mathfrak: (font) => ({
1559
+ script: "fraktur",
1560
+ style: plainOrBold(font)
1561
+ }),
1562
+ mathsf: (font) => ({
1563
+ script: "sansSerif",
1564
+ style: plainOrBold(font)
1565
+ }),
1566
+ mathtt: (font) => ({
1567
+ script: "monospace",
1568
+ style: plainOrBold(font)
1569
+ })
1570
+ };
1571
+ /** The old commands that change the font for the rest of their group, such as `{\bf x}` */
1572
+ var FONT_SWITCHES = {
1573
+ rm: "mathrm",
1574
+ bf: "mathbf",
1575
+ it: "mathit",
1576
+ sf: "mathsf",
1577
+ tt: "mathtt",
1578
+ cal: "mathcal"
1579
+ };
1580
+ /** Commands written between a numerator and a denominator, such as `{a \over b}` */
1581
+ var INFIX_FRACTIONS = {
1582
+ over: {},
1583
+ atop: { type: "noBar" },
1584
+ choose: {
1585
+ type: "noBar",
1586
+ brackets: ["(", ")"]
1587
+ },
1588
+ brace: {
1589
+ type: "noBar",
1590
+ brackets: ["{", "}"]
1591
+ },
1592
+ brack: {
1593
+ type: "noBar",
1594
+ brackets: ["[", "]"]
1595
+ }
1596
+ };
1597
+ /** Commands that are nothing to Word: sizes, spacing it works out itself, and labels */
1598
+ var IGNORED = /* @__PURE__ */ new Set([
1599
+ "displaystyle",
1600
+ "textstyle",
1601
+ "scriptstyle",
1602
+ "scriptscriptstyle",
1603
+ "nonumber",
1604
+ "notag",
1605
+ "limits",
1606
+ "nolimits",
1607
+ "allowbreak",
1608
+ "nobreak",
1609
+ "hline",
1610
+ "hdashline",
1611
+ "/"
1612
+ ]);
1613
+ /** Commands that are nothing to Word and take an argument, which is left out */
1614
+ var IGNORED_WITH_ARGUMENT = /* @__PURE__ */ new Set([
1615
+ "label",
1616
+ "cline",
1617
+ "color"
1618
+ ]);
1619
+ var MATRIX_BRACKETS = {
1620
+ matrix: "none",
1621
+ smallmatrix: "none",
1622
+ pmatrix: "round",
1623
+ bmatrix: "square",
1624
+ Bmatrix: "curly",
1625
+ vmatrix: "verticalBars",
1626
+ Vmatrix: "doubleVerticalBars"
1627
+ };
1628
+ var ALIGNED_ENVIRONMENTS = /* @__PURE__ */ new Set([
1629
+ "align",
1630
+ "aligned",
1631
+ "alignat",
1632
+ "alignedat",
1633
+ "flalign",
1634
+ "eqnarray",
1635
+ "split",
1636
+ "gather",
1637
+ "gathered",
1638
+ "multline"
1639
+ ]);
1640
+ /** Environments that hold one equation, and are only numbered with `\tag` */
1641
+ var EQUATION_ENVIRONMENTS = /* @__PURE__ */ new Set([
1642
+ "equation",
1643
+ "displaymath",
1644
+ "math"
1645
+ ]);
1646
+ var COLUMN_ALIGNMENTS = {
1647
+ l: "left",
1648
+ c: "center",
1649
+ r: "right"
1650
+ };
1651
+ var PRIMES = [
1652
+ "′",
1653
+ "″",
1654
+ "‴",
1655
+ "⁗"
1656
+ ];
1657
+ /** What LaTeX writes for some characters typed next to each other in text, such as an en dash for -- */
1658
+ var LIGATURES = [
1659
+ ["---", "—"],
1660
+ ["--", "–"],
1661
+ ["``", "“"],
1662
+ ["''", "”"],
1663
+ ["`", "‘"],
1664
+ ["'", "’"],
1665
+ ["~", "\xA0"]
1666
+ ];
1667
+ /**
1668
+ * Math of rows: aligned equations, each row's cells as the parts lined up at their `&`s, with its number.
1669
+ */
1670
+ var equationArrayOf = (rows) => new MathEquationArray({ rows: rows.map(({ cells, tag }) => ({
1671
+ parts: cells.map(atomsToMath),
1672
+ equationNumber: tag
1673
+ })) });
1674
+ /**
1675
+ * Reads the LaTeX from `from` to `to` in `source` into rows of cells.
1676
+ *
1677
+ * @throws If the LaTeX has a command, an environment or a character it doesn't know, or isn't well formed
1678
+ */
1679
+ var parseLatex = (source, from, to) => {
1680
+ let index = from;
1681
+ const fail = (problem, at = index) => {
1682
+ const start = Math.max(from, at - 30);
1683
+ const end = Math.min(to, at + 30);
1684
+ const excerpt = `${start > from ? "…" : ""}${source.slice(start, end)}${end < to ? "…" : ""}`;
1685
+ throw new Error(`latexToMath: ${problem}, at character ${at + 1} of "${excerpt}"`);
1686
+ };
1687
+ const skipSpace = () => {
1688
+ while (index < to) if (source[index] === "%") while (index < to && source[index] !== "\n") index++;
1689
+ else if (/\s/.test(source[index])) index++;
1690
+ else return;
1691
+ };
1692
+ const tokenAt = (at) => {
1693
+ if (at >= to) return;
1694
+ if (source[at] === "\\") {
1695
+ if (at + 1 >= to) return fail("a backslash ends the LaTeX, with no command after it", at);
1696
+ const letters = /^[a-zA-Z]+/.exec(source.slice(at + 1, to));
1697
+ if (letters) return {
1698
+ token: {
1699
+ type: "command",
1700
+ name: letters[0],
1701
+ start: at
1702
+ },
1703
+ next: at + 1 + letters[0].length
1704
+ };
1705
+ const escaped = String.fromCodePoint(source.codePointAt(at + 1));
1706
+ return {
1707
+ token: {
1708
+ type: "command",
1709
+ name: /\s/.test(escaped) ? " " : escaped,
1710
+ start: at
1711
+ },
1712
+ next: at + 1 + escaped.length
1713
+ };
1714
+ }
1715
+ const character = String.fromCodePoint(source.codePointAt(at));
1716
+ return {
1717
+ token: {
1718
+ type: "character",
1719
+ value: character,
1720
+ start: at
1721
+ },
1722
+ next: at + character.length
1723
+ };
1724
+ };
1725
+ const peek = () => {
1726
+ var _tokenAt;
1727
+ skipSpace();
1728
+ return (_tokenAt = tokenAt(index)) === null || _tokenAt === void 0 ? void 0 : _tokenAt.token;
1729
+ };
1730
+ const next = () => {
1731
+ skipSpace();
1732
+ const read = tokenAt(index);
1733
+ if (read !== void 0) index = read.next;
1734
+ return read === null || read === void 0 ? void 0 : read.token;
1735
+ };
1736
+ const isCharacter = (token, value) => (token === null || token === void 0 ? void 0 : token.type) === "character" && token.value === value;
1737
+ const isCommand = (token, name) => (token === null || token === void 0 ? void 0 : token.type) === "command" && token.name === name;
1738
+ /** Reads a star after a command, as in `\operatorname*` */
1739
+ const readStar = () => {
1740
+ if (isCharacter(peek(), "*")) {
1741
+ next();
1742
+ return true;
1743
+ }
1744
+ return false;
1745
+ };
1746
+ /** Reads what is between braces as it is, such as an environment's name */
1747
+ const readRawGroup = (what) => {
1748
+ skipSpace();
1749
+ if (source[index] !== "{") return fail(`${what} needs an argument in braces`);
1750
+ const start = index;
1751
+ let depth = 0;
1752
+ for (; index < to; index++) if (source[index] === "\\") index++;
1753
+ else if (source[index] === "{") depth++;
1754
+ else if (source[index] === "}" && --depth === 0) {
1755
+ index++;
1756
+ return source.slice(start + 1, index - 1).trim();
1757
+ }
1758
+ return fail(`${what}'s argument has no closing }`, start);
1759
+ };
1760
+ /** Reads what is between square brackets as it is, such as `\smash[t]`'s option, if there are any */
1761
+ const readRawOption = () => {
1762
+ skipSpace();
1763
+ if (source[index] !== "[") return;
1764
+ const end = source.indexOf("]", index);
1765
+ if (end === -1 || end >= to) return fail("a [ has no closing ]");
1766
+ const option = source.slice(index + 1, end).trim();
1767
+ index = end + 1;
1768
+ return option;
1769
+ };
1770
+ const text = (value, font, role = "ordinary") => ({
1771
+ kind: "text",
1772
+ text: value,
1773
+ font,
1774
+ role
1775
+ });
1776
+ const isPlainFont = (font) => font.style === void 0 && font.script === void 0 && !font.normalText;
1777
+ /** Says what is wrong with a token that ends a list where it can't */
1778
+ const unexpected = (token) => {
1779
+ if (isCharacter(token, "&") || isCommand(token, "\\")) return fail(`${token.type === "command" ? "a \\\\" : "an &"} can only go between the rows and cells of a matrix or of aligned equations, not inside braces, brackets or \\left and \\right`, token.start);
1780
+ if (isCharacter(token, "}")) return fail("a } has no { before it", token.start);
1781
+ return token.type === "command" && token.name !== "end" ? fail(`\\${token.name} has no \\left before it`, token.start) : fail("\\end has no \\begin before it", token.start);
1782
+ };
1783
+ /** Reads the closing character of what a list is in, or says what is wrong */
1784
+ const readClosing = (end, closing, what, at) => {
1785
+ if (isCharacter(end, closing)) {
1786
+ next();
1787
+ return;
1788
+ }
1789
+ if (end === void 0) fail(`${what} has no closing ${closing}`, at);
1790
+ unexpected(end);
1791
+ };
1792
+ /**
1793
+ * Reads atoms up to the end of their list: a closing brace, a `&` or `\\`, `\right`, `\middle` or `\end`, the
1794
+ * closing character given, or the end of the LaTeX. The token at the end isn't read.
1795
+ */
1796
+ const parseList = (outer, closing) => {
1797
+ let atoms = [];
1798
+ let font = outer;
1799
+ let infix;
1800
+ for (let token = peek(); token !== void 0; token = peek()) {
1801
+ if (token.type === "character" && (token.value === "}" || token.value === "&" || token.value === closing)) break;
1802
+ if (token.type === "command" && LIST_ENDS.has(token.name)) break;
1803
+ if (token.type === "command" && hasEntry(FONT_SWITCHES, token.name)) {
1804
+ next();
1805
+ font = FONT_COMMANDS[FONT_SWITCHES[token.name]](font);
1806
+ continue;
1807
+ }
1808
+ if (token.type === "command" && hasEntry(INFIX_FRACTIONS, token.name)) {
1809
+ next();
1810
+ if (infix !== void 0) fail(`\\${token.name} follows \\${infix.name} in the same group. Put one of them in braces`, token.start);
1811
+ infix = {
1812
+ name: token.name,
1813
+ numerator: atoms
1814
+ };
1815
+ atoms = [];
1816
+ continue;
1817
+ }
1818
+ atoms = [...atoms, ...parseAtom(font)];
1819
+ }
1820
+ if (infix === void 0) return {
1821
+ atoms,
1822
+ end: peek()
1823
+ };
1824
+ const { type, brackets } = INFIX_FRACTIONS[infix.name];
1825
+ const fraction = new MathFraction$1({
1826
+ numerator: orSpace(atomsToMath(infix.numerator)),
1827
+ denominator: orSpace(atomsToMath(atoms)),
1828
+ type
1829
+ });
1830
+ return {
1831
+ atoms: [{
1832
+ kind: "built",
1833
+ component: brackets ? new MathBrackets({
1834
+ open: brackets[0],
1835
+ close: brackets[1],
1836
+ children: [fraction]
1837
+ }) : fraction
1838
+ }],
1839
+ end: peek()
1840
+ };
1841
+ };
1842
+ /**
1843
+ * Reads a command's argument: a group in braces, or one token, such as the 1 and 2 of `\frac12`.
1844
+ */
1845
+ const readArgument = (font, what) => {
1846
+ const token = peek();
1847
+ if (token === void 0 || token.type === "character" && [
1848
+ "}",
1849
+ "&",
1850
+ "^",
1851
+ "_"
1852
+ ].includes(token.value) || token.type === "command" && LIST_ENDS.has(token.name)) {
1853
+ var _token$start;
1854
+ return fail(`${what} needs an argument`, (_token$start = token === null || token === void 0 ? void 0 : token.start) !== null && _token$start !== void 0 ? _token$start : index);
1855
+ }
1856
+ if (isCharacter(token, "{")) {
1857
+ next();
1858
+ const { atoms, end } = parseList(font);
1859
+ readClosing(end, "}", `${what}'s argument`, token.start);
1860
+ return atoms;
1861
+ }
1862
+ const atom = parsePrimary(font, false);
1863
+ return atom === void 0 ? [] : [atom];
1864
+ };
1865
+ /** Reads an argument in square brackets, as `\sqrt[3]{x}` has, if there is one */
1866
+ const readOptionalArgument = (font, what) => {
1867
+ skipSpace();
1868
+ if (source[index] !== "[") return;
1869
+ const start = index;
1870
+ index++;
1871
+ const { atoms, end } = parseList(font, "]");
1872
+ readClosing(end, "]", `${what}'s option`, start);
1873
+ return atoms;
1874
+ };
1875
+ const readMath = (font, what) => atomsToMath(readArgument(font, what));
1876
+ /** Reads an atom, and the subscripts, superscripts and primes after it */
1877
+ const parseAtom = (font) => {
1878
+ var _PRIMES, _sup;
1879
+ const base = parsePrimary(font, true);
1880
+ if (base === void 0) return [];
1881
+ let sub;
1882
+ let sup;
1883
+ let primes = 0;
1884
+ for (let token = peek(); (token === null || token === void 0 ? void 0 : token.type) === "character"; token = peek()) if (token.value === "'") {
1885
+ if (sup !== void 0) fail("a prime follows a superscript. Put the prime first, as in f'^2", token.start);
1886
+ next();
1887
+ primes++;
1888
+ } else if (token.value === "^") {
1889
+ if (sup !== void 0) fail("there are two superscripts in a row. Put them in braces, as in x^{ab}", token.start);
1890
+ next();
1891
+ sup = readArgument(font, "^");
1892
+ } else if (token.value === "_") {
1893
+ if (sub !== void 0) fail("there are two subscripts in a row. Put them in braces, as in x_{ab}", token.start);
1894
+ next();
1895
+ sub = readArgument(font, "_");
1896
+ } else break;
1897
+ const superscript = primes === 0 ? sup : [text((_PRIMES = PRIMES[primes - 1]) !== null && _PRIMES !== void 0 ? _PRIMES : "′".repeat(primes), font), ...(_sup = sup) !== null && _sup !== void 0 ? _sup : []];
1898
+ if (sub === void 0 && superscript === void 0) return [base];
1899
+ if (base.kind === "operator" || base.kind === "function") return [_objectSpread2(_objectSpread2({}, base), {}, {
1900
+ sub,
1901
+ sup: superscript
1902
+ })];
1903
+ return [{
1904
+ kind: "scripts",
1905
+ base: base.kind === "group" ? base.atoms : [base],
1906
+ sub,
1907
+ sup: superscript
1908
+ }];
1909
+ };
1910
+ /**
1911
+ * Reads one atom, without its scripts, or nothing for a command that writes nothing. Digits are read as one number
1912
+ * when `numbers` is true, but not in an argument of one token, as the 1 and 2 of `\frac12`.
1913
+ */
1914
+ const parsePrimary = (font, numbers) => {
1915
+ const token = next();
1916
+ if (token.type === "command") return parseCommand(token, font);
1917
+ const { value } = token;
1918
+ switch (value) {
1919
+ case "{": {
1920
+ const { atoms, end } = parseList(font);
1921
+ readClosing(end, "}", "a {", token.start);
1922
+ return {
1923
+ kind: "group",
1924
+ atoms
1925
+ };
1926
+ }
1927
+ case "^":
1928
+ case "_":
1929
+ case "'":
1930
+ index = token.start;
1931
+ return {
1932
+ kind: "group",
1933
+ atoms: []
1934
+ };
1935
+ case "~": return text("\xA0", font);
1936
+ case "$": return fail("a $ can only end math that is in \\text", token.start);
1937
+ }
1938
+ if (numbers && /\d/.test(value)) {
1939
+ const [digits] = /^\d*(?:\.\d+)*/.exec(source.slice(index, to));
1940
+ index += digits.length;
1941
+ return text(value + digits, font);
1942
+ }
1943
+ const character = CHARACTERS.get(value);
1944
+ return character === void 0 ? text(value, font, roleOf(value)) : text(character.text, font, character.role);
1945
+ };
1946
+ /** Reads `\limits` or `\nolimits` after a large operator or function, if there is one */
1947
+ const readLimits = () => {
1948
+ const token = peek();
1949
+ if (isCommand(token, "limits")) {
1950
+ next();
1951
+ return "aboveBelow";
1952
+ }
1953
+ if (isCommand(token, "nolimits")) {
1954
+ next();
1955
+ return "side";
1956
+ }
1957
+ };
1958
+ const functionAtom = (name, limitsBelow) => {
1959
+ const limits = readLimits();
1960
+ return {
1961
+ kind: "function",
1962
+ name,
1963
+ limitsBelow: limits === void 0 ? limitsBelow : limits === "aboveBelow"
1964
+ };
1965
+ };
1966
+ /** Reads a delimiter, for `\left`, `\right`, `\middle` and `\big` */
1967
+ const readDelimiter = (what) => {
1968
+ var _DELIMITER_CHARACTERS;
1969
+ const token = next();
1970
+ if (token === void 0) return fail(`${what} needs a delimiter after it, such as ( or \\langle`);
1971
+ if (token.type === "command") {
1972
+ var _DELIMITER_COMMANDS$g;
1973
+ return (_DELIMITER_COMMANDS$g = DELIMITER_COMMANDS.get(token.name)) !== null && _DELIMITER_COMMANDS$g !== void 0 ? _DELIMITER_COMMANDS$g : fail(`${what} can't take \\${token.name}, which isn't a delimiter`, token.start);
1974
+ }
1975
+ const role = roleOf(token.value);
1976
+ return (_DELIMITER_CHARACTERS = DELIMITER_CHARACTERS.get(token.value)) !== null && _DELIMITER_CHARACTERS !== void 0 ? _DELIMITER_CHARACTERS : role === "open" || role === "close" ? token.value : fail(`${what} can't take "${token.value}", which isn't a delimiter`, token.start);
1977
+ };
1978
+ const parseLeftRight = (font, start) => {
1979
+ const open = readDelimiter("\\left");
1980
+ let items = [];
1981
+ let separators = [];
1982
+ for (;;) {
1983
+ const { atoms, end } = parseList(font);
1984
+ items = [...items, atoms];
1985
+ if (isCommand(end, "middle")) {
1986
+ next();
1987
+ separators = [...separators, readDelimiter("\\middle")];
1988
+ } else if (isCommand(end, "right")) {
1989
+ next();
1990
+ break;
1991
+ } else if (end === void 0) return fail("\\left has no \\right", start);
1992
+ else unexpected(end);
1993
+ }
1994
+ const close = readDelimiter("\\right");
1995
+ const converted = items.map(atomsToMath);
1996
+ if (converted.length === 1) return {
1997
+ kind: "built",
1998
+ component: new MathBrackets({
1999
+ open,
2000
+ close,
2001
+ children: converted[0]
2002
+ })
2003
+ };
2004
+ if (separators.every((separator) => separator === separators[0])) return {
2005
+ kind: "built",
2006
+ component: new MathBrackets({
2007
+ open,
2008
+ close,
2009
+ separator: separators[0],
2010
+ items: converted
2011
+ })
2012
+ };
2013
+ return {
2014
+ kind: "built",
2015
+ component: new MathBrackets({
2016
+ open,
2017
+ close,
2018
+ children: converted.flatMap((item, itemIndex) => itemIndex === 0 ? item : [new MathRun$1(separators[itemIndex - 1]), ...item])
2019
+ })
2020
+ };
2021
+ };
2022
+ /** Reads `\text` and its like: normal text, which can hold math between dollar signs */
2023
+ const parseText = (what) => {
2024
+ const font = { normalText: true };
2025
+ skipSpace();
2026
+ if (source[index] !== "{") {
2027
+ const token = next();
2028
+ return (token === null || token === void 0 ? void 0 : token.type) === "character" ? [text(token.value, font)] : fail(`${what} needs an argument`);
2029
+ }
2030
+ const start = index;
2031
+ index++;
2032
+ let atoms = [];
2033
+ let written = "";
2034
+ let depth = 0;
2035
+ const flush = () => {
2036
+ if (written !== "") {
2037
+ atoms = [...atoms, text(written, font)];
2038
+ written = "";
2039
+ }
2040
+ };
2041
+ for (;;) {
2042
+ if (index >= to) return fail(`${what}'s argument has no closing }`, start);
2043
+ const character = source[index];
2044
+ if (character === "}") {
2045
+ index++;
2046
+ if (depth === 0) break;
2047
+ depth--;
2048
+ } else if (character === "{") {
2049
+ index++;
2050
+ depth++;
2051
+ } else if (character === "$") {
2052
+ flush();
2053
+ index++;
2054
+ const { atoms: math, end } = parseList({}, "$");
2055
+ readClosing(end, "$", "math in text", index);
2056
+ atoms = [...atoms, ...math];
2057
+ } else if (character === "\\") {
2058
+ const { token, next: after } = tokenAt(index);
2059
+ const { name } = token;
2060
+ index = after;
2061
+ if (/^[a-zA-Z]+$/.test(name)) while (index < to && /[ \t]/.test(source[index])) index++;
2062
+ if (TEXT_COMMANDS.has(name)) {
2063
+ flush();
2064
+ atoms = [...atoms, ...parseText(`\\${name}`)];
2065
+ } else if (SPACES.has(name)) written += name === " " ? " " : SPACES.get(name);
2066
+ else if ([
2067
+ "&",
2068
+ "%",
2069
+ "$",
2070
+ "#",
2071
+ "_",
2072
+ "{",
2073
+ "}"
2074
+ ].includes(name)) written += name;
2075
+ else if (name === "textbackslash") written += "\\";
2076
+ else if (name === "ldots" || name === "dots" || name === "textellipsis") written += "…";
2077
+ else fail(`unknown command \\${name} in text`, token.start);
2078
+ } else if (/\s/.test(character)) {
2079
+ written += written.endsWith(" ") ? "" : " ";
2080
+ index++;
2081
+ } else {
2082
+ const at = index;
2083
+ const ligature = LIGATURES.find(([characters]) => source.startsWith(characters, at));
2084
+ const typed = ligature ? ligature[0] : String.fromCodePoint(source.codePointAt(index));
2085
+ written += ligature ? ligature[1] : typed;
2086
+ index += typed.length;
2087
+ }
2088
+ }
2089
+ flush();
2090
+ return atoms;
2091
+ };
2092
+ /** Reads the rows and cells of an environment, or of the whole LaTeX when `environment` is undefined */
2093
+ const parseRows = (font, environment, begin) => {
2094
+ let rows = [];
2095
+ let cells = [];
2096
+ const endRow = () => {
2097
+ const tags = cells.flatMap((cell) => cell.filter((atom) => atom.kind === "tag"));
2098
+ const row = { cells: cells.map((cell) => cell.filter((atom) => atom.kind !== "tag")) };
2099
+ rows = [...rows, tags.length === 0 ? row : _objectSpread2(_objectSpread2({}, row), {}, { tag: tags[tags.length - 1].text })];
2100
+ cells = [];
2101
+ };
2102
+ for (;;) {
2103
+ const { atoms, end } = parseList(font);
2104
+ cells = [...cells, atoms];
2105
+ if (isCharacter(end, "&")) next();
2106
+ else if (isCommand(end, "\\")) {
2107
+ next();
2108
+ readRawOption();
2109
+ endRow();
2110
+ } else {
2111
+ endRow();
2112
+ if (environment === void 0) {
2113
+ if (end !== void 0) unexpected(end);
2114
+ } else if (isCommand(end, "end")) {
2115
+ next();
2116
+ const name = readRawGroup("\\end");
2117
+ if (name !== environment) fail(`\\begin{${environment}} ends with \\end{${name}}`, end.start);
2118
+ } else if (end === void 0) fail(`\\begin{${environment}} has no \\end{${environment}}`, begin);
2119
+ else unexpected(end);
2120
+ break;
2121
+ }
2122
+ }
2123
+ const last = rows[rows.length - 1];
2124
+ return rows.length > 1 && last.tag === void 0 && last.cells.length === 1 && last.cells[0].length === 0 ? rows.slice(0, -1) : rows;
2125
+ };
2126
+ const parseEnvironment = (font, start) => {
2127
+ const name = readRawGroup("\\begin");
2128
+ const base = name.replace(/\*$/, "");
2129
+ const cellsOf = (rows) => rows.map(({ cells }) => cells.map(atomsToMath));
2130
+ if (hasEntry(MATRIX_BRACKETS, base)) {
2131
+ const alignment = name.endsWith("*") ? readRawOption() : void 0;
2132
+ const rows = parseRows(font, name, start);
2133
+ return {
2134
+ kind: "built",
2135
+ component: new MathMatrix({
2136
+ brackets: MATRIX_BRACKETS[base],
2137
+ rows: cellsOf(rows),
2138
+ columnAlignment: hasEntry(COLUMN_ALIGNMENTS, alignment !== null && alignment !== void 0 ? alignment : "c") ? COLUMN_ALIGNMENTS[alignment !== null && alignment !== void 0 ? alignment : "c"] : fail(`\\begin{${name}} can't line its columns up "${alignment}"`, start)
2139
+ })
2140
+ };
2141
+ }
2142
+ if (base === "array" || base === "subarray") {
2143
+ readRawOption();
2144
+ const specification = [...readRawGroup(`\\begin{${name}}`).replace(/[@!]\{[^}]*\}/g, "").replace(/[pmb]\{[^}]*\}/g, "l")].map((letter) => COLUMN_ALIGNMENTS[letter]).filter((alignment) => alignment !== void 0);
2145
+ const rows = parseRows(font, name, start);
2146
+ const columns = Math.max(...rows.map(({ cells }) => cells.length));
2147
+ return {
2148
+ kind: "built",
2149
+ component: new MathMatrix({
2150
+ rows: cellsOf(rows),
2151
+ columnAlignment: Array.from({ length: columns }, (_, column) => {
2152
+ var _specification$column;
2153
+ return (_specification$column = specification[column]) !== null && _specification$column !== void 0 ? _specification$column : "center";
2154
+ })
2155
+ })
2156
+ };
2157
+ }
2158
+ if (base === "cases" || base === "dcases") return {
2159
+ kind: "built",
2160
+ component: new MathCases({ cases: parseRows(font, name, start).map(({ cells }, row) => {
2161
+ if (cells.length > 2) fail(`case ${row + 1} of \\begin{${name}} has ${cells.length} parts, but a case has at most two: its value & its condition`, start);
2162
+ const [value, condition] = cells.map(atomsToMath);
2163
+ return condition === void 0 ? { value } : {
2164
+ value,
2165
+ condition
2166
+ };
2167
+ }) })
2168
+ };
2169
+ if (base === "rcases" || base === "drcases") return {
2170
+ kind: "built",
2171
+ component: new MathBrackets({
2172
+ open: "",
2173
+ close: "}",
2174
+ children: [new MathMatrix({
2175
+ rows: cellsOf(parseRows(font, name, start)),
2176
+ columnAlignment: "left"
2177
+ })]
2178
+ })
2179
+ };
2180
+ if (ALIGNED_ENVIRONMENTS.has(base) || EQUATION_ENVIRONMENTS.has(base)) {
2181
+ if (base === "alignat" || base === "alignedat") readRawGroup(`\\begin{${name}}`);
2182
+ const rows = parseRows(font, name, start);
2183
+ return EQUATION_ENVIRONMENTS.has(base) && rows.length === 1 && rows[0].cells.length === 1 && rows[0].tag === void 0 ? {
2184
+ kind: "group",
2185
+ atoms: rows[0].cells[0]
2186
+ } : {
2187
+ kind: "built",
2188
+ component: equationArrayOf(rows)
2189
+ };
2190
+ }
2191
+ return fail(`unknown environment ${name}`, start);
2192
+ };
2193
+ const parseCommand = (token, font) => {
2194
+ const { name, start } = token;
2195
+ const what = `\\${name}`;
2196
+ if (name === "&" || name === "#") return text(name, _objectSpread2(_objectSpread2({}, font), {}, { literal: true }));
2197
+ if (hasEntry(UPRIGHT_GREEK, name)) return text(UPRIGHT_GREEK[name], isPlainFont(font) ? { style: "plain" } : font);
2198
+ if (hasEntry(ITALIC_GREEK, name)) return text(ITALIC_GREEK[name], isPlainFont(font) ? { style: "italic" } : font);
2199
+ const symbol = SYMBOLS.get(name);
2200
+ if (symbol !== void 0) return text(symbol.text, font, symbol.role);
2201
+ const width = SPACES.get(name);
2202
+ if (width !== void 0) return width === "" ? void 0 : text(width, font);
2203
+ if (hasEntry(FUNCTIONS, name)) return functionAtom([text(FUNCTIONS[name], { style: "plain" })], false);
2204
+ if (hasEntry(FUNCTIONS_WITH_LIMITS, name)) return functionAtom([text(FUNCTIONS_WITH_LIMITS[name], { style: "plain" })], true);
2205
+ if (hasEntry(LARGE_OPERATOR_COMMANDS, name)) return {
2206
+ kind: "operator",
2207
+ operator: LARGE_OPERATOR_COMMANDS[name],
2208
+ limits: readLimits()
2209
+ };
2210
+ if (hasEntry(ACCENT_COMMANDS, name)) return {
2211
+ kind: "built",
2212
+ component: new MathAccent({
2213
+ accent: ACCENT_COMMANDS[name],
2214
+ children: readMath(font, what)
2215
+ })
2216
+ };
2217
+ if (hasEntry(FONT_COMMANDS, name)) return {
2218
+ kind: "group",
2219
+ atoms: readArgument(FONT_COMMANDS[name](font), what)
2220
+ };
2221
+ if (TEXT_COMMANDS.has(name)) return {
2222
+ kind: "group",
2223
+ atoms: parseText(what)
2224
+ };
2225
+ if (hasEntry(BRACE_COMMANDS, name)) {
2226
+ const { brace, position } = BRACE_COMMANDS[name];
2227
+ const children = readMath(font, what);
2228
+ const labelled = isCharacter(peek(), position === "above" ? "^" : "_");
2229
+ if (labelled) next();
2230
+ return {
2231
+ kind: "built",
2232
+ component: new MathBrace({
2233
+ brace,
2234
+ position,
2235
+ children,
2236
+ label: labelled ? readMath(font, what) : void 0
2237
+ })
2238
+ };
2239
+ }
2240
+ if (hasEntry(EXTENSIBLE_ARROWS, name)) {
2241
+ const below = readOptionalArgument(font, what);
2242
+ const above = orSpace(readMath(font, what));
2243
+ const arrow = new MathLimitUpper$1({
2244
+ children: [new MathRun$1(EXTENSIBLE_ARROWS[name])],
2245
+ limit: above
2246
+ });
2247
+ return {
2248
+ kind: "built",
2249
+ role: "relation",
2250
+ component: below === void 0 ? arrow : new MathLimitLower$1({
2251
+ children: [arrow],
2252
+ limit: orSpace(atomsToMath(below))
2253
+ })
2254
+ };
2255
+ }
2256
+ if (/^[Bb]igg?[lrm]?$/.test(name)) {
2257
+ var _roles$name;
2258
+ const delimiter = readDelimiter(what);
2259
+ return delimiter === "" ? void 0 : text(delimiter, font, (_roles$name = {
2260
+ l: "open",
2261
+ r: "close",
2262
+ m: "relation"
2263
+ }[name[name.length - 1]]) !== null && _roles$name !== void 0 ? _roles$name : roleOf(delimiter));
2264
+ }
2265
+ if (IGNORED.has(name)) return;
2266
+ if (IGNORED_WITH_ARGUMENT.has(name)) {
2267
+ readRawGroup(what);
2268
+ return;
2269
+ }
2270
+ switch (name) {
2271
+ case "frac":
2272
+ case "dfrac":
2273
+ case "tfrac":
2274
+ case "cfrac":
2275
+ case "nicefrac":
2276
+ case "sfrac": {
2277
+ if (name === "cfrac") readRawOption();
2278
+ const numerator = orSpace(readMath(font, what));
2279
+ const denominator = orSpace(readMath(font, what));
2280
+ return {
2281
+ kind: "built",
2282
+ component: new MathFraction$1({
2283
+ numerator,
2284
+ denominator,
2285
+ type: name === "nicefrac" || name === "sfrac" ? "skewed" : void 0
2286
+ })
2287
+ };
2288
+ }
2289
+ case "binom":
2290
+ case "dbinom":
2291
+ case "tbinom": {
2292
+ const numerator = orSpace(readMath(font, what));
2293
+ const denominator = orSpace(readMath(font, what));
2294
+ return {
2295
+ kind: "built",
2296
+ component: new MathBrackets({ children: [new MathFraction$1({
2297
+ numerator,
2298
+ denominator,
2299
+ type: "noBar"
2300
+ })] })
2301
+ };
2302
+ }
2303
+ case "sqrt": {
2304
+ const degree = readOptionalArgument(font, what);
2305
+ const children = orSpace(readMath(font, what));
2306
+ return {
2307
+ kind: "built",
2308
+ component: new MathRadical$1(degree === void 0 || degree.length === 0 ? { children } : {
2309
+ children,
2310
+ degree: atomsToMath(degree)
2311
+ })
2312
+ };
2313
+ }
2314
+ case "left": return parseLeftRight(font, start);
2315
+ case "overline":
2316
+ case "underline": return {
2317
+ kind: "built",
2318
+ component: new MathBar({
2319
+ position: name === "overline" ? "above" : "below",
2320
+ children: readMath(font, what)
2321
+ })
2322
+ };
2323
+ case "overset":
2324
+ case "stackrel":
2325
+ case "underset": {
2326
+ const limit = orSpace(readMath(font, what));
2327
+ const base = readArgument(font, what);
2328
+ const children = orSpace(atomsToMath(base));
2329
+ return {
2330
+ kind: "built",
2331
+ role: name === "stackrel" ? "relation" : base.length === 1 && base[0].kind === "text" ? base[0].role : "ordinary",
2332
+ component: name === "underset" ? new MathLimitLower$1({
2333
+ children,
2334
+ limit
2335
+ }) : new MathLimitUpper$1({
2336
+ children,
2337
+ limit
2338
+ })
2339
+ };
2340
+ }
2341
+ case "operatorname": {
2342
+ const below = readStar();
2343
+ return functionAtom(readArgument({ style: "plain" }, what), below);
2344
+ }
2345
+ case "boxed": return {
2346
+ kind: "built",
2347
+ component: new MathBox({ children: readMath(font, what) })
2348
+ };
2349
+ case "fbox": return {
2350
+ kind: "built",
2351
+ component: new MathBox({ children: atomsToMath(parseText(what)) })
2352
+ };
2353
+ case "cancel":
2354
+ case "bcancel":
2355
+ case "xcancel": return {
2356
+ kind: "built",
2357
+ component: new MathBox({
2358
+ borders: [],
2359
+ strikes: {
2360
+ cancel: ["diagonalUp"],
2361
+ bcancel: ["diagonalDown"],
2362
+ xcancel: ["diagonalUp", "diagonalDown"]
2363
+ }[name],
2364
+ children: readMath(font, what)
2365
+ })
2366
+ };
2367
+ case "phantom":
2368
+ case "hphantom":
2369
+ case "vphantom":
2370
+ case "smash": {
2371
+ const option = name === "smash" ? readRawOption() : void 0;
2372
+ return {
2373
+ kind: "built",
2374
+ component: new MathPhantom(_objectSpread2(_objectSpread2({}, {
2375
+ phantom: {},
2376
+ hphantom: {
2377
+ height: false,
2378
+ depth: false
2379
+ },
2380
+ vphantom: { width: false },
2381
+ smash: {
2382
+ visible: true,
2383
+ height: option === "b",
2384
+ depth: option === "t"
2385
+ }
2386
+ }[name]), {}, { children: readMath(font, what) }))
2387
+ };
2388
+ }
2389
+ case "mathstrut": return {
2390
+ kind: "built",
2391
+ component: new MathPhantom({
2392
+ width: false,
2393
+ children: [new MathRun$1("(")]
2394
+ })
2395
+ };
2396
+ case "textcolor":
2397
+ readRawGroup(what);
2398
+ return {
2399
+ kind: "group",
2400
+ atoms: readArgument(font, what)
2401
+ };
2402
+ case "mathop":
2403
+ case "mathbin":
2404
+ case "mathrel":
2405
+ case "mathord":
2406
+ case "mathopen":
2407
+ case "mathclose":
2408
+ case "mathpunct":
2409
+ case "mathinner": return {
2410
+ kind: "group",
2411
+ atoms: readArgument(font, what)
2412
+ };
2413
+ case "not": {
2414
+ const negation = (relation) => {
2415
+ var _NEGATIONS$get;
2416
+ return text((_NEGATIONS$get = NEGATIONS.get(relation)) !== null && _NEGATIONS$get !== void 0 ? _NEGATIONS$get : `${relation}\u0338`, font, "relation");
2417
+ };
2418
+ const negated = peek();
2419
+ if ((negated === null || negated === void 0 ? void 0 : negated.type) === "character" && ![
2420
+ "{",
2421
+ "}",
2422
+ "^",
2423
+ "_",
2424
+ "&",
2425
+ "$"
2426
+ ].includes(negated.value)) {
2427
+ var _CHARACTERS$get$text, _CHARACTERS$get;
2428
+ next();
2429
+ return negation((_CHARACTERS$get$text = (_CHARACTERS$get = CHARACTERS.get(negated.value)) === null || _CHARACTERS$get === void 0 ? void 0 : _CHARACTERS$get.text) !== null && _CHARACTERS$get$text !== void 0 ? _CHARACTERS$get$text : negated.value);
2430
+ }
2431
+ if ((negated === null || negated === void 0 ? void 0 : negated.type) === "command" && SYMBOLS.has(negated.name)) {
2432
+ next();
2433
+ return negation(SYMBOLS.get(negated.name).text);
2434
+ }
2435
+ return fail("\\not needs a symbol after it, such as \\not= or \\not\\in", start);
2436
+ }
2437
+ case "bmod":
2438
+ case "mod": return {
2439
+ kind: "group",
2440
+ atoms: [
2441
+ text(name === "mod" ? " " : " ", font),
2442
+ text("mod", { style: "plain" }),
2443
+ text(" ", font)
2444
+ ]
2445
+ };
2446
+ case "pmod":
2447
+ case "pod": {
2448
+ const argument = readArgument(font, what);
2449
+ return {
2450
+ kind: "group",
2451
+ atoms: [
2452
+ text(" ", font),
2453
+ text("(", font, "open"),
2454
+ ...name === "pmod" ? [text("mod", { style: "plain" }), text(" ", font)] : [],
2455
+ ...argument,
2456
+ text(")", font, "close")
2457
+ ]
2458
+ };
2459
+ }
2460
+ case "hspace":
2461
+ readStar();
2462
+ readRawGroup(what);
2463
+ return text(" ", font);
2464
+ case "substack": {
2465
+ skipSpace();
2466
+ if (source[index] !== "{") return fail("\\substack needs an argument in braces");
2467
+ const open = index;
2468
+ index++;
2469
+ let rows = [];
2470
+ for (;;) {
2471
+ const { atoms, end } = parseList(font);
2472
+ rows = [...rows, atoms];
2473
+ if (isCommand(end, "\\")) next();
2474
+ else {
2475
+ readClosing(end, "}", "\\substack's argument", open);
2476
+ break;
2477
+ }
2478
+ }
2479
+ return {
2480
+ kind: "built",
2481
+ component: new MathMatrix({ rows: rows.map((row) => [atomsToMath(row)]) })
2482
+ };
2483
+ }
2484
+ case "tag": {
2485
+ const star = readStar();
2486
+ const tag = readRawGroup(what).replace(/\$/g, "");
2487
+ return {
2488
+ kind: "tag",
2489
+ text: star ? tag : `(${tag})`
2490
+ };
2491
+ }
2492
+ case "begin": return parseEnvironment(font, start);
2493
+ default: return fail(`unknown command ${what}`, start);
2494
+ }
2495
+ };
2496
+ return parseRows({}, void 0, from);
2497
+ };
2498
+ //#endregion
2499
+ //#region src/math/latex-to-math.ts
2500
+ var DELIMITERS = [
2501
+ ["$$", "$$"],
2502
+ ["\\[", "\\]"],
2503
+ ["\\(", "\\)"],
2504
+ ["$", "$"]
2505
+ ];
2506
+ /**
2507
+ * Turns LaTeX math into docx's math, to go in a `Math`, as Word's own equations, which it shows and edits as it does
2508
+ * those typed into it.
2509
+ *
2510
+ * It reads the math that LaTeX, MathJax and KaTeX write: fractions, scripts, roots, sums, integrals and other large
2511
+ * operators, functions such as sin and lim, brackets that grow with `\left` and `\right`, accents, braces, boxes,
2512
+ * fonts such as `\mathbb` and `\mathrm`, `\text`, Greek letters and symbols, and the environments for matrices,
2513
+ * cases and aligned equations, with `\tag` for their numbers. The math can be given in `$…$`, `$$…$$`, `\(…\)` or
2514
+ * `\[…\]`, which are left out.
2515
+ *
2516
+ * Colours, sizes and spacing that Word works out for itself are left out.
2517
+ *
2518
+ * @param latex - The LaTeX, such as `"\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}"`
2519
+ * @returns The math, to be the children of a `Math`, or to go among other math components
2520
+ * @throws If the LaTeX has a command or an environment it doesn't know, or isn't well formed, such as a `{` with no
2521
+ * `}`. The error says where
2522
+ *
2523
+ * @example
2524
+ * ```typescript
2525
+ * new Math({ children: latexToMath("x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}") });
2526
+ * ```
2527
+ */
2528
+ var latexToMath = (latex) => {
2529
+ var _DELIMITERS$find;
2530
+ const start = latex.length - latex.trimStart().length;
2531
+ const end = latex.trimEnd().length;
2532
+ const [open, close] = (_DELIMITERS$find = DELIMITERS.find(([opening, closing]) => end - start >= opening.length + closing.length && latex.startsWith(opening, start) && latex.endsWith(closing, end))) !== null && _DELIMITERS$find !== void 0 ? _DELIMITERS$find : ["", ""];
2533
+ const rows = parseLatex(latex, start + open.length, end - close.length);
2534
+ return rows.length === 1 && rows[0].cells.length === 1 && rows[0].tag === void 0 ? atomsToMath(rows[0].cells[0]) : [equationArrayOf(rows)];
2535
+ };
2536
+ //#endregion
2537
+ export { Math$1 as Math, MathAccent, MathAngledBrackets, MathBar, MathBox, MathBrace, MathBrackets, MathCases, MathCurlyBrackets, MathDegree, MathDenominator, MathEquationArray, MathFraction, MathFunction, MathFunctionName, MathFunctionProperties, MathIntegral, MathLargeOperator, MathLimit, MathLimitLower, MathLimitUpper, MathMatrix, MathNumerator, MathPhantom, MathPreSubSuperScript, MathRadical, MathRadicalProperties, MathRoundBrackets, MathRun, MathSquareBrackets, MathSubScript, MathSubSuperScript, MathSum, MathSuperScript, createMathAccentCharacter, createMathBase, createMathLimitLocation, createMathNAryProperties, createMathPreSubSuperScriptProperties, createMathSubScriptElement, createMathSubScriptProperties, createMathSubSuperScriptProperties, createMathSuperScriptElement, createMathSuperScriptProperties, latexToMath };