xmmath 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/main.ts ADDED
@@ -0,0 +1,1004 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ function createEl<K extends keyof HTMLElementTagNameMap>(tagName: K): HTMLElementTagNameMap[K];
4
+ function createEl<K extends keyof HTMLElementDeprecatedTagNameMap>(tagName: K): HTMLElementDeprecatedTagNameMap[K];
5
+ function createEl(tagName: string): HTMLElement;
6
+ function createEl(tagname: string) {
7
+ return document.createElement(tagname);
8
+ }
9
+
10
+ type mathtag =
11
+ | "math"
12
+ | "menclose"
13
+ | "merror"
14
+ | "mfrac"
15
+ | "mi"
16
+ | "mmultiscripts"
17
+ | "mprescripts"
18
+ | "mn"
19
+ | "mo"
20
+ | "mover"
21
+ | "mpadded"
22
+ | "mphantom"
23
+ | "mroot"
24
+ | "mrow"
25
+ | "ms"
26
+ | "mspace"
27
+ | "msqrt"
28
+ | "mstyle"
29
+ | "msub"
30
+ | "msubsup"
31
+ | "msup"
32
+ | "mtable"
33
+ | "mtd"
34
+ | "mtext"
35
+ | "mtr"
36
+ | "munder"
37
+ | "munderover"
38
+ | "semantics";
39
+
40
+ function createMath(tagname: mathtag, innerText?: string, attr?: { [name: string]: string }) {
41
+ let el = document.createElement(tagname);
42
+ if (innerText) el.innerText = innerText;
43
+ if (attr) {
44
+ for (let i in attr) {
45
+ el.setAttribute(i, attr[i]);
46
+ }
47
+ }
48
+ return el;
49
+ }
50
+
51
+ const mathvariant = "mathvariant";
52
+
53
+ type vtype = "" | "str" | "v" | "f" | "blank" | "group";
54
+ type tree = { type: vtype; value: string; children?: tree }[];
55
+
56
+ function ast(str: string) {
57
+ let v = /[a-zA-Z.]/;
58
+ let kh = /[\(\)]/;
59
+ let blank = /[ \t\n\r]+/;
60
+ let type: vtype = "";
61
+ let o: tree = [];
62
+ let p_tree: { tree: tree; close: boolean }[] = [];
63
+ let now_tree = o;
64
+ let tmp_str = "";
65
+
66
+ let lkh_stack: number[] = [];
67
+ let rkh_stack: number[] = [];
68
+ for (let i = 0; i < str.length; i++) {
69
+ const t = str[i];
70
+ // 字符
71
+ if (t == '"' && str[i - 1] != "\\") {
72
+ if (type != "str") {
73
+ type = "str";
74
+ } else {
75
+ type = "";
76
+ }
77
+ continue;
78
+ }
79
+ if (type == "str") {
80
+ continue;
81
+ }
82
+
83
+ if (t == "(") {
84
+ lkh_stack.push(i);
85
+ }
86
+ if (t == ")") {
87
+ if (lkh_stack.length == 0) {
88
+ rkh_stack.push(i);
89
+ } else {
90
+ lkh_stack.pop();
91
+ }
92
+ }
93
+ }
94
+
95
+ let continue_c = 0;
96
+
97
+ for (let i = 0; i < str.length; i++) {
98
+ if (continue_c > 0) {
99
+ continue_c--;
100
+ continue;
101
+ }
102
+
103
+ const t = str[i];
104
+ // 字符
105
+ if (t == '"' && str[i - 1] != "\\") {
106
+ if (type != "str") {
107
+ type = "str";
108
+ } else {
109
+ now_tree.push({ type, value: tmp_str });
110
+ type = "";
111
+ tmp_str = "";
112
+ }
113
+ continue;
114
+ }
115
+ if (type == "str") {
116
+ tmp_str += t;
117
+ continue;
118
+ }
119
+
120
+ // 空白
121
+ if (t.match(blank)) {
122
+ type = "blank";
123
+ }
124
+ if (type == "blank" && !t.match(blank)) {
125
+ now_tree.push({ type, value: "" });
126
+ type = "";
127
+ }
128
+
129
+ if (t == "\\") {
130
+ if (str[i + 1] == "\\") {
131
+ continue_c = 1;
132
+ now_tree.push({ type: "v", value: t });
133
+ }
134
+ continue;
135
+ }
136
+
137
+ // 原始值(字母变量、数字、符号)
138
+ if (
139
+ type == "" &&
140
+ (!str[i - 1] || !str[i - 1].match(v)) &&
141
+ (!str[i + 1] || !str[i + 1].match(v)) &&
142
+ !t.match(kh)
143
+ ) {
144
+ now_tree.push({ type: "v", value: t });
145
+ continue;
146
+ }
147
+ if (type == "" && !t.match(v) && !t.match(kh)) {
148
+ now_tree.push({ type: "v", value: t });
149
+ continue;
150
+ }
151
+
152
+ // 函数名
153
+ if (((str[i - 1] && str[i - 1].match(v)) || (str[i + 1] && str[i + 1].match(v))) && t.match(v)) {
154
+ type = "f";
155
+ }
156
+ if (type == "f") {
157
+ tmp_str += t;
158
+ }
159
+ if (type == "f" && (!str[i + 1] || !str[i + 1].match(v))) {
160
+ now_tree.push({ type, value: tmp_str });
161
+ type = "";
162
+ tmp_str = "";
163
+ }
164
+
165
+ if (t == "(") {
166
+ if (lkh_stack.includes(i)) {
167
+ now_tree.push({ type: "v", value: t });
168
+ } else {
169
+ p_tree.push({ tree: now_tree, close: false });
170
+ now_tree.push({ type: "group", value: tmp_str, children: [] });
171
+ now_tree = now_tree[now_tree.length - 1].children;
172
+ tmp_str = "";
173
+ continue;
174
+ }
175
+ }
176
+ if (t == ")") {
177
+ if (p_tree[p_tree.length - 1]) {
178
+ if (p_tree[p_tree.length - 1].close == false) {
179
+ p_tree[p_tree.length - 1].close = true;
180
+ now_tree = p_tree[p_tree.length - 1].tree;
181
+ p_tree.pop();
182
+ continue;
183
+ }
184
+ } else {
185
+ now_tree.push({ type: "v", value: t });
186
+ }
187
+ }
188
+ }
189
+
190
+ return o;
191
+ }
192
+
193
+ import symbols from "./symbols.json?raw";
194
+ /** @see https://github.com/typst/typst/blob/6c542ea1a4a0ee85069dad6974ff331851eff406/library/src/symbols/sym.rs */
195
+ let s = JSON.parse(symbols);
196
+
197
+ let f = {
198
+ accent: (attr: tree[], dic: fdic) => {
199
+ let base = createMath("mrow");
200
+ base.append(render(attr[0]));
201
+ let a = createMath("mrow");
202
+ a.append(render(attr[1]));
203
+ let over = createMath("mover");
204
+ over.setAttribute("accent", "true");
205
+ over.append(base, a);
206
+ return over;
207
+ },
208
+ attach: (attr: tree[], dic: fdic) => {
209
+ let base = createMath("mrow");
210
+ base.append(render(attr[0]));
211
+ let el = createMath("mmultiscripts");
212
+ el.append(base);
213
+ let tl = createMath("mrow");
214
+ if (dic.tl) tl.append(render(dic.tl));
215
+ let bl = createMath("mrow");
216
+ if (dic.bl) bl.append(render(dic.bl));
217
+ let tr = createMath("mrow");
218
+ if (dic.tr) tr.append(render(dic.tr));
219
+ let br = createMath("mrow");
220
+ if (dic.br) br.append(render(dic.br));
221
+ if (dic.tl || dic.bl || dic.tr || dic.br) {
222
+ el.append(br, tr, createMath("mprescripts"), bl, tl);
223
+ }
224
+ if (dic.t || dic.b) {
225
+ let ud = createMath("munderover");
226
+ if (el.children.length == 1) {
227
+ let base = createMath("mrow");
228
+ base.append(render(attr[0]));
229
+ ud.append(base);
230
+ } else {
231
+ ud.append(el);
232
+ }
233
+ let t = createMath("mrow");
234
+ if (dic.t) t.append(render(dic.t));
235
+ let b = createMath("mrow");
236
+ if (dic.b) b.append(render(dic.b));
237
+ ud.append(b, t);
238
+ el = ud;
239
+ }
240
+ return el;
241
+ },
242
+ scripts: (attr: tree[], dic: fdic) => {
243
+ return render(attr[0]);
244
+ },
245
+ limits: (attr: tree[], dic: fdic) => {
246
+ return render(attr[0]);
247
+ },
248
+ binom: (attr: tree[], dic: fdic) => {
249
+ let row = createMath("mrow");
250
+ let a = createMath("mrow");
251
+ a.append(render(attr[0]));
252
+ let b = createMath("mrow");
253
+ b.append(render(attr[1]));
254
+ let f = createMath("mfrac", null, { linethickness: "0" });
255
+ f.append(a, b);
256
+ let l = createMath("mo", "(");
257
+ let r = createMath("mo", ")");
258
+ row.append(l, f, r);
259
+ return row;
260
+ },
261
+ cancel: (attr: tree[], dic: fdic) => {},
262
+ cases: (attr: tree[], dic: fdic) => {
263
+ let f = createMath("mrow");
264
+ let l = createMath("mo", dic?.delim?.[0]?.value || "{");
265
+ let t = createMath("mtable", null, { columnalign: "left" });
266
+ for (let i of attr) {
267
+ let tr = createMath("mtr");
268
+ let td = createMath("mtd");
269
+ td.append(render(i));
270
+ tr.append(td);
271
+ t.append(tr);
272
+ }
273
+ f.append(l, t);
274
+ return f;
275
+ },
276
+ frac: (attr: tree[], dic: fdic) => {
277
+ console.log(attr);
278
+
279
+ let a = createMath("mrow");
280
+ a.append(render(attr[0]));
281
+ let b = createMath("mrow");
282
+ b.append(render(attr[1]));
283
+ let f = createMath("mfrac");
284
+ f.append(a, b);
285
+ return f;
286
+ },
287
+ lr: (attr: tree[], dic: fdic) => {
288
+ let list = attr[0];
289
+ let start: { c: tree; n: number }, end: { c: tree; n: number };
290
+ for (let i = 0; i < list.length; i++) {
291
+ const el = list[i];
292
+ if (el.type == "blank") continue;
293
+ start = { c: [el], n: i };
294
+ break;
295
+ }
296
+ for (let i = list.length - 1; i >= 0; i--) {
297
+ const el = list[i];
298
+ if (el.type == "blank") continue;
299
+ end = { c: [el], n: i };
300
+ break;
301
+ }
302
+ let l = document.createDocumentFragment();
303
+ l.append(render(start.c));
304
+ let r = document.createDocumentFragment();
305
+ r.append(render(end.c));
306
+ let c = document.createDocumentFragment();
307
+ c.append(render(list.slice(start.n + 1, end.n)));
308
+ let row = createMath("mrow");
309
+ row.append(l, c, r);
310
+ return row;
311
+ },
312
+ mat: (attr: tree[], dic: fdic, array: tree[][]) => {
313
+ let d = dic?.delim?.[0]?.value || "(";
314
+ let o = { "(": ["(", ")"], "[": ["[", "]"], "{": ["{", "}"], "|": ["|", "|"], "||": ["‖", "‖"] };
315
+ let row = createMath("mrow");
316
+ let l = createMath("mo", o[d][0]);
317
+ let r = createMath("mo", o[d][1]);
318
+ let t = createMath("mtable");
319
+ for (let i of array) {
320
+ let tr = createMath("mtr");
321
+ for (let j of i) {
322
+ let td = createMath("mtd");
323
+ td.append(render(j));
324
+ tr.append(td);
325
+ }
326
+ t.append(tr);
327
+ }
328
+ row.append(l, t, r);
329
+ return row;
330
+ },
331
+ root: (attr: tree[], dic: fdic) => {
332
+ let row = createMath("mrow");
333
+ row.append(render(attr[0]));
334
+ let base = createMath("mrow");
335
+ base.append(render(attr[1]));
336
+ let root = createMath("mroot");
337
+ root.append(base, row);
338
+ return root;
339
+ },
340
+ sqrt: (attr: tree[], dic: fdic) => {
341
+ return f.root([[], attr[0]], null);
342
+ },
343
+ display: (attr: tree[], dic: fdic) => {},
344
+ inline: (attr: tree[], dic: fdic) => {},
345
+ script: (attr: tree[], dic: fdic) => {},
346
+ sscript: (attr: tree[], dic: fdic) => {},
347
+ upright: (attr: tree[], dic: fdic) => {
348
+ let r = createMath("mrow");
349
+ r.append(render(attr[0]));
350
+ r.querySelectorAll("mi").forEach((el) => {
351
+ if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "normal");
352
+ });
353
+ r.querySelectorAll("ms").forEach((el) => {
354
+ if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "normal");
355
+ });
356
+ return r;
357
+ },
358
+ italic: (attr: tree[], dic: fdic) => {
359
+ let r = createMath("mrow");
360
+ r.querySelectorAll("mi").forEach((el) => {
361
+ if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "italic");
362
+ });
363
+ r.querySelectorAll("ms").forEach((el) => {
364
+ if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "italic");
365
+ });
366
+ r.append(render(attr[0]));
367
+ return r;
368
+ },
369
+ bold: (attr: tree[], dic: fdic) => {
370
+ let r = createMath("mrow");
371
+ r.style.fontWeight = "bold";
372
+ r.append(render(attr[0]));
373
+ return r;
374
+ },
375
+ op: (attr: tree[], dic: fdic) => {
376
+ let f = createMath("mrow");
377
+ let str = createMath("ms", attr[0][0].value);
378
+ f.append(str);
379
+ // TODO dic.limit
380
+ return f;
381
+ },
382
+ underline: (attr: tree[], dic: fdic) => {
383
+ return underover_f("under", attr[0], "_", attr?.[1]?.[0]?.value);
384
+ },
385
+ overline: (attr: tree[], dic: fdic) => {
386
+ return underover_f("over", attr[0], "‾", attr?.[1]?.[0]?.value);
387
+ },
388
+ underbrace: (attr: tree[], dic: fdic) => {
389
+ return underover_f("under", attr[0], "⏟", attr?.[1]?.[0]?.value);
390
+ },
391
+ overbrace: (attr: tree[], dic: fdic) => {
392
+ return underover_f("over", attr[0], "⏞", attr?.[1]?.[0]?.value);
393
+ },
394
+ underbracket: (attr: tree[], dic: fdic) => {
395
+ return underover_f("under", attr[0], "⎵", attr?.[1]?.[0]?.value);
396
+ },
397
+ overbracket: (attr: tree[], dic: fdic) => {
398
+ return underover_f("over", attr[0], "⎴", attr?.[1]?.[0]?.value);
399
+ },
400
+ serif: (attr: tree[], dic: fdic) => {},
401
+ sans: (attr: tree[], dic: fdic) => {},
402
+ frak: (attr: tree[], dic: fdic) => {},
403
+ mono: (attr: tree[], dic: fdic) => {},
404
+ bb: (attr: tree[], dic: fdic) => {},
405
+ cal: (attr: tree[], dic: fdic) => {},
406
+ vec: (attr: tree[], dic: fdic) => {
407
+ let d = dic?.delim?.[0]?.value || "(";
408
+ let o = { "(": ["(", ")"], "[": ["[", "]"], "{": ["{", "}"], "|": ["|", "|"], "||": ["‖", "‖"] };
409
+ let row = createMath("mrow");
410
+ let l = createMath("mo", o[d][0]);
411
+ let r = createMath("mo", o[d][1]);
412
+ let t = createMath("mtable");
413
+ for (let i of attr) {
414
+ let tr = createMath("mtr");
415
+ tr.append(render(i));
416
+ t.append(tr);
417
+ }
418
+ row.append(l, t, r);
419
+ return row;
420
+ },
421
+ // 额外
422
+ //
423
+ };
424
+
425
+ let opl: { id: string; str?: string; limits?: boolean }[] = [
426
+ { id: "arccos" },
427
+ { id: "arcsin" },
428
+ { id: "arctan" },
429
+ { id: "arg" },
430
+ { id: "cos" },
431
+ { id: "cosh" },
432
+ { id: "cot" },
433
+ { id: "ctg" },
434
+ { id: "coth" },
435
+ { id: "csc" },
436
+ { id: "deg" },
437
+ { id: "det", limits: true },
438
+ { id: "dim" },
439
+ { id: "exp" },
440
+ { id: "gcd", limits: true },
441
+ { id: "hom" },
442
+ { id: "mod" },
443
+ { id: "inf", limits: true },
444
+ { id: "ker" },
445
+ { id: "lg" },
446
+ { id: "lim", limits: true },
447
+ { id: "ln" },
448
+ { id: "log" },
449
+ { id: "max", limits: true },
450
+ { id: "min", limits: true },
451
+ { id: "Pr", limits: true },
452
+ { id: "sec" },
453
+ { id: "sin" },
454
+ { id: "sinc" },
455
+ { id: "sinh" },
456
+ { id: "sup", limits: true },
457
+ { id: "tan" },
458
+ { id: "tg" },
459
+ { id: "tanh" },
460
+ { id: "liminf", str: "lim inf", limits: true },
461
+ { id: "limsup", str: "lim sup", limits: true },
462
+ ];
463
+ function op_f() {
464
+ for (let i of opl) {
465
+ f[i.id] = (attr: tree[]) => {
466
+ let s = f.op([[{ type: "str", value: i.str || i.id }]], {});
467
+ if (attr) {
468
+ let f = document.createDocumentFragment();
469
+ f.append(s, kh(attr[0]));
470
+ return f;
471
+ } else {
472
+ return s;
473
+ }
474
+ };
475
+ }
476
+ }
477
+ op_f();
478
+
479
+ function accent_f() {
480
+ const l = [
481
+ "grave",
482
+ "acute",
483
+ "acute.double",
484
+ "hat",
485
+ "tilde",
486
+ "macron",
487
+ "breve",
488
+ "dot",
489
+ "dot.double",
490
+ "dot.triple",
491
+ "dot.quad",
492
+ "diaer",
493
+ "circle",
494
+ "arrow",
495
+ "arrow.l",
496
+ ];
497
+ for (let i of l) {
498
+ f[i] = (attr: tree[]) => {
499
+ let s = f.accent([attr[0], [{ type: "f", value: i }]], {});
500
+ return s;
501
+ };
502
+ }
503
+ }
504
+ accent_f();
505
+
506
+ function lr_f() {
507
+ let l: { name: string; l: tree[0]; r: tree[0] }[] = [
508
+ { name: "abs", l: v_f("|"), r: v_f("|") },
509
+ { name: "norm", l: v_f("‖"), r: v_f("‖") },
510
+ { name: "floor", l: v_f("⌊"), r: v_f("⌋") },
511
+ { name: "ceil", l: v_f("⌈"), r: v_f("⌉") },
512
+ { name: "round", l: v_f("⌊"), r: v_f("⌉") },
513
+ ];
514
+ for (let i of l) {
515
+ f[i.name] = (attr: tree[]) => {
516
+ let s = f.lr([[i.l, ...attr[0], i.r]], {});
517
+ return s;
518
+ };
519
+ }
520
+ }
521
+ lr_f();
522
+
523
+ function underover_f(type: "under" | "over", tree: tree, x: string, str?: string) {
524
+ let m =
525
+ type == "under"
526
+ ? createMath("munder", null, { accentunder: "true" })
527
+ : createMath("mover", null, { accent: "true" });
528
+ let base = createMath("mrow");
529
+ base.append(render(tree));
530
+ let xx = createMath("mo", x);
531
+ m.append(base, xx);
532
+ if (str) {
533
+ let s = createMath("ms", str);
534
+
535
+ let mm = type == "under" ? createMath("munder") : createMath("mover");
536
+ mm.append(m, s);
537
+ return mm;
538
+ }
539
+ return m;
540
+ }
541
+
542
+ function kh(tree: tree) {
543
+ let f = document.createDocumentFragment();
544
+ let l = createMath("ms");
545
+ l.innerText = "(";
546
+ let c = render(tree);
547
+ let r = createMath("ms");
548
+ r.innerText = ")";
549
+ f.append(l, c, r);
550
+ return f;
551
+ }
552
+
553
+ function out_kh(x: tree[0]) {
554
+ if (x.type == "group") {
555
+ return x.children;
556
+ } else {
557
+ return [x];
558
+ }
559
+ }
560
+
561
+ function is_limit(tree: tree) {
562
+ if (tree.length == 1) {
563
+ let x = tree[0];
564
+ if (x.type == "f") {
565
+ if (x.value == "sum" || x.value == "limits") {
566
+ return true;
567
+ }
568
+ for (let i of opl) {
569
+ if (i.limits && x.value == i.id) {
570
+ return true;
571
+ }
572
+ }
573
+ if (x.value == "scripts") return false;
574
+ if (x.value == "op") {
575
+ }
576
+ }
577
+ } else {
578
+ return false;
579
+ }
580
+ }
581
+
582
+ let dh: tree[0] = { type: "v", value: "," };
583
+
584
+ function v_f(str: string): tree[0] {
585
+ return { type: "v", value: str };
586
+ }
587
+
588
+ type fdic = { [id: string]: tree };
589
+
590
+ function dic_to_ast(dic: { [id: string]: tree }) {
591
+ let l: tree = [];
592
+ for (let i in dic) {
593
+ l.push({ type: "f", value: i });
594
+ l.push({ type: "v", value: ":" });
595
+ l.push(...dic[i]);
596
+ if (Number(i) + 1 != Object.keys(dic).length) {
597
+ l.push(dh);
598
+ }
599
+ }
600
+ return l;
601
+ }
602
+
603
+ function render(tree: tree) {
604
+ let fragment = document.createDocumentFragment();
605
+
606
+ // 处理数字和小数
607
+ {
608
+ let t: tree = [];
609
+ let num = /[0-9]/;
610
+ let number = "";
611
+ for (let i in tree) {
612
+ let n = Number(i);
613
+ let x = tree[n];
614
+ if (
615
+ x.value.match(num) ||
616
+ (tree[n - 1] &&
617
+ tree[n - 1].value.match(num) &&
618
+ x.value == "." &&
619
+ tree[n + 1] &&
620
+ tree[n + 1].value.match(num))
621
+ ) {
622
+ number += x.value;
623
+ } else {
624
+ t.push(x);
625
+ }
626
+ if (
627
+ x.value.match(num) &&
628
+ (!tree[n + 1] || !tree[n + 1].value.match(/[0-9]/)) &&
629
+ !(tree[n + 1]?.value == "." && tree[n + 2]?.value.match(num))
630
+ ) {
631
+ t.push({ type: "v", value: number });
632
+ number = "";
633
+ }
634
+ }
635
+ tree = t;
636
+ }
637
+
638
+ // 处理f
639
+ {
640
+ let t: tree = [];
641
+ let continue_c = 0;
642
+ for (let i in tree) {
643
+ if (continue_c > 0) {
644
+ continue_c--;
645
+ continue;
646
+ }
647
+ let n = Number(i);
648
+ let x = tree[n];
649
+
650
+ // 带有括号(参数)的函数
651
+ if (x.type == "f" && tree[n + 1] && tree[n + 1].type == "group") {
652
+ x.children = tree[n + 1].children;
653
+ t.push(x);
654
+
655
+ // 不处理group
656
+ continue_c = 1;
657
+ continue;
658
+ } else {
659
+ t.push(x);
660
+ }
661
+ }
662
+ tree = t;
663
+ }
664
+
665
+ // 移除blank
666
+ {
667
+ let t: tree = [];
668
+ for (let i of tree) {
669
+ if (i.type == "blank") continue;
670
+ t.push(i);
671
+ }
672
+ tree = t;
673
+ }
674
+
675
+ // 处理^_
676
+ {
677
+ // 获取^_嵌套索引
678
+ let index: [number, number][] = [];
679
+ let start = NaN;
680
+ for (let n = 0; n < tree.length; n++) {
681
+ const x = tree[n];
682
+ if (x.value != "^" && x.value != "_") {
683
+ if (
684
+ (tree[n + 1]?.value == "^" || tree[n + 1]?.value == "_") &&
685
+ !(tree[n - 1]?.value == "^" || tree[n - 1]?.value == "_")
686
+ ) {
687
+ if (!start) start = n;
688
+ }
689
+ if (
690
+ (tree[n - 1]?.value == "^" || tree[n - 1]?.value == "_") &&
691
+ !(tree[n + 1]?.value == "^" || tree[n + 1]?.value == "_")
692
+ ) {
693
+ index.push([start, n]);
694
+ start = NaN;
695
+ }
696
+ }
697
+ }
698
+
699
+ let t: tree = [];
700
+ let continue_c = 0;
701
+ for (let i in tree) {
702
+ if (continue_c > 0) {
703
+ continue_c--;
704
+ continue;
705
+ }
706
+ let n = Number(i);
707
+
708
+ if (n == index?.[0]?.[0]) {
709
+ {
710
+ let continue_c = 0;
711
+ let tmp: tree[0] = tree[index[0][1]];
712
+ for (let i = index[0][1]; i >= index[0][0]; i--) {
713
+ if (continue_c > 0) {
714
+ continue_c--;
715
+ continue;
716
+ }
717
+
718
+ if (tree[i - 1]?.value == "^" && tree[i - 3]?.value == "_") {
719
+ let o = is_limit([tree[i - 4]])
720
+ ? { t: out_kh(tmp), b: out_kh(tree[i - 2]) }
721
+ : { tr: out_kh(tmp), br: out_kh(tree[i - 2]) };
722
+ tmp = {
723
+ type: "f",
724
+ value: "attach",
725
+ children: [tree[i - 4], dh, ...dic_to_ast(o)],
726
+ };
727
+ continue_c = 4 - 1;
728
+ continue;
729
+ }
730
+ if (tree[i - 1]?.value == "_" && tree[i - 3]?.value == "^") {
731
+ let o = is_limit([tree[i - 4]])
732
+ ? { t: out_kh(tree[i - 2]), b: out_kh(tmp) }
733
+ : { tr: out_kh(tree[i - 2]), br: out_kh(tmp) };
734
+ tmp = {
735
+ type: "f",
736
+ value: "attach",
737
+ children: [tree[i - 4], dh, ...dic_to_ast(o)],
738
+ };
739
+ continue_c = 4 - 1;
740
+ continue;
741
+ }
742
+ if (tree[i - 1]?.value == "^") {
743
+ let o = is_limit([tree[i - 2]]) ? { t: out_kh(tmp) } : { tr: out_kh(tmp) };
744
+ tmp = {
745
+ type: "f",
746
+ value: "attach",
747
+ children: [tree[i - 2], dh, ...dic_to_ast(o)],
748
+ };
749
+ continue_c = 2 - 1;
750
+ continue;
751
+ }
752
+ if (tree[i - 1]?.value == "_") {
753
+ let o = is_limit([tree[i - 2]]) ? { b: out_kh(tmp) } : { br: out_kh(tmp) };
754
+ tmp = {
755
+ type: "f",
756
+ value: "attach",
757
+ children: [tree[i - 2], dh, ...dic_to_ast(o)],
758
+ };
759
+ continue_c = 2 - 1;
760
+ continue;
761
+ }
762
+ }
763
+ t.push(tmp);
764
+ }
765
+ continue_c = index[0][1] - index[0][0];
766
+ continue;
767
+ }
768
+
769
+ t.push(tree[i]);
770
+ }
771
+ tree = t;
772
+ }
773
+
774
+ // 处理/
775
+ {
776
+ // 获取/嵌套索引
777
+ let index: [number, number][] = [];
778
+ let start = NaN;
779
+ for (let n = 0; n < tree.length; n++) {
780
+ const x = tree[n];
781
+ if (x.value != "/") {
782
+ if (tree[n + 1]?.value == "/" && !(tree[n - 1]?.value == "/")) {
783
+ if (!start) start = n;
784
+ }
785
+ if (tree[n - 1]?.value == "/" && !(tree[n + 1]?.value == "/")) {
786
+ index.push([start, n]);
787
+ start = NaN;
788
+ }
789
+ }
790
+ }
791
+
792
+ let t: tree = [];
793
+ let continue_c = 0;
794
+ for (let i in tree) {
795
+ if (continue_c > 0) {
796
+ continue_c--;
797
+ continue;
798
+ }
799
+ let n = Number(i);
800
+
801
+ if (n == index?.[0]?.[0]) {
802
+ {
803
+ let continue_c = 0;
804
+ let tmp: tree[0] = tree[index[0][0]];
805
+ for (let i = index[0][0]; i <= index[0][1]; i++) {
806
+ if (continue_c > 0) {
807
+ continue_c--;
808
+ continue;
809
+ }
810
+
811
+ if (tree[i + 1]?.value == "/") {
812
+ tmp = {
813
+ type: "f",
814
+ value: "frac",
815
+ children: [...out_kh(tmp), dh, ...out_kh(tree[i + 2])],
816
+ };
817
+ continue_c = 2 - 1;
818
+ continue;
819
+ }
820
+ }
821
+ console.log(1, tmp);
822
+
823
+ t.push(tmp);
824
+ }
825
+ continue_c = index[0][1] - index[0][0];
826
+ index.splice(0, 1);
827
+ continue;
828
+ }
829
+
830
+ t.push(tree[i]);
831
+ }
832
+ tree = t;
833
+ }
834
+
835
+ let continue_c = 0;
836
+ for (let i in tree) {
837
+ if (continue_c > 0) {
838
+ continue_c--;
839
+ continue;
840
+ }
841
+ let n = Number(i);
842
+ let x = tree[n];
843
+
844
+ // 带有括号(参数)的函数
845
+ if (x.type == "f" && x.children) {
846
+ let type: "dic" | "array" | "attr" = "array";
847
+ let attr: tree[] = [];
848
+ let dicl: tree[] = [];
849
+ let array: tree[][] = [];
850
+ let l: tree = [];
851
+ for (let i in x.children) {
852
+ const t = x.children[i];
853
+ if (Number(i) + 1 == x.children.length) {
854
+ if (t.type == "blank" && x.children[Number(i) - 1].value.match(/[,;]/)) break;
855
+ if (t.value != "," && t.value != ";") l.push(t);
856
+ if (type == "dic") {
857
+ dicl.push(l);
858
+ l = [];
859
+ } else {
860
+ attr.push(l);
861
+ }
862
+ if (array.length) {
863
+ array.push(attr);
864
+ attr = [];
865
+ }
866
+ l = [];
867
+ } else {
868
+ if (t.value == ",") {
869
+ if (type == "dic") {
870
+ dicl.push(l);
871
+ l = [];
872
+ } else {
873
+ attr.push(l);
874
+ }
875
+ l = [];
876
+ } else if (t.value == ";") {
877
+ // 存在; 则存好的attr为array的一个子元素
878
+ type == "array";
879
+ attr.push(l);
880
+ l = [];
881
+ array.push(attr);
882
+ attr = [];
883
+ } else {
884
+ // 按,拆分成段
885
+ l.push(t);
886
+ // 段中有: 为dic
887
+ if (t.value == ":") {
888
+ type = "dic";
889
+ }
890
+ }
891
+ }
892
+ }
893
+
894
+ // 将dicl的tree转为键对
895
+ let dic: fdic = {};
896
+ for (let i of dicl) {
897
+ let n = "";
898
+ let t: tree = [];
899
+ for (let el of i) {
900
+ if (!n) {
901
+ n = el.value;
902
+ } else {
903
+ if (el.value != ":") t.push(el);
904
+ }
905
+ }
906
+ dic[n] = t;
907
+ }
908
+
909
+ if (f[x.value]) {
910
+ console.log(attr, dic, array);
911
+ let el = f[x.value](attr, dic, array);
912
+ fragment.append(el);
913
+ }
914
+ }
915
+
916
+ if (x.type == "f" && !x.children) {
917
+ let l = x.value.split(".");
918
+ if (s[l[0]]) {
919
+ let v = "";
920
+ if (l.length == 1) {
921
+ if (typeof s[l[0]] == "string") {
922
+ v = s[l[0]];
923
+ } else {
924
+ // 获取第一个元素值
925
+ let o = s[l[0]][0];
926
+ if (typeof o == "string") {
927
+ v = o;
928
+ } else {
929
+ v = Object.values(o)[0] as string;
930
+ }
931
+ }
932
+ } else {
933
+ let p = l.slice(1).join(".");
934
+ for (let i of s[l[0]]) {
935
+ if (typeof i == "object") {
936
+ l: for (let k of Object.keys(i)) {
937
+ if (k == p) {
938
+ v = i[k];
939
+ break l;
940
+ } else {
941
+ let ll = k.split(".");
942
+ for (let n = 1; n < ll.length; n++) {
943
+ if (p == ll.slice(0, n).join(".")) {
944
+ v = i[k];
945
+ break l;
946
+ }
947
+ }
948
+ }
949
+ }
950
+ }
951
+ }
952
+ }
953
+ let el = createMath("mo", v);
954
+ fragment.append(el);
955
+ } else {
956
+ if (f[x.value]) {
957
+ let el = f[x.value]();
958
+ fragment.append(el);
959
+ }
960
+ }
961
+ }
962
+
963
+ if (x.type == "str") {
964
+ let el = createMath("ms", x.value);
965
+ fragment.append(el);
966
+ }
967
+
968
+ if (x.type == "v") {
969
+ let tag: mathtag;
970
+ if (x.value.match(/[0-9]+/)) {
971
+ tag = "mn";
972
+ } else if (x.value.match(/[a-zA-Z]/)) {
973
+ tag = "mi";
974
+ } else {
975
+ tag = "mo";
976
+ }
977
+ let el = createMath(tag, x.value);
978
+ fragment.append(el);
979
+ }
980
+
981
+ if (x.type == "group") {
982
+ fragment.append(kh(x.children));
983
+ }
984
+ }
985
+
986
+ return fragment;
987
+ }
988
+
989
+ function toMML(str: string) {
990
+ let obj = ast(str);
991
+ console.log(obj);
992
+
993
+ let mathEl = createEl("math");
994
+ mathEl.setAttribute("display", "block");
995
+ let f = render(obj);
996
+ mathEl.append(f);
997
+ return mathEl;
998
+ }
999
+
1000
+ function toMMLHTML(str: string) {
1001
+ return toMML(str).outerHTML;
1002
+ }
1003
+
1004
+ export { toMML, toMMLHTML };