@drghaliasri/butex 5.3.3 → 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 ////////////////////////////////
@@ -1728,6 +1863,14 @@ function renderMatrixRowsArabic(node, options) {
1728
1863
  }
1729
1864
  return `\\begin{${envName}}${rows.join(" \\\\\n")}\\end{${envName}}`;
1730
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
+ }
1731
1874
  function escapeText(s) {
1732
1875
  return s.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
1733
1876
  }
@@ -1758,6 +1901,19 @@ function renderNodeArabic(node, options) {
1758
1901
  const content = `\\arabsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
1759
1902
  return arabicScripts(node, content, options);
1760
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
+ }
1761
1917
  if (node.kind === "env") {
1762
1918
  return arabicScripts(node, renderMatrixRowsArabic(node, options), options);
1763
1919
  }
@@ -1956,6 +2112,109 @@ var SQRT_CSS = `
1956
2112
  }
1957
2113
  `.trim();
1958
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
+
1959
2218
  // src/editor/display/env.ts
1960
2219
  var MATRIX_ENV_CSS = `
1961
2220
  .matrix-env {
@@ -2343,6 +2602,12 @@ ${FRAC_CSS}
2343
2602
 
2344
2603
  ${SQRT_CSS}
2345
2604
 
2605
+ ${OVERSET_CSS}
2606
+
2607
+ ${UNDERSET_CSS}
2608
+
2609
+ ${ACCENT_CSS}
2610
+
2346
2611
  ${MATRIX_ENV_CSS}
2347
2612
 
2348
2613
  ${ATOMIC_COMMAND_CSS}
@@ -2416,6 +2681,21 @@ function editorEnvToAstNode(node) {
2416
2681
  const scripts = attachAstScripts(node, env);
2417
2682
  return scripts ?? { ok: true, node: env };
2418
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
+ }
2419
2699
  function editorNodeToAstNode(node) {
2420
2700
  let astNode;
2421
2701
  if (node.kind === "char") {
@@ -2454,6 +2734,36 @@ function editorNodeToAstNode(node) {
2454
2734
  optionalArgs.push(rootIndex.chain);
2455
2735
  }
2456
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]);
2457
2767
  } else if (node.kind === "atomicCommand") {
2458
2768
  const tex = atomicCommandSpec(node.expr)?.englishTex;
2459
2769
  if (!tex) {