temml 0.10.32 → 0.10.33

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  | Library | Minified JavaScript + CSS |
4
4
  |:--------------|:-------------------------:|
5
- | Temml | 158 KB |
5
+ | Temml | 160 KB |
6
6
  | MathJax 2.7.5 | 338 KB |
7
7
  | KaTeX | 280 KB |
8
8
  | TeXZilla | 168 KB |
package/dist/temml.cjs CHANGED
@@ -501,6 +501,40 @@ let TextNode$1 = class TextNode {
501
501
  }
502
502
  };
503
503
 
504
+ // Create an <a href="…"> node.
505
+ class AnchorNode {
506
+ constructor(href, classes, children) {
507
+ this.href = href;
508
+ this.classes = classes;
509
+ this.children = children || [];
510
+ }
511
+
512
+ toNode() {
513
+ const node = document.createElement("a");
514
+ node.setAttribute("href", this.href);
515
+ if (this.classes.length > 0) {
516
+ node.className = createClass(this.classes);
517
+ }
518
+ for (let i = 0; i < this.children.length; i++) {
519
+ node.appendChild(this.children[i].toNode());
520
+ }
521
+ return node
522
+ }
523
+
524
+ toMarkup() {
525
+ let markup = `<a href='${utils.escape(this.href)}'`;
526
+ if (this.classes.length > 0) {
527
+ markup += ` class="${utils.escape(createClass(this.classes))}"`;
528
+ }
529
+ markup += ">";
530
+ for (let i = 0; i < this.children.length; i++) {
531
+ markup += this.children[i].toMarkup();
532
+ }
533
+ markup += "</a>";
534
+ return markup
535
+ }
536
+ }
537
+
504
538
  /*
505
539
  * This node represents an image embed (<img>) element.
506
540
  */
@@ -1530,7 +1564,7 @@ defineSymbol(math, open, "\u27e8", "\\langle", true);
1530
1564
  defineSymbol(math, open, "\u27ea", "\\lAngle", true);
1531
1565
  defineSymbol(math, open, "\u2989", "\\llangle", true);
1532
1566
  defineSymbol(math, open, "|", "\\lvert");
1533
- defineSymbol(math, open, "\u2016", "\\lVert");
1567
+ defineSymbol(math, open, "\u2016", "\\lVert", true);
1534
1568
  defineSymbol(math, textord, "!", "\\oc"); // cmll package
1535
1569
  defineSymbol(math, textord, "?", "\\wn");
1536
1570
  defineSymbol(math, textord, "\u2193", "\\shpos");
@@ -1694,7 +1728,7 @@ defineSymbol(math, inner, "\u22f0", "\\iddots", true);
1694
1728
  defineSymbol(math, inner, "\u22ef", "\\@cdots", true);
1695
1729
  defineSymbol(math, inner, "\u22f1", "\\ddots", true);
1696
1730
  defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
1697
- defineSymbol(text, textord, "\u22ee", "\\textvdots");
1731
+ defineSymbol(text, textord, "\u22ee", "\\varvdots");
1698
1732
  defineSymbol(math, accent, "\u02ca", "\\acute");
1699
1733
  defineSymbol(math, accent, "\u0060", "\\grave");
1700
1734
  defineSymbol(math, accent, "\u00a8", "\\ddot");
@@ -2147,61 +2181,6 @@ const consolidateText = mrow => {
2147
2181
  }
2148
2182
  };
2149
2183
 
2150
- const numberRegEx$1 = /^[0-9]$/;
2151
- const isDotOrComma = (node, followingNode) => {
2152
- return ((node.type === "textord" && node.text === ".") ||
2153
- (node.type === "atom" && node.text === ",")) &&
2154
- // Don't consolidate if there is a space after the comma.
2155
- node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
2156
- };
2157
- const consolidateNumbers = expression => {
2158
- // Consolidate adjacent numbers. We want to return <mn>1,506.3</mn>,
2159
- // not <mn>1</mn><mo>,</mo><mn>5</mn><mn>0</mn><mn>6</mn><mi>.</mi><mn>3</mn>
2160
- if (expression.length < 2) { return }
2161
- const nums = [];
2162
- let inNum = false;
2163
- // Find adjacent numerals
2164
- for (let i = 0; i < expression.length; i++) {
2165
- const node = expression[i];
2166
- if (node.type === "textord" && numberRegEx$1.test(node.text)) {
2167
- if (!inNum) { nums.push({ start: i }); }
2168
- inNum = true;
2169
- } else {
2170
- if (inNum) { nums[nums.length - 1].end = i - 1; }
2171
- inNum = false;
2172
- }
2173
- }
2174
- if (inNum) { nums[nums.length - 1].end = expression.length - 1; }
2175
-
2176
- // Determine if numeral groups are separated by a comma or dot.
2177
- for (let i = nums.length - 1; i > 0; i--) {
2178
- if (nums[i - 1].end === nums[i].start - 2 &&
2179
- isDotOrComma(expression[nums[i].start - 1], expression[nums[i].start])) {
2180
- // Merge the two groups.
2181
- nums[i - 1].end = nums[i].end;
2182
- nums.splice(i, 1);
2183
- }
2184
- }
2185
-
2186
- // Consolidate the number nodes
2187
- for (let i = nums.length - 1; i >= 0; i--) {
2188
- for (let j = nums[i].start + 1; j <= nums[i].end; j++) {
2189
- expression[nums[i].start].text += expression[j].text;
2190
- }
2191
- expression.splice(nums[i].start + 1, nums[i].end - nums[i].start);
2192
- // Check if the <mn> is followed by a numeric base in a supsub, e.g. the "3" in 123^4
2193
- // If so, merge the first <mn> into the base.
2194
- if (expression.length > nums[i].start + 1) {
2195
- const nextTerm = expression[nums[i].start + 1];
2196
- if (nextTerm.type === "supsub" && nextTerm.base && nextTerm.base.type === "textord" &&
2197
- numberRegEx$1.test(nextTerm.base.text)) {
2198
- nextTerm.base.text = expression[nums[i].start].text + nextTerm.base.text;
2199
- expression.splice(nums[i].start, 1);
2200
- }
2201
- }
2202
- }
2203
- };
2204
-
2205
2184
  /**
2206
2185
  * Wrap the given array of nodes in an <mrow> node if needed, i.e.,
2207
2186
  * unless the array has length 1. Always returns a single node.
@@ -2224,6 +2203,39 @@ const makeRow = function(body, semisimple = false) {
2224
2203
  return new mathMLTree.MathNode("mrow", body);
2225
2204
  };
2226
2205
 
2206
+ /**
2207
+ * Check for <mi>.</mi> which is how a dot renders in MathML,
2208
+ * or <mo separator="true" lspace="0em" rspace="0em">,</mo>
2209
+ * which is how a braced comma {,} renders in MathML
2210
+ */
2211
+ function isNumberPunctuation(group) {
2212
+ if (!group) {
2213
+ return false
2214
+ }
2215
+ if (group.type === 'mi' && group.children.length === 1) {
2216
+ const child = group.children[0];
2217
+ return child instanceof TextNode && child.text === '.'
2218
+ } else if (group.type === "mtext" && group.children.length === 1) {
2219
+ const child = group.children[0];
2220
+ return child instanceof TextNode && child.text === '\u2008' // punctuation space
2221
+ } else if (group.type === 'mo' && group.children.length === 1 &&
2222
+ group.getAttribute('separator') === 'true' &&
2223
+ group.getAttribute('lspace') === '0em' &&
2224
+ group.getAttribute('rspace') === '0em') {
2225
+ const child = group.children[0];
2226
+ return child instanceof TextNode && child.text === ','
2227
+ } else {
2228
+ return false
2229
+ }
2230
+ }
2231
+ const isComma = (expression, i) => {
2232
+ const node = expression[i];
2233
+ const followingNode = expression[i + 1];
2234
+ return (node.type === "atom" && node.text === ",") &&
2235
+ // Don't consolidate if there is a space after the comma.
2236
+ node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
2237
+ };
2238
+
2227
2239
  const isRel = item => {
2228
2240
  return (item.type === "atom" && item.family === "rel") ||
2229
2241
  (item.type === "mclass" && item.mclass === "mrel")
@@ -2247,11 +2259,16 @@ const buildExpression = function(expression, style, semisimple = false) {
2247
2259
  return [group];
2248
2260
  }
2249
2261
 
2250
- consolidateNumbers(expression);
2251
-
2252
2262
  const groups = [];
2263
+ const groupArray = [];
2264
+ let lastGroup;
2253
2265
  for (let i = 0; i < expression.length; i++) {
2254
- const group = buildGroup$1(expression[i], style);
2266
+ groupArray.push(buildGroup$1(expression[i], style));
2267
+ }
2268
+
2269
+ for (let i = 0; i < groupArray.length; i++) {
2270
+ const group = groupArray[i];
2271
+
2255
2272
  // Suppress spacing between adjacent relations
2256
2273
  if (i < expression.length - 1 && isRel(expression[i]) && isRel(expression[i + 1])) {
2257
2274
  group.setAttribute("rspace", "0em");
@@ -2259,9 +2276,39 @@ const buildExpression = function(expression, style, semisimple = false) {
2259
2276
  if (i > 0 && isRel(expression[i]) && isRel(expression[i - 1])) {
2260
2277
  group.setAttribute("lspace", "0em");
2261
2278
  }
2279
+
2280
+ // Concatenate numbers
2281
+ if (group.type === 'mn' && lastGroup && lastGroup.type === 'mn') {
2282
+ // Concatenate <mn>...</mn> followed by <mi>.</mi>
2283
+ lastGroup.children.push(...group.children);
2284
+ continue
2285
+ } else if (isNumberPunctuation(group) && lastGroup && lastGroup.type === 'mn') {
2286
+ // Concatenate <mn>...</mn> followed by <mi>.</mi>
2287
+ lastGroup.children.push(...group.children);
2288
+ continue
2289
+ } else if (lastGroup && lastGroup.type === "mn" && i < groupArray.length - 1 &&
2290
+ groupArray[i + 1].type === "mn" && isComma(expression, i)) {
2291
+ lastGroup.children.push(...group.children);
2292
+ continue
2293
+ } else if (group.type === 'mn' && isNumberPunctuation(lastGroup)) {
2294
+ // Concatenate <mi>.</mi> followed by <mn>...</mn>
2295
+ group.children = [...lastGroup.children, ...group.children];
2296
+ groups.pop();
2297
+ } else if ((group.type === 'msup' || group.type === 'msub') &&
2298
+ group.children.length >= 1 && lastGroup &&
2299
+ (lastGroup.type === 'mn' || isNumberPunctuation(lastGroup))) {
2300
+ // Put preceding <mn>...</mn> or <mi>.</mi> inside base of
2301
+ // <msup><mn>...base...</mn>...exponent...</msup> (or <msub>)
2302
+ const base = group.children[0];
2303
+ if (base instanceof MathNode && base.type === 'mn' && lastGroup) {
2304
+ base.children = [...lastGroup.children, ...base.children];
2305
+ groups.pop();
2306
+ }
2307
+ }
2262
2308
  groups.push(group);
2309
+ lastGroup = group;
2263
2310
  }
2264
- return groups;
2311
+ return groups
2265
2312
  };
2266
2313
 
2267
2314
  /**
@@ -2323,6 +2370,11 @@ function buildMathML(tree, texExpression, style, settings) {
2323
2370
  }
2324
2371
 
2325
2372
  const expression = buildExpression(tree, style);
2373
+
2374
+ if (expression.length === 1 && expression[0] instanceof AnchorNode) {
2375
+ return expression[0]
2376
+ }
2377
+
2326
2378
  const wrap = (settings.displayMode || settings.annotate) ? "none" : settings.wrap;
2327
2379
 
2328
2380
  const n1 = expression.length === 0 ? null : expression[0];
@@ -2347,6 +2399,9 @@ function buildMathML(tree, texExpression, style, settings) {
2347
2399
  if (settings.xml) {
2348
2400
  math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
2349
2401
  }
2402
+ if (wrapper.style.width) {
2403
+ math.style.width = "100%";
2404
+ }
2350
2405
  if (settings.displayMode) {
2351
2406
  math.setAttribute("display", "block");
2352
2407
  math.style.display = "block math"; // necessary in Chromium.
@@ -2678,12 +2733,19 @@ const padding$2 = width => {
2678
2733
  return node
2679
2734
  };
2680
2735
 
2681
- const paddedNode = (group, lspace = 0.3, rspace = 0) => {
2736
+ const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
2682
2737
  if (group == null && rspace === 0) { return padding$2(lspace) }
2683
2738
  const row = group ? [group] : [];
2684
2739
  if (lspace !== 0) { row.unshift(padding$2(lspace)); }
2685
2740
  if (rspace > 0) { row.push(padding$2(rspace)); }
2686
- return new mathMLTree.MathNode("mrow", row)
2741
+ if (mustSmash) {
2742
+ // Used for the bottom arrow in a {CD} environment
2743
+ const mpadded = new mathMLTree.MathNode("mpadded", row);
2744
+ mpadded.setAttribute("height", "0");
2745
+ return mpadded
2746
+ } else {
2747
+ return new mathMLTree.MathNode("mrow", row)
2748
+ }
2687
2749
  };
2688
2750
 
2689
2751
  const labelSize = (size, scriptLevel) => Number(size) / emScale(scriptLevel);
@@ -2723,7 +2785,8 @@ const munderoverNode = (fName, body, below, style) => {
2723
2785
  (body.body.body || body.body.length > 0));
2724
2786
  if (gotUpper) {
2725
2787
  let label = buildGroup$1(body, labelStyle);
2726
- label = paddedNode(label, space, space);
2788
+ const mustSmash = (fName === "\\\\cdrightarrow" || fName === "\\\\cdleftarrow");
2789
+ label = paddedNode(label, space, space, mustSmash);
2727
2790
  // Since Firefox does not support minsize, stack a invisible node
2728
2791
  // on top of the label. Its width will serve as a min-width.
2729
2792
  // TODO: Refactor this after Firefox supports minsize.
@@ -3146,18 +3209,23 @@ defineFunction({
3146
3209
  };
3147
3210
  },
3148
3211
  mathmlBuilder(group, style) {
3149
- let label = new mathMLTree.MathNode("mrow", [buildGroup$1(group.label, style)]);
3150
- label = new mathMLTree.MathNode("mpadded", [label]);
3151
- label.setAttribute("width", "0");
3152
- if (group.side === "left") {
3153
- label.setAttribute("lspace", "-1width");
3212
+ if (group.label.body.length === 0) {
3213
+ return new mathMLTree.MathNode("mrow", style) // empty label
3154
3214
  }
3155
- // We have to guess at vertical alignment. We know the arrow is 1.8em tall,
3156
- // But we don't know the height or depth of the label.
3157
- label.setAttribute("voffset", "0.7em");
3158
- label = new mathMLTree.MathNode("mstyle", [label]);
3215
+ // Abuse an <mtable> to create vertically centered content.
3216
+ const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.label, style)]);
3217
+ mtd.style.padding = "0";
3218
+ const mtr = new mathMLTree.MathNode("mtr", [mtd]);
3219
+ const mtable = new mathMLTree.MathNode("mtable", [mtr]);
3220
+ const label = new mathMLTree.MathNode("mpadded", [mtable]);
3221
+ // Set the label width to zero so that the arrow will be centered under the corner cell.
3222
+ label.setAttribute("width", "0");
3159
3223
  label.setAttribute("displaystyle", "false");
3160
3224
  label.setAttribute("scriptlevel", "1");
3225
+ if (group.side === "left") {
3226
+ label.style.display = "flex";
3227
+ label.style.justifyContent = "flex-end";
3228
+ }
3161
3229
  return label;
3162
3230
  }
3163
3231
  });
@@ -3747,10 +3815,13 @@ defineFunction({
3747
3815
  // replacement text, enclosed in '{' and '}' and properly nested
3748
3816
  const { tokens } = parser.gullet.consumeArg();
3749
3817
 
3750
- parser.gullet.macros.set(
3751
- name,
3752
- { tokens, numArgs }
3753
- );
3818
+ if (!(funcName === "\\providecommand" && parser.gullet.macros.has(name))) {
3819
+ // Ignore \providecommand
3820
+ parser.gullet.macros.set(
3821
+ name,
3822
+ { tokens, numArgs }
3823
+ );
3824
+ }
3754
3825
 
3755
3826
  return { type: "internal", mode: parser.mode };
3756
3827
 
@@ -3844,6 +3915,7 @@ const delimiters = [
3844
3915
  "\\vert",
3845
3916
  "\\|",
3846
3917
  "\\Vert",
3918
+ "\u2016",
3847
3919
  "\\uparrow",
3848
3920
  "\\Uparrow",
3849
3921
  "\\downarrow",
@@ -4613,7 +4685,7 @@ defineMacro("\\underbar", "\\underline{\\text{#1}}");
4613
4685
  // \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
4614
4686
  // We'll call \varvdots, which gets a glyph from symbols.js.
4615
4687
  // The zero-width rule gets us an equivalent to the vertical 6pt kern.
4616
- defineMacro("\\vdots", "\\TextOrMath{\\textvdots}{{\\varvdots\\rule{0pt}{15pt}}}\\relax");
4688
+ defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}");
4617
4689
  defineMacro("\u22ee", "\\vdots");
4618
4690
 
4619
4691
  // {array} environment gaps
@@ -8076,6 +8148,7 @@ defineFunction({
8076
8148
  "\\mathfrak",
8077
8149
  "\\mathscr",
8078
8150
  "\\mathsf",
8151
+ "\\mathsfit",
8079
8152
  "\\mathtt",
8080
8153
 
8081
8154
  // aliases
@@ -8145,10 +8218,19 @@ const mathmlBuilder$5 = (group, style) => {
8145
8218
  ? style.withLevel(StyleLevel.SCRIPT)
8146
8219
  : style.withLevel(StyleLevel.SCRIPTSCRIPT);
8147
8220
 
8148
- let node = new mathMLTree.MathNode("mfrac", [
8149
- buildGroup$1(group.numer, childOptions),
8150
- buildGroup$1(group.denom, childOptions)
8151
- ]);
8221
+ // Chromium (wrongly) continues to shrink fractions beyond scriptscriptlevel.
8222
+ // So we check for levels that Chromium shrinks too small.
8223
+ // If necessary, set an explicit fraction depth.
8224
+ const numer = buildGroup$1(group.numer, childOptions);
8225
+ const denom = buildGroup$1(group.denom, childOptions);
8226
+ if (style.level === 3) {
8227
+ numer.style.mathDepth = "2";
8228
+ numer.setAttribute("scriptlevel", "2");
8229
+ denom.style.mathDepth = "2";
8230
+ denom.setAttribute("scriptlevel", "2");
8231
+ }
8232
+
8233
+ let node = new mathMLTree.MathNode("mfrac", [numer, denom]);
8152
8234
 
8153
8235
  if (!group.hasBarLine) {
8154
8236
  node.setAttribute("linethickness", "0px");
@@ -8541,12 +8623,9 @@ defineFunction({
8541
8623
  };
8542
8624
  },
8543
8625
  mathmlBuilder: (group, style) => {
8544
- let math = buildExpressionRow(group.body, style);
8545
- if (!(math instanceof MathNode)) {
8546
- math = new MathNode("mrow", [math]);
8547
- }
8548
- math.setAttribute("href", group.href);
8549
- return math;
8626
+ const math = new MathNode("math", [buildExpressionRow(group.body, style)]);
8627
+ const anchorNode = new AnchorNode(group.href, [], [math]);
8628
+ return anchorNode
8550
8629
  }
8551
8630
  });
8552
8631
 
@@ -9418,13 +9497,6 @@ const mathmlBuilder$2 = (group, style) => {
9418
9497
  node = new MathNode("mo", [makeText(group.name, group.mode)]);
9419
9498
  if (noSuccessor.includes(group.name)) {
9420
9499
  node.setAttribute("largeop", "false");
9421
- } else if (group.limits) {
9422
- // This is a workaround for a MathML/Chromium bug.
9423
- // This is being applied to singleCharBigOps, which are not really stretchy.
9424
- // But by setting the stretchy attribute, Chromium will vertically center
9425
- // big ops around the math axis. This is needed since STIX TWO does not do so.
9426
- // TODO: Remove this hack when MathML & Chromium fix their problem.
9427
- node.setAttribute("stretchy", "true");
9428
9500
  } else {
9429
9501
  node.setAttribute("movablelimits", "false");
9430
9502
  }
@@ -10059,12 +10131,10 @@ defineFunction({
10059
10131
  };
10060
10132
  },
10061
10133
  mathmlBuilder(group, style) {
10062
- // Create an empty text node. Set a class and an href.
10134
+ // Create an empty <a> node. Set a class and an href attribute.
10063
10135
  // The post-processor will populate with the target's tag or equation number.
10064
10136
  const classes = group.funcName === "\\ref" ? ["tml-ref"] : ["tml-ref", "tml-eqref"];
10065
- const node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("")], classes);
10066
- node.setAttribute("href", "#" + group.string);
10067
- return node
10137
+ return new AnchorNode("#" + group.string, classes, null)
10068
10138
  }
10069
10139
  });
10070
10140
 
@@ -10111,6 +10181,8 @@ defineFunction({
10111
10181
  props: {
10112
10182
  numArgs: 2,
10113
10183
  numOptionalArgs: 1,
10184
+ allowedInText: true,
10185
+ allowedInMath: true,
10114
10186
  argTypes: ["size", "size", "size"]
10115
10187
  },
10116
10188
  handler({ parser }, args, optArgs) {
@@ -10403,16 +10475,25 @@ defineFunctionBuilders({
10403
10475
  ? [buildGroup$1(group.base.body[0], style)]
10404
10476
  : [buildGroup$1(group.base, style)];
10405
10477
 
10478
+ // Note regarding scriptstyle level.
10479
+ // (Sub|super)scripts should not shrink beyond MathML scriptlevel 2 aka \scriptscriptstyle
10480
+ // Ref: https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes
10481
+ // (BTW, MathML scriptlevel 2 is equal to Temml level 3.)
10482
+ // But Chromium continues to shrink the (sub|super)scripts. So we explicitly set scriptlevel 2.
10483
+
10406
10484
  const childStyle = style.inSubOrSup();
10407
10485
  if (group.sub) {
10408
- children.push(buildGroup$1(group.sub, childStyle));
10486
+ const sub = buildGroup$1(group.sub, childStyle);
10487
+ if (style.level === 3) { sub.setAttribute("scriptlevel", "2"); }
10488
+ children.push(sub);
10409
10489
  }
10410
10490
 
10411
10491
  if (group.sup) {
10412
10492
  const sup = buildGroup$1(group.sup, childStyle);
10493
+ if (style.level === 3) { sup.setAttribute("scriptlevel", "2"); }
10413
10494
  const testNode = sup.type === "mrow" ? sup.children[0] : sup;
10414
10495
  if ((testNode && testNode.type === "mo" && testNode.classes.includes("tml-prime"))
10415
- && group.base && group.base.text && group.base.text === "f") {
10496
+ && group.base && group.base.text && "fF".indexOf(group.base.text) > -1) {
10416
10497
  // Chromium does not address italic correction on prime. Prevent f′ from overlapping.
10417
10498
  testNode.classes.push("prime-pad");
10418
10499
  }
@@ -10639,6 +10720,8 @@ const getVariant = function(group, style) {
10639
10720
  return "script"
10640
10721
  case "mathsf":
10641
10722
  return "sans-serif"
10723
+ case "mathsfit":
10724
+ return "sans-serif-italic"
10642
10725
  case "mathtt":
10643
10726
  return "monospace"
10644
10727
  }
@@ -11103,6 +11186,32 @@ defineFunction({
11103
11186
  }
11104
11187
  });
11105
11188
 
11189
+ // \vcenter: Vertically center the argument group on the math axis.
11190
+
11191
+ defineFunction({
11192
+ type: "vcenter",
11193
+ names: ["\\vcenter"],
11194
+ props: {
11195
+ numArgs: 1,
11196
+ argTypes: ["original"],
11197
+ allowedInText: false
11198
+ },
11199
+ handler({ parser }, args) {
11200
+ return {
11201
+ type: "vcenter",
11202
+ mode: parser.mode,
11203
+ body: args[0]
11204
+ };
11205
+ },
11206
+ mathmlBuilder(group, style) {
11207
+ // Use a math table to create vertically centered content.
11208
+ const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.body, style)]);
11209
+ mtd.style.padding = "0";
11210
+ const mtr = new mathMLTree.MathNode("mtr", [mtd]);
11211
+ return new mathMLTree.MathNode("mtable", [mtr])
11212
+ }
11213
+ });
11214
+
11106
11215
  defineFunction({
11107
11216
  type: "verb",
11108
11217
  names: ["\\verb"],
@@ -13369,9 +13478,11 @@ class Style {
13369
13478
  constructor(data) {
13370
13479
  // Style.level can be 0 | 1 | 2 | 3, which correspond to
13371
13480
  // displaystyle, textstyle, scriptstyle, and scriptscriptstyle.
13372
- // style.level does not directly set MathML's script level. MathML does that itself.
13373
- // We use style.level to track, not set, math style so that we can get the
13374
- // correct scriptlevel when needed in supsub.js, mathchoice.js, or for dimensions in em.
13481
+ // style.level usually does not directly set MathML's script level. MathML does that itself.
13482
+ // However, Chromium does not stop shrinking after scriptscriptstyle, so we do explicitly
13483
+ // set a scriptlevel attribute in those conditions.
13484
+ // We also use style.level to track math style so that we can get the correct
13485
+ // scriptlevel when needed in supsub.js, mathchoice.js, or for dimensions in em.
13375
13486
  this.level = data.level;
13376
13487
  this.color = data.color; // string | void
13377
13488
  // A font family applies to a group of fonts (i.e. SansSerif), while a font
@@ -13495,39 +13606,47 @@ class Style {
13495
13606
  }
13496
13607
 
13497
13608
  /* Temml Post Process
13498
- * Perform two tasks not done by Temml when it created each individual Temml <math> element.
13499
- * Given a block,
13500
- * 1. At each AMS auto-numbered environment, assign an id.
13501
- * 2. Populate the text contents of each \ref & \eqref
13609
+ * Populate the text contents of each \ref & \eqref
13502
13610
  *
13503
13611
  * As with other Temml code, this file is released under terms of the MIT license.
13504
13612
  * https://mit-license.org/
13505
13613
  */
13506
13614
 
13507
- const version = "0.10.32";
13615
+ const version = "0.10.33";
13508
13616
 
13509
13617
  function postProcess(block) {
13510
13618
  const labelMap = {};
13511
13619
  let i = 0;
13512
13620
 
13513
13621
  // Get a collection of the parents of each \tag & auto-numbered equation
13514
- const parents = block.getElementsByClassName("tml-tageqn");
13515
- for (const parent of parents) {
13516
- const eqns = parent.getElementsByClassName("tml-eqn");
13517
- if (eqns. length > 0 ) {
13518
- // AMS automatically numbered equation.
13519
- // Assign an id.
13520
- i += 1;
13521
- eqns[0].id = "tml-eqn-" + i;
13522
- // No need to write a number into the text content of the element.
13523
- // A CSS counter does that even if this postProcess() function is not used.
13622
+ const amsEqns = document.getElementsByClassName('tml-eqn');
13623
+ for (let parent of amsEqns) {
13624
+ // AMS automatically numbered equation.
13625
+ // Assign an id.
13626
+ i += 1;
13627
+ parent.setAttribute("id", "tml-eqn-" + String(i));
13628
+ // No need to write a number into the text content of the element.
13629
+ // A CSS counter has done that even if this postProcess() function is not used.
13630
+
13631
+ // Find any \label that refers to an AMS eqn number.
13632
+ while (true) {
13633
+ const labels = parent.getElementsByClassName("tml-label");
13634
+ if (labels.length > 0) {
13635
+ parent.setAttribute("id", labels[0].id);
13636
+ labelMap[labels[0].id] = String(i);
13637
+ break
13638
+ } else {
13639
+ if (parent.tagName === "mtable") { break }
13640
+ parent = parent.parentElement;
13641
+ }
13524
13642
  }
13525
- // If there is a \label, add it to labelMap
13643
+ }
13644
+
13645
+ // Find \labels associated with \tag
13646
+ const taggedEqns = document.getElementsByClassName('tml-tageqn');
13647
+ for (const parent of taggedEqns) {
13526
13648
  const labels = parent.getElementsByClassName("tml-label");
13527
- if (labels.length === 0) { continue }
13528
- if (eqns.length > 0) {
13529
- labelMap[labels[0].id] = String(i);
13530
- } else {
13649
+ if (labels.length > 0) {
13531
13650
  const tags = parent.getElementsByClassName("tml-tag");
13532
13651
  if (tags.length > 0) {
13533
13652
  labelMap[labels[0].id] = tags[0].textContent;
@@ -13538,17 +13657,22 @@ function postProcess(block) {
13538
13657
  // Populate \ref & \eqref text content
13539
13658
  const refs = block.getElementsByClassName("tml-ref");
13540
13659
  [...refs].forEach(ref => {
13541
- let str = labelMap[ref.getAttribute("href").slice(1)];
13660
+ const attr = ref.getAttribute("href");
13661
+ let str = labelMap[attr.slice(1)];
13542
13662
  if (ref.className.indexOf("tml-eqref") === -1) {
13543
13663
  // \ref. Omit parens.
13544
13664
  str = str.replace(/^\(/, "");
13545
- str = str.replace(/\($/, "");
13546
- } {
13665
+ str = str.replace(/\)$/, "");
13666
+ } else {
13547
13667
  // \eqref. Include parens
13548
13668
  if (str.charAt(0) !== "(") { str = "(" + str; }
13549
13669
  if (str.slice(-1) !== ")") { str = str + ")"; }
13550
13670
  }
13551
- ref.textContent = str;
13671
+ const mtext = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mtext");
13672
+ mtext.appendChild(document.createTextNode(str));
13673
+ const math = document.createElementNS("http://www.w3.org/1998/Math/MathML", "math");
13674
+ math.appendChild(mtext);
13675
+ ref.appendChild(math);
13552
13676
  });
13553
13677
  }
13554
13678