temml 0.10.21 → 0.10.23
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 +0 -4
- package/dist/Temml-Fira.css +152 -0
- package/dist/Temml-STIX2.css +0 -4
- package/dist/temml.cjs +162 -83
- package/dist/temml.d.ts +1 -1
- package/dist/temml.js +162 -83
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +162 -83
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +1 -1
- package/src/Parser.js +8 -1
- package/src/buildMathML.js +7 -4
- package/src/functions/color.js +1 -1
- package/src/functions/delimsizing.js +22 -7
- package/src/functions/font.js +31 -2
- package/src/functions/mclass.js +3 -0
- package/src/functions/reflect.js +24 -0
- package/src/functions/sizing.js +1 -1
- package/src/functions/styling.js +1 -1
- package/src/functions/symbolsOrd.js +0 -2
- package/src/functions.js +1 -0
- package/src/linebreaking.js +3 -2
- package/src/macros.js +49 -53
- package/src/postProcess.js +1 -1
- package/src/replace.js +8 -8
- package/src/symbols.js +7 -1
package/README.md
CHANGED
package/dist/Temml-Asana.css
CHANGED
@@ -0,0 +1,152 @@
|
|
1
|
+
/*
|
2
|
+
Fira Math fonts are released under the SIL OPEN FONT LICENSE Version 1.1.
|
3
|
+
|
4
|
+
The Fira Math WOFF2 font has been obtained from
|
5
|
+
http://www.gust.org.pl/projects/e-foundry/
|
6
|
+
|
7
|
+
The Temml.woff2 is a clone of KaTeX_Script-Regular, except that the code points
|
8
|
+
have been changed from ASCII to Unicode Mathematical Alphanumeric Symbols Script capitals,
|
9
|
+
Unicode range 1D49C to 1D4B5.
|
10
|
+
*/
|
11
|
+
|
12
|
+
@font-face {
|
13
|
+
font-family: 'Temml';
|
14
|
+
src: url('Temml.woff2') format('woff2');
|
15
|
+
font-weight: normal;
|
16
|
+
font-style: normal;
|
17
|
+
}
|
18
|
+
|
19
|
+
@font-face {
|
20
|
+
font-family: Fira Math;
|
21
|
+
src: url('FiraMath-Regular.woff2');
|
22
|
+
}
|
23
|
+
|
24
|
+
math {
|
25
|
+
font-style: normal;
|
26
|
+
font-weight: normal;
|
27
|
+
line-height: normal;
|
28
|
+
font-size-adjust: none;
|
29
|
+
text-indent: 0;
|
30
|
+
text-transform: none;
|
31
|
+
letter-spacing: normal;
|
32
|
+
word-wrap: normal;
|
33
|
+
direction: ltr;
|
34
|
+
}
|
35
|
+
|
36
|
+
math * {
|
37
|
+
border-color: currentColor;
|
38
|
+
}
|
39
|
+
|
40
|
+
math {
|
41
|
+
font-family: "Fira Math", math;
|
42
|
+
}
|
43
|
+
|
44
|
+
/* Next line is active in Firefox and Safari.
|
45
|
+
* Not in Chromium, which recognizes display: "block math" written inline. */
|
46
|
+
math.tml-display { display: block; }
|
47
|
+
|
48
|
+
*.mathscr {
|
49
|
+
font-family: "Temml";
|
50
|
+
}
|
51
|
+
|
52
|
+
/* Chromium prime alignment */
|
53
|
+
mo.tml-prime {
|
54
|
+
font-family: Temml;
|
55
|
+
}
|
56
|
+
|
57
|
+
mrow.tml-cancel {
|
58
|
+
background: linear-gradient(to top left,
|
59
|
+
rgba(0,0,0,0) 0%,
|
60
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
61
|
+
rgba(0,0,0,1) 50%,
|
62
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
63
|
+
rgba(0,0,0,0) 100%);
|
64
|
+
}
|
65
|
+
|
66
|
+
mrow.tml-bcancel {
|
67
|
+
background: linear-gradient(to top right,
|
68
|
+
rgba(0,0,0,0) 0%,
|
69
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
70
|
+
rgba(0,0,0,1) 50%,
|
71
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
72
|
+
rgba(0,0,0,0) 100%);
|
73
|
+
}
|
74
|
+
|
75
|
+
mrow.tml-xcancel {
|
76
|
+
background: linear-gradient(to top left,
|
77
|
+
rgba(0,0,0,0) 0%,
|
78
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
79
|
+
rgba(0,0,0,1) 50%,
|
80
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
81
|
+
rgba(0,0,0,0) 100%),
|
82
|
+
linear-gradient(to top right,
|
83
|
+
rgba(0,0,0,0) 0%,
|
84
|
+
rgba(0,0,0,0) calc(50% - 0.06em),
|
85
|
+
rgba(0,0,0,1) 50%,
|
86
|
+
rgba(0,0,0,0) calc(50% + 0.06em),
|
87
|
+
rgba(0,0,0,0) 100%)
|
88
|
+
}
|
89
|
+
|
90
|
+
/* Prevent f' from overlapping in Chromium */
|
91
|
+
mo.prime-pad {
|
92
|
+
padding-left: 0.08em;
|
93
|
+
}
|
94
|
+
|
95
|
+
/* Array cell justification in Firefox & WebKit */
|
96
|
+
.tml-right {
|
97
|
+
text-align: right;
|
98
|
+
}
|
99
|
+
.tml-left {
|
100
|
+
text-align: left;
|
101
|
+
}
|
102
|
+
|
103
|
+
/* Stretch \widetilde & set array cell justification in Chromium */
|
104
|
+
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
105
|
+
.tml-crooked-2 {
|
106
|
+
transform: scale(2.0, 1.1)
|
107
|
+
}
|
108
|
+
.tml-crooked-3 {
|
109
|
+
transform: scale(3.0, 1.3)
|
110
|
+
}
|
111
|
+
.tml-crooked-4 {
|
112
|
+
transform: scale(4.0, 1.4)
|
113
|
+
}
|
114
|
+
.tml-right {
|
115
|
+
text-align: -webkit-right;
|
116
|
+
}
|
117
|
+
.tml-left {
|
118
|
+
text-align: -webkit-left;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
/* Adjust WebKit accents */
|
123
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
124
|
+
.tml-xshift { transform: translate(0px, 0.45em) }
|
125
|
+
.tml-capshift { transform: translate(0px, 0.35em) }
|
126
|
+
}
|
127
|
+
|
128
|
+
/* flex-wrap for line-breaking in Chromium */
|
129
|
+
math {
|
130
|
+
display: inline-flex;
|
131
|
+
flex-wrap: wrap;
|
132
|
+
align-items: baseline;
|
133
|
+
}
|
134
|
+
math > mrow {
|
135
|
+
padding: 0.5ex 0ex;
|
136
|
+
}
|
137
|
+
|
138
|
+
/* Avoid flex-wrap in Firefox */
|
139
|
+
@-moz-document url-prefix() {
|
140
|
+
math { display: inline; }
|
141
|
+
math > mrow { padding: 0 }
|
142
|
+
}
|
143
|
+
|
144
|
+
/* AMS environment auto-numbering via CSS counter. */
|
145
|
+
.tml-eqn::before {
|
146
|
+
counter-increment: tmlEqnNo;
|
147
|
+
content: "(" counter(tmlEqnNo) ")";
|
148
|
+
}
|
149
|
+
|
150
|
+
body {
|
151
|
+
counter-reset: tmlEqnNo;
|
152
|
+
}
|
package/dist/Temml-STIX2.css
CHANGED
package/dist/temml.cjs
CHANGED
@@ -936,7 +936,8 @@ defineSymbol(math, textord, "\u2135", "\\aleph", true);
|
|
936
936
|
defineSymbol(math, textord, "\u2200", "\\forall", true);
|
937
937
|
defineSymbol(math, textord, "\u210f", "\\hbar", true);
|
938
938
|
defineSymbol(math, textord, "\u2203", "\\exists", true);
|
939
|
-
|
939
|
+
// ∇ is actually a unary operator, not binary. But this works.
|
940
|
+
defineSymbol(math, bin, "\u2207", "\\nabla", true);
|
940
941
|
defineSymbol(math, textord, "\u266d", "\\flat", true);
|
941
942
|
defineSymbol(math, textord, "\u2113", "\\ell", true);
|
942
943
|
defineSymbol(math, textord, "\u266e", "\\natural", true);
|
@@ -990,6 +991,7 @@ defineSymbol(math, bin, "\u2021", "\\ddagger");
|
|
990
991
|
defineSymbol(math, bin, "\u2240", "\\wr", true);
|
991
992
|
defineSymbol(math, bin, "\u2a3f", "\\amalg");
|
992
993
|
defineSymbol(math, bin, "\u0026", "\\And"); // from amsmath
|
994
|
+
defineSymbol(math, bin, "\u2AFD", "\\sslash", true); // from stmaryrd
|
993
995
|
|
994
996
|
// Arrow Symbols
|
995
997
|
defineSymbol(math, rel, "\u27f5", "\\longleftarrow", true);
|
@@ -1024,6 +1026,7 @@ defineSymbol(math, mathord, "\u2609", "\\astrosun", true);
|
|
1024
1026
|
defineSymbol(math, mathord, "\u263c", "\\sun", true);
|
1025
1027
|
defineSymbol(math, mathord, "\u263e", "\\leftmoon", true);
|
1026
1028
|
defineSymbol(math, mathord, "\u263d", "\\rightmoon", true);
|
1029
|
+
defineSymbol(math, mathord, "\u2295", "\\Earth");
|
1027
1030
|
|
1028
1031
|
// AMS Negated Binary Relations
|
1029
1032
|
defineSymbol(math, rel, "\u226e", "\\nless", true);
|
@@ -1251,6 +1254,8 @@ defineSymbol(math, bin, "\u27d5", "\\leftouterjoin", true);
|
|
1251
1254
|
defineSymbol(math, bin, "\u27d6", "\\rightouterjoin", true);
|
1252
1255
|
defineSymbol(math, bin, "\u27d7", "\\fullouterjoin", true);
|
1253
1256
|
|
1257
|
+
defineSymbol(math, bin, "\u2238", "\\dotminus", true); // stix
|
1258
|
+
|
1254
1259
|
// AMS Arrows
|
1255
1260
|
// Note: unicode-math maps \u21e2 to their own function \rightdasharrow.
|
1256
1261
|
// We'll map it to AMS function \dashrightarrow. It produces the same atom.
|
@@ -1408,6 +1413,7 @@ defineSymbol(math, mathord, "\u2aeb", "\\Bot");
|
|
1408
1413
|
defineSymbol(math, bin, "\u2217", "\u2217", true);
|
1409
1414
|
defineSymbol(math, bin, "+", "+");
|
1410
1415
|
defineSymbol(math, bin, "*", "*");
|
1416
|
+
defineSymbol(math, bin, "\u2044", "/", true);
|
1411
1417
|
defineSymbol(math, bin, "\u2044", "\u2044");
|
1412
1418
|
defineSymbol(math, bin, "\u2212", "-", true);
|
1413
1419
|
defineSymbol(math, bin, "\u22c5", "\\cdot", true);
|
@@ -1864,7 +1870,8 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
|
|
1864
1870
|
continue
|
1865
1871
|
}
|
1866
1872
|
block.push(node);
|
1867
|
-
if (node.type && node.type === "mo" && node.children.length === 1
|
1873
|
+
if (node.type && node.type === "mo" && node.children.length === 1 &&
|
1874
|
+
!Object.hasOwn(node.attributes, "movablelimits")) {
|
1868
1875
|
const ch = node.children[0].text;
|
1869
1876
|
if (openDelims.indexOf(ch) > -1) {
|
1870
1877
|
level += 1;
|
@@ -1879,7 +1886,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
|
|
1879
1886
|
mrows.push(element);
|
1880
1887
|
block = [node];
|
1881
1888
|
}
|
1882
|
-
} else if (level === 0 && wrapMode === "tex") {
|
1889
|
+
} else if (level === 0 && wrapMode === "tex" && ch !== "∇") {
|
1883
1890
|
// Check if the following node is a \nobreak text node, e.g. "~""
|
1884
1891
|
const next = i < expression.length - 1 ? expression[i + 1] : null;
|
1885
1892
|
let glueIsFreeOfNobreak = true;
|
@@ -2017,9 +2024,11 @@ const consolidateText = mrow => {
|
|
2017
2024
|
};
|
2018
2025
|
|
2019
2026
|
const numberRegEx$1 = /^[0-9]$/;
|
2020
|
-
const
|
2021
|
-
return (node.type === "
|
2022
|
-
|
2027
|
+
const isDotOrComma = (node, followingNode) => {
|
2028
|
+
return ((node.type === "textord" && node.text === ".") ||
|
2029
|
+
(node.type === "atom" && node.text === ",")) &&
|
2030
|
+
// Don't consolidate if there is a space after the comma.
|
2031
|
+
node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
|
2023
2032
|
};
|
2024
2033
|
const consolidateNumbers = expression => {
|
2025
2034
|
// Consolidate adjacent numbers. We want to return <mn>1,506.3</mn>,
|
@@ -2042,7 +2051,8 @@ const consolidateNumbers = expression => {
|
|
2042
2051
|
|
2043
2052
|
// Determine if numeral groups are separated by a comma or dot.
|
2044
2053
|
for (let i = nums.length - 1; i > 0; i--) {
|
2045
|
-
if (nums[i - 1].end === nums[i].start - 2 &&
|
2054
|
+
if (nums[i - 1].end === nums[i].start - 2 &&
|
2055
|
+
isDotOrComma(expression[nums[i].start - 1], expression[nums[i].start])) {
|
2046
2056
|
// Merge the two groups.
|
2047
2057
|
nums[i - 1].end = nums[i].end;
|
2048
2058
|
nums.splice(i, 1);
|
@@ -3258,7 +3268,7 @@ defineFunction({
|
|
3258
3268
|
}
|
3259
3269
|
|
3260
3270
|
// Parse out the implicit body that should be colored.
|
3261
|
-
const body = parser.parseExpression(true, breakOnTokenText);
|
3271
|
+
const body = parser.parseExpression(true, breakOnTokenText, true);
|
3262
3272
|
|
3263
3273
|
return {
|
3264
3274
|
type: "color",
|
@@ -3700,17 +3710,13 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
|
|
3700
3710
|
|
3701
3711
|
// Delimiter functions
|
3702
3712
|
function checkDelimiter(delim, context) {
|
3703
|
-
if (delim.type === "ordgroup" && delim.body.length === 1 && delim.body[0].text === "\u2044") {
|
3704
|
-
// Recover "/" from the zero spacing group. (See macros.js)
|
3705
|
-
delim = { type: "textord", text: "/", mode: "math" };
|
3706
|
-
}
|
3707
3713
|
const symDelim = checkSymbolNodeType(delim);
|
3708
3714
|
if (symDelim && delimiters.includes(symDelim.text)) {
|
3709
3715
|
// If a character is not in the MathML operator dictionary, it will not stretch.
|
3710
3716
|
// Replace such characters w/characters that will stretch.
|
3717
|
+
if (["/", "\u2044"].includes(symDelim.text)) { symDelim.text = "\u2215"; }
|
3711
3718
|
if (["<", "\\lt"].includes(symDelim.text)) { symDelim.text = "⟨"; }
|
3712
3719
|
if ([">", "\\gt"].includes(symDelim.text)) { symDelim.text = "⟩"; }
|
3713
|
-
if (symDelim.text === "/") { symDelim.text = "\u2215"; }
|
3714
3720
|
if (symDelim.text === "\\backslash") { symDelim.text = "\u2216"; }
|
3715
3721
|
return symDelim;
|
3716
3722
|
} else if (symDelim) {
|
@@ -3819,8 +3825,26 @@ defineFunction({
|
|
3819
3825
|
const parser = context.parser;
|
3820
3826
|
// Parse out the implicit body
|
3821
3827
|
++parser.leftrightDepth;
|
3822
|
-
// parseExpression stops before '\\right'
|
3823
|
-
|
3828
|
+
// parseExpression stops before '\\right' or `\\middle`
|
3829
|
+
let body = parser.parseExpression(false, null, true);
|
3830
|
+
let nextToken = parser.fetch();
|
3831
|
+
while (nextToken.text === "\\middle") {
|
3832
|
+
// `\middle`, from the ε-TeX package, ends one group and starts another group.
|
3833
|
+
// We had to parse this expression with `breakOnMiddle` enabled in order
|
3834
|
+
// to get TeX-compliant parsing of \over.
|
3835
|
+
// But we do not want, at this point, to end on \middle, so continue
|
3836
|
+
// to parse until we fetch a `\right`.
|
3837
|
+
parser.consume();
|
3838
|
+
const middle = parser.fetch().text;
|
3839
|
+
if (!symbols.math[middle]) {
|
3840
|
+
throw new ParseError(`Invalid delimiter '${middle}' after '\\middle'`);
|
3841
|
+
}
|
3842
|
+
checkDelimiter({ type: "atom", mode: "math", text: middle }, { funcName: "\\middle" });
|
3843
|
+
body.push({ type: "middle", mode: "math", delim: middle });
|
3844
|
+
parser.consume();
|
3845
|
+
body = body.concat(parser.parseExpression(false, null, true));
|
3846
|
+
nextToken = parser.fetch();
|
3847
|
+
}
|
3824
3848
|
--parser.leftrightDepth;
|
3825
3849
|
// Check the next token
|
3826
3850
|
parser.expect("\\right", false);
|
@@ -5094,6 +5118,21 @@ defineFunction({
|
|
5094
5118
|
}
|
5095
5119
|
});
|
5096
5120
|
|
5121
|
+
const isLongVariableName = (group, font) => {
|
5122
|
+
if (font !== "mathrm" || group.body.type !== "ordgroup" || group.body.body.length === 1) {
|
5123
|
+
return false
|
5124
|
+
}
|
5125
|
+
if (group.body.body[0].type !== "mathord") { return false }
|
5126
|
+
for (let i = 1; i < group.body.body.length; i++) {
|
5127
|
+
const parseNodeType = group.body.body[i].type;
|
5128
|
+
if (!(parseNodeType === "mathord" ||
|
5129
|
+
(parseNodeType === "textord" && !isNaN(group.body.body[i].text)))) {
|
5130
|
+
return false
|
5131
|
+
}
|
5132
|
+
}
|
5133
|
+
return true
|
5134
|
+
};
|
5135
|
+
|
5097
5136
|
const mathmlBuilder$6 = (group, style) => {
|
5098
5137
|
const font = group.font;
|
5099
5138
|
const newStyle = style.withFont(font);
|
@@ -5105,6 +5144,20 @@ const mathmlBuilder$6 = (group, style) => {
|
|
5105
5144
|
return mathGroup
|
5106
5145
|
}
|
5107
5146
|
// Check if it is possible to consolidate elements into a single <mi> element.
|
5147
|
+
if (isLongVariableName(group, font)) {
|
5148
|
+
// This is a \mathrm{…} group. It gets special treatment because symbolsOrd.js
|
5149
|
+
// wraps <mi> elements with <mrow>s to work around a Firefox bug.
|
5150
|
+
const mi = mathGroup.children[0].children[0];
|
5151
|
+
delete mi.attributes.mathvariant;
|
5152
|
+
for (let i = 1; i < mathGroup.children.length; i++) {
|
5153
|
+
mi.children[0].text += mathGroup.children[i].type === "mn"
|
5154
|
+
? mathGroup.children[i].children[0].text
|
5155
|
+
: mathGroup.children[i].children[0].children[0].text;
|
5156
|
+
}
|
5157
|
+
// Wrap in a <mrow> to prevent the same Firefox bug.
|
5158
|
+
const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200b"));
|
5159
|
+
return new mathMLTree.MathNode("mrow", [bogus, mi])
|
5160
|
+
}
|
5108
5161
|
let canConsolidate = mathGroup.children[0].type === "mo";
|
5109
5162
|
for (let i = 1; i < mathGroup.children.length; i++) {
|
5110
5163
|
if (mathGroup.children[i].type === "mo" && font === "boldsymbol") {
|
@@ -5195,7 +5248,7 @@ defineFunction({
|
|
5195
5248
|
},
|
5196
5249
|
handler: ({ parser, funcName, breakOnTokenText }, args) => {
|
5197
5250
|
const { mode } = parser;
|
5198
|
-
const body = parser.parseExpression(true, breakOnTokenText);
|
5251
|
+
const body = parser.parseExpression(true, breakOnTokenText, true);
|
5199
5252
|
const fontStyle = `math${funcName.slice(1)}`;
|
5200
5253
|
|
5201
5254
|
return {
|
@@ -6156,6 +6209,9 @@ function mathmlBuilder$3(group, style) {
|
|
6156
6209
|
if (group.isCharacterBox || inner[0].type === "mathord") {
|
6157
6210
|
node = inner[0];
|
6158
6211
|
node.type = "mi";
|
6212
|
+
if (node.children.length === 1 && node.children[0].text && node.children[0].text === "∇") {
|
6213
|
+
node.setAttribute("mathvariant", "normal");
|
6214
|
+
}
|
6159
6215
|
} else {
|
6160
6216
|
node = new mathMLTree.MathNode("mi", inner);
|
6161
6217
|
}
|
@@ -7143,6 +7199,28 @@ defineFunction({
|
|
7143
7199
|
}
|
7144
7200
|
});
|
7145
7201
|
|
7202
|
+
defineFunction({
|
7203
|
+
type: "reflect",
|
7204
|
+
names: ["\\reflectbox"],
|
7205
|
+
props: {
|
7206
|
+
numArgs: 1,
|
7207
|
+
argTypes: ["hbox"],
|
7208
|
+
allowedInText: true
|
7209
|
+
},
|
7210
|
+
handler({ parser }, args) {
|
7211
|
+
return {
|
7212
|
+
type: "reflect",
|
7213
|
+
mode: parser.mode,
|
7214
|
+
body: args[0]
|
7215
|
+
};
|
7216
|
+
},
|
7217
|
+
mathmlBuilder(group, style) {
|
7218
|
+
const node = buildGroup$1(group.body, style);
|
7219
|
+
node.style.transform = "scaleX(-1)";
|
7220
|
+
return node
|
7221
|
+
}
|
7222
|
+
});
|
7223
|
+
|
7146
7224
|
defineFunction({
|
7147
7225
|
type: "internal",
|
7148
7226
|
names: ["\\relax"],
|
@@ -7248,7 +7326,7 @@ defineFunction({
|
|
7248
7326
|
// eslint-disable-next-line no-console
|
7249
7327
|
console.log(`Temml strict-mode warning: Command ${funcName} is invalid in math mode.`);
|
7250
7328
|
}
|
7251
|
-
const body = parser.parseExpression(false, breakOnTokenText);
|
7329
|
+
const body = parser.parseExpression(false, breakOnTokenText, true);
|
7252
7330
|
return {
|
7253
7331
|
type: "sizing",
|
7254
7332
|
mode: parser.mode,
|
@@ -7381,7 +7459,7 @@ defineFunction({
|
|
7381
7459
|
},
|
7382
7460
|
handler({ breakOnTokenText, funcName, parser }, args) {
|
7383
7461
|
// parse out the implicit body
|
7384
|
-
const body = parser.parseExpression(true, breakOnTokenText);
|
7462
|
+
const body = parser.parseExpression(true, breakOnTokenText, true);
|
7385
7463
|
|
7386
7464
|
const scriptLevel = funcName.slice(1, funcName.length - 5);
|
7387
7465
|
return {
|
@@ -7812,22 +7890,22 @@ const offset = Object.freeze({
|
|
7812
7890
|
"sans-serif-bold-italic": ch => { return 0x1D5F5 },
|
7813
7891
|
"monospace": ch => { return 0x1D629 }
|
7814
7892
|
},
|
7815
|
-
upperCaseGreek: { // A-Ω
|
7893
|
+
upperCaseGreek: { // A-Ω
|
7816
7894
|
"normal": ch => { return 0 },
|
7817
|
-
"bold": ch => { return
|
7818
|
-
"italic": ch => { return
|
7895
|
+
"bold": ch => { return 0x1D317 },
|
7896
|
+
"italic": ch => { return 0x1D351 },
|
7819
7897
|
// \boldsymbol actually returns upright bold for upperCaseGreek
|
7820
|
-
"bold-italic": ch => { return
|
7898
|
+
"bold-italic": ch => { return 0x1D317 },
|
7821
7899
|
"script": ch => { return 0 },
|
7822
7900
|
"script-bold": ch => { return 0 },
|
7823
7901
|
"fraktur": ch => { return 0 },
|
7824
7902
|
"fraktur-bold": ch => { return 0 },
|
7825
7903
|
"double-struck": ch => { return 0 },
|
7826
7904
|
// Unicode has no code points for regular-weight san-serif Greek. Use bold.
|
7827
|
-
"sans-serif": ch => { return
|
7828
|
-
"sans-serif-bold": ch => { return
|
7905
|
+
"sans-serif": ch => { return 0x1D3C5 },
|
7906
|
+
"sans-serif-bold": ch => { return 0x1D3C5 },
|
7829
7907
|
"sans-serif-italic": ch => { return 0 },
|
7830
|
-
"sans-serif-bold-italic": ch => { return
|
7908
|
+
"sans-serif-bold-italic": ch => { return 0x1D3FF },
|
7831
7909
|
"monospace": ch => { return 0 }
|
7832
7910
|
},
|
7833
7911
|
lowerCaseGreek: { // α-ω
|
@@ -7887,7 +7965,7 @@ const variantChar = (ch, variant) => {
|
|
7887
7965
|
? "upperCaseLatin"
|
7888
7966
|
: 0x60 < codePoint && codePoint < 0x7b
|
7889
7967
|
? "lowerCaseLatin"
|
7890
|
-
: (0x390 < codePoint && codePoint < 0x3AA)
|
7968
|
+
: (0x390 < codePoint && codePoint < 0x3AA)
|
7891
7969
|
? "upperCaseGreek"
|
7892
7970
|
: 0x3B0 < codePoint && codePoint < 0x3CA || ch === "\u03d5"
|
7893
7971
|
? "lowerCaseGreek"
|
@@ -8016,8 +8094,6 @@ defineFunctionBuilders({
|
|
8016
8094
|
node = new mathMLTree.MathNode("mi", [text]);
|
8017
8095
|
if (text.text === origText && latinRegEx.test(origText)) {
|
8018
8096
|
node.setAttribute("mathvariant", "italic");
|
8019
|
-
} else if (text.text === "∇" && variant === "normal") {
|
8020
|
-
node.setAttribute("mathvariant", "normal");
|
8021
8097
|
}
|
8022
8098
|
}
|
8023
8099
|
return node
|
@@ -8654,6 +8730,24 @@ defineMacro("\\char", function(context) {
|
|
8654
8730
|
return `\\@char{${number}}`;
|
8655
8731
|
});
|
8656
8732
|
|
8733
|
+
function recreateArgStr(context) {
|
8734
|
+
// Recreate the macro's original argument string from the array of parse tokens.
|
8735
|
+
const tokens = context.consumeArgs(1)[0];
|
8736
|
+
let str = "";
|
8737
|
+
let expectedLoc = tokens[tokens.length - 1].loc.start;
|
8738
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
8739
|
+
const actualLoc = tokens[i].loc.start;
|
8740
|
+
if (actualLoc > expectedLoc) {
|
8741
|
+
// context.consumeArgs has eaten a space.
|
8742
|
+
str += " ";
|
8743
|
+
expectedLoc = actualLoc;
|
8744
|
+
}
|
8745
|
+
str += tokens[i].text;
|
8746
|
+
expectedLoc += tokens[i].text.length;
|
8747
|
+
}
|
8748
|
+
return str
|
8749
|
+
}
|
8750
|
+
|
8657
8751
|
// The Latin Modern font renders <mi>√</mi> at the wrong vertical alignment.
|
8658
8752
|
// This macro provides a better rendering.
|
8659
8753
|
defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
|
@@ -8661,10 +8755,6 @@ defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
|
|
8661
8755
|
// See comment for \oplus in symbols.js.
|
8662
8756
|
defineMacro("\u2295", "\\oplus");
|
8663
8757
|
|
8664
|
-
// Per TeXbook p.122, "/" gets zero operator spacing.
|
8665
|
-
// And MDN recommends using U+2044 instead of / for inline
|
8666
|
-
defineMacro("/", "{\u2044}");
|
8667
|
-
|
8668
8758
|
// Since Temml has no \par, ignore \long.
|
8669
8759
|
defineMacro("\\long", "");
|
8670
8760
|
|
@@ -9042,6 +9132,11 @@ defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
|
|
9042
9132
|
defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
|
9043
9133
|
defineMacro("\\plim", "\\DOTSB\\operatorname*{plim}");
|
9044
9134
|
|
9135
|
+
//////////////////////////////////////////////////////////////////////
|
9136
|
+
// MnSymbol.sty
|
9137
|
+
|
9138
|
+
defineMacro("\\leftmodels", "\\mathop{\\reflectbox{$\\models$}}");
|
9139
|
+
|
9045
9140
|
//////////////////////////////////////////////////////////////////////
|
9046
9141
|
// braket.sty
|
9047
9142
|
// http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf
|
@@ -9051,56 +9146,33 @@ defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
|
|
9051
9146
|
defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
|
9052
9147
|
defineMacro("\\Bra", "\\left\\langle#1\\right|");
|
9053
9148
|
defineMacro("\\Ket", "\\left|#1\\right\\rangle");
|
9054
|
-
|
9055
|
-
|
9056
|
-
const
|
9057
|
-
const
|
9058
|
-
|
9059
|
-
const oldMiddle = context.macros.get("|");
|
9060
|
-
const oldMiddleDouble = context.macros.get("\\|");
|
9061
|
-
context.macros.beginGroup();
|
9062
|
-
const midMacro = (double) => (context) => {
|
9063
|
-
if (one) {
|
9064
|
-
// Only modify the first instance of | or \|
|
9065
|
-
context.macros.set("|", oldMiddle);
|
9066
|
-
if (middleDouble.length) {
|
9067
|
-
context.macros.set("\\|", oldMiddleDouble);
|
9068
|
-
}
|
9069
|
-
}
|
9070
|
-
let doubled = double;
|
9071
|
-
if (!double && middleDouble.length) {
|
9072
|
-
// Mimic \@ifnextchar
|
9073
|
-
const nextToken = context.future();
|
9074
|
-
if (nextToken.text === "|") {
|
9075
|
-
context.popToken();
|
9076
|
-
doubled = true;
|
9077
|
-
}
|
9078
|
-
}
|
9079
|
-
return {
|
9080
|
-
tokens: doubled ? middleDouble : middle,
|
9081
|
-
numArgs: 0
|
9082
|
-
};
|
9083
|
-
};
|
9084
|
-
context.macros.set("|", midMacro(false));
|
9085
|
-
if (middleDouble.length) {
|
9086
|
-
context.macros.set("\\|", midMacro(true));
|
9087
|
-
}
|
9088
|
-
const arg = context.consumeArg().tokens;
|
9089
|
-
const expanded = context.expandTokens([...right, ...arg, ...left]); // reversed
|
9090
|
-
context.macros.endGroup();
|
9091
|
-
return {
|
9092
|
-
tokens: expanded.reverse(),
|
9093
|
-
numArgs: 0
|
9094
|
-
};
|
9149
|
+
// A helper for \Braket and \Set
|
9150
|
+
const replaceVert = (argStr, match) => {
|
9151
|
+
const ch = match[0] === "|" ? "\\vert" : "\\Vert";
|
9152
|
+
const replaceStr = `}\\,\\middle${ch}\\,{`;
|
9153
|
+
return argStr.slice(0, match.index) + replaceStr + argStr.slice(match.index + match[0].length)
|
9095
9154
|
};
|
9096
|
-
defineMacro("\\
|
9097
|
-
|
9098
|
-
|
9099
|
-
|
9100
|
-
|
9101
|
-
|
9102
|
-
|
9103
|
-
|
9155
|
+
defineMacro("\\Braket", function(context) {
|
9156
|
+
let argStr = recreateArgStr(context);
|
9157
|
+
const regEx = /\|\||\||\\\|/g;
|
9158
|
+
let match;
|
9159
|
+
while ((match = regEx.exec(argStr)) !== null) {
|
9160
|
+
argStr = replaceVert(argStr, match);
|
9161
|
+
}
|
9162
|
+
return "\\left\\langle{" + argStr + "}\\right\\rangle"
|
9163
|
+
});
|
9164
|
+
defineMacro("\\Set", function(context) {
|
9165
|
+
let argStr = recreateArgStr(context);
|
9166
|
+
const match = /\|\||\||\\\|/.exec(argStr);
|
9167
|
+
if (match) {
|
9168
|
+
argStr = replaceVert(argStr, match);
|
9169
|
+
}
|
9170
|
+
return "\\left\\{\\:{" + argStr + "}\\:\\right\\}"
|
9171
|
+
});
|
9172
|
+
defineMacro("\\set", function(context) {
|
9173
|
+
const argStr = recreateArgStr(context);
|
9174
|
+
return "\\{{" + argStr.replace(/\|/, "}\\mid{") + "}\\}"
|
9175
|
+
});
|
9104
9176
|
|
9105
9177
|
//////////////////////////////////////////////////////////////////////
|
9106
9178
|
// actuarialangle.dtx
|
@@ -12149,8 +12221,12 @@ class Parser {
|
|
12149
12221
|
* `breakOnTokenText`: The text of the token that the expression should end
|
12150
12222
|
* with, or `null` if something else should end the
|
12151
12223
|
* expression.
|
12224
|
+
*
|
12225
|
+
* `breakOnMiddle`: \color, \over, and old styling functions work on an implicit group.
|
12226
|
+
* These groups end just before the usual tokens, but they also
|
12227
|
+
* end just before `\middle`.
|
12152
12228
|
*/
|
12153
|
-
parseExpression(breakOnInfix, breakOnTokenText) {
|
12229
|
+
parseExpression(breakOnInfix, breakOnTokenText, breakOnMiddle) {
|
12154
12230
|
const body = [];
|
12155
12231
|
// Keep adding atoms to the body until we can't parse any more atoms (either
|
12156
12232
|
// we reached the end, a }, or a \right)
|
@@ -12166,6 +12242,9 @@ class Parser {
|
|
12166
12242
|
if (breakOnTokenText && lex.text === breakOnTokenText) {
|
12167
12243
|
break;
|
12168
12244
|
}
|
12245
|
+
if (breakOnMiddle && lex.text === "\\middle") {
|
12246
|
+
break
|
12247
|
+
}
|
12169
12248
|
if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
|
12170
12249
|
break;
|
12171
12250
|
}
|
@@ -13144,7 +13223,7 @@ class Style {
|
|
13144
13223
|
* https://mit-license.org/
|
13145
13224
|
*/
|
13146
13225
|
|
13147
|
-
const version = "0.10.
|
13226
|
+
const version = "0.10.23";
|
13148
13227
|
|
13149
13228
|
function postProcess(block) {
|
13150
13229
|
const labelMap = {};
|