temml 0.11.7 → 0.11.8

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.
@@ -114,12 +114,17 @@ defineFunction({
114
114
  "\\xlongequal",
115
115
  "\\xtwoheadrightarrow",
116
116
  "\\xtwoheadleftarrow",
117
- // The next 5 functions are here only to support mhchem
117
+ "\\xtofrom", // expfeil
118
+ "\\xleftrightharpoons", // mathtools
119
+ "\\xrightleftharpoons", // mathtools
120
+ // The next 7 functions are here only to support mhchem
118
121
  "\\yields",
119
122
  "\\yieldsLeft",
120
123
  "\\mesomerism",
121
124
  "\\longrightharpoonup",
122
125
  "\\longleftharpoondown",
126
+ "\\yieldsLeftRight",
127
+ "\\chemequilibrium",
123
128
  // The next 3 functions are here only to support the {CD} environment.
124
129
  "\\\\cdrightarrow",
125
130
  "\\\\cdleftarrow",
@@ -150,26 +155,15 @@ defineFunction({
150
155
  });
151
156
 
152
157
  const arrowComponent = {
153
- "\\xtofrom": ["\\xrightarrow", "\\xleftarrow"],
154
- "\\xleftrightharpoons": ["\\xleftharpoonup", "\\xrightharpoondown"],
155
- "\\xrightleftharpoons": ["\\xrightharpoonup", "\\xleftharpoondown"],
156
- "\\yieldsLeftRight": ["\\yields", "\\yieldsLeft"],
157
- // The next three all get the same harpoon glyphs. Only the lengths and paddings differ.
158
- "\\equilibrium": ["\\longrightharpoonup", "\\longleftharpoondown"],
159
158
  "\\equilibriumRight": ["\\longrightharpoonup", "\\eqleftharpoondown"],
160
159
  "\\equilibriumLeft": ["\\eqrightharpoonup", "\\longleftharpoondown"]
161
160
  }
162
161
 
163
- // Browsers are not good at stretching a glyph that contains a pair of stacked arrows such as ⇄.
164
- // So we stack a pair of single arrows.
162
+ // Math fonts do not have a single glyph for these two mhchem functions.
163
+ // So we stack a pair of single harpoons.
165
164
  defineFunction({
166
165
  type: "stackedArrow",
167
166
  names: [
168
- "\\xtofrom", // expfeil
169
- "\\xleftrightharpoons", // mathtools
170
- "\\xrightleftharpoons", // mathtools
171
- "\\yieldsLeftRight", // mhchem
172
- "\\equilibrium", // mhchem
173
167
  "\\equilibriumRight",
174
168
  "\\equilibriumLeft"
175
169
  ],
@@ -71,7 +71,8 @@ const mathmlBuilder = (group, style) => {
71
71
  case "\\boxed":
72
72
  // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
73
73
  node.setAttribute("notation", "box")
74
- node.classes.push("tml-box")
74
+ node.style.padding = "padding: 3pt 0 3pt 0"
75
+ node.style.border = "1px solid"
75
76
  node.setAttribute("scriptlevel", "0")
76
77
  node.setAttribute("displaystyle", "true")
77
78
  break
@@ -145,7 +145,9 @@ export const binrelClass = (arg) => {
145
145
  // (by rendering separately and with {}s before and after, and measuring
146
146
  // the change in spacing). We'll do roughly the same by detecting the
147
147
  // atom type directly.
148
- const atom = arg.type === "ordgroup" && arg.body.length ? arg.body[0] : arg;
148
+ const atom = arg.type === "ordgroup" && arg.body.length && arg.body.length === 1
149
+ ? arg.body[0]
150
+ : arg;
149
151
  if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) {
150
152
  return "m" + atom.family;
151
153
  } else {
@@ -183,14 +185,25 @@ defineFunction({
183
185
  const baseArg = args[1];
184
186
  const shiftedArg = args[0];
185
187
 
188
+ let mclass
189
+ if (funcName !== "\\stackrel") {
190
+ // LaTeX applies \binrel spacing to \overset and \underset.
191
+ mclass = binrelClass(baseArg)
192
+ } else {
193
+ mclass = "mrel" // for \stackrel
194
+ }
195
+
196
+ const baseType = mclass === "mrel" || mclass === "mbin"
197
+ ? "op"
198
+ : "ordgroup"
199
+
186
200
  const baseOp = {
187
- type: "op",
201
+ type: baseType,
188
202
  mode: baseArg.mode,
189
203
  limits: true,
190
204
  alwaysHandleSupSub: true,
191
205
  parentIsSupSub: false,
192
206
  symbol: false,
193
- stack: true,
194
207
  suppressBaseShift: funcName !== "\\stackrel",
195
208
  body: ordargument(baseArg)
196
209
  };
@@ -198,6 +211,7 @@ defineFunction({
198
211
  return {
199
212
  type: "supsub",
200
213
  mode: shiftedArg.mode,
214
+ stack: true,
201
215
  base: baseOp,
202
216
  sup: funcName === "\\underset" ? null : shiftedArg,
203
217
  sub: funcName === "\\underset" ? shiftedArg : null
@@ -0,0 +1,68 @@
1
+ import defineFunction from "../defineFunction";
2
+ import mathMLTree from "../mathMLTree";
3
+ import ParseError from "../ParseError"
4
+
5
+ const numRegEx = /^[0-9]$/
6
+ const unicodeNumSubs = {
7
+ '0': '₀',
8
+ '1': '₁',
9
+ '2': '₂',
10
+ '3': '₃',
11
+ '4': '₄',
12
+ '5': '₅',
13
+ '6': '₆',
14
+ '7': '₇',
15
+ '8': '₈',
16
+ '9': '₉'
17
+ }
18
+ const unicodeNumSups = {
19
+ '0': '⁰',
20
+ '1': '¹',
21
+ '2': '²',
22
+ '3': '³',
23
+ '4': '⁴',
24
+ '5': '⁵',
25
+ '6': '⁶',
26
+ '7': '⁷',
27
+ '8': '⁸',
28
+ '9': '⁹'
29
+ }
30
+
31
+ defineFunction({
32
+ type: "sfrac",
33
+ names: ["\\sfrac"],
34
+ props: {
35
+ numArgs: 2,
36
+ allowedInText: true,
37
+ allowedInMath: true
38
+ },
39
+ handler({ parser }, args) {
40
+ let numerator = ""
41
+ for (const node of args[0].body) {
42
+ if (node.type !== "textord" || !numRegEx.test(node.text)) {
43
+ throw new ParseError("Numerator must be an integer.", node)
44
+ }
45
+ numerator += node.text
46
+ }
47
+ let denominator = ""
48
+ for (const node of args[1].body) {
49
+ if (node.type !== "textord" || !numRegEx.test(node.text)) {
50
+ throw new ParseError("Denominator must be an integer.", node)
51
+ }
52
+ denominator += node.text
53
+ }
54
+ return {
55
+ type: "sfrac",
56
+ mode: parser.mode,
57
+ numerator,
58
+ denominator
59
+ };
60
+ },
61
+ mathmlBuilder(group, style) {
62
+ const numerator = group.numerator.split('').map(c => unicodeNumSups[c]).join('')
63
+ const denominator = group.denominator.split('').map(c => unicodeNumSubs[c]).join('')
64
+ // Use a fraction slash.
65
+ const text = new mathMLTree.TextNode(numerator + "\u2044" + denominator, group.mode, style)
66
+ return new mathMLTree.MathNode("mn", [text], ["special-fraction"])
67
+ }
68
+ });
@@ -14,6 +14,11 @@ import * as mml from "../buildMathML"
14
14
  // Helpers
15
15
  const symbolRegEx = /^m(over|under|underover)$/
16
16
 
17
+ // From the KaTeX font metrics, identify letters that encroach on a superscript.
18
+ const smallPad = "DHKLUcegorsuvxyzΠΥΨαδηιμνοτυχϵ"
19
+ const mediumPad = "BCEFGIMNOPQRSTXZlpqtwΓΘΞΣΦΩβεζθξρςφψϑϕϱ"
20
+ const largePad = "AJdfΔΛ"
21
+
17
22
  // Super scripts and subscripts, whose precise placement can depend on other
18
23
  // functions that precede them.
19
24
  defineFunctionBuilders({
@@ -35,7 +40,7 @@ defineFunctionBuilders({
35
40
  }
36
41
  }
37
42
 
38
- if (group.base && !group.base.stack &&
43
+ if (group.base && !group.stack &&
39
44
  (group.base.type === "op" || group.base.type === "operatorname")) {
40
45
  group.base.parentIsSupSub = true
41
46
  appendApplyFunction = !group.base.symbol
@@ -43,7 +48,7 @@ defineFunctionBuilders({
43
48
  needsLeadingSpace = group.base.needsLeadingSpace
44
49
  }
45
50
 
46
- const children = group.base && group.base.stack
51
+ const children = group.stack && group.base.body.length === 1
47
52
  ? [mml.buildGroup(group.base.body[0], style)]
48
53
  : [mml.buildGroup(group.base, style)];
49
54
 
@@ -63,11 +68,16 @@ defineFunctionBuilders({
63
68
  if (group.sup) {
64
69
  const sup = mml.buildGroup(group.sup, childStyle)
65
70
  if (style.level === 3) { sup.setAttribute("scriptlevel", "2") }
66
- const testNode = sup.type === "mrow" ? sup.children[0] : sup
67
- if ((testNode && testNode.type === "mo" && testNode.classes.includes("tml-prime"))
68
- && group.base && group.base.text && "fF".indexOf(group.base.text) > -1) {
69
- // Chromium does not address italic correction on prime. Prevent f′ from overlapping.
70
- testNode.classes.push("prime-pad")
71
+ if (group.base && group.base.text && group.base.text.length === 1) {
72
+ // Make an italic correction on the superscript.
73
+ const text = group.base.text
74
+ if (smallPad.indexOf(text) > -1) {
75
+ sup.classes.push("tml-sml-pad")
76
+ } else if (mediumPad.indexOf(text) > -1) {
77
+ sup.classes.push("tml-med-pad")
78
+ } else if (largePad.indexOf(text) > -1) {
79
+ sup.classes.push("tml-lrg-pad")
80
+ }
71
81
  }
72
82
  children.push(sup)
73
83
  }
@@ -96,7 +106,9 @@ defineFunctionBuilders({
96
106
  }
97
107
  } else if (!group.sup) {
98
108
  const base = group.base;
99
- if (
109
+ if (group.stack) {
110
+ nodeType = "munder";
111
+ } else if (
100
112
  base &&
101
113
  base.type === "op" &&
102
114
  base.limits &&
package/src/functions.js CHANGED
@@ -44,6 +44,7 @@ import "./functions/ref";
44
44
  import "./functions/reflect";
45
45
  import "./functions/relax";
46
46
  import "./functions/rule";
47
+ import "./functions/sfrac";
47
48
  import "./functions/sizing";
48
49
  import "./functions/smash";
49
50
  import "./functions/sqrt";
@@ -5,7 +5,7 @@
5
5
  * https://mit-license.org/
6
6
  */
7
7
 
8
- export const version = "0.11.07";
8
+ export const version = "0.11.08";
9
9
 
10
10
  export function postProcess(block) {
11
11
  const labelMap = {}
package/src/stretchy.js CHANGED
@@ -72,6 +72,9 @@ const stretchyCodePoint = {
72
72
  xtwoheadrightarrow: "\u21a0",
73
73
  xlongequal: "=",
74
74
  xrightleftarrows: "\u21c4",
75
+ xtofrom: "\u21c4",
76
+ xleftrightharpoons: "\u21cb",
77
+ xrightleftharpoons: "\u21cc",
75
78
  yields: "\u2192",
76
79
  yieldsLeft: "\u2190",
77
80
  mesomerism: "\u2194",
@@ -81,7 +84,9 @@ const stretchyCodePoint = {
81
84
  eqleftharpoondown: "\u21bd",
82
85
  "\\cdrightarrow": "\u2192",
83
86
  "\\cdleftarrow": "\u2190",
84
- "\\cdlongequal": "="
87
+ "\\cdlongequal": "=",
88
+ yieldsLeftRight: "\u21c4",
89
+ chemequilibrium: "\u21cc"
85
90
  }
86
91
 
87
92
  const mathMLnode = function(label) {
package/src/symbols.js CHANGED
@@ -894,7 +894,7 @@ defineSymbol(math, inner, "\u22ef", "\\@cdots", true);
894
894
  defineSymbol(math, inner, "\u22f1", "\\ddots", true);
895
895
  defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
896
896
  defineSymbol(text, textord, "\u22ee", "\\varvdots");
897
- defineSymbol(math, accent, "\u02ca", "\\acute");
897
+ defineSymbol(math, accent, "\u00b4", "\\acute");
898
898
  defineSymbol(math, accent, "\u0060", "\\grave");
899
899
  defineSymbol(math, accent, "\u00a8", "\\ddot");
900
900
  defineSymbol(math, accent, "\u2026", "\\dddot");
@@ -920,7 +920,7 @@ defineSymbol(math, mathord, "\u00d8", "\\O", true);
920
920
  defineSymbol(text, accent, "\u02ca", "\\'"); // acute
921
921
  defineSymbol(text, accent, "\u02cb", "\\`"); // grave
922
922
  defineSymbol(text, accent, "\u02c6", "\\^"); // circumflex
923
- defineSymbol(text, accent, "\u02dc", "\\~"); // tilde
923
+ defineSymbol(text, accent, "\u007e", "\\~"); // tilde
924
924
  defineSymbol(text, accent, "\u02c9", "\\="); // macron
925
925
  defineSymbol(text, accent, "\u02d8", "\\u"); // breve
926
926
  defineSymbol(text, accent, "\u02d9", "\\."); // dot above
@@ -932,7 +932,7 @@ defineSymbol(text, accent, "\u02dd", "\\H"); // double acute
932
932
  defineSymbol(math, accent, "\u02ca", "\\'"); // acute
933
933
  defineSymbol(math, accent, "\u02cb", "\\`"); // grave
934
934
  defineSymbol(math, accent, "\u02c6", "\\^"); // circumflex
935
- defineSymbol(math, accent, "\u02dc", "\\~"); // tilde
935
+ defineSymbol(math, accent, "\u007e", "\\~"); // tilde
936
936
  defineSymbol(math, accent, "\u02c9", "\\="); // macron
937
937
  defineSymbol(math, accent, "\u02d8", "\\u"); // breve
938
938
  defineSymbol(math, accent, "\u02d9", "\\."); // dot above