temml 0.10.15 → 0.10.17
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +2 -2
- package/contrib/copy-tex/README.md +42 -0
- package/contrib/copy-tex/copy-tex.js +66 -0
- package/contrib/copy-tex/copy-tex.min.js +1 -0
- package/dist/Temml-Asana.css +38 -0
- package/dist/Temml-Latin-Modern.css +40 -1
- package/dist/Temml-Libertinus.css +38 -0
- package/dist/Temml-Local.css +39 -1
- package/dist/Temml-STIX2.css +38 -0
- package/dist/Temml.woff2 +0 -0
- package/dist/temml.cjs +13306 -13215
- package/dist/temml.js +11409 -11318
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +13304 -13213
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +1 -1
- package/src/Parser.js +0 -1
- package/src/buildMathML.js +2 -7
- package/src/domTree.js +2 -2
- package/src/environments/array.js +14 -8
- package/src/functions/accent.js +47 -22
- package/src/functions/accentunder.js +1 -1
- package/src/functions/enclose.js +4 -1
- package/src/functions/lap.js +1 -1
- 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 +7 -1
package/dist/temmlPostProcess.js
CHANGED
package/package.json
CHANGED
package/src/Parser.js
CHANGED
package/src/buildMathML.js
CHANGED
@@ -207,13 +207,8 @@ const taggedExpression = (expression, tag, style, leqno) => {
|
|
207
207
|
|
208
208
|
expression = new mathMLTree.MathNode("mtd", [expression])
|
209
209
|
const rowArray = [glue(), expression, glue()]
|
210
|
-
|
211
|
-
|
212
|
-
rowArray[0].style.textAlign = "-webkit-left"
|
213
|
-
} else {
|
214
|
-
rowArray[2].children.push(tag)
|
215
|
-
rowArray[2].style.textAlign = "-webkit-right"
|
216
|
-
}
|
210
|
+
rowArray[leqno ? 0 : 2].classes.push(leqno ? "tml-left" : "tml-right")
|
211
|
+
rowArray[leqno ? 0 : 2].children.push(tag)
|
217
212
|
const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"])
|
218
213
|
const table = new mathMLTree.MathNode("mtable", [mtr])
|
219
214
|
table.style.width = "100%"
|
package/src/domTree.js
CHANGED
@@ -134,7 +134,7 @@ export class TextNode {
|
|
134
134
|
}
|
135
135
|
}
|
136
136
|
|
137
|
-
|
137
|
+
/*
|
138
138
|
* This node represents an image embed (<img>) element.
|
139
139
|
*/
|
140
140
|
export class Img {
|
@@ -179,7 +179,7 @@ export class Img {
|
|
179
179
|
markup += ` style="${utils.escape(styles)}"`;
|
180
180
|
}
|
181
181
|
|
182
|
-
markup += "
|
182
|
+
markup += ">";
|
183
183
|
return markup;
|
184
184
|
}
|
185
185
|
}
|
@@ -2,6 +2,7 @@ import defineEnvironment from "../defineEnvironment";
|
|
2
2
|
import { parseCD } from "./cd";
|
3
3
|
import defineFunction from "../defineFunction";
|
4
4
|
import mathMLTree from "../mathMLTree";
|
5
|
+
import { Span } from "../domTree"
|
5
6
|
import { StyleLevel } from "../constants"
|
6
7
|
import ParseError from "../ParseError";
|
7
8
|
import { assertNodeType, assertSymbolNodeType } from "../parseNode";
|
@@ -57,8 +58,9 @@ const getTag = (group, style, rowNum) => {
|
|
57
58
|
return tag
|
58
59
|
} else {
|
59
60
|
// AMS automatcally numbered equaton.
|
60
|
-
// Insert a class so the element can be populated by a
|
61
|
-
|
61
|
+
// Insert a class so the element can be populated by a CSS counter.
|
62
|
+
// WebKit will display the CSS counter only inside a span.
|
63
|
+
tag = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])])
|
62
64
|
}
|
63
65
|
return tag
|
64
66
|
}
|
@@ -255,7 +257,7 @@ const mathmlBuilder = function(group, style) {
|
|
255
257
|
const align = i === 0 ? "left" : i === numRows - 1 ? "right" : "center"
|
256
258
|
mtd.setAttribute("columnalign", align)
|
257
259
|
if (align !== "center") {
|
258
|
-
mtd.
|
260
|
+
mtd.classes.push("tml-" + align)
|
259
261
|
}
|
260
262
|
}
|
261
263
|
row.push(mtd)
|
@@ -266,10 +268,10 @@ const mathmlBuilder = function(group, style) {
|
|
266
268
|
const tag = getTag(group, style.withLevel(cellLevel), i)
|
267
269
|
if (group.leqno) {
|
268
270
|
row[0].children.push(tag)
|
269
|
-
row[0].
|
271
|
+
row[0].classes.push("tml-left")
|
270
272
|
} else {
|
271
273
|
row[row.length - 1].children.push(tag)
|
272
|
-
row[row.length - 1].
|
274
|
+
row[row.length - 1].classes.push("tml-right")
|
273
275
|
}
|
274
276
|
}
|
275
277
|
const mtr = new mathMLTree.MathNode("mtr", row, [])
|
@@ -340,7 +342,11 @@ const mathmlBuilder = function(group, style) {
|
|
340
342
|
for (let j = 0; j < row.children.length; j++) {
|
341
343
|
// Chromium does not recognize text-align: left. Use -webkit-
|
342
344
|
// TODO: Remove -webkit- when Chromium no longer needs it.
|
343
|
-
row.children[j].
|
345
|
+
row.children[j].classes = ["tml-" + (j % 2 ? "left" : "right")]
|
346
|
+
}
|
347
|
+
if (group.addEqnNum) {
|
348
|
+
const k = group.leqno ? 0 : row.children.length - 1
|
349
|
+
row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")]
|
344
350
|
}
|
345
351
|
}
|
346
352
|
if (row.children.length > 1 && group.envClasses.includes("cases")) {
|
@@ -349,7 +355,7 @@ const mathmlBuilder = function(group, style) {
|
|
349
355
|
|
350
356
|
if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
|
351
357
|
for (const cell of row.children) {
|
352
|
-
cell.
|
358
|
+
cell.classes.push("tml-left")
|
353
359
|
}
|
354
360
|
}
|
355
361
|
}
|
@@ -404,7 +410,7 @@ const mathmlBuilder = function(group, style) {
|
|
404
410
|
iCol += 1
|
405
411
|
for (const row of table.children) {
|
406
412
|
if (colAlign.trim() !== "center" && iCol < row.children.length) {
|
407
|
-
row.children[iCol].
|
413
|
+
row.children[iCol].classes = ["tml-" + colAlign.trim()]
|
408
414
|
}
|
409
415
|
}
|
410
416
|
prevTypeWasAlign = true;
|
package/src/functions/accent.js
CHANGED
@@ -2,10 +2,20 @@ import defineFunction, { normalizeArgument } from "../defineFunction"
|
|
2
2
|
import mathMLTree from "../mathMLTree"
|
3
3
|
import stretchy from "../stretchy"
|
4
4
|
import * as mml from "../buildMathML"
|
5
|
+
import utils from "../utils"
|
6
|
+
|
7
|
+
const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚𝐜𝐞𝐠𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐮𝐯𝐰𝐱𝐲𝐳"
|
8
|
+
const talls = "ABCDEFGHIJKLMNOPQRSTUVWXYZbdfhkltΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩβδλζφθψ"
|
9
|
+
+ "𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙𝐛𝐝𝐟𝐡𝐤𝐥𝐭"
|
10
|
+
const longSmalls = new Set(["\\alpha", "\\gamma", "\\delta", "\\epsilon", "\\eta", "\\iota",
|
11
|
+
"\\kappa", "\\mu", "\\nu", "\\pi", "\\rho", "\\sigma", "\\tau", "\\upsilon", "\\chi", "\\psi",
|
12
|
+
"\\omega", "\\imath", "\\jmath"])
|
13
|
+
const longTalls = new Set(["\\Gamma", "\\Delta", "\\Sigma", "\\Omega", "\\beta", "\\delta",
|
14
|
+
"\\lambda", "\\theta", "\\psi"])
|
5
15
|
|
6
16
|
const mathmlBuilder = (group, style) => {
|
7
17
|
const accentNode = group.isStretchy
|
8
|
-
? stretchy.
|
18
|
+
? stretchy.accentNode(group)
|
9
19
|
: new mathMLTree.MathNode("mo", [mml.makeText(group.label, group.mode)]);
|
10
20
|
|
11
21
|
if (group.label === "\\vec") {
|
@@ -13,6 +23,13 @@ const mathmlBuilder = (group, style) => {
|
|
13
23
|
} else {
|
14
24
|
accentNode.style.mathStyle = "normal"
|
15
25
|
accentNode.style.mathDepth = "0"
|
26
|
+
if (needWebkitShift.has(group.label) && utils.isCharacterBox(group.base)) {
|
27
|
+
let shift = ""
|
28
|
+
const ch = group.base.text
|
29
|
+
if (smalls.indexOf(ch) > -1 || longSmalls.has(ch)) { shift = "tml-xshift" }
|
30
|
+
if (talls.indexOf(ch) > -1 || longTalls.has(ch)) { shift = "tml-capshift" }
|
31
|
+
if (shift) { accentNode.classes.push(shift) }
|
32
|
+
}
|
16
33
|
}
|
17
34
|
if (!group.isStretchy) {
|
18
35
|
accentNode.setAttribute("stretchy", "false")
|
@@ -25,25 +42,34 @@ const mathmlBuilder = (group, style) => {
|
|
25
42
|
return node;
|
26
43
|
};
|
27
44
|
|
28
|
-
const
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
const nonStretchyAccents = new Set([
|
46
|
+
"\\acute",
|
47
|
+
"\\grave",
|
48
|
+
"\\ddot",
|
49
|
+
"\\dddot",
|
50
|
+
"\\ddddot",
|
51
|
+
"\\tilde",
|
52
|
+
"\\bar",
|
53
|
+
"\\breve",
|
54
|
+
"\\check",
|
55
|
+
"\\hat",
|
56
|
+
"\\vec",
|
57
|
+
"\\dot",
|
58
|
+
"\\mathring"
|
59
|
+
])
|
60
|
+
|
61
|
+
const needWebkitShift = new Set([
|
62
|
+
"\\acute",
|
63
|
+
"\\bar",
|
64
|
+
"\\breve",
|
65
|
+
"\\check",
|
66
|
+
"\\dot",
|
67
|
+
"\\ddot",
|
68
|
+
"\\grave",
|
69
|
+
"\\hat",
|
70
|
+
"\\mathring",
|
71
|
+
"\\'", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\r", "\\H", "\\v"
|
72
|
+
])
|
47
73
|
|
48
74
|
// Accents
|
49
75
|
defineFunction({
|
@@ -81,7 +107,7 @@ defineFunction({
|
|
81
107
|
handler: (context, args) => {
|
82
108
|
const base = normalizeArgument(args[0]);
|
83
109
|
|
84
|
-
const isStretchy = !
|
110
|
+
const isStretchy = !nonStretchyAccents.has(context.funcName);
|
85
111
|
|
86
112
|
return {
|
87
113
|
type: "accent",
|
@@ -119,7 +145,6 @@ defineFunction({
|
|
119
145
|
mode: mode,
|
120
146
|
label: context.funcName,
|
121
147
|
isStretchy: false,
|
122
|
-
isShifty: true,
|
123
148
|
base: base
|
124
149
|
};
|
125
150
|
},
|
@@ -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
@@ -63,7 +63,10 @@ rgba(0,0,0,0) 100%);`
|
|
63
63
|
node.style.marginRight = "0.03889em"
|
64
64
|
break
|
65
65
|
case "\\sout":
|
66
|
-
node.style
|
66
|
+
node.style.backgroundImage = 'linear-gradient(black, black)'
|
67
|
+
node.style.backgroundRepeat = 'no-repeat'
|
68
|
+
node.style.backgroundSize = '100% 1.5px'
|
69
|
+
node.style.backgroundPosition = '0 center'
|
67
70
|
break
|
68
71
|
case "\\boxed":
|
69
72
|
// \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
|
package/src/functions/lap.js
CHANGED
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
@@ -294,6 +294,8 @@ defineSymbol(math, textord, "\u2127", "\\mho");
|
|
294
294
|
defineSymbol(math, textord, "\u2132", "\\Finv", true);
|
295
295
|
defineSymbol(math, textord, "\u2141", "\\Game", true);
|
296
296
|
defineSymbol(math, textord, "\u2035", "\\backprime");
|
297
|
+
defineSymbol(math, textord, "\u2036", "\\backdprime");
|
298
|
+
defineSymbol(math, textord, "\u2037", "\\backtrprime");
|
297
299
|
defineSymbol(math, textord, "\u25b2", "\\blacktriangle");
|
298
300
|
defineSymbol(math, textord, "\u25bc", "\\blacktriangledown");
|
299
301
|
defineSymbol(math, textord, "\u25a0", "\\blacksquare");
|
@@ -497,6 +499,9 @@ defineSymbol(text, textord, "\u2423", "\\textvisiblespace", true);
|
|
497
499
|
defineSymbol(math, textord, "\u2220", "\\angle", true);
|
498
500
|
defineSymbol(math, textord, "\u221e", "\\infty", true);
|
499
501
|
defineSymbol(math, textord, "\u2032", "\\prime");
|
502
|
+
defineSymbol(math, textord, "\u2033", "\\dprime");
|
503
|
+
defineSymbol(math, textord, "\u2034", "\\trprime");
|
504
|
+
defineSymbol(math, textord, "\u2057", "\\qprime");
|
500
505
|
defineSymbol(math, textord, "\u25b3", "\\triangle");
|
501
506
|
defineSymbol(text, textord, "\u0391", "\\Alpha", true);
|
502
507
|
defineSymbol(text, textord, "\u0392", "\\Beta", true);
|
@@ -676,7 +681,8 @@ defineSymbol(math, punct, ";", ";");
|
|
676
681
|
defineSymbol(math, bin, "\u22bc", "\\barwedge", true);
|
677
682
|
defineSymbol(math, bin, "\u22bb", "\\veebar", true);
|
678
683
|
defineSymbol(math, bin, "\u2299", "\\odot", true);
|
679
|
-
|
684
|
+
// Firefox turns ⊕ into an emoji. So append \uFE0E. Define Unicode character in macros, not here.
|
685
|
+
defineSymbol(math, bin, "\u2295\uFE0E", "\\oplus");
|
680
686
|
defineSymbol(math, bin, "\u2297", "\\otimes", true);
|
681
687
|
defineSymbol(math, textord, "\u2202", "\\partial", true);
|
682
688
|
defineSymbol(math, bin, "\u2298", "\\oslash", true);
|