ed-mathml2tex 0.0.1
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 +47 -0
- package/lib/mathml2latex.browser.cjs.js +1027 -0
- package/lib/mathml2latex.browser.es.js +1025 -0
- package/lib/mathml2latex.browser.umd.js +1033 -0
- package/lib/mathml2latex.cjs.js +1027 -0
- package/lib/mathml2latex.es.js +1025 -0
- package/lib/mathml2latex.umd.js +1033 -0
- package/package.json +54 -0
|
@@ -0,0 +1,1033 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
4
|
+
(global = global || self, global.MathML2LaTeX = factory());
|
|
5
|
+
}(this, (function () { 'use strict';
|
|
6
|
+
|
|
7
|
+
const Brackets = {
|
|
8
|
+
left: ['(', '[', '{', '|', '‖', '⟨', '⌊', '⌈', '⌜'],
|
|
9
|
+
right: [')', ']', '}', '|', '‖', '⟩', '⌋', '⌉', '⌝'],
|
|
10
|
+
isPair: function(l, r){
|
|
11
|
+
const idx = this.left.indexOf(l);
|
|
12
|
+
return r === this.right[idx];
|
|
13
|
+
},
|
|
14
|
+
contains: function(it) {
|
|
15
|
+
return this.isLeft(it) || this.isRight(it);
|
|
16
|
+
},
|
|
17
|
+
isLeft: function(it) {
|
|
18
|
+
return this.left.indexOf(it) > -1
|
|
19
|
+
},
|
|
20
|
+
isRight: function(it) {
|
|
21
|
+
return this.right.indexOf(it) > -1;
|
|
22
|
+
},
|
|
23
|
+
parseLeft: function(it, stretchy = true) {
|
|
24
|
+
if(this.left.indexOf(it) < 0){ return it}
|
|
25
|
+
let r = '';
|
|
26
|
+
switch(it){
|
|
27
|
+
case '(':
|
|
28
|
+
case '[':
|
|
29
|
+
case '|': r = `\\left${it}`;
|
|
30
|
+
break;
|
|
31
|
+
case '‖': r = '\\left\\|';
|
|
32
|
+
break;
|
|
33
|
+
case '{': r = '\\left\\{';
|
|
34
|
+
break;
|
|
35
|
+
case '⟨': r = '\\left\\langle ';
|
|
36
|
+
break;
|
|
37
|
+
case '⌊': r = '\\left\\lfloor ';
|
|
38
|
+
break;
|
|
39
|
+
case '⌈': r = '\\left\\lceil ';
|
|
40
|
+
break;
|
|
41
|
+
case '⌜': r = '\\left\\ulcorner ';
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
return (stretchy ? r : r.replace('\\left', ''));
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
parseRight: function(it, stretchy = true) {
|
|
48
|
+
if(this.right.indexOf(it) < 0){ return it}
|
|
49
|
+
let r = '';
|
|
50
|
+
switch(it){
|
|
51
|
+
case ')':
|
|
52
|
+
case ']':
|
|
53
|
+
case '|': r = `\\right${it}`;
|
|
54
|
+
break;
|
|
55
|
+
case '‖': r = '\\right\\|';
|
|
56
|
+
break;
|
|
57
|
+
case '}': r = '\\right\\}';
|
|
58
|
+
break;
|
|
59
|
+
case '⟩': r = ' \\right\\rangle';
|
|
60
|
+
break;
|
|
61
|
+
case '⌋': r = ' \\right\\rfloor';
|
|
62
|
+
break;
|
|
63
|
+
case '⌉': r = ' \\right\\rceil';
|
|
64
|
+
break;
|
|
65
|
+
case '⌝': r = ' \\right\\urcorner';
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
return (stretchy ? r : r.replace('\\right', ''));
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
* Set up window for Node.js
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
const root = (typeof window !== 'undefined' ? window : {});
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Parsing HTML strings
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
function canParseHTMLNatively () {
|
|
83
|
+
const Parser = root.DOMParser;
|
|
84
|
+
let canParse = false;
|
|
85
|
+
|
|
86
|
+
// Adapted from https://gist.github.com/1129031
|
|
87
|
+
// Firefox/Opera/IE throw errors on unsupported types
|
|
88
|
+
try {
|
|
89
|
+
// WebKit returns null on unsupported types
|
|
90
|
+
if (new Parser().parseFromString('', 'text/html')) {
|
|
91
|
+
canParse = true;
|
|
92
|
+
}
|
|
93
|
+
} catch (e) {}
|
|
94
|
+
|
|
95
|
+
return canParse
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function createHTMLParser () {
|
|
99
|
+
const Parser = function () {};
|
|
100
|
+
|
|
101
|
+
if (typeof process !== 'undefined' && true) {
|
|
102
|
+
if (shouldUseActiveX()) {
|
|
103
|
+
Parser.prototype.parseFromString = function (string) {
|
|
104
|
+
const doc = new window.ActiveXObject('htmlfile');
|
|
105
|
+
doc.designMode = 'on'; // disable on-page scripts
|
|
106
|
+
doc.open();
|
|
107
|
+
doc.write(string);
|
|
108
|
+
doc.close();
|
|
109
|
+
return doc
|
|
110
|
+
};
|
|
111
|
+
} else {
|
|
112
|
+
Parser.prototype.parseFromString = function (string) {
|
|
113
|
+
const doc = document.implementation.createHTMLDocument('');
|
|
114
|
+
doc.open();
|
|
115
|
+
doc.write(string);
|
|
116
|
+
doc.close();
|
|
117
|
+
return doc
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
Parser.prototype.parseFromString = function (string) {
|
|
122
|
+
const doc = document.implementation.createHTMLDocument('');
|
|
123
|
+
doc.open();
|
|
124
|
+
doc.write(string);
|
|
125
|
+
doc.close();
|
|
126
|
+
return doc
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return Parser
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function shouldUseActiveX () {
|
|
133
|
+
let useActiveX = false;
|
|
134
|
+
try {
|
|
135
|
+
document.implementation.createHTMLDocument('').open();
|
|
136
|
+
} catch (e) {
|
|
137
|
+
if (window.ActiveXObject) useActiveX = true;
|
|
138
|
+
}
|
|
139
|
+
return useActiveX
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser();
|
|
143
|
+
|
|
144
|
+
const NodeTool = {
|
|
145
|
+
parseMath: function(html) {
|
|
146
|
+
const parser = new HTMLParser();
|
|
147
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
148
|
+
return doc.querySelector('math');
|
|
149
|
+
},
|
|
150
|
+
getChildren: function(node) {
|
|
151
|
+
return node.children;
|
|
152
|
+
},
|
|
153
|
+
getNodeName: function(node) {
|
|
154
|
+
return node.tagName.toLowerCase();
|
|
155
|
+
},
|
|
156
|
+
getNodeText: function(node) {
|
|
157
|
+
return node.textContent;
|
|
158
|
+
},
|
|
159
|
+
getAttr: function(node, attrName, defaultValue) {
|
|
160
|
+
const value = node.getAttribute(attrName);
|
|
161
|
+
if ( value === null) {
|
|
162
|
+
return defaultValue;
|
|
163
|
+
} else {
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
getPrevNode: function(node) {
|
|
168
|
+
return node.previousElementSibling;
|
|
169
|
+
},
|
|
170
|
+
getNextNode: function(node) {
|
|
171
|
+
return node.nextElementSibling;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// @see https://en.wikibooks.org/wiki/LaTeX/Mathematics#List_of_mathematical_symbols
|
|
176
|
+
// @see https://www.andy-roberts.net/res/writing/latex/symbols.pdf (more completed)
|
|
177
|
+
// @see http://www.rpi.edu/dept/arc/training/latex/LaTeX_symbols.pdf (wtf)
|
|
178
|
+
// https://oeis.org/wiki/List_of_LaTeX_mathematical_symbols
|
|
179
|
+
|
|
180
|
+
// accessed directly from keyboard
|
|
181
|
+
// + - = ! / ( ) [ ] < > | ' : *
|
|
182
|
+
|
|
183
|
+
const MathSymbol = {
|
|
184
|
+
parseIdentifier: function(it) {
|
|
185
|
+
if(it.length === 0){ return '' }
|
|
186
|
+
if(it.length === 1){
|
|
187
|
+
const charCode = it.charCodeAt(0);
|
|
188
|
+
// First check special math sets
|
|
189
|
+
let index = this.mathSets.decimals.indexOf(charCode);
|
|
190
|
+
if (index > -1) {
|
|
191
|
+
return this.mathSets.scripts[index] + ' ';
|
|
192
|
+
}
|
|
193
|
+
// Then check greek letters
|
|
194
|
+
index = this.greekLetter.decimals.indexOf(charCode);
|
|
195
|
+
if (index > -1) {
|
|
196
|
+
return this.greekLetter.scripts[index] + ' ';
|
|
197
|
+
}
|
|
198
|
+
return it;
|
|
199
|
+
} else {
|
|
200
|
+
return this.parseMathFunction(it);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
parseOperator: function(it) {
|
|
205
|
+
if(it.length === 0){ return ''}
|
|
206
|
+
// Handle backslash operator
|
|
207
|
+
if(it === '\\'){ return '\\setminus '}
|
|
208
|
+
if(it.length === 1){
|
|
209
|
+
const charCode = it.charCodeAt(0);
|
|
210
|
+
// First check special operators
|
|
211
|
+
let index = this.specialOperators.decimals.indexOf(charCode);
|
|
212
|
+
if (index > -1) {
|
|
213
|
+
return this.specialOperators.scripts[index] + ' ';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const opSymbols = [
|
|
217
|
+
this.bigCommand,
|
|
218
|
+
this.relation,
|
|
219
|
+
this.binaryOperation,
|
|
220
|
+
this.setAndLogic,
|
|
221
|
+
this.delimiter,
|
|
222
|
+
this.other
|
|
223
|
+
];
|
|
224
|
+
|
|
225
|
+
const padSpaceBothSide = [false, true, true, false, false, false];
|
|
226
|
+
|
|
227
|
+
for(let i = 0; i < opSymbols.length; i++){
|
|
228
|
+
const opSymbol = opSymbols[i];
|
|
229
|
+
const index = opSymbol.decimals.indexOf(charCode);
|
|
230
|
+
if(index > -1) {
|
|
231
|
+
if(padSpaceBothSide[i]){
|
|
232
|
+
return [' ', opSymbol.scripts[index], ' '].join('');
|
|
233
|
+
}else {
|
|
234
|
+
return opSymbol.scripts[index] + ' ';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return it;
|
|
239
|
+
} else {
|
|
240
|
+
return this.parseMathFunction(it);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
parseMathFunction: function (it) {
|
|
245
|
+
const marker = T.createMarker();
|
|
246
|
+
const replacements = [];
|
|
247
|
+
this.mathFunction.names.forEach((name, index) => {
|
|
248
|
+
const regExp = new RegExp(name, 'g');
|
|
249
|
+
if(it.match(regExp)){
|
|
250
|
+
replacements.push(this.mathFunction.scripts[index]);
|
|
251
|
+
it = it.replace(regExp, marker.next() + ' ');
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
return marker.replaceBack(it, replacements);
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
//FIXME COMPLETE ME
|
|
258
|
+
overScript: {
|
|
259
|
+
decimals: [9182, 8594],
|
|
260
|
+
templates: [
|
|
261
|
+
"\\overbrace{@v}",
|
|
262
|
+
"\\vec{@v}"
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
//FIXME COMPLETE ME
|
|
267
|
+
underScript: {
|
|
268
|
+
decimals: [9183],
|
|
269
|
+
templates: [
|
|
270
|
+
"\\underbrace{@v}"
|
|
271
|
+
]
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
// sum, integral...
|
|
275
|
+
bigCommand: {
|
|
276
|
+
decimals: [8721, 8719, 8720, 10753, 10754, 10752, 8899, 8898, 10756, 10758, 8897, 8896, 8747, 8750, 8748, 8749, 10764, 8747],
|
|
277
|
+
scripts: [
|
|
278
|
+
"\\sum",
|
|
279
|
+
"\\prod",
|
|
280
|
+
"\\coprod",
|
|
281
|
+
"\\bigoplus",
|
|
282
|
+
"\\bigotimes",
|
|
283
|
+
"\\bigodot",
|
|
284
|
+
"\\bigcup",
|
|
285
|
+
"\\bigcap",
|
|
286
|
+
"\\biguplus",
|
|
287
|
+
"\\bigsqcup",
|
|
288
|
+
"\\bigvee",
|
|
289
|
+
"\\bigwedge",
|
|
290
|
+
"\\int",
|
|
291
|
+
"\\oint",
|
|
292
|
+
"\\iint",
|
|
293
|
+
"\\iiint",
|
|
294
|
+
"\\iiiint",
|
|
295
|
+
"\\idotsint",
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
// mo
|
|
300
|
+
relation: {
|
|
301
|
+
decimals: [60, 62, 61, 8741, 8742, 8804, 8805, 8784, 8781, 8904, 8810, 8811, 8801, 8866, 8867, 8834, 8835, 8776, 8712, 8715, 8838, 8839, 8773, 8995, 8994, 8840, 8841, 8771, 8872, 8713, 8847, 8848, 126, 8764, 8869, 8739, 8849, 8850, 8733, 8826, 8827, 10927, 10928, 8800, 8738, 8737],
|
|
302
|
+
scripts: [
|
|
303
|
+
"<",
|
|
304
|
+
">",
|
|
305
|
+
"=",
|
|
306
|
+
"\\parallel",
|
|
307
|
+
"\\nparallel",
|
|
308
|
+
"\\leq",
|
|
309
|
+
"\\geq",
|
|
310
|
+
"\\doteq",
|
|
311
|
+
"\\asymp",
|
|
312
|
+
"\\bowtie",
|
|
313
|
+
"\\ll",
|
|
314
|
+
"\\gg",
|
|
315
|
+
"\\equiv",
|
|
316
|
+
"\\vdash",
|
|
317
|
+
"\\dashv",
|
|
318
|
+
"\\subset",
|
|
319
|
+
"\\supset",
|
|
320
|
+
"\\approx",
|
|
321
|
+
"\\in",
|
|
322
|
+
"\\ni",
|
|
323
|
+
"\\subseteq",
|
|
324
|
+
"\\supseteq",
|
|
325
|
+
"\\cong",
|
|
326
|
+
"\\smile",
|
|
327
|
+
"\\frown",
|
|
328
|
+
"\\nsubseteq",
|
|
329
|
+
"\\nsupseteq",
|
|
330
|
+
"\\simeq",
|
|
331
|
+
"\\models",
|
|
332
|
+
"\\notin",
|
|
333
|
+
"\\sqsubset",
|
|
334
|
+
"\\sqsupset",
|
|
335
|
+
"\\sim",
|
|
336
|
+
"\\sim",
|
|
337
|
+
"\\perp",
|
|
338
|
+
"\\mid",
|
|
339
|
+
"\\sqsubseteq",
|
|
340
|
+
"\\sqsupseteq",
|
|
341
|
+
"\\propto",
|
|
342
|
+
"\\prec",
|
|
343
|
+
"\\succ",
|
|
344
|
+
"\\preceq",
|
|
345
|
+
"\\succeq",
|
|
346
|
+
"\\neq",
|
|
347
|
+
"\\sphericalangle",
|
|
348
|
+
"\\measuredangle"
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
// complete
|
|
353
|
+
binaryOperation: {
|
|
354
|
+
decimals: [43, 45, 177, 8745, 8900, 8853, 8723, 8746, 9651, 8854, 215, 8846, 9661, 8855, 247, 8851, 9667, 8856, 8727, 8852, 9657, 8857, 8902, 8744, 9711, 8728, 8224, 8743, 8729, 8726, 8225, 8901, 8768, 10815],
|
|
355
|
+
scripts: [
|
|
356
|
+
"+",
|
|
357
|
+
"-",
|
|
358
|
+
"\\pm",
|
|
359
|
+
"\\cap",
|
|
360
|
+
"\\diamond",
|
|
361
|
+
"\\oplus",
|
|
362
|
+
"\\mp",
|
|
363
|
+
"\\cup",
|
|
364
|
+
"\\bigtriangleup",
|
|
365
|
+
"\\ominus",
|
|
366
|
+
"\\times",
|
|
367
|
+
"\\uplus",
|
|
368
|
+
"\\bigtriangledown",
|
|
369
|
+
"\\otimes",
|
|
370
|
+
"\\div",
|
|
371
|
+
"\\sqcap",
|
|
372
|
+
"\\triangleleft",
|
|
373
|
+
"\\oslash",
|
|
374
|
+
"\\ast",
|
|
375
|
+
"\\sqcup",
|
|
376
|
+
"\\triangleright",
|
|
377
|
+
"\\odot",
|
|
378
|
+
"\\star",
|
|
379
|
+
"\\vee",
|
|
380
|
+
"\\bigcirc",
|
|
381
|
+
"\\circ",
|
|
382
|
+
"\\dagger",
|
|
383
|
+
"\\wedge",
|
|
384
|
+
"\\bullet",
|
|
385
|
+
"\\setminus",
|
|
386
|
+
"\\ddagger",
|
|
387
|
+
"\\cdot",
|
|
388
|
+
"\\wr",
|
|
389
|
+
"\\amalg"
|
|
390
|
+
]
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
setAndLogic: {
|
|
394
|
+
decimals: [8707, 8594, 8594, 8708, 8592, 8592, 8704, 8614, 172, 10233, 8834, 8658, 10233, 8835, 8596, 8712, 10234, 8713, 8660, 8715, 8868, 8743, 8869, 8744, 8709, 8709],
|
|
395
|
+
scripts: [
|
|
396
|
+
"\\exists",
|
|
397
|
+
"\\rightarrow",
|
|
398
|
+
"\\to",
|
|
399
|
+
"\\nexists",
|
|
400
|
+
"\\leftarrow",
|
|
401
|
+
"\\gets",
|
|
402
|
+
"\\forall",
|
|
403
|
+
"\\mapsto",
|
|
404
|
+
"\\neg",
|
|
405
|
+
"\\implies",
|
|
406
|
+
"\\subset",
|
|
407
|
+
"\\Rightarrow",
|
|
408
|
+
"\\implies",
|
|
409
|
+
"\\supset",
|
|
410
|
+
"\\leftrightarrow",
|
|
411
|
+
"\\in",
|
|
412
|
+
"\\iff",
|
|
413
|
+
"\\notin",
|
|
414
|
+
"\\Leftrightarrow",
|
|
415
|
+
"\\ni",
|
|
416
|
+
"\\top",
|
|
417
|
+
"\\land",
|
|
418
|
+
"\\bot",
|
|
419
|
+
"\\lor",
|
|
420
|
+
"\\emptyset",
|
|
421
|
+
"\\varnothing"
|
|
422
|
+
]
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
delimiter: {
|
|
426
|
+
decimals: [124, 8739, 8214, 47, 8726, 123, 125, 10216, 10217, 8593, 8657, 8968, 8969, 8595, 8659, 8970, 8971],
|
|
427
|
+
scripts: [
|
|
428
|
+
"|",
|
|
429
|
+
"\\mid",
|
|
430
|
+
"\\|",
|
|
431
|
+
"/",
|
|
432
|
+
"\\backslash",
|
|
433
|
+
"\\{",
|
|
434
|
+
"\\}",
|
|
435
|
+
"\\langle",
|
|
436
|
+
"\\rangle",
|
|
437
|
+
"\\uparrow",
|
|
438
|
+
"\\Uparrow",
|
|
439
|
+
"\\lceil",
|
|
440
|
+
"\\rceil",
|
|
441
|
+
"\\downarrow",
|
|
442
|
+
"\\Downarrow",
|
|
443
|
+
"\\lfloor",
|
|
444
|
+
"\\rfloor"
|
|
445
|
+
]
|
|
446
|
+
},
|
|
447
|
+
|
|
448
|
+
greekLetter: {
|
|
449
|
+
decimals: [ 913, 945, 925, 957, 914, 946, 926, 958, 915, 947, 927, 959, 916, 948, 928, 960, 982, 917, 1013, 949, 929, 961, 1009, 918, 950, 931, 963, 962, 919, 951, 932, 964, 920, 952, 977, 933, 965, 921, 953, 934, 981, 966, 922, 954, 1008, 935, 967, 923, 955, 936, 968, 924, 956, 937, 969 ],
|
|
450
|
+
scripts: [
|
|
451
|
+
"A" , "\\alpha" ,
|
|
452
|
+
"N" , "\\nu" ,
|
|
453
|
+
"B" , "\\beta" ,
|
|
454
|
+
"\\Xi" , "\\xi" ,
|
|
455
|
+
"\\Gamma" , "\\gamma" ,
|
|
456
|
+
"O" , "o" ,
|
|
457
|
+
"\\Delta" , "\\delta" ,
|
|
458
|
+
"\\Pi" , "\\pi" , "\\varpi" ,
|
|
459
|
+
"E" , "\\epsilon" , "\\varepsilon" ,
|
|
460
|
+
"P" , "\\rho" , "\\varrho" ,
|
|
461
|
+
"Z" , "\\zeta" ,
|
|
462
|
+
"\\Sigma" , "\\sigma" , "\\varsigma" ,
|
|
463
|
+
"H" , "\\eta" ,
|
|
464
|
+
"T" , "\\tau" ,
|
|
465
|
+
"\\Theta" , "\\theta" , "\\vartheta" ,
|
|
466
|
+
"\\Upsilon" , "\\upsilon" ,
|
|
467
|
+
"I" , "\\iota" ,
|
|
468
|
+
"\\Phi" , "\\phi" , "\\varphi" ,
|
|
469
|
+
"K" , "\\kappa" , "\\varkappa" ,
|
|
470
|
+
"X" , "\\chi" ,
|
|
471
|
+
"\\Lambda" , "\\lambda" ,
|
|
472
|
+
"\\Psi" , "\\psi" ,
|
|
473
|
+
"M" , "\\mu" ,
|
|
474
|
+
"\\Omega" , "\\omega"
|
|
475
|
+
]
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
other: {
|
|
479
|
+
decimals: [8706, 305, 8476, 8711, 8501, 240, 567, 8465, 9723, 8502, 8463, 8467, 8472, 8734, 8503],
|
|
480
|
+
scripts: [
|
|
481
|
+
"\\partial",
|
|
482
|
+
"\\imath",
|
|
483
|
+
"\\Re",
|
|
484
|
+
"\\nabla",
|
|
485
|
+
"\\aleph",
|
|
486
|
+
"\\eth",
|
|
487
|
+
"\\jmath",
|
|
488
|
+
"\\Im",
|
|
489
|
+
"\\Box",
|
|
490
|
+
"\\beth",
|
|
491
|
+
"\\hbar",
|
|
492
|
+
"\\ell",
|
|
493
|
+
"\\wp",
|
|
494
|
+
"\\infty",
|
|
495
|
+
"\\gimel"
|
|
496
|
+
]
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
// complete
|
|
500
|
+
// Be careful, the order of these name matters (overlap situation).
|
|
501
|
+
mathFunction: {
|
|
502
|
+
|
|
503
|
+
names: [
|
|
504
|
+
"arcsin" , "sinh" , "sin" , "sec" ,
|
|
505
|
+
"arccos" , "cosh" , "cos" , "csc" ,
|
|
506
|
+
"arctan" , "tanh" , "tan" ,
|
|
507
|
+
"arccot" , "coth" , "cot" ,
|
|
508
|
+
|
|
509
|
+
"limsup" , "liminf" , "exp" , "ker" ,
|
|
510
|
+
"deg" , "gcd" , "lg" , "ln" ,
|
|
511
|
+
"Pr" , "sup" , "det" , "hom" ,
|
|
512
|
+
"lim" , "log" , "arg" , "dim" ,
|
|
513
|
+
"inf" , "max" , "min" ,
|
|
514
|
+
],
|
|
515
|
+
scripts: [
|
|
516
|
+
"\\arcsin" , "\\sinh" , "\\sin" , "\\sec" ,
|
|
517
|
+
"\\arccos" , "\\cosh" , "\\cos" , "\\csc" ,
|
|
518
|
+
"\\arctan" , "\\tanh" , "\\tan" ,
|
|
519
|
+
"\\arccot" , "\\coth" , "\\cot" ,
|
|
520
|
+
|
|
521
|
+
"\\limsup" , "\\liminf" , "\\exp" , "\\ker" ,
|
|
522
|
+
"\\deg" , "\\gcd" , "\\lg" , "\\ln" ,
|
|
523
|
+
"\\Pr" , "\\sup" , "\\det" , "\\hom" ,
|
|
524
|
+
"\\lim" , "\\log" , "\\arg" , "\\dim" ,
|
|
525
|
+
"\\inf" , "\\max" , "\\min" ,
|
|
526
|
+
]
|
|
527
|
+
},
|
|
528
|
+
|
|
529
|
+
// Add special operators section
|
|
530
|
+
specialOperators: {
|
|
531
|
+
decimals: [
|
|
532
|
+
8712, // ∈
|
|
533
|
+
8713, // ∉
|
|
534
|
+
8746, // ∪
|
|
535
|
+
8745, // ∩
|
|
536
|
+
92, // \
|
|
537
|
+
],
|
|
538
|
+
scripts: [
|
|
539
|
+
"\\in",
|
|
540
|
+
"\\notin",
|
|
541
|
+
"\\cup",
|
|
542
|
+
"\\cap",
|
|
543
|
+
"\\setminus"
|
|
544
|
+
]
|
|
545
|
+
},
|
|
546
|
+
|
|
547
|
+
// Update mathSets section
|
|
548
|
+
mathSets: {
|
|
549
|
+
decimals: [
|
|
550
|
+
8477, // ℝ
|
|
551
|
+
8484, // ℤ
|
|
552
|
+
8469, // ℕ
|
|
553
|
+
8474, // ℚ
|
|
554
|
+
8450, // ℂ
|
|
555
|
+
8709, // ∅
|
|
556
|
+
8734 // ∞
|
|
557
|
+
],
|
|
558
|
+
scripts: [
|
|
559
|
+
"\\mathbb{R}",
|
|
560
|
+
"\\mathbb{Z}",
|
|
561
|
+
"\\mathbb{N}",
|
|
562
|
+
"\\mathbb{Q}",
|
|
563
|
+
"\\mathbb{C}",
|
|
564
|
+
"\\emptyset",
|
|
565
|
+
"\\infty"
|
|
566
|
+
]
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
const T = {}; // Tool
|
|
571
|
+
T.createMarker = function() {
|
|
572
|
+
return {
|
|
573
|
+
idx: -1,
|
|
574
|
+
reReplace: /@\[\[(\d+)\]\]/mg,
|
|
575
|
+
next: function() {
|
|
576
|
+
return `@[[${++this.idx}]]`
|
|
577
|
+
},
|
|
578
|
+
replaceBack: function(str, replacements) {
|
|
579
|
+
return str.replace(this.reReplace, (match, p1) => {
|
|
580
|
+
const index = parseInt(p1);
|
|
581
|
+
return replacements[index];
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
function convert(mathmlHtml){
|
|
588
|
+
const math = NodeTool.parseMath(mathmlHtml);
|
|
589
|
+
return toLatex(parse(math));
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function toLatex(result) {
|
|
593
|
+
// binomial coefficients
|
|
594
|
+
result = result.replace(/\\left\(\\DELETE_BRACKET_L/g, '');
|
|
595
|
+
result = result.replace(/\\DELETE_BRACKET_R\\right\)/g, '');
|
|
596
|
+
result = result.replace(/\\DELETE_BRACKET_L/g, '');
|
|
597
|
+
result = result.replace(/\\DELETE_BRACKET_R/g, '');
|
|
598
|
+
return result;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
function parse(node) {
|
|
602
|
+
const children = NodeTool.getChildren(node);
|
|
603
|
+
if (!children || children.length === 0) {
|
|
604
|
+
return parseLeaf(node);
|
|
605
|
+
} else {
|
|
606
|
+
return parseContainer(node, children);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// @see https://www.w3.org/TR/MathML3/chapter7.html
|
|
611
|
+
function parseLeaf(node) {
|
|
612
|
+
let r = '';
|
|
613
|
+
const nodeName = NodeTool.getNodeName(node);
|
|
614
|
+
switch(nodeName){
|
|
615
|
+
case 'mi': r = parseElementMi(node);
|
|
616
|
+
break;
|
|
617
|
+
case 'mn': r = parseElementMn(node);
|
|
618
|
+
break;
|
|
619
|
+
case 'mo': r = parseOperator(node);
|
|
620
|
+
break;
|
|
621
|
+
case 'ms': r = parseElementMs(node);
|
|
622
|
+
break;
|
|
623
|
+
case 'mtext': r = parseElementMtext(node);
|
|
624
|
+
break;
|
|
625
|
+
case 'mglyph': r = parseElementMglyph(node);
|
|
626
|
+
break;
|
|
627
|
+
case 'mprescripts': r = '';
|
|
628
|
+
break;
|
|
629
|
+
case 'mspace': r = parseElementMspace();
|
|
630
|
+
case 'none': r = '\\:';
|
|
631
|
+
//TODO other usecase of 'none' ?
|
|
632
|
+
break;
|
|
633
|
+
default: r = escapeSpecialChars(NodeTool.getNodeText(node).trim());
|
|
634
|
+
break;
|
|
635
|
+
}
|
|
636
|
+
return r;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// operator token, mathematical operators
|
|
640
|
+
function parseOperator(node) {
|
|
641
|
+
let it = NodeTool.getNodeText(node).trim();
|
|
642
|
+
it = MathSymbol.parseOperator(it);
|
|
643
|
+
return escapeSpecialChars(it);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Math identifier
|
|
647
|
+
function parseElementMi(node){
|
|
648
|
+
let it = NodeTool.getNodeText(node).trim();
|
|
649
|
+
it = MathSymbol.parseIdentifier(it);
|
|
650
|
+
return escapeSpecialChars(it);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Math Number
|
|
654
|
+
function parseElementMn(node){
|
|
655
|
+
let it = NodeTool.getNodeText(node).trim();
|
|
656
|
+
return escapeSpecialChars(it);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Math String
|
|
660
|
+
function parseElementMs(node){
|
|
661
|
+
const content = NodeTool.getNodeText(node).trimRight();
|
|
662
|
+
const it = escapeSpecialChars(content);
|
|
663
|
+
return ['"', it, '"'].join('');
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// Math Text
|
|
667
|
+
function parseElementMtext(node){
|
|
668
|
+
const content = NodeTool.getNodeText(node);
|
|
669
|
+
const it = escapeSpecialChars(content);
|
|
670
|
+
return `\\text{${it}}`;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Math glyph (image)
|
|
674
|
+
function parseElementMglyph(node){
|
|
675
|
+
const it = ['"', NodeTool.getAttr(node, 'alt', ''), '"'].join('');
|
|
676
|
+
return escapeSpecialChars(it);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// TODO need or not
|
|
680
|
+
function parseElementMspace(node){
|
|
681
|
+
return '';
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
function escapeSpecialChars(text) {
|
|
685
|
+
const specialChars = /\$|%|_|&|#|\{|\}/g;
|
|
686
|
+
text = text.replace(specialChars, char => `\\${ char }`);
|
|
687
|
+
return text;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
function parseContainer(node, children) {
|
|
692
|
+
const render = getRender(node);
|
|
693
|
+
if(render){
|
|
694
|
+
return render(node, children);
|
|
695
|
+
} else {
|
|
696
|
+
throw new Error(`Couldn't get render function for container node: ${NodeTool.getNodeName(node)}`);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
function renderChildren(children) {
|
|
701
|
+
const parts = [];
|
|
702
|
+
let lefts = [];
|
|
703
|
+
Array.prototype.forEach.call(children, (node) => {
|
|
704
|
+
if(NodeTool.getNodeName(node) === 'mo'){
|
|
705
|
+
const op = NodeTool.getNodeText(node).trim();
|
|
706
|
+
if(Brackets.contains(op)){
|
|
707
|
+
let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
|
|
708
|
+
stretchy = ['', 'true'].indexOf(stretchy) > -1;
|
|
709
|
+
// 操作符是括號
|
|
710
|
+
if(Brackets.isRight(op)){
|
|
711
|
+
const nearLeft = lefts[lefts.length - 1];
|
|
712
|
+
if(nearLeft){
|
|
713
|
+
if(Brackets.isPair(nearLeft, op)){
|
|
714
|
+
parts.push(Brackets.parseRight(op, stretchy));
|
|
715
|
+
lefts.pop();
|
|
716
|
+
} else {
|
|
717
|
+
// some brackets left side is same as right side.
|
|
718
|
+
if(Brackets.isLeft(op)) {
|
|
719
|
+
parts.push(Brackets.parseLeft(op, stretchy));
|
|
720
|
+
lefts.push(op);
|
|
721
|
+
} else {
|
|
722
|
+
console.error("bracket not match");
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}else {
|
|
726
|
+
// some brackets left side is same as right side.
|
|
727
|
+
if(Brackets.isLeft(op)) {
|
|
728
|
+
parts.push(Brackets.parseLeft(op, stretchy));
|
|
729
|
+
lefts.push(op);
|
|
730
|
+
}else {
|
|
731
|
+
console.error("bracket not match");
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
} else {
|
|
735
|
+
parts.push(Brackets.parseLeft(op, stretchy));
|
|
736
|
+
lefts.push(op);
|
|
737
|
+
}
|
|
738
|
+
} else {
|
|
739
|
+
parts.push(parseOperator(node));
|
|
740
|
+
}
|
|
741
|
+
} else {
|
|
742
|
+
parts.push(parse(node));
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
// 這裏非常不嚴謹
|
|
746
|
+
if(lefts.length > 0){
|
|
747
|
+
for(let i=0; i < lefts.length; i++){
|
|
748
|
+
parts.push("\\right.");
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
lefts = undefined;
|
|
752
|
+
return parts;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
function getRender(node) {
|
|
757
|
+
let render = undefined;
|
|
758
|
+
const nodeName = NodeTool.getNodeName(node);
|
|
759
|
+
switch(nodeName){
|
|
760
|
+
case 'msub':
|
|
761
|
+
render = getRender_default("@1_{@2}");
|
|
762
|
+
break;
|
|
763
|
+
case 'msup':
|
|
764
|
+
render = getRender_default("@1^{@2}");
|
|
765
|
+
break;
|
|
766
|
+
case 'msubsup':
|
|
767
|
+
render = getRender_default("@1_{@2}^{@3}");
|
|
768
|
+
break;
|
|
769
|
+
case 'mover':
|
|
770
|
+
render = renderMover;
|
|
771
|
+
break;
|
|
772
|
+
case 'munder':
|
|
773
|
+
render = renderMunder;
|
|
774
|
+
break;
|
|
775
|
+
case 'munderover':
|
|
776
|
+
render = getRender_default("@1\\limits_{@2}^{@3}");
|
|
777
|
+
break;
|
|
778
|
+
case 'mmultiscripts':
|
|
779
|
+
render = renderMmultiscripts;
|
|
780
|
+
break;
|
|
781
|
+
case 'mroot':
|
|
782
|
+
render = getRender_default("\\sqrt[@2]{@1}");
|
|
783
|
+
break;
|
|
784
|
+
case 'msqrt':
|
|
785
|
+
render = getRender_joinSeparator("\\sqrt{@content}");
|
|
786
|
+
break;
|
|
787
|
+
case 'mtable':
|
|
788
|
+
render = renderTable;
|
|
789
|
+
break;
|
|
790
|
+
case 'mtr':
|
|
791
|
+
render = getRender_joinSeparator("@content \\\\ ", ' & ');
|
|
792
|
+
break;
|
|
793
|
+
case 'mtd':
|
|
794
|
+
render = getRender_joinSeparator("@content");
|
|
795
|
+
break;
|
|
796
|
+
case 'mfrac':
|
|
797
|
+
render = renderMfrac;
|
|
798
|
+
break;
|
|
799
|
+
case 'mfenced':
|
|
800
|
+
render = renderMfenced;
|
|
801
|
+
break;
|
|
802
|
+
case 'mi':
|
|
803
|
+
case 'mn':
|
|
804
|
+
case 'mo':
|
|
805
|
+
case 'ms':
|
|
806
|
+
case 'mtext':
|
|
807
|
+
// they may contains <mglyph>
|
|
808
|
+
render = getRender_joinSeparator("@content");
|
|
809
|
+
break;
|
|
810
|
+
case 'mphantom':
|
|
811
|
+
render = renderMphantom;
|
|
812
|
+
break;
|
|
813
|
+
default:
|
|
814
|
+
// math, mstyle, mrow
|
|
815
|
+
render = getRender_joinSeparator("@content");
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
return render;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
function renderTable(node, children) {
|
|
822
|
+
const template = "\\begin{matrix} @content \\end{matrix}";
|
|
823
|
+
const render = getRender_joinSeparator(template);
|
|
824
|
+
return render(node, children);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function renderMfrac(node, children){
|
|
828
|
+
const [linethickness, bevelled] = [
|
|
829
|
+
NodeTool.getAttr(node, 'linethickness', 'medium'),
|
|
830
|
+
NodeTool.getAttr(node, 'bevelled', 'false')
|
|
831
|
+
];
|
|
832
|
+
|
|
833
|
+
let render = null;
|
|
834
|
+
if(bevelled === 'true') {
|
|
835
|
+
render = getRender_default("{}^{@1}/_{@2}");
|
|
836
|
+
} else if(['0', '0px'].indexOf(linethickness) > -1) {
|
|
837
|
+
const [prevNode, nextNode] = [
|
|
838
|
+
NodeTool.getPrevNode(node),
|
|
839
|
+
NodeTool.getNextNode(node)
|
|
840
|
+
];
|
|
841
|
+
if((prevNode && NodeTool.getNodeText(prevNode).trim() === '(') &&
|
|
842
|
+
(nextNode && NodeTool.getNodeText(nextNode).trim() === ')')
|
|
843
|
+
) {
|
|
844
|
+
render = getRender_default("\\DELETE_BRACKET_L\\binom{@1}{@2}\\DELETE_BRACKET_R");
|
|
845
|
+
} else {
|
|
846
|
+
render = getRender_default("{}_{@2}^{@1}");
|
|
847
|
+
}
|
|
848
|
+
} else {
|
|
849
|
+
render = getRender_default("\\frac{@1}{@2}");
|
|
850
|
+
}
|
|
851
|
+
return render(node, children);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function renderMfenced(node, children){
|
|
855
|
+
const [open, close, separatorsStr] = [
|
|
856
|
+
NodeTool.getAttr(node, 'open', '('),
|
|
857
|
+
NodeTool.getAttr(node, 'close', ')'),
|
|
858
|
+
NodeTool.getAttr(node, 'separators', ',')
|
|
859
|
+
];
|
|
860
|
+
const [left, right] = [
|
|
861
|
+
Brackets.parseLeft(open),
|
|
862
|
+
Brackets.parseRight(close)
|
|
863
|
+
];
|
|
864
|
+
|
|
865
|
+
const separators = separatorsStr.split('').filter((c) => c.trim().length === 1);
|
|
866
|
+
const template = `${left}@content${right}`;
|
|
867
|
+
const render = getRender_joinSeparators(template, separators);
|
|
868
|
+
return render(node, children);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
function renderMmultiscripts(node, children) {
|
|
872
|
+
if(children.length === 0) { return '' }
|
|
873
|
+
let sepIndex = -1;
|
|
874
|
+
let mprescriptsNode = null;
|
|
875
|
+
Array.prototype.forEach.call(children, (node) => {
|
|
876
|
+
if(NodeTool.getNodeName(node) === 'mprescripts'){
|
|
877
|
+
mprescriptsNode = node;
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
if(mprescriptsNode) {
|
|
881
|
+
sepIndex = Array.prototype.indexOf.call(children, mprescriptsNode);
|
|
882
|
+
}
|
|
883
|
+
const parts = renderChildren(children);
|
|
884
|
+
|
|
885
|
+
const splitArray = (arr, index) => {
|
|
886
|
+
return [arr.slice(0, index), arr.slice(index + 1, arr.length)]
|
|
887
|
+
};
|
|
888
|
+
const renderScripts = (items) => {
|
|
889
|
+
if(items.length > 0) {
|
|
890
|
+
const subs = [];
|
|
891
|
+
const sups = [];
|
|
892
|
+
items.forEach((item, index) => {
|
|
893
|
+
// one render as sub script, one as super script
|
|
894
|
+
if((index + 1) % 2 === 0){
|
|
895
|
+
sups.push(item);
|
|
896
|
+
} else {
|
|
897
|
+
subs.push(item);
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
return [
|
|
901
|
+
(subs.length > 0 ? `_{${subs.join(' ')}}` : ''),
|
|
902
|
+
(sups.length > 0 ? `^{${sups.join(' ')}}` : '')
|
|
903
|
+
].join('');
|
|
904
|
+
} else {
|
|
905
|
+
return '';
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
const base = parts.shift();
|
|
909
|
+
let prevScripts = [];
|
|
910
|
+
let backScripts = [];
|
|
911
|
+
if(sepIndex === -1){
|
|
912
|
+
backScripts = parts;
|
|
913
|
+
} else {
|
|
914
|
+
[backScripts, prevScripts] = splitArray(parts, sepIndex - 1);
|
|
915
|
+
}
|
|
916
|
+
return [renderScripts(prevScripts), base, renderScripts(backScripts)].join('');
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function renderMover(node, children){
|
|
920
|
+
const nodes = flattenNodeTreeByNodeName(node, 'mover');
|
|
921
|
+
let result = undefined;
|
|
922
|
+
for(let i = 0; i < nodes.length - 1; i++) {
|
|
923
|
+
if(!result){ result = parse(nodes[i]); }
|
|
924
|
+
const over = parse(nodes[i + 1]);
|
|
925
|
+
const template = getMatchValueByChar({
|
|
926
|
+
decimals: MathSymbol.overScript.decimals,
|
|
927
|
+
values: MathSymbol.overScript.templates,
|
|
928
|
+
judgeChar: over,
|
|
929
|
+
defaultValue: "@1^{@2}"
|
|
930
|
+
});
|
|
931
|
+
result = renderTemplate(template.replace("@v", "@1"), [result, over]);
|
|
932
|
+
}
|
|
933
|
+
return result;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
function renderMunder(node, children){
|
|
937
|
+
const nodes = flattenNodeTreeByNodeName(node, 'munder');
|
|
938
|
+
let result = undefined;
|
|
939
|
+
for(let i = 0; i < nodes.length - 1; i++) {
|
|
940
|
+
if(!result){ result = parse(nodes[i]); }
|
|
941
|
+
const under = parse(nodes[i + 1]);
|
|
942
|
+
const template = getMatchValueByChar({
|
|
943
|
+
decimals: MathSymbol.underScript.decimals,
|
|
944
|
+
values: MathSymbol.underScript.templates,
|
|
945
|
+
judgeChar: under,
|
|
946
|
+
defaultValue: "@1\\limits_{@2}"
|
|
947
|
+
});
|
|
948
|
+
result = renderTemplate(template.replace("@v", "@1"), [result, under]);
|
|
949
|
+
}
|
|
950
|
+
return result;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
function flattenNodeTreeByNodeName(root, nodeName) {
|
|
954
|
+
let result = [];
|
|
955
|
+
const children = NodeTool.getChildren(root);
|
|
956
|
+
Array.prototype.forEach.call(children, (node) => {
|
|
957
|
+
if (NodeTool.getNodeName(node) === nodeName) {
|
|
958
|
+
result = result.concat(flattenNodeTreeByNodeName(node, nodeName));
|
|
959
|
+
} else {
|
|
960
|
+
result.push(node);
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
return result;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
function getMatchValueByChar(params) {
|
|
968
|
+
const {decimals, values, judgeChar, defaultValue=null} = params;
|
|
969
|
+
if (judgeChar && judgeChar.length === 1) {
|
|
970
|
+
const index = decimals.indexOf(judgeChar.charCodeAt(0));
|
|
971
|
+
if (index > -1) {
|
|
972
|
+
return values[index];
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return defaultValue;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mphantom
|
|
979
|
+
// FIXME :)
|
|
980
|
+
function renderMphantom(node, children) {
|
|
981
|
+
return '';
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
function getRender_default(template) {
|
|
987
|
+
return function(node, children) {
|
|
988
|
+
const parts = renderChildren(children);
|
|
989
|
+
return renderTemplate(template, parts)
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
function renderTemplate(template, values) {
|
|
994
|
+
return template.replace(/\@\d+/g, (m) => {
|
|
995
|
+
const idx = parseInt(m.substring(1, m.length)) - 1;
|
|
996
|
+
return values[idx];
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
function getRender_joinSeparator(template, separator = '') {
|
|
1001
|
+
return function(node, children) {
|
|
1002
|
+
const parts = renderChildren(children);
|
|
1003
|
+
return template.replace("@content", parts.join(separator));
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
function getRender_joinSeparators(template, separators) {
|
|
1008
|
+
return function(node, children) {
|
|
1009
|
+
const parts = renderChildren(children);
|
|
1010
|
+
let content = '';
|
|
1011
|
+
if(separators.length === 0){
|
|
1012
|
+
content = parts.join('');
|
|
1013
|
+
} else {
|
|
1014
|
+
content = parts.reduce((accumulator, part, index) => {
|
|
1015
|
+
accumulator += part;
|
|
1016
|
+
if(index < parts.length - 1){
|
|
1017
|
+
accumulator += (separators[index] || separators[separators.length - 1]);
|
|
1018
|
+
}
|
|
1019
|
+
return accumulator;
|
|
1020
|
+
}, '');
|
|
1021
|
+
}
|
|
1022
|
+
return template.replace("@content", content);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// Add exports at the end of file
|
|
1027
|
+
var mathml2latex = {
|
|
1028
|
+
convert: convert
|
|
1029
|
+
};
|
|
1030
|
+
|
|
1031
|
+
return mathml2latex;
|
|
1032
|
+
|
|
1033
|
+
})));
|