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/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 continue_c = 0;
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 f = createMath("mrow");
339
+ let r = createMath("mrow");
328
340
  let l = createMath("mo", dic?.delim?.[0]?.value || "{");
329
- let t = createMath("mtable", null, { columnalign: "left" });
330
- for (let i of attr) {
331
- let tr = createMath("mtr");
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
- inline: (attr: tree[], dic: fdic) => {},
409
- script: (attr: tree[], dic: fdic) => {},
410
- sscript: (attr: tree[], dic: fdic) => {},
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
- sans: (attr: tree[], dic: fdic) => {},
466
- frak: (attr: tree[], dic: fdic) => {},
467
- mono: (attr: tree[], dic: fdic) => {},
468
- bb: (attr: tree[], dic: fdic) => {},
469
- cal: (attr: tree[], dic: fdic) => {},
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 i in tree) {
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(/[0-9]/)) &&
760
- !(tree[n + 1]?.value == "." && tree[n + 2]?.value.match(num))
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 continue_c = 0;
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
- continue_c = l.at(-1).length - 1;
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 continue_c = 0;
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
- continue_c = 1;
883
+ n++;
830
884
  } else if (next.type == "blank") {
831
885
  t.push({ type: "v", value: "br", esc: true });
832
- continue_c = 1;
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
- continue_c = 1;
891
+ n++;
838
892
  } else {
839
893
  let v = next;
840
894
  v.esc = true;
841
895
  t.push(v);
842
- continue_c = 1;
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
- // 处理f
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 continue_c = 0;
856
- for (let i in tree) {
857
- if (continue_c > 0) {
858
- continue_c--;
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
- let n = Number(i);
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
- continue_c = 1;
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 continue_c = 0;
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
- continue_c = 4 - 1;
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
- continue_c = 4 - 1;
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
- continue_c = 2 - 1;
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
- continue_c = 2 - 1;
1057
+ i -= 2 - 1;
981
1058
  continue;
982
1059
  }
983
1060
  }
984
1061
  t.push(tmp);
985
1062
  }
986
- continue_c = index[0][1] - index[0][0];
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[i]);
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 continue_c = 0;
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
- continue_c = 2 - 1;
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
- continue_c = index[0][1] - index[0][0];
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[i]);
1116
+ t.push(tree[n]);
1053
1117
  }
1054
1118
  tree = t;
1055
1119
  }
1056
1120
  return tree;
1057
1121
  }
1058
1122
 
1059
- function render(tree: tree) {
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 type: "dic" | "array" | "attr" = "array";
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
- if (x.value.match(/[a-zA-Z\u0391-\u03C9]/)) {
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 };