@drghaliasri/butex 4.0.1 → 4.2.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.
@@ -932,6 +932,16 @@ var ATOMIC_COMMANDS = {
932
932
  arabicLabel: "\u0645\u062D\u062F\u062F",
933
933
  title: "\u0645\u062D\u062F\u062F"
934
934
  },
935
+ ////////////////////// Derivatives ////////////////////////////////
936
+ ad: {
937
+ id: "ad",
938
+ category: "derivative",
939
+ englishTex: "\\mathrm{d}",
940
+ englishLabel: "d",
941
+ arabicTex: "\\ad",
942
+ arabicLabel: "\u0621",
943
+ title: "\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0627\u0634\u062A\u0642\u0627\u0642"
944
+ },
935
945
  ////////////////////// Groups /////////////////////////////////
936
946
  N: {
937
947
  id: "N",
@@ -1680,6 +1690,16 @@ function createEditorSession(englishTree, arabicTree, activeSide = "arabic") {
1680
1690
  };
1681
1691
  }
1682
1692
 
1693
+ // src/editor/divideOperator.ts
1694
+ var DIVIDE_OPERATOR_EN = "/";
1695
+ var DIVIDE_OPERATOR_AR = "\\";
1696
+ function isDivideOperatorExpr(expr) {
1697
+ return expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR;
1698
+ }
1699
+ function renderDivideOperatorLatex(side) {
1700
+ return side === "arabic" ? "\\backslash" : DIVIDE_OPERATOR_EN;
1701
+ }
1702
+
1683
1703
  // src/editor/digits.ts
1684
1704
  var WESTERN = "0123456789";
1685
1705
  var ARABIC_INDIC = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
@@ -1828,6 +1848,9 @@ function renderNodeEnglish(node, options) {
1828
1848
  if (node.kind === "char") {
1829
1849
  return `${renderCharContent(node, options)}${latinScripts(node, options)}`;
1830
1850
  }
1851
+ if (node.kind === "operator" && isDivideOperatorExpr(node.expr)) {
1852
+ return `${renderDivideOperatorLatex("english")}${latinScripts(node, options)}`;
1853
+ }
1831
1854
  return `${formatDigits(node.expr, selectedDigitForm(options))}${latinScripts(node, options)}`;
1832
1855
  }
1833
1856
  function renderNodeArabic(node, options) {
@@ -1862,6 +1885,9 @@ function renderNodeArabic(node, options) {
1862
1885
  const content = renderCharContent(node, options);
1863
1886
  return arabicScripts(node, (node.characterFont ?? "default") === "default" ? `\\text{${escapeText(expr)}}` : content, options);
1864
1887
  }
1888
+ if (node.kind === "operator" && isDivideOperatorExpr(node.expr)) {
1889
+ return arabicScripts(node, renderDivideOperatorLatex("arabic"), options);
1890
+ }
1865
1891
  return arabicScripts(node, formatDigits(node.expr, selectedDigitForm(options)), options);
1866
1892
  }
1867
1893
  function renderChainEnglish(chain, options) {
@@ -2438,7 +2464,95 @@ ${ATOMIC_COMMAND_CSS}
2438
2464
  ${ATOMIC_OPERATOR_COMMAND_CSS}
2439
2465
  `.trim();
2440
2466
 
2467
+ // src/document/normalizeCharImport.ts
2468
+ var WRAPPER_SPECS = [
2469
+ { prefix: "\\butexdiwanioutline", font: "diwaniOutline" },
2470
+ { prefix: "\\diwanioutlineshaded", font: "diwaniOutline" },
2471
+ { prefix: "\\butexdiwani", font: "diwani" },
2472
+ { prefix: "\\butextakween", font: "takween" },
2473
+ { prefix: "\\diwani", font: "diwani" },
2474
+ { prefix: "\\takween", font: "takween" },
2475
+ { prefix: "\\text" }
2476
+ ];
2477
+ function readBracedArg(source, openBraceIndex) {
2478
+ if (source[openBraceIndex] !== "{") {
2479
+ return null;
2480
+ }
2481
+ let depth = 0;
2482
+ for (let index = openBraceIndex; index < source.length; index += 1) {
2483
+ const char = source[index];
2484
+ if (char === "{") {
2485
+ depth += 1;
2486
+ } else if (char === "}") {
2487
+ depth -= 1;
2488
+ if (depth === 0) {
2489
+ return { inner: source.slice(openBraceIndex + 1, index), end: index + 1 };
2490
+ }
2491
+ }
2492
+ }
2493
+ return null;
2494
+ }
2495
+ function peelWrapper(source) {
2496
+ for (const wrapper of WRAPPER_SPECS) {
2497
+ if (!source.startsWith(wrapper.prefix)) {
2498
+ continue;
2499
+ }
2500
+ const braced = readBracedArg(source, wrapper.prefix.length);
2501
+ if (!braced || braced.end !== source.length) {
2502
+ continue;
2503
+ }
2504
+ return { inner: braced.inner, font: wrapper.font };
2505
+ }
2506
+ return null;
2507
+ }
2508
+ function normalizeCharImportExpr(expr) {
2509
+ const original = expr;
2510
+ let current = expr;
2511
+ let characterFont = "default";
2512
+ let changed = false;
2513
+ while (true) {
2514
+ const peeled = peelWrapper(current);
2515
+ if (!peeled) {
2516
+ break;
2517
+ }
2518
+ current = peeled.inner;
2519
+ if (peeled.font) {
2520
+ characterFont = peeled.font;
2521
+ }
2522
+ changed = true;
2523
+ }
2524
+ if (!changed) {
2525
+ return { expr: original, characterFont: "default" };
2526
+ }
2527
+ if (current.includes("\\")) {
2528
+ return { expr: original, characterFont: "default" };
2529
+ }
2530
+ return { expr: current, characterFont };
2531
+ }
2532
+
2441
2533
  // src/document/mathEditorAdapter.ts
2534
+ var COMMAND_FONT_MAP = {
2535
+ "\\text": "infer",
2536
+ "\\butextakween": "takween",
2537
+ "\\takween": "takween",
2538
+ "\\butexdiwani": "diwani",
2539
+ "\\diwani": "diwani",
2540
+ "\\butexdiwanioutline": "diwaniOutline",
2541
+ "\\diwanioutlineshaded": "diwaniOutline"
2542
+ };
2543
+ var CHAR_FONT_EXPORT_TEX = {
2544
+ takween: "\\butextakween",
2545
+ diwani: "\\butexdiwani",
2546
+ diwaniOutline: "\\butexdiwanioutline"
2547
+ };
2548
+ function charEditorNodeToAstNode(node) {
2549
+ const font = node.characterFont ?? "default";
2550
+ const charNode = new CharNode(node.expr);
2551
+ if (font === "default") {
2552
+ return charNode;
2553
+ }
2554
+ return new CommandNode(CHAR_FONT_EXPORT_TEX[font], [], [new ChainNode([charNode])]);
2555
+ }
2442
2556
  function commandIdForTex(tex) {
2443
2557
  for (const spec of Object.values(ATOMIC_COMMANDS)) {
2444
2558
  const renderTex = spec.arabicRenderTex;
@@ -2550,6 +2664,42 @@ function envToEditorNode(node) {
2550
2664
  const scripts = attachScripts(node, env);
2551
2665
  return scripts ?? { editable: true, node: env };
2552
2666
  }
2667
+ function charFromTextLikeCommand(node) {
2668
+ const commandFont = COMMAND_FONT_MAP[node.name];
2669
+ if (commandFont === void 0) {
2670
+ return null;
2671
+ }
2672
+ if (node.optionalArgs.length > 0 || node.mandatoryArgs.length !== 1) {
2673
+ return null;
2674
+ }
2675
+ const arg = node.mandatoryArgs[0];
2676
+ if (arg.chain.length !== 1) {
2677
+ return null;
2678
+ }
2679
+ const child = arg.chain[0];
2680
+ if (child instanceof CommandNode) {
2681
+ const nested = charFromTextLikeCommand(child);
2682
+ if (!nested?.editable) {
2683
+ return null;
2684
+ }
2685
+ if (commandFont !== "infer") {
2686
+ nested.node.characterFont = commandFont;
2687
+ }
2688
+ const scripts2 = attachScripts(node, nested.node);
2689
+ return scripts2 ?? nested;
2690
+ }
2691
+ if (!(child instanceof CharNode)) {
2692
+ return null;
2693
+ }
2694
+ const normalized = normalizeCharImportExpr(child.expr);
2695
+ const characterFont = commandFont === "infer" ? normalized.characterFont : commandFont;
2696
+ const editorNode = createEditorNode("char", normalized.expr);
2697
+ if (characterFont !== "default") {
2698
+ editorNode.characterFont = characterFont;
2699
+ }
2700
+ const scripts = attachScripts(node, editorNode);
2701
+ return scripts ?? { editable: true, node: editorNode };
2702
+ }
2553
2703
  function commandToEditorNode(node) {
2554
2704
  if (node.name === "\\frac" && node.mandatoryArgs.length >= 2) {
2555
2705
  const frac = createFracNode();
@@ -2607,11 +2757,19 @@ function commandToEditorNode(node) {
2607
2757
  }
2608
2758
  return { editable: true, node: atomicOperator };
2609
2759
  }
2760
+ const textLike = charFromTextLikeCommand(node);
2761
+ if (textLike) {
2762
+ return textLike;
2763
+ }
2610
2764
  return { editable: false, reason: `\u0623\u0645\u0631 \u0631\u064A\u0627\u0636\u064A \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645 \u062D\u0627\u0644\u064A\u0627: ${node.name}` };
2611
2765
  }
2612
2766
  function astNodeToEditorNode(node) {
2613
2767
  if (node instanceof CharNode) {
2614
- const editorNode = createEditorNode("char", node.expr);
2768
+ const normalized = normalizeCharImportExpr(node.expr);
2769
+ const editorNode = createEditorNode("char", normalized.expr);
2770
+ if (normalized.characterFont !== "default") {
2771
+ editorNode.characterFont = normalized.characterFont;
2772
+ }
2615
2773
  const scripts = attachScripts(node, editorNode);
2616
2774
  return scripts ?? { editable: true, node: editorNode };
2617
2775
  }
@@ -2720,7 +2878,7 @@ function editorEnvToAstNode(node) {
2720
2878
  function editorNodeToAstNode(node) {
2721
2879
  let astNode;
2722
2880
  if (node.kind === "char") {
2723
- astNode = new CharNode(node.expr);
2881
+ astNode = charEditorNodeToAstNode(node);
2724
2882
  } else if (node.kind === "number") {
2725
2883
  astNode = new NumberNode(node.expr);
2726
2884
  } else if (node.kind === "operator") {