@drghaliasri/butex 5.3.2 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -160,7 +160,7 @@ declare function renderMathNodeLatex(math: MathNode): string;
160
160
  declare function isDisplayMathNode(math: MathNode): boolean;
161
161
 
162
162
  type EditorSide = 'english' | 'arabic';
163
- type EditorNodeKind = 'char' | 'number' | 'operator' | 'delimiter' | 'frac' | 'sqrt' | 'env' | 'atomicCommand' | 'atomicOperatorCommand';
163
+ type EditorNodeKind = 'char' | 'number' | 'operator' | 'delimiter' | 'frac' | 'sqrt' | 'overset' | 'underset' | 'accent' | 'env' | 'atomicCommand' | 'atomicOperatorCommand';
164
164
  type MatrixEnvStyle = 'matrix' | 'pmatrix' | 'bmatrix' | 'Bmatrix' | 'vmatrix' | 'Vmatrix';
165
165
  type GridEnvName = MatrixEnvStyle | 'array' | 'aligned';
166
166
  type EnvColumnAlignment = 'l' | 'c' | 'r';
@@ -185,6 +185,9 @@ type EditorNode = {
185
185
  denominator: EditorChain | null;
186
186
  radicand: EditorChain | null;
187
187
  rootIndex: EditorChain | null;
188
+ overExpr: EditorChain | null;
189
+ underExpr: EditorChain | null;
190
+ baseExpr: EditorChain | null;
188
191
  envName: GridEnvName | null;
189
192
  matrixStyle: MatrixEnvStyle | null;
190
193
  matrixRows: EditorChain[][] | null;
@@ -160,7 +160,7 @@ declare function renderMathNodeLatex(math: MathNode): string;
160
160
  declare function isDisplayMathNode(math: MathNode): boolean;
161
161
 
162
162
  type EditorSide = 'english' | 'arabic';
163
- type EditorNodeKind = 'char' | 'number' | 'operator' | 'delimiter' | 'frac' | 'sqrt' | 'env' | 'atomicCommand' | 'atomicOperatorCommand';
163
+ type EditorNodeKind = 'char' | 'number' | 'operator' | 'delimiter' | 'frac' | 'sqrt' | 'overset' | 'underset' | 'accent' | 'env' | 'atomicCommand' | 'atomicOperatorCommand';
164
164
  type MatrixEnvStyle = 'matrix' | 'pmatrix' | 'bmatrix' | 'Bmatrix' | 'vmatrix' | 'Vmatrix';
165
165
  type GridEnvName = MatrixEnvStyle | 'array' | 'aligned';
166
166
  type EnvColumnAlignment = 'l' | 'c' | 'r';
@@ -185,6 +185,9 @@ type EditorNode = {
185
185
  denominator: EditorChain | null;
186
186
  radicand: EditorChain | null;
187
187
  rootIndex: EditorChain | null;
188
+ overExpr: EditorChain | null;
189
+ underExpr: EditorChain | null;
190
+ baseExpr: EditorChain | null;
188
191
  envName: GridEnvName | null;
189
192
  matrixStyle: MatrixEnvStyle | null;
190
193
  matrixRows: EditorChain[][] | null;
package/dist/document.js CHANGED
@@ -768,6 +768,141 @@ function isSupportedDocumentCommand(command) {
768
768
  return TEXT_COMMANDS.has(command) || LIST_COMMANDS.has(command) || command === "\\begin{tabular}" || command === "\\includegraphics" || command === "\\raw";
769
769
  }
770
770
 
771
+ // src/editor/accentCommands.ts
772
+ var ACCENT_COMMANDS = {
773
+ vec: {
774
+ id: "vec",
775
+ englishTex: "\\vec",
776
+ arabicTex: "\\arabvec",
777
+ placement: "over",
778
+ label: "\u20D7",
779
+ title: "\u0633\u0647\u0645 \u0641\u0648\u0642"
780
+ },
781
+ hat: {
782
+ id: "hat",
783
+ englishTex: "\\hat",
784
+ arabicTex: "\\hat",
785
+ placement: "over",
786
+ label: "\u02C6",
787
+ title: "\u0642\u0628\u0639\u0629"
788
+ },
789
+ tilde: {
790
+ id: "tilde",
791
+ englishTex: "\\tilde",
792
+ arabicTex: "\\tilde",
793
+ placement: "over",
794
+ label: "\u02DC",
795
+ title: "\u0645\u062F\u0629"
796
+ },
797
+ dot: {
798
+ id: "dot",
799
+ englishTex: "\\dot",
800
+ arabicTex: "\\dot",
801
+ placement: "over",
802
+ label: "\u02D9",
803
+ title: "\u0646\u0642\u0637\u0629 \u0641\u0648\u0642"
804
+ },
805
+ ddot: {
806
+ id: "ddot",
807
+ englishTex: "\\ddot",
808
+ arabicTex: "\\ddot",
809
+ placement: "over",
810
+ label: "\xA8",
811
+ title: "\u0646\u0642\u0637\u062A\u0627\u0646 \u0641\u0648\u0642"
812
+ },
813
+ dddot: {
814
+ id: "dddot",
815
+ englishTex: "\\dddot",
816
+ arabicTex: "\\dddot",
817
+ placement: "over",
818
+ label: "\u20DB",
819
+ title: "\u062B\u0644\u0627\u062B \u0646\u0642\u0627\u0637 \u0641\u0648\u0642"
820
+ },
821
+ bar: {
822
+ id: "bar",
823
+ englishTex: "\\bar",
824
+ arabicTex: "\\bar",
825
+ placement: "over",
826
+ label: "\xAF",
827
+ title: "\u062E\u0637 \u0641\u0648\u0642"
828
+ },
829
+ check: {
830
+ id: "check",
831
+ englishTex: "\\check",
832
+ arabicTex: "\\check",
833
+ placement: "over",
834
+ label: "\u02C7",
835
+ title: "\u0639\u0644\u0627\u0645\u0629 \u062A\u062D\u0642\u0642"
836
+ },
837
+ breve: {
838
+ id: "breve",
839
+ englishTex: "\\breve",
840
+ arabicTex: "\\breve",
841
+ placement: "over",
842
+ label: "\u02D8",
843
+ title: "\u0642\u0648\u0633 \u0642\u0635\u064A\u0631"
844
+ },
845
+ acute: {
846
+ id: "acute",
847
+ englishTex: "\\acute",
848
+ arabicTex: "\\grave",
849
+ placement: "over",
850
+ label: "\xB4",
851
+ title: "\u0646\u0628\u0631\u0629 \u062D\u0627\u062F\u0629"
852
+ },
853
+ grave: {
854
+ id: "grave",
855
+ englishTex: "\\grave",
856
+ arabicTex: "\\acute",
857
+ placement: "over",
858
+ label: "`",
859
+ title: "\u0646\u0628\u0631\u0629 \u062B\u0642\u064A\u0644\u0629"
860
+ },
861
+ overline: {
862
+ id: "overline",
863
+ englishTex: "\\overline",
864
+ arabicTex: "\\overline",
865
+ placement: "over",
866
+ label: "\u203E",
867
+ title: "\u062E\u0637 \u0639\u0644\u0648\u064A \u0645\u0645\u062A\u062F"
868
+ },
869
+ underline: {
870
+ id: "underline",
871
+ englishTex: "\\underline",
872
+ arabicTex: "\\underline",
873
+ placement: "under",
874
+ label: "_",
875
+ title: "\u062E\u0637 \u0633\u0641\u0644\u064A"
876
+ },
877
+ overleftarrow: {
878
+ id: "overleftarrow",
879
+ englishTex: "\\overleftarrow",
880
+ arabicTex: "\\overrightarrow",
881
+ placement: "over",
882
+ label: "\u2190",
883
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631"
884
+ },
885
+ overrightarrow: {
886
+ id: "overrightarrow",
887
+ englishTex: "\\overrightarrow",
888
+ arabicTex: "\\overleftarrow",
889
+ placement: "over",
890
+ label: "\u2192",
891
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646"
892
+ },
893
+ overleftrightarrow: {
894
+ id: "overleftrightarrow",
895
+ englishTex: "\\overleftrightarrow",
896
+ arabicTex: "\\overleftrightarrow",
897
+ placement: "over",
898
+ label: "\u2194",
899
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0645\u0632\u062F\u0648\u062C \u0627\u0644\u0627\u062A\u062C\u0627\u0647"
900
+ }
901
+ };
902
+ function accentCommandSpec(id) {
903
+ return Object.prototype.hasOwnProperty.call(ACCENT_COMMANDS, id) ? ACCENT_COMMANDS[id] : null;
904
+ }
905
+
771
906
  // src/editor/atomicCommands.ts
772
907
  var ATOMIC_COMMANDS = {
773
908
  ///////////////////////// Functions ////////////////////////////////
@@ -1182,7 +1317,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1182
1317
  id: "neq",
1183
1318
  category: "operators1",
1184
1319
  Tex: "\\neq",
1185
- mirror: false,
1320
+ mirror: true,
1186
1321
  Label: "\u2260",
1187
1322
  title: "\u0644\u0627 \u064A\u0633\u0627\u0648\u064A",
1188
1323
  svg_path: null
@@ -1192,6 +1327,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1192
1327
  category: "operators1",
1193
1328
  Tex: "\\approx",
1194
1329
  mirror: false,
1330
+ displayMirror: true,
1195
1331
  Label: "\u2248",
1196
1332
  title: "\u062A\u0642\u0631\u064A\u0628\u0627 \u064A\u0633\u0627\u0648\u064A",
1197
1333
  svg_path: null
@@ -1201,6 +1337,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1201
1337
  category: "operators1",
1202
1338
  Tex: "\\sim",
1203
1339
  mirror: false,
1340
+ displayMirror: true,
1204
1341
  Label: "\u223C",
1205
1342
  title: "\u0645\u0634\u0627\u0628\u0647",
1206
1343
  svg_path: null
@@ -1219,6 +1356,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1219
1356
  category: "operators1",
1220
1357
  Tex: "\\leq",
1221
1358
  mirror: true,
1359
+ displayMirror: false,
1222
1360
  Label: "\u2264",
1223
1361
  title: "\u0623\u0635\u063A\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1224
1362
  svg_path: null
@@ -1228,6 +1366,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1228
1366
  category: "operators1",
1229
1367
  Tex: "\\geq",
1230
1368
  mirror: true,
1369
+ displayMirror: false,
1231
1370
  Label: "\u2265",
1232
1371
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1233
1372
  svg_path: null
@@ -1237,6 +1376,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1237
1376
  category: "operators1",
1238
1377
  Tex: "\\coloneqq",
1239
1378
  mirror: true,
1379
+ displayMirror: false,
1240
1380
  Label: "\u2254",
1241
1381
  title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
1242
1382
  svg_path: null
@@ -1246,6 +1386,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1246
1386
  category: "operators1",
1247
1387
  Tex: "\\eqqcolon",
1248
1388
  mirror: true,
1389
+ displayMirror: false,
1249
1390
  Label: "\u2255",
1250
1391
  title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
1251
1392
  svg_path: null
@@ -1256,6 +1397,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1256
1397
  category: "operators2",
1257
1398
  Tex: "\\propto",
1258
1399
  mirror: true,
1400
+ displayMirror: false,
1259
1401
  Label: "\u221D",
1260
1402
  title: "\u064A\u062A\u0646\u0627\u0633\u0628 \u0645\u0639",
1261
1403
  svg_path: null
@@ -1265,6 +1407,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1265
1407
  category: "operators2",
1266
1408
  Tex: "\\in",
1267
1409
  mirror: true,
1410
+ displayMirror: false,
1268
1411
  Label: "\u2208",
1269
1412
  title: "\u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1270
1413
  svg_path: null
@@ -1274,6 +1417,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1274
1417
  category: "operators2",
1275
1418
  Tex: "\\notin",
1276
1419
  mirror: false,
1420
+ displayMirror: true,
1277
1421
  Label: "\u2209",
1278
1422
  title: "\u0644\u0627 \u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1279
1423
  svg_path: null
@@ -1283,6 +1427,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1283
1427
  category: "operators2",
1284
1428
  Tex: "\\subset",
1285
1429
  mirror: true,
1430
+ displayMirror: false,
1286
1431
  Label: "\u2282",
1287
1432
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0645\u0646",
1288
1433
  svg_path: null
@@ -1292,6 +1437,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1292
1437
  category: "operators2",
1293
1438
  Tex: "\\supset",
1294
1439
  mirror: true,
1440
+ displayMirror: false,
1295
1441
  Label: "\u2283",
1296
1442
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0644\u0640",
1297
1443
  svg_path: null
@@ -1301,6 +1447,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1301
1447
  category: "operators2",
1302
1448
  Tex: "\\subseteq",
1303
1449
  mirror: true,
1450
+ displayMirror: false,
1304
1451
  Label: "\u2286",
1305
1452
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1306
1453
  svg_path: null
@@ -1310,6 +1457,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1310
1457
  category: "operators2",
1311
1458
  Tex: "\\supseteq",
1312
1459
  mirror: true,
1460
+ displayMirror: false,
1313
1461
  Label: "\u2287",
1314
1462
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1315
1463
  svg_path: null
@@ -1319,6 +1467,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1319
1467
  category: "operators2",
1320
1468
  Tex: "\\cap",
1321
1469
  mirror: false,
1470
+ displayMirror: true,
1322
1471
  Label: "\u2229",
1323
1472
  title: "\u062A\u0642\u0627\u0637\u0639",
1324
1473
  svg_path: null
@@ -1328,6 +1477,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1328
1477
  category: "operators2",
1329
1478
  Tex: "\\cup",
1330
1479
  mirror: false,
1480
+ displayMirror: true,
1331
1481
  Label: "\u222A",
1332
1482
  title: "\u0627\u062A\u062D\u0627\u062F",
1333
1483
  svg_path: null
@@ -1337,6 +1487,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1337
1487
  category: "operators2",
1338
1488
  Tex: "\\emptyset",
1339
1489
  mirror: false,
1490
+ displayMirror: true,
1340
1491
  Label: "\u2205",
1341
1492
  title: "\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u062E\u0627\u0644\u064A\u0629",
1342
1493
  svg_path: null
@@ -1346,6 +1497,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1346
1497
  category: "operators2",
1347
1498
  Tex: "\\nsubseteq",
1348
1499
  mirror: true,
1500
+ displayMirror: false,
1349
1501
  Label: "\u2288",
1350
1502
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1351
1503
  svg_path: null
@@ -1355,6 +1507,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1355
1507
  category: "operators2",
1356
1508
  Tex: "\\nsupseteq",
1357
1509
  mirror: true,
1510
+ displayMirror: false,
1358
1511
  Label: "\u2289",
1359
1512
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1360
1513
  svg_path: null
@@ -1566,6 +1719,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1566
1719
  category: "integrals",
1567
1720
  Tex: "\\iint",
1568
1721
  mirror: true,
1722
+ displayMirror: false,
1569
1723
  Label: "\u222C",
1570
1724
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u0632\u062F\u0648\u062C",
1571
1725
  svg_path: null
@@ -1575,6 +1729,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1575
1729
  category: "integrals",
1576
1730
  Tex: "\\iiint",
1577
1731
  mirror: true,
1732
+ displayMirror: false,
1578
1733
  Label: "\u222D",
1579
1734
  title: "\u062A\u0643\u0627\u0645\u0644 \u062B\u0644\u0627\u062B\u064A",
1580
1735
  svg_path: null
@@ -1584,6 +1739,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1584
1739
  category: "integrals",
1585
1740
  Tex: "\\iiiint",
1586
1741
  mirror: true,
1742
+ displayMirror: false,
1587
1743
  Label: "\u2A0C",
1588
1744
  title: "\u062A\u0643\u0627\u0645\u0644 \u0631\u0628\u0627\u0639\u064A",
1589
1745
  svg_path: null
@@ -1593,6 +1749,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1593
1749
  category: "integrals",
1594
1750
  Tex: "\\oint",
1595
1751
  mirror: true,
1752
+ displayMirror: false,
1596
1753
  Label: "\u222E",
1597
1754
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u063A\u0644\u0642",
1598
1755
  svg_path: null
@@ -1602,6 +1759,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1602
1759
  category: "integrals",
1603
1760
  Tex: "\\oiint",
1604
1761
  mirror: true,
1762
+ displayMirror: false,
1605
1763
  Label: "\u222F",
1606
1764
  title: "\u062A\u0643\u0627\u0645\u0644 \u0633\u0637\u062D\u064A \u0645\u063A\u0644\u0642",
1607
1765
  svg_path: null
@@ -1611,6 +1769,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1611
1769
  category: "integrals",
1612
1770
  Tex: "\\oiiint",
1613
1771
  mirror: true,
1772
+ displayMirror: false,
1614
1773
  Label: "\u2230",
1615
1774
  title: "\u062A\u0643\u0627\u0645\u0644 \u062D\u062C\u0645\u064A \u0645\u063A\u0644\u0642",
1616
1775
  svg_path: null
@@ -1704,6 +1863,14 @@ function renderMatrixRowsArabic(node, options) {
1704
1863
  }
1705
1864
  return `\\begin{${envName}}${rows.join(" \\\\\n")}\\end{${envName}}`;
1706
1865
  }
1866
+ function renderAccentArabic(command, accent, base, options) {
1867
+ const baseTex = base ? renderChainArabic(base, options) : "";
1868
+ const accentTex = accent ? renderChainArabic(accent, options) : "";
1869
+ if (accentTex === "") {
1870
+ return baseTex;
1871
+ }
1872
+ return `\\${command}{${accentTex}}{${baseTex}}`;
1873
+ }
1707
1874
  function escapeText(s) {
1708
1875
  return s.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
1709
1876
  }
@@ -1734,6 +1901,19 @@ function renderNodeArabic(node, options) {
1734
1901
  const content = `\\arabsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
1735
1902
  return arabicScripts(node, content, options);
1736
1903
  }
1904
+ if (node.kind === "overset" && node.baseExpr) {
1905
+ const content = renderAccentArabic("overset", node.overExpr, node.baseExpr, options);
1906
+ return arabicScripts(node, content, options);
1907
+ }
1908
+ if (node.kind === "underset" && node.baseExpr) {
1909
+ const content = renderAccentArabic("underset", node.underExpr, node.baseExpr, options);
1910
+ return arabicScripts(node, content, options);
1911
+ }
1912
+ if (node.kind === "accent" && node.baseExpr) {
1913
+ const cmd = accentCommandSpec(node.expr)?.arabicTex ?? `\\${node.expr}`;
1914
+ const content = `${cmd}{${renderChainArabic(node.baseExpr, options)}}`;
1915
+ return arabicScripts(node, content, options);
1916
+ }
1737
1917
  if (node.kind === "env") {
1738
1918
  return arabicScripts(node, renderMatrixRowsArabic(node, options), options);
1739
1919
  }
@@ -1932,6 +2112,109 @@ var SQRT_CSS = `
1932
2112
  }
1933
2113
  `.trim();
1934
2114
 
2115
+ // src/editor/display/overset.ts
2116
+ var OVERSET_CSS = `
2117
+ .overset {
2118
+ display: inline-flex;
2119
+ flex-direction: column;
2120
+ align-items: center;
2121
+ justify-content: center;
2122
+ vertical-align: middle;
2123
+ margin: 0 2px;
2124
+ min-width: 1.2em;
2125
+ }
2126
+
2127
+ .overset-over {
2128
+ display: inline-flex;
2129
+ justify-content: center;
2130
+ align-items: center;
2131
+ min-height: 0.85em;
2132
+ padding: 0 2px;
2133
+ font-size: 0.72em;
2134
+ line-height: 1.1;
2135
+ }
2136
+
2137
+ .overset-base {
2138
+ display: inline-flex;
2139
+ justify-content: center;
2140
+ align-items: center;
2141
+ min-height: 1.05em;
2142
+ padding: 0 2px;
2143
+ }
2144
+ `.trim();
2145
+
2146
+ // src/editor/display/underset.ts
2147
+ var UNDERSET_CSS = `
2148
+ .underset {
2149
+ display: inline-flex;
2150
+ flex-direction: column;
2151
+ align-items: center;
2152
+ justify-content: center;
2153
+ vertical-align: middle;
2154
+ margin: 0 2px;
2155
+ min-width: 1.2em;
2156
+ }
2157
+
2158
+ .underset-base {
2159
+ display: inline-flex;
2160
+ justify-content: center;
2161
+ align-items: center;
2162
+ min-height: 1.05em;
2163
+ padding: 0 2px;
2164
+ }
2165
+
2166
+ .underset-under {
2167
+ display: inline-flex;
2168
+ justify-content: center;
2169
+ align-items: center;
2170
+ min-height: 0.85em;
2171
+ padding: 0 2px;
2172
+ font-size: 0.72em;
2173
+ line-height: 1.1;
2174
+ }
2175
+ `.trim();
2176
+
2177
+ // src/editor/display/accent.ts
2178
+ var ACCENT_CSS = `
2179
+ .math-accent {
2180
+ display: inline-flex;
2181
+ flex-direction: column;
2182
+ align-items: center;
2183
+ justify-content: center;
2184
+ vertical-align: middle;
2185
+ margin: 0 2px;
2186
+ min-width: 1.1em;
2187
+ }
2188
+
2189
+ .math-accent-chrome {
2190
+ display: inline-flex;
2191
+ justify-content: center;
2192
+ align-items: center;
2193
+ min-height: 0.7em;
2194
+ padding: 0 2px;
2195
+ font-size: 0.85em;
2196
+ line-height: 1;
2197
+ color: var(--butex-script-color, #475569);
2198
+ user-select: none;
2199
+ }
2200
+
2201
+ .math-accent-base {
2202
+ display: inline-flex;
2203
+ justify-content: center;
2204
+ align-items: center;
2205
+ min-height: 1.05em;
2206
+ padding: 0 2px;
2207
+ }
2208
+
2209
+ .math-accent--under .math-accent-chrome {
2210
+ min-height: 0.45em;
2211
+ border-top: 1.5px solid currentColor;
2212
+ width: 100%;
2213
+ font-size: 0;
2214
+ color: var(--butex-surface-fg, #0f172a);
2215
+ }
2216
+ `.trim();
2217
+
1935
2218
  // src/editor/display/env.ts
1936
2219
  var MATRIX_ENV_CSS = `
1937
2220
  .matrix-env {
@@ -2319,6 +2602,12 @@ ${FRAC_CSS}
2319
2602
 
2320
2603
  ${SQRT_CSS}
2321
2604
 
2605
+ ${OVERSET_CSS}
2606
+
2607
+ ${UNDERSET_CSS}
2608
+
2609
+ ${ACCENT_CSS}
2610
+
2322
2611
  ${MATRIX_ENV_CSS}
2323
2612
 
2324
2613
  ${ATOMIC_COMMAND_CSS}
@@ -2392,6 +2681,21 @@ function editorEnvToAstNode(node) {
2392
2681
  const scripts = attachAstScripts(node, env);
2393
2682
  return scripts ?? { ok: true, node: env };
2394
2683
  }
2684
+ function accentChainForExport(accent) {
2685
+ if (!accent) {
2686
+ return { ok: true, chain: new ChainNode([]) };
2687
+ }
2688
+ return editorChainToAstChain(accent);
2689
+ }
2690
+ function nodeFromAccentBase(command, accent, base) {
2691
+ if (accent.chain.length > 0) {
2692
+ return new CommandNode(command, [], [accent, base]);
2693
+ }
2694
+ if (base.chain.length === 1) {
2695
+ return base.chain[0];
2696
+ }
2697
+ return new DelimiterNode("", base, "");
2698
+ }
2395
2699
  function editorNodeToAstNode(node) {
2396
2700
  let astNode;
2397
2701
  if (node.kind === "char") {
@@ -2430,6 +2734,36 @@ function editorNodeToAstNode(node) {
2430
2734
  optionalArgs.push(rootIndex.chain);
2431
2735
  }
2432
2736
  astNode = new CommandNode("\\sqrt", optionalArgs, [radicand.chain]);
2737
+ } else if (node.kind === "overset" && node.baseExpr) {
2738
+ const accent = accentChainForExport(node.overExpr);
2739
+ if (!accent.ok) {
2740
+ return accent;
2741
+ }
2742
+ const baseExpr = editorChainToAstChain(node.baseExpr);
2743
+ if (!baseExpr.ok) {
2744
+ return baseExpr;
2745
+ }
2746
+ astNode = nodeFromAccentBase("\\overset", accent.chain, baseExpr.chain);
2747
+ } else if (node.kind === "underset" && node.baseExpr) {
2748
+ const accent = accentChainForExport(node.underExpr);
2749
+ if (!accent.ok) {
2750
+ return accent;
2751
+ }
2752
+ const baseExpr = editorChainToAstChain(node.baseExpr);
2753
+ if (!baseExpr.ok) {
2754
+ return baseExpr;
2755
+ }
2756
+ astNode = nodeFromAccentBase("\\underset", accent.chain, baseExpr.chain);
2757
+ } else if (node.kind === "accent" && node.baseExpr) {
2758
+ const tex = accentCommandSpec(node.expr)?.englishTex;
2759
+ if (!tex) {
2760
+ return { ok: false, reason: `\u0644\u0643\u0646\u0629 \u0631\u064A\u0627\u0636\u064A\u0629 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645\u0629 \u062D\u0627\u0644\u064A\u0627: ${node.expr}` };
2761
+ }
2762
+ const baseExpr = editorChainToAstChain(node.baseExpr);
2763
+ if (!baseExpr.ok) {
2764
+ return baseExpr;
2765
+ }
2766
+ astNode = new CommandNode(tex, [], [baseExpr.chain]);
2433
2767
  } else if (node.kind === "atomicCommand") {
2434
2768
  const tex = atomicCommandSpec(node.expr)?.englishTex;
2435
2769
  if (!tex) {