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