temml 0.13.2 → 0.13.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "temml",
3
- "version": "0.13.02",
3
+ "version": "0.13.4",
4
4
  "description": "TeX to MathML conversion in JavaScript.",
5
5
  "main": "dist/temml.js",
6
6
  "engines": {
@@ -34,7 +34,8 @@
34
34
  "esm": "^3.2.25",
35
35
  "globals": "^15.9.0",
36
36
  "rollup": "^4.59.0",
37
- "terser": "^5.34.0"
37
+ "terser": "^5.34.0",
38
+ "ws": "^8.20.0"
38
39
  },
39
40
  "scripts": {
40
41
  "lint": "eslint temml.js src",
@@ -44,6 +45,7 @@
44
45
  "minify": "terser test/temml.js -o site/assets/temml.min.js -c -m && terser contrib/mhchem/mhchem.js -o site/assets/mhchem.min.js -c -m",
45
46
  "build": "rollup --config ./utils/rollupConfig.mjs && yarn minify && node utils/insertPlugins.js",
46
47
  "docs": "node utils/buildDocs.js",
47
- "dist": "yarn build && node ./utils/copyfiles.js"
48
+ "dist": "yarn build && node ./utils/copyfiles.js",
49
+ "serve": "node utils/server.cjs site/docs/en/mathml-status.html 8000"
48
50
  }
49
51
  }
@@ -9,6 +9,7 @@ import Lexer from "./Lexer";
9
9
  import { Token } from "./Token";
10
10
 
11
11
  import ParseError from "./ParseError";
12
+ import SourceLocation from "./SourceLocation";
12
13
  import Namespace from "./Namespace";
13
14
  import macros from "./macros";
14
15
 
@@ -118,7 +119,7 @@ export default class MacroExpander {
118
119
  this.pushToken(new Token("EOF", end.loc));
119
120
 
120
121
  this.pushTokens(tokens);
121
- return start.range(end, "");
122
+ return new Token("", SourceLocation.range(start, end));
122
123
  }
123
124
 
124
125
  /**
@@ -358,9 +358,9 @@ const mathmlBuilder = function(group, style) {
358
358
  }
359
359
  if (mustSquashRow) {
360
360
  // All the cell contents are \hphantom. Squash the cell.
361
+ // TODO: Remove the next line when Firefox no longer needs it.
362
+ mtr.classes.push("ff-squash") // necessary in Firefox only.
361
363
  for (let j = 0; j < mtr.children.length; j++) {
362
- mtr.children[j].style.display = "block" // necessary in Firefox only
363
- mtr.children[j].style.height = "0" // necessary in Firefox only
364
364
  mtr.children[j].style.paddingTop = "0"
365
365
  mtr.children[j].style.paddingBottom = "0"
366
366
  }
@@ -14,13 +14,11 @@ defineFunction({
14
14
  },
15
15
  handler: ({ parser, funcName }, args, optArgs) => {
16
16
  // Find out if the author has defined custom delimiters
17
- let delimiters = ["(", ")"]
17
+ let delimiters = ["(", ")"]; // default
18
18
  if (funcName === "\\bordermatrix" && optArgs[0] && optArgs[0].body) {
19
19
  const body = optArgs[0].body
20
- if (body.length === 2 && body[0].type === "atom" && body[1].type === "atom") {
21
- if (body[0].family === "open" && body[1].family === "close") {
22
- delimiters = [body[0].text, body[1].text]
23
- }
20
+ if (body.length === 1 && body[0].type === "delimiter") {
21
+ delimiters = [body[0].left, body[0].right]
24
22
  }
25
23
  }
26
24
  // consume the opening brace
@@ -424,17 +424,14 @@ defineFunction({
424
424
  mathmlBuilder: (group) => {
425
425
  const textNode = mml.makeText(group.delim, group.mode);
426
426
  const middleNode = new mathMLTree.MathNode("mo", [textNode]);
427
- middleNode.setAttribute("fence", "true");
428
- if (group.delim.indexOf("arrow") > -1) {
429
- middleNode.setAttribute("stretchy", "true")
427
+ middleNode.setAttribute("stretchy", "true")
428
+ middleNode.setAttribute("form", "infix")
429
+ if (textNode.text !== "/") {
430
+ // MathML gives 5/18em spacing to each <mo> element.
431
+ // \middle should get delimiter spacing instead.
432
+ middleNode.setAttribute("lspace", "0.05em");
433
+ middleNode.setAttribute("rspace", "0.05em");
430
434
  }
431
- // The next line is not semantically correct, but
432
- // Chromium fails to stretch if it is not there.
433
- middleNode.setAttribute("form", "prefix")
434
- // MathML gives 5/18em spacing to each <mo> element.
435
- // \middle should get delimiter spacing instead.
436
- middleNode.setAttribute("lspace", "0.05em");
437
- middleNode.setAttribute("rspace", "0.05em");
438
435
  return middleNode;
439
436
  }
440
437
  });
@@ -166,7 +166,7 @@ defineFunction({
166
166
 
167
167
  defineFunction({
168
168
  type: "enclose",
169
- names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline",
169
+ names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\overline",
170
170
  "\\boxed", "\\longdiv", "\\phase"],
171
171
  props: {
172
172
  numArgs: 1
@@ -183,6 +183,25 @@ defineFunction({
183
183
  mathmlBuilder
184
184
  });
185
185
 
186
+ defineFunction({
187
+ type: "enclose",
188
+ names: ["\\sout"],
189
+ props: {
190
+ numArgs: 1,
191
+ allowedInText: true
192
+ },
193
+ handler({ parser, funcName }, args) {
194
+ const body = args[0];
195
+ return {
196
+ type: "enclose",
197
+ mode: parser.mode,
198
+ label: funcName,
199
+ body
200
+ };
201
+ },
202
+ mathmlBuilder
203
+ });
204
+
186
205
  defineFunction({
187
206
  type: "enclose",
188
207
  names: ["\\underline"],
@@ -1,9 +1,13 @@
1
1
  import defineFunction, { normalizeArgument } from "../defineFunction"
2
2
  import * as mml from "../buildMathML"
3
3
  import * as mathMLTree from "../mathMLTree"
4
+ import { variantChar } from "../replace"
5
+
6
+ const varNameFonts = ["mathrm", "mathit"];
4
7
 
5
8
  const isLongVariableName = (group, font) => {
6
- if (font !== "mathrm" || group.body.type !== "ordgroup" || group.body.body.length === 1) {
9
+ if (!varNameFonts.includes(font) || !group.body || group.body.type !== "ordgroup" ||
10
+ group.body.body.length === 1) {
7
11
  return false
8
12
  }
9
13
  if (group.body.body[0].type !== "mathord") { return false }
@@ -29,8 +33,7 @@ const mathmlBuilder = (group, style) => {
29
33
  }
30
34
  // Check if it is possible to consolidate elements into a single <mi> element.
31
35
  if (isLongVariableName(group, font)) {
32
- // This is a \mathrm{…} group. It gets special treatment because symbolsOrd.js
33
- // wraps <mi> elements with <mpadded>s to work around a Firefox bug.
36
+ // This is a \mathrm{…} or \mathit{…} group. It gets special treatment.
34
37
  const mi = mathGroup.children[0].children[0].children
35
38
  ? mathGroup.children[0].children[0]
36
39
  : mathGroup.children[0];
@@ -40,7 +43,14 @@ const mathmlBuilder = (group, style) => {
40
43
  ? mathGroup.children[i].children[0].children[0].text
41
44
  : mathGroup.children[i].children[0].text
42
45
  }
43
- // Wrap in a <mpadded> to prevent the same Firefox bug.
46
+ if (font === "mathit") {
47
+ // Long <mi> elements are normally rendered in upright font.
48
+ // To get italic, we need to convert each character to the corresponding italic character.
49
+ mi.children[0].text = mi.children[0].text.split("")
50
+ .map(c => variantChar(c, "italic")).join("")
51
+ return mi
52
+ }
53
+ // Otherwise, font is "mathrm". Wrap in a <mpadded> to prevent a Firefox spacing bug.
44
54
  const mpadded = new mathMLTree.MathNode("mpadded", [mi])
45
55
  mpadded.setAttribute("lspace", "0")
46
56
  return mpadded
@@ -67,7 +67,7 @@ defineFunction({
67
67
  const inner = mml.buildExpression(ordargument(group.body), style);
68
68
  const phantom = new mathMLTree.MathNode("mphantom", inner);
69
69
  const node = new mathMLTree.MathNode("mpadded", [phantom]);
70
- node.setAttribute("width", "0px");
70
+ node.setAttribute("width", "0.1px");
71
71
  return node;
72
72
  }
73
73
  });
@@ -5,7 +5,7 @@
5
5
  * https://mit-license.org/
6
6
  */
7
7
 
8
- export const version = "0.13.02";
8
+ export const version = "0.13.4";
9
9
 
10
10
  export function postProcess(block) {
11
11
  const labelMap = {}
package/src/stretchy.js CHANGED
@@ -35,7 +35,7 @@ const estimatedWidth = node => {
35
35
  }
36
36
 
37
37
  const stretchyCodePoint = {
38
- widehat: "^",
38
+ widehat: "\u02c6", // Shorter than \u005e, which is appropriate for an accent.
39
39
  widecheck: "ˇ",
40
40
  widetilde: "~",
41
41
  wideparen: "⏜", // \u23dc
@@ -98,19 +98,30 @@ export const mathMLnode = function(label) {
98
98
  return node
99
99
  }
100
100
 
101
- const crookedWides = ["\\widetilde", "\\widehat", "\\widecheck", "\\utilde"]
101
+ const wideHats = ["\\widehat", "\\widecheck"];
102
102
 
103
- // TODO: Remove when Chromium stretches \widetilde & \widehat
103
+ // TODO: Remove if/when Chromium stretches \widetilde & \widehat
104
104
  export const accentNode = (group) => {
105
105
  const mo = mathMLnode(group.label)
106
- if (crookedWides.includes(group.label)) {
106
+ if (group.label.indexOf("tilde") > -1) {
107
107
  const width = estimatedWidth(group.base)
108
108
  if (1 < width && width < 1.6) {
109
- mo.classes.push("tml-crooked-2")
109
+ mo.classes.push("tml-tilde-2")
110
+ } else if (1.6 <= width && width < 2.5) {
111
+ mo.classes.push("tml-tilde-3")
112
+ } else if (2.5 <= width) {
113
+ mo.classes.push("tml-tilde-4")
114
+ }
115
+ } else if (wideHats.includes(group.label)) {
116
+ const width = estimatedWidth(group.base)
117
+ if (0 < width && width <= 1) {
118
+ mo.classes.push("tml-hat-1")
119
+ } else if (1 < width && width < 1.6) {
120
+ mo.classes.push("tml-hat-2")
110
121
  } else if (1.6 <= width && width < 2.5) {
111
- mo.classes.push("tml-crooked-3")
122
+ mo.classes.push("tml-hat-3")
112
123
  } else if (2.5 <= width) {
113
- mo.classes.push("tml-crooked-4")
124
+ mo.classes.push("tml-hat-4")
114
125
  }
115
126
  }
116
127
  return mo
package/src/symbols.js CHANGED
@@ -902,7 +902,7 @@ defineSymbol(math, accent, "\u007e", "\\tilde");
902
902
  defineSymbol(math, accent, "\u203e", "\\bar");
903
903
  defineSymbol(math, accent, "\u02d8", "\\breve");
904
904
  defineSymbol(math, accent, "\u02c7", "\\check");
905
- defineSymbol(math, accent, "\u005e", "\\hat");
905
+ defineSymbol(math, accent, "\u02c6", "\\hat");
906
906
  defineSymbol(math, accent, "\u2192", "\\vec");
907
907
  defineSymbol(math, accent, "\u02d9", "\\dot");
908
908
  defineSymbol(math, accent, "\u02da", "\\mathring");