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/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
- 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,31 +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
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 == '"' && strl[i - 1] != "\\") {
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: t });
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 (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)) {
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 (p_tree.at(-1)) {
155
- 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) {
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
- let ss: { [id: string]: string } = {};
176
- for (let i in s) {
177
- if (typeof s[i] == "string") {
178
- ss[i] = s[i];
179
- } else {
180
- for (let objOrStr of s[i]) {
181
- // 第二层的array
182
- if (typeof objOrStr == "string") {
183
- ss[i] = objOrStr;
184
- } else {
185
- if (!ss[i]) ss[i] = objOrStr[Object.keys(objOrStr)[0]];
186
- for (let j in objOrStr) {
187
- // 第三层的obj
188
- ss[`${i}.${j}`] = objOrStr[j];
189
- // 允许部分索引,但要保证唯一
190
- let l = j.split(".");
191
- for (let n = 1; n < l.length; n++) {
192
- let shotKey = l.slice(0, n).join(".");
193
- if (!objOrStr[shotKey]) {
194
- 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
+ }
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?: tree[], dic?: fdic, array?: tree[][], e?: fonts) => MathMLElement | DocumentFragment;
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?.delim?.[0]?.value || "{";
354
- let t = f.x_table(attr, { cases: [] }) as MathMLElement;
355
- const gap = dic?.gap?.[0]?.value || "0.5em";
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", delimPair[d][1]);
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[0];
379
- let start: { c: tree; n: number }, end: { c: tree; n: number };
380
- for (let i = 0; i < list.length; i++) {
381
- const el = list[i];
382
- if (el.type == "blank") continue;
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(l, c, r);
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, array: tree[][]) => {
413
- let d = dic?.delim?.[0]?.value || "(";
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", o[d][0]);
417
- let r = createMath("mo", o[d][1]);
471
+ let l = createMath("mo", d[0]);
472
+ let r = createMath("mo", d[1]);
418
473
  let t = createMath("mtable");
419
- let augment = lan_dic(dic?.augment?.[0].children);
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 (Array.isArray(augment)) {
424
- xa = Number((augment as tree).map((i) => i.value).join(""));
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?.gap?.[0]?.value;
443
- const rowgap = dic?.["row-gap"]?.[0]?.value;
444
- const colgap = dic?.["column-gap"]?.[0]?.value;
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, a, e) => {
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 underover_f("under", attr[0], "_", attr?.[1]);
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 underover_f("over", attr[0], "‾", attr?.[1]);
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[], dic: fdic) => {
605
+ serif: (attr: tree[]) => {
547
606
  return render(attr[0], "serif");
548
607
  },
549
- sans: (attr: tree[], dic: fdic) => {
608
+ sans: (attr: tree[]) => {
550
609
  return render(attr[0], "sans");
551
610
  },
552
- frak: (attr: tree[], dic: fdic) => {
611
+ frak: (attr: tree[]) => {
553
612
  return render(attr[0], "frak");
554
613
  },
555
- mono: (attr: tree[], dic: fdic) => {
614
+ mono: (attr: tree[]) => {
556
615
  return render(attr[0], "mono");
557
616
  },
558
- bb: (attr: tree[], dic: fdic) => {
617
+ bb: (attr: tree[]) => {
559
618
  return render(attr[0], "bb");
560
619
  },
561
- cal: (attr: tree[], dic: fdic) => {
620
+ cal: (attr: tree[]) => {
562
621
  return render(attr[0], "cal");
563
622
  },
564
- vec: (attr: tree[], dic: fdic) => {
565
- let d = dic?.delim?.[0]?.value || "(";
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", o[d][0]);
569
- let r = createMath("mo", o[d][1]);
570
- let t = createMath("mtable");
571
- const gap = dic?.gap?.[0]?.value || "0.5em";
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
- for (let i of attr) {
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 max = 0;
588
- let t = createMath("mtable");
589
- for (let i of attr) {
590
- let r = createMath("mtr");
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
- for (let i of result) {
612
- let d = createMath("mtd");
613
- r.append(d);
614
- 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]);
615
664
  }
616
-
617
- t.append(r);
618
665
  }
619
- let al = [];
620
- if (dic.cases) {
621
- // cases
622
- al.push("left");
623
- } else {
624
- // 其他换行对齐 交替
625
- for (let i = 0; i < max; i++) {
626
- if (i % 2 == 0) {
627
- al.push("right");
628
- } else {
629
- al.push("left");
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
- return t;
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, b, e) => {
684
- 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);
685
737
  if (attr) {
686
738
  let f = document.createDocumentFragment();
687
- f.append(s, kh(attr[0]));
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?: tree) {
895
+ function underover_f(type: "under" | "over", tree: tree, x: string, str: tree, e: fonts) {
772
896
  let m =
773
- type == "under"
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 == "under" ? createMath("munder") : createMath("mover");
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 == "group") {
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 == "scripts") return false;
846
- if (x.value == "op") {
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
- while (tree.length > 0 && tree[0].type === "blank") {
894
- tree.shift();
895
- }
896
- while (tree.length > 0 && tree.at(-1).type === "blank") {
897
- tree.pop();
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.value == "\\" && x.type == "v") {
1149
+ if (eqq(x, v_f("\\"))) {
983
1150
  if (tree?.[n + 1]) {
984
1151
  let next = tree[n + 1];
985
- if (next.value == "\\" && next.type == "v") {
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 == "blank") {
1155
+ } else if (next.type === "blank") {
989
1156
  t.push({ type: "v", value: "br", esc: true });
990
1157
  n++;
991
- } else if (next.type == "f") {
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 == "f" && tree[n + 1] && tree[n + 1].type == "group") {
1165
- x.children = tree[n + 1].children;
1166
- for (let i in x.children) {
1167
- 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") {
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
- // 不处理group
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
- let x = tree[n];
1190
- let nn = n;
1191
- if (eqq(x, { type: "f", value: "prime" })) {
1192
- while (tree[nn] && eqq(tree[nn], { type: "f", value: "prime" })) {
1193
- nn++;
1194
- }
1195
- const primes = nn - n;
1196
- if (
1197
- tree[n - 1] &&
1198
- !is_sup(tree[n - 1]) &&
1199
- !is_sub(tree[n - 1]) &&
1200
- !eq(tree[n - 1], { type: "f", value: "prime" }) &&
1201
- tree[n - 1].type != "blank"
1202
- ) {
1203
- t.push({ type: "v", value: "^" });
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
- t.push({ type: "v", value: "'".repeat(primes), children: [{ type: "v", value: String(primes) }] });
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
- let type: "dic" | "array" | "attr" = "array";
1357
- let attr: tree[] = [];
1358
- let dicl: tree[] = [];
1359
- let array: tree[][] = [];
1360
- let l: tree = [];
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
- if (is_f_mark(t, ",")) {
1379
- if (type == "dic") {
1380
- dicl.push(l);
1381
- type = "array";
1382
- } else {
1383
- attr.push(l);
1384
- }
1385
- l = [];
1386
- } else if (is_f_mark(t, ";")) {
1387
- // 存在; 则存好的attr为array的一个子元素
1388
- type == "array";
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.value === ":") {
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, 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);
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
- switch (type) {
1433
- case "serif":
1434
- return str;
1435
- case "sans":
1436
- const s0 = [..."𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫"];
1437
- const s1 = [..."𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓"];
1438
- const s2 = [..."𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹"];
1439
- str = str.replace(/[0-9]+/g, (s) => s0[s]);
1440
- str = str.replace(/[a-z]/g, (s) => s1[index_c(s)]);
1441
- str = str.replace(/[A-Z]/g, (s) => s2[index_c(s)]);
1442
- return str;
1443
- case "frak":
1444
- const frak1 = [..."𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷"];
1445
- const frak2 = [..."𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ"];
1446
- str = str.replace(/[a-z]/g, (s) => frak1[index_c(s)]);
1447
- str = str.replace(/[A-Z]/g, (s) => frak2[index_c(s)]);
1448
- return str;
1449
- case "mono":
1450
- const m0 = [..."0𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿"];
1451
- const m1 = [..."𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣"];
1452
- const m2 = [..."𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉"];
1453
- str = str.replace(/[0-9]+/g, (s) => m0[s]);
1454
- str = str.replace(/[a-z]/g, (s) => m1[index_c(s)]);
1455
- str = str.replace(/[A-Z]/g, (s) => m2[index_c(s)]);
1456
- return str;
1457
- case "bb":
1458
- const bb0 = [..."𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡"];
1459
- const bb1 = [..."𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫"];
1460
- const bb2 = [..."𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ"];
1461
- str = str.replace(/[0-9]+/g, (s) => bb0[s]);
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 w = (tree: tree) => {
1483
- for (let i of tree) {
1484
- if (is_br(i)) {
1485
- xx = true;
1486
- return;
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
- // 移除group
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 x = tree[n];
1514
- if (is_br(x)) {
1515
- tree[n] = dh;
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
- let t: tree = [];
1520
- t.push({ type: "f", value: "x_table", children: tree });
1521
- tree = t;
1522
- } else {
1523
- let t: tree = [];
1524
- for (let x of tree) {
1525
- // 移除&
1526
- if (!(x.type == "v" && x.value == "&" && !x.esc)) {
1527
- t.push(x);
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 == "f" && x.children) {
1553
- let { attr, dic, array }: { attr: tree[]; dic: fdic; array: tree[][] } = f_attr(x);
1554
-
1555
- if (f[x.value]) {
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
- if (x.type == "f" && !x.children) {
1566
- if (ss[x.value]) {
1567
- let tag: keyof MathMLElementTagNameMap;
1568
- let space_w = null;
1569
- const space_width = {
1570
- " ": "0.36em",
1571
- "\u2002": "0.5em",
1572
- "\u2003": "1em",
1573
- "\u2004": "0.333em",
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 (f[x.value]) {
1594
- 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);
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.value.length > 1) x.value = x.value.replaceAll("'", ss["prime"]);
1887
+ if (!x.esc) value = x.value.replaceAll("'", ss["prime"]);
1613
1888
  tag = "mo";
1614
1889
  } else {
1615
1890
  tag = "mo";
1616
1891
  }
1617
- 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));
1618
1899
  fragment.append(el);
1619
1900
  }
1620
1901
 
1621
- if (x.type == "group") {
1622
- fragment.append(kh(x.children));
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: boolean | ((str: string) => string) } = {
1630
- emoji: false,
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;