xmmath 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xmmath.es.js +599 -533
- package/dist/xmmath.es.js.map +1 -1
- package/dist/xmmath.umd.js +2 -2
- package/dist/xmmath.umd.js.map +1 -1
- package/package.json +2 -1
- package/readme.md +39 -0
- package/src/main.ts +337 -189
package/src/main.ts
CHANGED
|
@@ -31,7 +31,7 @@ type vtype = "" | "str" | "v" | "f" | "blank" | "group";
|
|
|
31
31
|
type tree = { type: vtype; value: string; children?: tree; esc?: boolean }[];
|
|
32
32
|
|
|
33
33
|
function ast(str: string) {
|
|
34
|
-
let v = /[a-zA-Z
|
|
34
|
+
let v = /[a-zA-Z]/;
|
|
35
35
|
let kh = /[\(\)]/;
|
|
36
36
|
let blank = /[ \t\n\r]+/;
|
|
37
37
|
let type: vtype = "";
|
|
@@ -74,15 +74,8 @@ function ast(str: string) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
let strl = splitter.splitGraphemes(str);
|
|
77
|
+
let strl = init_c.emoji ? splitter.splitGraphemes(str) : [...str];
|
|
80
78
|
for (let i = 0; i < strl.length; i++) {
|
|
81
|
-
if (continue_c > 0) {
|
|
82
|
-
continue_c--;
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
79
|
const t = strl[i];
|
|
87
80
|
// 字符
|
|
88
81
|
if (t == '"' && strl[i - 1] != "\\") {
|
|
@@ -249,7 +242,9 @@ for (let i in shorthand) {
|
|
|
249
242
|
}
|
|
250
243
|
}
|
|
251
244
|
|
|
252
|
-
let f
|
|
245
|
+
let f: {
|
|
246
|
+
[name: string]: (attr?: tree[], dic?: fdic, array?: tree[][], e?: fonts) => MathMLElement | DocumentFragment;
|
|
247
|
+
} = {
|
|
253
248
|
accent: (attr: tree[], dic: fdic) => {
|
|
254
249
|
let base = createMath("mrow");
|
|
255
250
|
base.append(render(attr[0]));
|
|
@@ -322,20 +317,30 @@ let f = {
|
|
|
322
317
|
row.append(l, f, r);
|
|
323
318
|
return row;
|
|
324
319
|
},
|
|
325
|
-
cancel: (attr: tree[], dic: fdic) => {
|
|
320
|
+
cancel: (attr: tree[], dic: fdic) => {
|
|
321
|
+
let r = createMath("mrow");
|
|
322
|
+
const bg = (x: boolean) =>
|
|
323
|
+
`linear-gradient(to ${
|
|
324
|
+
x ? "left" : "right"
|
|
325
|
+
} top, transparent 47.75%, currentColor 49.5%, currentColor 50.5%, transparent 52.25%)`;
|
|
326
|
+
let s = "";
|
|
327
|
+
if (is_true(dic.cross)) {
|
|
328
|
+
s = bg(true) + "," + bg(false);
|
|
329
|
+
} else if (is_true(dic.inverted)) {
|
|
330
|
+
s = bg(false);
|
|
331
|
+
} else {
|
|
332
|
+
s = bg(true);
|
|
333
|
+
}
|
|
334
|
+
r.style.backgroundImage = s;
|
|
335
|
+
r.append(render(attr[0]));
|
|
336
|
+
return r;
|
|
337
|
+
},
|
|
326
338
|
cases: (attr: tree[], dic: fdic) => {
|
|
327
|
-
let
|
|
339
|
+
let r = createMath("mrow");
|
|
328
340
|
let l = createMath("mo", dic?.delim?.[0]?.value || "{");
|
|
329
|
-
let t =
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
let td = createMath("mtd");
|
|
333
|
-
td.append(render(i));
|
|
334
|
-
tr.append(td);
|
|
335
|
-
t.append(tr);
|
|
336
|
-
}
|
|
337
|
-
f.append(l, t);
|
|
338
|
-
return f;
|
|
341
|
+
let t = f.x_table(attr, { cases: [] });
|
|
342
|
+
r.append(l, t);
|
|
343
|
+
return r;
|
|
339
344
|
},
|
|
340
345
|
frac: (attr: tree[], dic: fdic) => {
|
|
341
346
|
console.log(attr);
|
|
@@ -404,10 +409,26 @@ let f = {
|
|
|
404
409
|
sqrt: (attr: tree[], dic: fdic) => {
|
|
405
410
|
return f.root([[], attr[0]], null);
|
|
406
411
|
},
|
|
407
|
-
display: (attr: tree[], dic: fdic) => {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
412
|
+
display: (attr: tree[], dic: fdic) => {
|
|
413
|
+
let m = createMath("mrow", null, { displaystyle: "true" });
|
|
414
|
+
m.append(render(attr[0]));
|
|
415
|
+
return m;
|
|
416
|
+
},
|
|
417
|
+
inline: (attr: tree[], dic: fdic) => {
|
|
418
|
+
let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "0" });
|
|
419
|
+
m.append(render(attr[0]));
|
|
420
|
+
return m;
|
|
421
|
+
},
|
|
422
|
+
script: (attr: tree[], dic: fdic) => {
|
|
423
|
+
let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "1" });
|
|
424
|
+
m.append(render(attr[0]));
|
|
425
|
+
return m;
|
|
426
|
+
},
|
|
427
|
+
sscript: (attr: tree[], dic: fdic) => {
|
|
428
|
+
let m = createMath("mrow", null, { displaystyle: "false", scriptlevel: "2" });
|
|
429
|
+
m.append(render(attr[0]));
|
|
430
|
+
return m;
|
|
431
|
+
},
|
|
411
432
|
upright: (attr: tree[], dic: fdic) => {
|
|
412
433
|
let r = createMath("mrow");
|
|
413
434
|
r.append(render(attr[0]));
|
|
@@ -436,11 +457,10 @@ let f = {
|
|
|
436
457
|
r.append(render(attr[0]));
|
|
437
458
|
return r;
|
|
438
459
|
},
|
|
439
|
-
op: (attr: tree[], dic: fdic) => {
|
|
460
|
+
op: (attr: tree[], dic: fdic, a, e) => {
|
|
440
461
|
let f = createMath("mrow");
|
|
441
|
-
let str = createMath("ms", attr[0][0].value);
|
|
462
|
+
let str = createMath("ms", font(attr[0][0].value, e));
|
|
442
463
|
f.append(str);
|
|
443
|
-
// TODO dic.limit
|
|
444
464
|
return f;
|
|
445
465
|
},
|
|
446
466
|
underline: (attr: tree[], dic: fdic) => {
|
|
@@ -461,12 +481,24 @@ let f = {
|
|
|
461
481
|
overbracket: (attr: tree[], dic: fdic) => {
|
|
462
482
|
return underover_f("over", attr[0], "⎴", attr?.[1]);
|
|
463
483
|
},
|
|
464
|
-
serif: (attr: tree[], dic: fdic) => {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
484
|
+
serif: (attr: tree[], dic: fdic) => {
|
|
485
|
+
return render(attr[0], "serif");
|
|
486
|
+
},
|
|
487
|
+
sans: (attr: tree[], dic: fdic) => {
|
|
488
|
+
return render(attr[0], "sans");
|
|
489
|
+
},
|
|
490
|
+
frak: (attr: tree[], dic: fdic) => {
|
|
491
|
+
return render(attr[0], "frak");
|
|
492
|
+
},
|
|
493
|
+
mono: (attr: tree[], dic: fdic) => {
|
|
494
|
+
return render(attr[0], "mono");
|
|
495
|
+
},
|
|
496
|
+
bb: (attr: tree[], dic: fdic) => {
|
|
497
|
+
return render(attr[0], "bb");
|
|
498
|
+
},
|
|
499
|
+
cal: (attr: tree[], dic: fdic) => {
|
|
500
|
+
return render(attr[0], "cal");
|
|
501
|
+
},
|
|
470
502
|
vec: (attr: tree[], dic: fdic) => {
|
|
471
503
|
let d = dic?.delim?.[0]?.value || "(";
|
|
472
504
|
let o = { "(": ["(", ")"], "[": ["[", "]"], "{": ["{", "}"], "|": ["|", "|"], "||": ["‖", "‖"] };
|
|
@@ -484,7 +516,8 @@ let f = {
|
|
|
484
516
|
},
|
|
485
517
|
// 额外
|
|
486
518
|
//
|
|
487
|
-
x_table: (attr: tree[]) => {
|
|
519
|
+
x_table: (attr: tree[], dic: fdic) => {
|
|
520
|
+
let max = 0;
|
|
488
521
|
let t = createMath("mtable");
|
|
489
522
|
for (let i of attr) {
|
|
490
523
|
let r = createMath("mtr");
|
|
@@ -506,6 +539,8 @@ let f = {
|
|
|
506
539
|
result.push(tmp_group);
|
|
507
540
|
}
|
|
508
541
|
|
|
542
|
+
if (result.length > max) max = result.length;
|
|
543
|
+
|
|
509
544
|
for (let i of result) {
|
|
510
545
|
let d = createMath("mtd");
|
|
511
546
|
r.append(d);
|
|
@@ -514,6 +549,21 @@ let f = {
|
|
|
514
549
|
|
|
515
550
|
t.append(r);
|
|
516
551
|
}
|
|
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
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
t.setAttribute("columnalign", al.join(" "));
|
|
517
567
|
return t;
|
|
518
568
|
},
|
|
519
569
|
};
|
|
@@ -558,8 +608,8 @@ let opl: { id: string; str?: string; limits?: boolean }[] = [
|
|
|
558
608
|
];
|
|
559
609
|
function op_f() {
|
|
560
610
|
for (let i of opl) {
|
|
561
|
-
f[i.id] = (attr: tree[]) => {
|
|
562
|
-
let s = f.op([[{ type: "str", value: i.str || i.id }]], {});
|
|
611
|
+
f[i.id] = (attr: tree[], a, b, e) => {
|
|
612
|
+
let s = f.op([[{ type: "str", value: i.str || i.id }]], {}, null, e);
|
|
563
613
|
if (attr) {
|
|
564
614
|
let f = document.createDocumentFragment();
|
|
565
615
|
f.append(s, kh(attr[0]));
|
|
@@ -695,6 +745,13 @@ function is_limit(tree: tree) {
|
|
|
695
745
|
}
|
|
696
746
|
if (x.value == "scripts") return false;
|
|
697
747
|
if (x.value == "op") {
|
|
748
|
+
let { dic } = f_attr(x);
|
|
749
|
+
let t = "";
|
|
750
|
+
if (dic.limits)
|
|
751
|
+
for (let i of dic.limits) {
|
|
752
|
+
t += i.value;
|
|
753
|
+
}
|
|
754
|
+
return t == "#true";
|
|
698
755
|
}
|
|
699
756
|
}
|
|
700
757
|
if (x.type == "v" && limits_sy.includes(x.value)) {
|
|
@@ -709,6 +766,10 @@ function is_f_mark(x: tree[0], str: string) {
|
|
|
709
766
|
return x.value == str && x.type == "v" && !x.esc;
|
|
710
767
|
}
|
|
711
768
|
|
|
769
|
+
function is_dot(x: tree[0]) {
|
|
770
|
+
return x && x.type == "v" && x.value == ".";
|
|
771
|
+
}
|
|
772
|
+
|
|
712
773
|
let dh: tree[0] = { type: "v", value: "," };
|
|
713
774
|
|
|
714
775
|
function v_f(str: string): tree[0] {
|
|
@@ -733,31 +794,36 @@ function dic_to_ast(dic: { [id: string]: tree }) {
|
|
|
733
794
|
return l;
|
|
734
795
|
}
|
|
735
796
|
|
|
797
|
+
function is_true(t: tree) {
|
|
798
|
+
let n = 0;
|
|
799
|
+
if (t) {
|
|
800
|
+
if (t[0].type == "blank") n++;
|
|
801
|
+
if (t[n] && t[n].type == "v" && t[n].value == "#") {
|
|
802
|
+
if (t[n + 1] && t[n + 1].type == "f" && t[n + 1].value == "true") {
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return false;
|
|
808
|
+
}
|
|
809
|
+
|
|
736
810
|
function ast2(tree: tree) {
|
|
737
811
|
// 处理数字和小数
|
|
738
812
|
{
|
|
739
813
|
let t: tree = [];
|
|
740
814
|
let num = /[0-9]/;
|
|
741
815
|
let number = "";
|
|
742
|
-
for (let
|
|
743
|
-
let n = Number(i);
|
|
816
|
+
for (let n = 0; n < tree.length; n++) {
|
|
744
817
|
let x = tree[n];
|
|
745
|
-
if (
|
|
746
|
-
x.value.match(num) ||
|
|
747
|
-
(tree[n - 1] &&
|
|
748
|
-
tree[n - 1].value.match(num) &&
|
|
749
|
-
x.value == "." &&
|
|
750
|
-
tree[n + 1] &&
|
|
751
|
-
tree[n + 1].value.match(num))
|
|
752
|
-
) {
|
|
818
|
+
if (x.value.match(num) || (tree[n - 1]?.value.match(num) && is_dot(x) && tree[n + 1]?.value.match(num))) {
|
|
753
819
|
number += x.value;
|
|
754
820
|
} else {
|
|
755
821
|
t.push(x);
|
|
756
822
|
}
|
|
757
823
|
if (
|
|
758
824
|
x.value.match(num) &&
|
|
759
|
-
(!tree[n + 1] || !tree[n + 1].value.match(
|
|
760
|
-
!(tree[n + 1]
|
|
825
|
+
(!tree[n + 1] || !tree[n + 1].value.match(num)) &&
|
|
826
|
+
!(is_dot(tree[n + 1]) && tree[n + 2]?.value.match(num))
|
|
761
827
|
) {
|
|
762
828
|
t.push({ type: "v", value: number });
|
|
763
829
|
number = "";
|
|
@@ -769,13 +835,7 @@ function ast2(tree: tree) {
|
|
|
769
835
|
// 处理符号简写(shorthand)
|
|
770
836
|
{
|
|
771
837
|
let t: tree = [];
|
|
772
|
-
let
|
|
773
|
-
for (let i in tree) {
|
|
774
|
-
if (continue_c > 0) {
|
|
775
|
-
continue_c--;
|
|
776
|
-
continue;
|
|
777
|
-
}
|
|
778
|
-
let n = Number(i);
|
|
838
|
+
for (let n = 0; n < tree.length; n++) {
|
|
779
839
|
let x = tree[n];
|
|
780
840
|
|
|
781
841
|
if (tree?.[n - 1]?.value != "\\") {
|
|
@@ -795,7 +855,7 @@ function ast2(tree: tree) {
|
|
|
795
855
|
t.push(nx);
|
|
796
856
|
|
|
797
857
|
// 不处理已经后面连起来的字符
|
|
798
|
-
|
|
858
|
+
n += l.at(-1).length - 1;
|
|
799
859
|
} else {
|
|
800
860
|
t.push(x);
|
|
801
861
|
}
|
|
@@ -812,13 +872,7 @@ function ast2(tree: tree) {
|
|
|
812
872
|
// 处理\转义
|
|
813
873
|
{
|
|
814
874
|
let t: tree = [];
|
|
815
|
-
let
|
|
816
|
-
for (let i in tree) {
|
|
817
|
-
if (continue_c > 0) {
|
|
818
|
-
continue_c--;
|
|
819
|
-
continue;
|
|
820
|
-
}
|
|
821
|
-
let n = Number(i);
|
|
875
|
+
for (let n = 0; n < tree.length; n++) {
|
|
822
876
|
let x = tree[n];
|
|
823
877
|
|
|
824
878
|
if (x.value == "\\" && x.type == "v") {
|
|
@@ -826,20 +880,20 @@ function ast2(tree: tree) {
|
|
|
826
880
|
let next = tree[n + 1];
|
|
827
881
|
if (next.value == "\\" && next.type == "v") {
|
|
828
882
|
t.push({ type: "v", value: "\\" });
|
|
829
|
-
|
|
883
|
+
n++;
|
|
830
884
|
} else if (next.type == "blank") {
|
|
831
885
|
t.push({ type: "v", value: "br", esc: true });
|
|
832
|
-
|
|
886
|
+
n++;
|
|
833
887
|
} else if (next.type == "f") {
|
|
834
888
|
let v = next.value;
|
|
835
889
|
t.push({ type: "v", value: v[0] });
|
|
836
890
|
t.push({ type: v.length == 2 ? "v" : "f", value: v.slice(1) });
|
|
837
|
-
|
|
891
|
+
n++;
|
|
838
892
|
} else {
|
|
839
893
|
let v = next;
|
|
840
894
|
v.esc = true;
|
|
841
895
|
t.push(v);
|
|
842
|
-
|
|
896
|
+
n++;
|
|
843
897
|
}
|
|
844
898
|
}
|
|
845
899
|
} else {
|
|
@@ -849,16 +903,52 @@ function ast2(tree: tree) {
|
|
|
849
903
|
tree = t;
|
|
850
904
|
}
|
|
851
905
|
|
|
852
|
-
//
|
|
906
|
+
// 处理字符与v之间空格
|
|
907
|
+
{
|
|
908
|
+
let t: tree = [];
|
|
909
|
+
for (let n = 0; n < tree.length; n++) {
|
|
910
|
+
let x = tree[n];
|
|
911
|
+
|
|
912
|
+
if (x.type == "v" && tree?.[n + 1]?.type == "blank" && tree?.[n + 2]?.type == "str") {
|
|
913
|
+
t.push(x);
|
|
914
|
+
t.push({ type: "f", value: "space" });
|
|
915
|
+
} else if (x.type == "str" && tree?.[n + 1]?.type == "blank" && tree?.[n + 2]?.type == "v") {
|
|
916
|
+
t.push(x);
|
|
917
|
+
t.push({ type: "f", value: "space" });
|
|
918
|
+
} else {
|
|
919
|
+
t.push(x);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
tree = t;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// 处理带.的f
|
|
853
926
|
{
|
|
854
927
|
let t: tree = [];
|
|
855
|
-
let
|
|
856
|
-
for (let
|
|
857
|
-
|
|
858
|
-
|
|
928
|
+
let f = "";
|
|
929
|
+
for (let n = 0; n < tree.length; n++) {
|
|
930
|
+
let x = tree[n];
|
|
931
|
+
|
|
932
|
+
if (x.type == "f" && is_dot(tree[n + 1])) {
|
|
933
|
+
f += x.value + ".";
|
|
934
|
+
n++;
|
|
859
935
|
continue;
|
|
936
|
+
} else if (f && x.type == "f") {
|
|
937
|
+
f += x.value;
|
|
938
|
+
if (!is_dot(tree[n + 1])) {
|
|
939
|
+
t.push({ type: "f", value: f });
|
|
940
|
+
f = "";
|
|
941
|
+
}
|
|
942
|
+
} else {
|
|
943
|
+
t.push(x);
|
|
860
944
|
}
|
|
861
|
-
|
|
945
|
+
}
|
|
946
|
+
tree = t;
|
|
947
|
+
}
|
|
948
|
+
// 处理f
|
|
949
|
+
{
|
|
950
|
+
let t: tree = [];
|
|
951
|
+
for (let n = 0; n < tree.length; n++) {
|
|
862
952
|
let x = tree[n];
|
|
863
953
|
|
|
864
954
|
// 带有括号(参数)的函数
|
|
@@ -874,7 +964,7 @@ function ast2(tree: tree) {
|
|
|
874
964
|
t.push(x);
|
|
875
965
|
|
|
876
966
|
// 不处理group
|
|
877
|
-
|
|
967
|
+
n++;
|
|
878
968
|
continue;
|
|
879
969
|
} else {
|
|
880
970
|
t.push(x);
|
|
@@ -918,24 +1008,11 @@ function ast2(tree: tree) {
|
|
|
918
1008
|
}
|
|
919
1009
|
|
|
920
1010
|
let t: tree = [];
|
|
921
|
-
let
|
|
922
|
-
for (let i in tree) {
|
|
923
|
-
if (continue_c > 0) {
|
|
924
|
-
continue_c--;
|
|
925
|
-
continue;
|
|
926
|
-
}
|
|
927
|
-
let n = Number(i);
|
|
928
|
-
|
|
1011
|
+
for (let n = 0; n < tree.length; n++) {
|
|
929
1012
|
if (n == index?.[0]?.[0]) {
|
|
930
1013
|
{
|
|
931
|
-
let continue_c = 0;
|
|
932
1014
|
let tmp: tree[0] = tree[index[0][1]];
|
|
933
1015
|
for (let i = index[0][1]; i >= index[0][0]; i--) {
|
|
934
|
-
if (continue_c > 0) {
|
|
935
|
-
continue_c--;
|
|
936
|
-
continue;
|
|
937
|
-
}
|
|
938
|
-
|
|
939
1016
|
if (tree[i - 1]?.value == "^" && tree[i - 3]?.value == "_") {
|
|
940
1017
|
let o = is_limit([tree[i - 4]])
|
|
941
1018
|
? { t: out_kh(tmp), b: out_kh(tree[i - 2]) }
|
|
@@ -945,7 +1022,7 @@ function ast2(tree: tree) {
|
|
|
945
1022
|
value: "attach",
|
|
946
1023
|
children: [tree[i - 4], dh, ...dic_to_ast(o)],
|
|
947
1024
|
};
|
|
948
|
-
|
|
1025
|
+
i -= 4 - 1;
|
|
949
1026
|
continue;
|
|
950
1027
|
}
|
|
951
1028
|
if (tree[i - 1]?.value == "_" && tree[i - 3]?.value == "^") {
|
|
@@ -957,7 +1034,7 @@ function ast2(tree: tree) {
|
|
|
957
1034
|
value: "attach",
|
|
958
1035
|
children: [tree[i - 4], dh, ...dic_to_ast(o)],
|
|
959
1036
|
};
|
|
960
|
-
|
|
1037
|
+
i -= 4 - 1;
|
|
961
1038
|
continue;
|
|
962
1039
|
}
|
|
963
1040
|
if (tree[i - 1]?.value == "^") {
|
|
@@ -967,7 +1044,7 @@ function ast2(tree: tree) {
|
|
|
967
1044
|
value: "attach",
|
|
968
1045
|
children: [tree[i - 2], dh, ...dic_to_ast(o)],
|
|
969
1046
|
};
|
|
970
|
-
|
|
1047
|
+
i -= 2 - 1;
|
|
971
1048
|
continue;
|
|
972
1049
|
}
|
|
973
1050
|
if (tree[i - 1]?.value == "_") {
|
|
@@ -977,18 +1054,18 @@ function ast2(tree: tree) {
|
|
|
977
1054
|
value: "attach",
|
|
978
1055
|
children: [tree[i - 2], dh, ...dic_to_ast(o)],
|
|
979
1056
|
};
|
|
980
|
-
|
|
1057
|
+
i -= 2 - 1;
|
|
981
1058
|
continue;
|
|
982
1059
|
}
|
|
983
1060
|
}
|
|
984
1061
|
t.push(tmp);
|
|
985
1062
|
}
|
|
986
|
-
|
|
1063
|
+
n += index[0][1] - index[0][0];
|
|
987
1064
|
index = index.slice(1);
|
|
988
1065
|
continue;
|
|
989
1066
|
}
|
|
990
1067
|
|
|
991
|
-
t.push(tree[
|
|
1068
|
+
t.push(tree[n]);
|
|
992
1069
|
}
|
|
993
1070
|
tree = t;
|
|
994
1071
|
}
|
|
@@ -1012,31 +1089,18 @@ function ast2(tree: tree) {
|
|
|
1012
1089
|
}
|
|
1013
1090
|
|
|
1014
1091
|
let t: tree = [];
|
|
1015
|
-
let
|
|
1016
|
-
for (let i in tree) {
|
|
1017
|
-
if (continue_c > 0) {
|
|
1018
|
-
continue_c--;
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
|
-
let n = Number(i);
|
|
1022
|
-
|
|
1092
|
+
for (let n = 0; n < tree.length; n++) {
|
|
1023
1093
|
if (n == index?.[0]?.[0]) {
|
|
1024
1094
|
{
|
|
1025
|
-
let continue_c = 0;
|
|
1026
1095
|
let tmp: tree[0] = tree[index[0][0]];
|
|
1027
1096
|
for (let i = index[0][0]; i <= index[0][1]; i++) {
|
|
1028
|
-
if (continue_c > 0) {
|
|
1029
|
-
continue_c--;
|
|
1030
|
-
continue;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
1097
|
if (tree[i + 1]?.value == "/") {
|
|
1034
1098
|
tmp = {
|
|
1035
1099
|
type: "f",
|
|
1036
1100
|
value: "frac",
|
|
1037
1101
|
children: [...out_kh(tmp), dh, ...out_kh(tree[i + 2])],
|
|
1038
1102
|
};
|
|
1039
|
-
|
|
1103
|
+
i += 2 - 1;
|
|
1040
1104
|
continue;
|
|
1041
1105
|
}
|
|
1042
1106
|
}
|
|
@@ -1044,19 +1108,133 @@ function ast2(tree: tree) {
|
|
|
1044
1108
|
|
|
1045
1109
|
t.push(tmp);
|
|
1046
1110
|
}
|
|
1047
|
-
|
|
1111
|
+
n += index[0][1] - index[0][0];
|
|
1048
1112
|
index.splice(0, 1);
|
|
1049
1113
|
continue;
|
|
1050
1114
|
}
|
|
1051
1115
|
|
|
1052
|
-
t.push(tree[
|
|
1116
|
+
t.push(tree[n]);
|
|
1053
1117
|
}
|
|
1054
1118
|
tree = t;
|
|
1055
1119
|
}
|
|
1056
1120
|
return tree;
|
|
1057
1121
|
}
|
|
1058
1122
|
|
|
1059
|
-
function
|
|
1123
|
+
function f_attr(x: tree[0]) {
|
|
1124
|
+
let type: "dic" | "array" | "attr" = "array";
|
|
1125
|
+
let attr: tree[] = [];
|
|
1126
|
+
let dicl: tree[] = [];
|
|
1127
|
+
let array: tree[][] = [];
|
|
1128
|
+
let l: tree = [];
|
|
1129
|
+
for (let i in x.children) {
|
|
1130
|
+
const t = x.children[i];
|
|
1131
|
+
if (Number(i) + 1 == x.children.length) {
|
|
1132
|
+
if (t.type == "blank" && x.children[Number(i) - 1].value.match(/[,;]/)) break;
|
|
1133
|
+
if (!is_f_mark(t, ",") && !is_f_mark(t, ";")) l.push(t);
|
|
1134
|
+
if (type == "dic") {
|
|
1135
|
+
dicl.push(l);
|
|
1136
|
+
l = [];
|
|
1137
|
+
} else {
|
|
1138
|
+
attr.push(l);
|
|
1139
|
+
}
|
|
1140
|
+
if (array.length) {
|
|
1141
|
+
array.push(attr);
|
|
1142
|
+
attr = [];
|
|
1143
|
+
}
|
|
1144
|
+
l = [];
|
|
1145
|
+
} else {
|
|
1146
|
+
if (is_f_mark(t, ",")) {
|
|
1147
|
+
if (type == "dic") {
|
|
1148
|
+
dicl.push(l);
|
|
1149
|
+
type = "array";
|
|
1150
|
+
} else {
|
|
1151
|
+
attr.push(l);
|
|
1152
|
+
}
|
|
1153
|
+
l = [];
|
|
1154
|
+
} else if (is_f_mark(t, ";")) {
|
|
1155
|
+
// 存在; 则存好的attr为array的一个子元素
|
|
1156
|
+
type == "array";
|
|
1157
|
+
attr.push(l);
|
|
1158
|
+
l = [];
|
|
1159
|
+
array.push(attr);
|
|
1160
|
+
attr = [];
|
|
1161
|
+
} else {
|
|
1162
|
+
// 按,拆分成段
|
|
1163
|
+
l.push(t);
|
|
1164
|
+
// 段中有: 为dic
|
|
1165
|
+
if (is_f_mark(t, ":")) {
|
|
1166
|
+
type = "dic";
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// 将dicl的tree转为键对
|
|
1173
|
+
let dic: fdic = {};
|
|
1174
|
+
for (let i of dicl) {
|
|
1175
|
+
let n = "";
|
|
1176
|
+
let t: tree = [];
|
|
1177
|
+
for (let el of i) {
|
|
1178
|
+
if (!n) {
|
|
1179
|
+
n = el.value;
|
|
1180
|
+
} else {
|
|
1181
|
+
if (el.value != ":") t.push(el);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
dic[n] = t;
|
|
1185
|
+
}
|
|
1186
|
+
return { attr, dic, array };
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
type fonts = "serif" | "sans" | "frak" | "mono" | "bb" | "cal";
|
|
1190
|
+
function font(str: string, type: fonts = "serif") {
|
|
1191
|
+
function index_c(c: string) {
|
|
1192
|
+
const l = "abcdefghijklmnopqrstuvwxyz";
|
|
1193
|
+
return l.indexOf(c.toLowerCase());
|
|
1194
|
+
}
|
|
1195
|
+
switch (type) {
|
|
1196
|
+
case "serif":
|
|
1197
|
+
return str;
|
|
1198
|
+
case "sans":
|
|
1199
|
+
const s0 = [..."𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫"];
|
|
1200
|
+
const s1 = [..."𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓"];
|
|
1201
|
+
const s2 = [..."𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹"];
|
|
1202
|
+
str = str.replace(/[0-9]+/g, (s) => s0[s]);
|
|
1203
|
+
str = str.replace(/[a-z]/g, (s) => s1[index_c(s)]);
|
|
1204
|
+
str = str.replace(/[A-Z]/g, (s) => s2[index_c(s)]);
|
|
1205
|
+
return str;
|
|
1206
|
+
case "frak":
|
|
1207
|
+
const frak1 = [..."𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷"];
|
|
1208
|
+
const frak2 = [..."𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ"];
|
|
1209
|
+
str = str.replace(/[a-z]/g, (s) => frak1[index_c(s)]);
|
|
1210
|
+
str = str.replace(/[A-Z]/g, (s) => frak2[index_c(s)]);
|
|
1211
|
+
return str;
|
|
1212
|
+
case "mono":
|
|
1213
|
+
const m0 = [..."0𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿"];
|
|
1214
|
+
const m1 = [..."𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣"];
|
|
1215
|
+
const m2 = [..."𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉"];
|
|
1216
|
+
str = str.replace(/[0-9]+/g, (s) => m0[s]);
|
|
1217
|
+
str = str.replace(/[a-z]/g, (s) => m1[index_c(s)]);
|
|
1218
|
+
str = str.replace(/[A-Z]/g, (s) => m2[index_c(s)]);
|
|
1219
|
+
return str;
|
|
1220
|
+
case "bb":
|
|
1221
|
+
const bb0 = [..."𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡"];
|
|
1222
|
+
const bb1 = [..."𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫"];
|
|
1223
|
+
const bb2 = [..."𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ"];
|
|
1224
|
+
str = str.replace(/[0-9]+/g, (s) => bb0[s]);
|
|
1225
|
+
str = str.replace(/[a-z]/g, (s) => bb1[index_c(s)]);
|
|
1226
|
+
str = str.replace(/[A-Z]/g, (s) => bb2[index_c(s)]);
|
|
1227
|
+
return str;
|
|
1228
|
+
case "cal":
|
|
1229
|
+
const c1 = [..."𝒶𝒷𝒸𝒹ℯ𝒻ℊ𝒽𝒾𝒿𝓀𝓁𝓂𝓃ℴ𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏"];
|
|
1230
|
+
const c2 = [..."𝒜ℬ𝒞𝒟ℰℱ𝒢ℋℐ𝒥𝒦ℒℳ𝒩𝒪𝒫𝒬ℛ𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵"];
|
|
1231
|
+
str = str.replace(/[a-z]/g, (s) => c1[index_c(s)]);
|
|
1232
|
+
str = str.replace(/[A-Z]/g, (s) => c2[index_c(s)]);
|
|
1233
|
+
return str;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
function render(tree: tree, e?: fonts) {
|
|
1060
1238
|
let fragment = document.createDocumentFragment();
|
|
1061
1239
|
|
|
1062
1240
|
tree = ast2(tree);
|
|
@@ -1104,86 +1282,29 @@ function render(tree: tree) {
|
|
|
1104
1282
|
let t: tree = [];
|
|
1105
1283
|
t.push({ type: "f", value: "x_table", children: tree });
|
|
1106
1284
|
tree = t;
|
|
1285
|
+
} else {
|
|
1286
|
+
let t: tree = [];
|
|
1287
|
+
for (let x of tree) {
|
|
1288
|
+
// 移除&
|
|
1289
|
+
if (!(x.type == "v" && x.value == "&" && !x.esc)) {
|
|
1290
|
+
t.push(x);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
tree = t;
|
|
1107
1294
|
}
|
|
1108
1295
|
}
|
|
1109
1296
|
|
|
1110
|
-
let continue_c = 0;
|
|
1111
1297
|
for (let i in tree) {
|
|
1112
|
-
if (continue_c > 0) {
|
|
1113
|
-
continue_c--;
|
|
1114
|
-
continue;
|
|
1115
|
-
}
|
|
1116
1298
|
let n = Number(i);
|
|
1117
1299
|
let x = tree[n];
|
|
1118
1300
|
|
|
1119
1301
|
// 带有括号(参数)的函数
|
|
1120
1302
|
if (x.type == "f" && x.children) {
|
|
1121
|
-
let
|
|
1122
|
-
let attr: tree[] = [];
|
|
1123
|
-
let dicl: tree[] = [];
|
|
1124
|
-
let array: tree[][] = [];
|
|
1125
|
-
let l: tree = [];
|
|
1126
|
-
for (let i in x.children) {
|
|
1127
|
-
const t = x.children[i];
|
|
1128
|
-
if (Number(i) + 1 == x.children.length) {
|
|
1129
|
-
if (t.type == "blank" && x.children[Number(i) - 1].value.match(/[,;]/)) break;
|
|
1130
|
-
if (!is_f_mark(t, ",") && !is_f_mark(t, ";")) l.push(t);
|
|
1131
|
-
if (type == "dic") {
|
|
1132
|
-
dicl.push(l);
|
|
1133
|
-
l = [];
|
|
1134
|
-
} else {
|
|
1135
|
-
attr.push(l);
|
|
1136
|
-
}
|
|
1137
|
-
if (array.length) {
|
|
1138
|
-
array.push(attr);
|
|
1139
|
-
attr = [];
|
|
1140
|
-
}
|
|
1141
|
-
l = [];
|
|
1142
|
-
} else {
|
|
1143
|
-
if (is_f_mark(t, ",")) {
|
|
1144
|
-
if (type == "dic") {
|
|
1145
|
-
dicl.push(l);
|
|
1146
|
-
type = "array";
|
|
1147
|
-
} else {
|
|
1148
|
-
attr.push(l);
|
|
1149
|
-
}
|
|
1150
|
-
l = [];
|
|
1151
|
-
} else if (is_f_mark(t, ";")) {
|
|
1152
|
-
// 存在; 则存好的attr为array的一个子元素
|
|
1153
|
-
type == "array";
|
|
1154
|
-
attr.push(l);
|
|
1155
|
-
l = [];
|
|
1156
|
-
array.push(attr);
|
|
1157
|
-
attr = [];
|
|
1158
|
-
} else {
|
|
1159
|
-
// 按,拆分成段
|
|
1160
|
-
l.push(t);
|
|
1161
|
-
// 段中有: 为dic
|
|
1162
|
-
if (is_f_mark(t, ":")) {
|
|
1163
|
-
type = "dic";
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
// 将dicl的tree转为键对
|
|
1170
|
-
let dic: fdic = {};
|
|
1171
|
-
for (let i of dicl) {
|
|
1172
|
-
let n = "";
|
|
1173
|
-
let t: tree = [];
|
|
1174
|
-
for (let el of i) {
|
|
1175
|
-
if (!n) {
|
|
1176
|
-
n = el.value;
|
|
1177
|
-
} else {
|
|
1178
|
-
if (el.value != ":") t.push(el);
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
dic[n] = t;
|
|
1182
|
-
}
|
|
1303
|
+
let { attr, dic, array }: { attr: tree[]; dic: fdic; array: tree[][] } = f_attr(x);
|
|
1183
1304
|
|
|
1184
1305
|
if (f[x.value]) {
|
|
1185
1306
|
console.log(attr, dic, array);
|
|
1186
|
-
let el = f[x.value](attr, dic, array);
|
|
1307
|
+
let el = f[x.value](attr, dic, array, e);
|
|
1187
1308
|
fragment.append(el);
|
|
1188
1309
|
} else if (ss[x.value]) {
|
|
1189
1310
|
let el = createMath("mo", ss[x.value]);
|
|
@@ -1194,36 +1315,53 @@ function render(tree: tree) {
|
|
|
1194
1315
|
if (x.type == "f" && !x.children) {
|
|
1195
1316
|
if (ss[x.value]) {
|
|
1196
1317
|
let tag: keyof MathMLElementTagNameMap;
|
|
1197
|
-
|
|
1318
|
+
let space_w = null;
|
|
1319
|
+
const space_width = {
|
|
1320
|
+
" ": "0.36em",
|
|
1321
|
+
" ": "0.5em",
|
|
1322
|
+
" ": "3.75em",
|
|
1323
|
+
" ": "0.333em",
|
|
1324
|
+
" ": "0.25em",
|
|
1325
|
+
" ": "0.166em",
|
|
1326
|
+
" ": "0.222em",
|
|
1327
|
+
" ": "1ch",
|
|
1328
|
+
" ": "0.27em",
|
|
1329
|
+
" ": "0.2em",
|
|
1330
|
+
" ": "0.09em",
|
|
1331
|
+
};
|
|
1332
|
+
if (ss[x.value].match(/[a-zA-Z\u0391-\u03C9]/)) {
|
|
1198
1333
|
tag = "mi";
|
|
1334
|
+
} else if (space_width[ss[x.value]]) {
|
|
1335
|
+
tag = "mspace";
|
|
1336
|
+
space_w = { width: space_width[ss[x.value]] };
|
|
1199
1337
|
} else {
|
|
1200
1338
|
tag = "mo";
|
|
1201
1339
|
}
|
|
1202
|
-
let el = createMath(tag, ss[x.value]);
|
|
1340
|
+
let el = createMath(tag, ss[x.value], space_w);
|
|
1203
1341
|
fragment.append(el);
|
|
1204
1342
|
} else {
|
|
1205
1343
|
if (f[x.value]) {
|
|
1206
|
-
let el = f[x.value]();
|
|
1344
|
+
let el = f[x.value](null, null, null, e);
|
|
1207
1345
|
fragment.append(el);
|
|
1208
1346
|
}
|
|
1209
1347
|
}
|
|
1210
1348
|
}
|
|
1211
1349
|
|
|
1212
1350
|
if (x.type == "str") {
|
|
1213
|
-
let el = createMath("ms", x.value);
|
|
1351
|
+
let el = createMath("ms", font(x.value, e));
|
|
1214
1352
|
fragment.append(el);
|
|
1215
1353
|
}
|
|
1216
1354
|
|
|
1217
1355
|
if (x.type == "v") {
|
|
1218
1356
|
let tag: keyof MathMLElementTagNameMap;
|
|
1219
|
-
if (x.value.match(/[0-9]+/)) {
|
|
1357
|
+
if (x.value.match(/[0-9.]+/)) {
|
|
1220
1358
|
tag = "mn";
|
|
1221
1359
|
} else if (x.value.match(/[a-zA-Z\u0391-\u03C9]/)) {
|
|
1222
1360
|
tag = "mi";
|
|
1223
1361
|
} else {
|
|
1224
1362
|
tag = "mo";
|
|
1225
1363
|
}
|
|
1226
|
-
let el = createMath(tag, x.value);
|
|
1364
|
+
let el = createMath(tag, font(x.value, e));
|
|
1227
1365
|
fragment.append(el);
|
|
1228
1366
|
}
|
|
1229
1367
|
|
|
@@ -1235,6 +1373,16 @@ function render(tree: tree) {
|
|
|
1235
1373
|
return fragment;
|
|
1236
1374
|
}
|
|
1237
1375
|
|
|
1376
|
+
var init_c = {
|
|
1377
|
+
emoji: false,
|
|
1378
|
+
};
|
|
1379
|
+
|
|
1380
|
+
function init(p: { emoji: boolean }) {
|
|
1381
|
+
for (let i in p) {
|
|
1382
|
+
if (init_c[i]) init_c[i] = p[i];
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1238
1386
|
function toMML(str: string) {
|
|
1239
1387
|
let obj = ast(str);
|
|
1240
1388
|
console.log(obj);
|
|
@@ -1250,4 +1398,4 @@ function toMMLHTML(str: string) {
|
|
|
1250
1398
|
return toMML(str).outerHTML;
|
|
1251
1399
|
}
|
|
1252
1400
|
|
|
1253
|
-
export { toMML, toMMLHTML };
|
|
1401
|
+
export { init, toMML, toMMLHTML };
|