@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.
package/dist/document2.js CHANGED
@@ -1501,6 +1501,155 @@ function createEmptyDocument2() {
1501
1501
  };
1502
1502
  }
1503
1503
 
1504
+ // src/editor/accentCommands.ts
1505
+ var ACCENT_COMMANDS = {
1506
+ vec: {
1507
+ id: "vec",
1508
+ englishTex: "\\vec",
1509
+ arabicTex: "\\arabvec",
1510
+ placement: "over",
1511
+ label: "\u20D7",
1512
+ title: "\u0633\u0647\u0645 \u0641\u0648\u0642"
1513
+ },
1514
+ hat: {
1515
+ id: "hat",
1516
+ englishTex: "\\hat",
1517
+ arabicTex: "\\hat",
1518
+ placement: "over",
1519
+ label: "\u02C6",
1520
+ title: "\u0642\u0628\u0639\u0629"
1521
+ },
1522
+ tilde: {
1523
+ id: "tilde",
1524
+ englishTex: "\\tilde",
1525
+ arabicTex: "\\tilde",
1526
+ placement: "over",
1527
+ label: "\u02DC",
1528
+ title: "\u0645\u062F\u0629"
1529
+ },
1530
+ dot: {
1531
+ id: "dot",
1532
+ englishTex: "\\dot",
1533
+ arabicTex: "\\dot",
1534
+ placement: "over",
1535
+ label: "\u02D9",
1536
+ title: "\u0646\u0642\u0637\u0629 \u0641\u0648\u0642"
1537
+ },
1538
+ ddot: {
1539
+ id: "ddot",
1540
+ englishTex: "\\ddot",
1541
+ arabicTex: "\\ddot",
1542
+ placement: "over",
1543
+ label: "\xA8",
1544
+ title: "\u0646\u0642\u0637\u062A\u0627\u0646 \u0641\u0648\u0642"
1545
+ },
1546
+ dddot: {
1547
+ id: "dddot",
1548
+ englishTex: "\\dddot",
1549
+ arabicTex: "\\dddot",
1550
+ placement: "over",
1551
+ label: "\u20DB",
1552
+ title: "\u062B\u0644\u0627\u062B \u0646\u0642\u0627\u0637 \u0641\u0648\u0642"
1553
+ },
1554
+ bar: {
1555
+ id: "bar",
1556
+ englishTex: "\\bar",
1557
+ arabicTex: "\\bar",
1558
+ placement: "over",
1559
+ label: "\xAF",
1560
+ title: "\u062E\u0637 \u0641\u0648\u0642"
1561
+ },
1562
+ check: {
1563
+ id: "check",
1564
+ englishTex: "\\check",
1565
+ arabicTex: "\\check",
1566
+ placement: "over",
1567
+ label: "\u02C7",
1568
+ title: "\u0639\u0644\u0627\u0645\u0629 \u062A\u062D\u0642\u0642"
1569
+ },
1570
+ breve: {
1571
+ id: "breve",
1572
+ englishTex: "\\breve",
1573
+ arabicTex: "\\breve",
1574
+ placement: "over",
1575
+ label: "\u02D8",
1576
+ title: "\u0642\u0648\u0633 \u0642\u0635\u064A\u0631"
1577
+ },
1578
+ acute: {
1579
+ id: "acute",
1580
+ englishTex: "\\acute",
1581
+ arabicTex: "\\grave",
1582
+ placement: "over",
1583
+ label: "\xB4",
1584
+ title: "\u0646\u0628\u0631\u0629 \u062D\u0627\u062F\u0629"
1585
+ },
1586
+ grave: {
1587
+ id: "grave",
1588
+ englishTex: "\\grave",
1589
+ arabicTex: "\\acute",
1590
+ placement: "over",
1591
+ label: "`",
1592
+ title: "\u0646\u0628\u0631\u0629 \u062B\u0642\u064A\u0644\u0629"
1593
+ },
1594
+ overline: {
1595
+ id: "overline",
1596
+ englishTex: "\\overline",
1597
+ arabicTex: "\\overline",
1598
+ placement: "over",
1599
+ label: "\u203E",
1600
+ title: "\u062E\u0637 \u0639\u0644\u0648\u064A \u0645\u0645\u062A\u062F"
1601
+ },
1602
+ underline: {
1603
+ id: "underline",
1604
+ englishTex: "\\underline",
1605
+ arabicTex: "\\underline",
1606
+ placement: "under",
1607
+ label: "_",
1608
+ title: "\u062E\u0637 \u0633\u0641\u0644\u064A"
1609
+ },
1610
+ overleftarrow: {
1611
+ id: "overleftarrow",
1612
+ englishTex: "\\overleftarrow",
1613
+ arabicTex: "\\overrightarrow",
1614
+ placement: "over",
1615
+ label: "\u2190",
1616
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631"
1617
+ },
1618
+ overrightarrow: {
1619
+ id: "overrightarrow",
1620
+ englishTex: "\\overrightarrow",
1621
+ arabicTex: "\\overleftarrow",
1622
+ placement: "over",
1623
+ label: "\u2192",
1624
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646"
1625
+ },
1626
+ overleftrightarrow: {
1627
+ id: "overleftrightarrow",
1628
+ englishTex: "\\overleftrightarrow",
1629
+ arabicTex: "\\overleftrightarrow",
1630
+ placement: "over",
1631
+ label: "\u2194",
1632
+ title: "\u0633\u0647\u0645 \u0639\u0644\u0648\u064A \u0645\u0632\u062F\u0648\u062C \u0627\u0644\u0627\u062A\u062C\u0627\u0647"
1633
+ }
1634
+ };
1635
+ function accentCommandSpec(id) {
1636
+ return Object.prototype.hasOwnProperty.call(ACCENT_COMMANDS, id) ? ACCENT_COMMANDS[id] : null;
1637
+ }
1638
+ function accentCommandIdFromTex(tex) {
1639
+ const normalized = tex.startsWith("\\") ? tex : `\\${tex}`;
1640
+ for (const spec of Object.values(ACCENT_COMMANDS)) {
1641
+ if (spec.englishTex === normalized) {
1642
+ return spec.id;
1643
+ }
1644
+ }
1645
+ for (const spec of Object.values(ACCENT_COMMANDS)) {
1646
+ if (spec.arabicTex === normalized) {
1647
+ return spec.id;
1648
+ }
1649
+ }
1650
+ return null;
1651
+ }
1652
+
1504
1653
  // src/editor/atomicCommands.ts
1505
1654
  var ATOMIC_COMMANDS = {
1506
1655
  ///////////////////////// Functions ////////////////////////////////
@@ -1915,7 +2064,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1915
2064
  id: "neq",
1916
2065
  category: "operators1",
1917
2066
  Tex: "\\neq",
1918
- mirror: false,
2067
+ mirror: true,
1919
2068
  Label: "\u2260",
1920
2069
  title: "\u0644\u0627 \u064A\u0633\u0627\u0648\u064A",
1921
2070
  svg_path: null
@@ -1925,6 +2074,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1925
2074
  category: "operators1",
1926
2075
  Tex: "\\approx",
1927
2076
  mirror: false,
2077
+ displayMirror: true,
1928
2078
  Label: "\u2248",
1929
2079
  title: "\u062A\u0642\u0631\u064A\u0628\u0627 \u064A\u0633\u0627\u0648\u064A",
1930
2080
  svg_path: null
@@ -1934,6 +2084,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1934
2084
  category: "operators1",
1935
2085
  Tex: "\\sim",
1936
2086
  mirror: false,
2087
+ displayMirror: true,
1937
2088
  Label: "\u223C",
1938
2089
  title: "\u0645\u0634\u0627\u0628\u0647",
1939
2090
  svg_path: null
@@ -1952,6 +2103,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1952
2103
  category: "operators1",
1953
2104
  Tex: "\\leq",
1954
2105
  mirror: true,
2106
+ displayMirror: false,
1955
2107
  Label: "\u2264",
1956
2108
  title: "\u0623\u0635\u063A\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1957
2109
  svg_path: null
@@ -1961,6 +2113,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1961
2113
  category: "operators1",
1962
2114
  Tex: "\\geq",
1963
2115
  mirror: true,
2116
+ displayMirror: false,
1964
2117
  Label: "\u2265",
1965
2118
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1966
2119
  svg_path: null
@@ -1970,6 +2123,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1970
2123
  category: "operators1",
1971
2124
  Tex: "\\coloneqq",
1972
2125
  mirror: true,
2126
+ displayMirror: false,
1973
2127
  Label: "\u2254",
1974
2128
  title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
1975
2129
  svg_path: null
@@ -1979,6 +2133,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1979
2133
  category: "operators1",
1980
2134
  Tex: "\\eqqcolon",
1981
2135
  mirror: true,
2136
+ displayMirror: false,
1982
2137
  Label: "\u2255",
1983
2138
  title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
1984
2139
  svg_path: null
@@ -1989,6 +2144,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1989
2144
  category: "operators2",
1990
2145
  Tex: "\\propto",
1991
2146
  mirror: true,
2147
+ displayMirror: false,
1992
2148
  Label: "\u221D",
1993
2149
  title: "\u064A\u062A\u0646\u0627\u0633\u0628 \u0645\u0639",
1994
2150
  svg_path: null
@@ -1998,6 +2154,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1998
2154
  category: "operators2",
1999
2155
  Tex: "\\in",
2000
2156
  mirror: true,
2157
+ displayMirror: false,
2001
2158
  Label: "\u2208",
2002
2159
  title: "\u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
2003
2160
  svg_path: null
@@ -2007,6 +2164,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2007
2164
  category: "operators2",
2008
2165
  Tex: "\\notin",
2009
2166
  mirror: false,
2167
+ displayMirror: true,
2010
2168
  Label: "\u2209",
2011
2169
  title: "\u0644\u0627 \u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
2012
2170
  svg_path: null
@@ -2016,6 +2174,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2016
2174
  category: "operators2",
2017
2175
  Tex: "\\subset",
2018
2176
  mirror: true,
2177
+ displayMirror: false,
2019
2178
  Label: "\u2282",
2020
2179
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0645\u0646",
2021
2180
  svg_path: null
@@ -2025,6 +2184,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2025
2184
  category: "operators2",
2026
2185
  Tex: "\\supset",
2027
2186
  mirror: true,
2187
+ displayMirror: false,
2028
2188
  Label: "\u2283",
2029
2189
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0644\u0640",
2030
2190
  svg_path: null
@@ -2034,6 +2194,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2034
2194
  category: "operators2",
2035
2195
  Tex: "\\subseteq",
2036
2196
  mirror: true,
2197
+ displayMirror: false,
2037
2198
  Label: "\u2286",
2038
2199
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2039
2200
  svg_path: null
@@ -2043,6 +2204,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2043
2204
  category: "operators2",
2044
2205
  Tex: "\\supseteq",
2045
2206
  mirror: true,
2207
+ displayMirror: false,
2046
2208
  Label: "\u2287",
2047
2209
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2048
2210
  svg_path: null
@@ -2052,6 +2214,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2052
2214
  category: "operators2",
2053
2215
  Tex: "\\cap",
2054
2216
  mirror: false,
2217
+ displayMirror: true,
2055
2218
  Label: "\u2229",
2056
2219
  title: "\u062A\u0642\u0627\u0637\u0639",
2057
2220
  svg_path: null
@@ -2061,6 +2224,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2061
2224
  category: "operators2",
2062
2225
  Tex: "\\cup",
2063
2226
  mirror: false,
2227
+ displayMirror: true,
2064
2228
  Label: "\u222A",
2065
2229
  title: "\u0627\u062A\u062D\u0627\u062F",
2066
2230
  svg_path: null
@@ -2070,6 +2234,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2070
2234
  category: "operators2",
2071
2235
  Tex: "\\emptyset",
2072
2236
  mirror: false,
2237
+ displayMirror: true,
2073
2238
  Label: "\u2205",
2074
2239
  title: "\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u062E\u0627\u0644\u064A\u0629",
2075
2240
  svg_path: null
@@ -2079,6 +2244,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2079
2244
  category: "operators2",
2080
2245
  Tex: "\\nsubseteq",
2081
2246
  mirror: true,
2247
+ displayMirror: false,
2082
2248
  Label: "\u2288",
2083
2249
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2084
2250
  svg_path: null
@@ -2088,6 +2254,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2088
2254
  category: "operators2",
2089
2255
  Tex: "\\nsupseteq",
2090
2256
  mirror: true,
2257
+ displayMirror: false,
2091
2258
  Label: "\u2289",
2092
2259
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2093
2260
  svg_path: null
@@ -2299,6 +2466,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2299
2466
  category: "integrals",
2300
2467
  Tex: "\\iint",
2301
2468
  mirror: true,
2469
+ displayMirror: false,
2302
2470
  Label: "\u222C",
2303
2471
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u0632\u062F\u0648\u062C",
2304
2472
  svg_path: null
@@ -2308,6 +2476,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2308
2476
  category: "integrals",
2309
2477
  Tex: "\\iiint",
2310
2478
  mirror: true,
2479
+ displayMirror: false,
2311
2480
  Label: "\u222D",
2312
2481
  title: "\u062A\u0643\u0627\u0645\u0644 \u062B\u0644\u0627\u062B\u064A",
2313
2482
  svg_path: null
@@ -2317,6 +2486,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2317
2486
  category: "integrals",
2318
2487
  Tex: "\\iiiint",
2319
2488
  mirror: true,
2489
+ displayMirror: false,
2320
2490
  Label: "\u2A0C",
2321
2491
  title: "\u062A\u0643\u0627\u0645\u0644 \u0631\u0628\u0627\u0639\u064A",
2322
2492
  svg_path: null
@@ -2326,6 +2496,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2326
2496
  category: "integrals",
2327
2497
  Tex: "\\oint",
2328
2498
  mirror: true,
2499
+ displayMirror: false,
2329
2500
  Label: "\u222E",
2330
2501
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u063A\u0644\u0642",
2331
2502
  svg_path: null
@@ -2335,6 +2506,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2335
2506
  category: "integrals",
2336
2507
  Tex: "\\oiint",
2337
2508
  mirror: true,
2509
+ displayMirror: false,
2338
2510
  Label: "\u222F",
2339
2511
  title: "\u062A\u0643\u0627\u0645\u0644 \u0633\u0637\u062D\u064A \u0645\u063A\u0644\u0642",
2340
2512
  svg_path: null
@@ -2344,6 +2516,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2344
2516
  category: "integrals",
2345
2517
  Tex: "\\oiiint",
2346
2518
  mirror: true,
2519
+ displayMirror: false,
2347
2520
  Label: "\u2230",
2348
2521
  title: "\u062A\u0643\u0627\u0645\u0644 \u062D\u062C\u0645\u064A \u0645\u063A\u0644\u0642",
2349
2522
  svg_path: null
@@ -2382,6 +2555,9 @@ function createEditorNode(kind, expr) {
2382
2555
  denominator: null,
2383
2556
  radicand: null,
2384
2557
  rootIndex: null,
2558
+ overExpr: null,
2559
+ underExpr: null,
2560
+ baseExpr: null,
2385
2561
  envName: null,
2386
2562
  matrixStyle: null,
2387
2563
  matrixRows: null,
@@ -2410,6 +2586,26 @@ function createSqrtNode() {
2410
2586
  rootIndex: createEditorChain()
2411
2587
  };
2412
2588
  }
2589
+ function createOversetNode() {
2590
+ return {
2591
+ ...createEditorNode("overset", ""),
2592
+ overExpr: createEditorChain(),
2593
+ baseExpr: createEditorChain()
2594
+ };
2595
+ }
2596
+ function createUndersetNode() {
2597
+ return {
2598
+ ...createEditorNode("underset", ""),
2599
+ underExpr: createEditorChain(),
2600
+ baseExpr: createEditorChain()
2601
+ };
2602
+ }
2603
+ function createAccentNode(accentId) {
2604
+ return {
2605
+ ...createEditorNode("accent", accentId),
2606
+ baseExpr: createEditorChain()
2607
+ };
2608
+ }
2413
2609
  function createGridEnvNode(envName, rows, columns, columnAlignments) {
2414
2610
  const safeRows = Math.max(1, Math.min(12, Math.trunc(rows)));
2415
2611
  const safeColumns = Math.max(1, Math.min(12, Math.trunc(columns)));
@@ -2468,6 +2664,15 @@ function collectNodeIds(chain, ids) {
2468
2664
  if (node.radicand) {
2469
2665
  collectNodeIds(node.radicand, ids);
2470
2666
  }
2667
+ if (node.overExpr) {
2668
+ collectNodeIds(node.overExpr, ids);
2669
+ }
2670
+ if (node.underExpr) {
2671
+ collectNodeIds(node.underExpr, ids);
2672
+ }
2673
+ if (node.baseExpr) {
2674
+ collectNodeIds(node.baseExpr, ids);
2675
+ }
2471
2676
  if (node.matrixRows) {
2472
2677
  for (const row of node.matrixRows) {
2473
2678
  for (const cell of row) {
@@ -2598,6 +2803,22 @@ function renderMatrixRowsArabic(node, options) {
2598
2803
  }
2599
2804
  return `\\begin{${envName}}${rows.join(" \\\\\n")}\\end{${envName}}`;
2600
2805
  }
2806
+ function renderAccentEnglish(command, accent, base, options) {
2807
+ const baseTex = base ? renderChainEnglish(base, options) : "";
2808
+ const accentTex = accent ? renderChainEnglish(accent, options) : "";
2809
+ if (accentTex === "") {
2810
+ return baseTex;
2811
+ }
2812
+ return `\\${command}{${accentTex}}{${baseTex}}`;
2813
+ }
2814
+ function renderAccentArabic(command, accent, base, options) {
2815
+ const baseTex = base ? renderChainArabic(base, options) : "";
2816
+ const accentTex = accent ? renderChainArabic(accent, options) : "";
2817
+ if (accentTex === "") {
2818
+ return baseTex;
2819
+ }
2820
+ return `\\${command}{${accentTex}}{${baseTex}}`;
2821
+ }
2601
2822
  function escapeText(s) {
2602
2823
  return s.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
2603
2824
  }
@@ -2627,6 +2848,19 @@ function renderNodeEnglish(node, options) {
2627
2848
  const body = `\\sqrt${optionalRootIndexEnglish(node, options)}{${renderChainEnglish(node.radicand, options)}}`;
2628
2849
  return `${body}${latinScripts(node, options)}`;
2629
2850
  }
2851
+ if (node.kind === "overset" && node.baseExpr) {
2852
+ const body = renderAccentEnglish("overset", node.overExpr, node.baseExpr, options);
2853
+ return `${body}${latinScripts(node, options)}`;
2854
+ }
2855
+ if (node.kind === "underset" && node.baseExpr) {
2856
+ const body = renderAccentEnglish("underset", node.underExpr, node.baseExpr, options);
2857
+ return `${body}${latinScripts(node, options)}`;
2858
+ }
2859
+ if (node.kind === "accent" && node.baseExpr) {
2860
+ const cmd = accentCommandSpec(node.expr)?.englishTex ?? `\\${node.expr}`;
2861
+ const body = `${cmd}{${renderChainEnglish(node.baseExpr, options)}}`;
2862
+ return `${body}${latinScripts(node, options)}`;
2863
+ }
2630
2864
  if (node.kind === "env") {
2631
2865
  return `${renderMatrixRowsEnglish(node, options)}${latinScripts(node, options)}`;
2632
2866
  }
@@ -2659,6 +2893,19 @@ function renderNodeArabic(node, options) {
2659
2893
  const content = `\\arabsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
2660
2894
  return arabicScripts(node, content, options);
2661
2895
  }
2896
+ if (node.kind === "overset" && node.baseExpr) {
2897
+ const content = renderAccentArabic("overset", node.overExpr, node.baseExpr, options);
2898
+ return arabicScripts(node, content, options);
2899
+ }
2900
+ if (node.kind === "underset" && node.baseExpr) {
2901
+ const content = renderAccentArabic("underset", node.underExpr, node.baseExpr, options);
2902
+ return arabicScripts(node, content, options);
2903
+ }
2904
+ if (node.kind === "accent" && node.baseExpr) {
2905
+ const cmd = accentCommandSpec(node.expr)?.arabicTex ?? `\\${node.expr}`;
2906
+ const content = `${cmd}{${renderChainArabic(node.baseExpr, options)}}`;
2907
+ return arabicScripts(node, content, options);
2908
+ }
2662
2909
  if (node.kind === "env") {
2663
2910
  return arabicScripts(node, renderMatrixRowsArabic(node, options), options);
2664
2911
  }
@@ -2863,6 +3110,109 @@ var SQRT_CSS = `
2863
3110
  }
2864
3111
  `.trim();
2865
3112
 
3113
+ // src/editor/display/overset.ts
3114
+ var OVERSET_CSS = `
3115
+ .overset {
3116
+ display: inline-flex;
3117
+ flex-direction: column;
3118
+ align-items: center;
3119
+ justify-content: center;
3120
+ vertical-align: middle;
3121
+ margin: 0 2px;
3122
+ min-width: 1.2em;
3123
+ }
3124
+
3125
+ .overset-over {
3126
+ display: inline-flex;
3127
+ justify-content: center;
3128
+ align-items: center;
3129
+ min-height: 0.85em;
3130
+ padding: 0 2px;
3131
+ font-size: 0.72em;
3132
+ line-height: 1.1;
3133
+ }
3134
+
3135
+ .overset-base {
3136
+ display: inline-flex;
3137
+ justify-content: center;
3138
+ align-items: center;
3139
+ min-height: 1.05em;
3140
+ padding: 0 2px;
3141
+ }
3142
+ `.trim();
3143
+
3144
+ // src/editor/display/underset.ts
3145
+ var UNDERSET_CSS = `
3146
+ .underset {
3147
+ display: inline-flex;
3148
+ flex-direction: column;
3149
+ align-items: center;
3150
+ justify-content: center;
3151
+ vertical-align: middle;
3152
+ margin: 0 2px;
3153
+ min-width: 1.2em;
3154
+ }
3155
+
3156
+ .underset-base {
3157
+ display: inline-flex;
3158
+ justify-content: center;
3159
+ align-items: center;
3160
+ min-height: 1.05em;
3161
+ padding: 0 2px;
3162
+ }
3163
+
3164
+ .underset-under {
3165
+ display: inline-flex;
3166
+ justify-content: center;
3167
+ align-items: center;
3168
+ min-height: 0.85em;
3169
+ padding: 0 2px;
3170
+ font-size: 0.72em;
3171
+ line-height: 1.1;
3172
+ }
3173
+ `.trim();
3174
+
3175
+ // src/editor/display/accent.ts
3176
+ var ACCENT_CSS = `
3177
+ .math-accent {
3178
+ display: inline-flex;
3179
+ flex-direction: column;
3180
+ align-items: center;
3181
+ justify-content: center;
3182
+ vertical-align: middle;
3183
+ margin: 0 2px;
3184
+ min-width: 1.1em;
3185
+ }
3186
+
3187
+ .math-accent-chrome {
3188
+ display: inline-flex;
3189
+ justify-content: center;
3190
+ align-items: center;
3191
+ min-height: 0.7em;
3192
+ padding: 0 2px;
3193
+ font-size: 0.85em;
3194
+ line-height: 1;
3195
+ color: var(--butex-script-color, #475569);
3196
+ user-select: none;
3197
+ }
3198
+
3199
+ .math-accent-base {
3200
+ display: inline-flex;
3201
+ justify-content: center;
3202
+ align-items: center;
3203
+ min-height: 1.05em;
3204
+ padding: 0 2px;
3205
+ }
3206
+
3207
+ .math-accent--under .math-accent-chrome {
3208
+ min-height: 0.45em;
3209
+ border-top: 1.5px solid currentColor;
3210
+ width: 100%;
3211
+ font-size: 0;
3212
+ color: var(--butex-surface-fg, #0f172a);
3213
+ }
3214
+ `.trim();
3215
+
2866
3216
  // src/editor/display/env.ts
2867
3217
  var MATRIX_ENV_CSS = `
2868
3218
  .matrix-env {
@@ -3250,6 +3600,12 @@ ${FRAC_CSS}
3250
3600
 
3251
3601
  ${SQRT_CSS}
3252
3602
 
3603
+ ${OVERSET_CSS}
3604
+
3605
+ ${UNDERSET_CSS}
3606
+
3607
+ ${ACCENT_CSS}
3608
+
3253
3609
  ${MATRIX_ENV_CSS}
3254
3610
 
3255
3611
  ${ATOMIC_COMMAND_CSS}
@@ -3532,6 +3888,56 @@ function commandToEditorNode(node) {
3532
3888
  }
3533
3889
  return { editable: true, node: sqrt };
3534
3890
  }
3891
+ if (node.name === "\\overset" && node.mandatoryArgs.length >= 2) {
3892
+ const overset = createOversetNode();
3893
+ const overExpr = chainToEditorChain(node.mandatoryArgs[0]);
3894
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[1]);
3895
+ if (!overExpr.editable) {
3896
+ return overExpr;
3897
+ }
3898
+ if (!baseExpr.editable) {
3899
+ return baseExpr;
3900
+ }
3901
+ overset.overExpr = overExpr.chain;
3902
+ overset.baseExpr = baseExpr.chain;
3903
+ const scripts = attachScripts(node, overset);
3904
+ if (scripts) {
3905
+ return scripts;
3906
+ }
3907
+ return { editable: true, node: overset };
3908
+ }
3909
+ if (node.name === "\\underset" && node.mandatoryArgs.length >= 2) {
3910
+ const underset = createUndersetNode();
3911
+ const underExpr = chainToEditorChain(node.mandatoryArgs[0]);
3912
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[1]);
3913
+ if (!underExpr.editable) {
3914
+ return underExpr;
3915
+ }
3916
+ if (!baseExpr.editable) {
3917
+ return baseExpr;
3918
+ }
3919
+ underset.underExpr = underExpr.chain;
3920
+ underset.baseExpr = baseExpr.chain;
3921
+ const scripts = attachScripts(node, underset);
3922
+ if (scripts) {
3923
+ return scripts;
3924
+ }
3925
+ return { editable: true, node: underset };
3926
+ }
3927
+ const accentId = accentCommandIdFromTex(node.name);
3928
+ if (accentId && node.mandatoryArgs.length >= 1) {
3929
+ const accent = createAccentNode(accentId);
3930
+ const baseExpr = chainToEditorChain(node.mandatoryArgs[0]);
3931
+ if (!baseExpr.editable) {
3932
+ return baseExpr;
3933
+ }
3934
+ accent.baseExpr = baseExpr.chain;
3935
+ const scripts = attachScripts(node, accent);
3936
+ if (scripts) {
3937
+ return scripts;
3938
+ }
3939
+ return { editable: true, node: accent };
3940
+ }
3535
3941
  const atomicId = commandIdForTex(node.name);
3536
3942
  if (atomicId && node.optionalArgs.length === 0 && node.mandatoryArgs.length === 0) {
3537
3943
  const atomic = createEditorNode("atomicCommand", atomicId);
@@ -3668,6 +4074,21 @@ function editorEnvToAstNode(node) {
3668
4074
  const scripts = attachAstScripts(node, env);
3669
4075
  return scripts ?? { ok: true, node: env };
3670
4076
  }
4077
+ function accentChainForExport(accent) {
4078
+ if (!accent) {
4079
+ return { ok: true, chain: new ChainNode([]) };
4080
+ }
4081
+ return editorChainToAstChain(accent);
4082
+ }
4083
+ function nodeFromAccentBase(command, accent, base) {
4084
+ if (accent.chain.length > 0) {
4085
+ return new CommandNode(command, [], [accent, base]);
4086
+ }
4087
+ if (base.chain.length === 1) {
4088
+ return base.chain[0];
4089
+ }
4090
+ return new DelimiterNode("", base, "");
4091
+ }
3671
4092
  function editorNodeToAstNode(node) {
3672
4093
  let astNode;
3673
4094
  if (node.kind === "char") {
@@ -3706,6 +4127,36 @@ function editorNodeToAstNode(node) {
3706
4127
  optionalArgs.push(rootIndex.chain);
3707
4128
  }
3708
4129
  astNode = new CommandNode("\\sqrt", optionalArgs, [radicand.chain]);
4130
+ } else if (node.kind === "overset" && node.baseExpr) {
4131
+ const accent = accentChainForExport(node.overExpr);
4132
+ if (!accent.ok) {
4133
+ return accent;
4134
+ }
4135
+ const baseExpr = editorChainToAstChain(node.baseExpr);
4136
+ if (!baseExpr.ok) {
4137
+ return baseExpr;
4138
+ }
4139
+ astNode = nodeFromAccentBase("\\overset", accent.chain, baseExpr.chain);
4140
+ } else if (node.kind === "underset" && node.baseExpr) {
4141
+ const accent = accentChainForExport(node.underExpr);
4142
+ if (!accent.ok) {
4143
+ return accent;
4144
+ }
4145
+ const baseExpr = editorChainToAstChain(node.baseExpr);
4146
+ if (!baseExpr.ok) {
4147
+ return baseExpr;
4148
+ }
4149
+ astNode = nodeFromAccentBase("\\underset", accent.chain, baseExpr.chain);
4150
+ } else if (node.kind === "accent" && node.baseExpr) {
4151
+ const tex = accentCommandSpec(node.expr)?.englishTex;
4152
+ if (!tex) {
4153
+ 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}` };
4154
+ }
4155
+ const baseExpr = editorChainToAstChain(node.baseExpr);
4156
+ if (!baseExpr.ok) {
4157
+ return baseExpr;
4158
+ }
4159
+ astNode = new CommandNode(tex, [], [baseExpr.chain]);
3709
4160
  } else if (node.kind === "atomicCommand") {
3710
4161
  const tex = atomicCommandSpec(node.expr)?.englishTex;
3711
4162
  if (!tex) {