@drghaliasri/butex 5.5.5 → 5.6.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.
@@ -65,7 +65,9 @@ function butexBasmalaDisplayTex() {
65
65
  }
66
66
  function butexBasmalaDisplayLatex() {
67
67
  return `\\[
68
- ${butexBasmalaDisplayTex()}
68
+ \\begin{gathered}
69
+ ${BASMALA_LINES.map((line) => butexMaghribiDisplayTex(line)).join(" \\\\\n")}
70
+ \\end{gathered}
69
71
  \\]`;
70
72
  }
71
73
  function butexInColumnMaketitleHook() {
@@ -2067,6 +2069,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2067
2069
  category: "operators1",
2068
2070
  Tex: "\\neq",
2069
2071
  mirror: true,
2072
+ compileMirror: true,
2070
2073
  Label: "\u2260",
2071
2074
  title: "\u0644\u0627 \u064A\u0633\u0627\u0648\u064A",
2072
2075
  svg_path: null
@@ -2106,6 +2109,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2106
2109
  Tex: "\\leq",
2107
2110
  mirror: true,
2108
2111
  displayMirror: false,
2112
+ compileMirror: true,
2109
2113
  Label: "\u2264",
2110
2114
  title: "\u0623\u0635\u063A\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
2111
2115
  svg_path: null
@@ -2116,6 +2120,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2116
2120
  Tex: "\\geq",
2117
2121
  mirror: true,
2118
2122
  displayMirror: false,
2123
+ compileMirror: true,
2119
2124
  Label: "\u2265",
2120
2125
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
2121
2126
  svg_path: null
@@ -2126,6 +2131,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2126
2131
  Tex: "\\coloneqq",
2127
2132
  mirror: true,
2128
2133
  displayMirror: false,
2134
+ compileMirror: true,
2129
2135
  Label: "\u2254",
2130
2136
  title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
2131
2137
  svg_path: null
@@ -2136,6 +2142,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2136
2142
  Tex: "\\eqqcolon",
2137
2143
  mirror: true,
2138
2144
  displayMirror: false,
2145
+ compileMirror: true,
2139
2146
  Label: "\u2255",
2140
2147
  title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
2141
2148
  svg_path: null
@@ -2147,6 +2154,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2147
2154
  Tex: "\\propto",
2148
2155
  mirror: true,
2149
2156
  displayMirror: false,
2157
+ compileMirror: true,
2150
2158
  Label: "\u221D",
2151
2159
  title: "\u064A\u062A\u0646\u0627\u0633\u0628 \u0645\u0639",
2152
2160
  svg_path: null
@@ -2157,6 +2165,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2157
2165
  Tex: "\\in",
2158
2166
  mirror: true,
2159
2167
  displayMirror: false,
2168
+ compileMirror: true,
2160
2169
  Label: "\u2208",
2161
2170
  title: "\u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
2162
2171
  svg_path: null
@@ -2177,6 +2186,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2177
2186
  Tex: "\\subset",
2178
2187
  mirror: true,
2179
2188
  displayMirror: false,
2189
+ compileMirror: true,
2180
2190
  Label: "\u2282",
2181
2191
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0645\u0646",
2182
2192
  svg_path: null
@@ -2187,6 +2197,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2187
2197
  Tex: "\\supset",
2188
2198
  mirror: true,
2189
2199
  displayMirror: false,
2200
+ compileMirror: true,
2190
2201
  Label: "\u2283",
2191
2202
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0644\u0640",
2192
2203
  svg_path: null
@@ -2197,6 +2208,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2197
2208
  Tex: "\\subseteq",
2198
2209
  mirror: true,
2199
2210
  displayMirror: false,
2211
+ compileMirror: true,
2200
2212
  Label: "\u2286",
2201
2213
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2202
2214
  svg_path: null
@@ -2207,6 +2219,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2207
2219
  Tex: "\\supseteq",
2208
2220
  mirror: true,
2209
2221
  displayMirror: false,
2222
+ compileMirror: true,
2210
2223
  Label: "\u2287",
2211
2224
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2212
2225
  svg_path: null
@@ -2247,6 +2260,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2247
2260
  Tex: "\\nsubseteq",
2248
2261
  mirror: true,
2249
2262
  displayMirror: false,
2263
+ compileMirror: true,
2250
2264
  Label: "\u2288",
2251
2265
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2252
2266
  svg_path: null
@@ -2257,6 +2271,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2257
2271
  Tex: "\\nsupseteq",
2258
2272
  mirror: true,
2259
2273
  displayMirror: false,
2274
+ compileMirror: true,
2260
2275
  Label: "\u2289",
2261
2276
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
2262
2277
  svg_path: null
@@ -2304,6 +2319,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2304
2319
  Tex: "\\ddots",
2305
2320
  mirror: true,
2306
2321
  displayMirror: false,
2322
+ compileMirror: true,
2307
2323
  Label: "\u22F1",
2308
2324
  title: "\u0646\u0642\u0627\u0637 \u0642\u0637\u0631\u064A\u0629",
2309
2325
  svg_path: null
@@ -2323,6 +2339,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2323
2339
  category: "operators3",
2324
2340
  Tex: "\\implies",
2325
2341
  mirror: true,
2342
+ compileMirror: true,
2326
2343
  Label: "\u21D2",
2327
2344
  title: "\u064A\u0633\u062A\u0644\u0632\u0645",
2328
2345
  svg_path: null
@@ -2332,6 +2349,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2332
2349
  category: "operators3",
2333
2350
  Tex: "\\impliedby",
2334
2351
  mirror: true,
2352
+ compileMirror: true,
2335
2353
  Label: "\u21D0",
2336
2354
  title: "\u0645\u0633\u062A\u0644\u0632\u0645 \u0645\u0646",
2337
2355
  svg_path: null
@@ -2350,6 +2368,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2350
2368
  category: "operators3",
2351
2369
  Tex: "\\Longrightarrow",
2352
2370
  mirror: true,
2371
+ compileMirror: true,
2353
2372
  Label: "\u27F9",
2354
2373
  title: "\u0633\u0647\u0645 \u0645\u0632\u062F\u0648\u062C \u0637\u0648\u064A\u0644 \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646",
2355
2374
  svg_path: null
@@ -2359,6 +2378,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2359
2378
  category: "operators3",
2360
2379
  Tex: "\\Longleftarrow",
2361
2380
  mirror: true,
2381
+ compileMirror: true,
2362
2382
  Label: "\u27F8",
2363
2383
  title: "\u0633\u0647\u0645 \u0645\u0632\u062F\u0648\u062C \u0637\u0648\u064A\u0644 \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631",
2364
2384
  svg_path: null
@@ -2368,6 +2388,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2368
2388
  category: "operators3",
2369
2389
  Tex: "\\to",
2370
2390
  mirror: true,
2391
+ compileMirror: true,
2371
2392
  Label: "\u2192",
2372
2393
  title: "\u064A\u0624\u0648\u0644 \u0625\u0644\u0649",
2373
2394
  svg_path: null
@@ -2377,6 +2398,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2377
2398
  category: "operators3",
2378
2399
  Tex: "\\rightleftharpoons",
2379
2400
  mirror: true,
2401
+ compileMirror: true,
2380
2402
  Label: "\u21CC",
2381
2403
  title: "\u0627\u062A\u0632\u0627\u0646",
2382
2404
  svg_path: null
@@ -2386,6 +2408,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2386
2408
  category: "operators3",
2387
2409
  Tex: "\\leftarrow",
2388
2410
  mirror: true,
2411
+ compileMirror: true,
2389
2412
  Label: "\u2190",
2390
2413
  title: "\u0633\u0647\u0645 \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631",
2391
2414
  svg_path: null
@@ -2395,6 +2418,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2395
2418
  category: "operators3",
2396
2419
  Tex: "\\rightarrow",
2397
2420
  mirror: true,
2421
+ compileMirror: true,
2398
2422
  Label: "\u2192",
2399
2423
  title: "\u0633\u0647\u0645 \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646",
2400
2424
  svg_path: null
@@ -2404,6 +2428,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2404
2428
  category: "operators3",
2405
2429
  Tex: "\\Leftarrow",
2406
2430
  mirror: true,
2431
+ compileMirror: true,
2407
2432
  Label: "\u21D0",
2408
2433
  title: "\u0633\u0647\u0645 \u0645\u0632\u062F\u0648\u062C \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631",
2409
2434
  svg_path: null
@@ -2413,6 +2438,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2413
2438
  category: "operators3",
2414
2439
  Tex: "\\Rightarrow",
2415
2440
  mirror: true,
2441
+ compileMirror: true,
2416
2442
  Label: "\u21D2",
2417
2443
  title: "\u0633\u0647\u0645 \u0645\u0632\u062F\u0648\u062C \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646",
2418
2444
  svg_path: null
@@ -2422,6 +2448,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2422
2448
  category: "operators3",
2423
2449
  Tex: "\\leftharpoonup",
2424
2450
  mirror: true,
2451
+ compileMirror: true,
2425
2452
  Label: "\u21BC",
2426
2453
  title: "\u0633\u0647\u0645 \u062E\u0637\u0627\u0641\u064A \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631",
2427
2454
  svg_path: null
@@ -2431,6 +2458,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2431
2458
  category: "operators3",
2432
2459
  Tex: "\\rightharpoonup",
2433
2460
  mirror: true,
2461
+ compileMirror: true,
2434
2462
  Label: "\u21C0",
2435
2463
  title: "\u0633\u0647\u0645 \u062E\u0637\u0627\u0641\u064A \u0639\u0644\u0648\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646",
2436
2464
  svg_path: null
@@ -2440,6 +2468,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2440
2468
  category: "operators3",
2441
2469
  Tex: "\\leftharpoondown",
2442
2470
  mirror: true,
2471
+ compileMirror: true,
2443
2472
  Label: "\u21BD",
2444
2473
  title: "\u0633\u0647\u0645 \u062E\u0637\u0627\u0641\u064A \u0633\u0641\u0644\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631",
2445
2474
  svg_path: null
@@ -2449,6 +2478,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2449
2478
  category: "operators3",
2450
2479
  Tex: "\\rightharpoondown",
2451
2480
  mirror: true,
2481
+ compileMirror: true,
2452
2482
  Label: "\u21C1",
2453
2483
  title: "\u0633\u0647\u0645 \u062E\u0637\u0627\u0641\u064A \u0633\u0641\u0644\u064A \u0625\u0644\u0649 \u0627\u0644\u064A\u0645\u064A\u0646",
2454
2484
  svg_path: null
@@ -2459,6 +2489,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2459
2489
  category: "integrals",
2460
2490
  Tex: "\\int",
2461
2491
  mirror: true,
2492
+ compileMirror: true,
2462
2493
  Label: "\u222B",
2463
2494
  title: "\u062A\u0643\u0627\u0645\u0644",
2464
2495
  svg_path: null
@@ -2469,6 +2500,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2469
2500
  Tex: "\\iint",
2470
2501
  mirror: true,
2471
2502
  displayMirror: false,
2503
+ compileMirror: true,
2472
2504
  Label: "\u222C",
2473
2505
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u0632\u062F\u0648\u062C",
2474
2506
  svg_path: null
@@ -2479,6 +2511,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2479
2511
  Tex: "\\iiint",
2480
2512
  mirror: true,
2481
2513
  displayMirror: false,
2514
+ compileMirror: true,
2482
2515
  Label: "\u222D",
2483
2516
  title: "\u062A\u0643\u0627\u0645\u0644 \u062B\u0644\u0627\u062B\u064A",
2484
2517
  svg_path: null
@@ -2489,6 +2522,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2489
2522
  Tex: "\\iiiint",
2490
2523
  mirror: true,
2491
2524
  displayMirror: false,
2525
+ compileMirror: true,
2492
2526
  Label: "\u2A0C",
2493
2527
  title: "\u062A\u0643\u0627\u0645\u0644 \u0631\u0628\u0627\u0639\u064A",
2494
2528
  svg_path: null
@@ -2499,6 +2533,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2499
2533
  Tex: "\\oint",
2500
2534
  mirror: true,
2501
2535
  displayMirror: false,
2536
+ compileMirror: true,
2502
2537
  Label: "\u222E",
2503
2538
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u063A\u0644\u0642",
2504
2539
  svg_path: null
@@ -2509,6 +2544,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2509
2544
  Tex: "\\oiint",
2510
2545
  mirror: true,
2511
2546
  displayMirror: false,
2547
+ compileMirror: true,
2512
2548
  Label: "\u222F",
2513
2549
  title: "\u062A\u0643\u0627\u0645\u0644 \u0633\u0637\u062D\u064A \u0645\u063A\u0644\u0642",
2514
2550
  svg_path: null
@@ -2519,6 +2555,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2519
2555
  Tex: "\\oiiint",
2520
2556
  mirror: true,
2521
2557
  displayMirror: false,
2558
+ compileMirror: true,
2522
2559
  Label: "\u2230",
2523
2560
  title: "\u062A\u0643\u0627\u0645\u0644 \u062D\u062C\u0645\u064A \u0645\u063A\u0644\u0642",
2524
2561
  svg_path: null
@@ -2528,8 +2565,9 @@ function shouldMirrorOperatorDisplay(command) {
2528
2565
  return command?.displayMirror ?? command?.mirror ?? false;
2529
2566
  }
2530
2567
  var MIRRORED_OPERATOR_TEX = Object.values(ATOMIC_OPERATOR_COMMANDS).filter((command) => command.mirror).map((command) => command.Tex).sort((a, b) => b.length - a.length);
2531
- function matchingMirroredOperator(tex, index) {
2532
- for (const operatorTex of MIRRORED_OPERATOR_TEX) {
2568
+ var COMPILE_MIRRORED_OPERATOR_TEX = Object.values(ATOMIC_OPERATOR_COMMANDS).filter((command) => "compileMirror" in command && command.compileMirror).map((command) => command.Tex).sort((a, b) => b.length - a.length);
2569
+ function matchingMirroredOperatorFrom(tex, index, operatorTexList) {
2570
+ for (const operatorTex of operatorTexList) {
2533
2571
  if (!tex.startsWith(operatorTex, index)) {
2534
2572
  continue;
2535
2573
  }
@@ -2560,19 +2598,26 @@ function findMatchingBrace(tex, openIndex) {
2560
2598
  }
2561
2599
  return -1;
2562
2600
  }
2563
- function mirrorBuTeXOperatorsInTex(tex) {
2601
+ function mirrorBuTeXOperatorsInTex(tex, options = {}) {
2602
+ const mirroredOperatorTex = options.target === "compile" ? COMPILE_MIRRORED_OPERATOR_TEX : MIRRORED_OPERATOR_TEX;
2564
2603
  let result = "";
2565
2604
  let index = 0;
2566
2605
  while (index < tex.length) {
2567
2606
  if (tex.startsWith("\\butexmirror{", index)) {
2568
2607
  const end = findMatchingBrace(tex, index + "\\butexmirror".length);
2569
2608
  if (end !== -1) {
2570
- result += tex.slice(index, end + 1);
2609
+ const bodyStart = index + "\\butexmirror{".length;
2610
+ const body = tex.slice(bodyStart, end);
2611
+ if (options.target === "compile" && MIRRORED_OPERATOR_TEX.includes(body) && !mirroredOperatorTex.includes(body)) {
2612
+ result += body;
2613
+ } else {
2614
+ result += tex.slice(index, end + 1);
2615
+ }
2571
2616
  index = end + 1;
2572
2617
  continue;
2573
2618
  }
2574
2619
  }
2575
- const operatorTex = matchingMirroredOperator(tex, index);
2620
+ const operatorTex = matchingMirroredOperatorFrom(tex, index, mirroredOperatorTex);
2576
2621
  if (operatorTex) {
2577
2622
  result += `\\butexmirror{${operatorTex}}`;
2578
2623
  index += operatorTex.length;
@@ -8234,18 +8279,19 @@ function mathNodeFromSession(session, opening = "$", closing = "$") {
8234
8279
  }
8235
8280
  return { nodeType: "MathObject", mathMode: opening, lines: [], closing };
8236
8281
  }
8237
- function mathTokenSourceForSide(token, side) {
8282
+ function mathTokenSourceForSide(token, side, digitForm) {
8238
8283
  if (!token.math || token.sourceOwner === "raw") {
8239
8284
  return token.source;
8240
8285
  }
8241
- if (token.sourceSide === side) {
8286
+ if (token.sourceSide === side && digitForm === void 0) {
8242
8287
  return token.source;
8243
8288
  }
8244
8289
  const result = mathTokenToEditorSession(token.math, side);
8245
8290
  if (!result.editable) {
8246
8291
  return token.source;
8247
8292
  }
8248
- return mathSourceFromSession(result.session, side, token.opening, token.closing);
8293
+ const session = digitForm === void 0 ? result.session : setCurrentDigitForm(result.session, digitForm);
8294
+ return mathSourceFromSession(session, side, token.opening, token.closing);
8249
8295
  }
8250
8296
 
8251
8297
  // src/document2/commands.ts
@@ -8979,6 +9025,19 @@ function document2KeyError(key, namespace = {}) {
8979
9025
  }
8980
9026
 
8981
9027
  // src/document2/arabicPreamble.ts
9028
+ function fontOptions(digitsMapping, includeScript = true) {
9029
+ const parts = [];
9030
+ if (includeScript) {
9031
+ parts.push("Script=Arabic");
9032
+ }
9033
+ if (digitsMapping !== "digits") {
9034
+ parts.push(`Mapping=${digitsMapping}`);
9035
+ }
9036
+ if (parts.length === 0) {
9037
+ return "";
9038
+ }
9039
+ return `[${parts.join(",")}]`;
9040
+ }
8982
9041
  function arabicXeLatexPreamblePkg(twocolumn = false) {
8983
9042
  const classOptions = twocolumn ? "12pt,a4paper,notitlepage,twocolumn" : "12pt,a4paper,notitlepage";
8984
9043
  return `
@@ -9007,25 +9066,27 @@ function arabicXeLatexPreamblePkg(twocolumn = false) {
9007
9066
  % save back tick for use - copy paste -> ` + "`";
9008
9067
  }
9009
9068
  function arabicXeLatexPreambleFont(digitsMapping = "arabicdigits") {
9010
- const customFonts = NON_DEFAULT_CHARACTER_FONT_SPECS.filter((font) => font.latexFontCommand && font.latexFontFamily).map((font) => `\\newfontfamily${font.latexFontCommand}[Script=Arabic,Mapping=${digitsMapping}]{${font.latexFontFamily}}`).join("\n");
9069
+ const customFonts = NON_DEFAULT_CHARACTER_FONT_SPECS.filter((font) => font.latexFontCommand && font.latexFontFamily).map((font) => `\\newfontfamily${font.latexFontCommand}${fontOptions(digitsMapping)}{${font.latexFontFamily}}`).join("\n");
9070
+ const mathFontOptions = fontOptions(digitsMapping, false);
9011
9071
  return `
9012
9072
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9013
9073
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9014
- % Toggle between eastern and western digits by changing the Mapping in the below fonts (inside math font as well) between "arabicdigits" and "digits"
9074
+ % Persian digits: Mapping=farsidigits
9075
+ % Arabic-Indic digits: Mapping=arabicdigits
9076
+ % Western digits: omit Mapping entirely
9015
9077
  \\setdefaultlanguage[calendar=gregorian]{arabic} % from polyglossia
9016
- \\setmainfont[Script=Arabic , Mapping=${digitsMapping}]{Amiri}
9078
+ \\setmainfont${fontOptions(digitsMapping)}{Amiri}
9017
9079
  ${customFonts}
9018
- \\newfontfamily\\boldarabic[Script=Arabic,Mapping=${digitsMapping}]{Amiri Bold}
9019
- \\newfontfamily\\italicarabic[Script=Arabic,Mapping=${digitsMapping}]{Amiri Italic}
9080
+ \\newfontfamily\\boldarabic${fontOptions(digitsMapping)}{Amiri Bold}
9081
+ \\newfontfamily\\italicarabic${fontOptions(digitsMapping)}{Amiri Italic}
9020
9082
 
9021
9083
  % for polyglossia url I dont know, sugggested by cursor
9022
- \\newfontfamily\\arabicfonttt[Script=Arabic,Mapping=${digitsMapping}]{Amiri}
9023
- \\newfontfamily\\arabicfontsf[Script=Arabic,Mapping=${digitsMapping}]{Amiri}
9084
+ \\newfontfamily\\arabicfonttt${fontOptions(digitsMapping)}{Amiri}
9085
+ \\newfontfamily\\arabicfontsf${fontOptions(digitsMapping)}{Amiri}
9024
9086
 
9025
9087
 
9026
9088
  % Explicitly set math font to XITS Math
9027
- % Remove "Script=Arabic" to cancel reflected symbols and other RTL symbols
9028
- \\setmathfont[Script=Arabic , Mapping=${digitsMapping}]{XITS Math} % Ensure XITS Math is correctly installed and available
9089
+ \\setmathfont${mathFontOptions}{XITS Math} % Ensure XITS Math is correctly installed and available
9029
9090
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9030
9091
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9031
9092
  `;
@@ -9187,8 +9248,20 @@ function getArabicXeLatexPreamble(digitsMappingOrOptions = "arabicdigits") {
9187
9248
  }
9188
9249
 
9189
9250
  // src/document2/exportLatex.ts
9251
+ function digitsMappingFromDigitForm(digitForm) {
9252
+ if (digitForm === "western") {
9253
+ return "digits";
9254
+ }
9255
+ if (digitForm === "persianIndic") {
9256
+ return "farsidigits";
9257
+ }
9258
+ return "arabicdigits";
9259
+ }
9190
9260
  function mathBodyLatex(token) {
9191
- if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
9261
+ if (token.sourceOwner === "editor") {
9262
+ return stripDisplayMathDelimiters(mirrorBuTeXOperatorsInTex(token.source, { target: "compile" }));
9263
+ }
9264
+ if (!token.math || token.sourceOwner === "raw") {
9192
9265
  return stripDisplayMathDelimiters(token.source);
9193
9266
  }
9194
9267
  const rendered = renderMathNodeLatex(token.math);
@@ -9224,7 +9297,10 @@ ${body}
9224
9297
  \\label{${token.label.trim()}}
9225
9298
  \\end{equation}`;
9226
9299
  }
9227
- if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
9300
+ if (token.sourceOwner === "editor") {
9301
+ return mirrorBuTeXOperatorsInTex(token.source, { target: "compile" });
9302
+ }
9303
+ if (!token.math || token.sourceOwner === "raw") {
9228
9304
  return token.source;
9229
9305
  }
9230
9306
  return renderMathNodeLatex(token.math);
@@ -9342,7 +9418,7 @@ function articleMaketitlePreamble(meta, twocolumn = false) {
9342
9418
  if (meta.authors.trim().length > 0) {
9343
9419
  parts.push(`\\author{${authorLatex(meta.authors)}}`);
9344
9420
  }
9345
- parts.push(`\\date{${formatHijriDate(meta.date, { locale: "ar", digitForm: "arabicIndic" })}}`);
9421
+ parts.push(`\\date{${formatHijriDate(meta.date, { locale: "ar", digitForm: "western" })}}`);
9346
9422
  return parts.join("\n");
9347
9423
  }
9348
9424
  function articleFrontMatterLatex(meta) {
@@ -9374,7 +9450,7 @@ function document2Latex(document2, options = {}) {
9374
9450
  ${body}` : body;
9375
9451
  }
9376
9452
  const preamble = getArabicXeLatexPreamble({
9377
- digitsMapping: options.digitsMapping ?? "arabicdigits",
9453
+ digitsMapping: options.digitsMapping ?? digitsMappingFromDigitForm(options.digitForm),
9378
9454
  twocolumn
9379
9455
  }) + "\n" + articleMaketitlePreamble(meta, twocolumn);
9380
9456
  return `${preamble}
@@ -9630,8 +9706,8 @@ function remapSelectionAfterRangeMove(selection, direction) {
9630
9706
  }
9631
9707
 
9632
9708
  // src/document2/previewModel.ts
9633
- function mathTex(token, equationSide) {
9634
- return mathTokenSourceForSide(token, equationSide);
9709
+ function mathTex(token, equationSide, digitForm) {
9710
+ return mathTokenSourceForSide(token, equationSide, digitForm);
9635
9711
  }
9636
9712
  function previewInlines(field, islands, output, equationSide, document2, previewOptions) {
9637
9713
  return field.tokens.map((token) => {
@@ -9663,7 +9739,7 @@ function previewInlines(field, islands, output, equationSide, document2, preview
9663
9739
  }
9664
9740
  const island = {
9665
9741
  id: token.id,
9666
- tex: mathTex(token, equationSide),
9742
+ tex: mathTex(token, equationSide, previewOptions.digitForm),
9667
9743
  display: token.display,
9668
9744
  output,
9669
9745
  editable: token.editable
@@ -10304,7 +10380,33 @@ function focusArticleMetaPanel(panel) {
10304
10380
  }
10305
10381
 
10306
10382
  // src/react-document2/ButexDocumentEditor2.tsx
10307
- import { useCallback as useCallback2, useEffect as useEffect9, useMemo as useMemo2, useRef as useRef8, useState as useState12 } from "react";
10383
+ import { forwardRef as forwardRef2, useCallback as useCallback2, useEffect as useEffect9, useImperativeHandle as useImperativeHandle2, useMemo as useMemo2, useRef as useRef8, useState as useState12 } from "react";
10384
+
10385
+ // src/debugJson.ts
10386
+ function lineColumnForPosition(text, position) {
10387
+ const before = text.slice(0, Math.max(0, position));
10388
+ const lines = before.split("\n");
10389
+ return {
10390
+ line: lines.length,
10391
+ column: (lines[lines.length - 1]?.length ?? 0) + 1
10392
+ };
10393
+ }
10394
+ function parseJsonDebugInput(text) {
10395
+ try {
10396
+ return { ok: true, value: JSON.parse(text) };
10397
+ } catch (error) {
10398
+ const message = error instanceof Error ? error.message : String(error);
10399
+ const positionMatch = message.match(/position\s+(\d+)/i);
10400
+ if (positionMatch) {
10401
+ const position = Number(positionMatch[1]);
10402
+ if (Number.isFinite(position)) {
10403
+ const location = lineColumnForPosition(text, position);
10404
+ return { ok: false, error: `Invalid JSON at line ${String(location.line)}, column ${String(location.column)}: ${message}` };
10405
+ }
10406
+ }
10407
+ return { ok: false, error: `Invalid JSON: ${message}` };
10408
+ }
10409
+ }
10308
10410
 
10309
10411
  // src/react-document2/BlockEditor.tsx
10310
10412
  import { useState as useState3 } from "react";
@@ -10845,6 +10947,7 @@ function MathChip({
10845
10947
  token,
10846
10948
  output = "svg",
10847
10949
  documentDirection = "rtl",
10950
+ digitForm,
10848
10951
  equationSide = "arabic",
10849
10952
  editable = true,
10850
10953
  uiLocale = "ar",
@@ -10856,7 +10959,7 @@ function MathChip({
10856
10959
  onTextInputFromFocus
10857
10960
  }) {
10858
10961
  const messages = document2Messages(uiLocale);
10859
- const tex = mathTokenSourceForSide(token, equationSide);
10962
+ const tex = mathTokenSourceForSide(token, equationSide, digitForm);
10860
10963
  const forwardArrowKey = documentDirection === "rtl" ? "ArrowLeft" : "ArrowRight";
10861
10964
  const backwardArrowKey = documentDirection === "rtl" ? "ArrowRight" : "ArrowLeft";
10862
10965
  const island = /* @__PURE__ */ jsx4(MathIsland, { id: token.id, tex, display: token.display, output });
@@ -11266,6 +11369,7 @@ function InlineField({
11266
11369
  token,
11267
11370
  output: mathOutput,
11268
11371
  equationSide,
11372
+ digitForm,
11269
11373
  editable: editableEquations,
11270
11374
  uiLocale,
11271
11375
  buttonRef: (element) => {
@@ -12817,6 +12921,11 @@ var WIDGET_CHROME_CSS = `
12817
12921
  font-family: ${BUTEX_DIWANI_OUTLINE_FONT_STACK};
12818
12922
  }
12819
12923
 
12924
+ .butex-widget .font-mode-btn--maghribi,
12925
+ .butex-widget .character-font-option--maghribi {
12926
+ font-family: ${BUTEX_MAGHRIBI_FONT_STACK};
12927
+ }
12928
+
12820
12929
  .butex-widget .character-font-options {
12821
12930
  position: absolute;
12822
12931
  z-index: 10;
@@ -13351,6 +13460,36 @@ var WIDGET_CHROME_CSS = `
13351
13460
  background: var(--butex-dev-inset-bg);
13352
13461
  color: var(--butex-dev-inset-fg);
13353
13462
  }
13463
+
13464
+ .butex-widget .debug-json-import {
13465
+ display: grid;
13466
+ gap: 8px;
13467
+ margin-bottom: 10px;
13468
+ }
13469
+
13470
+ .butex-widget .debug-json-import textarea {
13471
+ min-height: 150px;
13472
+ resize: vertical;
13473
+ border: 1px solid var(--butex-dev-inset-border);
13474
+ border-radius: 8px;
13475
+ padding: 8px 10px;
13476
+ direction: ltr;
13477
+ text-align: left;
13478
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
13479
+ font-size: 11px;
13480
+ background: var(--butex-dev-inset-bg);
13481
+ color: var(--butex-dev-inset-fg);
13482
+ }
13483
+
13484
+ .butex-widget .debug-json-error {
13485
+ margin: 0;
13486
+ border: 1px solid rgba(220, 38, 38, 0.45);
13487
+ background: rgba(254, 226, 226, 0.9);
13488
+ color: #991b1b;
13489
+ border-radius: 8px;
13490
+ padding: 8px 10px;
13491
+ white-space: pre-wrap;
13492
+ }
13354
13493
  `.trim();
13355
13494
  var CHROME_STYLE_ID = "butex-widget-chrome-css";
13356
13495
  function injectWidgetChromeCss(doc) {
@@ -13479,6 +13618,7 @@ ${latex || messages.empty}`;
13479
13618
  var ButexEditor = forwardRef(
13480
13619
  function ButexEditor2({ className, debug = false, defaultSide, uiLocale = "ar", initialSession, onSessionChange }, ref) {
13481
13620
  const messages = equationEditorMessages(uiLocale);
13621
+ const debugEnabled = debug || typeof window !== "undefined" && new URLSearchParams(window.location.search).get("debug") === "1";
13482
13622
  const wrapperRef = useRef6(null);
13483
13623
  const surfaceRef = useRef6(null);
13484
13624
  const inputRef = useRef6(null);
@@ -13496,7 +13636,7 @@ var ButexEditor = forwardRef(
13496
13636
  const digitFormBtnRef = useRef6(null);
13497
13637
  const runtimeRef = useRef6(null);
13498
13638
  const debugRef = useRef6(debug);
13499
- debugRef.current = debug;
13639
+ debugRef.current = debugEnabled;
13500
13640
  const uiLocaleRef = useRef6(uiLocale);
13501
13641
  uiLocaleRef.current = uiLocale;
13502
13642
  const onSessionChangeRef = useRef6(onSessionChange);
@@ -13504,6 +13644,9 @@ var ButexEditor = forwardRef(
13504
13644
  const debugBodyHiddenRef = useRef6(false);
13505
13645
  const [debugBodyHidden, setDebugBodyHidden] = useState7(false);
13506
13646
  debugBodyHiddenRef.current = debugBodyHidden;
13647
+ const [debugImportOpen, setDebugImportOpen] = useState7(false);
13648
+ const [debugImportText, setDebugImportText] = useState7("");
13649
+ const [debugImportError, setDebugImportError] = useState7("");
13507
13650
  const [digitMenuOpen, setDigitMenuOpen] = useState7(false);
13508
13651
  const [characterFontMenuOpen, setCharacterFontMenuOpen] = useState7(false);
13509
13652
  const [delimiterMenuOpen, setDelimiterMenuOpen] = useState7(false);
@@ -13584,6 +13727,54 @@ ${arabic || currentMessages.empty}`;
13584
13727
  }, []);
13585
13728
  const updatePreviewRef = useRef6(updatePreview);
13586
13729
  updatePreviewRef.current = updatePreview;
13730
+ async function copyDebugText(text) {
13731
+ try {
13732
+ await navigator.clipboard.writeText(text);
13733
+ } catch {
13734
+ }
13735
+ }
13736
+ function currentMathObjectJsonText() {
13737
+ const session = runtimeRef.current?.getSession();
13738
+ if (!session) {
13739
+ return "";
13740
+ }
13741
+ const math = mathNodeFromEditorSession(session);
13742
+ if (!math.ok) {
13743
+ return "";
13744
+ }
13745
+ return JSON.stringify(toMathObjectJson(math.math), null, 2);
13746
+ }
13747
+ function openDebugMathObjectImport() {
13748
+ setDebugImportText(currentMathObjectJsonText());
13749
+ setDebugImportError("");
13750
+ setDebugImportOpen(true);
13751
+ }
13752
+ function applyDebugMathObjectImport() {
13753
+ const parsed = parseJsonDebugInput(debugImportText);
13754
+ if (!parsed.ok) {
13755
+ setDebugImportError(parsed.error);
13756
+ return;
13757
+ }
13758
+ try {
13759
+ const math = fromMathObjectJson(parsed.value, activeEditorSide);
13760
+ const result = mathObjectToEditorSession(math);
13761
+ if (!result.editable) {
13762
+ setDebugImportError(result.reason);
13763
+ return;
13764
+ }
13765
+ const next = { ...result.session, activeSide: activeEditorSide };
13766
+ runtimeRef.current?.setSession(next);
13767
+ setSelectedDigitForm(next.currentDigitForm ?? "western");
13768
+ setSelectedCharacterFont(next.currentCharacterFont ?? "default");
13769
+ setActiveEditorSide(next.activeSide);
13770
+ onSessionChangeRef.current?.(next);
13771
+ setDebugImportError("");
13772
+ setDebugImportOpen(false);
13773
+ void updatePreviewRef.current(next);
13774
+ } catch (importError) {
13775
+ setDebugImportError(importError instanceof Error ? importError.message : String(importError));
13776
+ }
13777
+ }
13587
13778
  useEffect6(() => {
13588
13779
  injectWidgetChromeCss();
13589
13780
  injectBuTeXEditorStyles(typeof document !== "undefined" ? document : void 0);
@@ -14744,7 +14935,7 @@ ${arabic || currentMessages.empty}`;
14744
14935
  /* @__PURE__ */ jsx12("div", { ref: renderErrorRef, className: "error", hidden: true })
14745
14936
  ] }),
14746
14937
  /* @__PURE__ */ jsx12("section", { className: "panel panel-preview", "aria-label": messages.renderPreview, children: /* @__PURE__ */ jsx12("div", { ref: mathOutputRef, className: "preview-box" }) }),
14747
- debug ? /* @__PURE__ */ jsxs10("section", { className: "panel", children: [
14938
+ debugEnabled ? /* @__PURE__ */ jsxs10("section", { className: "panel", children: [
14748
14939
  /* @__PURE__ */ jsxs10("div", { className: "dev-strip", children: [
14749
14940
  /* @__PURE__ */ jsx12("span", { className: "dev-badge", children: messages.development }),
14750
14941
  /* @__PURE__ */ jsx12("div", { ref: latexLinesRef, className: "ascii" }),
@@ -14752,6 +14943,8 @@ ${arabic || currentMessages.empty}`;
14752
14943
  ] }),
14753
14944
  /* @__PURE__ */ jsxs10("div", { style: { marginTop: 12 }, children: [
14754
14945
  /* @__PURE__ */ jsxs10("div", { className: "debug-head", children: [
14946
+ /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => void copyDebugText(currentMathObjectJsonText()), children: "Copy MathObject JSON" }),
14947
+ /* @__PURE__ */ jsx12("button", { type: "button", "aria-expanded": debugImportOpen, onClick: openDebugMathObjectImport, children: "Import MathObject JSON" }),
14755
14948
  /* @__PURE__ */ jsx12(
14756
14949
  "button",
14757
14950
  {
@@ -14787,6 +14980,35 @@ ${arabic || currentMessages.empty}`;
14787
14980
  }
14788
14981
  )
14789
14982
  ] }),
14983
+ debugImportOpen ? /* @__PURE__ */ jsxs10("div", { className: "debug-json-import", children: [
14984
+ /* @__PURE__ */ jsx12(
14985
+ "textarea",
14986
+ {
14987
+ value: debugImportText,
14988
+ "aria-label": "Import MathObject JSON",
14989
+ spellCheck: false,
14990
+ onChange: (event) => {
14991
+ setDebugImportText(event.currentTarget.value);
14992
+ setDebugImportError("");
14993
+ }
14994
+ }
14995
+ ),
14996
+ /* @__PURE__ */ jsxs10("div", { className: "debug-head", children: [
14997
+ /* @__PURE__ */ jsx12("button", { type: "button", onClick: applyDebugMathObjectImport, children: "Apply" }),
14998
+ /* @__PURE__ */ jsx12(
14999
+ "button",
15000
+ {
15001
+ type: "button",
15002
+ onClick: () => {
15003
+ setDebugImportOpen(false);
15004
+ setDebugImportError("");
15005
+ },
15006
+ children: "Cancel"
15007
+ }
15008
+ )
15009
+ ] }),
15010
+ debugImportError ? /* @__PURE__ */ jsx12("p", { className: "debug-json-error", children: debugImportError }) : null
15011
+ ] }) : null,
14790
15012
  /* @__PURE__ */ jsx12("div", { ref: debugLogRef, className: "debug-log" })
14791
15013
  ] })
14792
15014
  ] }) : null
@@ -14812,6 +15034,7 @@ function keyErrorMessage2(error, messages) {
14812
15034
  return null;
14813
15035
  }
14814
15036
  function EquationDrawer({
15037
+ debug = false,
14815
15038
  session,
14816
15039
  reason,
14817
15040
  mathMode,
@@ -14929,7 +15152,7 @@ function EquationDrawer({
14929
15152
  /* @__PURE__ */ jsx13(
14930
15153
  ButexEditor,
14931
15154
  {
14932
- debug: false,
15155
+ debug,
14933
15156
  defaultSide: equationSide,
14934
15157
  uiLocale,
14935
15158
  initialSession: session,
@@ -16511,6 +16734,42 @@ var DOCUMENT2_WIDGET_CSS = `
16511
16734
  white-space: pre-wrap;
16512
16735
  }
16513
16736
 
16737
+ .butex-document2-widget__dev-actions {
16738
+ display: flex;
16739
+ flex-wrap: wrap;
16740
+ gap: 8px;
16741
+ margin: 0 0 10px;
16742
+ }
16743
+
16744
+ .butex-document2-widget__dev-import {
16745
+ display: grid;
16746
+ gap: 8px;
16747
+ margin-bottom: 12px;
16748
+ }
16749
+
16750
+ .butex-document2-widget__dev-import textarea {
16751
+ background: var(--butex-document2-dev-code-bg);
16752
+ border: 1px solid var(--butex-document2-dev-border);
16753
+ border-radius: 8px;
16754
+ color: var(--butex-document2-dev-code-fg);
16755
+ direction: ltr;
16756
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
16757
+ min-height: 180px;
16758
+ padding: 10px;
16759
+ resize: vertical;
16760
+ text-align: left;
16761
+ }
16762
+
16763
+ .butex-document2-widget__dev-error {
16764
+ background: rgba(254, 226, 226, 0.9);
16765
+ border: 1px solid rgba(220, 38, 38, 0.45);
16766
+ border-radius: 8px;
16767
+ color: #991b1b;
16768
+ margin: 0;
16769
+ padding: 8px 10px;
16770
+ white-space: pre-wrap;
16771
+ }
16772
+
16514
16773
  .butex-document2-widget__dev-diagnostic {
16515
16774
  background: rgba(251, 191, 36, 0.18);
16516
16775
  border: 1px solid rgba(217, 119, 6, 0.4);
@@ -17341,868 +17600,977 @@ function resolveInitialDocument2(initialDocument, uiLocale = "ar", documentMeta)
17341
17600
  };
17342
17601
  }
17343
17602
  }
17344
- function ButexDocumentEditor2({
17345
- initialDocument,
17346
- documentMeta,
17347
- className,
17348
- debug = false,
17349
- documentDirection = "rtl",
17350
- equationSide = "arabic",
17351
- editableEquations = true,
17352
- previewOnly = false,
17353
- uiLocale = "ar",
17354
- mathOutput = "svg",
17355
- digitForm: digitFormProp,
17356
- onDigitFormChange,
17357
- resolveImageUrl,
17358
- onDocumentChange,
17359
- onDocumentJsonChange,
17360
- onLatexChange
17361
- }) {
17362
- const messages = document2Messages(uiLocale);
17363
- const initialState = useMemo2(
17364
- () => resolveInitialDocument2(initialDocument, uiLocale, documentMeta),
17365
- [initialDocument, documentMeta, uiLocale]
17366
- );
17367
- const [documentNode, setDocumentNode] = useState12(initialState.document);
17368
- const [error, setError] = useState12(initialState.error);
17369
- const [editorOpen, setEditorOpen] = useState12(true);
17370
- const [previewOpen, setPreviewOpen] = useState12(true);
17371
- const [selectedMath, setSelectedMath] = useState12(null);
17372
- const [citePicker, setCitePicker] = useState12(null);
17373
- const [referencesOpen, setReferencesOpen] = useState12(false);
17374
- const [labelsOpen, setLabelsOpen] = useState12(false);
17375
- const [refPicker, setRefPicker] = useState12(null);
17376
- const [digitFormState, setDigitFormState] = useState12(null);
17377
- const [editorFocus, setEditorFocus] = useState12(createEmptyDocument2EditorFocus());
17378
- const [collapsedBlockIds, setCollapsedBlockIds] = useState12(() => /* @__PURE__ */ new Set());
17379
- const [blockSelectionState, setBlockSelectionState] = useState12(emptyBlockSelection);
17380
- const [historyTick, setHistoryTick] = useState12(0);
17381
- const digitForm = digitFormProp ?? digitFormState ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
17382
- const historyRef = useRef8(createDocument2History());
17383
- const documentRef = useRef8(documentNode);
17384
- const textSnapshotArmedRef = useRef8(false);
17385
- const textDebounceRef = useRef8(null);
17386
- const widgetRef = useRef8(null);
17387
- const articleMetaPanelRef = useRef8(null);
17388
- const pendingFocusRef = useRef8(null);
17389
- documentRef.current = documentNode;
17390
- const latex = document2Latex(documentNode);
17391
- const documentJson = useMemo2(() => toDocumentJson2(documentNode), [documentNode]);
17392
- const documentLabels = useMemo2(() => collectDocument2Labels(documentNode), [documentNode]);
17393
- const preview = useMemo2(
17394
- () => document2Preview(documentNode, mathOutput, equationSide, {
17395
- documentDirection,
17396
- digitForm,
17397
- uiLocale
17398
- }),
17399
- [documentNode, documentDirection, digitForm, equationSide, mathOutput, uiLocale]
17400
- );
17401
- const debugEnabled = useMemo2(() => {
17402
- if (debug) {
17403
- return true;
17404
- }
17405
- if (typeof window === "undefined") {
17406
- return false;
17407
- }
17408
- return new URLSearchParams(window.location.search).get("debug") === "1";
17409
- }, [debug]);
17410
- const canUndo = useMemo2(() => document2HistoryCanUndo(historyRef.current), [historyTick, documentNode]);
17411
- const canRedo = useMemo2(() => document2HistoryCanRedo(historyRef.current), [historyTick, documentNode]);
17412
- const blockSelection = normalizeBlockSelection(blockSelectionState.selection, documentNode.blocks.length);
17413
- const selectionCount = blockSelection ? blockSelection.to - blockSelection.from + 1 : 0;
17414
- const canMoveSelectionUp = Boolean(blockSelection && blockSelection.from > 0);
17415
- const canMoveSelectionDown = Boolean(blockSelection && blockSelection.to < documentNode.blocks.length - 1);
17416
- const formatTextToken = useMemo2(() => findFormatTextToken(documentNode, editorFocus), [documentNode, editorFocus]);
17417
- const canFormatText = formatTextToken !== null;
17418
- const activeTextStyles = formatTextToken?.style ?? {};
17419
- function clearBlockSelection() {
17420
- setBlockSelectionState(emptyBlockSelection());
17421
- }
17422
- function toggleSelectBlock(blockId, shiftKey) {
17423
- const index = documentRef.current.blocks.findIndex((block) => block.id === blockId);
17424
- if (index < 0) {
17425
- return;
17426
- }
17427
- const blockCount = documentRef.current.blocks.length;
17428
- setBlockSelectionState(
17429
- (current) => shiftKey ? extendBlockSelectionFromAnchor(current, index, blockCount) : toggleBlockInSelection(current, index, blockCount)
17603
+ var ButexDocumentEditor2 = forwardRef2(
17604
+ function ButexDocumentEditor22({
17605
+ initialDocument,
17606
+ documentMeta,
17607
+ className,
17608
+ debug = false,
17609
+ documentDirection = "rtl",
17610
+ equationSide = "arabic",
17611
+ editableEquations = true,
17612
+ previewOnly = false,
17613
+ uiLocale = "ar",
17614
+ mathOutput = "svg",
17615
+ digitForm: digitFormProp,
17616
+ onDigitFormChange,
17617
+ resolveImageUrl,
17618
+ onDocumentChange,
17619
+ onDocumentJsonChange,
17620
+ onLatexChange
17621
+ }, ref) {
17622
+ const messages = document2Messages(uiLocale);
17623
+ const initialState = useMemo2(
17624
+ () => resolveInitialDocument2(initialDocument, uiLocale, documentMeta),
17625
+ [initialDocument, documentMeta, uiLocale]
17430
17626
  );
17431
- }
17432
- function moveSelectedBlocks(direction) {
17433
- const selection = normalizeBlockSelection(blockSelectionState.selection, documentRef.current.blocks.length);
17434
- if (!selection) {
17435
- return;
17627
+ const [documentNode, setDocumentNode] = useState12(initialState.document);
17628
+ const [error, setError] = useState12(initialState.error);
17629
+ const [editorOpen, setEditorOpen] = useState12(true);
17630
+ const [previewOpen, setPreviewOpen] = useState12(true);
17631
+ const [selectedMath, setSelectedMath] = useState12(null);
17632
+ const [citePicker, setCitePicker] = useState12(null);
17633
+ const [referencesOpen, setReferencesOpen] = useState12(false);
17634
+ const [labelsOpen, setLabelsOpen] = useState12(false);
17635
+ const [refPicker, setRefPicker] = useState12(null);
17636
+ const [digitFormState, setDigitFormState] = useState12(null);
17637
+ const [debugImportOpen, setDebugImportOpen] = useState12(false);
17638
+ const [debugImportText, setDebugImportText] = useState12("");
17639
+ const [debugImportError, setDebugImportError] = useState12("");
17640
+ const [editorFocus, setEditorFocus] = useState12(createEmptyDocument2EditorFocus());
17641
+ const [collapsedBlockIds, setCollapsedBlockIds] = useState12(() => /* @__PURE__ */ new Set());
17642
+ const [blockSelectionState, setBlockSelectionState] = useState12(emptyBlockSelection);
17643
+ const [historyTick, setHistoryTick] = useState12(0);
17644
+ const digitForm = digitFormProp ?? digitFormState ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
17645
+ function equationSessionWithDocumentDigits(session) {
17646
+ return setCurrentDigitForm(session, digitForm);
17647
+ }
17648
+ const historyRef = useRef8(createDocument2History());
17649
+ const documentRef = useRef8(documentNode);
17650
+ const editorFocusRef = useRef8(editorFocus);
17651
+ const textSnapshotArmedRef = useRef8(false);
17652
+ const textDebounceRef = useRef8(null);
17653
+ const widgetRef = useRef8(null);
17654
+ const articleMetaPanelRef = useRef8(null);
17655
+ const pendingFocusRef = useRef8(null);
17656
+ documentRef.current = documentNode;
17657
+ editorFocusRef.current = editorFocus;
17658
+ const latex = document2Latex(documentNode, { digitForm });
17659
+ const documentJson = useMemo2(() => toDocumentJson2(documentNode), [documentNode]);
17660
+ const documentLabels = useMemo2(() => collectDocument2Labels(documentNode), [documentNode]);
17661
+ const preview = useMemo2(
17662
+ () => document2Preview(documentNode, mathOutput, equationSide, {
17663
+ documentDirection,
17664
+ digitForm,
17665
+ uiLocale
17666
+ }),
17667
+ [documentNode, documentDirection, digitForm, equationSide, mathOutput, uiLocale]
17668
+ );
17669
+ const debugEnabled = useMemo2(() => {
17670
+ if (debug) {
17671
+ return true;
17672
+ }
17673
+ if (typeof window === "undefined") {
17674
+ return false;
17675
+ }
17676
+ return new URLSearchParams(window.location.search).get("debug") === "1";
17677
+ }, [debug]);
17678
+ const canUndo = useMemo2(() => document2HistoryCanUndo(historyRef.current), [historyTick, documentNode]);
17679
+ const canRedo = useMemo2(() => document2HistoryCanRedo(historyRef.current), [historyTick, documentNode]);
17680
+ const blockSelection = normalizeBlockSelection(blockSelectionState.selection, documentNode.blocks.length);
17681
+ const selectionCount = blockSelection ? blockSelection.to - blockSelection.from + 1 : 0;
17682
+ const canMoveSelectionUp = Boolean(blockSelection && blockSelection.from > 0);
17683
+ const canMoveSelectionDown = Boolean(blockSelection && blockSelection.to < documentNode.blocks.length - 1);
17684
+ const formatTextToken = useMemo2(() => findFormatTextToken(documentNode, editorFocus), [documentNode, editorFocus]);
17685
+ const canFormatText = formatTextToken !== null;
17686
+ const activeTextStyles = formatTextToken?.style ?? {};
17687
+ function clearBlockSelection() {
17688
+ setBlockSelectionState(emptyBlockSelection());
17689
+ }
17690
+ function toggleSelectBlock(blockId, shiftKey) {
17691
+ const index = documentRef.current.blocks.findIndex((block) => block.id === blockId);
17692
+ if (index < 0) {
17693
+ return;
17694
+ }
17695
+ const blockCount = documentRef.current.blocks.length;
17696
+ setBlockSelectionState(
17697
+ (current) => shiftKey ? extendBlockSelectionFromAnchor(current, index, blockCount) : toggleBlockInSelection(current, index, blockCount)
17698
+ );
17436
17699
  }
17437
- const next = moveDocument2BlockRange(documentRef.current, selection.from, selection.to, direction);
17438
- if (next === documentRef.current) {
17439
- return;
17700
+ function moveSelectedBlocks(direction) {
17701
+ const selection = normalizeBlockSelection(blockSelectionState.selection, documentRef.current.blocks.length);
17702
+ if (!selection) {
17703
+ return;
17704
+ }
17705
+ const next = moveDocument2BlockRange(documentRef.current, selection.from, selection.to, direction);
17706
+ if (next === documentRef.current) {
17707
+ return;
17708
+ }
17709
+ applyDocument(next, "immediate");
17710
+ const remapped = remapSelectionAfterRangeMove(selection, direction);
17711
+ setBlockSelectionState({
17712
+ selection: normalizeBlockSelection(remapped, next.blocks.length),
17713
+ anchor: blockSelectionState.anchor === null ? null : blockSelectionState.anchor + direction
17714
+ });
17440
17715
  }
17441
- applyDocument(next, "immediate");
17442
- const remapped = remapSelectionAfterRangeMove(selection, direction);
17443
- setBlockSelectionState({
17444
- selection: normalizeBlockSelection(remapped, next.blocks.length),
17445
- anchor: blockSelectionState.anchor === null ? null : blockSelectionState.anchor + direction
17446
- });
17447
- }
17448
- function deleteSelectedBlocks() {
17449
- const selection = normalizeBlockSelection(blockSelectionState.selection, documentRef.current.blocks.length);
17450
- if (!selection) {
17451
- return;
17716
+ function deleteSelectedBlocks() {
17717
+ const selection = normalizeBlockSelection(blockSelectionState.selection, documentRef.current.blocks.length);
17718
+ if (!selection) {
17719
+ return;
17720
+ }
17721
+ applyDocument(removeDocument2BlockRange(documentRef.current, selection.from, selection.to), "immediate");
17722
+ clearBlockSelection();
17452
17723
  }
17453
- applyDocument(removeDocument2BlockRange(documentRef.current, selection.from, selection.to), "immediate");
17454
- clearBlockSelection();
17455
- }
17456
- useEffect9(() => {
17457
- injectBuTeXDocument2Styles();
17458
- }, []);
17459
- useEffect9(() => {
17460
- if (!editableEquations || previewOnly) {
17724
+ useEffect9(() => {
17725
+ injectBuTeXDocument2Styles();
17726
+ }, []);
17727
+ useEffect9(() => {
17728
+ if (!editableEquations || previewOnly) {
17729
+ setSelectedMath(null);
17730
+ }
17731
+ }, [editableEquations, previewOnly]);
17732
+ useEffect9(() => {
17733
+ const next = resolveInitialDocument2(initialDocument, uiLocale, documentMeta);
17734
+ setDocumentNode(next.document);
17735
+ setError(next.error);
17461
17736
  setSelectedMath(null);
17462
- }
17463
- }, [editableEquations, previewOnly]);
17464
- useEffect9(() => {
17465
- const next = resolveInitialDocument2(initialDocument, uiLocale, documentMeta);
17466
- setDocumentNode(next.document);
17467
- setError(next.error);
17468
- setSelectedMath(null);
17469
- setCollapsedBlockIds(/* @__PURE__ */ new Set());
17470
- historyRef.current = createDocument2History();
17471
- setHistoryTick((tick) => tick + 1);
17472
- }, [initialDocument, documentMeta, uiLocale]);
17473
- useEffect9(() => {
17474
- onDocumentChange?.(documentNode);
17475
- }, [documentNode, onDocumentChange]);
17476
- useEffect9(() => {
17477
- onDocumentJsonChange?.(documentJson);
17478
- }, [documentJson, onDocumentJsonChange]);
17479
- useEffect9(() => {
17480
- onLatexChange?.(latex);
17481
- }, [latex, onLatexChange]);
17482
- useEffect9(() => {
17483
- const pending = pendingFocusRef.current;
17484
- const root = widgetRef.current;
17485
- if (!pending || !root) {
17486
- return;
17487
- }
17488
- pendingFocusRef.current = null;
17489
- requestAnimationFrame(() => {
17490
- if (pending.kind === "math") {
17491
- const mathButton = Array.from(root.querySelectorAll("[data-math-token-id]")).find(
17492
- (button) => button.dataset.mathTokenId === pending.tokenId
17493
- );
17494
- mathButton?.focus();
17737
+ setCollapsedBlockIds(/* @__PURE__ */ new Set());
17738
+ historyRef.current = createDocument2History();
17739
+ setHistoryTick((tick) => tick + 1);
17740
+ }, [initialDocument, documentMeta, uiLocale]);
17741
+ useEffect9(() => {
17742
+ onDocumentChange?.(documentNode);
17743
+ }, [documentNode, onDocumentChange]);
17744
+ useEffect9(() => {
17745
+ onDocumentJsonChange?.(documentJson);
17746
+ }, [documentJson, onDocumentJsonChange]);
17747
+ useEffect9(() => {
17748
+ onLatexChange?.(latex);
17749
+ }, [latex, onLatexChange]);
17750
+ useEffect9(() => {
17751
+ const pending = pendingFocusRef.current;
17752
+ const root = widgetRef.current;
17753
+ if (!pending || !root) {
17495
17754
  return;
17496
17755
  }
17497
- if (pending.kind === "cite") {
17498
- const citeButton = Array.from(root.querySelectorAll("[data-cite-token-id]")).find(
17499
- (button) => button.dataset.citeTokenId === pending.tokenId
17756
+ pendingFocusRef.current = null;
17757
+ requestAnimationFrame(() => {
17758
+ if (pending.kind === "math") {
17759
+ const mathButton = Array.from(root.querySelectorAll("[data-math-token-id]")).find(
17760
+ (button) => button.dataset.mathTokenId === pending.tokenId
17761
+ );
17762
+ mathButton?.focus();
17763
+ return;
17764
+ }
17765
+ if (pending.kind === "cite") {
17766
+ const citeButton = Array.from(root.querySelectorAll("[data-cite-token-id]")).find(
17767
+ (button) => button.dataset.citeTokenId === pending.tokenId
17768
+ );
17769
+ citeButton?.focus();
17770
+ return;
17771
+ }
17772
+ if (pending.kind === "ref") {
17773
+ const refButton = Array.from(root.querySelectorAll("[data-ref-token-id]")).find(
17774
+ (button) => button.dataset.refTokenId === pending.tokenId
17775
+ );
17776
+ refButton?.focus();
17777
+ return;
17778
+ }
17779
+ const textarea = Array.from(root.querySelectorAll("textarea[data-field-id][data-text-token-id]")).find(
17780
+ (element) => element.dataset.fieldId === pending.fieldId && element.dataset.textTokenId === pending.textTokenId
17500
17781
  );
17501
- citeButton?.focus();
17782
+ if (!textarea) {
17783
+ return;
17784
+ }
17785
+ const safeOffset = Math.max(0, Math.min(pending.caretOffset, textarea.value.length));
17786
+ textarea.focus();
17787
+ textarea.setSelectionRange(safeOffset, safeOffset);
17788
+ });
17789
+ }, [documentNode]);
17790
+ const bumpHistoryUi = useCallback2(() => {
17791
+ setHistoryTick((tick) => tick + 1);
17792
+ }, []);
17793
+ const applyDocument = useCallback2(
17794
+ (next, mode = "immediate") => {
17795
+ if (mode === "immediate") {
17796
+ pushDocument2Snapshot(historyRef.current, documentRef.current);
17797
+ bumpHistoryUi();
17798
+ } else if (mode === "text") {
17799
+ if (!textSnapshotArmedRef.current) {
17800
+ pushDocument2Snapshot(historyRef.current, documentRef.current);
17801
+ textSnapshotArmedRef.current = true;
17802
+ bumpHistoryUi();
17803
+ }
17804
+ if (textDebounceRef.current !== null) {
17805
+ window.clearTimeout(textDebounceRef.current);
17806
+ }
17807
+ textDebounceRef.current = window.setTimeout(() => {
17808
+ textSnapshotArmedRef.current = false;
17809
+ }, 400);
17810
+ }
17811
+ documentRef.current = next;
17812
+ setDocumentNode(next);
17813
+ },
17814
+ [bumpHistoryUi]
17815
+ );
17816
+ const afterBlockId = useCallback2(() => resolveInsertAfterBlockId(documentRef.current, editorFocusRef.current), []);
17817
+ const insertImageBlock = useCallback2(
17818
+ (srcOrAssetId = "") => {
17819
+ clearBlockSelection();
17820
+ const after = resolveInsertAfterBlockId(documentRef.current, editorFocusRef.current);
17821
+ applyDocument(addDocument2ImageBlock(documentRef.current, srcOrAssetId, after), "immediate");
17822
+ },
17823
+ [applyDocument]
17824
+ );
17825
+ useImperativeHandle2(
17826
+ ref,
17827
+ () => ({
17828
+ insertImageBlock,
17829
+ updateImageBlockValue(blockId, value) {
17830
+ applyDocument(updateDocument2ImageValue(documentRef.current, blockId, value), "immediate");
17831
+ },
17832
+ getDocumentJson() {
17833
+ return toDocumentJson2(documentRef.current);
17834
+ }
17835
+ }),
17836
+ [applyDocument, insertImageBlock]
17837
+ );
17838
+ function undoDocument() {
17839
+ const restored = restoreDocument2Undo(historyRef.current, documentRef.current);
17840
+ if (!restored) {
17502
17841
  return;
17503
17842
  }
17504
- if (pending.kind === "ref") {
17505
- const refButton = Array.from(root.querySelectorAll("[data-ref-token-id]")).find(
17506
- (button) => button.dataset.refTokenId === pending.tokenId
17507
- );
17508
- refButton?.focus();
17843
+ textSnapshotArmedRef.current = false;
17844
+ clearBlockSelection();
17845
+ documentRef.current = restored;
17846
+ setDocumentNode(restored);
17847
+ bumpHistoryUi();
17848
+ }
17849
+ function redoDocument() {
17850
+ const restored = restoreDocument2Redo(historyRef.current, documentRef.current);
17851
+ if (!restored) {
17509
17852
  return;
17510
17853
  }
17511
- const textarea = Array.from(root.querySelectorAll("textarea[data-field-id][data-text-token-id]")).find(
17512
- (element) => element.dataset.fieldId === pending.fieldId && element.dataset.textTokenId === pending.textTokenId
17513
- );
17514
- if (!textarea) {
17854
+ textSnapshotArmedRef.current = false;
17855
+ clearBlockSelection();
17856
+ documentRef.current = restored;
17857
+ setDocumentNode(restored);
17858
+ bumpHistoryUi();
17859
+ }
17860
+ function openBlock(blockId) {
17861
+ if (!blockId) {
17515
17862
  return;
17516
17863
  }
17517
- const safeOffset = Math.max(0, Math.min(pending.caretOffset, textarea.value.length));
17518
- textarea.focus();
17519
- textarea.setSelectionRange(safeOffset, safeOffset);
17520
- });
17521
- }, [documentNode]);
17522
- const bumpHistoryUi = useCallback2(() => {
17523
- setHistoryTick((tick) => tick + 1);
17524
- }, []);
17525
- const applyDocument = useCallback2(
17526
- (next, mode = "immediate") => {
17527
- if (mode === "immediate") {
17528
- pushDocument2Snapshot(historyRef.current, documentRef.current);
17529
- bumpHistoryUi();
17530
- } else if (mode === "text") {
17531
- if (!textSnapshotArmedRef.current) {
17532
- pushDocument2Snapshot(historyRef.current, documentRef.current);
17533
- textSnapshotArmedRef.current = true;
17534
- bumpHistoryUi();
17864
+ setCollapsedBlockIds((current) => {
17865
+ if (!current.has(blockId)) {
17866
+ return current;
17535
17867
  }
17536
- if (textDebounceRef.current !== null) {
17537
- window.clearTimeout(textDebounceRef.current);
17868
+ const next = new Set(current);
17869
+ next.delete(blockId);
17870
+ return next;
17871
+ });
17872
+ }
17873
+ function toggleBlockCollapse(blockId) {
17874
+ setCollapsedBlockIds((current) => {
17875
+ const next = new Set(current);
17876
+ if (next.has(blockId)) {
17877
+ next.delete(blockId);
17878
+ } else {
17879
+ next.add(blockId);
17538
17880
  }
17539
- textDebounceRef.current = window.setTimeout(() => {
17540
- textSnapshotArmedRef.current = false;
17541
- }, 400);
17542
- }
17543
- setDocumentNode(next);
17544
- },
17545
- [bumpHistoryUi]
17546
- );
17547
- const afterBlockId = useCallback2(() => resolveInsertAfterBlockId(documentRef.current, editorFocus), [editorFocus]);
17548
- function undoDocument() {
17549
- const restored = restoreDocument2Undo(historyRef.current, documentRef.current);
17550
- if (!restored) {
17551
- return;
17881
+ return next;
17882
+ });
17552
17883
  }
17553
- textSnapshotArmedRef.current = false;
17554
- clearBlockSelection();
17555
- setDocumentNode(restored);
17556
- bumpHistoryUi();
17557
- }
17558
- function redoDocument() {
17559
- const restored = restoreDocument2Redo(historyRef.current, documentRef.current);
17560
- if (!restored) {
17561
- return;
17884
+ function collapseAllBlocks() {
17885
+ setCollapsedBlockIds(new Set(documentRef.current.blocks.map((block) => block.id)));
17562
17886
  }
17563
- textSnapshotArmedRef.current = false;
17564
- clearBlockSelection();
17565
- setDocumentNode(restored);
17566
- bumpHistoryUi();
17567
- }
17568
- function openBlock(blockId) {
17569
- if (!blockId) {
17570
- return;
17887
+ function openAllBlocks() {
17888
+ setCollapsedBlockIds(/* @__PURE__ */ new Set());
17571
17889
  }
17572
- setCollapsedBlockIds((current) => {
17573
- if (!current.has(blockId)) {
17574
- return current;
17890
+ async function copyDebugText(text) {
17891
+ try {
17892
+ await navigator.clipboard.writeText(text);
17893
+ } catch {
17575
17894
  }
17576
- const next = new Set(current);
17577
- next.delete(blockId);
17578
- return next;
17579
- });
17580
- }
17581
- function toggleBlockCollapse(blockId) {
17582
- setCollapsedBlockIds((current) => {
17583
- const next = new Set(current);
17584
- if (next.has(blockId)) {
17585
- next.delete(blockId);
17586
- } else {
17587
- next.add(blockId);
17895
+ }
17896
+ function openDebugJsonImport() {
17897
+ setDebugImportText(JSON.stringify(documentJson, null, 2));
17898
+ setDebugImportError("");
17899
+ setDebugImportOpen(true);
17900
+ }
17901
+ function applyDebugJsonImport() {
17902
+ const parsed = parseJsonDebugInput(debugImportText);
17903
+ if (!parsed.ok) {
17904
+ setDebugImportError(parsed.error);
17905
+ return;
17906
+ }
17907
+ try {
17908
+ const imported = fromDocumentJson2(parsed.value);
17909
+ textSnapshotArmedRef.current = false;
17910
+ if (textDebounceRef.current !== null) {
17911
+ window.clearTimeout(textDebounceRef.current);
17912
+ textDebounceRef.current = null;
17913
+ }
17914
+ setDocumentNode(imported);
17915
+ setError(null);
17916
+ setSelectedMath(null);
17917
+ setCitePicker(null);
17918
+ setRefPicker(null);
17919
+ clearBlockSelection();
17920
+ setCollapsedBlockIds(/* @__PURE__ */ new Set());
17921
+ setEditorFocus(createEmptyDocument2EditorFocus());
17922
+ historyRef.current = createDocument2History();
17923
+ bumpHistoryUi();
17924
+ setDebugImportError("");
17925
+ setDebugImportOpen(false);
17926
+ } catch (importError) {
17927
+ setDebugImportError(importError instanceof Error ? importError.message : String(importError));
17588
17928
  }
17589
- return next;
17590
- });
17591
- }
17592
- function collapseAllBlocks() {
17593
- setCollapsedBlockIds(new Set(documentRef.current.blocks.map((block) => block.id)));
17594
- }
17595
- function openAllBlocks() {
17596
- setCollapsedBlockIds(/* @__PURE__ */ new Set());
17597
- }
17598
- useEffect9(() => {
17599
- const root = widgetRef.current;
17600
- if (!root) {
17601
- return;
17602
17929
  }
17603
- const onKeyDown = (event) => {
17604
- if (!editorOpen) {
17930
+ useEffect9(() => {
17931
+ const root = widgetRef.current;
17932
+ if (!root) {
17605
17933
  return;
17606
17934
  }
17607
- const mod = event.ctrlKey || event.metaKey;
17608
- if (!mod) {
17935
+ const onKeyDown = (event) => {
17936
+ if (!editorOpen) {
17937
+ return;
17938
+ }
17939
+ const mod = event.ctrlKey || event.metaKey;
17940
+ if (!mod) {
17941
+ return;
17942
+ }
17943
+ if (event.key.toLowerCase() === "z" && !event.shiftKey) {
17944
+ event.preventDefault();
17945
+ undoDocument();
17946
+ } else if (event.key.toLowerCase() === "z" && event.shiftKey || event.key.toLowerCase() === "y") {
17947
+ event.preventDefault();
17948
+ redoDocument();
17949
+ }
17950
+ };
17951
+ root.addEventListener("keydown", onKeyDown);
17952
+ return () => root.removeEventListener("keydown", onKeyDown);
17953
+ }, [editorOpen]);
17954
+ function rememberFieldFocus(blockId, fieldId, textTokenId, caretOffset, selectionStart, selectionEnd) {
17955
+ openBlock(blockId);
17956
+ clearBlockSelection();
17957
+ setEditorFocus({ blockId, fieldId, textTokenId, caretOffset, selectionStart, selectionEnd });
17958
+ }
17959
+ function rememberMathFocus(blockId, fieldId) {
17960
+ openBlock(blockId);
17961
+ clearBlockSelection();
17962
+ setEditorFocus({ blockId, fieldId, textTokenId: null, caretOffset: 0, selectionStart: 0, selectionEnd: 0 });
17963
+ }
17964
+ function rememberBlockFocus(blockId) {
17965
+ openBlock(blockId);
17966
+ setEditorFocus((current) => ({ ...current, blockId }));
17967
+ }
17968
+ function onFieldBlur() {
17969
+ textSnapshotArmedRef.current = false;
17970
+ }
17971
+ function openNewEquation(mode) {
17972
+ if (!editableEquations) {
17609
17973
  return;
17610
17974
  }
17611
- if (event.key.toLowerCase() === "z" && !event.shiftKey) {
17612
- event.preventDefault();
17613
- undoDocument();
17614
- } else if (event.key.toLowerCase() === "z" && event.shiftKey || event.key.toLowerCase() === "y") {
17615
- event.preventDefault();
17616
- redoDocument();
17975
+ const target = resolveInsertField(documentRef.current, editorFocus);
17976
+ if (target?.fieldId) {
17977
+ openBlock(topLevelBlockIdForField(documentRef.current, target.fieldId));
17617
17978
  }
17618
- };
17619
- root.addEventListener("keydown", onKeyDown);
17620
- return () => root.removeEventListener("keydown", onKeyDown);
17621
- }, [editorOpen]);
17622
- function rememberFieldFocus(blockId, fieldId, textTokenId, caretOffset, selectionStart, selectionEnd) {
17623
- openBlock(blockId);
17624
- clearBlockSelection();
17625
- setEditorFocus({ blockId, fieldId, textTokenId, caretOffset, selectionStart, selectionEnd });
17626
- }
17627
- function rememberMathFocus(blockId, fieldId) {
17628
- openBlock(blockId);
17629
- clearBlockSelection();
17630
- setEditorFocus({ blockId, fieldId, textTokenId: null, caretOffset: 0, selectionStart: 0, selectionEnd: 0 });
17631
- }
17632
- function rememberBlockFocus(blockId) {
17633
- openBlock(blockId);
17634
- setEditorFocus((current) => ({ ...current, blockId }));
17635
- }
17636
- function onFieldBlur() {
17637
- textSnapshotArmedRef.current = false;
17638
- }
17639
- function openNewEquation(mode) {
17640
- if (!editableEquations) {
17641
- return;
17642
- }
17643
- const target = resolveInsertField(documentRef.current, editorFocus);
17644
- if (target?.fieldId) {
17645
- openBlock(topLevelBlockIdForField(documentRef.current, target.fieldId));
17646
- }
17647
- setSelectedMath({
17648
- tokenId: null,
17649
- fieldId: target?.fieldId ?? null,
17650
- textTokenId: target?.textTokenId ?? null,
17651
- insertAt: target?.caretOffset ?? 0,
17652
- mathMode: mode,
17653
- session: createEmptyEquationSession(equationSide),
17654
- reason: null,
17655
- labelEnabled: false,
17656
- label: ""
17657
- });
17658
- }
17659
- function openMath(token) {
17660
- if (!editableEquations) {
17661
- return;
17979
+ setSelectedMath({
17980
+ tokenId: null,
17981
+ fieldId: target?.fieldId ?? null,
17982
+ textTokenId: target?.textTokenId ?? null,
17983
+ insertAt: target?.caretOffset ?? 0,
17984
+ mathMode: mode,
17985
+ session: equationSessionWithDocumentDigits(createEmptyEquationSession(equationSide)),
17986
+ reason: null,
17987
+ labelEnabled: false,
17988
+ label: ""
17989
+ });
17662
17990
  }
17663
- openBlock(topLevelBlockIdForToken(documentRef.current, token.id));
17664
- const result = mathTokenToEditorSession(token.math, equationSide);
17665
- const mode = token.display ? "display" : "inline";
17666
- if (!result.editable) {
17991
+ function openMath(token) {
17992
+ if (!editableEquations) {
17993
+ return;
17994
+ }
17995
+ openBlock(topLevelBlockIdForToken(documentRef.current, token.id));
17996
+ const result = mathTokenToEditorSession(token.math, equationSide);
17997
+ const mode = token.display ? "display" : "inline";
17998
+ if (!result.editable) {
17999
+ setSelectedMath({
18000
+ tokenId: token.id,
18001
+ fieldId: null,
18002
+ insertAt: 0,
18003
+ textTokenId: null,
18004
+ mathMode: mode,
18005
+ session: equationSessionWithDocumentDigits(createEmptyEquationSession(equationSide)),
18006
+ reason: result.reason,
18007
+ labelEnabled: Boolean(token.labelEnabled),
18008
+ label: token.label ?? ""
18009
+ });
18010
+ return;
18011
+ }
17667
18012
  setSelectedMath({
17668
18013
  tokenId: token.id,
17669
18014
  fieldId: null,
17670
18015
  insertAt: 0,
17671
18016
  textTokenId: null,
17672
18017
  mathMode: mode,
17673
- session: createEmptyEquationSession(equationSide),
17674
- reason: result.reason,
18018
+ session: equationSessionWithDocumentDigits(result.session),
18019
+ reason: null,
17675
18020
  labelEnabled: Boolean(token.labelEnabled),
17676
18021
  label: token.label ?? ""
17677
18022
  });
17678
- return;
17679
18023
  }
17680
- setSelectedMath({
17681
- tokenId: token.id,
17682
- fieldId: null,
17683
- insertAt: 0,
17684
- textTokenId: null,
17685
- mathMode: mode,
17686
- session: result.session,
17687
- reason: null,
17688
- labelEnabled: Boolean(token.labelEnabled),
17689
- label: token.label ?? ""
17690
- });
17691
- }
17692
- function toggleEditorPanel() {
17693
- setEditorOpen((open) => {
17694
- if (open && !previewOpen) {
17695
- setPreviewOpen(true);
18024
+ function toggleEditorPanel() {
18025
+ setEditorOpen((open) => {
18026
+ if (open && !previewOpen) {
18027
+ setPreviewOpen(true);
18028
+ }
18029
+ return !open;
18030
+ });
18031
+ }
18032
+ function togglePreviewPanel() {
18033
+ setPreviewOpen((open) => {
18034
+ if (open && !editorOpen) {
18035
+ setEditorOpen(true);
18036
+ }
18037
+ return !open;
18038
+ });
18039
+ }
18040
+ function saveEquation(session) {
18041
+ if (!selectedMath) {
18042
+ return;
17696
18043
  }
17697
- return !open;
17698
- });
17699
- }
17700
- function togglePreviewPanel() {
17701
- setPreviewOpen((open) => {
17702
- if (open && !editorOpen) {
17703
- setEditorOpen(true);
18044
+ const delimiters = mathDelimiters(selectedMath.mathMode);
18045
+ if (selectedMath.tokenId) {
18046
+ let next2 = replaceMathTokenFromSession(
18047
+ documentRef.current,
18048
+ selectedMath.tokenId,
18049
+ session,
18050
+ delimiters.opening,
18051
+ delimiters.closing,
18052
+ equationSide
18053
+ );
18054
+ if (selectedMath.mathMode === "display") {
18055
+ next2 = updateMathTokenLabel(next2, selectedMath.tokenId, {
18056
+ labelEnabled: selectedMath.labelEnabled,
18057
+ label: selectedMath.label
18058
+ });
18059
+ } else {
18060
+ next2 = updateMathTokenLabel(next2, selectedMath.tokenId, { labelEnabled: false, label: "" });
18061
+ }
18062
+ pendingFocusRef.current = { kind: "math", tokenId: selectedMath.tokenId };
18063
+ applyDocument(next2, "immediate");
18064
+ setSelectedMath(null);
18065
+ return;
17704
18066
  }
17705
- return !open;
17706
- });
17707
- }
17708
- function saveEquation(session) {
17709
- if (!selectedMath) {
17710
- return;
17711
- }
17712
- const delimiters = mathDelimiters(selectedMath.mathMode);
17713
- if (selectedMath.tokenId) {
17714
- let next2 = replaceMathTokenFromSession(
17715
- documentRef.current,
17716
- selectedMath.tokenId,
18067
+ let current = documentRef.current;
18068
+ let fieldId = selectedMath.fieldId;
18069
+ let textTokenId = selectedMath.textTokenId;
18070
+ let insertAt = selectedMath.insertAt;
18071
+ if (!fieldId) {
18072
+ const anchor = afterBlockId();
18073
+ current = addDocument2TextBlock(current, "\\paragraph", anchor);
18074
+ const anchorIndex = anchor ? current.blocks.findIndex((block) => block.id === anchor) : -1;
18075
+ const newIndex = anchorIndex >= 0 ? anchorIndex + 1 : current.blocks.length - 1;
18076
+ const newBlock = current.blocks[newIndex];
18077
+ const field = newBlock?.kind === "textBlock" ? newBlock.field : null;
18078
+ if (!field) {
18079
+ setSelectedMath(null);
18080
+ return;
18081
+ }
18082
+ fieldId = field.id;
18083
+ textTokenId = field.tokens.find((token) => token.kind === "text")?.id ?? null;
18084
+ insertAt = 0;
18085
+ }
18086
+ let next = insertMathTokenAtCaret(
18087
+ current,
18088
+ fieldId,
18089
+ textTokenId,
18090
+ insertAt,
17717
18091
  session,
17718
18092
  delimiters.opening,
17719
18093
  delimiters.closing,
17720
18094
  equationSide
17721
18095
  );
17722
- if (selectedMath.mathMode === "display") {
17723
- next2 = updateMathTokenLabel(next2, selectedMath.tokenId, {
17724
- labelEnabled: selectedMath.labelEnabled,
18096
+ const trailingTextTokenId = trailingTextTokenAfterInsertedMath(current, next, fieldId, textTokenId, insertAt);
18097
+ const fieldAfter = findInlineFieldById(next, fieldId);
18098
+ const insertedMathId = trailingTextTokenId && fieldAfter ? fieldAfter.tokens[Math.max(
18099
+ 0,
18100
+ fieldAfter.tokens.findIndex((token) => token.id === trailingTextTokenId) - 1
18101
+ )]?.kind === "math" ? fieldAfter.tokens[Math.max(
18102
+ 0,
18103
+ fieldAfter.tokens.findIndex((token) => token.id === trailingTextTokenId) - 1
18104
+ )]?.id : null : fieldAfter?.tokens.filter((token) => token.kind === "math").at(-1)?.id ?? null;
18105
+ if (insertedMathId && selectedMath.mathMode === "display" && selectedMath.labelEnabled) {
18106
+ next = updateMathTokenLabel(next, insertedMathId, {
18107
+ labelEnabled: true,
17725
18108
  label: selectedMath.label
17726
18109
  });
17727
- } else {
17728
- next2 = updateMathTokenLabel(next2, selectedMath.tokenId, { labelEnabled: false, label: "" });
17729
18110
  }
17730
- pendingFocusRef.current = { kind: "math", tokenId: selectedMath.tokenId };
17731
- applyDocument(next2, "immediate");
18111
+ if (trailingTextTokenId) {
18112
+ pendingFocusRef.current = { kind: "text", fieldId, textTokenId: trailingTextTokenId, caretOffset: 0 };
18113
+ }
18114
+ applyDocument(next, "immediate");
17732
18115
  setSelectedMath(null);
17733
- return;
17734
18116
  }
17735
- let current = documentRef.current;
17736
- let fieldId = selectedMath.fieldId;
17737
- let textTokenId = selectedMath.textTokenId;
17738
- let insertAt = selectedMath.insertAt;
17739
- if (!fieldId) {
17740
- const anchor = afterBlockId();
17741
- current = addDocument2TextBlock(current, "\\paragraph", anchor);
17742
- const anchorIndex = anchor ? current.blocks.findIndex((block) => block.id === anchor) : -1;
17743
- const newIndex = anchorIndex >= 0 ? anchorIndex + 1 : current.blocks.length - 1;
17744
- const newBlock = current.blocks[newIndex];
17745
- const field = newBlock?.kind === "textBlock" ? newBlock.field : null;
17746
- if (!field) {
17747
- setSelectedMath(null);
18117
+ function deleteSelectedEquation() {
18118
+ if (!selectedMath?.tokenId) {
17748
18119
  return;
17749
18120
  }
17750
- fieldId = field.id;
17751
- textTokenId = field.tokens.find((token) => token.kind === "text")?.id ?? null;
17752
- insertAt = 0;
17753
- }
17754
- let next = insertMathTokenAtCaret(
17755
- current,
17756
- fieldId,
17757
- textTokenId,
17758
- insertAt,
17759
- session,
17760
- delimiters.opening,
17761
- delimiters.closing,
17762
- equationSide
17763
- );
17764
- const trailingTextTokenId = trailingTextTokenAfterInsertedMath(current, next, fieldId, textTokenId, insertAt);
17765
- const fieldAfter = findInlineFieldById(next, fieldId);
17766
- const insertedMathId = trailingTextTokenId && fieldAfter ? fieldAfter.tokens[Math.max(
17767
- 0,
17768
- fieldAfter.tokens.findIndex((token) => token.id === trailingTextTokenId) - 1
17769
- )]?.kind === "math" ? fieldAfter.tokens[Math.max(
17770
- 0,
17771
- fieldAfter.tokens.findIndex((token) => token.id === trailingTextTokenId) - 1
17772
- )]?.id : null : fieldAfter?.tokens.filter((token) => token.kind === "math").at(-1)?.id ?? null;
17773
- if (insertedMathId && selectedMath.mathMode === "display" && selectedMath.labelEnabled) {
17774
- next = updateMathTokenLabel(next, insertedMathId, {
17775
- labelEnabled: true,
17776
- label: selectedMath.label
17777
- });
17778
- }
17779
- if (trailingTextTokenId) {
17780
- pendingFocusRef.current = { kind: "text", fieldId, textTokenId: trailingTextTokenId, caretOffset: 0 };
18121
+ const current = documentRef.current;
18122
+ const next = removeMathTokenById(current, selectedMath.tokenId);
18123
+ pendingFocusRef.current = focusAfterDeletedMath(current, next, selectedMath.tokenId);
18124
+ applyDocument(next, "immediate");
18125
+ setSelectedMath(null);
17781
18126
  }
17782
- applyDocument(next, "immediate");
17783
- setSelectedMath(null);
17784
- }
17785
- function deleteSelectedEquation() {
17786
- if (!selectedMath?.tokenId) {
17787
- return;
18127
+ function deleteMathToken(tokenId) {
18128
+ const current = documentRef.current;
18129
+ const next = removeMathTokenById(current, tokenId);
18130
+ pendingFocusRef.current = focusAfterDeletedMath(current, next, tokenId);
18131
+ applyDocument(next, "immediate");
18132
+ }
18133
+ function openCitePickerForInsert() {
18134
+ const target = resolveInsertField(documentRef.current, editorFocus);
18135
+ setCitePicker({
18136
+ tokenId: null,
18137
+ fieldId: target?.fieldId ?? null,
18138
+ textTokenId: target?.textTokenId ?? editorFocus.textTokenId,
18139
+ caretOffset: target?.caretOffset ?? editorFocus.caretOffset,
18140
+ keys: []
18141
+ });
17788
18142
  }
17789
- const current = documentRef.current;
17790
- const next = removeMathTokenById(current, selectedMath.tokenId);
17791
- pendingFocusRef.current = focusAfterDeletedMath(current, next, selectedMath.tokenId);
17792
- applyDocument(next, "immediate");
17793
- setSelectedMath(null);
17794
- }
17795
- function deleteMathToken(tokenId) {
17796
- const current = documentRef.current;
17797
- const next = removeMathTokenById(current, tokenId);
17798
- pendingFocusRef.current = focusAfterDeletedMath(current, next, tokenId);
17799
- applyDocument(next, "immediate");
17800
- }
17801
- function openCitePickerForInsert() {
17802
- const target = resolveInsertField(documentRef.current, editorFocus);
17803
- setCitePicker({
17804
- tokenId: null,
17805
- fieldId: target?.fieldId ?? null,
17806
- textTokenId: target?.textTokenId ?? editorFocus.textTokenId,
17807
- caretOffset: target?.caretOffset ?? editorFocus.caretOffset,
17808
- keys: []
17809
- });
17810
- }
17811
- function openCite(token) {
17812
- setCitePicker({
17813
- tokenId: token.id,
17814
- fieldId: null,
17815
- textTokenId: null,
17816
- caretOffset: 0,
17817
- keys: [...token.keys]
17818
- });
17819
- }
17820
- function confirmCiteKeys(keys) {
17821
- if (!citePicker || keys.length === 0) {
17822
- setCitePicker(null);
17823
- return;
18143
+ function openCite(token) {
18144
+ setCitePicker({
18145
+ tokenId: token.id,
18146
+ fieldId: null,
18147
+ textTokenId: null,
18148
+ caretOffset: 0,
18149
+ keys: [...token.keys]
18150
+ });
17824
18151
  }
17825
- if (citePicker.tokenId) {
17826
- applyDocument(updateCiteTokenKeys(documentRef.current, citePicker.tokenId, keys), "immediate");
17827
- pendingFocusRef.current = { kind: "cite", tokenId: citePicker.tokenId };
18152
+ function confirmCiteKeys(keys) {
18153
+ if (!citePicker || keys.length === 0) {
18154
+ setCitePicker(null);
18155
+ return;
18156
+ }
18157
+ if (citePicker.tokenId) {
18158
+ applyDocument(updateCiteTokenKeys(documentRef.current, citePicker.tokenId, keys), "immediate");
18159
+ pendingFocusRef.current = { kind: "cite", tokenId: citePicker.tokenId };
18160
+ setCitePicker(null);
18161
+ return;
18162
+ }
18163
+ const target = resolveInsertField(documentRef.current, editorFocus);
18164
+ const fieldId = citePicker.fieldId ?? target?.fieldId;
18165
+ if (!fieldId) {
18166
+ setCitePicker(null);
18167
+ return;
18168
+ }
18169
+ const textTokenId = citePicker.textTokenId ?? target?.textTokenId ?? null;
18170
+ const caretOffset = citePicker.caretOffset ?? target?.caretOffset ?? 0;
18171
+ const next = insertCiteTokenAtCaret(documentRef.current, fieldId, textTokenId, caretOffset, keys);
18172
+ applyDocument(next, "immediate");
17828
18173
  setCitePicker(null);
17829
- return;
17830
18174
  }
17831
- const target = resolveInsertField(documentRef.current, editorFocus);
17832
- const fieldId = citePicker.fieldId ?? target?.fieldId;
17833
- if (!fieldId) {
17834
- setCitePicker(null);
17835
- return;
18175
+ function deleteCiteToken(tokenId) {
18176
+ applyDocument(removeCiteTokenById(documentRef.current, tokenId), "immediate");
18177
+ }
18178
+ function openRefPickerForInsert() {
18179
+ const target = resolveInsertField(documentRef.current, editorFocus);
18180
+ setRefPicker({
18181
+ tokenId: null,
18182
+ fieldId: target?.fieldId ?? null,
18183
+ textTokenId: target?.textTokenId ?? editorFocus.textTokenId,
18184
+ caretOffset: target?.caretOffset ?? editorFocus.caretOffset,
18185
+ keys: [],
18186
+ refCommand: "ref"
18187
+ });
17836
18188
  }
17837
- const textTokenId = citePicker.textTokenId ?? target?.textTokenId ?? null;
17838
- const caretOffset = citePicker.caretOffset ?? target?.caretOffset ?? 0;
17839
- const next = insertCiteTokenAtCaret(documentRef.current, fieldId, textTokenId, caretOffset, keys);
17840
- applyDocument(next, "immediate");
17841
- setCitePicker(null);
17842
- }
17843
- function deleteCiteToken(tokenId) {
17844
- applyDocument(removeCiteTokenById(documentRef.current, tokenId), "immediate");
17845
- }
17846
- function openRefPickerForInsert() {
17847
- const target = resolveInsertField(documentRef.current, editorFocus);
17848
- setRefPicker({
17849
- tokenId: null,
17850
- fieldId: target?.fieldId ?? null,
17851
- textTokenId: target?.textTokenId ?? editorFocus.textTokenId,
17852
- caretOffset: target?.caretOffset ?? editorFocus.caretOffset,
17853
- keys: [],
17854
- refCommand: "ref"
17855
- });
17856
- }
17857
- function openRef(token) {
17858
- setRefPicker({
17859
- tokenId: token.id,
17860
- fieldId: null,
17861
- textTokenId: null,
17862
- caretOffset: 0,
17863
- keys: [...token.keys],
17864
- refCommand: token.refCommand
17865
- });
17866
- }
17867
- function confirmRefKeys(keys, refCommand) {
17868
- if (!refPicker || keys.length === 0) {
17869
- setRefPicker(null);
17870
- return;
18189
+ function openRef(token) {
18190
+ setRefPicker({
18191
+ tokenId: token.id,
18192
+ fieldId: null,
18193
+ textTokenId: null,
18194
+ caretOffset: 0,
18195
+ keys: [...token.keys],
18196
+ refCommand: token.refCommand
18197
+ });
17871
18198
  }
17872
- if (refPicker.tokenId) {
17873
- applyDocument(updateRefTokenKeys(documentRef.current, refPicker.tokenId, keys, refCommand), "immediate");
17874
- pendingFocusRef.current = { kind: "ref", tokenId: refPicker.tokenId };
18199
+ function confirmRefKeys(keys, refCommand) {
18200
+ if (!refPicker || keys.length === 0) {
18201
+ setRefPicker(null);
18202
+ return;
18203
+ }
18204
+ if (refPicker.tokenId) {
18205
+ applyDocument(updateRefTokenKeys(documentRef.current, refPicker.tokenId, keys, refCommand), "immediate");
18206
+ pendingFocusRef.current = { kind: "ref", tokenId: refPicker.tokenId };
18207
+ setRefPicker(null);
18208
+ return;
18209
+ }
18210
+ const target = resolveInsertField(documentRef.current, editorFocus);
18211
+ const fieldId = refPicker.fieldId ?? target?.fieldId;
18212
+ if (!fieldId) {
18213
+ setRefPicker(null);
18214
+ return;
18215
+ }
18216
+ const textTokenId = refPicker.textTokenId ?? target?.textTokenId ?? null;
18217
+ const caretOffset = refPicker.caretOffset ?? target?.caretOffset ?? 0;
18218
+ const next = insertRefTokenAtCaret(documentRef.current, fieldId, textTokenId, caretOffset, keys, refCommand);
18219
+ applyDocument(next, "immediate");
17875
18220
  setRefPicker(null);
17876
- return;
17877
18221
  }
17878
- const target = resolveInsertField(documentRef.current, editorFocus);
17879
- const fieldId = refPicker.fieldId ?? target?.fieldId;
17880
- if (!fieldId) {
17881
- setRefPicker(null);
17882
- return;
18222
+ function deleteRefToken(tokenId) {
18223
+ applyDocument(removeRefTokenById(documentRef.current, tokenId), "immediate");
17883
18224
  }
17884
- const textTokenId = refPicker.textTokenId ?? target?.textTokenId ?? null;
17885
- const caretOffset = refPicker.caretOffset ?? target?.caretOffset ?? 0;
17886
- const next = insertRefTokenAtCaret(documentRef.current, fieldId, textTokenId, caretOffset, keys, refCommand);
17887
- applyDocument(next, "immediate");
17888
- setRefPicker(null);
17889
- }
17890
- function deleteRefToken(tokenId) {
17891
- applyDocument(removeRefTokenById(documentRef.current, tokenId), "immediate");
17892
- }
17893
- function toggleInlineTextStyle(styleName) {
17894
- if (!canFormatText || !editorFocus.fieldId || !editorFocus.textTokenId) {
17895
- return;
18225
+ function toggleInlineTextStyle(styleName) {
18226
+ if (!canFormatText || !editorFocus.fieldId || !editorFocus.textTokenId) {
18227
+ return;
18228
+ }
18229
+ applyDocument(
18230
+ toggleTextTokenStyle(
18231
+ documentRef.current,
18232
+ editorFocus.fieldId,
18233
+ editorFocus.textTokenId,
18234
+ editorFocus.selectionStart,
18235
+ editorFocus.selectionEnd,
18236
+ styleName
18237
+ ),
18238
+ "immediate"
18239
+ );
17896
18240
  }
17897
- applyDocument(
17898
- toggleTextTokenStyle(
17899
- documentRef.current,
17900
- editorFocus.fieldId,
17901
- editorFocus.textTokenId,
17902
- editorFocus.selectionStart,
17903
- editorFocus.selectionEnd,
17904
- styleName
17905
- ),
17906
- "immediate"
17907
- );
17908
- }
17909
- const showEditorPanel = !previewOnly && editorOpen;
17910
- const showPreviewPanel = previewOnly || previewOpen;
17911
- return /* @__PURE__ */ jsx17(
17912
- "div",
17913
- {
17914
- ref: widgetRef,
17915
- className: ["butex-document2-widget", className].filter(Boolean).join(" "),
17916
- dir: uiLocaleDirection(uiLocale),
17917
- lang: uiLocale,
17918
- children: /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__shell", children: [
17919
- !previewOnly ? /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__toolbar", children: [
17920
- /* @__PURE__ */ jsx17(
17921
- DocumentInsertToolbar,
17922
- {
17923
- canUndo,
17924
- canRedo,
17925
- editableEquations,
17926
- uiLocale,
17927
- digitForm,
17928
- selectionCount,
17929
- canMoveSelectionUp,
17930
- canMoveSelectionDown,
17931
- canFormatText,
17932
- activeTextStyles,
17933
- onUndo: undoDocument,
17934
- onRedo: redoDocument,
17935
- onToggleTextStyle: toggleInlineTextStyle,
17936
- onMoveSelectionUp: () => moveSelectedBlocks(-1),
17937
- onMoveSelectionDown: () => moveSelectedBlocks(1),
17938
- onDeleteSelection: deleteSelectedBlocks,
17939
- onAddSection: () => {
17940
- clearBlockSelection();
17941
- applyDocument(addDocument2TextBlock(documentRef.current, "\\section", afterBlockId()), "immediate");
17942
- },
17943
- onAddSubsection: () => {
17944
- clearBlockSelection();
17945
- applyDocument(addDocument2TextBlock(documentRef.current, "\\subsection", afterBlockId()), "immediate");
17946
- },
17947
- onAddSubsubsection: () => {
17948
- clearBlockSelection();
17949
- applyDocument(addDocument2TextBlock(documentRef.current, "\\subsubsection", afterBlockId()), "immediate");
17950
- },
17951
- onAddParagraph: () => {
17952
- clearBlockSelection();
17953
- applyDocument(addDocument2TextBlock(documentRef.current, "\\paragraph", afterBlockId()), "immediate");
17954
- },
17955
- onAddInlineEquation: () => openNewEquation("inline"),
17956
- onAddDisplayEquation: () => openNewEquation("display"),
17957
- onAddTable: (rowCount, colCount) => {
17958
- clearBlockSelection();
17959
- applyDocument(addDocument2TableBlock(documentRef.current, "l".repeat(colCount), rowCount, colCount, afterBlockId()), "immediate");
17960
- },
17961
- onAddList: () => {
17962
- clearBlockSelection();
17963
- applyDocument(addDocument2ListBlock(documentRef.current, false, afterBlockId()), "immediate");
17964
- },
17965
- onAddEnumerate: () => {
17966
- clearBlockSelection();
17967
- applyDocument(addDocument2ListBlock(documentRef.current, true, afterBlockId()), "immediate");
17968
- },
17969
- onAddFigure: () => {
17970
- clearBlockSelection();
17971
- applyDocument(addDocument2ImageBlock(documentRef.current, "", afterBlockId()), "immediate");
17972
- },
17973
- onInsertCitation: openCitePickerForInsert,
17974
- onInsertInternalRef: openRefPickerForInsert,
17975
- onInsertBibliography: () => {
17976
- clearBlockSelection();
17977
- applyDocument(ensureDocument2BibliographyBlock(documentRef.current, afterBlockId()), "immediate");
17978
- },
17979
- onManageReferences: () => setReferencesOpen(true),
17980
- onManageLabels: () => setLabelsOpen(true),
17981
- onOpenArticleMeta: () => focusArticleMetaPanel(articleMetaPanelRef.current),
17982
- onDigitFormChange: (next) => {
17983
- setDigitFormState(next);
17984
- onDigitFormChange?.(next);
18241
+ const showEditorPanel = !previewOnly && editorOpen;
18242
+ const showPreviewPanel = previewOnly || previewOpen;
18243
+ return /* @__PURE__ */ jsx17(
18244
+ "div",
18245
+ {
18246
+ ref: widgetRef,
18247
+ className: ["butex-document2-widget", className].filter(Boolean).join(" "),
18248
+ dir: uiLocaleDirection(uiLocale),
18249
+ lang: uiLocale,
18250
+ children: /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__shell", children: [
18251
+ !previewOnly ? /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__toolbar", children: [
18252
+ /* @__PURE__ */ jsx17(
18253
+ DocumentInsertToolbar,
18254
+ {
18255
+ canUndo,
18256
+ canRedo,
18257
+ editableEquations,
18258
+ uiLocale,
18259
+ digitForm,
18260
+ selectionCount,
18261
+ canMoveSelectionUp,
18262
+ canMoveSelectionDown,
18263
+ canFormatText,
18264
+ activeTextStyles,
18265
+ onUndo: undoDocument,
18266
+ onRedo: redoDocument,
18267
+ onToggleTextStyle: toggleInlineTextStyle,
18268
+ onMoveSelectionUp: () => moveSelectedBlocks(-1),
18269
+ onMoveSelectionDown: () => moveSelectedBlocks(1),
18270
+ onDeleteSelection: deleteSelectedBlocks,
18271
+ onAddSection: () => {
18272
+ clearBlockSelection();
18273
+ applyDocument(addDocument2TextBlock(documentRef.current, "\\section", afterBlockId()), "immediate");
18274
+ },
18275
+ onAddSubsection: () => {
18276
+ clearBlockSelection();
18277
+ applyDocument(addDocument2TextBlock(documentRef.current, "\\subsection", afterBlockId()), "immediate");
18278
+ },
18279
+ onAddSubsubsection: () => {
18280
+ clearBlockSelection();
18281
+ applyDocument(addDocument2TextBlock(documentRef.current, "\\subsubsection", afterBlockId()), "immediate");
18282
+ },
18283
+ onAddParagraph: () => {
18284
+ clearBlockSelection();
18285
+ applyDocument(addDocument2TextBlock(documentRef.current, "\\paragraph", afterBlockId()), "immediate");
18286
+ },
18287
+ onAddInlineEquation: () => openNewEquation("inline"),
18288
+ onAddDisplayEquation: () => openNewEquation("display"),
18289
+ onAddTable: (rowCount, colCount) => {
18290
+ clearBlockSelection();
18291
+ applyDocument(addDocument2TableBlock(documentRef.current, "l".repeat(colCount), rowCount, colCount, afterBlockId()), "immediate");
18292
+ },
18293
+ onAddList: () => {
18294
+ clearBlockSelection();
18295
+ applyDocument(addDocument2ListBlock(documentRef.current, false, afterBlockId()), "immediate");
18296
+ },
18297
+ onAddEnumerate: () => {
18298
+ clearBlockSelection();
18299
+ applyDocument(addDocument2ListBlock(documentRef.current, true, afterBlockId()), "immediate");
18300
+ },
18301
+ onAddFigure: () => insertImageBlock(""),
18302
+ onInsertCitation: openCitePickerForInsert,
18303
+ onInsertInternalRef: openRefPickerForInsert,
18304
+ onInsertBibliography: () => {
18305
+ clearBlockSelection();
18306
+ applyDocument(ensureDocument2BibliographyBlock(documentRef.current, afterBlockId()), "immediate");
18307
+ },
18308
+ onManageReferences: () => setReferencesOpen(true),
18309
+ onManageLabels: () => setLabelsOpen(true),
18310
+ onOpenArticleMeta: () => focusArticleMetaPanel(articleMetaPanelRef.current),
18311
+ onDigitFormChange: (next) => {
18312
+ setDigitFormState(next);
18313
+ onDigitFormChange?.(next);
18314
+ }
17985
18315
  }
17986
- }
17987
- ),
17988
- /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.panels, children: [
17989
- /* @__PURE__ */ jsx17("button", { type: "button", "aria-pressed": editorOpen, onClick: toggleEditorPanel, children: editorOpen ? messages.hideEditor : messages.editor }),
17990
- /* @__PURE__ */ jsx17("button", { type: "button", "aria-pressed": previewOpen, onClick: togglePreviewPanel, children: previewOpen ? messages.hidePreview : messages.preview })
17991
- ] }),
17992
- /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.collapseBlocks, children: [
17993
- /* @__PURE__ */ jsx17("button", { type: "button", onClick: collapseAllBlocks, children: messages.collapseAll }),
17994
- /* @__PURE__ */ jsx17("button", { type: "button", onClick: openAllBlocks, children: messages.openAll })
17995
- ] })
17996
- ] }) : null,
17997
- error ? /* @__PURE__ */ jsx17("p", { className: "butex-document2-widget__error", children: error }) : null,
17998
- /* @__PURE__ */ jsxs15(
17999
- "div",
18000
- {
18001
- className: `butex-document2-widget__layout butex-document2-widget__layout--editor-${showEditorPanel ? "open" : "closed"} butex-document2-widget__layout--preview-${showPreviewPanel ? "open" : "closed"}`,
18002
- children: [
18003
- !previewOnly ? /* @__PURE__ */ jsx17(
18004
- "section",
18005
- {
18006
- className: "butex-document2-widget__panel butex-document2-widget__editor-panel",
18007
- "aria-label": messages.documentEditor,
18008
- "aria-hidden": !showEditorPanel,
18009
- children: /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__blocks", children: [
18010
- /* @__PURE__ */ jsx17(
18011
- ArticleMetaPanel,
18012
- {
18013
- meta: documentNode.meta ?? emptyDocument2Meta(),
18014
- uiLocale,
18015
- digitForm,
18016
- panelRef: articleMetaPanelRef,
18017
- onChange: (patch) => {
18018
- clearBlockSelection();
18019
- applyDocument(updateDocument2Meta(documentRef.current, patch), "text");
18316
+ ),
18317
+ /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.panels, children: [
18318
+ /* @__PURE__ */ jsx17("button", { type: "button", "aria-pressed": editorOpen, onClick: toggleEditorPanel, children: editorOpen ? messages.hideEditor : messages.editor }),
18319
+ /* @__PURE__ */ jsx17("button", { type: "button", "aria-pressed": previewOpen, onClick: togglePreviewPanel, children: previewOpen ? messages.hidePreview : messages.preview })
18320
+ ] }),
18321
+ /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__toolbar-group", role: "group", "aria-label": messages.collapseBlocks, children: [
18322
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: collapseAllBlocks, children: messages.collapseAll }),
18323
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: openAllBlocks, children: messages.openAll })
18324
+ ] })
18325
+ ] }) : null,
18326
+ error ? /* @__PURE__ */ jsx17("p", { className: "butex-document2-widget__error", children: error }) : null,
18327
+ /* @__PURE__ */ jsxs15(
18328
+ "div",
18329
+ {
18330
+ className: `butex-document2-widget__layout butex-document2-widget__layout--editor-${showEditorPanel ? "open" : "closed"} butex-document2-widget__layout--preview-${showPreviewPanel ? "open" : "closed"}`,
18331
+ children: [
18332
+ !previewOnly ? /* @__PURE__ */ jsx17(
18333
+ "section",
18334
+ {
18335
+ className: "butex-document2-widget__panel butex-document2-widget__editor-panel",
18336
+ "aria-label": messages.documentEditor,
18337
+ "aria-hidden": !showEditorPanel,
18338
+ children: /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__blocks", children: [
18339
+ /* @__PURE__ */ jsx17(
18340
+ ArticleMetaPanel,
18341
+ {
18342
+ meta: documentNode.meta ?? emptyDocument2Meta(),
18343
+ uiLocale,
18344
+ digitForm,
18345
+ panelRef: articleMetaPanelRef,
18346
+ onChange: (patch) => {
18347
+ clearBlockSelection();
18348
+ applyDocument(updateDocument2Meta(documentRef.current, patch), "text");
18349
+ }
18020
18350
  }
18021
- }
18022
- ),
18023
- documentNode.blocks.map((block, blockIndex) => /* @__PURE__ */ jsx17(
18024
- BlockEditor,
18351
+ ),
18352
+ documentNode.blocks.map((block, blockIndex) => /* @__PURE__ */ jsx17(
18353
+ BlockEditor,
18354
+ {
18355
+ block,
18356
+ references: documentNode.references,
18357
+ documentNode,
18358
+ documentDirection,
18359
+ digitForm,
18360
+ mathOutput,
18361
+ equationSide,
18362
+ editableEquations,
18363
+ editableCitations: !previewOnly,
18364
+ uiLocale,
18365
+ isCollapsed: collapsedBlockIds.has(block.id),
18366
+ selected: Boolean(blockSelection && blockIndex >= blockSelection.from && blockIndex <= blockSelection.to),
18367
+ onToggleSelect: toggleSelectBlock,
18368
+ onTextChange: (fieldId, tokenId, text) => {
18369
+ clearBlockSelection();
18370
+ applyDocument(updateTextToken(documentRef.current, fieldId, tokenId, text), "text");
18371
+ },
18372
+ onOpenMath: openMath,
18373
+ onDeleteMath: editableEquations ? deleteMathToken : void 0,
18374
+ onOpenCite: openCite,
18375
+ onDeleteCite: deleteCiteToken,
18376
+ onOpenRef: openRef,
18377
+ onDeleteRef: deleteRefToken,
18378
+ onToggleCollapse: toggleBlockCollapse,
18379
+ onBlockFocus: rememberBlockFocus,
18380
+ onFieldFocus: rememberFieldFocus,
18381
+ onMathFocus: rememberMathFocus,
18382
+ onFieldBlur,
18383
+ onImageSrcChange: (blockId, value) => {
18384
+ clearBlockSelection();
18385
+ applyDocument(updateDocument2ImageValue(documentRef.current, blockId, value), "text");
18386
+ },
18387
+ onFloatMetaChange: (blockId, kind, patch) => {
18388
+ clearBlockSelection();
18389
+ applyDocument(
18390
+ kind === "image" ? updateDocument2ImageMeta(documentRef.current, blockId, patch) : updateDocument2TableMeta(documentRef.current, blockId, patch),
18391
+ "text"
18392
+ );
18393
+ },
18394
+ onParagraphCenteredChange: (blockId, centered) => {
18395
+ clearBlockSelection();
18396
+ applyDocument(updateDocument2TextBlockCentered(documentRef.current, blockId, centered), "text");
18397
+ },
18398
+ onAddListItem: (listBlockId) => {
18399
+ clearBlockSelection();
18400
+ applyDocument(addDocument2ListItem(documentRef.current, listBlockId), "immediate");
18401
+ },
18402
+ onRemoveListItem: (listBlockId, itemId) => {
18403
+ clearBlockSelection();
18404
+ applyDocument(removeDocument2ListItem(documentRef.current, listBlockId, itemId), "immediate");
18405
+ },
18406
+ onManageReferences: () => setReferencesOpen(true)
18407
+ },
18408
+ block.id
18409
+ ))
18410
+ ] })
18411
+ }
18412
+ ) : null,
18413
+ /* @__PURE__ */ jsx17(
18414
+ "section",
18415
+ {
18416
+ className: "butex-document2-widget__panel butex-document2-widget__preview-panel",
18417
+ "aria-label": messages.documentPreview,
18418
+ "aria-hidden": !showPreviewPanel,
18419
+ children: /* @__PURE__ */ jsx17(
18420
+ DocumentPreview,
18025
18421
  {
18026
- block,
18027
- references: documentNode.references,
18028
- documentNode,
18422
+ blocks: preview.blocks,
18423
+ output: mathOutput,
18029
18424
  documentDirection,
18030
- digitForm,
18031
- mathOutput,
18032
- equationSide,
18033
- editableEquations,
18034
- editableCitations: !previewOnly,
18035
18425
  uiLocale,
18036
- isCollapsed: collapsedBlockIds.has(block.id),
18037
- selected: Boolean(blockSelection && blockIndex >= blockSelection.from && blockIndex <= blockSelection.to),
18038
- onToggleSelect: toggleSelectBlock,
18039
- onTextChange: (fieldId, tokenId, text) => {
18040
- clearBlockSelection();
18041
- applyDocument(updateTextToken(documentRef.current, fieldId, tokenId, text), "text");
18042
- },
18043
- onOpenMath: openMath,
18044
- onDeleteMath: editableEquations ? deleteMathToken : void 0,
18045
- onOpenCite: openCite,
18046
- onDeleteCite: deleteCiteToken,
18047
- onOpenRef: openRef,
18048
- onDeleteRef: deleteRefToken,
18049
- onToggleCollapse: toggleBlockCollapse,
18050
- onBlockFocus: rememberBlockFocus,
18051
- onFieldFocus: rememberFieldFocus,
18052
- onMathFocus: rememberMathFocus,
18053
- onFieldBlur,
18054
- onImageSrcChange: (blockId, value) => {
18055
- clearBlockSelection();
18056
- applyDocument(updateDocument2ImageValue(documentRef.current, blockId, value), "text");
18057
- },
18058
- onFloatMetaChange: (blockId, kind, patch) => {
18059
- clearBlockSelection();
18060
- applyDocument(
18061
- kind === "image" ? updateDocument2ImageMeta(documentRef.current, blockId, patch) : updateDocument2TableMeta(documentRef.current, blockId, patch),
18062
- "text"
18063
- );
18064
- },
18065
- onParagraphCenteredChange: (blockId, centered) => {
18066
- clearBlockSelection();
18067
- applyDocument(updateDocument2TextBlockCentered(documentRef.current, blockId, centered), "text");
18068
- },
18069
- onAddListItem: (listBlockId) => {
18070
- clearBlockSelection();
18071
- applyDocument(addDocument2ListItem(documentRef.current, listBlockId), "immediate");
18072
- },
18073
- onRemoveListItem: (listBlockId, itemId) => {
18074
- clearBlockSelection();
18075
- applyDocument(removeDocument2ListItem(documentRef.current, listBlockId, itemId), "immediate");
18076
- },
18077
- onManageReferences: () => setReferencesOpen(true)
18078
- },
18079
- block.id
18080
- ))
18081
- ] })
18082
- }
18083
- ) : null,
18426
+ digitForm,
18427
+ resolveImageUrl
18428
+ }
18429
+ )
18430
+ }
18431
+ )
18432
+ ]
18433
+ }
18434
+ ),
18435
+ debugEnabled ? /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__dev", children: [
18436
+ debugEnabled && documentNode.diagnostics.length > 0 ? /* @__PURE__ */ jsxs15(Fragment4, { children: [
18437
+ /* @__PURE__ */ jsx17("strong", { children: messages.importWarnings }),
18438
+ documentNode.diagnostics.map((diagnostic) => /* @__PURE__ */ jsx17("p", { className: "butex-document2-widget__dev-diagnostic", children: formatDocument2Diagnostic(diagnostic, messages) }, `${diagnostic.path}-${diagnostic.message}`))
18439
+ ] }) : null,
18440
+ /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__dev-actions", children: [
18441
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => void copyDebugText(JSON.stringify(documentJson, null, 2)), children: "Copy JSON" }),
18442
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => void copyDebugText(latex), children: "Copy TeX" }),
18443
+ /* @__PURE__ */ jsx17("button", { type: "button", "aria-expanded": debugImportOpen, onClick: openDebugJsonImport, children: "Import JSON" })
18444
+ ] }),
18445
+ debugImportOpen ? /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__dev-import", children: [
18084
18446
  /* @__PURE__ */ jsx17(
18085
- "section",
18447
+ "textarea",
18086
18448
  {
18087
- className: "butex-document2-widget__panel butex-document2-widget__preview-panel",
18088
- "aria-label": messages.documentPreview,
18089
- "aria-hidden": !showPreviewPanel,
18090
- children: /* @__PURE__ */ jsx17(
18091
- DocumentPreview,
18092
- {
18093
- blocks: preview.blocks,
18094
- output: mathOutput,
18095
- documentDirection,
18096
- uiLocale,
18097
- digitForm,
18098
- resolveImageUrl
18099
- }
18100
- )
18449
+ value: debugImportText,
18450
+ "aria-label": "Import Document2 JSON",
18451
+ spellCheck: false,
18452
+ onChange: (event) => {
18453
+ setDebugImportText(event.currentTarget.value);
18454
+ setDebugImportError("");
18455
+ }
18101
18456
  }
18102
- )
18103
- ]
18104
- }
18105
- ),
18106
- debugEnabled ? /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__dev", children: [
18107
- debugEnabled && documentNode.diagnostics.length > 0 ? /* @__PURE__ */ jsxs15(Fragment4, { children: [
18108
- /* @__PURE__ */ jsx17("strong", { children: messages.importWarnings }),
18109
- documentNode.diagnostics.map((diagnostic) => /* @__PURE__ */ jsx17("p", { className: "butex-document2-widget__dev-diagnostic", children: formatDocument2Diagnostic(diagnostic, messages) }, `${diagnostic.path}-${diagnostic.message}`))
18457
+ ),
18458
+ /* @__PURE__ */ jsxs15("div", { className: "butex-document2-widget__dev-actions", children: [
18459
+ /* @__PURE__ */ jsx17("button", { type: "button", onClick: applyDebugJsonImport, children: "Apply" }),
18460
+ /* @__PURE__ */ jsx17(
18461
+ "button",
18462
+ {
18463
+ type: "button",
18464
+ onClick: () => {
18465
+ setDebugImportOpen(false);
18466
+ setDebugImportError("");
18467
+ },
18468
+ children: "Cancel"
18469
+ }
18470
+ )
18471
+ ] }),
18472
+ debugImportError ? /* @__PURE__ */ jsx17("p", { className: "butex-document2-widget__dev-error", children: debugImportError }) : null
18473
+ ] }) : null,
18474
+ /* @__PURE__ */ jsx17("strong", { children: "LaTeX" }),
18475
+ /* @__PURE__ */ jsx17("pre", { children: latex }),
18476
+ /* @__PURE__ */ jsx17("strong", { children: "JSON" }),
18477
+ /* @__PURE__ */ jsx17("pre", { children: JSON.stringify(documentJson, null, 2) }),
18478
+ /* @__PURE__ */ jsx17("strong", { children: "AST" }),
18479
+ /* @__PURE__ */ jsx17("pre", { children: JSON.stringify(documentNode, null, 2) })
18110
18480
  ] }) : null,
18111
- /* @__PURE__ */ jsx17("strong", { children: "LaTeX" }),
18112
- /* @__PURE__ */ jsx17("pre", { children: latex }),
18113
- /* @__PURE__ */ jsx17("strong", { children: "AST" }),
18114
- /* @__PURE__ */ jsx17("pre", { children: JSON.stringify(documentNode, null, 2) })
18115
- ] }) : null,
18116
- !previewOnly && selectedMath ? /* @__PURE__ */ jsx17(
18117
- EquationDrawer,
18118
- {
18119
- session: selectedMath.session,
18120
- reason: selectedMath.reason,
18121
- mathMode: selectedMath.mathMode,
18122
- canDelete: Boolean(selectedMath.tokenId),
18123
- equationSide,
18124
- uiLocale,
18125
- labelEnabled: selectedMath.labelEnabled,
18126
- label: selectedMath.label,
18127
- labels: documentLabels,
18128
- references: documentNode.references,
18129
- ownerId: selectedMath.tokenId ?? void 0,
18130
- onLabelEnabledChange: (enabled) => setSelectedMath((current) => current ? { ...current, labelEnabled: enabled } : current),
18131
- onLabelChange: (nextLabel) => setSelectedMath((current) => current ? { ...current, label: nextLabel } : current),
18132
- onMathModeChange: (mode) => setSelectedMath((current) => current ? { ...current, mathMode: mode } : current),
18133
- onClose: () => setSelectedMath(null),
18134
- onSave: saveEquation,
18135
- onDelete: deleteSelectedEquation
18136
- }
18137
- ) : null,
18138
- !previewOnly ? /* @__PURE__ */ jsx17(
18139
- CitePickerPopover,
18140
- {
18141
- open: citePicker !== null,
18142
- references: documentNode.references,
18143
- initialKeys: citePicker?.keys ?? [],
18144
- uiLocale,
18145
- digitForm,
18146
- onClose: () => setCitePicker(null),
18147
- onConfirm: confirmCiteKeys,
18148
- onManageReferences: () => {
18149
- setCitePicker(null);
18150
- setReferencesOpen(true);
18481
+ !previewOnly && selectedMath ? /* @__PURE__ */ jsx17(
18482
+ EquationDrawer,
18483
+ {
18484
+ debug: debugEnabled,
18485
+ session: selectedMath.session,
18486
+ reason: selectedMath.reason,
18487
+ mathMode: selectedMath.mathMode,
18488
+ canDelete: Boolean(selectedMath.tokenId),
18489
+ equationSide,
18490
+ uiLocale,
18491
+ labelEnabled: selectedMath.labelEnabled,
18492
+ label: selectedMath.label,
18493
+ labels: documentLabels,
18494
+ references: documentNode.references,
18495
+ ownerId: selectedMath.tokenId ?? void 0,
18496
+ onLabelEnabledChange: (enabled) => setSelectedMath((current) => current ? { ...current, labelEnabled: enabled } : current),
18497
+ onLabelChange: (nextLabel) => setSelectedMath((current) => current ? { ...current, label: nextLabel } : current),
18498
+ onMathModeChange: (mode) => setSelectedMath((current) => current ? { ...current, mathMode: mode } : current),
18499
+ onClose: () => setSelectedMath(null),
18500
+ onSave: saveEquation,
18501
+ onDelete: deleteSelectedEquation
18151
18502
  }
18152
- }
18153
- ) : null,
18154
- !previewOnly ? /* @__PURE__ */ jsx17(
18155
- RefPickerPopover,
18156
- {
18157
- open: refPicker !== null,
18158
- labels: documentLabels,
18159
- initialKeys: refPicker?.keys ?? [],
18160
- initialRefCommand: refPicker?.refCommand ?? "ref",
18161
- uiLocale,
18162
- digitForm,
18163
- onClose: () => setRefPicker(null),
18164
- onConfirm: confirmRefKeys,
18165
- onManageLabels: () => {
18166
- setRefPicker(null);
18167
- setLabelsOpen(true);
18503
+ ) : null,
18504
+ !previewOnly ? /* @__PURE__ */ jsx17(
18505
+ CitePickerPopover,
18506
+ {
18507
+ open: citePicker !== null,
18508
+ references: documentNode.references,
18509
+ initialKeys: citePicker?.keys ?? [],
18510
+ uiLocale,
18511
+ digitForm,
18512
+ onClose: () => setCitePicker(null),
18513
+ onConfirm: confirmCiteKeys,
18514
+ onManageReferences: () => {
18515
+ setCitePicker(null);
18516
+ setReferencesOpen(true);
18517
+ }
18168
18518
  }
18169
- }
18170
- ) : null,
18171
- !previewOnly ? /* @__PURE__ */ jsx17(
18172
- ReferencesPanel,
18173
- {
18174
- open: referencesOpen,
18175
- references: documentNode.references,
18176
- labels: documentLabels,
18177
- uiLocale,
18178
- digitForm,
18179
- onClose: () => setReferencesOpen(false),
18180
- onAdd: (partial) => applyDocument(addDocument2Reference(documentRef.current, partial), "immediate"),
18181
- onUpdate: (referenceId, patch) => applyDocument(updateDocument2Reference(documentRef.current, referenceId, patch), "immediate"),
18182
- onRemove: (referenceId) => applyDocument(removeDocument2Reference(documentRef.current, referenceId), "immediate"),
18183
- onMove: (referenceId, direction) => applyDocument(moveDocument2Reference(documentRef.current, referenceId, direction), "immediate")
18184
- }
18185
- ) : null,
18186
- !previewOnly ? /* @__PURE__ */ jsx17(
18187
- LabelsPanel,
18188
- {
18189
- open: labelsOpen,
18190
- labels: documentLabels,
18191
- references: documentNode.references,
18192
- uiLocale,
18193
- digitForm,
18194
- onClose: () => setLabelsOpen(false),
18195
- onUpdateFloat: (ownerId, kind, patch) => applyDocument(
18196
- kind === "fig" ? updateDocument2ImageMeta(documentRef.current, ownerId, patch) : updateDocument2TableMeta(documentRef.current, ownerId, patch),
18197
- "text"
18198
- ),
18199
- onUpdateEquationLabel: (tokenId, patch) => applyDocument(updateMathTokenLabel(documentRef.current, tokenId, patch), "text")
18200
- }
18201
- ) : null
18202
- ] })
18203
- }
18204
- );
18205
- }
18519
+ ) : null,
18520
+ !previewOnly ? /* @__PURE__ */ jsx17(
18521
+ RefPickerPopover,
18522
+ {
18523
+ open: refPicker !== null,
18524
+ labels: documentLabels,
18525
+ initialKeys: refPicker?.keys ?? [],
18526
+ initialRefCommand: refPicker?.refCommand ?? "ref",
18527
+ uiLocale,
18528
+ digitForm,
18529
+ onClose: () => setRefPicker(null),
18530
+ onConfirm: confirmRefKeys,
18531
+ onManageLabels: () => {
18532
+ setRefPicker(null);
18533
+ setLabelsOpen(true);
18534
+ }
18535
+ }
18536
+ ) : null,
18537
+ !previewOnly ? /* @__PURE__ */ jsx17(
18538
+ ReferencesPanel,
18539
+ {
18540
+ open: referencesOpen,
18541
+ references: documentNode.references,
18542
+ labels: documentLabels,
18543
+ uiLocale,
18544
+ digitForm,
18545
+ onClose: () => setReferencesOpen(false),
18546
+ onAdd: (partial) => applyDocument(addDocument2Reference(documentRef.current, partial), "immediate"),
18547
+ onUpdate: (referenceId, patch) => applyDocument(updateDocument2Reference(documentRef.current, referenceId, patch), "immediate"),
18548
+ onRemove: (referenceId) => applyDocument(removeDocument2Reference(documentRef.current, referenceId), "immediate"),
18549
+ onMove: (referenceId, direction) => applyDocument(moveDocument2Reference(documentRef.current, referenceId, direction), "immediate")
18550
+ }
18551
+ ) : null,
18552
+ !previewOnly ? /* @__PURE__ */ jsx17(
18553
+ LabelsPanel,
18554
+ {
18555
+ open: labelsOpen,
18556
+ labels: documentLabels,
18557
+ references: documentNode.references,
18558
+ uiLocale,
18559
+ digitForm,
18560
+ onClose: () => setLabelsOpen(false),
18561
+ onUpdateFloat: (ownerId, kind, patch) => applyDocument(
18562
+ kind === "fig" ? updateDocument2ImageMeta(documentRef.current, ownerId, patch) : updateDocument2TableMeta(documentRef.current, ownerId, patch),
18563
+ "text"
18564
+ ),
18565
+ onUpdateEquationLabel: (tokenId, patch) => applyDocument(updateMathTokenLabel(documentRef.current, tokenId, patch), "text")
18566
+ }
18567
+ ) : null
18568
+ ] })
18569
+ }
18570
+ );
18571
+ }
18572
+ );
18573
+ ButexDocumentEditor2.displayName = "ButexDocumentEditor2";
18206
18574
  export {
18207
18575
  ButexDocumentEditor2,
18208
18576
  DOCUMENT2_WIDGET_CSS,