xmmath 1.0.7 → 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/src/main.ts CHANGED
@@ -24,17 +24,20 @@ function createMath<K extends keyof MathMLElementTagNameMap>(
24
24
 
25
25
  const mathvariant = "mathvariant";
26
26
 
27
- import GraphemeSplitter from "grapheme-splitter";
28
- var splitter = new GraphemeSplitter();
27
+ const Segmenter = Intl.Segmenter;
28
+ const segmenter = new Segmenter("emoji", { granularity: "grapheme" });
29
29
 
30
- type vtype = "" | "str" | "v" | "f" | "blank" | "group" | "group1"; // group1组合基本类型,提高优先级
31
- type tree = { type: vtype; value: string; children?: tree; esc?: boolean }[];
30
+ type vtype = "" | "str" | "v" | "f" | "blank" | "group" | "group1" | "sharp"; // group1组合基本类型,提高优先级
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
- let blank = /[ \t\n\r]+/;
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 == '"' && str[i - 1] != "\\") {
57
+ if (t === '"' && last != "\\" && !ignore) {
54
58
  if (type != "str") {
55
59
  type = "str";
56
60
  } else {
@@ -58,27 +62,71 @@ function ast(str: string) {
58
62
  }
59
63
  continue;
60
64
  }
61
- if (type == "str") {
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 == 0) {
86
+ if (t.match(khr) && !ignore && last != "\\") {
87
+ if (lkh_stack.length === 0) {
70
88
  rkh_stack.push(i);
71
89
  } else {
72
- if (str[i - 1] != "\\") lkh_stack.pop();
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 ? splitter.splitGraphemes(str) : [...str];
78
104
  for (let i = 0; i < strl.length; i++) {
79
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
+ }
80
128
  // 字符
81
- if (t == '"' && strl[i - 1] != "\\") {
129
+ if (t === '"' && strl[i - 1] != "\\") {
82
130
  if (type != "str") {
83
131
  type = "str";
84
132
  } else {
@@ -97,9 +145,10 @@ function ast(str: string) {
97
145
  if (t.match(blank)) {
98
146
  type = "blank";
99
147
  }
100
- if (type == "blank" && !t.match(blank)) {
101
- now_tree.push({ type, value: "" });
102
- type = "";
148
+
149
+ if (t === "#") {
150
+ now_tree.push({ type: "sharp", value: "" });
151
+ continue;
103
152
  }
104
153
 
105
154
  // 原始值(字母变量、数字、符号)
@@ -130,22 +179,27 @@ function ast(str: string) {
130
179
  tmp_str = "";
131
180
  }
132
181
 
133
- if (t == "(") {
134
- if (lkh_stack.includes(i) || strl[i - 1] == "\\") {
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)) {
135
186
  now_tree.push({ type: "v", value: t });
136
187
  } else {
137
188
  p_tree.push({ tree: now_tree, close: false });
138
- now_tree.push({ type: "group", value: tmp_str, children: [] });
189
+ now_tree.push({ type: "group", value: tmp_str, children: [], kh: t });
139
190
  now_tree = now_tree.at(-1).children;
140
191
  tmp_str = "";
141
192
  continue;
142
193
  }
143
194
  }
144
- if (t == ")") {
145
- if (p_tree.at(-1)) {
146
- if (p_tree.at(-1).close == false) {
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) {
147
200
  p_tree.at(-1).close = true;
148
201
  now_tree = p_tree.at(-1).tree;
202
+ now_tree.at(-1).kh += t;
149
203
  p_tree.pop();
150
204
  continue;
151
205
  }
@@ -159,37 +213,46 @@ function ast(str: string) {
159
213
  }
160
214
 
161
215
  import symbols from "./symbols.json?raw";
162
- /** @see https://github.com/typst/typst/blob/v0.6.0/library/src/symbols/sym.rs */
216
+ /** @see https://github.com/typst/typst/blob/v0.11.1/crates/typst/src/symbols/sym.rs */
163
217
  let s = JSON.parse(symbols);
164
218
 
165
219
  // symbols路径简写
166
- let ss: { [id: string]: string } = {};
167
- for (let i in s) {
168
- if (typeof s[i] == "string") {
169
- ss[i] = s[i];
170
- } else {
171
- for (let objOrStr of s[i]) {
172
- // 第二层的array
173
- if (typeof objOrStr == "string") {
174
- ss[i] = objOrStr;
175
- } else {
176
- if (!ss[i]) ss[i] = objOrStr[Object.keys(objOrStr)[0]];
177
- for (let j in objOrStr) {
178
- // 第三层的obj
179
- ss[`${i}.${j}`] = objOrStr[j];
180
- // 允许部分索引,但要保证唯一
181
- let l = j.split(".");
182
- for (let n = 1; n < l.length; n++) {
183
- let shotKey = l.slice(0, n).join(".");
184
- if (!objOrStr[shotKey]) {
185
- ss[`${i}.${shotKey}`] = objOrStr[j];
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
+ }
186
243
  }
187
244
  }
188
245
  }
189
246
  }
190
247
  }
191
248
  }
249
+ return ss;
192
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));
193
256
 
194
257
  let shorthand = {
195
258
  "->": "arrow.r",
@@ -242,31 +305,50 @@ for (let i in shorthand) {
242
305
  }
243
306
  }
244
307
 
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
+ }
325
+
245
326
  let f: {
246
- [name: string]: (attr?: tree[], dic?: fdic, array?: tree[][], e?: fonts) => MathMLElement | DocumentFragment;
327
+ [name: string]: (attr: tree[], dic?: fdic, e?: fonts) => MathMLElement | DocumentFragment;
247
328
  } = {
248
- accent: (attr: tree[], dic: fdic) => {
329
+ accent: (attr: tree[], dic: fdic, e) => {
249
330
  let base = createMath("mrow");
250
- base.append(render(attr[0]));
331
+ base.append(render(attr[0], e));
251
332
  let a = createMath("mrow");
252
- a.append(render(attr[1]));
333
+ a.append(render(attr[1], e));
334
+ a.children[0].innerHTML = accent_match_str(a.children[0].innerHTML);
253
335
  let over = createMath("mover");
254
336
  over.setAttribute("accent", "true");
255
337
  over.append(base, a);
256
338
  return over;
257
339
  },
258
- attach: (attr: tree[], dic: fdic) => {
340
+ attach: (attr: tree[], dic: fdic, e) => {
259
341
  let base = createMath("mrow");
260
342
  base.append(render(attr[0]));
261
343
  let el: MathMLElement;
262
344
  let tl = createMath("mrow");
263
- if (dic.tl) tl.append(render(dic.tl));
345
+ if (dic.tl) tl.append(render(dic.tl, e));
264
346
  let bl = createMath("mrow");
265
- if (dic.bl) bl.append(render(dic.bl));
347
+ if (dic.bl) bl.append(render(dic.bl, e));
266
348
  let tr = createMath("mrow");
267
- if (dic.tr) tr.append(render(dic.tr));
349
+ if (dic.tr) tr.append(render(dic.tr, e));
268
350
  let br = createMath("mrow");
269
- if (dic.br) br.append(render(dic.br));
351
+ if (dic.br) br.append(render(dic.br, e));
270
352
  if (dic.tl || dic.bl || dic.tr || dic.br) {
271
353
  if (dic.tl || dic.bl) {
272
354
  el = createMath("mmultiscripts");
@@ -290,26 +372,28 @@ let f: {
290
372
  uo.append(el);
291
373
  }
292
374
  let t = createMath("mrow");
293
- if (dic.t) t.append(render(dic.t));
375
+ if (dic.t) t.append(render(dic.t, e));
294
376
  let b = createMath("mrow");
295
- if (dic.b) b.append(render(dic.b));
377
+ if (dic.b) b.append(render(dic.b, e));
296
378
  uo.append(b, t);
297
379
  el = uo;
298
380
  }
299
381
  return el;
300
382
  },
301
- scripts: (attr: tree[], dic: fdic) => {
302
- return render(attr[0]);
383
+ scripts: (attr: tree[], dic: fdic, e) => {
384
+ return render(attr[0], e);
303
385
  },
304
- limits: (attr: tree[], dic: fdic) => {
305
- return render(attr[0]);
386
+ limits: (attr: tree[], dic: fdic, e) => {
387
+ return render(attr[0], e);
306
388
  },
307
- binom: (attr: tree[], dic: fdic) => {
389
+ binom: (attr: tree[], dic: fdic, e) => {
308
390
  let row = createMath("mrow");
309
391
  let a = createMath("mrow");
310
- a.append(render(attr[0]));
392
+ a.append(render(attr[0], e));
311
393
  let b = createMath("mrow");
312
- b.append(render(attr[1]));
394
+ const s: tree = [];
395
+ for (let x of attr.slice(1)) s.push(...x, dh);
396
+ b.append(render(s.slice(0, -1), e));
313
397
  let f = createMath("mfrac", null, { linethickness: "0" });
314
398
  f.append(a, b);
315
399
  let l = createMath("mo", "(");
@@ -317,7 +401,7 @@ let f: {
317
401
  row.append(l, f, r);
318
402
  return row;
319
403
  },
320
- cancel: (attr: tree[], dic: fdic) => {
404
+ cancel: (attr: tree[], dic: fdic, e) => {
321
405
  let r = createMath("mrow");
322
406
  const bg = (x: boolean) =>
323
407
  `linear-gradient(to ${
@@ -332,64 +416,100 @@ let f: {
332
416
  s = bg(true);
333
417
  }
334
418
  r.style.backgroundImage = s;
335
- r.append(render(attr[0]));
419
+ r.append(render(attr[0], e));
336
420
  return r;
337
421
  },
338
- cases: (attr: tree[], dic: fdic) => {
422
+ cases: (attr: tree[], dic: fdic, e) => {
339
423
  let r = createMath("mrow");
340
- let l = createMath("mo", dic?.delim?.[0]?.value || "{");
341
- let t = f.x_table(attr, { cases: [] });
342
- r.append(l, t);
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";
427
+ t.setAttribute("rowspacing", gap);
428
+ if (is_true(dic?.reverse)) {
429
+ const l = createMath("mo", d[1]);
430
+ r.append(t, l);
431
+ } else {
432
+ const l = createMath("mo", d[0]);
433
+ r.append(l, t);
434
+ }
343
435
  return r;
344
436
  },
345
- frac: (attr: tree[], dic: fdic) => {
346
- console.log(attr);
347
-
437
+ frac: (attr: tree[], dic: fdic, e) => {
348
438
  let a = createMath("mrow");
349
- a.append(render(attr[0]));
439
+ a.append(render(attr[0], e));
350
440
  let b = createMath("mrow");
351
- b.append(render(attr[1]));
441
+ b.append(render(attr[1], e));
352
442
  let f = createMath("mfrac");
353
443
  f.append(a, b);
354
444
  return f;
355
445
  },
356
- lr: (attr: tree[], dic: fdic) => {
357
- let list = attr[0];
358
- let start: { c: tree; n: number }, end: { c: tree; n: number };
359
- for (let i = 0; i < list.length; i++) {
360
- const el = list[i];
361
- if (el.type == "blank") continue;
362
- start = { c: [el], n: i };
363
- break;
364
- }
365
- for (let i = list.length - 1; i >= 0; i--) {
366
- const el = list[i];
367
- if (el.type == "blank") continue;
368
- end = { c: [el], n: i };
369
- break;
370
- }
371
- let l = document.createDocumentFragment();
372
- l.append(render(start.c));
373
- let r = document.createDocumentFragment();
374
- r.append(render(end.c));
375
- let c = document.createDocumentFragment();
376
- c.append(render(list.slice(start.n + 1, end.n)));
377
- let row = createMath("mrow");
378
- row.append(l, c, r);
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);
452
+ const row = createMath("mrow");
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
+ }
379
462
  return row;
380
463
  },
381
- mat: (attr: tree[], dic: fdic, array: tree[][]) => {
382
- let d = dic?.delim?.[0]?.value || "(";
383
- let o = { "(": ["(", ")"], "[": ["[", "]"], "{": ["{", "}"], "|": ["|", "|"], "||": ["‖", "‖"] };
464
+ mid: (attr: tree[], dic: fdic) => {
465
+ const o = createMath("mo", attr?.[0]?.[0]?.value, { stretchy: "true" });
466
+ return o;
467
+ },
468
+ mat: (attr: tree[] | tree[][], dic: fdic, e) => {
469
+ let d = delim(dic, "(");
384
470
  let row = createMath("mrow");
385
- let l = createMath("mo", o[d][0]);
386
- let r = createMath("mo", o[d][1]);
471
+ let l = createMath("mo", d[0]);
472
+ let r = createMath("mo", d[1]);
387
473
  let t = createMath("mtable");
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");
479
+ if (augment) {
480
+ let xa = NaN;
481
+ let ya = NaN;
482
+ if (typeof augment != "object") {
483
+ xa = Number(augment);
484
+ } else {
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(""));
487
+ }
488
+ if (xa < 0) xa = array[0].length + xa;
489
+ if (ya < 0) ya = array.length + ya;
490
+
491
+ if (ya) {
492
+ let l: boolean[] = [];
493
+ for (let i = 1; i < array.length; i++) l.push(i === ya);
494
+ t.setAttribute("rowlines", l.map((i) => (i ? "solid" : "none")).join(" "));
495
+ }
496
+ if (xa) {
497
+ let l: boolean[] = [];
498
+ for (let i = 1; i < array[0].length; i++) l.push(i === xa);
499
+ t.setAttribute("columnlines", l.map((i) => (i ? "solid" : "none")).join(" "));
500
+ }
501
+ }
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;
505
+ t.setAttribute("columnspacing", colgap || gap || "0.5em");
506
+ t.setAttribute("rowspacing", rowgap || gap || "0.5em");
507
+
388
508
  for (let i of array) {
389
509
  let tr = createMath("mtr");
390
510
  for (let j of i) {
391
511
  let td = createMath("mtd");
392
- td.append(render(j));
512
+ td.append(render(j, e));
393
513
  tr.append(td);
394
514
  }
395
515
  t.append(tr);
@@ -397,41 +517,41 @@ let f: {
397
517
  row.append(l, t, r);
398
518
  return row;
399
519
  },
400
- root: (attr: tree[], dic: fdic) => {
520
+ root: (attr: tree[], dic: fdic, e) => {
401
521
  let row = createMath("mrow");
402
- row.append(render(attr[0]));
522
+ row.append(render(attr[0], e));
403
523
  let base = createMath("mrow");
404
- base.append(render(attr[1]));
524
+ base.append(render(attr[1], e));
405
525
  let root = createMath("mroot");
406
526
  root.append(base, row);
407
527
  return root;
408
528
  },
409
- sqrt: (attr: tree[], dic: fdic) => {
410
- return f.root([[], attr[0]], null);
529
+ sqrt: (attr: tree[], dic: fdic, e) => {
530
+ return f.root([[], attr[0]], null, e);
411
531
  },
412
- display: (attr: tree[], dic: fdic) => {
532
+ display: (attr: tree[], dic: fdic, e) => {
413
533
  let m = createMath("mrow", null, { displaystyle: "true" });
414
- m.append(render(attr[0]));
534
+ m.append(render(attr[0], e));
415
535
  return m;
416
536
  },
417
- inline: (attr: tree[], dic: fdic) => {
537
+ inline: (attr: tree[], dic: fdic, e) => {
418
538
  let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "0" });
419
- m.append(render(attr[0]));
539
+ m.append(render(attr[0], e));
420
540
  return m;
421
541
  },
422
- script: (attr: tree[], dic: fdic) => {
542
+ script: (attr: tree[], dic: fdic, e) => {
423
543
  let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "1" });
424
- m.append(render(attr[0]));
544
+ m.append(render(attr[0], e));
425
545
  return m;
426
546
  },
427
- sscript: (attr: tree[], dic: fdic) => {
547
+ sscript: (attr: tree[], dic: fdic, e) => {
428
548
  let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "2" });
429
- m.append(render(attr[0]));
549
+ m.append(render(attr[0], e));
430
550
  return m;
431
551
  },
432
- upright: (attr: tree[], dic: fdic) => {
552
+ upright: (attr: tree[], dic: fdic, e) => {
433
553
  let r = createMath("mrow");
434
- r.append(render(attr[0]));
554
+ r.append(render(attr[0], e));
435
555
  r.querySelectorAll("mi").forEach((el) => {
436
556
  if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "normal");
437
557
  });
@@ -440,133 +560,130 @@ let f: {
440
560
  });
441
561
  return r;
442
562
  },
443
- italic: (attr: tree[], dic: fdic) => {
563
+ italic: (attr: tree[], dic: fdic, e) => {
444
564
  let r = createMath("mrow");
565
+ r.append(render(attr[0], e));
445
566
  r.querySelectorAll("mi").forEach((el) => {
446
567
  if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "italic");
447
568
  });
448
569
  r.querySelectorAll("ms").forEach((el) => {
449
570
  if (!el.getAttribute(mathvariant)) el.setAttribute(mathvariant, "italic");
450
571
  });
451
- r.append(render(attr[0]));
452
572
  return r;
453
573
  },
454
- bold: (attr: tree[], dic: fdic) => {
574
+ bold: (attr: tree[], dic: fdic, e) => {
455
575
  let r = createMath("mrow");
456
576
  r.style.fontWeight = "bold";
457
- r.append(render(attr[0]));
577
+ r.append(render(attr[0], e));
458
578
  return r;
459
579
  },
460
- op: (attr: tree[], dic: fdic, a, e) => {
580
+ op: (attr: tree[], dic: fdic, e) => {
461
581
  let f = createMath("mrow");
462
- let str = createMath("ms", font(attr[0][0].value, e));
582
+ let str = createMath("ms");
583
+ str.append(render(attr[0], e));
463
584
  f.append(str);
464
585
  return f;
465
586
  },
466
- underline: (attr: tree[], dic: fdic) => {
467
- return underover_f("under", attr[0], "_", attr?.[1]);
587
+ underline: (attr: tree[], dic: fdic, e) => {
588
+ return underover_line_f("under", attr[0], e);
468
589
  },
469
- overline: (attr: tree[], dic: fdic) => {
470
- return underover_f("over", attr[0], "‾", attr?.[1]);
590
+ overline: (attr: tree[], dic: fdic, e) => {
591
+ return underover_line_f("over", attr[0], e);
471
592
  },
472
- underbrace: (attr: tree[], dic: fdic) => {
473
- 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);
474
595
  },
475
- overbrace: (attr: tree[], dic: fdic) => {
476
- 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);
477
598
  },
478
- underbracket: (attr: tree[], dic: fdic) => {
479
- 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);
480
601
  },
481
- overbracket: (attr: tree[], dic: fdic) => {
482
- 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);
483
604
  },
484
- serif: (attr: tree[], dic: fdic) => {
605
+ serif: (attr: tree[]) => {
485
606
  return render(attr[0], "serif");
486
607
  },
487
- sans: (attr: tree[], dic: fdic) => {
608
+ sans: (attr: tree[]) => {
488
609
  return render(attr[0], "sans");
489
610
  },
490
- frak: (attr: tree[], dic: fdic) => {
611
+ frak: (attr: tree[]) => {
491
612
  return render(attr[0], "frak");
492
613
  },
493
- mono: (attr: tree[], dic: fdic) => {
614
+ mono: (attr: tree[]) => {
494
615
  return render(attr[0], "mono");
495
616
  },
496
- bb: (attr: tree[], dic: fdic) => {
617
+ bb: (attr: tree[]) => {
497
618
  return render(attr[0], "bb");
498
619
  },
499
- cal: (attr: tree[], dic: fdic) => {
620
+ cal: (attr: tree[]) => {
500
621
  return render(attr[0], "cal");
501
622
  },
502
- vec: (attr: tree[], dic: fdic) => {
503
- let d = dic?.delim?.[0]?.value || "(";
504
- let o = { "(": ["(", ")"], "[": ["[", "]"], "{": ["{", "}"], "|": ["|", "|"], "||": ["‖", "‖"] };
623
+ vec: (attr: tree[], dic: fdic, e) => {
624
+ let d = delim(dic, "(");
505
625
  let row = createMath("mrow");
506
- let l = createMath("mo", o[d][0]);
507
- let r = createMath("mo", o[d][1]);
508
- let t = createMath("mtable");
509
- for (let i of attr) {
510
- let tr = createMath("mtr");
511
- tr.append(render(i));
512
- t.append(tr);
513
- }
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";
630
+ t.setAttribute("rowspacing", gap);
631
+ t.setAttribute("columnspacing", "0.5em");
514
632
  row.append(l, t, r);
515
633
  return row;
516
634
  },
635
+ h: (attr: tree[], dic: fdic) => {
636
+ return createMath("mspace", "", { width: attr[0][0].value });
637
+ },
517
638
  // 额外
518
639
  //
519
640
  x_table: (attr: tree[], dic: fdic) => {
520
- let max = 0;
521
- let t = createMath("mtable");
522
- for (let i of attr) {
523
- let r = createMath("mtr");
524
-
525
- // 按&拆分
526
- let result: tree[] = [];
527
- let tmp_group: tree = [];
528
- for (let n = 0; n < i.length; n++) {
529
- if (!i[n].esc && i[n].value == "&") {
530
- if (tmp_group.length > 0) {
531
- result.push(tmp_group);
532
- tmp_group = [];
533
- }
534
- } else {
535
- tmp_group.push(i[n]);
536
- }
537
- }
538
- if (tmp_group.length > 0) {
539
- result.push(tmp_group);
540
- }
541
-
542
- 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
+ };
543
646
 
544
- for (let i of result) {
545
- let d = createMath("mtd");
546
- r.append(d);
547
- d.append(render(i));
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]);
548
664
  }
549
-
550
- t.append(r);
551
665
  }
552
- let al = [];
553
- if (dic.cases) {
554
- // cases
555
- al.push("left");
556
- } else {
557
- // 其他换行对齐 交替
558
- for (let i = 0; i < max; i++) {
559
- if (i % 2 == 0) {
560
- al.push("right");
561
- } else {
562
- al.push("left");
563
- }
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");
564
679
  }
565
680
  }
566
681
  t.setAttribute("columnalign", al.join(" "));
567
- return t;
568
- },
569
- };
682
+ t.setAttribute("columnspacing", "0");
683
+ t.append(r);
684
+ }
685
+ return t;
686
+ }
570
687
 
571
688
  let opl: { id: string; str?: string; limits?: boolean }[] = [
572
689
  { id: "arccos" },
@@ -579,6 +696,7 @@ let opl: { id: string; str?: string; limits?: boolean }[] = [
579
696
  { id: "ctg" },
580
697
  { id: "coth" },
581
698
  { id: "csc" },
699
+ { id: "csch" },
582
700
  { id: "deg" },
583
701
  { id: "det", limits: true },
584
702
  { id: "dim" },
@@ -586,6 +704,8 @@ let opl: { id: string; str?: string; limits?: boolean }[] = [
586
704
  { id: "gcd", limits: true },
587
705
  { id: "hom" },
588
706
  { id: "mod" },
707
+ { id: "id" },
708
+ { id: "im" },
589
709
  { id: "inf", limits: true },
590
710
  { id: "ker" },
591
711
  { id: "lg" },
@@ -596,23 +716,27 @@ let opl: { id: string; str?: string; limits?: boolean }[] = [
596
716
  { id: "min", limits: true },
597
717
  { id: "Pr", limits: true },
598
718
  { id: "sec" },
719
+ { id: "sech" },
599
720
  { id: "sin" },
600
721
  { id: "sinc" },
601
722
  { id: "sinh" },
602
723
  { id: "sup", limits: true },
603
724
  { id: "tan" },
604
725
  { id: "tg" },
726
+ { id: "tr" },
605
727
  { id: "tanh" },
606
728
  { id: "liminf", str: "lim inf", limits: true },
607
729
  { id: "limsup", str: "lim sup", limits: true },
730
+ { id: "dif", str: "d" },
731
+ { id: "Dif", str: "D" },
608
732
  ];
609
733
  function op_f() {
610
734
  for (let i of opl) {
611
- f[i.id] = (attr: tree[], a, b, e) => {
612
- let s = f.op([[{ type: "str", value: i.str || i.id }]], {}, null, e);
735
+ f[i.id] = (attr: tree[], a, e) => {
736
+ let s = f.op([[{ type: "str", value: i.str || i.id }]], {}, e);
613
737
  if (attr) {
614
738
  let f = document.createDocumentFragment();
615
- f.append(s, kh(attr[0]));
739
+ f.append(s, kh(attr_join(attr)));
616
740
  return f;
617
741
  } else {
618
742
  return s;
@@ -622,6 +746,20 @@ function op_f() {
622
746
  }
623
747
  op_f();
624
748
 
749
+ const spaceConst = {
750
+ quad: "1em",
751
+ med: "0.222em",
752
+ thin: "0.17em",
753
+ thick: "0.28em",
754
+ wide: "2em",
755
+ };
756
+
757
+ for (let i in spaceConst) {
758
+ f[i] = () => {
759
+ return f.h([[{ type: "str", value: spaceConst[i] }]]);
760
+ };
761
+ }
762
+
625
763
  let limits_f = [];
626
764
  let limits_sy = ["∏", "∐", "∑", "⋀", "⋁", "⋂", "⋃", "⨀", "⨁", "⨂", "⨃", "⨄", "⨅", "⨆"];
627
765
  for (let i in ss) {
@@ -632,6 +770,78 @@ for (let i in ss) {
632
770
  }
633
771
  }
634
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
+
635
845
  function accent_f() {
636
846
  const l = [
637
847
  "grave",
@@ -648,11 +858,17 @@ function accent_f() {
648
858
  "diaer",
649
859
  "circle",
650
860
  "arrow",
861
+ "arrow.r",
651
862
  "arrow.l",
863
+ "arrow.l.r",
864
+ "caron",
865
+ "harpoon",
866
+ "harpoon.rt",
867
+ "harpoon.lt",
652
868
  ];
653
869
  for (let i of l) {
654
- f[i] = (attr: tree[]) => {
655
- 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);
656
872
  return s;
657
873
  };
658
874
  }
@@ -668,25 +884,25 @@ function lr_f() {
668
884
  { name: "round", l: v_f("⌊"), r: v_f("⌉") },
669
885
  ];
670
886
  for (let i of l) {
671
- f[i.name] = (attr: tree[]) => {
672
- let s = f.lr([[i.l, ...attr[0], i.r]], {});
887
+ f[i.name] = (attr: tree[], dic, e) => {
888
+ let s = f.lr([[i.l, ...attr[0], i.r]], dic, e);
673
889
  return s;
674
890
  };
675
891
  }
676
892
  }
677
893
  lr_f();
678
894
 
679
- function underover_f(type: "under" | "over", tree: tree, x: string, str?: tree) {
895
+ function underover_f(type: "under" | "over", tree: tree, x: string, str: tree, e: fonts) {
680
896
  let m =
681
- type == "under"
897
+ type === "under"
682
898
  ? createMath("munder", null, { accentunder: "true" })
683
899
  : createMath("mover", null, { accent: "true" });
684
900
  let base = createMath("mrow");
685
- base.append(render(tree));
901
+ base.append(render(tree, e));
686
902
  if (str) {
687
903
  let s = createMath("mrow");
688
- s.append(render(str));
689
- let mm = type == "under" ? createMath("munder") : createMath("mover");
904
+ s.append(render(str, e));
905
+ let mm = type === "under" ? createMath("munder") : createMath("mover");
690
906
  let xx = createMath("mo", x);
691
907
  mm.append(xx, s);
692
908
  m.append(base, mm);
@@ -697,6 +913,25 @@ function underover_f(type: "under" | "over", tree: tree, x: string, str?: tree)
697
913
  return m;
698
914
  }
699
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
+
700
935
  function kh(tree: tree) {
701
936
  let f = createMath("mrow");
702
937
  let l = createMath("mo");
@@ -709,28 +944,35 @@ function kh(tree: tree) {
709
944
  }
710
945
 
711
946
  function out_kh(x: tree[0]) {
712
- if (x.type == "group") {
713
- return x.children;
947
+ if (x.type === "group") {
948
+ if (x.kh === "()") return x.children;
949
+ else return [x];
714
950
  } else {
715
951
  return [x];
716
952
  }
717
953
  }
718
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
+
719
961
  function in_kh(x: tree) {
720
- let k: tree = [{ type: "group", value: "", children: x }];
962
+ let k: tree = [{ type: "group", value: "", children: x, kh: "()" }];
721
963
  return k;
722
964
  }
723
965
 
724
966
  function is_sup(x: tree[0]) {
725
- return x && x.type == "v" && x.value == "^" && !x.esc;
967
+ return eqq(x, { type: "v", value: "^" });
726
968
  }
727
969
 
728
970
  function is_sub(x: tree[0]) {
729
- return x && x.type == "v" && x.value == "_" && !x.esc;
971
+ return eqq(x, { type: "v", value: "_" });
730
972
  }
731
973
 
732
974
  function is_frac(x: tree[0]) {
733
- return x && x.type == "v" && x.value == "/" && !x.esc;
975
+ return eqq(x, { type: "v", value: "/" });
734
976
  }
735
977
 
736
978
  function is_br(x: tree[0]) {
@@ -744,20 +986,17 @@ function is_limit(tree: tree) {
744
986
  if (limits_f.includes(x.value)) {
745
987
  return true;
746
988
  }
989
+ if (x.value.split(".").at(0) === "arrow") return true;
747
990
  for (let i of opl) {
748
991
  if (i.limits && x.value == i.id) {
749
992
  return true;
750
993
  }
751
994
  }
752
- if (x.value == "scripts") return false;
753
- if (x.value == "op") {
995
+ if (x.value === "scripts") return false;
996
+ if (x.value === "limits") return true;
997
+ if (x.value === "op") {
754
998
  let { dic } = f_attr(x);
755
- let t = "";
756
- if (dic.limits)
757
- for (let i of dic.limits) {
758
- t += i.value;
759
- }
760
- return t == "#true";
999
+ return is_true(dic.limits);
761
1000
  }
762
1001
  }
763
1002
  if (x.type == "v" && limits_sy.includes(x.value)) {
@@ -773,7 +1012,7 @@ function is_f_mark(x: tree[0], str: string) {
773
1012
  }
774
1013
 
775
1014
  function is_dot(x: tree[0]) {
776
- return x && x.type == "v" && x.value == ".";
1015
+ return eq(x, { type: "v", value: "." });
777
1016
  }
778
1017
 
779
1018
  function is_dot_f(x: tree[0]) {
@@ -790,6 +1029,29 @@ function v_f(str: string): tree[0] {
790
1029
  return { type: "v", value: str };
791
1030
  }
792
1031
 
1032
+ function eq(x0: tree[0], x1: tree[0]) {
1033
+ if (!x0 || !x1) return false;
1034
+ return x0.type === x1.type && x0.value === x1.value;
1035
+ }
1036
+
1037
+ function eqq(x0: tree[0], x1: tree[0]) {
1038
+ if (!x0 || !x1) return false;
1039
+ return x0.type === x1.type && x0.value === x1.value && x0?.esc === x1?.esc;
1040
+ }
1041
+
1042
+ function is_type(x: tree[0], ...type: vtype[]) {
1043
+ return type.includes(x?.type);
1044
+ }
1045
+
1046
+ function trim(tree: 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);
1053
+ }
1054
+
793
1055
  type fdic = { [id: string]: tree };
794
1056
 
795
1057
  function dic_to_ast(dic: { [id: string]: tree }) {
@@ -798,7 +1060,7 @@ function dic_to_ast(dic: { [id: string]: tree }) {
798
1060
  l.push({ type: "f", value: i });
799
1061
  l.push({ type: "v", value: ":" });
800
1062
  for (let x of dic[i]) {
801
- if (x.type == "v" && x.value == ",") x.esc = true;
1063
+ if (eq(x, dh)) x.esc = true;
802
1064
  }
803
1065
  l.push(...dic[i]);
804
1066
  if (Number(i) + 1 != Object.keys(dic).length) {
@@ -808,17 +1070,49 @@ function dic_to_ast(dic: { [id: string]: tree }) {
808
1070
  return l;
809
1071
  }
810
1072
 
811
- function is_true(t: tree) {
812
- let n = 0;
813
- if (t) {
814
- if (t[0].type == "blank") n++;
815
- if (t[n] && t[n].type == "v" && t[n].value == "#") {
816
- if (t[n + 1] && t[n + 1].type == "f" && t[n + 1].value == "true") {
817
- return true;
1073
+ function lan_dic(tree: tree) {
1074
+ tree = trim(tree);
1075
+ const o = new Object();
1076
+ let key = "";
1077
+ let value: tree = [];
1078
+ tree.push(dh);
1079
+ for (let i = 0; i < tree.length; i++) {
1080
+ if (!key && tree[i].type != "blank") {
1081
+ key = tree[i].value;
1082
+ } else {
1083
+ if (value.length) {
1084
+ if (eqq(tree[i], dh)) {
1085
+ o[key] = trim(value);
1086
+ key = "";
1087
+ value = [];
1088
+ } else value.push(tree[i]);
1089
+ } else {
1090
+ if (eqq(tree[i], v_f(":"))) {
1091
+ value.push(tree[i + 1]);
1092
+ }
818
1093
  }
819
1094
  }
820
1095
  }
821
- return false;
1096
+ return o;
1097
+ }
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
+
1114
+ function is_true(t: tree) {
1115
+ return eqq(trim(t)?.[0], { type: "sharp", value: "true" });
822
1116
  }
823
1117
 
824
1118
  function ast2(tree: tree) {
@@ -846,13 +1140,54 @@ function ast2(tree: tree) {
846
1140
  tree = t;
847
1141
  }
848
1142
 
1143
+ // 处理\转义
1144
+ {
1145
+ let t: tree = [];
1146
+ for (let n = 0; n < tree.length; n++) {
1147
+ let x = tree[n];
1148
+
1149
+ if (eqq(x, v_f("\\"))) {
1150
+ if (tree?.[n + 1]) {
1151
+ let next = tree[n + 1];
1152
+ if (eq(next, v_f("\\"))) {
1153
+ t.push({ type: "v", value: "\\", esc: true });
1154
+ n++;
1155
+ } else if (next.type === "blank") {
1156
+ t.push({ type: "v", value: "br", esc: true });
1157
+ n++;
1158
+ } else if (next.type === "f") {
1159
+ let v = next.value;
1160
+ t.push({ type: "v", value: v[0] });
1161
+ t.push({ type: v.length == 2 ? "v" : "f", value: v.slice(1) });
1162
+ n++;
1163
+ } else if (next.type === "sharp") {
1164
+ t.push({ type: "v", value: "#" });
1165
+ n++;
1166
+ } else {
1167
+ let v = next;
1168
+ v.esc = true;
1169
+ t.push(v);
1170
+ n++;
1171
+ }
1172
+ }
1173
+ } else {
1174
+ t.push(x);
1175
+ }
1176
+ }
1177
+ tree = t;
1178
+ }
1179
+
1180
+ return tree;
1181
+ }
1182
+
1183
+ function ast3(tree: tree) {
849
1184
  // 处理符号简写(shorthand)
850
1185
  {
851
1186
  let t: tree = [];
852
1187
  for (let n = 0; n < tree.length; n++) {
853
1188
  let x = tree[n];
854
1189
 
855
- if (tree?.[n - 1]?.value != "\\") {
1190
+ if (!x.esc) {
856
1191
  if (x.type == "v") {
857
1192
  let nn = n;
858
1193
  let shortkey = x.value;
@@ -865,7 +1200,7 @@ function ast2(tree: tree) {
865
1200
  nn++;
866
1201
  }
867
1202
  if (l.length) {
868
- 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) };
869
1204
  t.push(nx);
870
1205
 
871
1206
  // 不处理已经后面连起来的字符
@@ -883,40 +1218,6 @@ function ast2(tree: tree) {
883
1218
  tree = t;
884
1219
  }
885
1220
 
886
- // 处理\转义
887
- {
888
- let t: tree = [];
889
- for (let n = 0; n < tree.length; n++) {
890
- let x = tree[n];
891
-
892
- if (x.value == "\\" && x.type == "v") {
893
- if (tree?.[n + 1]) {
894
- let next = tree[n + 1];
895
- if (next.value == "\\" && next.type == "v") {
896
- t.push({ type: "v", value: "\\" });
897
- n++;
898
- } else if (next.type == "blank") {
899
- t.push({ type: "v", value: "br", esc: true });
900
- n++;
901
- } else if (next.type == "f") {
902
- let v = next.value;
903
- t.push({ type: "v", value: v[0] });
904
- t.push({ type: v.length == 2 ? "v" : "f", value: v.slice(1) });
905
- n++;
906
- } else {
907
- let v = next;
908
- v.esc = true;
909
- t.push(v);
910
- n++;
911
- }
912
- }
913
- } else {
914
- t.push(x);
915
- }
916
- }
917
- tree = t;
918
- }
919
-
920
1221
  // 处理字符与v之间空格
921
1222
  {
922
1223
  let t: tree = [];
@@ -986,25 +1287,161 @@ function ast2(tree: tree) {
986
1287
  }
987
1288
  tree = t;
988
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
+ }
989
1308
  // 处理f
990
1309
  {
991
1310
  let t: tree = [];
992
1311
  for (let n = 0; n < tree.length; n++) {
993
1312
  let x = tree[n];
1313
+ const next = tree[n + 1];
994
1314
 
995
1315
  // 带有括号(参数)的函数
996
- if (x.type == "f" && tree[n + 1] && tree[n + 1].type == "group") {
997
- x.children = tree[n + 1].children;
998
- for (let i in x.children) {
999
- if (x.children[i].value == "\\" && x.children[i].type == "v") {
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") {
1000
1348
  if (x.children[Number(i) + 1]) {
1001
1349
  x.children[Number(i) + 1]["esc"] = true;
1002
1350
  }
1003
1351
  }
1004
1352
  }
1353
+ } else {
1005
1354
  t.push(x);
1355
+ }
1356
+ }
1357
+ tree = t;
1358
+ }
1006
1359
 
1007
- // 不处理group
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
+ }
1412
+
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);
1008
1445
  n++;
1009
1446
  continue;
1010
1447
  } else {
@@ -1014,6 +1451,40 @@ function ast2(tree: tree) {
1014
1451
  tree = t;
1015
1452
  }
1016
1453
 
1454
+ // '->^'
1455
+ {
1456
+ let t: tree = [];
1457
+ for (let n = 0; n < tree.length; n++) {
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" });
1479
+ }
1480
+ n += primes;
1481
+ continue;
1482
+ }
1483
+ t.push(x);
1484
+ }
1485
+ tree = t;
1486
+ }
1487
+
1017
1488
  // 移除blank
1018
1489
  {
1019
1490
  let t: tree = [];
@@ -1156,69 +1627,92 @@ function ast2(tree: tree) {
1156
1627
  }
1157
1628
 
1158
1629
  function f_attr(x: tree[0]) {
1159
- let type: "dic" | "array" | "attr" = "array";
1160
- let attr: tree[] = [];
1161
- let dicl: tree[] = [];
1162
- let array: tree[][] = [];
1163
- let l: tree = [];
1164
- for (let i in x.children) {
1165
- const t = x.children[i];
1166
- if (Number(i) + 1 == x.children.length) {
1167
- if (t.type == "blank" && x.children[Number(i) - 1].value.match(/[,;]/)) break;
1168
- if (!is_f_mark(t, ",") && !is_f_mark(t, ";")) l.push(t);
1169
- if (type == "dic") {
1170
- dicl.push(l);
1171
- l = [];
1172
- } else {
1173
- attr.push(l);
1174
- }
1175
- if (array.length) {
1176
- array.push(attr);
1177
- attr = [];
1178
- }
1179
- 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([]);
1180
1635
  } else {
1181
- if (is_f_mark(t, ",")) {
1182
- if (type == "dic") {
1183
- dicl.push(l);
1184
- type = "array";
1185
- } else {
1186
- attr.push(l);
1187
- }
1188
- l = [];
1189
- } else if (is_f_mark(t, ";")) {
1190
- // 存在; 则存好的attr为array的一个子元素
1191
- type == "array";
1192
- attr.push(l);
1193
- l = [];
1194
- array.push(attr);
1195
- 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);
1196
1647
  } else {
1197
- // 按,拆分成段
1198
- l.push(t);
1199
- // 段中有: 为dic
1200
- if (is_f_mark(t, ":")) {
1201
- type = "dic";
1202
- }
1648
+ xattr.push(x);
1203
1649
  }
1204
1650
  }
1205
1651
  }
1206
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
+
1207
1676
  // 将dicl的tree转为键对
1208
1677
  let dic: fdic = {};
1209
1678
  for (let i of dicl) {
1679
+ let x = false;
1210
1680
  let n = "";
1211
1681
  let t: tree = [];
1212
1682
  for (let el of i) {
1213
- if (!n) {
1214
- n = el.value;
1683
+ if (eqq(el, { type: "v", value: ":" })) {
1684
+ x = true;
1685
+ continue;
1686
+ }
1687
+ if (!x) {
1688
+ n += el.value;
1215
1689
  } else {
1216
- if (el.value != ":") t.push(el);
1690
+ t.push(el);
1217
1691
  }
1218
1692
  }
1219
- dic[n] = t;
1693
+ dic[n] = ast3(ast2(t));
1220
1694
  }
1221
- return { attr, dic, array };
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);
1222
1716
  }
1223
1717
 
1224
1718
  type fonts = "serif" | "sans" | "frak" | "mono" | "bb" | "cal";
@@ -1227,46 +1721,38 @@ function font(str: string, type: fonts = "serif") {
1227
1721
  const l = "abcdefghijklmnopqrstuvwxyz";
1228
1722
  return l.indexOf(c.toLowerCase());
1229
1723
  }
1230
- switch (type) {
1231
- case "serif":
1232
- return str;
1233
- case "sans":
1234
- const s0 = [..."𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫"];
1235
- const s1 = [..."𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓"];
1236
- const s2 = [..."𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹"];
1237
- str = str.replace(/[0-9]+/g, (s) => s0[s]);
1238
- str = str.replace(/[a-z]/g, (s) => s1[index_c(s)]);
1239
- str = str.replace(/[A-Z]/g, (s) => s2[index_c(s)]);
1240
- return str;
1241
- case "frak":
1242
- const frak1 = [..."𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷"];
1243
- const frak2 = [..."𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ"];
1244
- str = str.replace(/[a-z]/g, (s) => frak1[index_c(s)]);
1245
- str = str.replace(/[A-Z]/g, (s) => frak2[index_c(s)]);
1246
- return str;
1247
- case "mono":
1248
- const m0 = [..."0𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿"];
1249
- const m1 = [..."𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣"];
1250
- const m2 = [..."𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉"];
1251
- str = str.replace(/[0-9]+/g, (s) => m0[s]);
1252
- str = str.replace(/[a-z]/g, (s) => m1[index_c(s)]);
1253
- str = str.replace(/[A-Z]/g, (s) => m2[index_c(s)]);
1254
- return str;
1255
- case "bb":
1256
- const bb0 = [..."𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡"];
1257
- const bb1 = [..."𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫"];
1258
- const bb2 = [..."𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ"];
1259
- str = str.replace(/[0-9]+/g, (s) => bb0[s]);
1260
- str = str.replace(/[a-z]/g, (s) => bb1[index_c(s)]);
1261
- str = str.replace(/[A-Z]/g, (s) => bb2[index_c(s)]);
1262
- return str;
1263
- case "cal":
1264
- const c1 = [..."𝒶𝒷𝒸𝒹ℯ𝒻ℊ𝒽𝒾𝒿𝓀𝓁𝓂𝓃ℴ𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏"];
1265
- const c2 = [..."𝒜ℬ𝒞𝒟ℰℱ𝒢ℋℐ𝒥𝒦ℒℳ𝒩𝒪𝒫𝒬ℛ𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵"];
1266
- str = str.replace(/[a-z]/g, (s) => c1[index_c(s)]);
1267
- str = str.replace(/[A-Z]/g, (s) => c2[index_c(s)]);
1268
- 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)]);
1269
1754
  }
1755
+ return str;
1270
1756
  }
1271
1757
 
1272
1758
  function render(tree: tree, e?: fonts) {
@@ -1274,59 +1760,44 @@ function render(tree: tree, e?: fonts) {
1274
1760
 
1275
1761
  tree = ast2(tree);
1276
1762
 
1763
+ // 多行
1277
1764
  // 处理\ 换行
1278
1765
  {
1279
1766
  let xx = false;
1280
- let w = (tree: tree) => {
1281
- for (let i of tree) {
1282
- if (is_br(i)) {
1283
- xx = true;
1284
- return;
1285
- }
1286
- if (i.type == "group") {
1287
- w(i.children);
1288
- }
1767
+ for (let n in tree) {
1768
+ const i = tree[n];
1769
+ if (is_br(i)) {
1770
+ xx = true;
1771
+ break;
1289
1772
  }
1290
- };
1291
- w(tree);
1773
+ }
1292
1774
  if (xx) {
1293
- // 移除group
1294
- {
1295
- let t: tree = [];
1296
- for (let i in tree) {
1297
- let x = tree[i];
1298
- // 不作为group,只是数学上显示的括号对
1299
- if (x.type == "group") {
1300
- t.push(v_f("("));
1301
- t.push(...ast2(x.children));
1302
- t.push(v_f(")"));
1303
- } else {
1304
- t.push(x);
1305
- }
1306
- }
1307
- tree = t;
1308
- }
1309
- // 将换行替换成逗号传入函数
1775
+ const trees: tree[] = [[]];
1310
1776
  for (let n = 0; n < tree.length; n++) {
1311
- const x = tree[n];
1312
- if (is_br(x)) {
1313
- tree[n] = dh;
1777
+ const i = tree[n];
1778
+ if (is_br(i)) {
1779
+ trees.push([]);
1780
+ } else {
1781
+ trees.at(-1).push(i);
1314
1782
  }
1315
1783
  }
1784
+ return x_table(trees);
1785
+ }
1786
+ }
1316
1787
 
1317
- let t: tree = [];
1318
- t.push({ type: "f", value: "x_table", children: tree });
1319
- tree = t;
1320
- } else {
1321
- let t: tree = [];
1322
- for (let x of tree) {
1323
- // 移除&
1324
- if (!(x.type == "v" && x.value == "&" && !x.esc)) {
1325
- t.push(x);
1326
- }
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);
1327
1798
  }
1328
- tree = t;
1329
1799
  }
1800
+ tree = t;
1330
1801
  }
1331
1802
 
1332
1803
  // 移除group1
@@ -1342,54 +1813,59 @@ function render(tree: tree, e?: fonts) {
1342
1813
  tree = t;
1343
1814
  }
1344
1815
 
1816
+ console.log("ast3", structuredClone(tree));
1345
1817
  for (let i in tree) {
1346
1818
  let n = Number(i);
1347
1819
  let x = tree[n];
1348
1820
 
1349
- // 带有括号(参数)的函数
1350
- if (x.type == "f" && x.children) {
1351
- let { attr, dic, array }: { attr: tree[]; dic: fdic; array: tree[][] } = f_attr(x);
1352
-
1353
- if (f[x.value]) {
1354
- console.log(attr, dic, array);
1355
- let el = f[x.value](attr, dic, array, e);
1356
- fragment.append(el);
1357
- } else if (ss[x.value]) {
1358
- let el = createMath("mo", ss[x.value]);
1359
- fragment.append(el, render(in_kh(x.children)));
1360
- }
1361
- }
1821
+ // 函数
1822
+ if (x.type === "f") {
1823
+ // 带有括号(参数)的函数
1824
+ if (x.children && (x.kh === "()" || !x.kh)) {
1825
+ let { attr, dic } = f_attr(x);
1362
1826
 
1363
- if (x.type == "f" && !x.children) {
1364
- if (ss[x.value]) {
1365
- let tag: keyof MathMLElementTagNameMap;
1366
- let space_w = null;
1367
- const space_width = {
1368
- " ": "0.36em",
1369
- " ": "0.5em",
1370
- " ": "3.75em",
1371
- " ": "0.333em",
1372
- " ": "0.25em",
1373
- " ": "0.166em",
1374
- " ": "0.222em",
1375
- " ": "1ch",
1376
- " ": "0.27em",
1377
- " ": "0.2em",
1378
- " ": "0.09em",
1379
- };
1380
- if (ss[x.value].match(/[a-zA-Z\u0391-\u03C9]/)) {
1381
- tag = "mi";
1382
- } else if (space_width[ss[x.value]]) {
1383
- tag = "mspace";
1384
- space_w = { width: space_width[ss[x.value]] };
1385
- } else {
1386
- 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);
1387
1836
  }
1388
- let el = createMath(tag, ss[x.value], space_w);
1389
- fragment.append(el);
1390
1837
  } else {
1391
- if (f[x.value]) {
1392
- let el = f[x.value](null, null, null, e);
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);
1393
1869
  fragment.append(el);
1394
1870
  }
1395
1871
  }
@@ -1400,29 +1876,39 @@ function render(tree: tree, e?: fonts) {
1400
1876
  fragment.append(el);
1401
1877
  }
1402
1878
 
1403
- if (x.type == "v") {
1879
+ if (x.type === "v" || x.type === "sharp") {
1404
1880
  let tag: keyof MathMLElementTagNameMap;
1881
+ let value = x.value;
1405
1882
  if (x.value.match(/[0-9.]+/)) {
1406
1883
  tag = "mn";
1407
1884
  } else if (x.value.match(/[a-zA-Z\u0391-\u03C9]/)) {
1408
1885
  tag = "mi";
1886
+ } else if (x.value.match(/^'+$/)) {
1887
+ if (!x.esc) value = x.value.replaceAll("'", ss["prime"]);
1888
+ tag = "mo";
1409
1889
  } else {
1410
1890
  tag = "mo";
1411
1891
  }
1412
- let el = createMath(tag, font(x.value, e));
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));
1413
1899
  fragment.append(el);
1414
1900
  }
1415
1901
 
1416
- if (x.type == "group") {
1417
- fragment.append(kh(x.children));
1902
+ if (x.type === "group") {
1903
+ fragment.append(f.lr([[x]], null, e));
1418
1904
  }
1419
1905
  }
1420
1906
 
1421
1907
  return fragment;
1422
1908
  }
1423
1909
 
1424
- var init_c = {
1425
- emoji: false,
1910
+ var init_c: { emoji: (str: string) => string } = {
1911
+ emoji: null,
1426
1912
  };
1427
1913
 
1428
1914
  function init(p: { emoji: boolean }) {
@@ -1431,12 +1917,12 @@ function init(p: { emoji: boolean }) {
1431
1917
  }
1432
1918
  }
1433
1919
 
1434
- function toMML(str: string) {
1920
+ function toMML(str: string, inline?: boolean) {
1435
1921
  let obj = ast(str);
1436
- console.log(obj);
1922
+ console.log("ast1", obj);
1437
1923
 
1438
1924
  let mathEl = createMath("math");
1439
- mathEl.setAttribute("display", "block");
1925
+ if (!inline) mathEl.setAttribute("display", "block");
1440
1926
  let f = render(obj);
1441
1927
  mathEl.append(f);
1442
1928
  return mathEl;
@@ -1446,4 +1932,9 @@ function toMMLHTML(str: string) {
1446
1932
  return toMML(str).outerHTML;
1447
1933
  }
1448
1934
 
1449
- export { init, toMML, toMMLHTML };
1935
+ const version = {
1936
+ lan: "0.11.1",
1937
+ symbol: "0.11.1",
1938
+ };
1939
+
1940
+ export { init, toMML, toMMLHTML, version };