@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.
- package/README.md +4 -2
- package/dist/document.js +37 -1
- package/dist/document.js.map +1 -1
- package/dist/document.mjs +37 -1
- package/dist/document.mjs.map +1 -1
- package/dist/document2.js +160 -2
- package/dist/document2.js.map +1 -1
- package/dist/document2.mjs +160 -2
- package/dist/document2.mjs.map +1 -1
- package/dist/index.d.mts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.global.js +223 -4
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +223 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +223 -4
- package/dist/index.mjs.map +1 -1
- package/dist/react-document.js +437 -6
- package/dist/react-document.js.map +1 -1
- package/dist/react-document.mjs +437 -6
- package/dist/react-document.mjs.map +1 -1
- package/dist/react-document2.js +437 -6
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +437 -6
- package/dist/react-document2.mjs.map +1 -1
- package/dist/react.d.mts +11 -0
- package/dist/react.d.ts +11 -0
- package/dist/react.js +303 -4
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +303 -4
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react-document.js
CHANGED
|
@@ -946,6 +946,16 @@ var ATOMIC_COMMANDS = {
|
|
|
946
946
|
arabicLabel: "\u0645\u062D\u062F\u062F",
|
|
947
947
|
title: "\u0645\u062D\u062F\u062F"
|
|
948
948
|
},
|
|
949
|
+
////////////////////// Derivatives ////////////////////////////////
|
|
950
|
+
ad: {
|
|
951
|
+
id: "ad",
|
|
952
|
+
category: "derivative",
|
|
953
|
+
englishTex: "\\mathrm{d}",
|
|
954
|
+
englishLabel: "d",
|
|
955
|
+
arabicTex: "\\ad",
|
|
956
|
+
arabicLabel: "\u0621",
|
|
957
|
+
title: "\u0639\u0644\u0627\u0645\u0629 \u0627\u0644\u0627\u0634\u062A\u0642\u0627\u0642"
|
|
958
|
+
},
|
|
949
959
|
////////////////////// Groups /////////////////////////////////
|
|
950
960
|
N: {
|
|
951
961
|
id: "N",
|
|
@@ -1769,6 +1779,22 @@ function createEditorSession(englishTree, arabicTree, activeSide = "arabic") {
|
|
|
1769
1779
|
};
|
|
1770
1780
|
}
|
|
1771
1781
|
|
|
1782
|
+
// src/editor/divideOperator.ts
|
|
1783
|
+
var DIVIDE_OPERATOR_EN = "/";
|
|
1784
|
+
var DIVIDE_OPERATOR_AR = "\\";
|
|
1785
|
+
function isDivideOperatorExpr(expr) {
|
|
1786
|
+
return expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR;
|
|
1787
|
+
}
|
|
1788
|
+
function divideOperatorSurfaceExpr(expr, side) {
|
|
1789
|
+
if (!isDivideOperatorExpr(expr)) {
|
|
1790
|
+
return expr;
|
|
1791
|
+
}
|
|
1792
|
+
return side === "arabic" ? DIVIDE_OPERATOR_AR : DIVIDE_OPERATOR_EN;
|
|
1793
|
+
}
|
|
1794
|
+
function renderDivideOperatorLatex(side) {
|
|
1795
|
+
return side === "arabic" ? "\\backslash" : DIVIDE_OPERATOR_EN;
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1772
1798
|
// src/editor/digits.ts
|
|
1773
1799
|
var WESTERN = "0123456789";
|
|
1774
1800
|
var ARABIC_INDIC = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
|
|
@@ -1917,6 +1943,9 @@ function renderNodeEnglish(node, options) {
|
|
|
1917
1943
|
if (node.kind === "char") {
|
|
1918
1944
|
return `${renderCharContent(node, options)}${latinScripts(node, options)}`;
|
|
1919
1945
|
}
|
|
1946
|
+
if (node.kind === "operator" && isDivideOperatorExpr(node.expr)) {
|
|
1947
|
+
return `${renderDivideOperatorLatex("english")}${latinScripts(node, options)}`;
|
|
1948
|
+
}
|
|
1920
1949
|
return `${formatDigits(node.expr, selectedDigitForm(options))}${latinScripts(node, options)}`;
|
|
1921
1950
|
}
|
|
1922
1951
|
function renderNodeArabic(node, options) {
|
|
@@ -1951,6 +1980,9 @@ function renderNodeArabic(node, options) {
|
|
|
1951
1980
|
const content = renderCharContent(node, options);
|
|
1952
1981
|
return arabicScripts(node, (node.characterFont ?? "default") === "default" ? `\\text{${escapeText(expr)}}` : content, options);
|
|
1953
1982
|
}
|
|
1983
|
+
if (node.kind === "operator" && isDivideOperatorExpr(node.expr)) {
|
|
1984
|
+
return arabicScripts(node, renderDivideOperatorLatex("arabic"), options);
|
|
1985
|
+
}
|
|
1954
1986
|
return arabicScripts(node, formatDigits(node.expr, selectedDigitForm(options)), options);
|
|
1955
1987
|
}
|
|
1956
1988
|
function renderChainEnglish(chain, options) {
|
|
@@ -2474,6 +2506,128 @@ function undoRedoCanRedo(stacks) {
|
|
|
2474
2506
|
return stacks.future.length > 0;
|
|
2475
2507
|
}
|
|
2476
2508
|
|
|
2509
|
+
// src/editor/derivativeTemplates.ts
|
|
2510
|
+
var ARABIC_VAR = "\u0633";
|
|
2511
|
+
var ENGLISH_VAR = "x";
|
|
2512
|
+
function mirroredAd() {
|
|
2513
|
+
const english = createAtomicCommandNode("ad");
|
|
2514
|
+
const arabic = createAtomicCommandNode("ad");
|
|
2515
|
+
arabic.id = english.id;
|
|
2516
|
+
return { english, arabic };
|
|
2517
|
+
}
|
|
2518
|
+
function mirroredVar() {
|
|
2519
|
+
const english = createEditorNode("char", ENGLISH_VAR);
|
|
2520
|
+
const arabic = createEditorNode("char", ARABIC_VAR);
|
|
2521
|
+
arabic.id = english.id;
|
|
2522
|
+
return { english, arabic };
|
|
2523
|
+
}
|
|
2524
|
+
function withMirroredSuperscript2(english, arabic) {
|
|
2525
|
+
const englishSup = createEditorChain([createEditorNode("number", "2")]);
|
|
2526
|
+
const arabicSup = createEditorChain([createEditorNode("number", "2")]);
|
|
2527
|
+
arabicSup.id = englishSup.id;
|
|
2528
|
+
arabicSup.nodes[0].id = englishSup.nodes[0].id;
|
|
2529
|
+
english.superscript = englishSup;
|
|
2530
|
+
arabic.superscript = arabicSup;
|
|
2531
|
+
}
|
|
2532
|
+
function syncChainIds(english, arabic) {
|
|
2533
|
+
arabic.id = english.id;
|
|
2534
|
+
const limit = Math.min(english.nodes.length, arabic.nodes.length);
|
|
2535
|
+
for (let index = 0; index < limit; index += 1) {
|
|
2536
|
+
arabic.nodes[index].id = english.nodes[index].id;
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
function syncFracIds(englishFrac, arabicFrac) {
|
|
2540
|
+
arabicFrac.id = englishFrac.id;
|
|
2541
|
+
if (englishFrac.numerator && arabicFrac.numerator) {
|
|
2542
|
+
syncChainIds(englishFrac.numerator, arabicFrac.numerator);
|
|
2543
|
+
}
|
|
2544
|
+
if (englishFrac.denominator && arabicFrac.denominator) {
|
|
2545
|
+
syncChainIds(englishFrac.denominator, arabicFrac.denominator);
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
function buildAdVarChain() {
|
|
2549
|
+
const ad = mirroredAd();
|
|
2550
|
+
const variable = mirroredVar();
|
|
2551
|
+
const english = createEditorChain([ad.english, variable.english]);
|
|
2552
|
+
const arabic = createEditorChain([ad.arabic, variable.arabic]);
|
|
2553
|
+
syncChainIds(english, arabic);
|
|
2554
|
+
return { english, arabic };
|
|
2555
|
+
}
|
|
2556
|
+
function mirroredEmptyDelimiter() {
|
|
2557
|
+
const english = createDelimiterNode("", "");
|
|
2558
|
+
const arabic = createDelimiterNode("", "");
|
|
2559
|
+
arabic.id = english.id;
|
|
2560
|
+
if (english.innerExpr && arabic.innerExpr) {
|
|
2561
|
+
syncChainIds(english.innerExpr, arabic.innerExpr);
|
|
2562
|
+
}
|
|
2563
|
+
return { english, arabic };
|
|
2564
|
+
}
|
|
2565
|
+
function setMirroredDelimiterInner(english, arabic, pairs) {
|
|
2566
|
+
const englishInner = createEditorChain(pairs.map((pair) => pair.english));
|
|
2567
|
+
const arabicInner = createEditorChain(pairs.map((pair) => pair.arabic));
|
|
2568
|
+
syncChainIds(englishInner, arabicInner);
|
|
2569
|
+
english.innerExpr = englishInner;
|
|
2570
|
+
arabic.innerExpr = arabicInner;
|
|
2571
|
+
}
|
|
2572
|
+
function buildFirstDerivativeFrac() {
|
|
2573
|
+
const englishFrac = createFracNode();
|
|
2574
|
+
const arabicFrac = createFracNode();
|
|
2575
|
+
syncFracIds(englishFrac, arabicFrac);
|
|
2576
|
+
const numerator = buildAdVarChain();
|
|
2577
|
+
const denominator = buildAdVarChain();
|
|
2578
|
+
englishFrac.numerator = numerator.english;
|
|
2579
|
+
englishFrac.denominator = denominator.english;
|
|
2580
|
+
arabicFrac.numerator = numerator.arabic;
|
|
2581
|
+
arabicFrac.denominator = denominator.arabic;
|
|
2582
|
+
return { english: englishFrac, arabic: arabicFrac };
|
|
2583
|
+
}
|
|
2584
|
+
function buildSecondDerivativeFrac() {
|
|
2585
|
+
const englishFrac = createFracNode();
|
|
2586
|
+
const arabicFrac = createFracNode();
|
|
2587
|
+
syncFracIds(englishFrac, arabicFrac);
|
|
2588
|
+
const numAd = mirroredAd();
|
|
2589
|
+
const numVar = mirroredVar();
|
|
2590
|
+
withMirroredSuperscript2(numAd.english, numAd.arabic);
|
|
2591
|
+
const englishNumerator = createEditorChain([numAd.english, numVar.english]);
|
|
2592
|
+
const arabicNumerator = createEditorChain([numAd.arabic, numVar.arabic]);
|
|
2593
|
+
syncChainIds(englishNumerator, arabicNumerator);
|
|
2594
|
+
englishFrac.numerator = englishNumerator;
|
|
2595
|
+
arabicFrac.numerator = arabicNumerator;
|
|
2596
|
+
const denGroup = mirroredEmptyDelimiter();
|
|
2597
|
+
const denInnerAd = mirroredAd();
|
|
2598
|
+
const denInnerVar = mirroredVar();
|
|
2599
|
+
setMirroredDelimiterInner(denGroup.english, denGroup.arabic, [
|
|
2600
|
+
{ english: denInnerAd.english, arabic: denInnerAd.arabic },
|
|
2601
|
+
{ english: denInnerVar.english, arabic: denInnerVar.arabic }
|
|
2602
|
+
]);
|
|
2603
|
+
withMirroredSuperscript2(denGroup.english, denGroup.arabic);
|
|
2604
|
+
englishFrac.denominator = createEditorChain([denGroup.english]);
|
|
2605
|
+
arabicFrac.denominator = createEditorChain([denGroup.arabic]);
|
|
2606
|
+
syncChainIds(englishFrac.denominator, arabicFrac.denominator);
|
|
2607
|
+
return { english: englishFrac, arabic: arabicFrac };
|
|
2608
|
+
}
|
|
2609
|
+
var DERIVATIVE_TEMPLATE_VAR_CARET_INDEX = 1;
|
|
2610
|
+
function derivativeTemplateInitialCaret(englishFrac) {
|
|
2611
|
+
const denominator = englishFrac.denominator;
|
|
2612
|
+
if (!denominator) {
|
|
2613
|
+
return {
|
|
2614
|
+
chainId: englishFrac.numerator?.id ?? "",
|
|
2615
|
+
index: DERIVATIVE_TEMPLATE_VAR_CARET_INDEX
|
|
2616
|
+
};
|
|
2617
|
+
}
|
|
2618
|
+
const loneDelimiter = denominator.nodes.length === 1 && denominator.nodes[0]?.kind === "delimiter" && denominator.nodes[0].innerExpr;
|
|
2619
|
+
if (loneDelimiter) {
|
|
2620
|
+
return {
|
|
2621
|
+
chainId: denominator.nodes[0].innerExpr.id,
|
|
2622
|
+
index: DERIVATIVE_TEMPLATE_VAR_CARET_INDEX
|
|
2623
|
+
};
|
|
2624
|
+
}
|
|
2625
|
+
return {
|
|
2626
|
+
chainId: denominator.id,
|
|
2627
|
+
index: DERIVATIVE_TEMPLATE_VAR_CARET_INDEX
|
|
2628
|
+
};
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2477
2631
|
// src/editor/uiLocale.ts
|
|
2478
2632
|
var ENGLISH_COMMAND_TITLES = {
|
|
2479
2633
|
cos: "Cosine",
|
|
@@ -2504,6 +2658,7 @@ var ENGLISH_COMMAND_TITLES = {
|
|
|
2504
2658
|
ln: "Natural logarithm",
|
|
2505
2659
|
log: "Logarithm",
|
|
2506
2660
|
det: "Determinant",
|
|
2661
|
+
ad: "Derivative (d / ad)",
|
|
2507
2662
|
N: "Natural numbers",
|
|
2508
2663
|
Z: "Integers",
|
|
2509
2664
|
Q: "Rational numbers",
|
|
@@ -2615,6 +2770,10 @@ var EQUATION_EDITOR_MESSAGES = {
|
|
|
2615
2770
|
insertFunction: "\u0625\u062F\u0631\u0627\u062C \u062F\u0627\u0644\u0629",
|
|
2616
2771
|
insertLimitsSeries: "\u0625\u062F\u0631\u0627\u062C \u062D\u062F\u0648\u062F \u0648\u0645\u062A\u0633\u0644\u0633\u0644\u0627\u062A",
|
|
2617
2772
|
insertAdditionalFunctions: "\u0625\u062F\u0631\u0627\u062C \u062F\u0648\u0627\u0644 \u0625\u0636\u0627\u0641\u064A\u0629",
|
|
2773
|
+
derivatives: "\u0627\u0644\u0627\u0634\u062A\u0642\u0627\u0642",
|
|
2774
|
+
insertDerivative: "\u0625\u062F\u0631\u0627\u062C \u0639\u0644\u0627\u0645\u0629 \u0627\u0634\u062A\u0642\u0627\u0642",
|
|
2775
|
+
insertFirstDerivative: "\u0625\u062F\u0631\u0627\u062C \u0627\u0634\u062A\u0642\u0627\u0642 \u0623\u0648\u0644",
|
|
2776
|
+
insertSecondDerivative: "\u0625\u062F\u0631\u0627\u062C \u0627\u0634\u062A\u0642\u0627\u0642 \u062B\u0627\u0646\u064A",
|
|
2618
2777
|
insertNumberSets: "\u0625\u062F\u0631\u0627\u062C \u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0623\u0639\u062F\u0627\u062F",
|
|
2619
2778
|
operations: "\u0627\u0644\u0639\u0645\u0644\u064A\u0627\u062A",
|
|
2620
2779
|
insertOperation: "\u0625\u062F\u0631\u0627\u062C \u0631\u0645\u0632 \u0639\u0645\u0644\u064A\u0629",
|
|
@@ -2718,6 +2877,10 @@ var EQUATION_EDITOR_MESSAGES = {
|
|
|
2718
2877
|
insertFunction: "Insert function",
|
|
2719
2878
|
insertLimitsSeries: "Insert limits and series",
|
|
2720
2879
|
insertAdditionalFunctions: "Insert additional functions",
|
|
2880
|
+
derivatives: "Derivatives",
|
|
2881
|
+
insertDerivative: "Insert derivative marker",
|
|
2882
|
+
insertFirstDerivative: "Insert first derivative",
|
|
2883
|
+
insertSecondDerivative: "Insert second derivative",
|
|
2721
2884
|
insertNumberSets: "Insert number sets",
|
|
2722
2885
|
operations: "Operators",
|
|
2723
2886
|
insertOperation: "Insert operator",
|
|
@@ -3425,10 +3588,27 @@ function insertNumber(session, expr) {
|
|
|
3425
3588
|
inserted.forceSplitNextLeaf = false;
|
|
3426
3589
|
return inserted;
|
|
3427
3590
|
}
|
|
3591
|
+
function insertDivideOperator(session) {
|
|
3592
|
+
const base = replaceSelectionFirst(session);
|
|
3593
|
+
const next = cloneEditorSession(base);
|
|
3594
|
+
const englishNode = createEditorNode("operator", DIVIDE_OPERATOR_EN);
|
|
3595
|
+
const arabicNode = createEditorNode("operator", DIVIDE_OPERATOR_AR);
|
|
3596
|
+
arabicNode.id = englishNode.id;
|
|
3597
|
+
insertMirroredNode(next, next.caret.chainId, next.caret.index, englishNode, arabicNode);
|
|
3598
|
+
markExprSync(next, englishNode.id);
|
|
3599
|
+
next.caret.index += 1;
|
|
3600
|
+
next.selectedStructureNodeId = null;
|
|
3601
|
+
syncSelectionToCaret(next);
|
|
3602
|
+
appendDebug(next, "insertDivideOperator", "");
|
|
3603
|
+
return next;
|
|
3604
|
+
}
|
|
3428
3605
|
function insertOperator(session, expr) {
|
|
3429
3606
|
if (expr === "." && !session.splitLeafTyping && precedingIsExtendableNumber(session)) {
|
|
3430
3607
|
return insertNumber(session, ".");
|
|
3431
3608
|
}
|
|
3609
|
+
if (expr === DIVIDE_OPERATOR_EN || expr === DIVIDE_OPERATOR_AR) {
|
|
3610
|
+
return insertDivideOperator(session);
|
|
3611
|
+
}
|
|
3432
3612
|
const base = replaceSelectionFirst(session);
|
|
3433
3613
|
return insertLeaf(base, "operator", expr);
|
|
3434
3614
|
}
|
|
@@ -3499,6 +3679,24 @@ function insertFraction(session) {
|
|
|
3499
3679
|
appendDebug(next, "insertFraction", "");
|
|
3500
3680
|
return next;
|
|
3501
3681
|
}
|
|
3682
|
+
function insertDerivativeFrac(session, build, debugLabel) {
|
|
3683
|
+
const base = replaceSelectionFirst(session);
|
|
3684
|
+
const next = cloneEditorSession(base);
|
|
3685
|
+
const { english, arabic } = build();
|
|
3686
|
+
insertMirroredNode(next, next.caret.chainId, next.caret.index, english, arabic);
|
|
3687
|
+
syncSubtreeRecursive(next, english, arabic);
|
|
3688
|
+
next.caret = derivativeTemplateInitialCaret(english);
|
|
3689
|
+
next.selectedStructureNodeId = null;
|
|
3690
|
+
syncSelectionToCaret(next);
|
|
3691
|
+
appendDebug(next, debugLabel, "");
|
|
3692
|
+
return next;
|
|
3693
|
+
}
|
|
3694
|
+
function insertFirstDerivative(session) {
|
|
3695
|
+
return insertDerivativeFrac(session, buildFirstDerivativeFrac, "insertFirstDerivative");
|
|
3696
|
+
}
|
|
3697
|
+
function insertSecondDerivative(session) {
|
|
3698
|
+
return insertDerivativeFrac(session, buildSecondDerivativeFrac, "insertSecondDerivative");
|
|
3699
|
+
}
|
|
3502
3700
|
function insertSqrt(session) {
|
|
3503
3701
|
const base = replaceSelectionFirst(session);
|
|
3504
3702
|
const next = cloneEditorSession(base);
|
|
@@ -3969,6 +4167,11 @@ function pasteText(session, text) {
|
|
|
3969
4167
|
i += 1;
|
|
3970
4168
|
continue;
|
|
3971
4169
|
}
|
|
4170
|
+
if (ch === DIVIDE_OPERATOR_AR) {
|
|
4171
|
+
s = insertDivideOperator(s);
|
|
4172
|
+
i += 1;
|
|
4173
|
+
continue;
|
|
4174
|
+
}
|
|
3972
4175
|
s = insertChar(s, ch);
|
|
3973
4176
|
i += 1;
|
|
3974
4177
|
}
|
|
@@ -3976,7 +4179,7 @@ function pasteText(session, text) {
|
|
|
3976
4179
|
}
|
|
3977
4180
|
|
|
3978
4181
|
// src/editor/display/base.ts
|
|
3979
|
-
function buildBaseNodeBody(node, digitForm = "western") {
|
|
4182
|
+
function buildBaseNodeBody(node, digitForm = "western", side = "english") {
|
|
3980
4183
|
const value = document.createElement("span");
|
|
3981
4184
|
value.className = "node-value";
|
|
3982
4185
|
if (node.kind === "char" && node.characterFont === "takween") {
|
|
@@ -3986,7 +4189,8 @@ function buildBaseNodeBody(node, digitForm = "western") {
|
|
|
3986
4189
|
} else if (node.kind === "char" && node.characterFont === "diwaniOutline") {
|
|
3987
4190
|
value.classList.add("node-value--diwani-outline");
|
|
3988
4191
|
}
|
|
3989
|
-
|
|
4192
|
+
const surfaceExpr = node.kind === "operator" ? divideOperatorSurfaceExpr(node.expr, side) : node.expr;
|
|
4193
|
+
value.textContent = surfaceExpr === "" ? "\u25A1" : formatDigits(surfaceExpr, digitForm);
|
|
3990
4194
|
return value;
|
|
3991
4195
|
}
|
|
3992
4196
|
|
|
@@ -4507,7 +4711,7 @@ function buildFunctionAtomicCommandBody(node, side, spec) {
|
|
|
4507
4711
|
value.appendChild(label);
|
|
4508
4712
|
return value;
|
|
4509
4713
|
}
|
|
4510
|
-
value.textContent = side === "arabic" ? spec?.arabicLabel ?? node.expr : spec?.englishTex.replace(
|
|
4714
|
+
value.textContent = side === "arabic" ? spec?.arabicLabel ?? node.expr : spec?.englishLabel ?? spec?.englishTex.replace(/^\\/, "") ?? node.expr;
|
|
4511
4715
|
return value;
|
|
4512
4716
|
}
|
|
4513
4717
|
function buildSpacingAtomicCommandBody(spec, side, uiLocale) {
|
|
@@ -4633,7 +4837,7 @@ function buildNodeBody(node, buildChain, side, digitForm = "western", uiLocale =
|
|
|
4633
4837
|
if (node.kind === "atomicOperatorCommand") {
|
|
4634
4838
|
return buildAtomicOperatorCommandNodeBody(node, side, uiLocale);
|
|
4635
4839
|
}
|
|
4636
|
-
return buildBaseNodeBody(node, digitForm);
|
|
4840
|
+
return buildBaseNodeBody(node, digitForm, side);
|
|
4637
4841
|
}
|
|
4638
4842
|
|
|
4639
4843
|
// src/editor/styles.ts
|
|
@@ -5351,6 +5555,10 @@ function createEditorRuntime(options) {
|
|
|
5351
5555
|
applyStructural((prev) => insertNumber(prev, char));
|
|
5352
5556
|
return;
|
|
5353
5557
|
}
|
|
5558
|
+
if (char === "\\") {
|
|
5559
|
+
applyStructural((prev) => insertDivideOperator(prev));
|
|
5560
|
+
return;
|
|
5561
|
+
}
|
|
5354
5562
|
if (isOperator(char)) {
|
|
5355
5563
|
applyStructural((prev) => insertOperator(prev, char));
|
|
5356
5564
|
return;
|
|
@@ -5514,6 +5722,14 @@ function createEditorRuntime(options) {
|
|
|
5514
5722
|
applyStructural((prev) => insertFraction(prev));
|
|
5515
5723
|
surfaceEl.focus();
|
|
5516
5724
|
},
|
|
5725
|
+
insertFirstDerivative: () => {
|
|
5726
|
+
applyStructural((prev) => insertFirstDerivative(prev));
|
|
5727
|
+
surfaceEl.focus();
|
|
5728
|
+
},
|
|
5729
|
+
insertSecondDerivative: () => {
|
|
5730
|
+
applyStructural((prev) => insertSecondDerivative(prev));
|
|
5731
|
+
surfaceEl.focus();
|
|
5732
|
+
},
|
|
5517
5733
|
insertMatrixEnv: (style, rows, columns) => {
|
|
5518
5734
|
applyStructural((prev) => insertMatrixEnv(prev, style, rows, columns));
|
|
5519
5735
|
surfaceEl.focus();
|
|
@@ -5581,7 +5797,95 @@ function createEditorRuntime(options) {
|
|
|
5581
5797
|
return api;
|
|
5582
5798
|
}
|
|
5583
5799
|
|
|
5800
|
+
// src/document/normalizeCharImport.ts
|
|
5801
|
+
var WRAPPER_SPECS = [
|
|
5802
|
+
{ prefix: "\\butexdiwanioutline", font: "diwaniOutline" },
|
|
5803
|
+
{ prefix: "\\diwanioutlineshaded", font: "diwaniOutline" },
|
|
5804
|
+
{ prefix: "\\butexdiwani", font: "diwani" },
|
|
5805
|
+
{ prefix: "\\butextakween", font: "takween" },
|
|
5806
|
+
{ prefix: "\\diwani", font: "diwani" },
|
|
5807
|
+
{ prefix: "\\takween", font: "takween" },
|
|
5808
|
+
{ prefix: "\\text" }
|
|
5809
|
+
];
|
|
5810
|
+
function readBracedArg(source, openBraceIndex) {
|
|
5811
|
+
if (source[openBraceIndex] !== "{") {
|
|
5812
|
+
return null;
|
|
5813
|
+
}
|
|
5814
|
+
let depth = 0;
|
|
5815
|
+
for (let index = openBraceIndex; index < source.length; index += 1) {
|
|
5816
|
+
const char = source[index];
|
|
5817
|
+
if (char === "{") {
|
|
5818
|
+
depth += 1;
|
|
5819
|
+
} else if (char === "}") {
|
|
5820
|
+
depth -= 1;
|
|
5821
|
+
if (depth === 0) {
|
|
5822
|
+
return { inner: source.slice(openBraceIndex + 1, index), end: index + 1 };
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
5825
|
+
}
|
|
5826
|
+
return null;
|
|
5827
|
+
}
|
|
5828
|
+
function peelWrapper(source) {
|
|
5829
|
+
for (const wrapper of WRAPPER_SPECS) {
|
|
5830
|
+
if (!source.startsWith(wrapper.prefix)) {
|
|
5831
|
+
continue;
|
|
5832
|
+
}
|
|
5833
|
+
const braced = readBracedArg(source, wrapper.prefix.length);
|
|
5834
|
+
if (!braced || braced.end !== source.length) {
|
|
5835
|
+
continue;
|
|
5836
|
+
}
|
|
5837
|
+
return { inner: braced.inner, font: wrapper.font };
|
|
5838
|
+
}
|
|
5839
|
+
return null;
|
|
5840
|
+
}
|
|
5841
|
+
function normalizeCharImportExpr(expr) {
|
|
5842
|
+
const original = expr;
|
|
5843
|
+
let current = expr;
|
|
5844
|
+
let characterFont = "default";
|
|
5845
|
+
let changed = false;
|
|
5846
|
+
while (true) {
|
|
5847
|
+
const peeled = peelWrapper(current);
|
|
5848
|
+
if (!peeled) {
|
|
5849
|
+
break;
|
|
5850
|
+
}
|
|
5851
|
+
current = peeled.inner;
|
|
5852
|
+
if (peeled.font) {
|
|
5853
|
+
characterFont = peeled.font;
|
|
5854
|
+
}
|
|
5855
|
+
changed = true;
|
|
5856
|
+
}
|
|
5857
|
+
if (!changed) {
|
|
5858
|
+
return { expr: original, characterFont: "default" };
|
|
5859
|
+
}
|
|
5860
|
+
if (current.includes("\\")) {
|
|
5861
|
+
return { expr: original, characterFont: "default" };
|
|
5862
|
+
}
|
|
5863
|
+
return { expr: current, characterFont };
|
|
5864
|
+
}
|
|
5865
|
+
|
|
5584
5866
|
// src/document/mathEditorAdapter.ts
|
|
5867
|
+
var COMMAND_FONT_MAP = {
|
|
5868
|
+
"\\text": "infer",
|
|
5869
|
+
"\\butextakween": "takween",
|
|
5870
|
+
"\\takween": "takween",
|
|
5871
|
+
"\\butexdiwani": "diwani",
|
|
5872
|
+
"\\diwani": "diwani",
|
|
5873
|
+
"\\butexdiwanioutline": "diwaniOutline",
|
|
5874
|
+
"\\diwanioutlineshaded": "diwaniOutline"
|
|
5875
|
+
};
|
|
5876
|
+
var CHAR_FONT_EXPORT_TEX = {
|
|
5877
|
+
takween: "\\butextakween",
|
|
5878
|
+
diwani: "\\butexdiwani",
|
|
5879
|
+
diwaniOutline: "\\butexdiwanioutline"
|
|
5880
|
+
};
|
|
5881
|
+
function charEditorNodeToAstNode(node) {
|
|
5882
|
+
const font = node.characterFont ?? "default";
|
|
5883
|
+
const charNode = new CharNode(node.expr);
|
|
5884
|
+
if (font === "default") {
|
|
5885
|
+
return charNode;
|
|
5886
|
+
}
|
|
5887
|
+
return new CommandNode(CHAR_FONT_EXPORT_TEX[font], [], [new ChainNode([charNode])]);
|
|
5888
|
+
}
|
|
5585
5889
|
function commandIdForTex(tex) {
|
|
5586
5890
|
for (const spec of Object.values(ATOMIC_COMMANDS)) {
|
|
5587
5891
|
const renderTex = spec.arabicRenderTex;
|
|
@@ -5693,6 +5997,42 @@ function envToEditorNode(node) {
|
|
|
5693
5997
|
const scripts = attachScripts(node, env);
|
|
5694
5998
|
return scripts ?? { editable: true, node: env };
|
|
5695
5999
|
}
|
|
6000
|
+
function charFromTextLikeCommand(node) {
|
|
6001
|
+
const commandFont = COMMAND_FONT_MAP[node.name];
|
|
6002
|
+
if (commandFont === void 0) {
|
|
6003
|
+
return null;
|
|
6004
|
+
}
|
|
6005
|
+
if (node.optionalArgs.length > 0 || node.mandatoryArgs.length !== 1) {
|
|
6006
|
+
return null;
|
|
6007
|
+
}
|
|
6008
|
+
const arg = node.mandatoryArgs[0];
|
|
6009
|
+
if (arg.chain.length !== 1) {
|
|
6010
|
+
return null;
|
|
6011
|
+
}
|
|
6012
|
+
const child = arg.chain[0];
|
|
6013
|
+
if (child instanceof CommandNode) {
|
|
6014
|
+
const nested = charFromTextLikeCommand(child);
|
|
6015
|
+
if (!nested?.editable) {
|
|
6016
|
+
return null;
|
|
6017
|
+
}
|
|
6018
|
+
if (commandFont !== "infer") {
|
|
6019
|
+
nested.node.characterFont = commandFont;
|
|
6020
|
+
}
|
|
6021
|
+
const scripts2 = attachScripts(node, nested.node);
|
|
6022
|
+
return scripts2 ?? nested;
|
|
6023
|
+
}
|
|
6024
|
+
if (!(child instanceof CharNode)) {
|
|
6025
|
+
return null;
|
|
6026
|
+
}
|
|
6027
|
+
const normalized = normalizeCharImportExpr(child.expr);
|
|
6028
|
+
const characterFont = commandFont === "infer" ? normalized.characterFont : commandFont;
|
|
6029
|
+
const editorNode = createEditorNode("char", normalized.expr);
|
|
6030
|
+
if (characterFont !== "default") {
|
|
6031
|
+
editorNode.characterFont = characterFont;
|
|
6032
|
+
}
|
|
6033
|
+
const scripts = attachScripts(node, editorNode);
|
|
6034
|
+
return scripts ?? { editable: true, node: editorNode };
|
|
6035
|
+
}
|
|
5696
6036
|
function commandToEditorNode(node) {
|
|
5697
6037
|
if (node.name === "\\frac" && node.mandatoryArgs.length >= 2) {
|
|
5698
6038
|
const frac = createFracNode();
|
|
@@ -5750,11 +6090,19 @@ function commandToEditorNode(node) {
|
|
|
5750
6090
|
}
|
|
5751
6091
|
return { editable: true, node: atomicOperator };
|
|
5752
6092
|
}
|
|
6093
|
+
const textLike = charFromTextLikeCommand(node);
|
|
6094
|
+
if (textLike) {
|
|
6095
|
+
return textLike;
|
|
6096
|
+
}
|
|
5753
6097
|
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}` };
|
|
5754
6098
|
}
|
|
5755
6099
|
function astNodeToEditorNode(node) {
|
|
5756
6100
|
if (node instanceof CharNode) {
|
|
5757
|
-
const
|
|
6101
|
+
const normalized = normalizeCharImportExpr(node.expr);
|
|
6102
|
+
const editorNode = createEditorNode("char", normalized.expr);
|
|
6103
|
+
if (normalized.characterFont !== "default") {
|
|
6104
|
+
editorNode.characterFont = normalized.characterFont;
|
|
6105
|
+
}
|
|
5758
6106
|
const scripts = attachScripts(node, editorNode);
|
|
5759
6107
|
return scripts ?? { editable: true, node: editorNode };
|
|
5760
6108
|
}
|
|
@@ -5863,7 +6211,7 @@ function editorEnvToAstNode(node) {
|
|
|
5863
6211
|
function editorNodeToAstNode(node) {
|
|
5864
6212
|
let astNode;
|
|
5865
6213
|
if (node.kind === "char") {
|
|
5866
|
-
astNode =
|
|
6214
|
+
astNode = charEditorNodeToAstNode(node);
|
|
5867
6215
|
} else if (node.kind === "number") {
|
|
5868
6216
|
astNode = new NumberNode(node.expr);
|
|
5869
6217
|
} else if (node.kind === "operator") {
|
|
@@ -7734,6 +8082,7 @@ var CHARACTER_FONT_OPTIONS = [
|
|
|
7734
8082
|
var FUNCTION_COMMANDS = atomicCommandsByCategory("function");
|
|
7735
8083
|
var LIMITS_SERIES_COMMANDS = atomicCommandsByCategory("limits_series");
|
|
7736
8084
|
var FUNCTION2_COMMANDS = atomicCommandsByCategory("function2");
|
|
8085
|
+
var DERIVATIVE_COMMANDS = atomicCommandsByCategory("derivative");
|
|
7737
8086
|
var GROUP_COMMANDS = atomicCommandsByCategory("groups");
|
|
7738
8087
|
var SPACING_COMMANDS = atomicCommandsByCategory("spacing").filter(isSpacingCommandSpec);
|
|
7739
8088
|
var OPERATOR_COMMANDS = atomicOperatorCommandsByCategory("operators1");
|
|
@@ -7871,6 +8220,7 @@ var ButexEditor = (0, import_react.forwardRef)(
|
|
|
7871
8220
|
const [functionMenuOpen, setFunctionMenuOpen] = (0, import_react.useState)(false);
|
|
7872
8221
|
const [limitsSeriesMenuOpen, setLimitsSeriesMenuOpen] = (0, import_react.useState)(false);
|
|
7873
8222
|
const [function2MenuOpen, setFunction2MenuOpen] = (0, import_react.useState)(false);
|
|
8223
|
+
const [derivativeMenuOpen, setDerivativeMenuOpen] = (0, import_react.useState)(false);
|
|
7874
8224
|
const [groupMenuOpen, setGroupMenuOpen] = (0, import_react.useState)(false);
|
|
7875
8225
|
const [operatorMenuOpen, setOperatorMenuOpen] = (0, import_react.useState)(false);
|
|
7876
8226
|
const [operator2MenuOpen, setOperator2MenuOpen] = (0, import_react.useState)(false);
|
|
@@ -8529,6 +8879,87 @@ ${arabic || currentMessages.empty}`;
|
|
|
8529
8879
|
]
|
|
8530
8880
|
}
|
|
8531
8881
|
),
|
|
8882
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
8883
|
+
"div",
|
|
8884
|
+
{
|
|
8885
|
+
className: "function-command-menu function-command-menu--derivative",
|
|
8886
|
+
onBlur: (event) => {
|
|
8887
|
+
const nextFocus = event.relatedTarget;
|
|
8888
|
+
if (!(nextFocus instanceof Node) || !event.currentTarget.contains(nextFocus)) {
|
|
8889
|
+
setDerivativeMenuOpen(false);
|
|
8890
|
+
}
|
|
8891
|
+
},
|
|
8892
|
+
children: [
|
|
8893
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
8894
|
+
"button",
|
|
8895
|
+
{
|
|
8896
|
+
className: "icon-btn function-command-btn",
|
|
8897
|
+
type: "button",
|
|
8898
|
+
title: messages.insertDerivative,
|
|
8899
|
+
"aria-label": messages.insertDerivative,
|
|
8900
|
+
"aria-haspopup": "listbox",
|
|
8901
|
+
"aria-expanded": derivativeMenuOpen,
|
|
8902
|
+
onClick: () => setDerivativeMenuOpen((open) => !open),
|
|
8903
|
+
children: DERIVATIVE_COMMANDS[0]?.arabicLabel ?? "\u0621"
|
|
8904
|
+
}
|
|
8905
|
+
),
|
|
8906
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "function-command-options", role: "listbox", "aria-label": messages.insertDerivative, hidden: !derivativeMenuOpen, children: [
|
|
8907
|
+
DERIVATIVE_COMMANDS.map((command) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
8908
|
+
"button",
|
|
8909
|
+
{
|
|
8910
|
+
className: "function-command-option",
|
|
8911
|
+
type: "button",
|
|
8912
|
+
role: "option",
|
|
8913
|
+
title: atomicCommandTitle(command, uiLocale),
|
|
8914
|
+
"aria-label": atomicCommandTitle(command, uiLocale),
|
|
8915
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
8916
|
+
onClick: () => {
|
|
8917
|
+
runtimeRef.current?.insertAtomicCommand(command.id);
|
|
8918
|
+
setDerivativeMenuOpen(false);
|
|
8919
|
+
focusSurface();
|
|
8920
|
+
},
|
|
8921
|
+
children: command.arabicLabel
|
|
8922
|
+
},
|
|
8923
|
+
command.id
|
|
8924
|
+
)),
|
|
8925
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
8926
|
+
"button",
|
|
8927
|
+
{
|
|
8928
|
+
className: "function-command-option",
|
|
8929
|
+
type: "button",
|
|
8930
|
+
role: "option",
|
|
8931
|
+
title: messages.insertFirstDerivative,
|
|
8932
|
+
"aria-label": messages.insertFirstDerivative,
|
|
8933
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
8934
|
+
onClick: () => {
|
|
8935
|
+
runtimeRef.current?.insertFirstDerivative();
|
|
8936
|
+
setDerivativeMenuOpen(false);
|
|
8937
|
+
focusSurface();
|
|
8938
|
+
},
|
|
8939
|
+
children: "\u0621/\u0633"
|
|
8940
|
+
}
|
|
8941
|
+
),
|
|
8942
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
8943
|
+
"button",
|
|
8944
|
+
{
|
|
8945
|
+
className: "function-command-option",
|
|
8946
|
+
type: "button",
|
|
8947
|
+
role: "option",
|
|
8948
|
+
title: messages.insertSecondDerivative,
|
|
8949
|
+
"aria-label": messages.insertSecondDerivative,
|
|
8950
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
8951
|
+
onClick: () => {
|
|
8952
|
+
runtimeRef.current?.insertSecondDerivative();
|
|
8953
|
+
setDerivativeMenuOpen(false);
|
|
8954
|
+
focusSurface();
|
|
8955
|
+
},
|
|
8956
|
+
children: "\u0621\xB2/\u0633\xB2"
|
|
8957
|
+
}
|
|
8958
|
+
)
|
|
8959
|
+
] })
|
|
8960
|
+
]
|
|
8961
|
+
}
|
|
8962
|
+
),
|
|
8532
8963
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
8533
8964
|
"div",
|
|
8534
8965
|
{
|