temml 0.10.13 → 0.10.15

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.
@@ -276,24 +276,94 @@ const mathmlBuilder = function(group, style) {
276
276
  // Write horizontal rules
277
277
  if (i === 0 && hlines[0].length > 0) {
278
278
  if (hlines[0].length === 2) {
279
- mtr.classes.push("tml-top-double")
279
+ mtr.children.forEach(cell => { cell.style.borderTop = "0.15em double" })
280
280
  } else {
281
- mtr.classes.push(hlines[0][0] ? "tml-top-dashed" : "tml-top-solid")
281
+ mtr.children.forEach(cell => {
282
+ cell.style.borderTop = hlines[0][0] ? "0.06em dashed" : "0.06em solid"
283
+ })
282
284
  }
283
285
  }
284
286
  if (hlines[i + 1].length > 0) {
285
287
  if (hlines[i + 1].length === 2) {
286
- mtr.classes.push("tml-hline-double")
288
+ mtr.children.forEach(cell => { cell.style.borderBottom = "0.15em double" })
287
289
  } else {
288
- mtr.classes.push(hlines[i + 1][0] ? "tml-hline-dashed" : "tml-hline-solid")
290
+ mtr.children.forEach(cell => {
291
+ cell.style.borderBottom = hlines[i + 1][0] ? "0.06em dashed" : "0.06em solid"
292
+ })
289
293
  }
290
294
  }
291
295
  tbl.push(mtr);
292
296
  }
293
- let table = new mathMLTree.MathNode("mtable", tbl)
297
+
294
298
  if (group.envClasses.length > 0) {
295
- table.classes = group.envClasses.map(e => "tml-" + e)
299
+ const pad = group.envClasses.includes("jot")
300
+ ? "0.7" // 0.5ex + 0.09em top & bot padding
301
+ : group.envClasses.includes("small")
302
+ ? "0.35"
303
+ : "0.5" // 0.5ex default top & bot padding
304
+ const sidePadding = group.envClasses.includes("abut")
305
+ ? "0"
306
+ : group.envClasses.includes("cases")
307
+ ? "0"
308
+ : group.envClasses.includes("small")
309
+ ? "0.1389"
310
+ : group.envClasses.includes("cd")
311
+ ? "0.25"
312
+ : "0.4" // default side padding
313
+
314
+ const numCols = tbl.length === 0 ? 0 : tbl[0].children.length
315
+
316
+ const sidePad = (j, hand) => {
317
+ if (j === 0 && hand === 0) { return "0" }
318
+ if (j === numCols - 1 && hand === 1) { return "0" }
319
+ if (group.envClasses[0] !== "align") { return sidePadding }
320
+ if (hand === 1) { return "0" }
321
+ if (group.addEqnNum) {
322
+ return (j % 2) ? "1" : "0"
323
+ } else {
324
+ return (j % 2) ? "0" : "1"
325
+ }
326
+ }
327
+
328
+ // Padding
329
+ for (let i = 0; i < tbl.length; i++) {
330
+ for (let j = 0; j < tbl[i].children.length; j++) {
331
+ tbl[i].children[j].style.padding = `${pad}ex ${sidePad(j, 1)}em ${pad}ex ${sidePad(j, 0)}em`
332
+ }
333
+ }
334
+
335
+ // Justification
336
+ const align = group.envClasses.includes("align") || group.envClasses.includes("alignat")
337
+ for (let i = 0; i < tbl.length; i++) {
338
+ const row = tbl[i];
339
+ if (align) {
340
+ for (let j = 0; j < row.children.length; j++) {
341
+ // Chromium does not recognize text-align: left. Use -webkit-
342
+ // TODO: Remove -webkit- when Chromium no longer needs it.
343
+ row.children[j].style.textAlign = "-webkit-" + (j % 2 ? "left" : "right")
344
+ }
345
+ }
346
+ if (row.children.length > 1 && group.envClasses.includes("cases")) {
347
+ row.children[1].style.padding = row.children[1].style.padding.replace(/0em$/, "1em")
348
+ }
349
+
350
+ if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
351
+ for (const cell of row.children) {
352
+ cell.style.textAlign = "-webkit-" + "left"
353
+ }
354
+ }
355
+ }
356
+ } else {
357
+ // Set zero padding on side of the matrix
358
+ for (let i = 0; i < tbl.length; i++) {
359
+ tbl[i].children[0].style.paddingLeft = "0em"
360
+ if (tbl[i].children.length === tbl[0].children.length) {
361
+ tbl[i].children[tbl[i].children.length - 1].style.paddingRight = "0em"
362
+ }
363
+ }
296
364
  }
365
+
366
+ let table = new mathMLTree.MathNode("mtable", tbl)
297
367
  if (group.scriptLevel === "display") { table.setAttribute("displaystyle", "true") }
298
368
 
299
369
  if (group.addEqnNum || group.envClasses.includes("multline")) {
@@ -373,6 +443,8 @@ const mathmlBuilder = function(group, style) {
373
443
  align = "left " + (align.length > 0 ? align : "center ") + "right "
374
444
  }
375
445
  if (align) {
446
+ // Firefox reads this attribute, not the -webkit-left|right written above.
447
+ // TODO: When Chrome no longer needs "-webkit-", use CSS and delete the next line.
376
448
  table.setAttribute("columnalign", align.trim())
377
449
  }
378
450
 
@@ -397,7 +469,7 @@ const alignedHandler = function(context, args) {
397
469
  cols,
398
470
  addEqnNum: context.envName === "align" || context.envName === "alignat",
399
471
  emptySingleRow: true,
400
- envClasses: ["jot", "abut"], // set row spacing & provisional column spacing
472
+ envClasses: ["abut", "jot"], // set row spacing & provisional column spacing
401
473
  maxNumCols: context.envName === "split" ? 2 : undefined,
402
474
  leqno: context.parser.settings.leqno
403
475
  },
@@ -415,18 +487,22 @@ const alignedHandler = function(context, args) {
415
487
  // binary. This behavior is implemented in amsmath's \start@aligned.
416
488
  let numMaths;
417
489
  let numCols = 0;
418
- if (args[0] && args[0].type === "ordgroup") {
419
- let arg0 = "";
490
+ const isAlignedAt = context.envName.indexOf("at") > -1
491
+ if (args[0] && isAlignedAt) {
492
+ // alignat environment takes an argument w/ number of columns
493
+ let arg0 = ""
420
494
  for (let i = 0; i < args[0].body.length; i++) {
421
- const textord = assertNodeType(args[0].body[i], "textord");
422
- arg0 += textord.text;
495
+ const textord = assertNodeType(args[0].body[i], "textord")
496
+ arg0 += textord.text
497
+ }
498
+ if (isNaN(arg0)) {
499
+ throw new ParseError("The alignat enviroment requires a numeric first argument.")
423
500
  }
424
- numMaths = Number(arg0);
425
- numCols = numMaths * 2;
501
+ numMaths = Number(arg0)
502
+ numCols = numMaths * 2
426
503
  }
427
- const isAligned = !numCols;
428
504
  res.body.forEach(function(row) {
429
- if (!isAligned) {
505
+ if (isAlignedAt) {
430
506
  // Case 1
431
507
  const curMaths = row.length / 2;
432
508
  if (numMaths < curMaths) {
@@ -456,14 +532,10 @@ const alignedHandler = function(context, args) {
456
532
  }
457
533
  if (context.envName === "split") {
458
534
  // Append no more classes
459
- } else if (context.envName.indexOf("ed") > -1) {
460
- res.envClasses.push("aligned") // Sets justification
461
- } else if (isAligned) {
462
- res.envClasses[1] = context.envName === "align*"
463
- ? "align-star"
464
- : "align" // Sets column spacing & justification
535
+ } else if (isAlignedAt) {
536
+ res.envClasses.push("alignat") // Sets justification
465
537
  } else {
466
- res.envClasses.push("aligned") // Sets justification
538
+ res.envClasses[0] = "align" // Sets column spacing & justification
467
539
  }
468
540
  return res;
469
541
  };
@@ -713,7 +785,7 @@ defineEnvironment({
713
785
  }
714
786
  const res = {
715
787
  cols: [],
716
- envClasses: ["jot", "abut"],
788
+ envClasses: ["abut", "jot"],
717
789
  addEqnNum: context.envName === "gather",
718
790
  emptySingleRow: true,
719
791
  leqno: context.parser.settings.leqno
@@ -178,10 +178,9 @@ defineFunction({
178
178
  // so we have to explicitly set stretchy to true.
179
179
  node.setAttribute("stretchy", "true")
180
180
  }
181
-
182
181
  node.setAttribute("symmetric", "true"); // Needed for tall arrows in Firefox.
183
- node.setAttribute("minsize", sizeToMaxHeight[group.size] + "em");
184
- // Don't set the maxsize attribute. It's broken in Chromium.
182
+ node.setAttribute("minsize", sizeToMaxHeight[group.size] + "em")
183
+ node.setAttribute("maxsize", sizeToMaxHeight[group.size] + "em")
185
184
  return node;
186
185
  }
187
186
  });
@@ -12,34 +12,42 @@ const padding = _ => {
12
12
 
13
13
  const mathmlBuilder = (group, style) => {
14
14
  let node
15
- if (group.label.indexOf("colorbox") > -1) {
16
- // Chrome mpadded +width attribute is broken. Insert <mspace>
17
- node = new mathMLTree.MathNode("mpadded", [
15
+ if (group.label.indexOf("colorbox") > -1 || group.label === "\\boxed") {
16
+ // MathML core does not support +width attribute in <mpadded>.
17
+ // Firefox does not reliably add side padding.
18
+ // Insert <mspace>
19
+ node = new mathMLTree.MathNode("mrow", [
18
20
  padding(),
19
21
  mml.buildGroup(group.body, style),
20
22
  padding()
21
23
  ])
22
24
  } else {
23
- node = new mathMLTree.MathNode("menclose", [mml.buildGroup(group.body, style)])
25
+ node = new mathMLTree.MathNode("mrow", [mml.buildGroup(group.body, style)])
24
26
  }
25
27
  switch (group.label) {
26
28
  case "\\overline":
27
- node.setAttribute("notation", "top")
28
29
  node.style.padding = "0.1em 0 0 0"
29
30
  node.style.borderTop = "0.065em solid"
30
31
  break
31
32
  case "\\underline":
32
- node.setAttribute("notation", "bottom")
33
33
  node.style.padding = "0 0 0.1em 0"
34
34
  node.style.borderBottom = "0.065em solid"
35
35
  break
36
36
  case "\\cancel":
37
- node.setAttribute("notation", "updiagonalstrike");
38
- node.classes.push("cancel")
37
+ node.style.background = `linear-gradient(to top left,
38
+ rgba(0,0,0,0) 0%,
39
+ rgba(0,0,0,0) calc(50% - 0.06em),
40
+ rgba(0,0,0,1) 50%,
41
+ rgba(0,0,0,0) calc(50% + 0.06em),
42
+ rgba(0,0,0,0) 100%);`
39
43
  break
40
44
  case "\\bcancel":
41
- node.setAttribute("notation", "downdiagonalstrike");
42
- node.classes.push("bcancel")
45
+ node.style.background = `linear-gradient(to top right,
46
+ rgba(0,0,0,0) 0%,
47
+ rgba(0,0,0,0) calc(50% - 0.06em),
48
+ rgba(0,0,0,1) 50%,
49
+ rgba(0,0,0,0) calc(50% + 0.06em),
50
+ rgba(0,0,0,0) 100%);`
43
51
  break
44
52
  /*
45
53
  case "\\longdiv":
@@ -49,18 +57,21 @@ const mathmlBuilder = (group, style) => {
49
57
  node.setAttribute("notation", "phasorangle");
50
58
  break */
51
59
  case "\\angl":
52
- node.setAttribute("notation", "actuarial")
53
60
  node.style.padding = "0.03889em 0.03889em 0 0.03889em"
54
61
  node.style.borderTop = "0.049em solid"
55
62
  node.style.borderRight = "0.049em solid"
56
63
  node.style.marginRight = "0.03889em"
57
64
  break
58
65
  case "\\sout":
59
- node.setAttribute("notation", "horizontalstrike");
60
66
  node.style["text-decoration"] = "line-through 0.08em solid"
61
67
  break
68
+ case "\\boxed":
69
+ // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
70
+ node.style = { padding: "3pt 0 3pt 0", border: "1px solid" }
71
+ node.setAttribute("scriptlevel", "0")
72
+ node.setAttribute("displaystyle", "true")
73
+ break
62
74
  case "\\fbox":
63
- node.setAttribute("notation", "box");
64
75
  node.style = { padding: "3pt", border: "1px solid" }
65
76
  break
66
77
  case "\\fcolorbox":
@@ -80,8 +91,18 @@ const mathmlBuilder = (group, style) => {
80
91
  break
81
92
  }
82
93
  case "\\xcancel":
83
- node.setAttribute("notation", "updiagonalstrike downdiagonalstrike");
84
- node.classes.push("xcancel")
94
+ node.style.background = `linear-gradient(to top left,
95
+ rgba(0,0,0,0) 0%,
96
+ rgba(0,0,0,0) calc(50% - 0.06em),
97
+ rgba(0,0,0,1) 50%,
98
+ rgba(0,0,0,0) calc(50% + 0.06em),
99
+ rgba(0,0,0,0) 100%),
100
+ linear-gradient(to top right,
101
+ rgba(0,0,0,0) 0%,
102
+ rgba(0,0,0,0) calc(50% - 0.06em),
103
+ rgba(0,0,0,1) 50%,
104
+ rgba(0,0,0,0) calc(50% + 0.06em),
105
+ rgba(0,0,0,0) 100%);`
85
106
  break
86
107
  }
87
108
  if (group.backgroundColor) {
@@ -175,7 +196,7 @@ defineFunction({
175
196
 
176
197
  defineFunction({
177
198
  type: "enclose",
178
- names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline"],
199
+ names: ["\\angl", "\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\overline", "\\boxed"],
179
200
  // , "\\phase", "\\longdiv"
180
201
  props: {
181
202
  numArgs: 1
@@ -5,8 +5,6 @@ import { assertNodeType } from "../parseNode"
5
5
  import { calculateSize } from "../units"
6
6
  import * as mml from "../buildMathML"
7
7
 
8
- const sign = num => num >= 0 ? "+" : "-"
9
-
10
8
  // \raise, \lower, and \raisebox
11
9
 
12
10
  const mathmlBuilder = (group, style) => {
@@ -14,11 +12,13 @@ const mathmlBuilder = (group, style) => {
14
12
  const node = new mathMLTree.MathNode("mpadded", [mml.buildGroup(group.body, newStyle)])
15
13
  const dy = calculateSize(group.dy, style)
16
14
  node.setAttribute("voffset", dy.number + dy.unit)
17
- const dyAbs = Math.abs(dy.number)
18
- // The next two lines do not work in Chromium.
19
- // TODO: Find some other way to adjust height and depth.
20
- node.setAttribute("height", sign(dy.number) + dyAbs + dy.unit)
21
- node.setAttribute("depth", sign(-dy.number) + dyAbs + dy.unit)
15
+ // Add padding, which acts to increase height in Chromium.
16
+ // TODO: Figure out some way to change height in Firefox w/o breaking Chromium.
17
+ if (dy.number > 0) {
18
+ node.style.padding = dy.number + dy.unit + " 0 0 0"
19
+ } else {
20
+ node.style.padding = "0 0 " + Math.abs(dy.number) + dy.unit + " 0"
21
+ }
22
22
  return node
23
23
  }
24
24
 
@@ -26,13 +26,16 @@ import { DocumentFragment } from "./tree"
26
26
  * much of this module.
27
27
  */
28
28
 
29
+ const openDelims = "([{⌊⌈⟨⟮⎰⟦⦃"
30
+ const closeDelims = ")]}⌋⌉⟩⟯⎱⟦⦄"
31
+
29
32
  export default function setLineBreaks(expression, wrapMode, isDisplayMode) {
30
33
  const mtrs = [];
31
34
  let mrows = [];
32
35
  let block = [];
33
36
  let numTopLevelEquals = 0
34
- let canBeBIN = false // The first node cannot be an infix binary operator.
35
37
  let i = 0
38
+ let level = 0
36
39
  while (i < expression.length) {
37
40
  while (expression[i] instanceof DocumentFragment) {
38
41
  expression.splice(i, 1, ...expression[i].children) // Expand the fragment.
@@ -55,7 +58,12 @@ export default function setLineBreaks(expression, wrapMode, isDisplayMode) {
55
58
  }
56
59
  block.push(node);
57
60
  if (node.type && node.type === "mo" && node.children.length === 1) {
58
- if (wrapMode === "=" && node.children[0].text === "=") {
61
+ const ch = node.children[0].text
62
+ if (openDelims.indexOf(ch) > -1) {
63
+ level += 1
64
+ } else if (closeDelims.indexOf(ch) > -1) {
65
+ level -= 1
66
+ } else if (level === 0 && wrapMode === "=" && ch === "=") {
59
67
  numTopLevelEquals += 1
60
68
  if (numTopLevelEquals > 1) {
61
69
  block.pop()
@@ -64,59 +72,48 @@ export default function setLineBreaks(expression, wrapMode, isDisplayMode) {
64
72
  mrows.push(element)
65
73
  block = [node];
66
74
  }
67
- } else if (wrapMode === "tex") {
68
- // This may be a place for a soft line break.
69
- if (canBeBIN && !node.attributes.form) {
70
- // Check if the following node is a \nobreak text node, e.g. "~""
71
- const next = i < expression.length - 1 ? expression[i + 1] : null;
72
- let glueIsFreeOfNobreak = true;
73
- if (
74
- !(
75
- next &&
76
- next.type === "mtext" &&
77
- next.attributes.linebreak &&
78
- next.attributes.linebreak === "nobreak"
79
- )
80
- ) {
81
- // We may need to start a new block.
82
- // First, put any post-operator glue on same line as operator.
83
- for (let j = i + 1; j < expression.length; j++) {
84
- const nd = expression[j];
75
+ } else if (level === 0 && wrapMode === "tex") {
76
+ // Check if the following node is a \nobreak text node, e.g. "~""
77
+ const next = i < expression.length - 1 ? expression[i + 1] : null;
78
+ let glueIsFreeOfNobreak = true;
79
+ if (
80
+ !(
81
+ next &&
82
+ next.type === "mtext" &&
83
+ next.attributes.linebreak &&
84
+ next.attributes.linebreak === "nobreak"
85
+ )
86
+ ) {
87
+ // We may need to start a new block.
88
+ // First, put any post-operator glue on same line as operator.
89
+ for (let j = i + 1; j < expression.length; j++) {
90
+ const nd = expression[j];
91
+ if (
92
+ nd.type &&
93
+ nd.type === "mspace" &&
94
+ !(nd.attributes.linebreak && nd.attributes.linebreak === "newline")
95
+ ) {
96
+ block.push(nd);
97
+ i += 1;
85
98
  if (
86
- nd.type &&
87
- nd.type === "mspace" &&
88
- !(nd.attributes.linebreak && nd.attributes.linebreak === "newline")
99
+ nd.attributes &&
100
+ nd.attributes.linebreak &&
101
+ nd.attributes.linebreak === "nobreak"
89
102
  ) {
90
- block.push(nd);
91
- i += 1;
92
- if (
93
- nd.attributes &&
94
- nd.attributes.linebreak &&
95
- nd.attributes.linebreak === "nobreak"
96
- ) {
97
- glueIsFreeOfNobreak = false;
98
- }
99
- } else {
100
- break;
103
+ glueIsFreeOfNobreak = false;
101
104
  }
105
+ } else {
106
+ break;
102
107
  }
103
108
  }
104
- if (glueIsFreeOfNobreak) {
105
- // Start a new block. (Insert a soft linebreak.)
106
- const element = new mathMLTree.MathNode("mrow", block)
107
- mrows.push(element)
108
- block = [];
109
- }
110
- canBeBIN = false
111
109
  }
112
- const isOpenDelimiter = node.attributes.form && node.attributes.form === "prefix"
113
- // Any operator that follows an open delimiter is unary.
114
- canBeBIN = !(node.attributes.separator || isOpenDelimiter);
115
- } else {
116
- canBeBIN = true
110
+ if (glueIsFreeOfNobreak) {
111
+ // Start a new block. (Insert a soft linebreak.)
112
+ const element = new mathMLTree.MathNode("mrow", block)
113
+ mrows.push(element)
114
+ block = [];
115
+ }
117
116
  }
118
- } else {
119
- canBeBIN = true
120
117
  }
121
118
  i += 1
122
119
  }
package/src/macros.js CHANGED
@@ -238,9 +238,6 @@ defineMacro("\u22ee", "\\vdots");
238
238
  //\newcommand{\substack}[1]{\subarray{c}#1\endsubarray}
239
239
  defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}");
240
240
 
241
- // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}}
242
- defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}");
243
-
244
241
  // \def\iff{\DOTSB\;\Longleftrightarrow\;}
245
242
  // \def\implies{\DOTSB\;\Longrightarrow\;}
246
243
  // \def\impliedby{\DOTSB\;\Longleftarrow\;}
@@ -489,7 +486,7 @@ defineMacro(
489
486
  defineMacro(
490
487
  "\\Temml",
491
488
  // eslint-disable-next-line max-len
492
- "\\textrm{T}\\kern-0.2em\\lower{0.2em}\\textrm{E}\\kern-0.08em{\\textrm{M}\\kern-0.08em\\raise{0.2em}\\textrm{M}\\kern-0.08em\\textrm{L}}"
489
+ "\\textrm{T}\\kern-0.2em\\lower{0.2em}{\\textrm{E}}\\kern-0.08em{\\textrm{M}\\kern-0.08em\\raise{0.2em}\\textrm{M}\\kern-0.08em\\textrm{L}}"
493
490
  );
494
491
 
495
492
  // \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace}
@@ -8,7 +8,7 @@
8
8
  * https://mit-license.org/
9
9
  */
10
10
 
11
- export const version = "0.10.13";
11
+ export const version = "0.10.15";
12
12
 
13
13
  export function postProcess(block) {
14
14
  const labelMap = {}
package/src/symbols.js CHANGED
@@ -212,6 +212,10 @@ defineSymbol(math, mathord, "\u21af", "\\lightning", true);
212
212
  defineSymbol(math, mathord, "\u220E", "\\QED", true);
213
213
  defineSymbol(math, mathord, "\u2030", "\\permil", true);
214
214
  defineSymbol(text, textord, "\u2030", "\\permil");
215
+ defineSymbol(math, mathord, "\u2609", "\\astrosun", true);
216
+ defineSymbol(math, mathord, "\u263c", "\\sun", true);
217
+ defineSymbol(math, mathord, "\u263e", "\\leftmoon", true);
218
+ defineSymbol(math, mathord, "\u263d", "\\rightmoon", true);
215
219
 
216
220
  // AMS Negated Binary Relations
217
221
  defineSymbol(math, rel, "\u226e", "\\nless", true);
@@ -356,6 +360,7 @@ defineSymbol(math, rel, "\u2ab7", "\\precapprox", true);
356
360
  defineSymbol(math, rel, "\u22b2", "\\vartriangleleft");
357
361
  defineSymbol(math, rel, "\u22b4", "\\trianglelefteq");
358
362
  defineSymbol(math, rel, "\u22a8", "\\vDash", true);
363
+ defineSymbol(math, rel, "\u22ab", "\\VDash", true);
359
364
  defineSymbol(math, rel, "\u22aa", "\\Vvdash", true);
360
365
  defineSymbol(math, rel, "\u2323", "\\smallsmile");
361
366
  defineSymbol(math, rel, "\u2322", "\\smallfrown");
package/temml.js CHANGED
@@ -21,6 +21,7 @@ import defineMacro from "./src/defineMacro";
21
21
  import { postProcess, version } from "./src/postProcess";
22
22
 
23
23
  /**
24
+ * @type {import('./temml').render}
24
25
  * Parse and build an expression, and place that expression in the DOM node
25
26
  * given.
26
27
  */
@@ -58,6 +59,7 @@ if (typeof document !== "undefined") {
58
59
  }
59
60
 
60
61
  /**
62
+ * @type {import('./temml').renderToString}
61
63
  * Parse and build an expression, and return the markup for that.
62
64
  */
63
65
  const renderToString = function(expression, options) {
@@ -66,6 +68,7 @@ const renderToString = function(expression, options) {
66
68
  };
67
69
 
68
70
  /**
71
+ * @type {import('./temml').generateParseTree}
69
72
  * Parse an expression and return the parse tree.
70
73
  */
71
74
  const generateParseTree = function(expression, options) {
@@ -74,6 +77,7 @@ const generateParseTree = function(expression, options) {
74
77
  };
75
78
 
76
79
  /**
80
+ * @type {import('./temml').definePreamble}
77
81
  * Take an expression which contains a preamble.
78
82
  * Parse it and return the macros.
79
83
  */
@@ -106,6 +110,7 @@ const renderError = function(error, expression, options) {
106
110
  };
107
111
 
108
112
  /**
113
+ * @type {import('./temml').renderToMathMLTree}
109
114
  * Generates and returns the Temml build tree. This is used for advanced
110
115
  * use cases (like rendering to custom output).
111
116
  */
@@ -123,6 +128,7 @@ const renderToMathMLTree = function(expression, options) {
123
128
  }
124
129
  };
125
130
 
131
+ /** @type {import('./temml').default} */
126
132
  export default {
127
133
  /**
128
134
  * Current Temml version