temml 0.10.14 → 0.10.16
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/README.md +1 -1
- package/dist/Temml-Asana.css +18 -146
- package/dist/Temml-Latin-Modern.css +20 -148
- package/dist/Temml-Libertinus.css +18 -147
- package/dist/Temml-Local.css +19 -147
- package/dist/Temml-STIX2.css +18 -146
- package/dist/Temml.woff2 +0 -0
- package/dist/temml.cjs +221 -55
- package/dist/temml.d.ts +60 -0
- package/dist/temml.js +221 -55
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +221 -55
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +4 -2
- package/src/Parser.js +0 -1
- package/src/buildMathML.js +1 -3
- package/src/domTree.js +2 -2
- package/src/environments/array.js +99 -23
- package/src/functions/accent.js +17 -22
- package/src/functions/accentunder.js +1 -1
- package/src/functions/enclose.js +24 -3
- package/src/functions/supsub.js +8 -1
- package/src/functions/symbolsOrd.js +3 -1
- package/src/macros.js +3 -0
- package/src/postProcess.js +1 -1
- package/src/stretchy.js +48 -1
- package/src/symbols.js +13 -1
- package/temml.js +6 -0
@@ -276,24 +276,98 @@ const mathmlBuilder = function(group, style) {
|
|
276
276
|
// Write horizontal rules
|
277
277
|
if (i === 0 && hlines[0].length > 0) {
|
278
278
|
if (hlines[0].length === 2) {
|
279
|
-
mtr.
|
279
|
+
mtr.children.forEach(cell => { cell.style.borderTop = "0.15em double" })
|
280
280
|
} else {
|
281
|
-
mtr.
|
281
|
+
mtr.children.forEach(cell => {
|
282
|
+
cell.style.borderTop = hlines[0][0] ? "0.06em dashed" : "0.06em solid"
|
283
|
+
})
|
282
284
|
}
|
283
285
|
}
|
284
286
|
if (hlines[i + 1].length > 0) {
|
285
287
|
if (hlines[i + 1].length === 2) {
|
286
|
-
mtr.
|
288
|
+
mtr.children.forEach(cell => { cell.style.borderBottom = "0.15em double" })
|
287
289
|
} else {
|
288
|
-
mtr.
|
290
|
+
mtr.children.forEach(cell => {
|
291
|
+
cell.style.borderBottom = hlines[i + 1][0] ? "0.06em dashed" : "0.06em solid"
|
292
|
+
})
|
289
293
|
}
|
290
294
|
}
|
291
295
|
tbl.push(mtr);
|
292
296
|
}
|
293
|
-
|
297
|
+
|
294
298
|
if (group.envClasses.length > 0) {
|
295
|
-
|
299
|
+
const pad = group.envClasses.includes("jot")
|
300
|
+
? "0.7" // 0.5ex + 0.09em top & bot padding
|
301
|
+
: group.envClasses.includes("small")
|
302
|
+
? "0.35"
|
303
|
+
: "0.5" // 0.5ex default top & bot padding
|
304
|
+
const sidePadding = group.envClasses.includes("abut")
|
305
|
+
? "0"
|
306
|
+
: group.envClasses.includes("cases")
|
307
|
+
? "0"
|
308
|
+
: group.envClasses.includes("small")
|
309
|
+
? "0.1389"
|
310
|
+
: group.envClasses.includes("cd")
|
311
|
+
? "0.25"
|
312
|
+
: "0.4" // default side padding
|
313
|
+
|
314
|
+
const numCols = tbl.length === 0 ? 0 : tbl[0].children.length
|
315
|
+
|
316
|
+
const sidePad = (j, hand) => {
|
317
|
+
if (j === 0 && hand === 0) { return "0" }
|
318
|
+
if (j === numCols - 1 && hand === 1) { return "0" }
|
319
|
+
if (group.envClasses[0] !== "align") { return sidePadding }
|
320
|
+
if (hand === 1) { return "0" }
|
321
|
+
if (group.addEqnNum) {
|
322
|
+
return (j % 2) ? "1" : "0"
|
323
|
+
} else {
|
324
|
+
return (j % 2) ? "0" : "1"
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
// Padding
|
329
|
+
for (let i = 0; i < tbl.length; i++) {
|
330
|
+
for (let j = 0; j < tbl[i].children.length; j++) {
|
331
|
+
tbl[i].children[j].style.padding = `${pad}ex ${sidePad(j, 1)}em ${pad}ex ${sidePad(j, 0)}em`
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
// Justification
|
336
|
+
const align = group.envClasses.includes("align") || group.envClasses.includes("alignat")
|
337
|
+
for (let i = 0; i < tbl.length; i++) {
|
338
|
+
const row = tbl[i];
|
339
|
+
if (align) {
|
340
|
+
for (let j = 0; j < row.children.length; j++) {
|
341
|
+
// Chromium does not recognize text-align: left. Use -webkit-
|
342
|
+
// TODO: Remove -webkit- when Chromium no longer needs it.
|
343
|
+
row.children[j].style.textAlign = "-webkit-" + (j % 2 ? "left" : "right")
|
344
|
+
}
|
345
|
+
if (group.addEqnNum) {
|
346
|
+
const k = group.leqno ? 0 : row.children.length - 1
|
347
|
+
row.children[k].style.textAlign = "-webkit-" + (group.leqno ? "left" : "right")
|
348
|
+
}
|
349
|
+
}
|
350
|
+
if (row.children.length > 1 && group.envClasses.includes("cases")) {
|
351
|
+
row.children[1].style.padding = row.children[1].style.padding.replace(/0em$/, "1em")
|
352
|
+
}
|
353
|
+
|
354
|
+
if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
|
355
|
+
for (const cell of row.children) {
|
356
|
+
cell.style.textAlign = "-webkit-" + "left"
|
357
|
+
}
|
358
|
+
}
|
359
|
+
}
|
360
|
+
} else {
|
361
|
+
// Set zero padding on side of the matrix
|
362
|
+
for (let i = 0; i < tbl.length; i++) {
|
363
|
+
tbl[i].children[0].style.paddingLeft = "0em"
|
364
|
+
if (tbl[i].children.length === tbl[0].children.length) {
|
365
|
+
tbl[i].children[tbl[i].children.length - 1].style.paddingRight = "0em"
|
366
|
+
}
|
367
|
+
}
|
296
368
|
}
|
369
|
+
|
370
|
+
let table = new mathMLTree.MathNode("mtable", tbl)
|
297
371
|
if (group.scriptLevel === "display") { table.setAttribute("displaystyle", "true") }
|
298
372
|
|
299
373
|
if (group.addEqnNum || group.envClasses.includes("multline")) {
|
@@ -373,6 +447,8 @@ const mathmlBuilder = function(group, style) {
|
|
373
447
|
align = "left " + (align.length > 0 ? align : "center ") + "right "
|
374
448
|
}
|
375
449
|
if (align) {
|
450
|
+
// Firefox reads this attribute, not the -webkit-left|right written above.
|
451
|
+
// TODO: When Chrome no longer needs "-webkit-", use CSS and delete the next line.
|
376
452
|
table.setAttribute("columnalign", align.trim())
|
377
453
|
}
|
378
454
|
|
@@ -397,7 +473,7 @@ const alignedHandler = function(context, args) {
|
|
397
473
|
cols,
|
398
474
|
addEqnNum: context.envName === "align" || context.envName === "alignat",
|
399
475
|
emptySingleRow: true,
|
400
|
-
envClasses: ["
|
476
|
+
envClasses: ["abut", "jot"], // set row spacing & provisional column spacing
|
401
477
|
maxNumCols: context.envName === "split" ? 2 : undefined,
|
402
478
|
leqno: context.parser.settings.leqno
|
403
479
|
},
|
@@ -415,18 +491,22 @@ const alignedHandler = function(context, args) {
|
|
415
491
|
// binary. This behavior is implemented in amsmath's \start@aligned.
|
416
492
|
let numMaths;
|
417
493
|
let numCols = 0;
|
418
|
-
|
419
|
-
|
494
|
+
const isAlignedAt = context.envName.indexOf("at") > -1
|
495
|
+
if (args[0] && isAlignedAt) {
|
496
|
+
// alignat environment takes an argument w/ number of columns
|
497
|
+
let arg0 = ""
|
420
498
|
for (let i = 0; i < args[0].body.length; i++) {
|
421
|
-
const textord = assertNodeType(args[0].body[i], "textord")
|
422
|
-
arg0 += textord.text
|
499
|
+
const textord = assertNodeType(args[0].body[i], "textord")
|
500
|
+
arg0 += textord.text
|
501
|
+
}
|
502
|
+
if (isNaN(arg0)) {
|
503
|
+
throw new ParseError("The alignat enviroment requires a numeric first argument.")
|
423
504
|
}
|
424
|
-
numMaths = Number(arg0)
|
425
|
-
numCols = numMaths * 2
|
505
|
+
numMaths = Number(arg0)
|
506
|
+
numCols = numMaths * 2
|
426
507
|
}
|
427
|
-
const isAligned = !numCols;
|
428
508
|
res.body.forEach(function(row) {
|
429
|
-
if (
|
509
|
+
if (isAlignedAt) {
|
430
510
|
// Case 1
|
431
511
|
const curMaths = row.length / 2;
|
432
512
|
if (numMaths < curMaths) {
|
@@ -456,14 +536,10 @@ const alignedHandler = function(context, args) {
|
|
456
536
|
}
|
457
537
|
if (context.envName === "split") {
|
458
538
|
// Append no more classes
|
459
|
-
} else if (
|
460
|
-
res.envClasses.push("
|
461
|
-
} else if (isAligned) {
|
462
|
-
res.envClasses[1] = context.envName === "align*"
|
463
|
-
? "align-star"
|
464
|
-
: "align" // Sets column spacing & justification
|
539
|
+
} else if (isAlignedAt) {
|
540
|
+
res.envClasses.push("alignat") // Sets justification
|
465
541
|
} else {
|
466
|
-
res.envClasses
|
542
|
+
res.envClasses[0] = "align" // Sets column spacing & justification
|
467
543
|
}
|
468
544
|
return res;
|
469
545
|
};
|
@@ -713,7 +789,7 @@ defineEnvironment({
|
|
713
789
|
}
|
714
790
|
const res = {
|
715
791
|
cols: [],
|
716
|
-
envClasses: ["
|
792
|
+
envClasses: ["abut", "jot"],
|
717
793
|
addEqnNum: context.envName === "gather",
|
718
794
|
emptySingleRow: true,
|
719
795
|
leqno: context.parser.settings.leqno
|
package/src/functions/accent.js
CHANGED
@@ -5,7 +5,7 @@ import * as mml from "../buildMathML"
|
|
5
5
|
|
6
6
|
const mathmlBuilder = (group, style) => {
|
7
7
|
const accentNode = group.isStretchy
|
8
|
-
? stretchy.
|
8
|
+
? stretchy.accentNode(group)
|
9
9
|
: new mathMLTree.MathNode("mo", [mml.makeText(group.label, group.mode)]);
|
10
10
|
|
11
11
|
if (group.label === "\\vec") {
|
@@ -25,25 +25,21 @@ const mathmlBuilder = (group, style) => {
|
|
25
25
|
return node;
|
26
26
|
};
|
27
27
|
|
28
|
-
const
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
]
|
44
|
-
.map((accent) => `\\${accent}`)
|
45
|
-
.join("|")
|
46
|
-
);
|
28
|
+
const nonStretchyAccents = new Set([
|
29
|
+
"\\acute",
|
30
|
+
"\\grave",
|
31
|
+
"\\ddot",
|
32
|
+
"\\dddot",
|
33
|
+
"\\ddddot",
|
34
|
+
"\\tilde",
|
35
|
+
"\\bar",
|
36
|
+
"\\breve",
|
37
|
+
"\\check",
|
38
|
+
"\\hat",
|
39
|
+
"\\vec",
|
40
|
+
"\\dot",
|
41
|
+
"\\mathring"
|
42
|
+
])
|
47
43
|
|
48
44
|
// Accents
|
49
45
|
defineFunction({
|
@@ -81,7 +77,7 @@ defineFunction({
|
|
81
77
|
handler: (context, args) => {
|
82
78
|
const base = normalizeArgument(args[0]);
|
83
79
|
|
84
|
-
const isStretchy = !
|
80
|
+
const isStretchy = !nonStretchyAccents.has(context.funcName);
|
85
81
|
|
86
82
|
return {
|
87
83
|
type: "accent",
|
@@ -119,7 +115,6 @@ defineFunction({
|
|
119
115
|
mode: mode,
|
120
116
|
label: context.funcName,
|
121
117
|
isStretchy: false,
|
122
|
-
isShifty: true,
|
123
118
|
base: base
|
124
119
|
};
|
125
120
|
},
|
@@ -27,7 +27,7 @@ defineFunction({
|
|
27
27
|
};
|
28
28
|
},
|
29
29
|
mathmlBuilder: (group, style) => {
|
30
|
-
const accentNode = stretchy.
|
30
|
+
const accentNode = stretchy.accentNode(group);
|
31
31
|
accentNode.style["math-depth"] = 0
|
32
32
|
const node = new mathMLTree.MathNode("munder", [
|
33
33
|
mml.buildGroup(group.base, style),
|
package/src/functions/enclose.js
CHANGED
@@ -34,10 +34,20 @@ const mathmlBuilder = (group, style) => {
|
|
34
34
|
node.style.borderBottom = "0.065em solid"
|
35
35
|
break
|
36
36
|
case "\\cancel":
|
37
|
-
node.
|
37
|
+
node.style.background = `linear-gradient(to top left,
|
38
|
+
rgba(0,0,0,0) 0%,
|
39
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
40
|
+
rgba(0,0,0,1) 50%,
|
41
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
42
|
+
rgba(0,0,0,0) 100%);`
|
38
43
|
break
|
39
44
|
case "\\bcancel":
|
40
|
-
node.
|
45
|
+
node.style.background = `linear-gradient(to top right,
|
46
|
+
rgba(0,0,0,0) 0%,
|
47
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
48
|
+
rgba(0,0,0,1) 50%,
|
49
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
50
|
+
rgba(0,0,0,0) 100%);`
|
41
51
|
break
|
42
52
|
/*
|
43
53
|
case "\\longdiv":
|
@@ -81,7 +91,18 @@ const mathmlBuilder = (group, style) => {
|
|
81
91
|
break
|
82
92
|
}
|
83
93
|
case "\\xcancel":
|
84
|
-
node.
|
94
|
+
node.style.background = `linear-gradient(to top left,
|
95
|
+
rgba(0,0,0,0) 0%,
|
96
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
97
|
+
rgba(0,0,0,1) 50%,
|
98
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
99
|
+
rgba(0,0,0,0) 100%),
|
100
|
+
linear-gradient(to top right,
|
101
|
+
rgba(0,0,0,0) 0%,
|
102
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
103
|
+
rgba(0,0,0,1) 50%,
|
104
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
105
|
+
rgba(0,0,0,0) 100%);`
|
85
106
|
break
|
86
107
|
}
|
87
108
|
if (group.backgroundColor) {
|
package/src/functions/supsub.js
CHANGED
@@ -53,7 +53,14 @@ defineFunctionBuilders({
|
|
53
53
|
}
|
54
54
|
|
55
55
|
if (group.sup) {
|
56
|
-
|
56
|
+
const sup = mml.buildGroup(group.sup, childStyle)
|
57
|
+
const testNode = sup.type === "mrow" ? sup.children[0] : sup
|
58
|
+
if ((testNode.type === "mo" && testNode.classes.includes("tml-prime"))
|
59
|
+
&& group.base && group.base.text && group.base.text === "f") {
|
60
|
+
// Chromium does not address italic correction on prime. Prevent f′ from overlapping.
|
61
|
+
testNode.classes.push("prime-pad")
|
62
|
+
}
|
63
|
+
children.push(sup)
|
57
64
|
}
|
58
65
|
|
59
66
|
let nodeType;
|
@@ -9,6 +9,8 @@ import * as mml from "../buildMathML"
|
|
9
9
|
|
10
10
|
const numberRegEx = /^\d(?:[\d,.]*\d)?$/
|
11
11
|
const latinRegEx = /[A-Ba-z]/
|
12
|
+
const primes = new Set(["\\prime", "\\dprime", "\\trprime", "\\qprime",
|
13
|
+
"\\backprime", "\\backdprime", "\\backtrprime"]);
|
12
14
|
|
13
15
|
const italicNumber = (text, variant, tag) => {
|
14
16
|
const mn = new mathMLTree.MathNode(tag, [text])
|
@@ -76,7 +78,7 @@ defineFunctionBuilders({
|
|
76
78
|
text.text = variantChar(text.text, variant)
|
77
79
|
}
|
78
80
|
node = new mathMLTree.MathNode("mtext", [text])
|
79
|
-
} else if (group.text
|
81
|
+
} else if (primes.has(group.text)) {
|
80
82
|
node = new mathMLTree.MathNode("mo", [text])
|
81
83
|
// TODO: If/when Chromium uses ssty variant for prime, remove the next line.
|
82
84
|
node.classes.push("tml-prime")
|
package/src/macros.js
CHANGED
@@ -188,6 +188,9 @@ defineMacro("\\char", function(context) {
|
|
188
188
|
// This macro provides a better rendering.
|
189
189
|
defineMacro("\\surd", '\\sqrt{\\vphantom{|}}')
|
190
190
|
|
191
|
+
// See comment for \oplus in symbols.js.
|
192
|
+
defineMacro("\u2295", "\\oplus")
|
193
|
+
|
191
194
|
defineMacro("\\hbox", "\\text{#1}");
|
192
195
|
|
193
196
|
// Per TeXbook p.122, "/" gets zero operator spacing.
|
package/src/postProcess.js
CHANGED
package/src/stretchy.js
CHANGED
@@ -4,6 +4,34 @@
|
|
4
4
|
|
5
5
|
import mathMLTree from "./mathMLTree"
|
6
6
|
|
7
|
+
// TODO: Remove when Chromium stretches \widetilde & \widehat
|
8
|
+
const estimatedWidth = node => {
|
9
|
+
let width = 0
|
10
|
+
if (node.body) {
|
11
|
+
for (const item of node.body) {
|
12
|
+
width += estimatedWidth(item)
|
13
|
+
}
|
14
|
+
} else if (node.type === "supsub") {
|
15
|
+
width += estimatedWidth(node.base)
|
16
|
+
if (node.sub) { width += 0.7 * estimatedWidth(node.sub) }
|
17
|
+
if (node.sup) { width += 0.7 * estimatedWidth(node.sup) }
|
18
|
+
} else if (node.type === "mathord" || node.type === "textord") {
|
19
|
+
for (const ch of node.text.split('')) {
|
20
|
+
const codePoint = ch.codePointAt(0)
|
21
|
+
if ((0x60 < codePoint && codePoint < 0x7B) || (0x03B0 < codePoint && codePoint < 0x3CA)) {
|
22
|
+
width += 0.56 // lower case latin or greek. Use advance width of letter n
|
23
|
+
} else if (0x2F < codePoint && codePoint < 0x3A) {
|
24
|
+
width += 0.50 // numerals.
|
25
|
+
} else {
|
26
|
+
width += 0.92 // advance width of letter M
|
27
|
+
}
|
28
|
+
}
|
29
|
+
} else {
|
30
|
+
width += 1.0
|
31
|
+
}
|
32
|
+
return width
|
33
|
+
}
|
34
|
+
|
7
35
|
const stretchyCodePoint = {
|
8
36
|
widehat: "^",
|
9
37
|
widecheck: "ˇ",
|
@@ -61,6 +89,25 @@ const mathMLnode = function(label) {
|
|
61
89
|
return node
|
62
90
|
}
|
63
91
|
|
92
|
+
const crookedWides = ["\\widetilde", "\\widehat", "\\widecheck", "\\utilde"]
|
93
|
+
|
94
|
+
// TODO: Remove when Chromium stretches \widetilde & \widehat
|
95
|
+
const accentNode = (group) => {
|
96
|
+
const mo = mathMLnode(group.label)
|
97
|
+
if (crookedWides.includes(group.label)) {
|
98
|
+
const width = estimatedWidth(group.base)
|
99
|
+
if (1 < width && width < 1.6) {
|
100
|
+
mo.classes.push("tml-crooked-2")
|
101
|
+
} else if (1.6 <= width && width < 2.5) {
|
102
|
+
mo.classes.push("tml-crooked-3")
|
103
|
+
} else if (2.5 <= width) {
|
104
|
+
mo.classes.push("tml-crooked-4")
|
105
|
+
}
|
106
|
+
}
|
107
|
+
return mo
|
108
|
+
}
|
109
|
+
|
64
110
|
export default {
|
65
|
-
mathMLnode
|
111
|
+
mathMLnode,
|
112
|
+
accentNode
|
66
113
|
}
|
package/src/symbols.js
CHANGED
@@ -212,6 +212,10 @@ defineSymbol(math, mathord, "\u21af", "\\lightning", true);
|
|
212
212
|
defineSymbol(math, mathord, "\u220E", "\\QED", true);
|
213
213
|
defineSymbol(math, mathord, "\u2030", "\\permil", true);
|
214
214
|
defineSymbol(text, textord, "\u2030", "\\permil");
|
215
|
+
defineSymbol(math, mathord, "\u2609", "\\astrosun", true);
|
216
|
+
defineSymbol(math, mathord, "\u263c", "\\sun", true);
|
217
|
+
defineSymbol(math, mathord, "\u263e", "\\leftmoon", true);
|
218
|
+
defineSymbol(math, mathord, "\u263d", "\\rightmoon", true);
|
215
219
|
|
216
220
|
// AMS Negated Binary Relations
|
217
221
|
defineSymbol(math, rel, "\u226e", "\\nless", true);
|
@@ -290,6 +294,8 @@ defineSymbol(math, textord, "\u2127", "\\mho");
|
|
290
294
|
defineSymbol(math, textord, "\u2132", "\\Finv", true);
|
291
295
|
defineSymbol(math, textord, "\u2141", "\\Game", true);
|
292
296
|
defineSymbol(math, textord, "\u2035", "\\backprime");
|
297
|
+
defineSymbol(math, textord, "\u2036", "\\backdprime");
|
298
|
+
defineSymbol(math, textord, "\u2037", "\\backtrprime");
|
293
299
|
defineSymbol(math, textord, "\u25b2", "\\blacktriangle");
|
294
300
|
defineSymbol(math, textord, "\u25bc", "\\blacktriangledown");
|
295
301
|
defineSymbol(math, textord, "\u25a0", "\\blacksquare");
|
@@ -493,6 +499,9 @@ defineSymbol(text, textord, "\u2423", "\\textvisiblespace", true);
|
|
493
499
|
defineSymbol(math, textord, "\u2220", "\\angle", true);
|
494
500
|
defineSymbol(math, textord, "\u221e", "\\infty", true);
|
495
501
|
defineSymbol(math, textord, "\u2032", "\\prime");
|
502
|
+
defineSymbol(math, textord, "\u2033", "\\dprime");
|
503
|
+
defineSymbol(math, textord, "\u2034", "\\trprime");
|
504
|
+
defineSymbol(math, textord, "\u2057", "\\qprime");
|
496
505
|
defineSymbol(math, textord, "\u25b3", "\\triangle");
|
497
506
|
defineSymbol(text, textord, "\u0391", "\\Alpha", true);
|
498
507
|
defineSymbol(text, textord, "\u0392", "\\Beta", true);
|
@@ -672,7 +681,8 @@ defineSymbol(math, punct, ";", ";");
|
|
672
681
|
defineSymbol(math, bin, "\u22bc", "\\barwedge", true);
|
673
682
|
defineSymbol(math, bin, "\u22bb", "\\veebar", true);
|
674
683
|
defineSymbol(math, bin, "\u2299", "\\odot", true);
|
675
|
-
|
684
|
+
// Firefox turns ⊕ into an emoji. So append \uFE0E. Define Unicode character in macros, not here.
|
685
|
+
defineSymbol(math, bin, "\u2295\uFE0E", "\\oplus");
|
676
686
|
defineSymbol(math, bin, "\u2297", "\\otimes", true);
|
677
687
|
defineSymbol(math, textord, "\u2202", "\\partial", true);
|
678
688
|
defineSymbol(math, bin, "\u2298", "\\oslash", true);
|
@@ -903,6 +913,8 @@ for (let i = 0; i < letters.length; i++) {
|
|
903
913
|
defineSymbol(math, mathord, ch, ch);
|
904
914
|
defineSymbol(text, textord, ch, ch);
|
905
915
|
}
|
916
|
+
// Prevent Firefox from using a dotless i.
|
917
|
+
defineSymbol(text, textord, "i\uFE0E", "i")
|
906
918
|
|
907
919
|
// Some more letters in Unicode Basic Multilingual Plane.
|
908
920
|
const narrow = "ÇÐÞçþℂℍℕℙℚℝℤℎℏℊℋℌℐℑℒℓ℘ℛℜℬℰℱℳℭℨ";
|
package/temml.js
CHANGED
@@ -21,6 +21,7 @@ import defineMacro from "./src/defineMacro";
|
|
21
21
|
import { postProcess, version } from "./src/postProcess";
|
22
22
|
|
23
23
|
/**
|
24
|
+
* @type {import('./temml').render}
|
24
25
|
* Parse and build an expression, and place that expression in the DOM node
|
25
26
|
* given.
|
26
27
|
*/
|
@@ -58,6 +59,7 @@ if (typeof document !== "undefined") {
|
|
58
59
|
}
|
59
60
|
|
60
61
|
/**
|
62
|
+
* @type {import('./temml').renderToString}
|
61
63
|
* Parse and build an expression, and return the markup for that.
|
62
64
|
*/
|
63
65
|
const renderToString = function(expression, options) {
|
@@ -66,6 +68,7 @@ const renderToString = function(expression, options) {
|
|
66
68
|
};
|
67
69
|
|
68
70
|
/**
|
71
|
+
* @type {import('./temml').generateParseTree}
|
69
72
|
* Parse an expression and return the parse tree.
|
70
73
|
*/
|
71
74
|
const generateParseTree = function(expression, options) {
|
@@ -74,6 +77,7 @@ const generateParseTree = function(expression, options) {
|
|
74
77
|
};
|
75
78
|
|
76
79
|
/**
|
80
|
+
* @type {import('./temml').definePreamble}
|
77
81
|
* Take an expression which contains a preamble.
|
78
82
|
* Parse it and return the macros.
|
79
83
|
*/
|
@@ -106,6 +110,7 @@ const renderError = function(error, expression, options) {
|
|
106
110
|
};
|
107
111
|
|
108
112
|
/**
|
113
|
+
* @type {import('./temml').renderToMathMLTree}
|
109
114
|
* Generates and returns the Temml build tree. This is used for advanced
|
110
115
|
* use cases (like rendering to custom output).
|
111
116
|
*/
|
@@ -123,6 +128,7 @@ const renderToMathMLTree = function(expression, options) {
|
|
123
128
|
}
|
124
129
|
};
|
125
130
|
|
131
|
+
/** @type {import('./temml').default} */
|
126
132
|
export default {
|
127
133
|
/**
|
128
134
|
* Current Temml version
|