@drghaliasri/butex 3.2.2 → 4.0.1

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.
@@ -97,6 +97,7 @@ type MathToken2 = {
97
97
  opening: string;
98
98
  closing: string;
99
99
  source: string;
100
+ sourceSide?: Document2ParseMode;
100
101
  math: MathNode | null;
101
102
  editable: boolean;
102
103
  reason?: string;
@@ -302,9 +303,9 @@ declare function cloneDocument2Node(document: Document2Node): Document2Node;
302
303
  declare function insertDocument2BlockAfter(document: Document2Node, afterBlockId: string | null | undefined, block: Document2Block): Document2Node;
303
304
  declare function moveDocument2BlockById(document: Document2Node, blockId: string, direction: -1 | 1): Document2Node;
304
305
  declare function removeMathTokenById(document: Document2Node, tokenId: string): Document2Node;
305
- declare function insertMathTokenAtCaret(document: Document2Node, fieldId: string, textTokenId: string | null, caretOffset: number, session: EditorSession, opening?: string, closing?: string): Document2Node;
306
- declare function insertMathToken(document: Document2Node, fieldId: string, insertIndex: number, session: EditorSession, opening?: string, closing?: string): Document2Node;
307
- declare function replaceMathTokenFromSession(document: Document2Node, tokenId: string, session: EditorSession, opening?: string, closing?: string): Document2Node;
306
+ declare function insertMathTokenAtCaret(document: Document2Node, fieldId: string, textTokenId: string | null, caretOffset: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
307
+ declare function insertMathToken(document: Document2Node, fieldId: string, insertIndex: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
308
+ declare function replaceMathTokenFromSession(document: Document2Node, tokenId: string, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
308
309
  declare function addDocument2TextBlock(document: Document2Node, command?: '\\section' | '\\subsection' | '\\subsubsection' | '\\paragraph', afterBlockId?: string | null): Document2Node;
309
310
  declare function removeDocument2BlockById(document: Document2Node, blockId: string): Document2Node;
310
311
  declare function addDocument2ListBlock(document: Document2Node, ordered: boolean, afterBlockId?: string | null): Document2Node;
@@ -343,11 +344,16 @@ type Document2MathBridgeResult = {
343
344
  editable: false;
344
345
  reason: string;
345
346
  };
347
+ declare function createEmptyEquationSession(side?: EditorSide): EditorSession;
346
348
  declare function createEmptyArabicEquationSession(): EditorSession;
349
+ declare function mathTokenToEditorSession(math: MathNode | null, side?: EditorSide): Document2MathBridgeResult;
347
350
  declare function mathTokenToArabicEditorSession(math: MathNode | null): Document2MathBridgeResult;
351
+ declare function mathSourceFromSession(session: EditorSession, side: EditorSide, opening?: string, closing?: string): string;
348
352
  declare function mathSourceFromArabicSession(session: EditorSession, opening?: string, closing?: string): string;
353
+ declare function mathNodeFromSession(session: EditorSession, opening?: string, closing?: string): MathNode;
349
354
  declare function mathNodeFromArabicSession(session: EditorSession, opening?: string, closing?: string): MathNode;
355
+ declare function mathTokenSourceForSide(token: MathToken2, side: EditorSide): string;
350
356
 
351
- declare function document2Preview(document: Document2Node, output?: Document2MathOutput): Document2Preview;
357
+ declare function document2Preview(document: Document2Node, output?: Document2MathOutput, equationSide?: EditorSide): Document2Preview;
352
358
 
353
- export { DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2HistoryStacks, type Document2Json, type Document2MathOutput, type Document2Node, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type TableBlock2, type TextBlock2, type TextToken2, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2TableBlock, addDocument2TextBlock, cloneDocument2Node, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createInlineField2, detectMathSpans2, document2HistoryCanRedo, document2HistoryCanUndo, document2Latex, document2Preview, findFirstInlineField, fromDocumentJson2, inlineFieldLatex, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, mathNodeFromArabicSession, mathSourceFromArabicSession, mathTokenToArabicEditorSession, moveDocument2BlockById, pushDocument2Snapshot, removeDocument2BlockById, removeDocument2ListItem, removeMathTokenById, replaceMathTokenFromSession, restoreDocument2Redo, restoreDocument2Undo, updateDocument2ImageValue, updateTextToken };
359
+ export { DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2HistoryStacks, type Document2Json, type Document2MathOutput, type Document2Node, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type TableBlock2, type TextBlock2, type TextToken2, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2TableBlock, addDocument2TextBlock, cloneDocument2Node, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createEmptyEquationSession, createInlineField2, detectMathSpans2, document2HistoryCanRedo, document2HistoryCanUndo, document2Latex, document2Preview, findFirstInlineField, fromDocumentJson2, inlineFieldLatex, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, mathNodeFromArabicSession, mathNodeFromSession, mathSourceFromArabicSession, mathSourceFromSession, mathTokenSourceForSide, mathTokenToArabicEditorSession, mathTokenToEditorSession, moveDocument2BlockById, pushDocument2Snapshot, removeDocument2BlockById, removeDocument2ListItem, removeMathTokenById, replaceMathTokenFromSession, restoreDocument2Redo, restoreDocument2Undo, updateDocument2ImageValue, updateTextToken };
@@ -97,6 +97,7 @@ type MathToken2 = {
97
97
  opening: string;
98
98
  closing: string;
99
99
  source: string;
100
+ sourceSide?: Document2ParseMode;
100
101
  math: MathNode | null;
101
102
  editable: boolean;
102
103
  reason?: string;
@@ -302,9 +303,9 @@ declare function cloneDocument2Node(document: Document2Node): Document2Node;
302
303
  declare function insertDocument2BlockAfter(document: Document2Node, afterBlockId: string | null | undefined, block: Document2Block): Document2Node;
303
304
  declare function moveDocument2BlockById(document: Document2Node, blockId: string, direction: -1 | 1): Document2Node;
304
305
  declare function removeMathTokenById(document: Document2Node, tokenId: string): Document2Node;
305
- declare function insertMathTokenAtCaret(document: Document2Node, fieldId: string, textTokenId: string | null, caretOffset: number, session: EditorSession, opening?: string, closing?: string): Document2Node;
306
- declare function insertMathToken(document: Document2Node, fieldId: string, insertIndex: number, session: EditorSession, opening?: string, closing?: string): Document2Node;
307
- declare function replaceMathTokenFromSession(document: Document2Node, tokenId: string, session: EditorSession, opening?: string, closing?: string): Document2Node;
306
+ declare function insertMathTokenAtCaret(document: Document2Node, fieldId: string, textTokenId: string | null, caretOffset: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
307
+ declare function insertMathToken(document: Document2Node, fieldId: string, insertIndex: number, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
308
+ declare function replaceMathTokenFromSession(document: Document2Node, tokenId: string, session: EditorSession, opening?: string, closing?: string, side?: EditorSide): Document2Node;
308
309
  declare function addDocument2TextBlock(document: Document2Node, command?: '\\section' | '\\subsection' | '\\subsubsection' | '\\paragraph', afterBlockId?: string | null): Document2Node;
309
310
  declare function removeDocument2BlockById(document: Document2Node, blockId: string): Document2Node;
310
311
  declare function addDocument2ListBlock(document: Document2Node, ordered: boolean, afterBlockId?: string | null): Document2Node;
@@ -343,11 +344,16 @@ type Document2MathBridgeResult = {
343
344
  editable: false;
344
345
  reason: string;
345
346
  };
347
+ declare function createEmptyEquationSession(side?: EditorSide): EditorSession;
346
348
  declare function createEmptyArabicEquationSession(): EditorSession;
349
+ declare function mathTokenToEditorSession(math: MathNode | null, side?: EditorSide): Document2MathBridgeResult;
347
350
  declare function mathTokenToArabicEditorSession(math: MathNode | null): Document2MathBridgeResult;
351
+ declare function mathSourceFromSession(session: EditorSession, side: EditorSide, opening?: string, closing?: string): string;
348
352
  declare function mathSourceFromArabicSession(session: EditorSession, opening?: string, closing?: string): string;
353
+ declare function mathNodeFromSession(session: EditorSession, opening?: string, closing?: string): MathNode;
349
354
  declare function mathNodeFromArabicSession(session: EditorSession, opening?: string, closing?: string): MathNode;
355
+ declare function mathTokenSourceForSide(token: MathToken2, side: EditorSide): string;
350
356
 
351
- declare function document2Preview(document: Document2Node, output?: Document2MathOutput): Document2Preview;
357
+ declare function document2Preview(document: Document2Node, output?: Document2MathOutput, equationSide?: EditorSide): Document2Preview;
352
358
 
353
- export { DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2HistoryStacks, type Document2Json, type Document2MathOutput, type Document2Node, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type TableBlock2, type TextBlock2, type TextToken2, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2TableBlock, addDocument2TextBlock, cloneDocument2Node, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createInlineField2, detectMathSpans2, document2HistoryCanRedo, document2HistoryCanUndo, document2Latex, document2Preview, findFirstInlineField, fromDocumentJson2, inlineFieldLatex, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, mathNodeFromArabicSession, mathSourceFromArabicSession, mathTokenToArabicEditorSession, moveDocument2BlockById, pushDocument2Snapshot, removeDocument2BlockById, removeDocument2ListItem, removeMathTokenById, replaceMathTokenFromSession, restoreDocument2Redo, restoreDocument2Undo, updateDocument2ImageValue, updateTextToken };
359
+ export { DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH, type Document2Block, type Document2BlockJson, type Document2Diagnostic, type Document2HistoryStacks, type Document2Json, type Document2MathOutput, type Document2Node, type ImageBlock2, type ImportDocument2Options, type InlineField2, type InlineToken2, type ListBlock2, type MathIsland2, type MathObject2Json, type MathToken2, type PreviewBlock2, type PreviewInline2, type RawBlock2, type TableBlock2, type TextBlock2, type TextToken2, addDocument2ImageBlock, addDocument2ListBlock, addDocument2ListItem, addDocument2TableBlock, addDocument2TextBlock, cloneDocument2Node, createDocument2History, createEmptyArabicEquationSession, createEmptyDocument2, createEmptyEquationSession, createInlineField2, detectMathSpans2, document2HistoryCanRedo, document2HistoryCanUndo, document2Latex, document2Preview, findFirstInlineField, fromDocumentJson2, inlineFieldLatex, insertDocument2BlockAfter, insertMathToken, insertMathTokenAtCaret, mathNodeFromArabicSession, mathNodeFromSession, mathSourceFromArabicSession, mathSourceFromSession, mathTokenSourceForSide, mathTokenToArabicEditorSession, mathTokenToEditorSession, moveDocument2BlockById, pushDocument2Snapshot, removeDocument2BlockById, removeDocument2ListItem, removeMathTokenById, replaceMathTokenFromSession, restoreDocument2Redo, restoreDocument2Undo, updateDocument2ImageValue, updateTextToken };
package/dist/document2.js CHANGED
@@ -30,6 +30,7 @@ __export(document2_exports, {
30
30
  createDocument2History: () => createDocument2History,
31
31
  createEmptyArabicEquationSession: () => createEmptyArabicEquationSession,
32
32
  createEmptyDocument2: () => createEmptyDocument2,
33
+ createEmptyEquationSession: () => createEmptyEquationSession,
33
34
  createInlineField2: () => createInlineField2,
34
35
  detectMathSpans2: () => detectMathSpans2,
35
36
  document2HistoryCanRedo: () => document2HistoryCanRedo,
@@ -43,8 +44,12 @@ __export(document2_exports, {
43
44
  insertMathToken: () => insertMathToken,
44
45
  insertMathTokenAtCaret: () => insertMathTokenAtCaret,
45
46
  mathNodeFromArabicSession: () => mathNodeFromArabicSession,
47
+ mathNodeFromSession: () => mathNodeFromSession,
46
48
  mathSourceFromArabicSession: () => mathSourceFromArabicSession,
49
+ mathSourceFromSession: () => mathSourceFromSession,
50
+ mathTokenSourceForSide: () => mathTokenSourceForSide,
47
51
  mathTokenToArabicEditorSession: () => mathTokenToArabicEditorSession,
52
+ mathTokenToEditorSession: () => mathTokenToEditorSession,
48
53
  moveDocument2BlockById: () => moveDocument2BlockById,
49
54
  pushDocument2Snapshot: () => pushDocument2Snapshot,
50
55
  removeDocument2BlockById: () => removeDocument2BlockById,
@@ -591,6 +596,7 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
591
596
  opening: span.opening,
592
597
  closing: span.closing,
593
598
  source: span.source,
599
+ sourceSide: mode,
594
600
  math: fromMathObjectJson(mathJson, mode),
595
601
  editable: true,
596
602
  sourceOwner: "imported-structured"
@@ -1193,6 +1199,24 @@ var ATOMIC_OPERATOR_COMMANDS = {
1193
1199
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1194
1200
  svg_path: null
1195
1201
  },
1202
+ coloneqq: {
1203
+ id: "coloneqq",
1204
+ category: "operators1",
1205
+ Tex: "\\coloneqq",
1206
+ mirror: true,
1207
+ Label: "\u2254",
1208
+ title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
1209
+ svg_path: null
1210
+ },
1211
+ eqqcolon: {
1212
+ id: "eqqcolon",
1213
+ category: "operators1",
1214
+ Tex: "\\eqqcolon",
1215
+ mirror: true,
1216
+ Label: "\u2255",
1217
+ title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
1218
+ svg_path: null
1219
+ },
1196
1220
  ///// Operators 2
1197
1221
  propto: {
1198
1222
  id: "propto",
@@ -1359,6 +1383,60 @@ var ATOMIC_OPERATOR_COMMANDS = {
1359
1383
  title: "\u064A\u0643\u0627\u0641\u0626",
1360
1384
  svg_path: null
1361
1385
  },
1386
+ implies: {
1387
+ id: "implies",
1388
+ category: "operators3",
1389
+ Tex: "\\implies",
1390
+ mirror: true,
1391
+ Label: "\u21D2",
1392
+ title: "\u064A\u0633\u062A\u0644\u0632\u0645",
1393
+ svg_path: null
1394
+ },
1395
+ impliedby: {
1396
+ id: "impliedby",
1397
+ category: "operators3",
1398
+ Tex: "\\impliedby",
1399
+ mirror: true,
1400
+ Label: "\u21D0",
1401
+ title: "\u0645\u0633\u062A\u0644\u0632\u0645 \u0645\u0646",
1402
+ svg_path: null
1403
+ },
1404
+ iff: {
1405
+ id: "iff",
1406
+ category: "operators3",
1407
+ Tex: "\\iff",
1408
+ mirror: false,
1409
+ Label: "\u21D4",
1410
+ title: "\u0625\u0630\u0627 \u0648\u0641\u0642\u0637 \u0625\u0630\u0627",
1411
+ svg_path: null
1412
+ },
1413
+ Longrightarrow: {
1414
+ id: "Longrightarrow",
1415
+ category: "operators3",
1416
+ Tex: "\\Longrightarrow",
1417
+ mirror: true,
1418
+ Label: "\u27F9",
1419
+ title: "\u0633\u0647\u0645 \u0645\u0632\u062F\u0648\u062C \u0637\u0648\u064A\u0644 \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646",
1420
+ svg_path: null
1421
+ },
1422
+ Longleftarrow: {
1423
+ id: "Longleftarrow",
1424
+ category: "operators3",
1425
+ Tex: "\\Longleftarrow",
1426
+ mirror: true,
1427
+ Label: "\u27F8",
1428
+ title: "\u0633\u0647\u0645 \u0645\u0632\u062F\u0648\u062C \u0637\u0648\u064A\u0644 \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631",
1429
+ svg_path: null
1430
+ },
1431
+ to: {
1432
+ id: "to",
1433
+ category: "operators3",
1434
+ Tex: "\\to",
1435
+ mirror: true,
1436
+ Label: "\u2192",
1437
+ title: "\u064A\u0624\u0648\u0644 \u0625\u0644\u0649",
1438
+ svg_path: null
1439
+ },
1362
1440
  rightleftharpoons: {
1363
1441
  id: "rightleftharpoons",
1364
1442
  category: "operators3",
@@ -1699,6 +1777,23 @@ function formatDigits(value, digitForm = "western") {
1699
1777
  function selectedDigitForm(options) {
1700
1778
  return options?.digitForm ?? "western";
1701
1779
  }
1780
+ function latinScripts(node, options) {
1781
+ let scripts = "";
1782
+ if (node.superscript) {
1783
+ scripts += `^{${renderChainEnglish(node.superscript, options)}}`;
1784
+ }
1785
+ if (node.subscript) {
1786
+ scripts += `_{${renderChainEnglish(node.subscript, options)}}`;
1787
+ }
1788
+ return scripts;
1789
+ }
1790
+ function optionalRootIndexEnglish(node, options) {
1791
+ if (!node.rootIndex) {
1792
+ return "";
1793
+ }
1794
+ const rendered = renderChainEnglish(node.rootIndex, options);
1795
+ return rendered === "" ? "" : `[${rendered}]`;
1796
+ }
1702
1797
  function optionalRootIndexArabic(node, options) {
1703
1798
  if (!node.rootIndex) {
1704
1799
  return "";
@@ -1714,6 +1809,21 @@ function arabicScripts(node, content, options) {
1714
1809
  }
1715
1810
  return content;
1716
1811
  }
1812
+ function renderMatrixRowsEnglish(node, options) {
1813
+ if (!node.matrixRows) {
1814
+ return "";
1815
+ }
1816
+ const envName = node.envName ?? node.matrixStyle;
1817
+ if (!envName) {
1818
+ return "";
1819
+ }
1820
+ const rows = node.matrixRows.map((row) => row.map((cell) => renderChainEnglish(cell, options)).join(" & "));
1821
+ if (envName === "array") {
1822
+ const spec = (node.columnAlignments ?? []).slice(0, node.matrixRows[0]?.length ?? 0).join("");
1823
+ return `\\begin{array}{${spec || "c"}}${rows.join(" \\\\\n")}\\end{array}`;
1824
+ }
1825
+ return `\\begin{${envName}}${rows.join(" \\\\\n")}\\end{${envName}}`;
1826
+ }
1717
1827
  function reverseAlignmentForArabic(alignment) {
1718
1828
  if (alignment === "l") {
1719
1829
  return "r";
@@ -1757,6 +1867,34 @@ function renderCharContent(node, options) {
1757
1867
  }
1758
1868
  return expr;
1759
1869
  }
1870
+ function renderNodeEnglish(node, options) {
1871
+ if (node.kind === "delimiter" && node.innerExpr) {
1872
+ return `${node.leftDelimExpr}${renderChainEnglish(node.innerExpr, options)}${node.rightDelimExpr}${latinScripts(node, options)}`;
1873
+ }
1874
+ if (node.kind === "frac" && node.numerator && node.denominator) {
1875
+ const body = `\\frac{${renderChainEnglish(node.numerator, options)}}{${renderChainEnglish(node.denominator, options)}}`;
1876
+ return `${body}${latinScripts(node, options)}`;
1877
+ }
1878
+ if (node.kind === "sqrt" && node.radicand) {
1879
+ const body = `\\sqrt${optionalRootIndexEnglish(node, options)}{${renderChainEnglish(node.radicand, options)}}`;
1880
+ return `${body}${latinScripts(node, options)}`;
1881
+ }
1882
+ if (node.kind === "env") {
1883
+ return `${renderMatrixRowsEnglish(node, options)}${latinScripts(node, options)}`;
1884
+ }
1885
+ if (node.kind === "atomicCommand") {
1886
+ const body = atomicCommandSpec(node.expr)?.englishTex ?? node.expr;
1887
+ return `${body}${latinScripts(node, options)}`;
1888
+ }
1889
+ if (node.kind === "atomicOperatorCommand") {
1890
+ const body = atomicOperatorCommandSpec(node.expr)?.Tex ?? node.expr;
1891
+ return `${body}${latinScripts(node, options)}`;
1892
+ }
1893
+ if (node.kind === "char") {
1894
+ return `${renderCharContent(node, options)}${latinScripts(node, options)}`;
1895
+ }
1896
+ return `${formatDigits(node.expr, selectedDigitForm(options))}${latinScripts(node, options)}`;
1897
+ }
1760
1898
  function renderNodeArabic(node, options) {
1761
1899
  if (node.kind === "delimiter" && node.innerExpr) {
1762
1900
  const content = `${node.leftDelimExpr}${renderChainArabic(node.innerExpr, options)}${node.rightDelimExpr}`;
@@ -1791,9 +1929,15 @@ function renderNodeArabic(node, options) {
1791
1929
  }
1792
1930
  return arabicScripts(node, formatDigits(node.expr, selectedDigitForm(options)), options);
1793
1931
  }
1932
+ function renderChainEnglish(chain, options) {
1933
+ return chain.nodes.map((node) => renderNodeEnglish(node, options)).join(" ");
1934
+ }
1794
1935
  function renderChainArabic(chain, options) {
1795
1936
  return chain.nodes.slice().reverse().map((node) => renderNodeArabic(node, options)).join(" ");
1796
1937
  }
1938
+ function renderEnglishLatexFromSession(session) {
1939
+ return renderChainEnglish(session.englishTree, { digitForm: session.currentDigitForm ?? "western" });
1940
+ }
1797
1941
  function renderArabicLatexFromSession(session) {
1798
1942
  return renderChainArabic(session.arabicTree, { digitForm: session.currentDigitForm ?? "western" });
1799
1943
  }
@@ -2724,15 +2868,18 @@ function mathNodeFromEditorSession(session, mathMode = "$", closing = "$") {
2724
2868
  }
2725
2869
 
2726
2870
  // src/document2/mathBridge.ts
2727
- function createEmptyArabicEquationSession() {
2871
+ function createEmptyEquationSession(side = "arabic") {
2728
2872
  const english = createEditorChain();
2729
2873
  const arabic = createEditorChain();
2730
2874
  arabic.id = english.id;
2731
- const session = createEditorSession(english, arabic, "arabic");
2875
+ const session = createEditorSession(english, arabic, side);
2732
2876
  session.sync = buildInitialSyncMap(session.englishTree, session.arabicTree);
2733
2877
  return session;
2734
2878
  }
2735
- function mathTokenToArabicEditorSession(math) {
2879
+ function createEmptyArabicEquationSession() {
2880
+ return createEmptyEquationSession("arabic");
2881
+ }
2882
+ function mathTokenToEditorSession(math, side = "arabic") {
2736
2883
  if (!math) {
2737
2884
  return { editable: false, reason: "\u0647\u0630\u0647 \u0627\u0644\u0645\u0639\u0627\u062F\u0644\u0629 \u0645\u062D\u0641\u0648\u0638\u0629 \u0643\u0646\u0635 \u062E\u0627\u0645 \u0641\u0642\u0637 \u062D\u0627\u0644\u064A\u0627" };
2738
2885
  }
@@ -2740,12 +2887,15 @@ function mathTokenToArabicEditorSession(math) {
2740
2887
  if (!result.editable) {
2741
2888
  return result;
2742
2889
  }
2743
- result.session.activeSide = "arabic";
2890
+ result.session.activeSide = side;
2744
2891
  result.session.sync = buildInitialSyncMap(result.session.englishTree, result.session.arabicTree);
2745
2892
  return result;
2746
2893
  }
2747
- function mathSourceFromArabicSession(session, opening = "$", closing = "$") {
2748
- const inner = renderArabicLatexFromSession(session);
2894
+ function mathTokenToArabicEditorSession(math) {
2895
+ return mathTokenToEditorSession(math, "arabic");
2896
+ }
2897
+ function mathSourceFromSession(session, side, opening = "$", closing = "$") {
2898
+ const inner = side === "english" ? renderEnglishLatexFromSession(session) : renderArabicLatexFromSession(session);
2749
2899
  if (opening === "$" || opening === "\\(") {
2750
2900
  return opening + inner + closing;
2751
2901
  }
@@ -2758,13 +2908,32 @@ ${closing}`;
2758
2908
  ${inner}
2759
2909
  ${closing}`;
2760
2910
  }
2761
- function mathNodeFromArabicSession(session, opening = "$", closing = "$") {
2911
+ function mathSourceFromArabicSession(session, opening = "$", closing = "$") {
2912
+ return mathSourceFromSession(session, "arabic", opening, closing);
2913
+ }
2914
+ function mathNodeFromSession(session, opening = "$", closing = "$") {
2762
2915
  const converted = mathNodeFromEditorSession(session, opening, closing);
2763
2916
  if (converted.ok) {
2764
2917
  return converted.math;
2765
2918
  }
2766
2919
  return { nodeType: "MathObject", mathMode: opening, lines: [], closing };
2767
2920
  }
2921
+ function mathNodeFromArabicSession(session, opening = "$", closing = "$") {
2922
+ return mathNodeFromSession(session, opening, closing);
2923
+ }
2924
+ function mathTokenSourceForSide(token, side) {
2925
+ if (!token.math || token.sourceOwner === "raw") {
2926
+ return token.source;
2927
+ }
2928
+ if (token.sourceSide === side) {
2929
+ return token.source;
2930
+ }
2931
+ const result = mathTokenToEditorSession(token.math, side);
2932
+ if (!result.editable) {
2933
+ return token.source;
2934
+ }
2935
+ return mathSourceFromSession(result.session, side, token.opening, token.closing);
2936
+ }
2768
2937
 
2769
2938
  // src/document2/commands.ts
2770
2939
  function cloneToken(token) {
@@ -2849,15 +3018,16 @@ function updateTextToken(document2, fieldId, tokenId, text) {
2849
3018
  });
2850
3019
  return next;
2851
3020
  }
2852
- function mathTokenFromSession(session, opening = "$", closing = "$") {
3021
+ function mathTokenFromSession(session, opening = "$", closing = "$", side = "arabic") {
2853
3022
  return {
2854
3023
  id: document2Id("math"),
2855
3024
  kind: "math",
2856
3025
  display: opening === "$$" || opening === "\\[" || opening.startsWith("\\begin{"),
2857
3026
  opening,
2858
3027
  closing,
2859
- source: mathSourceFromArabicSession(session, opening, closing),
2860
- math: mathNodeFromArabicSession(session, opening, closing),
3028
+ source: mathSourceFromSession(session, side, opening, closing),
3029
+ sourceSide: side,
3030
+ math: mathNodeFromSession(session, opening, closing),
2861
3031
  editable: true,
2862
3032
  sourceOwner: "editor"
2863
3033
  };
@@ -2943,9 +3113,9 @@ function splitTextTokenAt(token, offset) {
2943
3113
  { id: document2Id("text"), kind: "text", text: token.text.slice(safeOffset) }
2944
3114
  ];
2945
3115
  }
2946
- function insertMathTokenAtCaret(document2, fieldId, textTokenId, caretOffset, session, opening = "$", closing = "$") {
3116
+ function insertMathTokenAtCaret(document2, fieldId, textTokenId, caretOffset, session, opening = "$", closing = "$", side = "arabic") {
2947
3117
  const next = cloneDocument(document2);
2948
- const mathToken = mathTokenFromSession(session, opening, closing);
3118
+ const mathToken = mathTokenFromSession(session, opening, closing, side);
2949
3119
  visitFields(next.blocks, (field) => {
2950
3120
  if (field.id !== fieldId) {
2951
3121
  return false;
@@ -2970,9 +3140,9 @@ function insertMathTokenAtCaret(document2, fieldId, textTokenId, caretOffset, se
2970
3140
  });
2971
3141
  return next;
2972
3142
  }
2973
- function insertMathToken(document2, fieldId, insertIndex, session, opening = "$", closing = "$") {
3143
+ function insertMathToken(document2, fieldId, insertIndex, session, opening = "$", closing = "$", side = "arabic") {
2974
3144
  const next = cloneDocument(document2);
2975
- const mathToken = mathTokenFromSession(session, opening, closing);
3145
+ const mathToken = mathTokenFromSession(session, opening, closing, side);
2976
3146
  visitFields(next.blocks, (field) => {
2977
3147
  if (field.id !== fieldId) {
2978
3148
  return false;
@@ -2990,7 +3160,7 @@ function insertMathToken(document2, fieldId, insertIndex, session, opening = "$"
2990
3160
  });
2991
3161
  return next;
2992
3162
  }
2993
- function replaceMathTokenFromSession(document2, tokenId, session, opening, closing) {
3163
+ function replaceMathTokenFromSession(document2, tokenId, session, opening, closing, side = "arabic") {
2994
3164
  const next = cloneDocument(document2);
2995
3165
  visitFields(next.blocks, (field) => {
2996
3166
  const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === "math");
@@ -3000,7 +3170,7 @@ function replaceMathTokenFromSession(document2, tokenId, session, opening, closi
3000
3170
  const current = field.tokens[index];
3001
3171
  const open = opening ?? current.opening;
3002
3172
  const close = closing ?? current.closing;
3003
- field.tokens[index] = mathTokenFromSession(session, open, close);
3173
+ field.tokens[index] = mathTokenFromSession(session, open, close, side);
3004
3174
  field.tokens[index].id = current.id;
3005
3175
  return true;
3006
3176
  });
@@ -3212,23 +3382,20 @@ function document2HistoryCanRedo(stacks) {
3212
3382
  }
3213
3383
 
3214
3384
  // src/document2/previewModel.ts
3215
- function mathTex(token) {
3385
+ function mathTex(token, equationSide) {
3216
3386
  if (token.kind === "text") {
3217
3387
  return token.text;
3218
3388
  }
3219
- if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
3220
- return token.source;
3221
- }
3222
- return renderMathNodeLatex(token.math);
3389
+ return mathTokenSourceForSide(token, equationSide);
3223
3390
  }
3224
- function previewInlines(field, islands, output) {
3391
+ function previewInlines(field, islands, output, equationSide) {
3225
3392
  return field.tokens.map((token) => {
3226
3393
  if (token.kind === "text") {
3227
3394
  return { kind: "text", text: token.text };
3228
3395
  }
3229
3396
  const island = {
3230
3397
  id: token.id,
3231
- tex: mathTex(token),
3398
+ tex: mathTex(token, equationSide),
3232
3399
  display: token.display,
3233
3400
  output,
3234
3401
  editable: token.editable
@@ -3237,21 +3404,21 @@ function previewInlines(field, islands, output) {
3237
3404
  return { kind: "math", ...island };
3238
3405
  });
3239
3406
  }
3240
- function textBlockPreview(block, islands, output) {
3407
+ function textBlockPreview(block, islands, output, equationSide) {
3241
3408
  if (block.command === "\\section") {
3242
- return { kind: "heading", id: block.id, level: 1, inlines: previewInlines(block.field, islands, output) };
3409
+ return { kind: "heading", id: block.id, level: 1, inlines: previewInlines(block.field, islands, output, equationSide) };
3243
3410
  }
3244
3411
  if (block.command === "\\subsection") {
3245
- return { kind: "heading", id: block.id, level: 2, inlines: previewInlines(block.field, islands, output) };
3412
+ return { kind: "heading", id: block.id, level: 2, inlines: previewInlines(block.field, islands, output, equationSide) };
3246
3413
  }
3247
3414
  if (block.command === "\\subsubsection") {
3248
- return { kind: "heading", id: block.id, level: 3, inlines: previewInlines(block.field, islands, output) };
3415
+ return { kind: "heading", id: block.id, level: 3, inlines: previewInlines(block.field, islands, output, equationSide) };
3249
3416
  }
3250
- return { kind: "paragraph", id: block.id, inlines: previewInlines(block.field, islands, output) };
3417
+ return { kind: "paragraph", id: block.id, inlines: previewInlines(block.field, islands, output, equationSide) };
3251
3418
  }
3252
- function blockPreview(block, islands, output) {
3419
+ function blockPreview(block, islands, output, equationSide) {
3253
3420
  if (block.kind === "textBlock") {
3254
- return textBlockPreview(block, islands, output);
3421
+ return textBlockPreview(block, islands, output, equationSide);
3255
3422
  }
3256
3423
  if (block.kind === "list") {
3257
3424
  return {
@@ -3260,23 +3427,23 @@ function blockPreview(block, islands, output) {
3260
3427
  ordered: block.command === "\\begin{enumerate}",
3261
3428
  items: block.items.map((item) => ({
3262
3429
  id: item.id,
3263
- inlines: previewInlines(item.field, islands, output),
3264
- blocks: item.blocks.map((child) => blockPreview(child, islands, output))
3430
+ inlines: previewInlines(item.field, islands, output, equationSide),
3431
+ blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide))
3265
3432
  }))
3266
3433
  };
3267
3434
  }
3268
3435
  if (block.kind === "table") {
3269
- return { kind: "table", id: block.id, rows: block.rows.map((row) => row.map((cell) => previewInlines(cell, islands, output))) };
3436
+ return { kind: "table", id: block.id, rows: block.rows.map((row) => row.map((cell) => previewInlines(cell, islands, output, equationSide))) };
3270
3437
  }
3271
3438
  if (block.kind === "image") {
3272
3439
  return { kind: "image", id: block.id, src: block.value, options: block.options };
3273
3440
  }
3274
3441
  return { kind: "omit", id: block.id };
3275
3442
  }
3276
- function document2Preview(document2, output = "svg") {
3443
+ function document2Preview(document2, output = "svg", equationSide = "arabic") {
3277
3444
  const mathIslands = [];
3278
3445
  return {
3279
- blocks: document2.blocks.map((block) => blockPreview(block, mathIslands, output)),
3446
+ blocks: document2.blocks.map((block) => blockPreview(block, mathIslands, output, equationSide)),
3280
3447
  mathIslands
3281
3448
  };
3282
3449
  }
@@ -3292,6 +3459,7 @@ function document2Preview(document2, output = "svg") {
3292
3459
  createDocument2History,
3293
3460
  createEmptyArabicEquationSession,
3294
3461
  createEmptyDocument2,
3462
+ createEmptyEquationSession,
3295
3463
  createInlineField2,
3296
3464
  detectMathSpans2,
3297
3465
  document2HistoryCanRedo,
@@ -3305,8 +3473,12 @@ function document2Preview(document2, output = "svg") {
3305
3473
  insertMathToken,
3306
3474
  insertMathTokenAtCaret,
3307
3475
  mathNodeFromArabicSession,
3476
+ mathNodeFromSession,
3308
3477
  mathSourceFromArabicSession,
3478
+ mathSourceFromSession,
3479
+ mathTokenSourceForSide,
3309
3480
  mathTokenToArabicEditorSession,
3481
+ mathTokenToEditorSession,
3310
3482
  moveDocument2BlockById,
3311
3483
  pushDocument2Snapshot,
3312
3484
  removeDocument2BlockById,