temml 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/contrib/auto-render/README.md +89 -0
  4. package/contrib/auto-render/auto-render.js +128 -0
  5. package/contrib/auto-render/dist/auto-render.js +217 -0
  6. package/contrib/auto-render/dist/auto-render.min.js +1 -0
  7. package/contrib/auto-render/splitAtDelimiters.js +84 -0
  8. package/contrib/auto-render/test/auto-render-spec.js +234 -0
  9. package/contrib/auto-render/test/auto-render.js +217 -0
  10. package/contrib/auto-render/test/test_page.html +59 -0
  11. package/contrib/mhchem/README.md +26 -0
  12. package/contrib/mhchem/mhchem.js +1705 -0
  13. package/contrib/mhchem/mhchem.min.js +1 -0
  14. package/contrib/physics/README.md +20 -0
  15. package/contrib/physics/physics.js +131 -0
  16. package/contrib/texvc/README.md +23 -0
  17. package/contrib/texvc/texvc.js +61 -0
  18. package/dist/Temml-Asana.css +201 -0
  19. package/dist/Temml-Latin-Modern.css +216 -0
  20. package/dist/Temml-Libertinus.css +214 -0
  21. package/dist/Temml-Local.css +194 -0
  22. package/dist/Temml-STIX2.css +203 -0
  23. package/dist/Temml.woff2 +0 -0
  24. package/dist/temml.cjs +13122 -0
  25. package/dist/temml.js +11225 -0
  26. package/dist/temml.min.js +1 -0
  27. package/dist/temml.mjs +13120 -0
  28. package/dist/temmlPostProcess.js +70 -0
  29. package/package.json +34 -0
  30. package/src/Lexer.js +121 -0
  31. package/src/MacroExpander.js +437 -0
  32. package/src/Namespace.js +107 -0
  33. package/src/ParseError.js +64 -0
  34. package/src/Parser.js +977 -0
  35. package/src/Settings.js +49 -0
  36. package/src/SourceLocation.js +29 -0
  37. package/src/Style.js +144 -0
  38. package/src/Token.js +40 -0
  39. package/src/buildMathML.js +235 -0
  40. package/src/constants.js +25 -0
  41. package/src/defineEnvironment.js +25 -0
  42. package/src/defineFunction.js +69 -0
  43. package/src/defineMacro.js +11 -0
  44. package/src/domTree.js +185 -0
  45. package/src/environments/array.js +791 -0
  46. package/src/environments/cd.js +252 -0
  47. package/src/environments.js +8 -0
  48. package/src/functions/accent.js +127 -0
  49. package/src/functions/accentunder.js +38 -0
  50. package/src/functions/arrow.js +204 -0
  51. package/src/functions/cancelto.js +36 -0
  52. package/src/functions/char.js +33 -0
  53. package/src/functions/color.js +253 -0
  54. package/src/functions/cr.js +46 -0
  55. package/src/functions/def.js +259 -0
  56. package/src/functions/delimsizing.js +304 -0
  57. package/src/functions/enclose.js +193 -0
  58. package/src/functions/envTag.js +38 -0
  59. package/src/functions/environment.js +59 -0
  60. package/src/functions/font.js +123 -0
  61. package/src/functions/genfrac.js +333 -0
  62. package/src/functions/hbox.js +29 -0
  63. package/src/functions/horizBrace.js +32 -0
  64. package/src/functions/href.js +90 -0
  65. package/src/functions/html.js +95 -0
  66. package/src/functions/includegraphics.js +131 -0
  67. package/src/functions/kern.js +75 -0
  68. package/src/functions/label.js +29 -0
  69. package/src/functions/lap.js +75 -0
  70. package/src/functions/math.js +40 -0
  71. package/src/functions/mathchoice.js +41 -0
  72. package/src/functions/mclass.js +201 -0
  73. package/src/functions/multiscript.js +91 -0
  74. package/src/functions/not.js +46 -0
  75. package/src/functions/op.js +338 -0
  76. package/src/functions/operatorname.js +139 -0
  77. package/src/functions/ordgroup.js +9 -0
  78. package/src/functions/phantom.js +73 -0
  79. package/src/functions/pmb.js +31 -0
  80. package/src/functions/raise.js +68 -0
  81. package/src/functions/ref.js +28 -0
  82. package/src/functions/relax.js +16 -0
  83. package/src/functions/rule.js +52 -0
  84. package/src/functions/sizing.js +64 -0
  85. package/src/functions/smash.js +66 -0
  86. package/src/functions/sqrt.js +31 -0
  87. package/src/functions/styling.js +58 -0
  88. package/src/functions/supsub.js +135 -0
  89. package/src/functions/symbolsOp.js +53 -0
  90. package/src/functions/symbolsOrd.js +102 -0
  91. package/src/functions/symbolsSpacing.js +53 -0
  92. package/src/functions/tag.js +8 -0
  93. package/src/functions/text.js +75 -0
  94. package/src/functions/tip.js +63 -0
  95. package/src/functions/toggle.js +13 -0
  96. package/src/functions/verb.js +33 -0
  97. package/src/functions.js +57 -0
  98. package/src/linebreaking.js +159 -0
  99. package/src/macros.js +708 -0
  100. package/src/mathMLTree.js +175 -0
  101. package/src/parseNode.js +42 -0
  102. package/src/parseTree.js +40 -0
  103. package/src/postProcess.js +57 -0
  104. package/src/replace.js +225 -0
  105. package/src/stretchy.js +66 -0
  106. package/src/svg.js +110 -0
  107. package/src/symbols.js +972 -0
  108. package/src/tree.js +50 -0
  109. package/src/unicodeAccents.js +16 -0
  110. package/src/unicodeScripts.js +119 -0
  111. package/src/unicodeSupOrSub.js +108 -0
  112. package/src/unicodeSymbolBuilder.js +31 -0
  113. package/src/unicodeSymbols.js +320 -0
  114. package/src/units.js +109 -0
  115. package/src/utils.js +109 -0
  116. package/src/variant.js +103 -0
  117. package/temml.js +181 -0
package/src/macros.js ADDED
@@ -0,0 +1,708 @@
1
+ /**
2
+ * Predefined macros for Temml.
3
+ * This can be used to define some commands in terms of others.
4
+ */
5
+
6
+ // Export global macros object from defineMacro
7
+ import defineMacro, { _macros } from "./defineMacro";
8
+ const macros = _macros;
9
+ export default macros;
10
+
11
+ import symbols from "./symbols";
12
+ import ParseError from "./ParseError";
13
+
14
+ //////////////////////////////////////////////////////////////////////
15
+ // macro tools
16
+
17
+ defineMacro("\\noexpand", function(context) {
18
+ // The expansion is the token itself; but that token is interpreted
19
+ // as if its meaning were ‘\relax’ if it is a control sequence that
20
+ // would ordinarily be expanded by TeX’s expansion rules.
21
+ const t = context.popToken();
22
+ if (context.isExpandable(t.text)) {
23
+ t.noexpand = true;
24
+ t.treatAsRelax = true;
25
+ }
26
+ return { tokens: [t], numArgs: 0 };
27
+ });
28
+
29
+ defineMacro("\\expandafter", function(context) {
30
+ // TeX first reads the token that comes immediately after \expandafter,
31
+ // without expanding it; let’s call this token t. Then TeX reads the
32
+ // token that comes after t (and possibly more tokens, if that token
33
+ // has an argument), replacing it by its expansion. Finally TeX puts
34
+ // t back in front of that expansion.
35
+ const t = context.popToken();
36
+ context.expandOnce(true); // expand only an expandable token
37
+ return { tokens: [t], numArgs: 0 };
38
+ });
39
+
40
+ // LaTeX's \@firstoftwo{#1}{#2} expands to #1, skipping #2
41
+ // TeX source: \long\def\@firstoftwo#1#2{#1}
42
+ defineMacro("\\@firstoftwo", function(context) {
43
+ const args = context.consumeArgs(2);
44
+ return { tokens: args[0], numArgs: 0 };
45
+ });
46
+
47
+ // LaTeX's \@secondoftwo{#1}{#2} expands to #2, skipping #1
48
+ // TeX source: \long\def\@secondoftwo#1#2{#2}
49
+ defineMacro("\\@secondoftwo", function(context) {
50
+ const args = context.consumeArgs(2);
51
+ return { tokens: args[1], numArgs: 0 };
52
+ });
53
+
54
+ // LaTeX's \@ifnextchar{#1}{#2}{#3} looks ahead to the next (unexpanded)
55
+ // symbol that isn't a space, consuming any spaces but not consuming the
56
+ // first nonspace character. If that nonspace character matches #1, then
57
+ // the macro expands to #2; otherwise, it expands to #3.
58
+ defineMacro("\\@ifnextchar", function(context) {
59
+ const args = context.consumeArgs(3); // symbol, if, else
60
+ context.consumeSpaces();
61
+ const nextToken = context.future();
62
+ if (args[0].length === 1 && args[0][0].text === nextToken.text) {
63
+ return { tokens: args[1], numArgs: 0 };
64
+ } else {
65
+ return { tokens: args[2], numArgs: 0 };
66
+ }
67
+ });
68
+
69
+ // LaTeX's \@ifstar{#1}{#2} looks ahead to the next (unexpanded) symbol.
70
+ // If it is `*`, then it consumes the symbol, and the macro expands to #1;
71
+ // otherwise, the macro expands to #2 (without consuming the symbol).
72
+ // TeX source: \def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
73
+ defineMacro("\\@ifstar", "\\@ifnextchar *{\\@firstoftwo{#1}}");
74
+
75
+ // LaTeX's \TextOrMath{#1}{#2} expands to #1 in text mode, #2 in math mode
76
+ defineMacro("\\TextOrMath", function(context) {
77
+ const args = context.consumeArgs(2);
78
+ if (context.mode === "text") {
79
+ return { tokens: args[0], numArgs: 0 };
80
+ } else {
81
+ return { tokens: args[1], numArgs: 0 };
82
+ }
83
+ });
84
+
85
+ const stringFromArg = arg => {
86
+ // Reverse the order of the arg and return a string.
87
+ let str = ""
88
+ for (let i = arg.length - 1; i > -1; i--) {
89
+ str += arg[i].text
90
+ }
91
+ return str
92
+ }
93
+
94
+ // Lookup table for parsing numbers in base 8 through 16
95
+ const digitToNumber = {
96
+ 0: 0,
97
+ 1: 1,
98
+ 2: 2,
99
+ 3: 3,
100
+ 4: 4,
101
+ 5: 5,
102
+ 6: 6,
103
+ 7: 7,
104
+ 8: 8,
105
+ 9: 9,
106
+ a: 10,
107
+ A: 10,
108
+ b: 11,
109
+ B: 11,
110
+ c: 12,
111
+ C: 12,
112
+ d: 13,
113
+ D: 13,
114
+ e: 14,
115
+ E: 14,
116
+ f: 15,
117
+ F: 15
118
+ };
119
+
120
+ const nextCharNumber = context => {
121
+ const numStr = context.future().text
122
+ if (numStr === "EOF") { return [null, ""] }
123
+ return [digitToNumber[numStr.charAt(0)], numStr]
124
+ }
125
+
126
+ const appendCharNumbers = (number, numStr, base) => {
127
+ for (let i = 1; i < numStr.length; i++) {
128
+ const digit = digitToNumber[numStr.charAt(i)]
129
+ number *= base;
130
+ number += digit;
131
+ }
132
+ return number
133
+ }
134
+
135
+ // TeX \char makes a literal character (catcode 12) using the following forms:
136
+ // (see The TeXBook, p. 43)
137
+ // \char123 -- decimal
138
+ // \char'123 -- octal
139
+ // \char"123 -- hex
140
+ // \char`x -- character that can be written (i.e. isn't active)
141
+ // \char`\x -- character that cannot be written (e.g. %)
142
+ // These all refer to characters from the font, so we turn them into special
143
+ // calls to a function \@char dealt with in the Parser.
144
+ defineMacro("\\char", function(context) {
145
+ let token = context.popToken();
146
+ let base;
147
+ let number = "";
148
+ if (token.text === "'") {
149
+ base = 8;
150
+ token = context.popToken();
151
+ } else if (token.text === '"') {
152
+ base = 16;
153
+ token = context.popToken();
154
+ } else if (token.text === "`") {
155
+ token = context.popToken();
156
+ if (token.text[0] === "\\") {
157
+ number = token.text.charCodeAt(1);
158
+ } else if (token.text === "EOF") {
159
+ throw new ParseError("\\char` missing argument");
160
+ } else {
161
+ number = token.text.charCodeAt(0);
162
+ }
163
+ } else {
164
+ base = 10;
165
+ }
166
+ if (base) {
167
+ // Parse a number in the given base, starting with first `token`.
168
+ let numStr = token.text
169
+ number = digitToNumber[numStr.charAt(0)];
170
+ if (number == null || number >= base) {
171
+ throw new ParseError(`Invalid base-${base} digit ${token.text}`);
172
+ }
173
+ number = appendCharNumbers(number, numStr, base)
174
+ let digit;
175
+ [digit, numStr] = nextCharNumber(context)
176
+ while (digit != null && digit < base) {
177
+ number *= base;
178
+ number += digit;
179
+ number = appendCharNumbers(number, numStr, base)
180
+ context.popToken();
181
+ [digit, numStr] = nextCharNumber(context)
182
+ }
183
+ }
184
+ return `\\@char{${number}}`;
185
+ });
186
+
187
+ // The Latin Modern font renders <mi>√</mi> at the wrong vertical alignment.
188
+ // This macro provides a better rendering.
189
+ defineMacro("\\surd", '\\sqrt{\\vphantom{|}}')
190
+
191
+ defineMacro("\\hbox", "\\text{#1}");
192
+
193
+ // Per TeXbook p.122, "/" gets zero operator spacing.
194
+ // And MDN recommends using U+2044 instead of / for inline
195
+ defineMacro("/", "{\u2044}")
196
+
197
+ // Since Temml has no \par, ignore \long.
198
+ defineMacro("\\long", "")
199
+
200
+ //////////////////////////////////////////////////////////////////////
201
+ // Grouping
202
+ // \let\bgroup={ \let\egroup=}
203
+ defineMacro("\\bgroup", "{");
204
+ defineMacro("\\egroup", "}");
205
+
206
+ // Symbols from latex.ltx:
207
+ // \def~{\nobreakspace{}}
208
+ // \def\lq{`}
209
+ // \def\rq{'}
210
+ // \def \aa {\r a}
211
+ defineMacro("~", "\\nobreakspace");
212
+ defineMacro("\\lq", "`");
213
+ defineMacro("\\rq", "'");
214
+ defineMacro("\\aa", "\\r a");
215
+
216
+ defineMacro("\\Bbbk", "\\Bbb{k}");
217
+
218
+ // \mathstrut from the TeXbook, p 360
219
+ defineMacro("\\mathstrut", "\\vphantom{(}");
220
+
221
+ // \underbar from TeXbook p 353
222
+ defineMacro("\\underbar", "\\underline{\\text{#1}}");
223
+
224
+ //////////////////////////////////////////////////////////////////////
225
+ // LaTeX_2ε
226
+
227
+ // \vdots{\vbox{\baselineskip4\p@ \lineskiplimit\z@
228
+ // \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
229
+ // We'll call \varvdots, which gets a glyph from symbols.js.
230
+ // The zero-width rule gets us an equivalent to the vertical 6pt kern.
231
+ defineMacro("\\vdots", "\\mathord{\\varvdots\\rule{0pt}{15pt}}");
232
+ defineMacro("\u22ee", "\\vdots");
233
+
234
+ //////////////////////////////////////////////////////////////////////
235
+ // amsmath.sty
236
+ // http://mirrors.concertpass.com/tex-archive/macros/latex/required/amsmath/amsmath.pdf
237
+
238
+ //\newcommand{\substack}[1]{\subarray{c}#1\endsubarray}
239
+ defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}");
240
+
241
+ // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}}
242
+ defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}");
243
+
244
+ // \def\iff{\DOTSB\;\Longleftrightarrow\;}
245
+ // \def\implies{\DOTSB\;\Longrightarrow\;}
246
+ // \def\impliedby{\DOTSB\;\Longleftarrow\;}
247
+ defineMacro("\\iff", "\\DOTSB\\;\\Longleftrightarrow\\;");
248
+ defineMacro("\\implies", "\\DOTSB\\;\\Longrightarrow\\;");
249
+ defineMacro("\\impliedby", "\\DOTSB\\;\\Longleftarrow\\;");
250
+
251
+ // AMSMath's automatic \dots, based on \mdots@@ macro.
252
+ const dotsByToken = {
253
+ ",": "\\dotsc",
254
+ "\\not": "\\dotsb",
255
+ // \keybin@ checks for the following:
256
+ "+": "\\dotsb",
257
+ "=": "\\dotsb",
258
+ "<": "\\dotsb",
259
+ ">": "\\dotsb",
260
+ "-": "\\dotsb",
261
+ "*": "\\dotsb",
262
+ ":": "\\dotsb",
263
+ // Symbols whose definition starts with \DOTSB:
264
+ "\\DOTSB": "\\dotsb",
265
+ "\\coprod": "\\dotsb",
266
+ "\\bigvee": "\\dotsb",
267
+ "\\bigwedge": "\\dotsb",
268
+ "\\biguplus": "\\dotsb",
269
+ "\\bigcap": "\\dotsb",
270
+ "\\bigcup": "\\dotsb",
271
+ "\\prod": "\\dotsb",
272
+ "\\sum": "\\dotsb",
273
+ "\\bigotimes": "\\dotsb",
274
+ "\\bigoplus": "\\dotsb",
275
+ "\\bigodot": "\\dotsb",
276
+ "\\bigsqcap": "\\dotsb",
277
+ "\\bigsqcup": "\\dotsb",
278
+ "\\And": "\\dotsb",
279
+ "\\longrightarrow": "\\dotsb",
280
+ "\\Longrightarrow": "\\dotsb",
281
+ "\\longleftarrow": "\\dotsb",
282
+ "\\Longleftarrow": "\\dotsb",
283
+ "\\longleftrightarrow": "\\dotsb",
284
+ "\\Longleftrightarrow": "\\dotsb",
285
+ "\\mapsto": "\\dotsb",
286
+ "\\longmapsto": "\\dotsb",
287
+ "\\hookrightarrow": "\\dotsb",
288
+ "\\doteq": "\\dotsb",
289
+ // Symbols whose definition starts with \mathbin:
290
+ "\\mathbin": "\\dotsb",
291
+ // Symbols whose definition starts with \mathrel:
292
+ "\\mathrel": "\\dotsb",
293
+ "\\relbar": "\\dotsb",
294
+ "\\Relbar": "\\dotsb",
295
+ "\\xrightarrow": "\\dotsb",
296
+ "\\xleftarrow": "\\dotsb",
297
+ // Symbols whose definition starts with \DOTSI:
298
+ "\\DOTSI": "\\dotsi",
299
+ "\\int": "\\dotsi",
300
+ "\\oint": "\\dotsi",
301
+ "\\iint": "\\dotsi",
302
+ "\\iiint": "\\dotsi",
303
+ "\\iiiint": "\\dotsi",
304
+ "\\idotsint": "\\dotsi",
305
+ // Symbols whose definition starts with \DOTSX:
306
+ "\\DOTSX": "\\dotsx"
307
+ };
308
+
309
+ defineMacro("\\dots", function(context) {
310
+ // TODO: If used in text mode, should expand to \textellipsis.
311
+ // However, in Temml, \textellipsis and \ldots behave the same
312
+ // (in text mode), and it's unlikely we'd see any of the math commands
313
+ // that affect the behavior of \dots when in text mode. So fine for now
314
+ // (until we support \ifmmode ... \else ... \fi).
315
+ let thedots = "\\dotso";
316
+ const next = context.expandAfterFuture().text;
317
+ if (next in dotsByToken) {
318
+ thedots = dotsByToken[next];
319
+ } else if (next.slice(0, 4) === "\\not") {
320
+ thedots = "\\dotsb";
321
+ } else if (next in symbols.math) {
322
+ if (["bin", "rel"].includes(symbols.math[next].group)) {
323
+ thedots = "\\dotsb";
324
+ }
325
+ }
326
+ return thedots;
327
+ });
328
+
329
+ const spaceAfterDots = {
330
+ // \rightdelim@ checks for the following:
331
+ ")": true,
332
+ "]": true,
333
+ "\\rbrack": true,
334
+ "\\}": true,
335
+ "\\rbrace": true,
336
+ "\\rangle": true,
337
+ "\\rceil": true,
338
+ "\\rfloor": true,
339
+ "\\rgroup": true,
340
+ "\\rmoustache": true,
341
+ "\\right": true,
342
+ "\\bigr": true,
343
+ "\\biggr": true,
344
+ "\\Bigr": true,
345
+ "\\Biggr": true,
346
+ // \extra@ also tests for the following:
347
+ $: true,
348
+ // \extrap@ checks for the following:
349
+ ";": true,
350
+ ".": true,
351
+ ",": true
352
+ };
353
+
354
+ defineMacro("\\dotso", function(context) {
355
+ const next = context.future().text;
356
+ if (next in spaceAfterDots) {
357
+ return "\\ldots\\,";
358
+ } else {
359
+ return "\\ldots";
360
+ }
361
+ });
362
+
363
+ defineMacro("\\dotsc", function(context) {
364
+ const next = context.future().text;
365
+ // \dotsc uses \extra@ but not \extrap@, instead specially checking for
366
+ // ';' and '.', but doesn't check for ','.
367
+ if (next in spaceAfterDots && next !== ",") {
368
+ return "\\ldots\\,";
369
+ } else {
370
+ return "\\ldots";
371
+ }
372
+ });
373
+
374
+ defineMacro("\\cdots", function(context) {
375
+ const next = context.future().text;
376
+ if (next in spaceAfterDots) {
377
+ return "\\@cdots\\,";
378
+ } else {
379
+ return "\\@cdots";
380
+ }
381
+ });
382
+
383
+ defineMacro("\\dotsb", "\\cdots");
384
+ defineMacro("\\dotsm", "\\cdots");
385
+ defineMacro("\\dotsi", "\\!\\cdots");
386
+ defineMacro("\\idotsint", "\\dotsi");
387
+ // amsmath doesn't actually define \dotsx, but \dots followed by a macro
388
+ // starting with \DOTSX implies \dotso, and then \extra@ detects this case
389
+ // and forces the added `\,`.
390
+ defineMacro("\\dotsx", "\\ldots\\,");
391
+
392
+ // \let\DOTSI\relax
393
+ // \let\DOTSB\relax
394
+ // \let\DOTSX\relax
395
+ defineMacro("\\DOTSI", "\\relax");
396
+ defineMacro("\\DOTSB", "\\relax");
397
+ defineMacro("\\DOTSX", "\\relax");
398
+
399
+ // Spacing, based on amsmath.sty's override of LaTeX defaults
400
+ // \DeclareRobustCommand{\tmspace}[3]{%
401
+ // \ifmmode\mskip#1#2\else\kern#1#3\fi\relax}
402
+ defineMacro("\\tmspace", "\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");
403
+ // \renewcommand{\,}{\tmspace+\thinmuskip{.1667em}}
404
+ // TODO: math mode should use \thinmuskip
405
+ defineMacro("\\,", "{\\tmspace+{3mu}{.1667em}}");
406
+ // \let\thinspace\,
407
+ defineMacro("\\thinspace", "\\,");
408
+ // \def\>{\mskip\medmuskip}
409
+ // \renewcommand{\:}{\tmspace+\medmuskip{.2222em}}
410
+ // TODO: \> and math mode of \: should use \medmuskip = 4mu plus 2mu minus 4mu
411
+ defineMacro("\\>", "\\mskip{4mu}");
412
+ defineMacro("\\:", "{\\tmspace+{4mu}{.2222em}}");
413
+ // \let\medspace\:
414
+ defineMacro("\\medspace", "\\:");
415
+ // \renewcommand{\;}{\tmspace+\thickmuskip{.2777em}}
416
+ // TODO: math mode should use \thickmuskip = 5mu plus 5mu
417
+ defineMacro("\\;", "{\\tmspace+{5mu}{.2777em}}");
418
+ // \let\thickspace\;
419
+ defineMacro("\\thickspace", "\\;");
420
+ // \renewcommand{\!}{\tmspace-\thinmuskip{.1667em}}
421
+ // TODO: math mode should use \thinmuskip
422
+ defineMacro("\\!", "{\\tmspace-{3mu}{.1667em}}");
423
+ // \let\negthinspace\!
424
+ defineMacro("\\negthinspace", "\\!");
425
+ // \newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}}
426
+ // TODO: math mode should use \medmuskip
427
+ defineMacro("\\negmedspace", "{\\tmspace-{4mu}{.2222em}}");
428
+ // \newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}}
429
+ // TODO: math mode should use \thickmuskip
430
+ defineMacro("\\negthickspace", "{\\tmspace-{5mu}{.277em}}");
431
+ // \def\enspace{\kern.5em }
432
+ defineMacro("\\enspace", "\\kern.5em ");
433
+ // \def\enskip{\hskip.5em\relax}
434
+ defineMacro("\\enskip", "\\hskip.5em\\relax");
435
+ // \def\quad{\hskip1em\relax}
436
+ defineMacro("\\quad", "\\hskip1em\\relax");
437
+ // \def\qquad{\hskip2em\relax}
438
+ defineMacro("\\qquad", "\\hskip2em\\relax");
439
+
440
+ // \tag@in@display form of \tag
441
+ defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren");
442
+ defineMacro("\\tag@paren", "\\tag@literal{({#1})}");
443
+ defineMacro("\\tag@literal", (context) => {
444
+ if (context.macros.get("\\df@tag")) {
445
+ throw new ParseError("Multiple \\tag");
446
+ }
447
+ return "\\def\\df@tag{\\text{#1}}";
448
+ });
449
+
450
+ // \renewcommand{\bmod}{\nonscript\mskip-\medmuskip\mkern5mu\mathbin
451
+ // {\operator@font mod}\penalty900
452
+ // \mkern5mu\nonscript\mskip-\medmuskip}
453
+ // \newcommand{\pod}[1]{\allowbreak
454
+ // \if@display\mkern18mu\else\mkern8mu\fi(#1)}
455
+ // \renewcommand{\pmod}[1]{\pod{{\operator@font mod}\mkern6mu#1}}
456
+ // \newcommand{\mod}[1]{\allowbreak\if@display\mkern18mu
457
+ // \else\mkern12mu\fi{\operator@font mod}\,\,#1}
458
+ // TODO: math mode should use \medmuskip = 4mu plus 2mu minus 4mu
459
+ defineMacro("\\bmod", "\\mathbin{\\text{mod}}");
460
+ defineMacro(
461
+ "\\pod",
462
+ "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"
463
+ );
464
+ defineMacro("\\pmod", "\\pod{{\\rm mod}\\mkern6mu#1}");
465
+ defineMacro(
466
+ "\\mod",
467
+ "\\allowbreak" +
468
+ "\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}" +
469
+ "{\\rm mod}\\,\\,#1"
470
+ );
471
+
472
+ //////////////////////////////////////////////////////////////////////
473
+ // LaTeX source2e
474
+
475
+ // \expandafter\let\expandafter\@normalcr
476
+ // \csname\expandafter\@gobble\string\\ \endcsname
477
+ // \DeclareRobustCommand\newline{\@normalcr\relax}
478
+ defineMacro("\\newline", "\\\\\\relax");
479
+
480
+ // \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@}
481
+ // TODO: Doesn't normally work in math mode because \@ fails.
482
+ defineMacro("\\TeX", "\\textrm{T}\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125em\\textrm{X}");
483
+
484
+ defineMacro(
485
+ "\\LaTeX",
486
+ "\\textrm{L}\\kern-.35em\\raisebox{0.2em}{\\scriptstyle A}\\kern-.15em\\TeX"
487
+ );
488
+
489
+ defineMacro(
490
+ "\\Temml",
491
+ // eslint-disable-next-line max-len
492
+ "\\textrm{T}\\kern-0.2em\\lower{0.2em}\\textrm{E}\\kern-0.08em{\\textrm{M}\\kern-0.08em\\raise{0.2em}\\textrm{M}\\kern-0.08em\\textrm{L}}"
493
+ );
494
+
495
+ // \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace}
496
+ // \def\@hspace#1{\hskip #1\relax}
497
+ // \def\@hspacer#1{\vrule \@width\z@\nobreak
498
+ // \hskip #1\hskip \z@skip}
499
+ defineMacro("\\hspace", "\\@ifstar\\@hspacer\\@hspace");
500
+ defineMacro("\\@hspace", "\\hskip #1\\relax");
501
+ defineMacro("\\@hspacer", "\\rule{0pt}{0pt}\\hskip #1\\relax");
502
+
503
+ defineMacro("\\colon", `\\mathpunct{\\char"3a}`)
504
+
505
+ //////////////////////////////////////////////////////////////////////
506
+ // mathtools.sty
507
+
508
+ defineMacro("\\prescript", "\\pres@cript{_{#1}^{#2}}{}{#3}")
509
+
510
+ //\providecommand\ordinarycolon{:}
511
+ defineMacro("\\ordinarycolon", `\\char"3a`);
512
+ // Raise to center on the math axis, as closely as possible.
513
+ defineMacro("\\vcentcolon", "\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}}");
514
+ // \providecommand*\coloneq{\vcentcolon\mathrel{\mkern-1.2mu}\mathrel{-}}
515
+ defineMacro("\\coloneq", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"2212}');
516
+ // \providecommand*\Coloneq{\dblcolon\mathrel{\mkern-1.2mu}\mathrel{-}}
517
+ defineMacro("\\Coloneq", '\\mathrel{\\char"2237\\char"2212}');
518
+ // \providecommand*\Eqqcolon{=\mathrel{\mkern-1.2mu}\dblcolon}
519
+ defineMacro("\\Eqqcolon", '\\mathrel{\\char"3d\\char"2237}');
520
+ // \providecommand*\Eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\dblcolon}
521
+ defineMacro("\\Eqcolon", '\\mathrel{\\char"2212\\char"2237}');
522
+ // \providecommand*\colonapprox{\vcentcolon\mathrel{\mkern-1.2mu}\approx}
523
+ defineMacro("\\colonapprox", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"2248}');
524
+ // \providecommand*\Colonapprox{\dblcolon\mathrel{\mkern-1.2mu}\approx}
525
+ defineMacro("\\Colonapprox", '\\mathrel{\\char"2237\\char"2248}');
526
+ // \providecommand*\colonsim{\vcentcolon\mathrel{\mkern-1.2mu}\sim}
527
+ defineMacro("\\colonsim", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"223c}');
528
+ // \providecommand*\Colonsim{\dblcolon\mathrel{\mkern-1.2mu}\sim}
529
+ defineMacro("\\Colonsim", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"223c}');
530
+
531
+ //////////////////////////////////////////////////////////////////////
532
+ // colonequals.sty
533
+
534
+ // Alternate names for mathtools's macros:
535
+ defineMacro("\\ratio", "\\vcentcolon");
536
+ defineMacro("\\coloncolon", "\\dblcolon");
537
+ defineMacro("\\colonequals", "\\coloneqq");
538
+ defineMacro("\\coloncolonequals", "\\Coloneqq");
539
+ defineMacro("\\equalscolon", "\\eqqcolon");
540
+ defineMacro("\\equalscoloncolon", "\\Eqqcolon");
541
+ defineMacro("\\colonminus", "\\coloneq");
542
+ defineMacro("\\coloncolonminus", "\\Coloneq");
543
+ defineMacro("\\minuscolon", "\\eqcolon");
544
+ defineMacro("\\minuscoloncolon", "\\Eqcolon");
545
+ // \colonapprox name is same in mathtools and colonequals.
546
+ defineMacro("\\coloncolonapprox", "\\Colonapprox");
547
+ // \colonsim name is same in mathtools and colonequals.
548
+ defineMacro("\\coloncolonsim", "\\Colonsim");
549
+
550
+ // Present in newtxmath, pxfonts and txfonts
551
+ defineMacro("\\notni", "\\mathrel{\\char`\u220C}");
552
+ defineMacro("\\limsup", "\\DOTSB\\operatorname*{lim\\,sup}");
553
+ defineMacro("\\liminf", "\\DOTSB\\operatorname*{lim\\,inf}");
554
+
555
+ //////////////////////////////////////////////////////////////////////
556
+ // From amsopn.sty
557
+ defineMacro("\\injlim", "\\DOTSB\\operatorname*{inj\\,lim}");
558
+ defineMacro("\\projlim", "\\DOTSB\\operatorname*{proj\\,lim}");
559
+ defineMacro("\\varlimsup", "\\DOTSB\\operatorname*{\\overline{\\text{lim}}}");
560
+ defineMacro("\\varliminf", "\\DOTSB\\operatorname*{\\underline{\\text{lim}}}");
561
+ defineMacro("\\varinjlim", "\\DOTSB\\operatorname*{\\underrightarrow{\\text{lim}}}");
562
+ defineMacro("\\varprojlim", "\\DOTSB\\operatorname*{\\underleftarrow{\\text{lim}}}");
563
+
564
+ defineMacro("\\centerdot", "{\\medspace\\rule{0.167em}{0.189em}\\medspace}")
565
+
566
+ //////////////////////////////////////////////////////////////////////
567
+ // statmath.sty
568
+ // https://ctan.math.illinois.edu/macros/latex/contrib/statmath/statmath.pdf
569
+
570
+ defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
571
+ defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
572
+ defineMacro("\\plim", "\\DOTSB\\operatorname*{plim}");
573
+
574
+ //////////////////////////////////////////////////////////////////////
575
+ // braket.sty
576
+ // http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf
577
+
578
+ defineMacro("\\bra", "\\mathinner{\\langle{#1}|}");
579
+ defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
580
+ defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
581
+ defineMacro("\\Bra", "\\left\\langle#1\\right|");
582
+ defineMacro("\\Ket", "\\left|#1\\right\\rangle");
583
+ const braketHelper = (one) => (context) => {
584
+ const left = context.consumeArg().tokens;
585
+ const middle = context.consumeArg().tokens;
586
+ const middleDouble = context.consumeArg().tokens;
587
+ const right = context.consumeArg().tokens;
588
+ const oldMiddle = context.macros.get("|");
589
+ const oldMiddleDouble = context.macros.get("\\|");
590
+ context.macros.beginGroup();
591
+ const midMacro = (double) => (context) => {
592
+ if (one) {
593
+ // Only modify the first instance of | or \|
594
+ context.macros.set("|", oldMiddle);
595
+ if (middleDouble.length) {
596
+ context.macros.set("\\|", oldMiddleDouble);
597
+ }
598
+ }
599
+ let doubled = double;
600
+ if (!double && middleDouble.length) {
601
+ // Mimic \@ifnextchar
602
+ const nextToken = context.future();
603
+ if (nextToken.text === "|") {
604
+ context.popToken();
605
+ doubled = true;
606
+ }
607
+ }
608
+ return {
609
+ tokens: doubled ? middleDouble : middle,
610
+ numArgs: 0
611
+ };
612
+ };
613
+ context.macros.set("|", midMacro(false));
614
+ if (middleDouble.length) {
615
+ context.macros.set("\\|", midMacro(true));
616
+ }
617
+ const arg = context.consumeArg().tokens;
618
+ const expanded = context.expandTokens([...right, ...arg, ...left]); // reversed
619
+ context.macros.endGroup();
620
+ return {
621
+ tokens: expanded.reverse(),
622
+ numArgs: 0
623
+ };
624
+ };
625
+ defineMacro("\\bra@ket", braketHelper(false));
626
+ defineMacro("\\bra@set", braketHelper(true));
627
+ defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" +
628
+ "{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");
629
+ defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" +
630
+ "{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");
631
+ defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");
632
+ // has no support for special || or \|
633
+
634
+ //////////////////////////////////////////////////////////////////////
635
+ // actuarialangle.dtx
636
+ defineMacro("\\angln", "{\\angl n}");
637
+
638
+ //////////////////////////////////////////////////////////////////////
639
+ // derivative.sty
640
+ defineMacro("\\odv", "\\@ifstar\\odv@next\\odv@numerator");
641
+ defineMacro("\\odv@numerator", "\\frac{\\mathrm{d}#1}{\\mathrm{d}#2}")
642
+ defineMacro("\\odv@next", "\\frac{\\mathrm{d}}{\\mathrm{d}#2}#1")
643
+ defineMacro("\\pdv", "\\@ifstar\\pdv@next\\pdv@numerator");
644
+
645
+ const pdvHelper = args => {
646
+ const numerator = args[0][0].text
647
+ const denoms = stringFromArg(args[1]).split(",")
648
+ const power = String(denoms.length)
649
+ const numOp = power === "1" ? "\\partial" : `\\partial^${power}`
650
+ let denominator = ""
651
+ denoms.map(e => { denominator += "\\partial " + e.trim() + "\\,"})
652
+ return [numerator, numOp, denominator.replace(/\\,$/, "")]
653
+ }
654
+ defineMacro("\\pdv@numerator", function(context) {
655
+ const [numerator, numOp, denominator] = pdvHelper(context.consumeArgs(2))
656
+ return `\\frac{${numOp} ${numerator}}{${denominator}}`
657
+ })
658
+ defineMacro("\\pdv@next", function(context) {
659
+ const [numerator, numOp, denominator] = pdvHelper(context.consumeArgs(2))
660
+ return `\\frac{${numOp}}{${denominator}} ${numerator}`
661
+ })
662
+
663
+ //////////////////////////////////////////////////////////////////////
664
+ // upgreek.dtx
665
+ defineMacro("\\upalpha", "\\up@greek{\\alpha}");
666
+ defineMacro("\\upbeta", "\\up@greek{\\beta}");
667
+ defineMacro("\\upgamma", "\\up@greek{\\gamma}");
668
+ defineMacro("\\updelta", "\\up@greek{\\delta}");
669
+ defineMacro("\\upepsilon", "\\up@greek{\\epsilon}");
670
+ defineMacro("\\upzeta", "\\up@greek{\\zeta}");
671
+ defineMacro("\\upeta", "\\up@greek{\\eta}");
672
+ defineMacro("\\uptheta", "\\up@greek{\\theta}");
673
+ defineMacro("\\upiota", "\\up@greek{\\iota}");
674
+ defineMacro("\\upkappa", "\\up@greek{\\kappa}");
675
+ defineMacro("\\uplambda", "\\up@greek{\\lambda}");
676
+ defineMacro("\\upmu", "\\up@greek{\\mu}");
677
+ defineMacro("\\upnu", "\\up@greek{\\nu}");
678
+ defineMacro("\\upxi", "\\up@greek{\\xi}");
679
+ defineMacro("\\upomicron", "\\up@greek{\\omicron}");
680
+ defineMacro("\\uppi", "\\up@greek{\\pi}");
681
+ defineMacro("\\upalpha", "\\up@greek{\\alpha}");
682
+ defineMacro("\\uprho", "\\up@greek{\\rho}");
683
+ defineMacro("\\upsigma", "\\up@greek{\\sigma}");
684
+ defineMacro("\\uptau", "\\up@greek{\\tau}");
685
+ defineMacro("\\upupsilon", "\\up@greek{\\upsilon}");
686
+ defineMacro("\\upphi", "\\up@greek{\\phi}");
687
+ defineMacro("\\upchi", "\\up@greek{\\chi}");
688
+ defineMacro("\\uppsi", "\\up@greek{\\psi}");
689
+ defineMacro("\\upomega", "\\up@greek{\\omega}");
690
+
691
+ //////////////////////////////////////////////////////////////////////
692
+ // cmll package
693
+ defineMacro("\\invamp", '\\mathbin{\\char"214b}')
694
+ defineMacro("\\parr", '\\mathbin{\\char"214b}')
695
+ defineMacro("\\with", '\\mathbin{\\char"26}')
696
+ defineMacro("\\multimapinv", '\\mathrel{\\char"27dc}')
697
+ defineMacro("\\multimapboth", '\\mathrel{\\char"29df}')
698
+ defineMacro("\\scoh", '{\\mkern5mu\\char"2322\\mkern5mu}')
699
+ defineMacro("\\sincoh", '{\\mkern5mu\\char"2323\\mkern5mu}')
700
+ defineMacro("\\coh", `{\\mkern5mu\\rule{}{0.7em}\\mathrlap{\\smash{\\raise2mu{\\char"2322}}}
701
+ {\\smash{\\lower4mu{\\char"2323}}}\\mkern5mu}`)
702
+ defineMacro("\\incoh", `{\\mkern5mu\\rule{}{0.7em}\\mathrlap{\\smash{\\raise2mu{\\char"2323}}}
703
+ {\\smash{\\lower4mu{\\char"2322}}}\\mkern5mu}`)
704
+
705
+
706
+ //////////////////////////////////////////////////////////////////////
707
+ // chemstyle package
708
+ defineMacro("\\standardstate", "\\text{\\tiny\\char`⦵}");