temml 0.10.14 → 0.10.16
Sign up to get free protection for your applications and to get access to all the features.
- 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
|