temml 0.10.33 → 0.11.0
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 +16 -1
- package/dist/Temml-Fira.css +16 -1
- package/dist/Temml-Latin-Modern.css +16 -1
- package/dist/Temml-Libertinus.css +16 -1
- package/dist/Temml-Local.css +16 -1
- package/dist/Temml-STIX2.css +16 -1
- package/dist/temml.cjs +495 -163
- package/dist/temml.d.ts +3 -0
- package/dist/temml.js +495 -163
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +495 -163
- package/dist/temmlPostProcess.js +7 -6
- package/package.json +2 -2
- package/src/auto-render.js +263 -0
- package/src/buildMathML.js +20 -0
- package/src/environments/array.js +119 -82
- package/src/environments/cd.js +2 -0
- package/src/functions/label.js +1 -1
- package/src/linebreaking.js +1 -1
- package/src/macros.js +3 -1
- package/src/mathMLTree.js +5 -0
- package/src/postProcess.js +7 -6
- package/src/symbols.js +1 -1
- package/temml.js +6 -0
- package/contrib/auto-render/README.md +0 -89
- package/contrib/auto-render/auto-render.js +0 -128
- package/contrib/auto-render/dist/auto-render.js +0 -214
- package/contrib/auto-render/dist/auto-render.min.js +0 -1
- package/contrib/auto-render/splitAtDelimiters.js +0 -84
- package/contrib/auto-render/test/auto-render-spec.js +0 -234
- package/contrib/auto-render/test/auto-render.js +0 -214
- package/contrib/auto-render/test/test_page.html +0 -59
@@ -3,6 +3,7 @@ import { parseCD } from "./cd";
|
|
3
3
|
import defineFunction from "../defineFunction";
|
4
4
|
import mathMLTree from "../mathMLTree";
|
5
5
|
import { Span } from "../domTree"
|
6
|
+
import { Token } from "../Token";
|
6
7
|
import { StyleLevel } from "../constants"
|
7
8
|
import ParseError from "../ParseError";
|
8
9
|
import { assertNodeType, assertSymbolNodeType } from "../parseNode";
|
@@ -57,31 +58,28 @@ const arrayGaps = macros => {
|
|
57
58
|
return [arraystretch, arraycolsep]
|
58
59
|
}
|
59
60
|
|
60
|
-
const
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
tag.classes = ["tml-tag"]
|
68
|
-
} else {
|
69
|
-
// \notag. Return an empty span.
|
70
|
-
tag = new mathMLTree.MathNode("mtext", [], [])
|
71
|
-
return tag
|
61
|
+
const checkCellForLabels = cell => {
|
62
|
+
// Check if the author wrote a \tag{} inside this cell.
|
63
|
+
let rowLabel = ""
|
64
|
+
for (let i = 0; i < cell.length; i++) {
|
65
|
+
if (cell[i].type === "label") {
|
66
|
+
if (rowLabel) { throw new ParseError(("Multiple \\labels in one row")) }
|
67
|
+
rowLabel = cell[i].string
|
72
68
|
}
|
73
|
-
} else if (group.envClasses.includes("multline") &&
|
74
|
-
((group.leqno && rowNum !== 0) || (!group.leqno && rowNum !== group.body.length - 1))) {
|
75
|
-
// A multiline that does not receive a tag. Return an empty cell.
|
76
|
-
tag = new mathMLTree.MathNode("mtext", [], [])
|
77
|
-
return tag
|
78
|
-
} else {
|
79
|
-
// AMS automatcally numbered equaton.
|
80
|
-
// Insert a class so the element can be populated by a CSS counter.
|
81
|
-
// WebKit will display the CSS counter only inside a span.
|
82
|
-
tag = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])])
|
83
69
|
}
|
84
|
-
return
|
70
|
+
return rowLabel
|
71
|
+
}
|
72
|
+
|
73
|
+
// autoTag (an argument to parseArray) can be one of three values:
|
74
|
+
// * undefined: Regular (not-top-level) array; no tags on each row
|
75
|
+
// * true: Automatic equation numbering, overridable by \tag
|
76
|
+
// * false: Tags allowed on each row, but no automatic numbering
|
77
|
+
// This function *doesn't* work with the "split" environment name.
|
78
|
+
function getAutoTag(name) {
|
79
|
+
if (name.indexOf("ed") === -1) {
|
80
|
+
return name.indexOf("*") === -1;
|
81
|
+
}
|
82
|
+
// return undefined;
|
85
83
|
}
|
86
84
|
|
87
85
|
/**
|
@@ -95,7 +93,7 @@ function parseArray(
|
|
95
93
|
{
|
96
94
|
cols, // [{ type: string , align: l|c|r|null }]
|
97
95
|
envClasses, // align(ed|at|edat) | array | cases | cd | small | multline
|
98
|
-
|
96
|
+
autoTag, // boolean
|
99
97
|
singleRow, // boolean
|
100
98
|
emptySingleRow, // boolean
|
101
99
|
maxNumCols, // number
|
@@ -111,13 +109,6 @@ function parseArray(
|
|
111
109
|
// TODO: provide helpful error when \cr is used outside array environment
|
112
110
|
parser.gullet.macros.set("\\cr", "\\\\\\relax");
|
113
111
|
}
|
114
|
-
if (addEqnNum) {
|
115
|
-
parser.gullet.macros.set("\\tag", "\\@ifstar\\envtag@literal\\envtag@paren")
|
116
|
-
parser.gullet.macros.set("\\envtag@paren", "\\env@tag{{(\\text{#1})}}");
|
117
|
-
parser.gullet.macros.set("\\envtag@literal", "\\env@tag{\\text{#1}}")
|
118
|
-
parser.gullet.macros.set("\\notag", "\\env@notag");
|
119
|
-
parser.gullet.macros.set("\\nonumber", "\\env@notag")
|
120
|
-
}
|
121
112
|
|
122
113
|
// Start group for first cell
|
123
114
|
parser.gullet.beginGroup();
|
@@ -125,29 +116,39 @@ function parseArray(
|
|
125
116
|
let row = [];
|
126
117
|
const body = [row];
|
127
118
|
const rowGaps = [];
|
128
|
-
const
|
129
|
-
|
119
|
+
const labels = [];
|
120
|
+
|
130
121
|
const hLinesBeforeRow = [];
|
131
122
|
|
123
|
+
const tags = (autoTag != null ? [] : undefined);
|
124
|
+
|
125
|
+
// amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent
|
126
|
+
// whether this row should have an equation number. Simulate this with
|
127
|
+
// a \@eqnsw macro set to 1 or 0.
|
128
|
+
function beginRow() {
|
129
|
+
if (autoTag) {
|
130
|
+
parser.gullet.macros.set("\\@eqnsw", "1", true);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
function endRow() {
|
134
|
+
if (tags) {
|
135
|
+
if (parser.gullet.macros.get("\\df@tag")) {
|
136
|
+
tags.push(parser.subparse([new Token("\\df@tag")]));
|
137
|
+
parser.gullet.macros.set("\\df@tag", undefined, true);
|
138
|
+
} else {
|
139
|
+
tags.push(Boolean(autoTag) &&
|
140
|
+
parser.gullet.macros.get("\\@eqnsw") === "1");
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
beginRow();
|
145
|
+
|
132
146
|
// Test for \hline at the top of the array.
|
133
147
|
hLinesBeforeRow.push(getHLines(parser));
|
134
148
|
|
135
149
|
while (true) {
|
136
150
|
// Parse each cell in its own group (namespace)
|
137
151
|
let cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
|
138
|
-
|
139
|
-
if (addEqnNum && !rowTag) {
|
140
|
-
// Check if the author wrote a \tag{} inside this cell.
|
141
|
-
for (let i = 0; i < cell.length; i++) {
|
142
|
-
if (cell[i].type === "envTag" || cell[i].type === "noTag") {
|
143
|
-
// Get the contents of the \text{} nested inside the \env@Tag{}
|
144
|
-
rowTag = cell[i].type === "envTag"
|
145
|
-
? cell.splice(i, 1)[0].body.body[0]
|
146
|
-
: { body: null };
|
147
|
-
break
|
148
|
-
}
|
149
|
-
}
|
150
|
-
}
|
151
152
|
parser.gullet.endGroup();
|
152
153
|
parser.gullet.beginGroup();
|
153
154
|
|
@@ -176,6 +177,7 @@ function parseArray(
|
|
176
177
|
}
|
177
178
|
parser.consume();
|
178
179
|
} else if (next === "\\end") {
|
180
|
+
endRow()
|
179
181
|
// Arrays terminate newlines with `\crcr` which consumes a `\cr` if
|
180
182
|
// the last line is empty. However, AMS environments keep the
|
181
183
|
// empty row if it's the only one.
|
@@ -183,6 +185,7 @@ function parseArray(
|
|
183
185
|
if (row.length === 1 && cell.body.length === 0 && (body.length > 1 || !emptySingleRow)) {
|
184
186
|
body.pop();
|
185
187
|
}
|
188
|
+
labels.push(checkCellForLabels(cell.body))
|
186
189
|
if (hLinesBeforeRow.length < body.length + 1) {
|
187
190
|
hLinesBeforeRow.push([]);
|
188
191
|
}
|
@@ -198,16 +201,17 @@ function parseArray(
|
|
198
201
|
if (parser.gullet.future().text !== " ") {
|
199
202
|
size = parser.parseSizeGroup(true);
|
200
203
|
}
|
201
|
-
rowGaps.push(size ? size.value : null)
|
204
|
+
rowGaps.push(size ? size.value : null)
|
205
|
+
endRow()
|
202
206
|
|
203
|
-
|
207
|
+
labels.push(checkCellForLabels(cell.body))
|
204
208
|
|
205
209
|
// check for \hline(s) following the row separator
|
206
210
|
hLinesBeforeRow.push(getHLines(parser));
|
207
211
|
|
208
212
|
row = [];
|
209
|
-
rowTag = null;
|
210
213
|
body.push(row);
|
214
|
+
beginRow();
|
211
215
|
} else {
|
212
216
|
throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken);
|
213
217
|
}
|
@@ -218,8 +222,6 @@ function parseArray(
|
|
218
222
|
// End array group defining \cr
|
219
223
|
parser.gullet.endGroup();
|
220
224
|
|
221
|
-
tags.push(rowTag)
|
222
|
-
|
223
225
|
return {
|
224
226
|
type: "array",
|
225
227
|
mode: parser.mode,
|
@@ -228,9 +230,10 @@ function parseArray(
|
|
228
230
|
rowGaps,
|
229
231
|
hLinesBeforeRow,
|
230
232
|
envClasses,
|
231
|
-
|
233
|
+
autoTag,
|
232
234
|
scriptLevel,
|
233
235
|
tags,
|
236
|
+
labels,
|
234
237
|
leqno,
|
235
238
|
arraystretch,
|
236
239
|
arraycolsep
|
@@ -287,19 +290,43 @@ const mathmlBuilder = function(group, style) {
|
|
287
290
|
}
|
288
291
|
row.push(mtd)
|
289
292
|
}
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
293
|
+
const numColumns = group.body[0].length
|
294
|
+
// Fill out a short row with empty <mtd> elements.
|
295
|
+
for (let k = 0; k < numColumns - rw.length; k++) {
|
296
|
+
row.push(new mathMLTree.MathNode("mtd", [], style))
|
297
|
+
}
|
298
|
+
if (group.autoTag) {
|
299
|
+
const tag = group.tags[i];
|
300
|
+
let tagElement
|
301
|
+
if (tag === true) { // automatic numbering
|
302
|
+
tagElement = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])])
|
303
|
+
} else if (tag === false) {
|
304
|
+
// \nonumber/\notag or starred environment
|
305
|
+
tagElement = new mathMLTree.MathNode("mtext", [], [])
|
306
|
+
} else { // manual \tag
|
307
|
+
tagElement = mml.buildExpressionRow(tag[0].body, style.withLevel(cellLevel), true)
|
308
|
+
tagElement = mml.consolidateText(tagElement)
|
309
|
+
tagElement.classes = ["tml-tag"]
|
310
|
+
}
|
311
|
+
if (tagElement) {
|
312
|
+
row.unshift(glue(group))
|
313
|
+
row.push(glue(group))
|
314
|
+
if (group.leqno) {
|
315
|
+
row[0].children.push(tagElement)
|
316
|
+
row[0].classes.push("tml-left")
|
317
|
+
} else {
|
318
|
+
row[row.length - 1].children.push(tagElement)
|
319
|
+
row[row.length - 1].classes.push("tml-right")
|
320
|
+
}
|
300
321
|
}
|
301
322
|
}
|
302
323
|
const mtr = new mathMLTree.MathNode("mtr", row, [])
|
324
|
+
const label = group.labels.shift()
|
325
|
+
if (label && group.tags && group.tags[i]) {
|
326
|
+
mtr.setAttribute("id", label)
|
327
|
+
if (Array.isArray(group.tags[i])) { mtr.classes.push("tml-tageqn") }
|
328
|
+
}
|
329
|
+
|
303
330
|
// Write horizontal rules
|
304
331
|
if (i === 0 && hlines[0].length > 0) {
|
305
332
|
if (hlines[0].length === 2) {
|
@@ -323,16 +350,17 @@ const mathmlBuilder = function(group, style) {
|
|
323
350
|
}
|
324
351
|
|
325
352
|
if (group.envClasses.length > 0) {
|
326
|
-
let pad = group.envClasses.includes("jot")
|
327
|
-
? "0.7" // 0.5ex + 0.09em top & bot padding
|
328
|
-
: group.envClasses.includes("small")
|
329
|
-
? "0.35"
|
330
|
-
: "0.5" // 0.5ex default top & bot padding
|
331
353
|
if (group.arraystretch && group.arraystretch !== 1) {
|
332
354
|
// In LaTeX, \arraystretch is a factor applied to a 12pt strut height.
|
333
355
|
// It defines a baseline to baseline distance.
|
334
356
|
// Here, we do an approximation of that approach.
|
335
|
-
pad = String(1.4 * group.arraystretch - 0.8)
|
357
|
+
const pad = String(1.4 * group.arraystretch - 0.8) + "ex"
|
358
|
+
for (let i = 0; i < tbl.length; i++) {
|
359
|
+
for (let j = 0; j < tbl[i].children.length; j++) {
|
360
|
+
tbl[i].children[j].style.paddingTop = pad
|
361
|
+
tbl[i].children[j].style.paddingBottom = pad
|
362
|
+
}
|
363
|
+
}
|
336
364
|
}
|
337
365
|
let sidePadding = group.envClasses.includes("abut")
|
338
366
|
? "0"
|
@@ -346,7 +374,7 @@ const mathmlBuilder = function(group, style) {
|
|
346
374
|
let sidePadUnit = "em"
|
347
375
|
if (group.arraycolsep) {
|
348
376
|
const arraySidePad = calculateSize(group.arraycolsep, style)
|
349
|
-
sidePadding = arraySidePad.number
|
377
|
+
sidePadding = arraySidePad.number.toFixed(4)
|
350
378
|
sidePadUnit = arraySidePad.unit
|
351
379
|
}
|
352
380
|
|
@@ -357,18 +385,18 @@ const mathmlBuilder = function(group, style) {
|
|
357
385
|
if (j === numCols - 1 && hand === 1) { return "0" }
|
358
386
|
if (group.envClasses[0] !== "align") { return sidePadding }
|
359
387
|
if (hand === 1) { return "0" }
|
360
|
-
if (group.
|
388
|
+
if (group.autoTag) {
|
361
389
|
return (j % 2) ? "1" : "0"
|
362
390
|
} else {
|
363
391
|
return (j % 2) ? "0" : "1"
|
364
392
|
}
|
365
393
|
}
|
366
394
|
|
367
|
-
//
|
395
|
+
// Side padding
|
368
396
|
for (let i = 0; i < tbl.length; i++) {
|
369
397
|
for (let j = 0; j < tbl[i].children.length; j++) {
|
370
|
-
tbl[i].children[j].style.
|
371
|
-
|
398
|
+
tbl[i].children[j].style.paddingLeft = `${sidePad(j, 0)}${sidePadUnit}`
|
399
|
+
tbl[i].children[j].style.paddingRight = `${sidePad(j, 1)}${sidePadUnit}`
|
372
400
|
}
|
373
401
|
}
|
374
402
|
|
@@ -382,13 +410,13 @@ const mathmlBuilder = function(group, style) {
|
|
382
410
|
// TODO: Remove -webkit- when Chromium no longer needs it.
|
383
411
|
row.children[j].classes = ["tml-" + (j % 2 ? "left" : "right")]
|
384
412
|
}
|
385
|
-
if (group.
|
413
|
+
if (group.autoTag) {
|
386
414
|
const k = group.leqno ? 0 : row.children.length - 1
|
387
415
|
row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")]
|
388
416
|
}
|
389
417
|
}
|
390
418
|
if (row.children.length > 1 && group.envClasses.includes("cases")) {
|
391
|
-
row.children[1].style.
|
419
|
+
row.children[1].style.paddingLeft = "1em"
|
392
420
|
}
|
393
421
|
|
394
422
|
if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
|
@@ -408,9 +436,17 @@ const mathmlBuilder = function(group, style) {
|
|
408
436
|
}
|
409
437
|
|
410
438
|
let table = new mathMLTree.MathNode("mtable", tbl)
|
439
|
+
if (group.envClasses.length > 0) {
|
440
|
+
// Top & bottom padding
|
441
|
+
if (group.envClasses.includes("jot")) {
|
442
|
+
table.classes.push("tml-jot")
|
443
|
+
} else if (group.envClasses.includes("small")) {
|
444
|
+
table.classes.push("tml-small")
|
445
|
+
}
|
446
|
+
}
|
411
447
|
if (group.scriptLevel === "display") { table.setAttribute("displaystyle", "true") }
|
412
448
|
|
413
|
-
if (group.
|
449
|
+
if (group.autoTag || group.envClasses.includes("multline")) {
|
414
450
|
table.style.width = "100%"
|
415
451
|
}
|
416
452
|
|
@@ -440,7 +476,7 @@ const mathmlBuilder = function(group, style) {
|
|
440
476
|
row.children[0].style.borderLeft = sep
|
441
477
|
}
|
442
478
|
}
|
443
|
-
let iCol = group.
|
479
|
+
let iCol = group.autoTag ? 0 : -1
|
444
480
|
for (let i = iStart; i < iEnd; i++) {
|
445
481
|
if (cols[i].type === "align") {
|
446
482
|
const colAlign = alignMap[cols[i].align];
|
@@ -482,7 +518,7 @@ const mathmlBuilder = function(group, style) {
|
|
482
518
|
}
|
483
519
|
}
|
484
520
|
}
|
485
|
-
if (group.
|
521
|
+
if (group.autoTag) {
|
486
522
|
// allow for glue cells on each side
|
487
523
|
align = "left " + (align.length > 0 ? align : "center ") + "right "
|
488
524
|
}
|
@@ -506,13 +542,14 @@ const alignedHandler = function(context, args) {
|
|
506
542
|
if (context.envName.indexOf("ed") === -1) {
|
507
543
|
validateAmsEnvironmentContext(context);
|
508
544
|
}
|
545
|
+
const isSplit = context.envName === "split";
|
509
546
|
const cols = [];
|
510
547
|
const res = parseArray(
|
511
548
|
context.parser,
|
512
549
|
{
|
513
550
|
cols,
|
514
|
-
addEqnNum: context.envName === "align" || context.envName === "alignat",
|
515
551
|
emptySingleRow: true,
|
552
|
+
autoTag: isSplit ? undefined : getAutoTag(context.envName),
|
516
553
|
envClasses: ["abut", "jot"], // set row spacing & provisional column spacing
|
517
554
|
maxNumCols: context.envName === "split" ? 2 : undefined,
|
518
555
|
leqno: context.parser.settings.leqno
|
@@ -836,7 +873,7 @@ defineEnvironment({
|
|
836
873
|
const res = {
|
837
874
|
cols: [],
|
838
875
|
envClasses: ["abut", "jot"],
|
839
|
-
|
876
|
+
autoTag: getAutoTag(context.envName),
|
840
877
|
emptySingleRow: true,
|
841
878
|
leqno: context.parser.settings.leqno
|
842
879
|
};
|
@@ -854,7 +891,7 @@ defineEnvironment({
|
|
854
891
|
handler(context) {
|
855
892
|
validateAmsEnvironmentContext(context);
|
856
893
|
const res = {
|
857
|
-
|
894
|
+
autoTag: getAutoTag(context.envName),
|
858
895
|
emptySingleRow: true,
|
859
896
|
singleRow: true,
|
860
897
|
maxNumCols: 1,
|
@@ -875,7 +912,7 @@ defineEnvironment({
|
|
875
912
|
handler(context) {
|
876
913
|
validateAmsEnvironmentContext(context);
|
877
914
|
const res = {
|
878
|
-
|
915
|
+
autoTag: context.envName === "multline",
|
879
916
|
maxNumCols: 1,
|
880
917
|
envClasses: ["jot", "multline"],
|
881
918
|
leqno: context.parser.settings.leqno
|
package/src/environments/cd.js
CHANGED
package/src/functions/label.js
CHANGED
@@ -22,7 +22,7 @@ defineFunction({
|
|
22
22
|
// Return a no-width, no-ink element with an HTML id.
|
23
23
|
const node = new mathMLTree.MathNode("mrow", [], ["tml-label"])
|
24
24
|
if (group.string.length > 0) {
|
25
|
-
node.
|
25
|
+
node.setLabel(group.string)
|
26
26
|
}
|
27
27
|
return node
|
28
28
|
}
|
package/src/linebreaking.js
CHANGED
@@ -58,7 +58,7 @@ export default function setLineBreaks(expression, wrapMode, isDisplayMode) {
|
|
58
58
|
}
|
59
59
|
block.push(node);
|
60
60
|
if (node.type && node.type === "mo" && node.children.length === 1 &&
|
61
|
-
!Object.
|
61
|
+
!Object.prototype.hasOwnProperty.call(node.attributes, "movablelimits")) {
|
62
62
|
const ch = node.children[0].text
|
63
63
|
if (openDelims.indexOf(ch) > -1) {
|
64
64
|
level += 1
|
package/src/macros.js
CHANGED
@@ -463,8 +463,10 @@ defineMacro("\\tag@literal", (context) => {
|
|
463
463
|
if (context.macros.get("\\df@tag")) {
|
464
464
|
throw new ParseError("Multiple \\tag");
|
465
465
|
}
|
466
|
-
return "\\
|
466
|
+
return "\\gdef\\df@tag{\\text{#1}}";
|
467
467
|
});
|
468
|
+
defineMacro("\\notag", "\\nonumber");
|
469
|
+
defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}")
|
468
470
|
|
469
471
|
// \renewcommand{\bmod}{\nonscript\mskip-\medmuskip\mkern5mu\mathbin
|
470
472
|
// {\operator@font mod}\penalty900
|
package/src/mathMLTree.js
CHANGED
@@ -25,6 +25,7 @@ export class MathNode {
|
|
25
25
|
this.children = children || [];
|
26
26
|
this.classes = classes || [];
|
27
27
|
this.style = style || {}; // Used for <mstyle> elements
|
28
|
+
this.label = "";
|
28
29
|
}
|
29
30
|
|
30
31
|
/**
|
@@ -42,6 +43,10 @@ export class MathNode {
|
|
42
43
|
return this.attributes[name];
|
43
44
|
}
|
44
45
|
|
46
|
+
setLabel(value) {
|
47
|
+
this.label = value
|
48
|
+
}
|
49
|
+
|
45
50
|
/**
|
46
51
|
* Converts the math node into a MathML-namespaced DOM element.
|
47
52
|
*/
|
package/src/postProcess.js
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
* https://mit-license.org/
|
6
6
|
*/
|
7
7
|
|
8
|
-
export const version = "0.
|
8
|
+
export const version = "0.11.00";
|
9
9
|
|
10
10
|
export function postProcess(block) {
|
11
11
|
const labelMap = {}
|
@@ -21,15 +21,15 @@ export function postProcess(block) {
|
|
21
21
|
// No need to write a number into the text content of the element.
|
22
22
|
// A CSS counter has done that even if this postProcess() function is not used.
|
23
23
|
|
24
|
-
// Find any \label that refers to an AMS eqn number.
|
24
|
+
// Find any \label that refers to an AMS automatic eqn number.
|
25
25
|
while (true) {
|
26
|
+
if (parent.tagName === "mtable") { break }
|
26
27
|
const labels = parent.getElementsByClassName("tml-label")
|
27
28
|
if (labels.length > 0) {
|
28
|
-
parent.
|
29
|
-
labelMap[
|
29
|
+
const id = parent.attributes.id.value
|
30
|
+
labelMap[id] = String(i)
|
30
31
|
break
|
31
32
|
} else {
|
32
|
-
if (parent.tagName === "mtable") { break }
|
33
33
|
parent = parent.parentElement
|
34
34
|
}
|
35
35
|
}
|
@@ -42,7 +42,8 @@ export function postProcess(block) {
|
|
42
42
|
if (labels.length > 0) {
|
43
43
|
const tags = parent.getElementsByClassName("tml-tag")
|
44
44
|
if (tags.length > 0) {
|
45
|
-
|
45
|
+
const id = parent.attributes.id.value
|
46
|
+
labelMap[id] = tags[0].textContent
|
46
47
|
}
|
47
48
|
}
|
48
49
|
}
|
package/src/symbols.js
CHANGED
@@ -670,7 +670,7 @@ defineSymbol(math, mathord, "\u03db", "\\stigma", true);
|
|
670
670
|
defineSymbol(math, mathord, "\u2aeb", "\\Bot");
|
671
671
|
defineSymbol(math, bin, "\u2217", "\u2217", true);
|
672
672
|
defineSymbol(math, bin, "+", "+");
|
673
|
-
defineSymbol(math, bin, "
|
673
|
+
defineSymbol(math, bin, "\u2217", "*");
|
674
674
|
defineSymbol(math, bin, "\u2044", "/", true);
|
675
675
|
defineSymbol(math, bin, "\u2044", "\u2044");
|
676
676
|
defineSymbol(math, bin, "\u2212", "-", true);
|
package/temml.js
CHANGED
@@ -19,6 +19,7 @@ import { Span, TextNode } from "./src/domTree";
|
|
19
19
|
import { defineSymbol } from "./src/symbols";
|
20
20
|
import defineMacro from "./src/defineMacro";
|
21
21
|
import { postProcess, version } from "./src/postProcess";
|
22
|
+
import { renderMathInElement } from "./src/auto-render"
|
22
23
|
|
23
24
|
/**
|
24
25
|
* @type {import('./temml').render}
|
@@ -144,6 +145,11 @@ export default {
|
|
144
145
|
* for sending to the client.
|
145
146
|
*/
|
146
147
|
renderToString,
|
148
|
+
/**
|
149
|
+
* Finds all the math delimiters in a given element of a running HTML document
|
150
|
+
* and converts the contents of each instance into a <math> element.
|
151
|
+
*/
|
152
|
+
renderMathInElement,
|
147
153
|
/**
|
148
154
|
* Post-process an entire HTML block.
|
149
155
|
* Writes AMS auto-numbers and implements \ref{}.
|
@@ -1,89 +0,0 @@
|
|
1
|
-
# Auto-render extension
|
2
|
-
|
3
|
-
This is a client-side extension to automatically render all of the math inside of the
|
4
|
-
text of a running HTML document. It searches all of the text nodes in a given element
|
5
|
-
for the given delimiters, and renders the math in place.
|
6
|
-
|
7
|
-
|
8
|
-
This extension isn't part of Temml proper, so the script needs to be included
|
9
|
-
(via a `<script>` tag) in the page along with Temml itself. For example:
|
10
|
-
|
11
|
-
```html
|
12
|
-
<head>
|
13
|
-
...
|
14
|
-
<link rel="stylesheet" href="./Temml-Local.css">
|
15
|
-
<script src="./temml.min.js"></script>
|
16
|
-
<script src="./auto-render.min.js"></script>
|
17
|
-
...
|
18
|
-
</head>
|
19
|
-
<body>
|
20
|
-
...
|
21
|
-
<script>renderMathInElement(document.body);</script>
|
22
|
-
</body>
|
23
|
-
```
|
24
|
-
|
25
|
-
The auto-render extension exposes a single function, `window.renderMathInElement`, with
|
26
|
-
the following API:
|
27
|
-
|
28
|
-
```js
|
29
|
-
function renderMathInElement(elem, options)
|
30
|
-
```
|
31
|
-
|
32
|
-
`elem` is an HTML DOM element, typically `document.main`. The function will
|
33
|
-
recursively search for text nodes inside this element and render the math in them.
|
34
|
-
|
35
|
-
`options` is an optional object argument that can have the same keys as [the
|
36
|
-
options](https://temml.org/docs/en/administration.html#options) passed to
|
37
|
-
`temml.render`. In addition, there are five auto-render-specific keys:
|
38
|
-
|
39
|
-
- `delimiters`: This is a list of delimiters to look for math, processed in
|
40
|
-
the same order as the list. Each delimiter has three properties:
|
41
|
-
|
42
|
-
- `left`: A string which starts the math expression (i.e. the left delimiter).
|
43
|
-
- `right`: A string which ends the math expression (i.e. the right delimiter).
|
44
|
-
- `display`: A boolean of whether the math in the expression should be
|
45
|
-
rendered in display mode or not.
|
46
|
-
|
47
|
-
The default `delimiters` value is:
|
48
|
-
|
49
|
-
```js
|
50
|
-
[
|
51
|
-
{ left: "$$", right: "$$", display: true },
|
52
|
-
{ left: "\\(", right: "\\)", display: false },
|
53
|
-
{ left: "\\begin{equation}", right: "\\end{equation}", display: true },
|
54
|
-
{ left: "\\begin{align}", right: "\\end{align}", display: true },
|
55
|
-
{ left: "\\begin{alignat}", right: "\\end{alignat}", display: true },
|
56
|
-
{ left: "\\begin{gather}", right: "\\end{gather}", display: true },
|
57
|
-
{ left: "\\begin{CD}", right: "\\end{CD}", display: true },
|
58
|
-
{ left: "\\begin{multline}", right: "\\end{multline}", display: true },
|
59
|
-
{ left: "\\[", right: "\\]", display: true }
|
60
|
-
]
|
61
|
-
```
|
62
|
-
|
63
|
-
If you want to add support for inline math via `$…$`, be sure to list it
|
64
|
-
**after** `$$…$$`. Because rules are processed in order, putting a `$` rule first would
|
65
|
-
match `$$` and treat as an empty math expression. Here is an example that includes `$…$`:
|
66
|
-
|
67
|
-
```js
|
68
|
-
[
|
69
|
-
{left: "$$", right: "$$", display: true},
|
70
|
-
// Put $ after $$.
|
71
|
-
{left: "$", right: "$", display: false},
|
72
|
-
{left: "\\(", right: "\\)", display: false},
|
73
|
-
// Put \[ last to avoid conflict with possible future \\[1em] row separator.
|
74
|
-
{left: "\\[", right: "\\]", display: true}
|
75
|
-
]
|
76
|
-
```
|
77
|
-
|
78
|
-
- `ignoredTags`: This is a list of DOM node types to ignore when recursing
|
79
|
-
through. The default value is
|
80
|
-
`["script", "noscript", "style", "textarea", "pre", "code", "option"]`.
|
81
|
-
|
82
|
-
- `ignoredClasses`: This is a list of DOM node class names to ignore when
|
83
|
-
recursing through. By default, this value is not set.
|
84
|
-
|
85
|
-
- `errorCallback`: A callback method returning a message and an error stack
|
86
|
-
in case of an critical error during rendering. The default uses `console.error`.
|
87
|
-
|
88
|
-
- `preProcess`: A callback function, `(math: string) => string`, used to process
|
89
|
-
math expressions before rendering.
|