xmmath 1.0.8 → 1.0.9
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/dist/xmmath.es.js +2312 -613
- package/dist/xmmath.es.js.map +1 -1
- package/dist/xmmath.umd.js +1462 -2
- package/dist/xmmath.umd.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +4 -2
- package/src/emoji.json +1458 -0
- package/src/main.ts +762 -481
package/src/main.ts
CHANGED
|
@@ -28,13 +28,16 @@ const Segmenter = Intl.Segmenter;
|
|
|
28
28
|
const segmenter = new Segmenter("emoji", { granularity: "grapheme" });
|
|
29
29
|
|
|
30
30
|
type vtype = "" | "str" | "v" | "f" | "blank" | "group" | "group1" | "sharp"; // group1组合基本类型,提高优先级
|
|
31
|
-
type tree = { type: vtype; value: string; children?: tree; esc?: boolean }[];
|
|
31
|
+
type tree = { type: vtype; value: string; children?: tree; esc?: boolean; kh?: string; src?: string }[];
|
|
32
32
|
|
|
33
33
|
function ast(str: string) {
|
|
34
34
|
let v = /[a-zA-Z]/;
|
|
35
|
-
let kh = /[\(\)]/;
|
|
36
|
-
|
|
35
|
+
let kh = /[\(\)\{\}\[\]]/;
|
|
36
|
+
const khl = /[\(\{\[]/;
|
|
37
|
+
const khr = /[\)\}\]]/;
|
|
38
|
+
let blank = /^[ \t\n\r]+$/;
|
|
37
39
|
let type: vtype = "";
|
|
40
|
+
let ignore: false | "line" | "block" = false;
|
|
38
41
|
let o: tree = [];
|
|
39
42
|
let p_tree: { tree: tree; close: boolean }[] = [];
|
|
40
43
|
let now_tree = o;
|
|
@@ -49,8 +52,9 @@ function ast(str: string) {
|
|
|
49
52
|
let rkh_stack: number[] = [];
|
|
50
53
|
for (let i = 0; i < str.length; i++) {
|
|
51
54
|
const t = str[i];
|
|
55
|
+
const last = str[i - 1];
|
|
52
56
|
// 字符
|
|
53
|
-
if (t
|
|
57
|
+
if (t === '"' && last != "\\" && !ignore) {
|
|
54
58
|
if (type != "str") {
|
|
55
59
|
type = "str";
|
|
56
60
|
} else {
|
|
@@ -58,31 +62,71 @@ function ast(str: string) {
|
|
|
58
62
|
}
|
|
59
63
|
continue;
|
|
60
64
|
}
|
|
61
|
-
if (type
|
|
65
|
+
if (type === "str") {
|
|
62
66
|
continue;
|
|
67
|
+
} else {
|
|
68
|
+
const next = str[i + 1];
|
|
69
|
+
if (t === "/" && next === "/") ignore = "line";
|
|
70
|
+
if (ignore === "line" && t === "\n") {
|
|
71
|
+
i++;
|
|
72
|
+
ignore = false;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (t === "/" && next === "*") ignore = "block";
|
|
76
|
+
if (ignore === "block" && t === "*" && next === "/") {
|
|
77
|
+
i++;
|
|
78
|
+
ignore = false;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
63
81
|
}
|
|
64
82
|
|
|
65
|
-
if (t
|
|
83
|
+
if (t.match(khl) && !ignore && last != "\\") {
|
|
66
84
|
lkh_stack.push(i);
|
|
67
85
|
}
|
|
68
|
-
if (t
|
|
69
|
-
if (lkh_stack.length
|
|
86
|
+
if (t.match(khr) && !ignore && last != "\\") {
|
|
87
|
+
if (lkh_stack.length === 0) {
|
|
70
88
|
rkh_stack.push(i);
|
|
71
89
|
} else {
|
|
72
|
-
|
|
90
|
+
lkh_stack.pop();
|
|
73
91
|
}
|
|
74
92
|
}
|
|
75
93
|
}
|
|
94
|
+
ignore = false;
|
|
95
|
+
|
|
96
|
+
let strl = init_c.emoji ? init_c.emoji(str) : Array.from(segmenter.segment(str)).map((w) => w.segment);
|
|
97
|
+
let strl2 = [];
|
|
98
|
+
for (let i of strl) {
|
|
99
|
+
if (i.length > 1 && i.includes(",")) strl2.push(...i);
|
|
100
|
+
else strl2.push(i);
|
|
101
|
+
}
|
|
102
|
+
strl = strl2;
|
|
76
103
|
|
|
77
|
-
let strl = init_c.emoji
|
|
78
|
-
? typeof init_c.emoji === "boolean"
|
|
79
|
-
? Array.from(segmenter.segment(str)).map((w) => w.segment)
|
|
80
|
-
: init_c.emoji(str)
|
|
81
|
-
: [...str];
|
|
82
104
|
for (let i = 0; i < strl.length; i++) {
|
|
83
105
|
const t = strl[i];
|
|
106
|
+
const next = strl[i + 1];
|
|
107
|
+
// 注释
|
|
108
|
+
if (t === "/" && next === "/") ignore = "line";
|
|
109
|
+
if (ignore === "line" && t === "\n") {
|
|
110
|
+
i++;
|
|
111
|
+
ignore = false;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (t === "/" && next === "*") ignore = "block";
|
|
115
|
+
if (ignore === "block" && t === "*" && next === "/") {
|
|
116
|
+
i++;
|
|
117
|
+
ignore = false;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (ignore) continue;
|
|
122
|
+
|
|
123
|
+
// 空白
|
|
124
|
+
if (type === "blank" && !t.match(blank)) {
|
|
125
|
+
now_tree.push({ type, value: "" });
|
|
126
|
+
type = "";
|
|
127
|
+
}
|
|
84
128
|
// 字符
|
|
85
|
-
if (t
|
|
129
|
+
if (t === '"' && strl[i - 1] != "\\") {
|
|
86
130
|
if (type != "str") {
|
|
87
131
|
type = "str";
|
|
88
132
|
} else {
|
|
@@ -101,13 +145,9 @@ function ast(str: string) {
|
|
|
101
145
|
if (t.match(blank)) {
|
|
102
146
|
type = "blank";
|
|
103
147
|
}
|
|
104
|
-
if (type == "blank" && !t.match(blank)) {
|
|
105
|
-
now_tree.push({ type, value: "" });
|
|
106
|
-
type = "";
|
|
107
|
-
}
|
|
108
148
|
|
|
109
149
|
if (t === "#") {
|
|
110
|
-
now_tree.push({ type: "sharp", value:
|
|
150
|
+
now_tree.push({ type: "sharp", value: "" });
|
|
111
151
|
continue;
|
|
112
152
|
}
|
|
113
153
|
|
|
@@ -139,22 +179,27 @@ function ast(str: string) {
|
|
|
139
179
|
tmp_str = "";
|
|
140
180
|
}
|
|
141
181
|
|
|
142
|
-
if (t
|
|
143
|
-
if (
|
|
182
|
+
if (t.match(khl)) {
|
|
183
|
+
if (strl[i - 1] === "\\") {
|
|
184
|
+
now_tree.push({ type: "v", value: t, esc: true });
|
|
185
|
+
} else if (lkh_stack.includes(i)) {
|
|
144
186
|
now_tree.push({ type: "v", value: t });
|
|
145
187
|
} else {
|
|
146
188
|
p_tree.push({ tree: now_tree, close: false });
|
|
147
|
-
now_tree.push({ type: "group", value: tmp_str, children: [] });
|
|
189
|
+
now_tree.push({ type: "group", value: tmp_str, children: [], kh: t });
|
|
148
190
|
now_tree = now_tree.at(-1).children;
|
|
149
191
|
tmp_str = "";
|
|
150
192
|
continue;
|
|
151
193
|
}
|
|
152
194
|
}
|
|
153
|
-
if (t
|
|
154
|
-
if (
|
|
155
|
-
|
|
195
|
+
if (t.match(khr)) {
|
|
196
|
+
if (strl[i - 1] === "\\") {
|
|
197
|
+
now_tree.push({ type: "v", value: t, esc: true });
|
|
198
|
+
} else if (p_tree.at(-1)) {
|
|
199
|
+
if (p_tree.at(-1).close === false) {
|
|
156
200
|
p_tree.at(-1).close = true;
|
|
157
201
|
now_tree = p_tree.at(-1).tree;
|
|
202
|
+
now_tree.at(-1).kh += t;
|
|
158
203
|
p_tree.pop();
|
|
159
204
|
continue;
|
|
160
205
|
}
|
|
@@ -172,33 +217,42 @@ import symbols from "./symbols.json?raw";
|
|
|
172
217
|
let s = JSON.parse(symbols);
|
|
173
218
|
|
|
174
219
|
// symbols路径简写
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
let
|
|
193
|
-
|
|
194
|
-
|
|
220
|
+
|
|
221
|
+
function simple_dot(s: any) {
|
|
222
|
+
const ss: { [id: string]: string } = {};
|
|
223
|
+
for (let i in s) {
|
|
224
|
+
if (typeof s[i] == "string") {
|
|
225
|
+
ss[i] = s[i];
|
|
226
|
+
} else {
|
|
227
|
+
for (let objOrStr of s[i]) {
|
|
228
|
+
// 第二层的array
|
|
229
|
+
if (typeof objOrStr == "string") {
|
|
230
|
+
ss[i] = objOrStr;
|
|
231
|
+
} else {
|
|
232
|
+
if (!ss[i]) ss[i] = objOrStr[Object.keys(objOrStr)[0]];
|
|
233
|
+
for (let j in objOrStr) {
|
|
234
|
+
// 第三层的obj
|
|
235
|
+
ss[`${i}.${j}`] = objOrStr[j];
|
|
236
|
+
// 允许部分索引,但要保证唯一
|
|
237
|
+
let l = j.split(".");
|
|
238
|
+
for (let n = 1; n < l.length; n++) {
|
|
239
|
+
let shotKey = l.slice(0, n).join(".");
|
|
240
|
+
if (!objOrStr[shotKey]) {
|
|
241
|
+
ss[`${i}.${shotKey}`] = objOrStr[j];
|
|
242
|
+
}
|
|
195
243
|
}
|
|
196
244
|
}
|
|
197
245
|
}
|
|
198
246
|
}
|
|
199
247
|
}
|
|
200
248
|
}
|
|
249
|
+
return ss;
|
|
201
250
|
}
|
|
251
|
+
let ss = simple_dot(s);
|
|
252
|
+
|
|
253
|
+
import emoji from "./emoji.json?raw";
|
|
254
|
+
/** @see https://github.com/typst/typst/blob/v0.11.1/crates/typst/src/symbols/emoji.rs */
|
|
255
|
+
let emojix = simple_dot(JSON.parse(emoji));
|
|
202
256
|
|
|
203
257
|
let shorthand = {
|
|
204
258
|
"->": "arrow.r",
|
|
@@ -251,33 +305,50 @@ for (let i in shorthand) {
|
|
|
251
305
|
}
|
|
252
306
|
}
|
|
253
307
|
|
|
254
|
-
const delimPair = {
|
|
308
|
+
const delimPair = {
|
|
309
|
+
"(": ["(", ")"],
|
|
310
|
+
"[": ["[", "]"],
|
|
311
|
+
"{": ["{", "}"],
|
|
312
|
+
"|": ["|", "|"],
|
|
313
|
+
"||": ["‖", "‖"],
|
|
314
|
+
"": ["", ""],
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
function delim(dic: fdic, _default: string) {
|
|
318
|
+
const d = get_value(dic, "delim") as string;
|
|
319
|
+
let x = "";
|
|
320
|
+
if (d !== null)
|
|
321
|
+
if (d === undefined) x = _default;
|
|
322
|
+
else x = d;
|
|
323
|
+
return delimPair[x] as [string, string];
|
|
324
|
+
}
|
|
255
325
|
|
|
256
326
|
let f: {
|
|
257
|
-
[name: string]: (attr
|
|
327
|
+
[name: string]: (attr: tree[], dic?: fdic, e?: fonts) => MathMLElement | DocumentFragment;
|
|
258
328
|
} = {
|
|
259
|
-
accent: (attr: tree[], dic: fdic) => {
|
|
329
|
+
accent: (attr: tree[], dic: fdic, e) => {
|
|
260
330
|
let base = createMath("mrow");
|
|
261
|
-
base.append(render(attr[0]));
|
|
331
|
+
base.append(render(attr[0], e));
|
|
262
332
|
let a = createMath("mrow");
|
|
263
|
-
a.append(render(attr[1]));
|
|
333
|
+
a.append(render(attr[1], e));
|
|
334
|
+
a.children[0].innerHTML = accent_match_str(a.children[0].innerHTML);
|
|
264
335
|
let over = createMath("mover");
|
|
265
336
|
over.setAttribute("accent", "true");
|
|
266
337
|
over.append(base, a);
|
|
267
338
|
return over;
|
|
268
339
|
},
|
|
269
|
-
attach: (attr: tree[], dic: fdic) => {
|
|
340
|
+
attach: (attr: tree[], dic: fdic, e) => {
|
|
270
341
|
let base = createMath("mrow");
|
|
271
342
|
base.append(render(attr[0]));
|
|
272
343
|
let el: MathMLElement;
|
|
273
344
|
let tl = createMath("mrow");
|
|
274
|
-
if (dic.tl) tl.append(render(dic.tl));
|
|
345
|
+
if (dic.tl) tl.append(render(dic.tl, e));
|
|
275
346
|
let bl = createMath("mrow");
|
|
276
|
-
if (dic.bl) bl.append(render(dic.bl));
|
|
347
|
+
if (dic.bl) bl.append(render(dic.bl, e));
|
|
277
348
|
let tr = createMath("mrow");
|
|
278
|
-
if (dic.tr) tr.append(render(dic.tr));
|
|
349
|
+
if (dic.tr) tr.append(render(dic.tr, e));
|
|
279
350
|
let br = createMath("mrow");
|
|
280
|
-
if (dic.br) br.append(render(dic.br));
|
|
351
|
+
if (dic.br) br.append(render(dic.br, e));
|
|
281
352
|
if (dic.tl || dic.bl || dic.tr || dic.br) {
|
|
282
353
|
if (dic.tl || dic.bl) {
|
|
283
354
|
el = createMath("mmultiscripts");
|
|
@@ -301,28 +372,28 @@ let f: {
|
|
|
301
372
|
uo.append(el);
|
|
302
373
|
}
|
|
303
374
|
let t = createMath("mrow");
|
|
304
|
-
if (dic.t) t.append(render(dic.t));
|
|
375
|
+
if (dic.t) t.append(render(dic.t, e));
|
|
305
376
|
let b = createMath("mrow");
|
|
306
|
-
if (dic.b) b.append(render(dic.b));
|
|
377
|
+
if (dic.b) b.append(render(dic.b, e));
|
|
307
378
|
uo.append(b, t);
|
|
308
379
|
el = uo;
|
|
309
380
|
}
|
|
310
381
|
return el;
|
|
311
382
|
},
|
|
312
|
-
scripts: (attr: tree[], dic: fdic) => {
|
|
313
|
-
return render(attr[0]);
|
|
383
|
+
scripts: (attr: tree[], dic: fdic, e) => {
|
|
384
|
+
return render(attr[0], e);
|
|
314
385
|
},
|
|
315
|
-
limits: (attr: tree[], dic: fdic) => {
|
|
316
|
-
return render(attr[0]);
|
|
386
|
+
limits: (attr: tree[], dic: fdic, e) => {
|
|
387
|
+
return render(attr[0], e);
|
|
317
388
|
},
|
|
318
|
-
binom: (attr: tree[], dic: fdic) => {
|
|
389
|
+
binom: (attr: tree[], dic: fdic, e) => {
|
|
319
390
|
let row = createMath("mrow");
|
|
320
391
|
let a = createMath("mrow");
|
|
321
|
-
a.append(render(attr[0]));
|
|
392
|
+
a.append(render(attr[0], e));
|
|
322
393
|
let b = createMath("mrow");
|
|
323
394
|
const s: tree = [];
|
|
324
395
|
for (let x of attr.slice(1)) s.push(...x, dh);
|
|
325
|
-
b.append(render(s.slice(0, -1)));
|
|
396
|
+
b.append(render(s.slice(0, -1), e));
|
|
326
397
|
let f = createMath("mfrac", null, { linethickness: "0" });
|
|
327
398
|
f.append(a, b);
|
|
328
399
|
let l = createMath("mo", "(");
|
|
@@ -330,7 +401,7 @@ let f: {
|
|
|
330
401
|
row.append(l, f, r);
|
|
331
402
|
return row;
|
|
332
403
|
},
|
|
333
|
-
cancel: (attr: tree[], dic: fdic) => {
|
|
404
|
+
cancel: (attr: tree[], dic: fdic, e) => {
|
|
334
405
|
let r = createMath("mrow");
|
|
335
406
|
const bg = (x: boolean) =>
|
|
336
407
|
`linear-gradient(to ${
|
|
@@ -345,85 +416,74 @@ let f: {
|
|
|
345
416
|
s = bg(true);
|
|
346
417
|
}
|
|
347
418
|
r.style.backgroundImage = s;
|
|
348
|
-
r.append(render(attr[0]));
|
|
419
|
+
r.append(render(attr[0], e));
|
|
349
420
|
return r;
|
|
350
421
|
},
|
|
351
|
-
cases: (attr: tree[], dic: fdic) => {
|
|
422
|
+
cases: (attr: tree[], dic: fdic, e) => {
|
|
352
423
|
let r = createMath("mrow");
|
|
353
|
-
const d = dic
|
|
354
|
-
let t = f.x_table(attr, { cases: [] }) as MathMLElement;
|
|
355
|
-
const gap = dic
|
|
424
|
+
const d = delim(dic, "{");
|
|
425
|
+
let t = f.x_table(attr, { cases: [] }, e) as MathMLElement;
|
|
426
|
+
const gap = (get_value(dic, "gap") as string) || "0.5em";
|
|
356
427
|
t.setAttribute("rowspacing", gap);
|
|
357
428
|
if (is_true(dic?.reverse)) {
|
|
358
|
-
const l = createMath("mo",
|
|
429
|
+
const l = createMath("mo", d[1]);
|
|
359
430
|
r.append(t, l);
|
|
360
431
|
} else {
|
|
361
|
-
const l = createMath("mo", d);
|
|
432
|
+
const l = createMath("mo", d[0]);
|
|
362
433
|
r.append(l, t);
|
|
363
434
|
}
|
|
364
435
|
return r;
|
|
365
436
|
},
|
|
366
|
-
frac: (attr: tree[], dic: fdic) => {
|
|
367
|
-
console.log(attr);
|
|
368
|
-
|
|
437
|
+
frac: (attr: tree[], dic: fdic, e) => {
|
|
369
438
|
let a = createMath("mrow");
|
|
370
|
-
a.append(render(attr[0]));
|
|
439
|
+
a.append(render(attr[0], e));
|
|
371
440
|
let b = createMath("mrow");
|
|
372
|
-
b.append(render(attr[1]));
|
|
441
|
+
b.append(render(attr[1], e));
|
|
373
442
|
let f = createMath("mfrac");
|
|
374
443
|
f.append(a, b);
|
|
375
444
|
return f;
|
|
376
445
|
},
|
|
377
|
-
lr: (attr: tree[], dic: fdic) => {
|
|
378
|
-
let list = attr
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
start = { c: [el], n: i };
|
|
384
|
-
break;
|
|
385
|
-
}
|
|
386
|
-
for (let i = list.length - 1; i >= 0; i--) {
|
|
387
|
-
const el = list[i];
|
|
388
|
-
if (el.type == "blank") continue;
|
|
389
|
-
end = { c: [el], n: i };
|
|
390
|
-
break;
|
|
391
|
-
}
|
|
392
|
-
const size = dic?.size?.[0]?.value;
|
|
393
|
-
const l = render(start.c);
|
|
394
|
-
const r = render(end.c);
|
|
395
|
-
if (size && size != "auto") {
|
|
396
|
-
const lm = l.querySelector("mo");
|
|
397
|
-
const rm = r.querySelector("mo");
|
|
398
|
-
lm.setAttribute("maxsize", size);
|
|
399
|
-
lm.setAttribute("minsize", size);
|
|
400
|
-
rm.setAttribute("maxsize", size);
|
|
401
|
-
rm.setAttribute("minsize", size);
|
|
402
|
-
}
|
|
403
|
-
const c = render(list.slice(start.n + 1, end.n));
|
|
446
|
+
lr: (attr: tree[], dic: fdic, e) => {
|
|
447
|
+
let list = attr_join(attr.map((i) => transfer_kh(i)));
|
|
448
|
+
const tList = trim(list);
|
|
449
|
+
|
|
450
|
+
const size = get_value(dic, "size") as string;
|
|
451
|
+
const c = render(tList, e);
|
|
404
452
|
const row = createMath("mrow");
|
|
405
|
-
row.append(
|
|
453
|
+
row.append(c);
|
|
454
|
+
if (size && size != "auto") {
|
|
455
|
+
const lm = row.children[0];
|
|
456
|
+
const rm = row.children[row.children.length - 1];
|
|
457
|
+
lm?.setAttribute("maxsize", size);
|
|
458
|
+
lm?.setAttribute("minsize", size);
|
|
459
|
+
rm?.setAttribute("maxsize", size);
|
|
460
|
+
rm?.setAttribute("minsize", size);
|
|
461
|
+
}
|
|
406
462
|
return row;
|
|
407
463
|
},
|
|
408
464
|
mid: (attr: tree[], dic: fdic) => {
|
|
409
465
|
const o = createMath("mo", attr?.[0]?.[0]?.value, { stretchy: "true" });
|
|
410
466
|
return o;
|
|
411
467
|
},
|
|
412
|
-
mat: (attr: tree[], dic: fdic,
|
|
413
|
-
let d = dic
|
|
414
|
-
let o = { "(": ["(", ")"], "[": ["[", "]"], "{": ["{", "}"], "|": ["|", "|"], "||": ["‖", "‖"] };
|
|
468
|
+
mat: (attr: tree[] | tree[][], dic: fdic, e) => {
|
|
469
|
+
let d = delim(dic, "(");
|
|
415
470
|
let row = createMath("mrow");
|
|
416
|
-
let l = createMath("mo",
|
|
417
|
-
let r = createMath("mo",
|
|
471
|
+
let l = createMath("mo", d[0]);
|
|
472
|
+
let r = createMath("mo", d[1]);
|
|
418
473
|
let t = createMath("mtable");
|
|
419
|
-
let
|
|
474
|
+
let array: tree[][];
|
|
475
|
+
if ((attr[0][0] as tree[0])?.type) array = [attr as tree[]];
|
|
476
|
+
else array = attr as tree[][];
|
|
477
|
+
|
|
478
|
+
let augment = get_value(dic, "augment");
|
|
420
479
|
if (augment) {
|
|
421
480
|
let xa = NaN;
|
|
422
481
|
let ya = NaN;
|
|
423
|
-
if (
|
|
424
|
-
xa = Number(
|
|
482
|
+
if (typeof augment != "object") {
|
|
483
|
+
xa = Number(augment);
|
|
425
484
|
} else {
|
|
426
|
-
ya = Number((augment["hline"] as tree).map((i) => i.value).join(""));
|
|
485
|
+
if (augment["hline"]) ya = Number((augment["hline"] as tree).map((i) => i.value).join(""));
|
|
486
|
+
if (augment["vline"]) xa = Number((augment["vline"] as tree).map((i) => i.value).join(""));
|
|
427
487
|
}
|
|
428
488
|
if (xa < 0) xa = array[0].length + xa;
|
|
429
489
|
if (ya < 0) ya = array.length + ya;
|
|
@@ -439,18 +499,17 @@ let f: {
|
|
|
439
499
|
t.setAttribute("columnlines", l.map((i) => (i ? "solid" : "none")).join(" "));
|
|
440
500
|
}
|
|
441
501
|
}
|
|
442
|
-
const gap = dic
|
|
443
|
-
const rowgap = dic
|
|
444
|
-
const colgap = dic
|
|
502
|
+
const gap = get_value(dic, "gap") as string;
|
|
503
|
+
const rowgap = get_value(dic, "row-gap") as string;
|
|
504
|
+
const colgap = get_value(dic, "column-gap") as string;
|
|
445
505
|
t.setAttribute("columnspacing", colgap || gap || "0.5em");
|
|
446
506
|
t.setAttribute("rowspacing", rowgap || gap || "0.5em");
|
|
447
507
|
|
|
448
508
|
for (let i of array) {
|
|
449
509
|
let tr = createMath("mtr");
|
|
450
|
-
if (!i.length) continue;
|
|
451
510
|
for (let j of i) {
|
|
452
511
|
let td = createMath("mtd");
|
|
453
|
-
td.append(render(j));
|
|
512
|
+
td.append(render(j, e));
|
|
454
513
|
tr.append(td);
|
|
455
514
|
}
|
|
456
515
|
t.append(tr);
|
|
@@ -458,41 +517,41 @@ let f: {
|
|
|
458
517
|
row.append(l, t, r);
|
|
459
518
|
return row;
|
|
460
519
|
},
|
|
461
|
-
root: (attr: tree[], dic: fdic) => {
|
|
520
|
+
root: (attr: tree[], dic: fdic, e) => {
|
|
462
521
|
let row = createMath("mrow");
|
|
463
|
-
row.append(render(attr[0]));
|
|
522
|
+
row.append(render(attr[0], e));
|
|
464
523
|
let base = createMath("mrow");
|
|
465
|
-
base.append(render(attr[1]));
|
|
524
|
+
base.append(render(attr[1], e));
|
|
466
525
|
let root = createMath("mroot");
|
|
467
526
|
root.append(base, row);
|
|
468
527
|
return root;
|
|
469
528
|
},
|
|
470
|
-
sqrt: (attr: tree[], dic: fdic) => {
|
|
471
|
-
return f.root([[], attr[0]], null);
|
|
529
|
+
sqrt: (attr: tree[], dic: fdic, e) => {
|
|
530
|
+
return f.root([[], attr[0]], null, e);
|
|
472
531
|
},
|
|
473
|
-
display: (attr: tree[], dic: fdic) => {
|
|
532
|
+
display: (attr: tree[], dic: fdic, e) => {
|
|
474
533
|
let m = createMath("mrow", null, { displaystyle: "true" });
|
|
475
|
-
m.append(render(attr[0]));
|
|
534
|
+
m.append(render(attr[0], e));
|
|
476
535
|
return m;
|
|
477
536
|
},
|
|
478
|
-
inline: (attr: tree[], dic: fdic) => {
|
|
537
|
+
inline: (attr: tree[], dic: fdic, e) => {
|
|
479
538
|
let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "0" });
|
|
480
|
-
m.append(render(attr[0]));
|
|
539
|
+
m.append(render(attr[0], e));
|
|
481
540
|
return m;
|
|
482
541
|
},
|
|
483
|
-
script: (attr: tree[], dic: fdic) => {
|
|
542
|
+
script: (attr: tree[], dic: fdic, e) => {
|
|
484
543
|
let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "1" });
|
|
485
|
-
m.append(render(attr[0]));
|
|
544
|
+
m.append(render(attr[0], e));
|
|
486
545
|
return m;
|
|
487
546
|
},
|
|
488
|
-
sscript: (attr: tree[], dic: fdic) => {
|
|
547
|
+
sscript: (attr: tree[], dic: fdic, e) => {
|
|
489
548
|
let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "2" });
|
|
490
|
-
m.append(render(attr[0]));
|
|
549
|
+
m.append(render(attr[0], e));
|
|
491
550
|
return m;
|
|
492
551
|
},
|
|
493
|
-
upright: (attr: tree[], dic: fdic) => {
|
|
552
|
+
upright: (attr: tree[], dic: fdic, e) => {
|
|
494
553
|
let r = createMath("mrow");
|
|
495
|
-
r.append(render(attr[0]));
|
|
554
|
+
r.append(render(attr[0], e));
|
|
496
555
|
r.querySelectorAll("mi").forEach((el) => {
|
|
497
556
|
if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "normal");
|
|
498
557
|
});
|
|
@@ -501,80 +560,75 @@ let f: {
|
|
|
501
560
|
});
|
|
502
561
|
return r;
|
|
503
562
|
},
|
|
504
|
-
italic: (attr: tree[], dic: fdic) => {
|
|
563
|
+
italic: (attr: tree[], dic: fdic, e) => {
|
|
505
564
|
let r = createMath("mrow");
|
|
565
|
+
r.append(render(attr[0], e));
|
|
506
566
|
r.querySelectorAll("mi").forEach((el) => {
|
|
507
567
|
if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "italic");
|
|
508
568
|
});
|
|
509
569
|
r.querySelectorAll("ms").forEach((el) => {
|
|
510
570
|
if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "italic");
|
|
511
571
|
});
|
|
512
|
-
r.append(render(attr[0]));
|
|
513
572
|
return r;
|
|
514
573
|
},
|
|
515
|
-
bold: (attr: tree[], dic: fdic) => {
|
|
574
|
+
bold: (attr: tree[], dic: fdic, e) => {
|
|
516
575
|
let r = createMath("mrow");
|
|
517
576
|
r.style.fontWeight = "bold";
|
|
518
|
-
r.append(render(attr[0]));
|
|
577
|
+
r.append(render(attr[0], e));
|
|
519
578
|
return r;
|
|
520
579
|
},
|
|
521
|
-
op: (attr: tree[], dic: fdic,
|
|
580
|
+
op: (attr: tree[], dic: fdic, e) => {
|
|
522
581
|
let f = createMath("mrow");
|
|
523
582
|
let str = createMath("ms");
|
|
524
583
|
str.append(render(attr[0], e));
|
|
525
584
|
f.append(str);
|
|
526
585
|
return f;
|
|
527
586
|
},
|
|
528
|
-
underline: (attr: tree[], dic: fdic) => {
|
|
529
|
-
return
|
|
587
|
+
underline: (attr: tree[], dic: fdic, e) => {
|
|
588
|
+
return underover_line_f("under", attr[0], e);
|
|
530
589
|
},
|
|
531
|
-
overline: (attr: tree[], dic: fdic) => {
|
|
532
|
-
return
|
|
590
|
+
overline: (attr: tree[], dic: fdic, e) => {
|
|
591
|
+
return underover_line_f("over", attr[0], e);
|
|
533
592
|
},
|
|
534
|
-
underbrace: (attr: tree[], dic: fdic) => {
|
|
535
|
-
return underover_f("under", attr[0], "⏟", attr?.[1]);
|
|
593
|
+
underbrace: (attr: tree[], dic: fdic, e) => {
|
|
594
|
+
return underover_f("under", attr[0], "⏟", attr?.[1], e);
|
|
536
595
|
},
|
|
537
|
-
overbrace: (attr: tree[], dic: fdic) => {
|
|
538
|
-
return underover_f("over", attr[0], "⏞", attr?.[1]);
|
|
596
|
+
overbrace: (attr: tree[], dic: fdic, e) => {
|
|
597
|
+
return underover_f("over", attr[0], "⏞", attr?.[1], e);
|
|
539
598
|
},
|
|
540
|
-
underbracket: (attr: tree[], dic: fdic) => {
|
|
541
|
-
return underover_f("under", attr[0], "⎵", attr?.[1]);
|
|
599
|
+
underbracket: (attr: tree[], dic: fdic, e) => {
|
|
600
|
+
return underover_f("under", attr[0], "⎵", attr?.[1], e);
|
|
542
601
|
},
|
|
543
|
-
overbracket: (attr: tree[], dic: fdic) => {
|
|
544
|
-
return underover_f("over", attr[0], "⎴", attr?.[1]);
|
|
602
|
+
overbracket: (attr: tree[], dic: fdic, e) => {
|
|
603
|
+
return underover_f("over", attr[0], "⎴", attr?.[1], e);
|
|
545
604
|
},
|
|
546
|
-
serif: (attr: tree[]
|
|
605
|
+
serif: (attr: tree[]) => {
|
|
547
606
|
return render(attr[0], "serif");
|
|
548
607
|
},
|
|
549
|
-
sans: (attr: tree[]
|
|
608
|
+
sans: (attr: tree[]) => {
|
|
550
609
|
return render(attr[0], "sans");
|
|
551
610
|
},
|
|
552
|
-
frak: (attr: tree[]
|
|
611
|
+
frak: (attr: tree[]) => {
|
|
553
612
|
return render(attr[0], "frak");
|
|
554
613
|
},
|
|
555
|
-
mono: (attr: tree[]
|
|
614
|
+
mono: (attr: tree[]) => {
|
|
556
615
|
return render(attr[0], "mono");
|
|
557
616
|
},
|
|
558
|
-
bb: (attr: tree[]
|
|
617
|
+
bb: (attr: tree[]) => {
|
|
559
618
|
return render(attr[0], "bb");
|
|
560
619
|
},
|
|
561
|
-
cal: (attr: tree[]
|
|
620
|
+
cal: (attr: tree[]) => {
|
|
562
621
|
return render(attr[0], "cal");
|
|
563
622
|
},
|
|
564
|
-
vec: (attr: tree[], dic: fdic) => {
|
|
565
|
-
let d = dic
|
|
566
|
-
let o = delimPair;
|
|
623
|
+
vec: (attr: tree[], dic: fdic, e) => {
|
|
624
|
+
let d = delim(dic, "(");
|
|
567
625
|
let row = createMath("mrow");
|
|
568
|
-
let l = createMath("mo",
|
|
569
|
-
let r = createMath("mo",
|
|
570
|
-
let t =
|
|
571
|
-
const gap = dic
|
|
626
|
+
let l = createMath("mo", d[0]);
|
|
627
|
+
let r = createMath("mo", d[1]);
|
|
628
|
+
let t = x_table(attr, e);
|
|
629
|
+
const gap = (get_value(dic, "gap") as string) || "0.5em";
|
|
572
630
|
t.setAttribute("rowspacing", gap);
|
|
573
|
-
|
|
574
|
-
let tr = createMath("mtr");
|
|
575
|
-
tr.append(render(i));
|
|
576
|
-
t.append(tr);
|
|
577
|
-
}
|
|
631
|
+
t.setAttribute("columnspacing", "0.5em");
|
|
578
632
|
row.append(l, t, r);
|
|
579
633
|
return row;
|
|
580
634
|
},
|
|
@@ -584,56 +638,52 @@ let f: {
|
|
|
584
638
|
// 额外
|
|
585
639
|
//
|
|
586
640
|
x_table: (attr: tree[], dic: fdic) => {
|
|
587
|
-
let
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
// 按&拆分
|
|
593
|
-
let result: tree[] = [];
|
|
594
|
-
let tmp_group: tree = [];
|
|
595
|
-
for (let n = 0; n < i.length; n++) {
|
|
596
|
-
if (!i[n].esc && i[n].value == "&") {
|
|
597
|
-
if (tmp_group.length > 0) {
|
|
598
|
-
result.push(tmp_group);
|
|
599
|
-
tmp_group = [];
|
|
600
|
-
}
|
|
601
|
-
} else {
|
|
602
|
-
tmp_group.push(i[n]);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
if (tmp_group.length > 0) {
|
|
606
|
-
result.push(tmp_group);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
if (result.length > max) max = result.length;
|
|
641
|
+
let t = x_table(attr);
|
|
642
|
+
if (dic.cases) t.setAttribute("columnalign", "left");
|
|
643
|
+
return t;
|
|
644
|
+
},
|
|
645
|
+
};
|
|
610
646
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
647
|
+
function x_table(trees: tree[], e?: fonts) {
|
|
648
|
+
let max = 0;
|
|
649
|
+
let t = createMath("mtable");
|
|
650
|
+
for (let i of trees) {
|
|
651
|
+
const n = i.filter((x) => eqq(x, v_f("&"))).length;
|
|
652
|
+
if (n > max) max = n;
|
|
653
|
+
}
|
|
654
|
+
for (let i of trees) {
|
|
655
|
+
let r = createMath("mtr");
|
|
656
|
+
|
|
657
|
+
// 按&拆分
|
|
658
|
+
let result: tree[] = [[]];
|
|
659
|
+
for (let n = 0; n < i.length; n++) {
|
|
660
|
+
if (eqq(i[n], v_f("&"))) {
|
|
661
|
+
result.push([]);
|
|
662
|
+
} else {
|
|
663
|
+
result.at(-1).push(i[n]);
|
|
615
664
|
}
|
|
616
|
-
|
|
617
|
-
t.append(r);
|
|
618
665
|
}
|
|
619
|
-
let
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
666
|
+
for (let i of result) {
|
|
667
|
+
let d = createMath("mtd");
|
|
668
|
+
r.append(d);
|
|
669
|
+
d.append(render(i, e));
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// 交替对齐
|
|
673
|
+
const al = [];
|
|
674
|
+
for (let i = 0; i <= max; i++) {
|
|
675
|
+
if (i % 2 === 0) {
|
|
676
|
+
al.push("right");
|
|
677
|
+
} else {
|
|
678
|
+
al.push("left");
|
|
631
679
|
}
|
|
632
680
|
}
|
|
633
681
|
t.setAttribute("columnalign", al.join(" "));
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
682
|
+
t.setAttribute("columnspacing", "0");
|
|
683
|
+
t.append(r);
|
|
684
|
+
}
|
|
685
|
+
return t;
|
|
686
|
+
}
|
|
637
687
|
|
|
638
688
|
let opl: { id: string; str?: string; limits?: boolean }[] = [
|
|
639
689
|
{ id: "arccos" },
|
|
@@ -677,14 +727,16 @@ let opl: { id: string; str?: string; limits?: boolean }[] = [
|
|
|
677
727
|
{ id: "tanh" },
|
|
678
728
|
{ id: "liminf", str: "lim inf", limits: true },
|
|
679
729
|
{ id: "limsup", str: "lim sup", limits: true },
|
|
730
|
+
{ id: "dif", str: "d" },
|
|
731
|
+
{ id: "Dif", str: "D" },
|
|
680
732
|
];
|
|
681
733
|
function op_f() {
|
|
682
734
|
for (let i of opl) {
|
|
683
|
-
f[i.id] = (attr: tree[], a,
|
|
684
|
-
let s = f.op([[{ type: "str", value: i.str || i.id }]], {},
|
|
735
|
+
f[i.id] = (attr: tree[], a, e) => {
|
|
736
|
+
let s = f.op([[{ type: "str", value: i.str || i.id }]], {}, e);
|
|
685
737
|
if (attr) {
|
|
686
738
|
let f = document.createDocumentFragment();
|
|
687
|
-
f.append(s, kh(attr
|
|
739
|
+
f.append(s, kh(attr_join(attr)));
|
|
688
740
|
return f;
|
|
689
741
|
} else {
|
|
690
742
|
return s;
|
|
@@ -718,6 +770,78 @@ for (let i in ss) {
|
|
|
718
770
|
}
|
|
719
771
|
}
|
|
720
772
|
|
|
773
|
+
function accent_match_str(c: string) {
|
|
774
|
+
switch (c) {
|
|
775
|
+
case "\u{0300}":
|
|
776
|
+
case "`":
|
|
777
|
+
return "\u{0300}";
|
|
778
|
+
case "\u{0301}":
|
|
779
|
+
case "´":
|
|
780
|
+
return "\u{0301}";
|
|
781
|
+
case "\u{0302}":
|
|
782
|
+
case "^":
|
|
783
|
+
case "ˆ":
|
|
784
|
+
return "\u{0302}";
|
|
785
|
+
case "\u{0303}":
|
|
786
|
+
case "~":
|
|
787
|
+
case "∼":
|
|
788
|
+
case "˜":
|
|
789
|
+
return "\u{0303}";
|
|
790
|
+
case "\u{0304}":
|
|
791
|
+
case "¯":
|
|
792
|
+
return "\u{0304}";
|
|
793
|
+
case "\u{0305}":
|
|
794
|
+
case "-":
|
|
795
|
+
case "‾":
|
|
796
|
+
case "−":
|
|
797
|
+
return "\u{0305}";
|
|
798
|
+
case "\u{0306}":
|
|
799
|
+
case "˘":
|
|
800
|
+
return "\u{0306}";
|
|
801
|
+
case "\u{0307}":
|
|
802
|
+
case ".":
|
|
803
|
+
case "˙":
|
|
804
|
+
case "⋅":
|
|
805
|
+
return "\u{0307}";
|
|
806
|
+
case "\u{0308}":
|
|
807
|
+
case "¨":
|
|
808
|
+
return "\u{0308}";
|
|
809
|
+
case "\u{20db}":
|
|
810
|
+
return "\u{20db}";
|
|
811
|
+
case "\u{20dc}":
|
|
812
|
+
return "\u{20dc}";
|
|
813
|
+
case "\u{030a}":
|
|
814
|
+
case "∘":
|
|
815
|
+
case "○":
|
|
816
|
+
return "\u{030a}";
|
|
817
|
+
case "\u{030b}":
|
|
818
|
+
case "˝":
|
|
819
|
+
return "\u{030b}";
|
|
820
|
+
case "\u{030c}":
|
|
821
|
+
case "ˇ":
|
|
822
|
+
return "\u{030c}";
|
|
823
|
+
case "\u{20d6}":
|
|
824
|
+
case "←":
|
|
825
|
+
return "\u{20d6}";
|
|
826
|
+
case "\u{20d7}":
|
|
827
|
+
case "→":
|
|
828
|
+
case "⟶":
|
|
829
|
+
return "\u{20d7}";
|
|
830
|
+
case "\u{20e1}":
|
|
831
|
+
case "↔":
|
|
832
|
+
case "⟷":
|
|
833
|
+
return "\u{20e1}";
|
|
834
|
+
case "\u{20d0}":
|
|
835
|
+
case "↼":
|
|
836
|
+
return "\u{20d0}";
|
|
837
|
+
case "\u{20d1}":
|
|
838
|
+
case "⇀":
|
|
839
|
+
return "\u{20d1}";
|
|
840
|
+
default:
|
|
841
|
+
return c;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
721
845
|
function accent_f() {
|
|
722
846
|
const l = [
|
|
723
847
|
"grave",
|
|
@@ -743,8 +867,8 @@ function accent_f() {
|
|
|
743
867
|
"harpoon.lt",
|
|
744
868
|
];
|
|
745
869
|
for (let i of l) {
|
|
746
|
-
f[i] = (attr: tree[]) => {
|
|
747
|
-
let s = f.accent([attr[0], [{ type: "f", value: i }]], {});
|
|
870
|
+
f[i] = (attr: tree[], dic, e) => {
|
|
871
|
+
let s = f.accent([attr[0], [{ type: "f", value: i }]], {}, e);
|
|
748
872
|
return s;
|
|
749
873
|
};
|
|
750
874
|
}
|
|
@@ -760,25 +884,25 @@ function lr_f() {
|
|
|
760
884
|
{ name: "round", l: v_f("⌊"), r: v_f("⌉") },
|
|
761
885
|
];
|
|
762
886
|
for (let i of l) {
|
|
763
|
-
f[i.name] = (attr: tree[], dic) => {
|
|
764
|
-
let s = f.lr([[i.l, ...attr[0], i.r]], dic);
|
|
887
|
+
f[i.name] = (attr: tree[], dic, e) => {
|
|
888
|
+
let s = f.lr([[i.l, ...attr[0], i.r]], dic, e);
|
|
765
889
|
return s;
|
|
766
890
|
};
|
|
767
891
|
}
|
|
768
892
|
}
|
|
769
893
|
lr_f();
|
|
770
894
|
|
|
771
|
-
function underover_f(type: "under" | "over", tree: tree, x: string, str
|
|
895
|
+
function underover_f(type: "under" | "over", tree: tree, x: string, str: tree, e: fonts) {
|
|
772
896
|
let m =
|
|
773
|
-
type
|
|
897
|
+
type === "under"
|
|
774
898
|
? createMath("munder", null, { accentunder: "true" })
|
|
775
899
|
: createMath("mover", null, { accent: "true" });
|
|
776
900
|
let base = createMath("mrow");
|
|
777
|
-
base.append(render(tree));
|
|
901
|
+
base.append(render(tree, e));
|
|
778
902
|
if (str) {
|
|
779
903
|
let s = createMath("mrow");
|
|
780
|
-
s.append(render(str));
|
|
781
|
-
let mm = type
|
|
904
|
+
s.append(render(str, e));
|
|
905
|
+
let mm = type === "under" ? createMath("munder") : createMath("mover");
|
|
782
906
|
let xx = createMath("mo", x);
|
|
783
907
|
mm.append(xx, s);
|
|
784
908
|
m.append(base, mm);
|
|
@@ -789,6 +913,25 @@ function underover_f(type: "under" | "over", tree: tree, x: string, str?: tree)
|
|
|
789
913
|
return m;
|
|
790
914
|
}
|
|
791
915
|
|
|
916
|
+
function underover_line_f(type: "under" | "over", tree: tree, e: fonts) {
|
|
917
|
+
let m =
|
|
918
|
+
type === "under"
|
|
919
|
+
? createMath("munder", null, { accentunder: "true" })
|
|
920
|
+
: createMath("mover", null, { accent: "true" });
|
|
921
|
+
let base = createMath("mrow");
|
|
922
|
+
base.append(render(tree, e));
|
|
923
|
+
if (type === "under") base.style.borderBottom = "1px solid black";
|
|
924
|
+
if (type === "over") base.style.borderTop = "1px solid black";
|
|
925
|
+
m.append(base);
|
|
926
|
+
return m;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
const ff: typeof f = {
|
|
930
|
+
"√": f["sqrt"],
|
|
931
|
+
"∛": (attr, _, e) => f.root([[v_f("3")], attr[0]], null, e),
|
|
932
|
+
"∜": (attr, _, e) => f.root([[v_f("4")], attr[0]], null, e),
|
|
933
|
+
};
|
|
934
|
+
|
|
792
935
|
function kh(tree: tree) {
|
|
793
936
|
let f = createMath("mrow");
|
|
794
937
|
let l = createMath("mo");
|
|
@@ -801,15 +944,22 @@ function kh(tree: tree) {
|
|
|
801
944
|
}
|
|
802
945
|
|
|
803
946
|
function out_kh(x: tree[0]) {
|
|
804
|
-
if (x.type
|
|
805
|
-
return x.children;
|
|
947
|
+
if (x.type === "group") {
|
|
948
|
+
if (x.kh === "()") return x.children;
|
|
949
|
+
else return [x];
|
|
806
950
|
} else {
|
|
807
951
|
return [x];
|
|
808
952
|
}
|
|
809
953
|
}
|
|
810
954
|
|
|
955
|
+
function transfer_kh(list: tree) {
|
|
956
|
+
if (list.length === 1 && list[0].type === "group")
|
|
957
|
+
list = [v_f(list[0].kh[0]), ...list[0].children, v_f(list[0].kh[1])];
|
|
958
|
+
return list;
|
|
959
|
+
}
|
|
960
|
+
|
|
811
961
|
function in_kh(x: tree) {
|
|
812
|
-
let k: tree = [{ type: "group", value: "", children: x }];
|
|
962
|
+
let k: tree = [{ type: "group", value: "", children: x, kh: "()" }];
|
|
813
963
|
return k;
|
|
814
964
|
}
|
|
815
965
|
|
|
@@ -842,8 +992,9 @@ function is_limit(tree: tree) {
|
|
|
842
992
|
return true;
|
|
843
993
|
}
|
|
844
994
|
}
|
|
845
|
-
if (x.value
|
|
846
|
-
if (x.value
|
|
995
|
+
if (x.value === "scripts") return false;
|
|
996
|
+
if (x.value === "limits") return true;
|
|
997
|
+
if (x.value === "op") {
|
|
847
998
|
let { dic } = f_attr(x);
|
|
848
999
|
return is_true(dic.limits);
|
|
849
1000
|
}
|
|
@@ -888,15 +1039,17 @@ function eqq(x0: tree[0], x1: tree[0]) {
|
|
|
888
1039
|
return x0.type === x1.type && x0.value === x1.value && x0?.esc === x1?.esc;
|
|
889
1040
|
}
|
|
890
1041
|
|
|
1042
|
+
function is_type(x: tree[0], ...type: vtype[]) {
|
|
1043
|
+
return type.includes(x?.type);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
891
1046
|
function trim(tree: tree) {
|
|
892
|
-
if (!tree) return [];
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
}
|
|
899
|
-
return tree;
|
|
1047
|
+
if (!tree || !tree[0]) return [];
|
|
1048
|
+
let start = 0;
|
|
1049
|
+
let end = tree.length;
|
|
1050
|
+
if (tree[0].type === "blank") start = 1;
|
|
1051
|
+
if (tree.at(-1).type === "blank") end--;
|
|
1052
|
+
return tree.slice(start, end);
|
|
900
1053
|
}
|
|
901
1054
|
|
|
902
1055
|
type fdic = { [id: string]: tree };
|
|
@@ -919,7 +1072,6 @@ function dic_to_ast(dic: { [id: string]: tree }) {
|
|
|
919
1072
|
|
|
920
1073
|
function lan_dic(tree: tree) {
|
|
921
1074
|
tree = trim(tree);
|
|
922
|
-
if (!tree.find((v) => eqq(v, v_f(":")))) return tree;
|
|
923
1075
|
const o = new Object();
|
|
924
1076
|
let key = "";
|
|
925
1077
|
let value: tree = [];
|
|
@@ -944,6 +1096,21 @@ function lan_dic(tree: tree) {
|
|
|
944
1096
|
return o;
|
|
945
1097
|
}
|
|
946
1098
|
|
|
1099
|
+
function get_value(dic: fdic, o: string) {
|
|
1100
|
+
if (!dic?.[o]?.[0]) return undefined;
|
|
1101
|
+
const x = dic[o][0];
|
|
1102
|
+
if (x.type === "sharp") {
|
|
1103
|
+
if (x.value === "true") return true;
|
|
1104
|
+
if (x.value === "false") return false;
|
|
1105
|
+
if (x.value === "none") return null;
|
|
1106
|
+
if (x.children) {
|
|
1107
|
+
if (!x.children.find((v) => eqq(v, v_f(":")))) return x.children.map((v) => v.value).join("");
|
|
1108
|
+
return lan_dic(x.children);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
return dic[o].map((i) => i.value).join("");
|
|
1112
|
+
}
|
|
1113
|
+
|
|
947
1114
|
function is_true(t: tree) {
|
|
948
1115
|
return eqq(trim(t)?.[0], { type: "sharp", value: "true" });
|
|
949
1116
|
}
|
|
@@ -979,16 +1146,16 @@ function ast2(tree: tree) {
|
|
|
979
1146
|
for (let n = 0; n < tree.length; n++) {
|
|
980
1147
|
let x = tree[n];
|
|
981
1148
|
|
|
982
|
-
if (x
|
|
1149
|
+
if (eqq(x, v_f("\\"))) {
|
|
983
1150
|
if (tree?.[n + 1]) {
|
|
984
1151
|
let next = tree[n + 1];
|
|
985
|
-
if (next
|
|
986
|
-
t.push({ type: "v", value: "\\" });
|
|
1152
|
+
if (eq(next, v_f("\\"))) {
|
|
1153
|
+
t.push({ type: "v", value: "\\", esc: true });
|
|
987
1154
|
n++;
|
|
988
|
-
} else if (next.type
|
|
1155
|
+
} else if (next.type === "blank") {
|
|
989
1156
|
t.push({ type: "v", value: "br", esc: true });
|
|
990
1157
|
n++;
|
|
991
|
-
} else if (next.type
|
|
1158
|
+
} else if (next.type === "f") {
|
|
992
1159
|
let v = next.value;
|
|
993
1160
|
t.push({ type: "v", value: v[0] });
|
|
994
1161
|
t.push({ type: v.length == 2 ? "v" : "f", value: v.slice(1) });
|
|
@@ -1010,44 +1177,10 @@ function ast2(tree: tree) {
|
|
|
1010
1177
|
tree = t;
|
|
1011
1178
|
}
|
|
1012
1179
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
const t: tree = [];
|
|
1016
|
-
for (let n = 0; n < tree.length; n++) {
|
|
1017
|
-
const x = tree[n];
|
|
1018
|
-
if (x.type === "sharp") {
|
|
1019
|
-
if (tree[n + 1]?.type === "group") {
|
|
1020
|
-
x.children = tree[n + 1].children;
|
|
1021
|
-
for (let i in x.children) {
|
|
1022
|
-
if (x.children[i].value === "\\" && x.children[i].type === "v") {
|
|
1023
|
-
if (x.children[Number(i) + 1]) {
|
|
1024
|
-
x.children[Number(i) + 1]["esc"] = true;
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
const v = x.children.map((i) => i.value).join("");
|
|
1029
|
-
if (v.match(/^[0-9\+\-\*\/()]+$/)) {
|
|
1030
|
-
x.value = v; // todo 数学运算
|
|
1031
|
-
} else {
|
|
1032
|
-
x.value = v;
|
|
1033
|
-
}
|
|
1034
|
-
} else {
|
|
1035
|
-
x.value = tree[n + 1]?.value;
|
|
1036
|
-
if (tree[n + 2]?.type === "f") {
|
|
1037
|
-
x.value += tree[n + 2].value;
|
|
1038
|
-
n++;
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
t.push(x);
|
|
1042
|
-
n++;
|
|
1043
|
-
continue;
|
|
1044
|
-
} else {
|
|
1045
|
-
t.push(x);
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
tree = t;
|
|
1049
|
-
}
|
|
1180
|
+
return tree;
|
|
1181
|
+
}
|
|
1050
1182
|
|
|
1183
|
+
function ast3(tree: tree) {
|
|
1051
1184
|
// 处理符号简写(shorthand)
|
|
1052
1185
|
{
|
|
1053
1186
|
let t: tree = [];
|
|
@@ -1067,7 +1200,7 @@ function ast2(tree: tree) {
|
|
|
1067
1200
|
nn++;
|
|
1068
1201
|
}
|
|
1069
1202
|
if (l.length) {
|
|
1070
|
-
let nx: tree[0] = { type: "f", value: shorthand[l.at(-1)] };
|
|
1203
|
+
let nx: tree[0] = { type: "f", value: shorthand[l.at(-1)], src: l.at(-1) };
|
|
1071
1204
|
t.push(nx);
|
|
1072
1205
|
|
|
1073
1206
|
// 不处理已经后面连起来的字符
|
|
@@ -1154,25 +1287,161 @@ function ast2(tree: tree) {
|
|
|
1154
1287
|
}
|
|
1155
1288
|
tree = t;
|
|
1156
1289
|
}
|
|
1290
|
+
// 处理后面直接跟参数的f
|
|
1291
|
+
{
|
|
1292
|
+
const t: tree = [];
|
|
1293
|
+
for (let n = 0; n < tree.length; n++) {
|
|
1294
|
+
const x = tree[n];
|
|
1295
|
+
if (x.type === "v" && ff[x.value] && tree[n + 1]) {
|
|
1296
|
+
x.type = "f";
|
|
1297
|
+
if (!(is_type(tree[n + 1], "group") && tree[n + 1].kh === "()")) {
|
|
1298
|
+
t.push(x);
|
|
1299
|
+
t.push({ type: "group", children: [tree[n + 1]], value: "", kh: "()" });
|
|
1300
|
+
n++;
|
|
1301
|
+
continue;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
t.push(x);
|
|
1305
|
+
}
|
|
1306
|
+
tree = t;
|
|
1307
|
+
}
|
|
1157
1308
|
// 处理f
|
|
1158
1309
|
{
|
|
1159
1310
|
let t: tree = [];
|
|
1160
1311
|
for (let n = 0; n < tree.length; n++) {
|
|
1161
1312
|
let x = tree[n];
|
|
1313
|
+
const next = tree[n + 1];
|
|
1162
1314
|
|
|
1163
1315
|
// 带有括号(参数)的函数
|
|
1164
|
-
if (x.type
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1316
|
+
if (x.type === "f" && next && next.type === "group") {
|
|
1317
|
+
if (next.kh === "()") {
|
|
1318
|
+
x.children = tree[n + 1].children;
|
|
1319
|
+
t.push(x);
|
|
1320
|
+
|
|
1321
|
+
// 不处理group
|
|
1322
|
+
n++;
|
|
1323
|
+
continue;
|
|
1324
|
+
} else {
|
|
1325
|
+
if (next.kh[0] === "(") {
|
|
1326
|
+
// 向后找
|
|
1327
|
+
const tt: tree = [];
|
|
1328
|
+
tt.push(...next.children);
|
|
1329
|
+
tt.push(v_f(next.kh[1]));
|
|
1330
|
+
for (let i = n + 2; i < tree.length; i++) {
|
|
1331
|
+
if (tree[i]) {
|
|
1332
|
+
if (eqq(tree[i], v_f(")"))) {
|
|
1333
|
+
n = i;
|
|
1334
|
+
break;
|
|
1335
|
+
} else {
|
|
1336
|
+
tt.push(tree[i]);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
x.children = tt;
|
|
1341
|
+
t.push(x);
|
|
1342
|
+
} else {
|
|
1343
|
+
t.push(x);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
for (let i in x.children || []) {
|
|
1347
|
+
if (x.children[i].value === "\\" && x.children[i].type === "v") {
|
|
1168
1348
|
if (x.children[Number(i) + 1]) {
|
|
1169
1349
|
x.children[Number(i) + 1]["esc"] = true;
|
|
1170
1350
|
}
|
|
1171
1351
|
}
|
|
1172
1352
|
}
|
|
1353
|
+
} else {
|
|
1173
1354
|
t.push(x);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
tree = t;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
// sin[]/2=(sin[])/2 a_i()=a_(i()) 之类的
|
|
1361
|
+
{
|
|
1362
|
+
const t: tree = [];
|
|
1363
|
+
const un_list_str = [
|
|
1364
|
+
"`",
|
|
1365
|
+
"~",
|
|
1366
|
+
"!",
|
|
1367
|
+
"@",
|
|
1368
|
+
"%",
|
|
1369
|
+
"*",
|
|
1370
|
+
"(",
|
|
1371
|
+
")",
|
|
1372
|
+
"-",
|
|
1373
|
+
"+",
|
|
1374
|
+
"=",
|
|
1375
|
+
"[",
|
|
1376
|
+
"]",
|
|
1377
|
+
"{",
|
|
1378
|
+
"}",
|
|
1379
|
+
"|",
|
|
1380
|
+
":",
|
|
1381
|
+
";",
|
|
1382
|
+
"<",
|
|
1383
|
+
",",
|
|
1384
|
+
">",
|
|
1385
|
+
".",
|
|
1386
|
+
"?",
|
|
1387
|
+
]; // typst 似乎是直接排除了这些字符,不排除转义,shorthand之类的
|
|
1388
|
+
for (let n = 0; n < tree.length; n++) {
|
|
1389
|
+
const x = tree[n];
|
|
1390
|
+
const next = tree[n + 1];
|
|
1391
|
+
if (
|
|
1392
|
+
is_type(next, "group") &&
|
|
1393
|
+
next.kh != "()" &&
|
|
1394
|
+
is_type(x, "f", "str", "v") &&
|
|
1395
|
+
!x.value.match(/[0-9]/) &&
|
|
1396
|
+
!is_sub(x) &&
|
|
1397
|
+
!is_sup(x) &&
|
|
1398
|
+
(!(
|
|
1399
|
+
(is_type(x, "f") && un_list_str.includes(x.src)) ||
|
|
1400
|
+
(is_type(x, "v") && un_list_str.includes(x.value))
|
|
1401
|
+
) ||
|
|
1402
|
+
x.esc)
|
|
1403
|
+
) {
|
|
1404
|
+
t.push({ type: "group1", value: "", children: [x, next] });
|
|
1405
|
+
n++;
|
|
1406
|
+
continue;
|
|
1407
|
+
}
|
|
1408
|
+
t.push(x);
|
|
1409
|
+
}
|
|
1410
|
+
tree = t;
|
|
1411
|
+
}
|
|
1174
1412
|
|
|
1175
|
-
|
|
1413
|
+
// 处理#
|
|
1414
|
+
{
|
|
1415
|
+
const t: tree = [];
|
|
1416
|
+
for (let n = 0; n < tree.length; n++) {
|
|
1417
|
+
const x = tree[n];
|
|
1418
|
+
if (x.type === "sharp") {
|
|
1419
|
+
if (!x.value)
|
|
1420
|
+
if (tree[n + 1]?.type === "group") {
|
|
1421
|
+
x.children = tree[n + 1].children;
|
|
1422
|
+
for (let i in x.children) {
|
|
1423
|
+
if (x.children[i].value === "\\" && x.children[i].type === "v") {
|
|
1424
|
+
if (x.children[Number(i) + 1]) {
|
|
1425
|
+
x.children[Number(i) + 1]["esc"] = true;
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
const v = x.children.map((i) => i.value).join("");
|
|
1430
|
+
if (v.match(/^[0-9\+\-\*\/()]+$/)) {
|
|
1431
|
+
x.value = v; // todo 数学运算
|
|
1432
|
+
} else {
|
|
1433
|
+
x.value = v;
|
|
1434
|
+
}
|
|
1435
|
+
} else {
|
|
1436
|
+
console.log("+1", tree[n + 1]);
|
|
1437
|
+
|
|
1438
|
+
x.value = tree[n + 1]?.value;
|
|
1439
|
+
if (tree[n + 2]?.type === "f") {
|
|
1440
|
+
x.value += tree[n + 2].value;
|
|
1441
|
+
n++;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
t.push(x);
|
|
1176
1445
|
n++;
|
|
1177
1446
|
continue;
|
|
1178
1447
|
} else {
|
|
@@ -1186,24 +1455,29 @@ function ast2(tree: tree) {
|
|
|
1186
1455
|
{
|
|
1187
1456
|
let t: tree = [];
|
|
1188
1457
|
for (let n = 0; n < tree.length; n++) {
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1458
|
+
const next = tree[n + 1];
|
|
1459
|
+
const x = tree[n];
|
|
1460
|
+
let nn = n + 1;
|
|
1461
|
+
if (eqq(next, { type: "f", value: "prime" })) {
|
|
1462
|
+
while (tree[nn] && eqq(tree[nn], { type: "f", value: "prime" })) nn++;
|
|
1463
|
+
const primes = nn - (n + 1);
|
|
1464
|
+
if (!is_sup(x) && !is_sub(x) && x.type != "blank") {
|
|
1465
|
+
t.push({
|
|
1466
|
+
type: "f",
|
|
1467
|
+
value: "attach",
|
|
1468
|
+
children: [
|
|
1469
|
+
x,
|
|
1470
|
+
dh,
|
|
1471
|
+
...dic_to_ast({
|
|
1472
|
+
tr: [{ type: "v", value: "'".repeat(primes) }],
|
|
1473
|
+
}),
|
|
1474
|
+
],
|
|
1475
|
+
});
|
|
1476
|
+
} else {
|
|
1477
|
+
t.push(x);
|
|
1478
|
+
for (let i = 0; i < primes; i++) t.push({ type: "f", value: "prime" });
|
|
1204
1479
|
}
|
|
1205
|
-
|
|
1206
|
-
n += primes - 1;
|
|
1480
|
+
n += primes;
|
|
1207
1481
|
continue;
|
|
1208
1482
|
}
|
|
1209
1483
|
t.push(x);
|
|
@@ -1353,54 +1627,52 @@ function ast2(tree: tree) {
|
|
|
1353
1627
|
}
|
|
1354
1628
|
|
|
1355
1629
|
function f_attr(x: tree[0]) {
|
|
1356
|
-
|
|
1357
|
-
let
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
for (let i in x.children) {
|
|
1362
|
-
const t = x.children[i];
|
|
1363
|
-
if (Number(i) + 1 == x.children.length) {
|
|
1364
|
-
if (t.type == "blank" && x.children[Number(i) - 1].value.match(/[,;]/)) break;
|
|
1365
|
-
if (!is_f_mark(t, ",") && !is_f_mark(t, ";")) l.push(t);
|
|
1366
|
-
if (type == "dic") {
|
|
1367
|
-
dicl.push(l);
|
|
1368
|
-
l = [];
|
|
1369
|
-
} else {
|
|
1370
|
-
attr.push(l);
|
|
1371
|
-
}
|
|
1372
|
-
if (array.length) {
|
|
1373
|
-
array.push(attr);
|
|
1374
|
-
attr = [];
|
|
1375
|
-
}
|
|
1376
|
-
l = [];
|
|
1630
|
+
const list: (tree | "," | ";")[] = [[]];
|
|
1631
|
+
for (let i of x.children) {
|
|
1632
|
+
if (eqq(i, { type: "v", value: "," }) || eqq(i, { type: "v", value: ";" })) {
|
|
1633
|
+
list.push(i.value as "," | ";");
|
|
1634
|
+
list.push([]);
|
|
1377
1635
|
} else {
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
attr.push(l);
|
|
1390
|
-
l = [];
|
|
1391
|
-
array.push(attr);
|
|
1392
|
-
attr = [];
|
|
1636
|
+
(list.at(-1) as tree).push(i);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
const dicl: tree[] = [];
|
|
1640
|
+
const xattr: typeof list = [];
|
|
1641
|
+
for (let x of list) {
|
|
1642
|
+
if (typeof x === "string") {
|
|
1643
|
+
xattr.push(x);
|
|
1644
|
+
} else {
|
|
1645
|
+
if (x.find((v, i) => is_type(x[i - 1], "f", "v") && eqq(v, { type: "v", value: ":" }))) {
|
|
1646
|
+
dicl.push(x);
|
|
1393
1647
|
} else {
|
|
1394
|
-
|
|
1395
|
-
l.push(t);
|
|
1396
|
-
// 段中有: 为dic
|
|
1397
|
-
if (is_f_mark(t, ":")) {
|
|
1398
|
-
type = "dic";
|
|
1399
|
-
}
|
|
1648
|
+
xattr.push(x);
|
|
1400
1649
|
}
|
|
1401
1650
|
}
|
|
1402
1651
|
}
|
|
1403
1652
|
|
|
1653
|
+
let nl: typeof xattr = [];
|
|
1654
|
+
for (let i = 0; i < xattr.length; i++) {
|
|
1655
|
+
const n = xattr[i],
|
|
1656
|
+
next = xattr[i + 1];
|
|
1657
|
+
if ((n === "," && next === ";") || (n === ";" && next === ",")) {
|
|
1658
|
+
nl.push(";");
|
|
1659
|
+
i++;
|
|
1660
|
+
} else {
|
|
1661
|
+
nl.push(xattr[i]);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
let attr: tree[] | tree[][];
|
|
1666
|
+
if (typeof nl.at(-1) === "string") nl = nl.slice(0, -1);
|
|
1667
|
+
const has_fenhao = nl.includes(";");
|
|
1668
|
+
if (has_fenhao) {
|
|
1669
|
+
let x = array_split(nl, (x) => x === ";");
|
|
1670
|
+
if (x.at(-1)[0].length === 0) x = x.slice(0, -1);
|
|
1671
|
+
attr = x.map((x) => x.filter((i) => typeof i != "string")) as tree[][];
|
|
1672
|
+
} else {
|
|
1673
|
+
attr = (nl.filter((i) => typeof i != "string") as tree[]).map((i) => trim(i));
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1404
1676
|
// 将dicl的tree转为键对
|
|
1405
1677
|
let dic: fdic = {};
|
|
1406
1678
|
for (let i of dicl) {
|
|
@@ -1408,7 +1680,7 @@ function f_attr(x: tree[0]) {
|
|
|
1408
1680
|
let n = "";
|
|
1409
1681
|
let t: tree = [];
|
|
1410
1682
|
for (let el of i) {
|
|
1411
|
-
if (el
|
|
1683
|
+
if (eqq(el, { type: "v", value: ":" })) {
|
|
1412
1684
|
x = true;
|
|
1413
1685
|
continue;
|
|
1414
1686
|
}
|
|
@@ -1418,9 +1690,29 @@ function f_attr(x: tree[0]) {
|
|
|
1418
1690
|
t.push(el);
|
|
1419
1691
|
}
|
|
1420
1692
|
}
|
|
1421
|
-
dic[n] = ast2(t);
|
|
1693
|
+
dic[n] = ast3(ast2(t));
|
|
1422
1694
|
}
|
|
1423
|
-
return { attr, dic
|
|
1695
|
+
return { attr, dic };
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
function array_split<i>(list: i[], f: (i: i) => boolean) {
|
|
1699
|
+
const l: i[][] = [[]];
|
|
1700
|
+
for (let x of list) {
|
|
1701
|
+
if (f(x)) {
|
|
1702
|
+
l.push([]);
|
|
1703
|
+
} else {
|
|
1704
|
+
l.at(-1).push(x);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
return l;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
function attr_join(attr: tree[]) {
|
|
1711
|
+
const t: tree = [];
|
|
1712
|
+
for (let i of attr) {
|
|
1713
|
+
t.push(...i, v_f(","));
|
|
1714
|
+
}
|
|
1715
|
+
return t.slice(0, -1);
|
|
1424
1716
|
}
|
|
1425
1717
|
|
|
1426
1718
|
type fonts = "serif" | "sans" | "frak" | "mono" | "bb" | "cal";
|
|
@@ -1429,46 +1721,38 @@ function font(str: string, type: fonts = "serif") {
|
|
|
1429
1721
|
const l = "abcdefghijklmnopqrstuvwxyz";
|
|
1430
1722
|
return l.indexOf(c.toLowerCase());
|
|
1431
1723
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
str = str.replace(/[a-z]/g, (s) => bb1[index_c(s)]);
|
|
1463
|
-
str = str.replace(/[A-Z]/g, (s) => bb2[index_c(s)]);
|
|
1464
|
-
return str;
|
|
1465
|
-
case "cal":
|
|
1466
|
-
const c1 = [..."𝒶𝒷𝒸𝒹ℯ𝒻ℊ𝒽𝒾𝒿𝓀𝓁𝓂𝓃ℴ𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏"];
|
|
1467
|
-
const c2 = [..."𝒜ℬ𝒞𝒟ℰℱ𝒢ℋℐ𝒥𝒦ℒℳ𝒩𝒪𝒫𝒬ℛ𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵"];
|
|
1468
|
-
str = str.replace(/[a-z]/g, (s) => c1[index_c(s)]);
|
|
1469
|
-
str = str.replace(/[A-Z]/g, (s) => c2[index_c(s)]);
|
|
1470
|
-
return str;
|
|
1724
|
+
const map: { [font in "sans" | "frak" | "mono" | "bb" | "cal"]: { num?: string; up: string; low: string } } = {
|
|
1725
|
+
sans: {
|
|
1726
|
+
num: "𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫",
|
|
1727
|
+
low: "𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓",
|
|
1728
|
+
up: "𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹",
|
|
1729
|
+
},
|
|
1730
|
+
frak: {
|
|
1731
|
+
low: "𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷",
|
|
1732
|
+
up: "𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ",
|
|
1733
|
+
},
|
|
1734
|
+
mono: {
|
|
1735
|
+
num: "𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿",
|
|
1736
|
+
low: "𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣",
|
|
1737
|
+
up: "𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉",
|
|
1738
|
+
},
|
|
1739
|
+
bb: {
|
|
1740
|
+
num: "𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡",
|
|
1741
|
+
low: "𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫",
|
|
1742
|
+
up: "𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ",
|
|
1743
|
+
},
|
|
1744
|
+
cal: {
|
|
1745
|
+
low: "𝒶𝒷𝒸𝒹ℯ𝒻ℊ𝒽𝒾𝒿𝓀𝓁𝓂𝓃ℴ𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏",
|
|
1746
|
+
up: "𝒜ℬ𝒞𝒟ℰℱ𝒢ℋℐ𝒥𝒦ℒℳ𝒩𝒪𝒫𝒬ℛ𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵",
|
|
1747
|
+
},
|
|
1748
|
+
};
|
|
1749
|
+
if (type === "serif") return str;
|
|
1750
|
+
else {
|
|
1751
|
+
str = str.replace(/[0-9]/g, (s) => [...map[type].num][s]);
|
|
1752
|
+
str = str.replace(/[a-z]/g, (s) => [...map[type].low][index_c(s)]);
|
|
1753
|
+
str = str.replace(/[A-Z]/g, (s) => [...map[type].up][index_c(s)]);
|
|
1471
1754
|
}
|
|
1755
|
+
return str;
|
|
1472
1756
|
}
|
|
1473
1757
|
|
|
1474
1758
|
function render(tree: tree, e?: fonts) {
|
|
@@ -1476,59 +1760,44 @@ function render(tree: tree, e?: fonts) {
|
|
|
1476
1760
|
|
|
1477
1761
|
tree = ast2(tree);
|
|
1478
1762
|
|
|
1763
|
+
// 多行
|
|
1479
1764
|
// 处理\ 换行
|
|
1480
1765
|
{
|
|
1481
1766
|
let xx = false;
|
|
1482
|
-
let
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
}
|
|
1488
|
-
if (i.type == "group") {
|
|
1489
|
-
w(i.children);
|
|
1490
|
-
}
|
|
1767
|
+
for (let n in tree) {
|
|
1768
|
+
const i = tree[n];
|
|
1769
|
+
if (is_br(i)) {
|
|
1770
|
+
xx = true;
|
|
1771
|
+
break;
|
|
1491
1772
|
}
|
|
1492
|
-
}
|
|
1493
|
-
w(tree);
|
|
1773
|
+
}
|
|
1494
1774
|
if (xx) {
|
|
1495
|
-
|
|
1496
|
-
{
|
|
1497
|
-
let t: tree = [];
|
|
1498
|
-
for (let i in tree) {
|
|
1499
|
-
let x = tree[i];
|
|
1500
|
-
// 不作为group,只是数学上显示的括号对
|
|
1501
|
-
if (x.type == "group") {
|
|
1502
|
-
t.push(v_f("("));
|
|
1503
|
-
t.push(...ast2(x.children));
|
|
1504
|
-
t.push(v_f(")"));
|
|
1505
|
-
} else {
|
|
1506
|
-
t.push(x);
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
tree = t;
|
|
1510
|
-
}
|
|
1511
|
-
// 将换行替换成逗号传入函数
|
|
1775
|
+
const trees: tree[] = [[]];
|
|
1512
1776
|
for (let n = 0; n < tree.length; n++) {
|
|
1513
|
-
const
|
|
1514
|
-
if (is_br(
|
|
1515
|
-
|
|
1777
|
+
const i = tree[n];
|
|
1778
|
+
if (is_br(i)) {
|
|
1779
|
+
trees.push([]);
|
|
1780
|
+
} else {
|
|
1781
|
+
trees.at(-1).push(i);
|
|
1516
1782
|
}
|
|
1517
1783
|
}
|
|
1784
|
+
return x_table(trees);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1518
1787
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1788
|
+
// 单行
|
|
1789
|
+
|
|
1790
|
+
tree = ast3(tree);
|
|
1791
|
+
|
|
1792
|
+
{
|
|
1793
|
+
let t: tree = [];
|
|
1794
|
+
for (let x of tree) {
|
|
1795
|
+
// 移除&
|
|
1796
|
+
if (!(x.type == "v" && x.value == "&" && !x.esc)) {
|
|
1797
|
+
t.push(x);
|
|
1529
1798
|
}
|
|
1530
|
-
tree = t;
|
|
1531
1799
|
}
|
|
1800
|
+
tree = t;
|
|
1532
1801
|
}
|
|
1533
1802
|
|
|
1534
1803
|
// 移除group1
|
|
@@ -1544,54 +1813,59 @@ function render(tree: tree, e?: fonts) {
|
|
|
1544
1813
|
tree = t;
|
|
1545
1814
|
}
|
|
1546
1815
|
|
|
1816
|
+
console.log("ast3", structuredClone(tree));
|
|
1547
1817
|
for (let i in tree) {
|
|
1548
1818
|
let n = Number(i);
|
|
1549
1819
|
let x = tree[n];
|
|
1550
1820
|
|
|
1551
|
-
//
|
|
1552
|
-
if (x.type
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
console.log(attr, dic, array);
|
|
1557
|
-
let el = f[x.value](attr, dic, array, e);
|
|
1558
|
-
fragment.append(el);
|
|
1559
|
-
} else if (ss[x.value]) {
|
|
1560
|
-
let el = createMath("mi", ss[x.value]);
|
|
1561
|
-
fragment.append(el, render(in_kh(x.children)));
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1821
|
+
// 函数
|
|
1822
|
+
if (x.type === "f") {
|
|
1823
|
+
// 带有括号(参数)的函数
|
|
1824
|
+
if (x.children && (x.kh === "()" || !x.kh)) {
|
|
1825
|
+
let { attr, dic } = f_attr(x);
|
|
1564
1826
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
"\u2005": "0.25em",
|
|
1575
|
-
"\u2006": "0.166em",
|
|
1576
|
-
"\u205f": "0.222em",
|
|
1577
|
-
"\u2007": "1ch",
|
|
1578
|
-
"\u2008": "0.27em",
|
|
1579
|
-
"\u2009": "0.17em",
|
|
1580
|
-
"\u200a": "0.09em",
|
|
1581
|
-
};
|
|
1582
|
-
if (ss[x.value].match(/[a-zA-Z\u0391-\u03C9]/)) {
|
|
1583
|
-
tag = "mi";
|
|
1584
|
-
} else if (space_width[ss[x.value]]) {
|
|
1585
|
-
tag = "mspace";
|
|
1586
|
-
space_w = { width: space_width[ss[x.value]] };
|
|
1587
|
-
} else {
|
|
1588
|
-
tag = "mo";
|
|
1827
|
+
if (f[x.value]) {
|
|
1828
|
+
let el = f[x.value](attr as tree[], dic, e);
|
|
1829
|
+
fragment.append(el);
|
|
1830
|
+
} else if (ss[x.value]) {
|
|
1831
|
+
let el = createMath("mi", ss[x.value]);
|
|
1832
|
+
fragment.append(el, render(in_kh(x.children), e));
|
|
1833
|
+
} else if (ff[x.value]) {
|
|
1834
|
+
let el = ff[x.value](attr as tree[], dic, e);
|
|
1835
|
+
fragment.append(el);
|
|
1589
1836
|
}
|
|
1590
|
-
let el = createMath(tag, ss[x.value], space_w);
|
|
1591
|
-
fragment.append(el);
|
|
1592
1837
|
} else {
|
|
1593
|
-
if (
|
|
1594
|
-
let
|
|
1838
|
+
if (ss[x.value]) {
|
|
1839
|
+
let tag: keyof MathMLElementTagNameMap;
|
|
1840
|
+
let space_w = null;
|
|
1841
|
+
const space_width = {
|
|
1842
|
+
" ": "0.36em",
|
|
1843
|
+
"\u2002": "0.5em",
|
|
1844
|
+
"\u2003": "1em",
|
|
1845
|
+
"\u2004": "0.333em",
|
|
1846
|
+
"\u2005": "0.25em",
|
|
1847
|
+
"\u2006": "0.166em",
|
|
1848
|
+
"\u205f": "0.222em",
|
|
1849
|
+
"\u2007": "1ch",
|
|
1850
|
+
"\u2008": "0.27em",
|
|
1851
|
+
"\u2009": "0.17em",
|
|
1852
|
+
"\u200a": "0.09em",
|
|
1853
|
+
};
|
|
1854
|
+
if (ss[x.value].match(/[a-zA-Z\u0391-\u03C9]/)) {
|
|
1855
|
+
tag = "mi";
|
|
1856
|
+
} else if (space_width[ss[x.value]]) {
|
|
1857
|
+
tag = "mspace";
|
|
1858
|
+
space_w = { width: space_width[ss[x.value]] };
|
|
1859
|
+
} else {
|
|
1860
|
+
tag = "mo";
|
|
1861
|
+
}
|
|
1862
|
+
let el = createMath(tag, ss[x.value], space_w);
|
|
1863
|
+
fragment.append(el);
|
|
1864
|
+
} else if (f[x.value]) {
|
|
1865
|
+
let el = f[x.value](null, null, e);
|
|
1866
|
+
fragment.append(el);
|
|
1867
|
+
} else if (ff[x.value]) {
|
|
1868
|
+
let el = ff[x.value]([x.children], null, e);
|
|
1595
1869
|
fragment.append(el);
|
|
1596
1870
|
}
|
|
1597
1871
|
}
|
|
@@ -1604,30 +1878,37 @@ function render(tree: tree, e?: fonts) {
|
|
|
1604
1878
|
|
|
1605
1879
|
if (x.type === "v" || x.type === "sharp") {
|
|
1606
1880
|
let tag: keyof MathMLElementTagNameMap;
|
|
1881
|
+
let value = x.value;
|
|
1607
1882
|
if (x.value.match(/[0-9.]+/)) {
|
|
1608
1883
|
tag = "mn";
|
|
1609
1884
|
} else if (x.value.match(/[a-zA-Z\u0391-\u03C9]/)) {
|
|
1610
1885
|
tag = "mi";
|
|
1611
1886
|
} else if (x.value.match(/^'+$/)) {
|
|
1612
|
-
if (x.
|
|
1887
|
+
if (!x.esc) value = x.value.replaceAll("'", ss["prime"]);
|
|
1613
1888
|
tag = "mo";
|
|
1614
1889
|
} else {
|
|
1615
1890
|
tag = "mo";
|
|
1616
1891
|
}
|
|
1617
|
-
|
|
1892
|
+
if (x.type === "sharp") {
|
|
1893
|
+
if (x.value.startsWith("emoji.")) {
|
|
1894
|
+
tag = "mi";
|
|
1895
|
+
value = emojix[x.value.replace("emoji.", "")];
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
let el = createMath(tag, font(value, e));
|
|
1618
1899
|
fragment.append(el);
|
|
1619
1900
|
}
|
|
1620
1901
|
|
|
1621
|
-
if (x.type
|
|
1622
|
-
fragment.append(
|
|
1902
|
+
if (x.type === "group") {
|
|
1903
|
+
fragment.append(f.lr([[x]], null, e));
|
|
1623
1904
|
}
|
|
1624
1905
|
}
|
|
1625
1906
|
|
|
1626
1907
|
return fragment;
|
|
1627
1908
|
}
|
|
1628
1909
|
|
|
1629
|
-
var init_c: { emoji:
|
|
1630
|
-
emoji:
|
|
1910
|
+
var init_c: { emoji: (str: string) => string } = {
|
|
1911
|
+
emoji: null,
|
|
1631
1912
|
};
|
|
1632
1913
|
|
|
1633
1914
|
function init(p: { emoji: boolean }) {
|
|
@@ -1636,12 +1917,12 @@ function init(p: { emoji: boolean }) {
|
|
|
1636
1917
|
}
|
|
1637
1918
|
}
|
|
1638
1919
|
|
|
1639
|
-
function toMML(str: string) {
|
|
1920
|
+
function toMML(str: string, inline?: boolean) {
|
|
1640
1921
|
let obj = ast(str);
|
|
1641
|
-
console.log(obj);
|
|
1922
|
+
console.log("ast1", obj);
|
|
1642
1923
|
|
|
1643
1924
|
let mathEl = createMath("math");
|
|
1644
|
-
mathEl.setAttribute("display", "block");
|
|
1925
|
+
if (!inline) mathEl.setAttribute("display", "block");
|
|
1645
1926
|
let f = render(obj);
|
|
1646
1927
|
mathEl.append(f);
|
|
1647
1928
|
return mathEl;
|