agentlas 1.0.42 → 1.0.44

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/engine/agentlas-workforce.cjs +1 -1
  3. package/engine/hephaestus/runtime.cjs +1 -1
  4. package/engine/storm/storm.cjs +1 -1
  5. package/engine/storm/swarm.cjs +1 -1
  6. package/engine/ui/palette.cjs +1 -0
  7. package/engine/ui/repl.cjs +34 -4
  8. package/engine/ui/shell.cjs +22 -3
  9. package/engine/vendor/mermaid/LICENSE +205 -0
  10. package/engine/vendor/mermaid/ansi.js +23 -0
  11. package/engine/vendor/mermaid/canvas.js +366 -0
  12. package/engine/vendor/mermaid/graph.js +91 -0
  13. package/engine/vendor/mermaid/index.js +100 -0
  14. package/engine/vendor/mermaid/labels.js +324 -0
  15. package/engine/vendor/mermaid/layout-seq.js +194 -0
  16. package/engine/vendor/mermaid/layout.js +881 -0
  17. package/engine/vendor/mermaid/package.json +1 -0
  18. package/engine/vendor/mermaid/parse.js +1108 -0
  19. package/engine/vendor/mermaid/source-box.js +78 -0
  20. package/engine/vendor/mermaid/types.js +1 -0
  21. package/engine/vendor/mermaid/width-data.js +994 -0
  22. package/engine/vendor/mermaid/width.js +76 -0
  23. package/engine/vendor/tui/LICENSE +20 -0
  24. package/engine/vendor/tui/autocomplete.js +632 -0
  25. package/engine/vendor/tui/components/alt-screen-flash.js +37 -0
  26. package/engine/vendor/tui/components/box.js +104 -0
  27. package/engine/vendor/tui/components/cancellable-loader.js +35 -0
  28. package/engine/vendor/tui/components/editor.js +1961 -0
  29. package/engine/vendor/tui/components/h-stack.js +43 -0
  30. package/engine/vendor/tui/components/image.js +90 -0
  31. package/engine/vendor/tui/components/input.js +378 -0
  32. package/engine/vendor/tui/components/loader.js +69 -0
  33. package/engine/vendor/tui/components/markdown.js +806 -0
  34. package/engine/vendor/tui/components/scroll-view.js +173 -0
  35. package/engine/vendor/tui/components/select-list.js +159 -0
  36. package/engine/vendor/tui/components/settings-list.js +182 -0
  37. package/engine/vendor/tui/components/spacer.js +23 -0
  38. package/engine/vendor/tui/components/stack.js +111 -0
  39. package/engine/vendor/tui/components/text.js +89 -0
  40. package/engine/vendor/tui/components/truncated-text.js +51 -0
  41. package/engine/vendor/tui/components/v-stack.js +26 -0
  42. package/engine/vendor/tui/deps/east-asian-width/LICENSE +9 -0
  43. package/engine/vendor/tui/deps/east-asian-width/index.js +30 -0
  44. package/engine/vendor/tui/deps/east-asian-width/lookup-data.js +21 -0
  45. package/engine/vendor/tui/deps/east-asian-width/lookup.js +138 -0
  46. package/engine/vendor/tui/deps/east-asian-width/utilities.js +24 -0
  47. package/engine/vendor/tui/deps/marked/LICENSE +44 -0
  48. package/engine/vendor/tui/deps/marked/index.js +77 -0
  49. package/engine/vendor/tui/editor-component.js +2 -0
  50. package/engine/vendor/tui/fuzzy.js +110 -0
  51. package/engine/vendor/tui/index.js +42 -0
  52. package/engine/vendor/tui/keybindings.js +209 -0
  53. package/engine/vendor/tui/keys.js +1174 -0
  54. package/engine/vendor/tui/kill-ring.js +44 -0
  55. package/engine/vendor/tui/latex.js +1264 -0
  56. package/engine/vendor/tui/layout-node.js +6 -0
  57. package/engine/vendor/tui/layout.js +314 -0
  58. package/engine/vendor/tui/native-modifiers.js +60 -0
  59. package/engine/vendor/tui/package.json +1 -0
  60. package/engine/vendor/tui/stdin-buffer.js +361 -0
  61. package/engine/vendor/tui/terminal-colors.js +59 -0
  62. package/engine/vendor/tui/terminal-image.js +518 -0
  63. package/engine/vendor/tui/terminal.js +436 -0
  64. package/engine/vendor/tui/tui-alt-screen.js +902 -0
  65. package/engine/vendor/tui/tui-main-screen.js +533 -0
  66. package/engine/vendor/tui/tui.js +937 -0
  67. package/engine/vendor/tui/undo-stack.js +25 -0
  68. package/engine/vendor/tui/utils.js +1191 -0
  69. package/engine/vendor/tui/word-navigation.js +96 -0
  70. package/package.json +2 -6
@@ -0,0 +1,1264 @@
1
+ import { visibleWidth } from "./utils.js";
2
+ const SYMBOLS = {
3
+ alpha: "α",
4
+ beta: "β",
5
+ gamma: "γ",
6
+ delta: "δ",
7
+ epsilon: "ϵ",
8
+ varepsilon: "ε",
9
+ zeta: "ζ",
10
+ eta: "η",
11
+ theta: "θ",
12
+ vartheta: "ϑ",
13
+ iota: "ι",
14
+ kappa: "κ",
15
+ varkappa: "ϰ",
16
+ lambda: "λ",
17
+ mu: "μ",
18
+ nu: "ν",
19
+ xi: "ξ",
20
+ pi: "π",
21
+ varpi: "ϖ",
22
+ rho: "ρ",
23
+ varrho: "ϱ",
24
+ sigma: "σ",
25
+ varsigma: "ς",
26
+ tau: "τ",
27
+ upsilon: "υ",
28
+ phi: "ϕ",
29
+ varphi: "φ",
30
+ chi: "χ",
31
+ psi: "ψ",
32
+ omega: "ω",
33
+ Gamma: "Γ",
34
+ Delta: "Δ",
35
+ Theta: "Θ",
36
+ Lambda: "Λ",
37
+ Xi: "Ξ",
38
+ Pi: "Π",
39
+ Sigma: "Σ",
40
+ Upsilon: "Υ",
41
+ Phi: "Φ",
42
+ Psi: "Ψ",
43
+ Omega: "Ω",
44
+ pm: "±",
45
+ mp: "∓",
46
+ times: "×",
47
+ div: "÷",
48
+ cdot: "·",
49
+ ast: "∗",
50
+ star: "⋆",
51
+ circ: "∘",
52
+ bullet: "•",
53
+ oplus: "⊕",
54
+ ominus: "⊖",
55
+ otimes: "⊗",
56
+ oslash: "⊘",
57
+ odot: "⊙",
58
+ bigcirc: "○",
59
+ dagger: "†",
60
+ ddagger: "‡",
61
+ amalg: "⨿",
62
+ uplus: "⊎",
63
+ sqcap: "⊓",
64
+ sqcup: "⊔",
65
+ triangleleft: "◁",
66
+ triangleright: "▷",
67
+ wr: "≀",
68
+ cap: "∩",
69
+ cup: "∪",
70
+ bigcap: "⋂",
71
+ bigcup: "⋃",
72
+ bigwedge: "⋀",
73
+ bigvee: "⋁",
74
+ bigsqcup: "⨆",
75
+ biguplus: "⨄",
76
+ bigoplus: "⨁",
77
+ bigotimes: "⨂",
78
+ bigodot: "⨀",
79
+ setminus: "∖",
80
+ in: "∈",
81
+ notin: "∉",
82
+ ni: "∋",
83
+ subset: "⊂",
84
+ supset: "⊃",
85
+ subseteq: "⊆",
86
+ supseteq: "⊇",
87
+ sqsubset: "⊏",
88
+ sqsupset: "⊐",
89
+ sqsubseteq: "⊑",
90
+ sqsupseteq: "⊒",
91
+ prec: "≺",
92
+ preceq: "≼",
93
+ succ: "≻",
94
+ succeq: "≽",
95
+ ll: "≪",
96
+ gg: "≫",
97
+ le: "≤",
98
+ leq: "≤",
99
+ leqslant: "≤",
100
+ ge: "≥",
101
+ geq: "≥",
102
+ geqslant: "≥",
103
+ ne: "≠",
104
+ neq: "≠",
105
+ equiv: "≡",
106
+ approx: "≈",
107
+ sim: "∼",
108
+ simeq: "≃",
109
+ cong: "≅",
110
+ asymp: "≍",
111
+ doteq: "≐",
112
+ propto: "∝",
113
+ parallel: "∥",
114
+ perp: "⊥",
115
+ mid: "∣",
116
+ vdash: "⊢",
117
+ dashv: "⊣",
118
+ models: "⊨",
119
+ Vdash: "⊩",
120
+ Vvdash: "⊪",
121
+ nvdash: "⊬",
122
+ nvDash: "⊭",
123
+ forall: "∀",
124
+ exists: "∃",
125
+ nexists: "∄",
126
+ neg: "¬",
127
+ land: "∧",
128
+ wedge: "∧",
129
+ lor: "∨",
130
+ vee: "∨",
131
+ to: "→",
132
+ rightarrow: "→",
133
+ longrightarrow: "→",
134
+ leftarrow: "←",
135
+ longleftarrow: "←",
136
+ gets: "←",
137
+ leftrightarrow: "↔",
138
+ longleftrightarrow: "↔",
139
+ hookleftarrow: "↩",
140
+ hookrightarrow: "↪",
141
+ twoheadleftarrow: "↞",
142
+ twoheadrightarrow: "↠",
143
+ leftharpoonup: "↼",
144
+ leftharpoondown: "↽",
145
+ rightharpoonup: "⇀",
146
+ rightharpoondown: "⇁",
147
+ rightleftharpoons: "⇌",
148
+ leftrightharpoons: "⇋",
149
+ nearrow: "↗",
150
+ searrow: "↘",
151
+ swarrow: "↙",
152
+ nwarrow: "↖",
153
+ rightsquigarrow: "⇝",
154
+ leadsto: "⇝",
155
+ Rightarrow: "⇒",
156
+ Longrightarrow: "⇒",
157
+ Leftarrow: "⇐",
158
+ Longleftarrow: "⇐",
159
+ Leftrightarrow: "⇔",
160
+ Longleftrightarrow: "⇔",
161
+ implies: "⇒",
162
+ iff: "⇔",
163
+ mapsto: "↦",
164
+ longmapsto: "↦",
165
+ uparrow: "↑",
166
+ downarrow: "↓",
167
+ partial: "∂",
168
+ nabla: "∇",
169
+ int: "∫",
170
+ iint: "∬",
171
+ iiint: "∭",
172
+ oint: "∮",
173
+ sum: "∑",
174
+ prod: "∏",
175
+ coprod: "∐",
176
+ infty: "∞",
177
+ emptyset: "∅",
178
+ varnothing: "∅",
179
+ angle: "∠",
180
+ therefore: "∴",
181
+ because: "∵",
182
+ aleph: "ℵ",
183
+ beth: "ℶ",
184
+ gimel: "ℷ",
185
+ daleth: "ℸ",
186
+ top: "⊤",
187
+ bot: "⊥",
188
+ triangle: "△",
189
+ square: "□",
190
+ lozenge: "◊",
191
+ checkmark: "✓",
192
+ complement: "∁",
193
+ wp: "℘",
194
+ prime: "′",
195
+ ldots: "…",
196
+ dots: "…",
197
+ cdots: "⋯",
198
+ vdots: "⋮",
199
+ ddots: "⋱",
200
+ ell: "ℓ",
201
+ hbar: "ℏ",
202
+ Im: "ℑ",
203
+ Re: "ℜ",
204
+ langle: "⟨",
205
+ rangle: "⟩",
206
+ vert: "|",
207
+ lvert: "|",
208
+ rvert: "|",
209
+ Vert: "‖",
210
+ lVert: "‖",
211
+ rVert: "‖",
212
+ lbrace: "{",
213
+ rbrace: "}",
214
+ backslash: "\\",
215
+ lfloor: "⌊",
216
+ rfloor: "⌋",
217
+ lceil: "⌈",
218
+ rceil: "⌉",
219
+ colon: ":",
220
+ };
221
+ const NAMED_OPERATORS = new Set([
222
+ "arccos",
223
+ "arcsin",
224
+ "arctan",
225
+ "arg",
226
+ "cos",
227
+ "cosh",
228
+ "cot",
229
+ "coth",
230
+ "csc",
231
+ "deg",
232
+ "det",
233
+ "dim",
234
+ "exp",
235
+ "gcd",
236
+ "hom",
237
+ "inf",
238
+ "ker",
239
+ "lg",
240
+ "lim",
241
+ "liminf",
242
+ "limsup",
243
+ "ln",
244
+ "log",
245
+ "max",
246
+ "min",
247
+ "Pr",
248
+ "sec",
249
+ "sin",
250
+ "sinh",
251
+ "sup",
252
+ "tan",
253
+ "tanh",
254
+ ]);
255
+ const LIMIT_OPERATORS = new Set([
256
+ "argmax",
257
+ "argmin",
258
+ "inf",
259
+ "injlim",
260
+ "lim",
261
+ "liminf",
262
+ "limsup",
263
+ "max",
264
+ "min",
265
+ "projlim",
266
+ "sup",
267
+ ]);
268
+ const DISPLAY_LIMIT_SYMBOLS = new Set([
269
+ "bigcap",
270
+ "bigcup",
271
+ "bigodot",
272
+ "bigoplus",
273
+ "bigotimes",
274
+ "bigsqcup",
275
+ "biguplus",
276
+ "bigvee",
277
+ "bigwedge",
278
+ "coprod",
279
+ "int",
280
+ "iint",
281
+ "iiint",
282
+ "oint",
283
+ "prod",
284
+ "sum",
285
+ ]);
286
+ const RELATION_COMMANDS = new Set([
287
+ "Leftarrow",
288
+ "Leftrightarrow",
289
+ "Longleftarrow",
290
+ "Longleftrightarrow",
291
+ "Longrightarrow",
292
+ "Rightarrow",
293
+ "Vdash",
294
+ "Vvdash",
295
+ "approx",
296
+ "asymp",
297
+ "cong",
298
+ "dashv",
299
+ "doteq",
300
+ "downarrow",
301
+ "equiv",
302
+ "ge",
303
+ "geq",
304
+ "geqslant",
305
+ "gets",
306
+ "gg",
307
+ "hookleftarrow",
308
+ "hookrightarrow",
309
+ "iff",
310
+ "implies",
311
+ "in",
312
+ "leadsto",
313
+ "le",
314
+ "leftarrow",
315
+ "leftharpoondown",
316
+ "leftharpoonup",
317
+ "leftrightarrow",
318
+ "leftrightharpoons",
319
+ "leq",
320
+ "leqslant",
321
+ "ll",
322
+ "longleftarrow",
323
+ "longleftrightarrow",
324
+ "longmapsto",
325
+ "longrightarrow",
326
+ "mapsto",
327
+ "mid",
328
+ "models",
329
+ "ne",
330
+ "nearrow",
331
+ "neq",
332
+ "ni",
333
+ "notin",
334
+ "nvdash",
335
+ "nvDash",
336
+ "nwarrow",
337
+ "parallel",
338
+ "perp",
339
+ "prec",
340
+ "preceq",
341
+ "propto",
342
+ "rightharpoondown",
343
+ "rightharpoonup",
344
+ "rightleftharpoons",
345
+ "rightarrow",
346
+ "rightsquigarrow",
347
+ "searrow",
348
+ "sim",
349
+ "simeq",
350
+ "sqsubset",
351
+ "sqsubseteq",
352
+ "sqsupset",
353
+ "sqsupseteq",
354
+ "subset",
355
+ "subseteq",
356
+ "succ",
357
+ "succeq",
358
+ "supset",
359
+ "supseteq",
360
+ "swarrow",
361
+ "to",
362
+ "triangleleft",
363
+ "triangleright",
364
+ "twoheadleftarrow",
365
+ "twoheadrightarrow",
366
+ "uparrow",
367
+ "vdash",
368
+ ]);
369
+ const NEGATED_SYMBOLS = {
370
+ "<": "≮",
371
+ ">": "≯",
372
+ "=": "≠",
373
+ "∈": "∉",
374
+ "∋": "∌",
375
+ "∣": "∤",
376
+ "∥": "∦",
377
+ "∼": "≁",
378
+ "≃": "≄",
379
+ "≅": "≇",
380
+ "≈": "≉",
381
+ "≡": "≢",
382
+ "≤": "≰",
383
+ "≥": "≱",
384
+ "≺": "⊀",
385
+ "≻": "⊁",
386
+ "⊂": "⊄",
387
+ "⊃": "⊅",
388
+ "⊆": "⊈",
389
+ "⊇": "⊉",
390
+ "⊢": "⊬",
391
+ "⊨": "⊭",
392
+ "↔": "↮",
393
+ "←": "↚",
394
+ "→": "↛",
395
+ "⇒": "⇏",
396
+ "⇐": "⇍",
397
+ "⇔": "⇎",
398
+ "≼": "⋠",
399
+ "≽": "⋡",
400
+ };
401
+ const BLACKBOARD = {
402
+ C: "ℂ",
403
+ H: "ℍ",
404
+ N: "ℕ",
405
+ P: "ℙ",
406
+ Q: "ℚ",
407
+ R: "ℝ",
408
+ Z: "ℤ",
409
+ };
410
+ const SUPERSCRIPTS = {
411
+ "0": "⁰",
412
+ "1": "¹",
413
+ "2": "²",
414
+ "3": "³",
415
+ "4": "⁴",
416
+ "5": "⁵",
417
+ "6": "⁶",
418
+ "7": "⁷",
419
+ "8": "⁸",
420
+ "9": "⁹",
421
+ "+": "⁺",
422
+ "-": "⁻",
423
+ "=": "⁼",
424
+ "(": "⁽",
425
+ ")": "⁾",
426
+ a: "ᵃ",
427
+ b: "ᵇ",
428
+ c: "ᶜ",
429
+ d: "ᵈ",
430
+ e: "ᵉ",
431
+ f: "ᶠ",
432
+ g: "ᵍ",
433
+ h: "ʰ",
434
+ i: "ⁱ",
435
+ j: "ʲ",
436
+ k: "ᵏ",
437
+ l: "ˡ",
438
+ m: "ᵐ",
439
+ n: "ⁿ",
440
+ o: "ᵒ",
441
+ p: "ᵖ",
442
+ r: "ʳ",
443
+ s: "ˢ",
444
+ t: "ᵗ",
445
+ u: "ᵘ",
446
+ v: "ᵛ",
447
+ w: "ʷ",
448
+ x: "ˣ",
449
+ y: "ʸ",
450
+ z: "ᶻ",
451
+ };
452
+ const SUBSCRIPTS = {
453
+ "0": "₀",
454
+ "1": "₁",
455
+ "2": "₂",
456
+ "3": "₃",
457
+ "4": "₄",
458
+ "5": "₅",
459
+ "6": "₆",
460
+ "7": "₇",
461
+ "8": "₈",
462
+ "9": "₉",
463
+ "+": "₊",
464
+ "-": "₋",
465
+ "=": "₌",
466
+ "(": "₍",
467
+ ")": "₎",
468
+ a: "ₐ",
469
+ e: "ₑ",
470
+ h: "ₕ",
471
+ i: "ᵢ",
472
+ j: "ⱼ",
473
+ k: "ₖ",
474
+ l: "ₗ",
475
+ m: "ₘ",
476
+ n: "ₙ",
477
+ o: "ₒ",
478
+ p: "ₚ",
479
+ r: "ᵣ",
480
+ s: "ₛ",
481
+ t: "ₜ",
482
+ u: "ᵤ",
483
+ v: "ᵥ",
484
+ x: "ₓ",
485
+ };
486
+ const SPACING_COMMANDS = new Set([
487
+ ",",
488
+ ":",
489
+ ";",
490
+ " ",
491
+ ">",
492
+ "enspace",
493
+ "enskip",
494
+ "medspace",
495
+ "quad",
496
+ "qquad",
497
+ "thickspace",
498
+ "thinspace",
499
+ ]);
500
+ const NEGATIVE_SPACING_COMMANDS = new Set(["!", "negmedspace", "negthickspace", "negthinspace"]);
501
+ const NEGATIVE_SPACE = "\u0000";
502
+ const IGNORED_COMMANDS = new Set([
503
+ "displaystyle",
504
+ "limits",
505
+ "nolimits",
506
+ "scriptstyle",
507
+ "scriptscriptstyle",
508
+ "textstyle",
509
+ ]);
510
+ const SIZE_COMMANDS = new Set([
511
+ "big",
512
+ "Big",
513
+ "bigg",
514
+ "Bigg",
515
+ "bigl",
516
+ "Bigl",
517
+ "biggl",
518
+ "Biggl",
519
+ "bigr",
520
+ "Bigr",
521
+ "biggr",
522
+ "Biggr",
523
+ ]);
524
+ const PLAIN_WRAPPERS = new Set([
525
+ "emph",
526
+ "mathcal",
527
+ "mathbf",
528
+ "mathfrak",
529
+ "mathit",
530
+ "mathrm",
531
+ "mathnormal",
532
+ "mathscr",
533
+ "mathsf",
534
+ "mathtt",
535
+ "mathup",
536
+ "mbox",
537
+ "overbrace",
538
+ "pmb",
539
+ "smash",
540
+ "substack",
541
+ "text",
542
+ "textbf",
543
+ "textit",
544
+ "textmd",
545
+ "textnormal",
546
+ "textrm",
547
+ "textsc",
548
+ "textsf",
549
+ "textsl",
550
+ "texttt",
551
+ "textup",
552
+ "underbrace",
553
+ "bm",
554
+ "boldsymbol",
555
+ ]);
556
+ const ACCENTS = {
557
+ acute: "\u0301",
558
+ bar: "\u0305",
559
+ breve: "\u0306",
560
+ check: "\u030c",
561
+ ddot: "\u0308",
562
+ dot: "\u0307",
563
+ grave: "\u0300",
564
+ hat: "\u0302",
565
+ mathring: "\u030a",
566
+ overleftarrow: "\u20d6",
567
+ overleftrightarrow: "\u20e1",
568
+ overline: "\u0305",
569
+ overrightarrow: "\u20d7",
570
+ tilde: "\u0303",
571
+ underline: "\u0332",
572
+ vec: "\u20d7",
573
+ widehat: "\u0302",
574
+ widetilde: "\u0303",
575
+ };
576
+ function replaceCharacters(value, replacements) {
577
+ let result = "";
578
+ for (const character of value) {
579
+ const replacement = replacements[character];
580
+ if (replacement === undefined) {
581
+ return undefined;
582
+ }
583
+ result += replacement;
584
+ }
585
+ return result;
586
+ }
587
+ function formatScript(value, kind) {
588
+ value = value.trim();
589
+ const replacements = kind === "sub" ? SUBSCRIPTS : SUPERSCRIPTS;
590
+ const unicode = replaceCharacters(value.replace(/\s*([=+-])\s*/g, "$1"), replacements);
591
+ if (unicode !== undefined) {
592
+ return unicode;
593
+ }
594
+ const prefix = kind === "sub" ? "_" : "^";
595
+ if (Array.from(value).length === 1 || (kind === "sub" && /^[A-Za-z]+$/.test(value))) {
596
+ return `${prefix}${value}`;
597
+ }
598
+ return `${prefix}(${value})`;
599
+ }
600
+ function formatFraction(numerator, denominator) {
601
+ numerator = numerator.trim();
602
+ denominator = denominator.trim();
603
+ const simpleNumerator = /^[\p{L}\p{N}.]+$/u.test(numerator);
604
+ const simpleDenominator = /^[\p{N}.]+$/u.test(denominator) || Array.from(denominator).length === 1;
605
+ return `${simpleNumerator ? numerator : `(${numerator})`}/${simpleDenominator ? denominator : `(${denominator})`}`;
606
+ }
607
+ function formatRoot(value, symbol = "√") {
608
+ value = value.trim();
609
+ return /^[\p{L}\p{N}.]+$/u.test(value) ? `${symbol}${value}` : `${symbol}(${value})`;
610
+ }
611
+ const NAMED_OPERATOR_START = "\u{f0004}";
612
+ const NAMED_OPERATOR_END = "\u{f0005}";
613
+ const NAMED_OPERATOR_LEFT_SPACING_PATTERN = /(?<=[\p{L}\p{N})\]}\u{f0001}])\u{f0004}/gu;
614
+ const NAMED_OPERATOR_RIGHT_SPACING_PATTERN = /\u{f0005}(?=[\p{L}\p{N}√\u{f0000}])/gu;
615
+ function normalizeOutput(value) {
616
+ return value
617
+ .replace(NAMED_OPERATOR_LEFT_SPACING_PATTERN, " ")
618
+ .replaceAll(NAMED_OPERATOR_START, "")
619
+ .replace(NAMED_OPERATOR_RIGHT_SPACING_PATTERN, " ")
620
+ .replaceAll(NAMED_OPERATOR_END, "")
621
+ .split("\n")
622
+ .map((line) => line.replace(/[ \t]+/g, " ").trim())
623
+ .filter((line, index, lines) => line.length > 0 || (index > 0 && index < lines.length - 1))
624
+ .join("\n")
625
+ .trim();
626
+ }
627
+ const LAYOUT_MARKER_START = "\u{f0000}";
628
+ const LAYOUT_MARKER_END = "\u{f0001}";
629
+ const LAYOUT_MARKER_PATTERN = /\u{f0000}(\d+)\u{f0001}/gu;
630
+ const TRAILING_LAYOUT_MARKER_PATTERN = /\u{f0000}(\d+)\u{f0001}$/u;
631
+ const PROTECTED_SPACE = "\u{f0002}";
632
+ function padLayoutLine(line, width, centered = false) {
633
+ const padding = Math.max(0, width - visibleWidth(line));
634
+ const left = centered ? Math.floor(padding / 2) : 0;
635
+ return `${" ".repeat(left)}${line}${" ".repeat(padding - left)}`;
636
+ }
637
+ function joinLayouts(layouts) {
638
+ if (layouts.length === 0) {
639
+ return { lines: [""], width: 0, baseline: 0 };
640
+ }
641
+ const baseline = Math.max(...layouts.map((layout) => layout.baseline));
642
+ const below = Math.max(...layouts.map((layout) => layout.lines.length - layout.baseline - 1));
643
+ const lines = [];
644
+ for (let row = 0; row <= baseline + below; row++) {
645
+ let line = "";
646
+ for (const layout of layouts) {
647
+ const sourceRow = row - baseline + layout.baseline;
648
+ line +=
649
+ sourceRow >= 0 && sourceRow < layout.lines.length
650
+ ? padLayoutLine(layout.lines[sourceRow] ?? "", layout.width)
651
+ : " ".repeat(layout.width);
652
+ }
653
+ lines.push(line.trimEnd());
654
+ }
655
+ return {
656
+ lines,
657
+ width: layouts.reduce((width, layout) => width + layout.width, 0),
658
+ baseline,
659
+ };
660
+ }
661
+ function renderLayout(source, nodes) {
662
+ const renderedLines = [];
663
+ let firstBaseline = 0;
664
+ for (const sourceLine of source.split("\n")) {
665
+ const layouts = [];
666
+ let position = 0;
667
+ let previousNode;
668
+ for (const match of sourceLine.matchAll(LAYOUT_MARKER_PATTERN)) {
669
+ const index = match.index;
670
+ const node = nodes[Number(match[1])];
671
+ if (!node) {
672
+ continue;
673
+ }
674
+ if (index > position) {
675
+ const sliced = sourceLine.slice(position, index);
676
+ const trimmed = (previousNode ? sliced.trimStart() : sliced).trimEnd();
677
+ const preserveLeadingSpace = previousNode?.type === "matrix" && /^\s/.test(sliced);
678
+ const preserveTrailingSpace = node.type === "matrix" && /\s$/.test(sliced);
679
+ const text = trimmed
680
+ ? `${preserveLeadingSpace ? " " : ""}${trimmed}${preserveTrailingSpace ? " " : ""}`
681
+ : preserveLeadingSpace || preserveTrailingSpace
682
+ ? " "
683
+ : "";
684
+ layouts.push({ lines: [text], width: visibleWidth(text), baseline: 0 });
685
+ }
686
+ if (node.type === "fraction") {
687
+ const numerator = renderLayout(node.numerator, nodes);
688
+ const denominator = renderLayout(node.denominator, nodes);
689
+ const contentWidth = Math.max(numerator.width, denominator.width, 1);
690
+ const width = contentWidth + 2;
691
+ layouts.push({
692
+ lines: [
693
+ ...numerator.lines.map((line) => padLayoutLine(line, width, true)),
694
+ ` ${"─".repeat(contentWidth)} `,
695
+ ...denominator.lines.map((line) => padLayoutLine(line, width, true)),
696
+ ],
697
+ width,
698
+ baseline: numerator.lines.length,
699
+ });
700
+ }
701
+ else if (node.type === "operator") {
702
+ const contentWidth = Math.max(visibleWidth(node.operator), node.lower === undefined ? 0 : visibleWidth(node.lower), node.upper === undefined ? 0 : visibleWidth(node.upper));
703
+ const lines = [];
704
+ if (node.upper !== undefined) {
705
+ lines.push(`${padLayoutLine(node.upper, contentWidth, true)} `);
706
+ }
707
+ lines.push(`${padLayoutLine(node.operator, contentWidth, true)} `);
708
+ if (node.lower !== undefined) {
709
+ lines.push(`${padLayoutLine(node.lower, contentWidth, true)} `);
710
+ }
711
+ layouts.push({
712
+ lines,
713
+ width: contentWidth + 1,
714
+ baseline: node.upper === undefined ? 0 : 1,
715
+ });
716
+ }
717
+ else {
718
+ const width = Math.max(0, ...node.lines.map((line) => visibleWidth(line)));
719
+ layouts.push({
720
+ lines: node.lines.map((line) => padLayoutLine(line, width)),
721
+ width,
722
+ baseline: node.baseline,
723
+ });
724
+ }
725
+ position = index + match[0].length;
726
+ previousNode = node;
727
+ }
728
+ if (position < sourceLine.length) {
729
+ const sliced = sourceLine.slice(position);
730
+ const trimmed = previousNode ? sliced.trimStart() : sliced;
731
+ const text = previousNode?.type === "matrix" && /^\s/.test(sliced) ? ` ${trimmed}` : trimmed;
732
+ layouts.push({ lines: [text], width: visibleWidth(text), baseline: 0 });
733
+ }
734
+ const lineLayout = joinLayouts(layouts);
735
+ if (renderedLines.length === 0) {
736
+ firstBaseline = lineLayout.baseline;
737
+ }
738
+ renderedLines.push(...lineLayout.lines);
739
+ }
740
+ return {
741
+ lines: renderedLines,
742
+ width: Math.max(0, ...renderedLines.map((line) => visibleWidth(line))),
743
+ baseline: firstBaseline,
744
+ };
745
+ }
746
+ class LatexParser {
747
+ source;
748
+ layoutNodes;
749
+ display;
750
+ position = 0;
751
+ supported = true;
752
+ stackFractions = true;
753
+ constructor(source, layoutNodes, display) {
754
+ this.source = source;
755
+ this.layoutNodes = layoutNodes;
756
+ this.display = display;
757
+ }
758
+ render() {
759
+ const rendered = this.parseSequence();
760
+ if (!this.supported || this.position !== this.source.length) {
761
+ return undefined;
762
+ }
763
+ return normalizeOutput(rendered);
764
+ }
765
+ parseSequence(endCharacter) {
766
+ let result = "";
767
+ while (this.position < this.source.length) {
768
+ const character = this.source[this.position];
769
+ if (endCharacter && character === endCharacter) {
770
+ this.position++;
771
+ return result;
772
+ }
773
+ if (character === "}") {
774
+ this.supported = false;
775
+ return result;
776
+ }
777
+ if (character === "{") {
778
+ this.position++;
779
+ result += this.parseSequence("}");
780
+ continue;
781
+ }
782
+ if (character === "\\") {
783
+ const command = this.parseCommand();
784
+ if (command === NEGATIVE_SPACE) {
785
+ result = result.trimEnd();
786
+ if (result.endsWith(NAMED_OPERATOR_END)) {
787
+ result = result.slice(0, -NAMED_OPERATOR_END.length);
788
+ }
789
+ }
790
+ else {
791
+ result += command;
792
+ }
793
+ continue;
794
+ }
795
+ if (character === "^" || character === "_") {
796
+ this.position++;
797
+ result = result.trimEnd();
798
+ const script = formatScript(this.parseRequiredArgument(false), character === "_" ? "sub" : "sup");
799
+ if (result.endsWith(NAMED_OPERATOR_END)) {
800
+ result = `${result.slice(0, -NAMED_OPERATOR_END.length)}${script}${NAMED_OPERATOR_END}`;
801
+ }
802
+ else {
803
+ result += script;
804
+ }
805
+ continue;
806
+ }
807
+ if (/\s/.test(character)) {
808
+ result += this.parseWhitespace();
809
+ continue;
810
+ }
811
+ if (character === "=" || character === "<" || character === ">") {
812
+ result = `${result.trimEnd()} ${character} `;
813
+ this.position++;
814
+ continue;
815
+ }
816
+ if (character === "&") {
817
+ this.position++;
818
+ continue;
819
+ }
820
+ if (character === "~") {
821
+ this.position++;
822
+ result += " ";
823
+ continue;
824
+ }
825
+ if (character === ".") {
826
+ const marker = TRAILING_LAYOUT_MARKER_PATTERN.exec(result);
827
+ const node = marker ? this.layoutNodes[Number(marker[1])] : undefined;
828
+ if (node?.type === "matrix") {
829
+ const lastLine = node.lines.length - 1;
830
+ node.lines[lastLine] = `${node.lines[lastLine] ?? ""}${character}`;
831
+ this.position++;
832
+ continue;
833
+ }
834
+ }
835
+ result += character;
836
+ this.position++;
837
+ }
838
+ if (endCharacter) {
839
+ this.supported = false;
840
+ }
841
+ return result;
842
+ }
843
+ parseWhitespace() {
844
+ while (this.position < this.source.length && /\s/.test(this.source[this.position] ?? "")) {
845
+ this.position++;
846
+ }
847
+ return " ";
848
+ }
849
+ parseCommand() {
850
+ this.position++;
851
+ if (this.position >= this.source.length) {
852
+ this.supported = false;
853
+ return "";
854
+ }
855
+ let command = "";
856
+ const first = this.source[this.position] ?? "";
857
+ if (/[A-Za-z]/.test(first)) {
858
+ const start = this.position;
859
+ while (this.position < this.source.length && /[A-Za-z]/.test(this.source[this.position] ?? "")) {
860
+ this.position++;
861
+ }
862
+ command = this.source.slice(start, this.position);
863
+ }
864
+ else {
865
+ command = first;
866
+ this.position++;
867
+ }
868
+ if (command === "\\") {
869
+ return "\n";
870
+ }
871
+ if (SPACING_COMMANDS.has(command)) {
872
+ return " ";
873
+ }
874
+ if (NEGATIVE_SPACING_COMMANDS.has(command)) {
875
+ return NEGATIVE_SPACE;
876
+ }
877
+ if (IGNORED_COMMANDS.has(command)) {
878
+ return "";
879
+ }
880
+ if (command === "{" ||
881
+ command === "}" ||
882
+ command === "$" ||
883
+ command === "%" ||
884
+ command === "#" ||
885
+ command === "_" ||
886
+ command === "&") {
887
+ return command;
888
+ }
889
+ if (command === "|") {
890
+ return "‖";
891
+ }
892
+ if (command === "not") {
893
+ const value = this.parseRequiredArgument(false).trim();
894
+ const negated = NEGATED_SYMBOLS[value];
895
+ if (negated !== undefined) {
896
+ return ` ${negated} `;
897
+ }
898
+ const characters = Array.from(value);
899
+ if (characters.length === 0) {
900
+ this.supported = false;
901
+ return "";
902
+ }
903
+ return ` ${characters[0]}\u0338${characters.slice(1).join("")} `;
904
+ }
905
+ if (LIMIT_OPERATORS.has(command)) {
906
+ return this.parseOperator(command, "bracket", true, true);
907
+ }
908
+ const symbol = SYMBOLS[command];
909
+ if (symbol !== undefined) {
910
+ if (DISPLAY_LIMIT_SYMBOLS.has(command)) {
911
+ return this.parseOperator(symbol, "script", true);
912
+ }
913
+ return command === "cdot" || command === "times" || RELATION_COMMANDS.has(command) ? ` ${symbol} ` : symbol;
914
+ }
915
+ if (NAMED_OPERATORS.has(command)) {
916
+ return `${NAMED_OPERATOR_START}${command}${NAMED_OPERATOR_END}`;
917
+ }
918
+ if (SIZE_COMMANDS.has(command)) {
919
+ return "";
920
+ }
921
+ if (command === "left" || command === "middle" || command === "right") {
922
+ if (this.source[this.position] === ".") {
923
+ this.position++;
924
+ }
925
+ return "";
926
+ }
927
+ if (command === "frac" || command === "dfrac" || command === "tfrac") {
928
+ const shouldStack = this.display && this.stackFractions && command !== "tfrac";
929
+ const numerator = this.parseRequiredArgument(!shouldStack);
930
+ const denominator = this.parseRequiredArgument(!shouldStack);
931
+ if (shouldStack) {
932
+ const index = this.layoutNodes.push({
933
+ type: "fraction",
934
+ numerator: normalizeOutput(numerator),
935
+ denominator: normalizeOutput(denominator),
936
+ }) - 1;
937
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
938
+ }
939
+ return formatFraction(numerator, denominator);
940
+ }
941
+ if (command === "sqrt") {
942
+ const degree = this.parseOptionalArgument()?.trim();
943
+ const value = this.parseRequiredArgument();
944
+ if (degree === undefined || degree === "2") {
945
+ return formatRoot(value);
946
+ }
947
+ if (degree === "3") {
948
+ return formatRoot(value, "∛");
949
+ }
950
+ if (degree === "4") {
951
+ return formatRoot(value, "∜");
952
+ }
953
+ return `${formatScript(degree, "sup")}${formatRoot(value)}`;
954
+ }
955
+ if (command === "boxed" || command === "fbox") {
956
+ return `[${this.parseRequiredArgument().trim()}]`;
957
+ }
958
+ if (command === "binom" || command === "dbinom" || command === "tbinom") {
959
+ return `(${this.parseRequiredArgument()} choose ${this.parseRequiredArgument()})`;
960
+ }
961
+ const accent = ACCENTS[command];
962
+ if (accent !== undefined) {
963
+ const value = this.parseRequiredArgument();
964
+ return Array.from(value).length === 1 ? `${value}${accent}` : `${command}(${value})`;
965
+ }
966
+ if (command === "mathbb") {
967
+ const value = this.parseRequiredArgument();
968
+ return Array.from(value, (character) => BLACKBOARD[character] ?? character).join("");
969
+ }
970
+ if (command === "operatorname") {
971
+ const starred = this.source[this.position] === "*";
972
+ if (starred) {
973
+ this.position++;
974
+ }
975
+ const operator = normalizeOutput(this.parseRequiredArgument()).trim();
976
+ return this.parseOperator(operator, "bracket", starred, true);
977
+ }
978
+ if (command === "mod" || command === "bmod") {
979
+ return " mod ";
980
+ }
981
+ if (command === "pmod" || command === "pod") {
982
+ const value = this.parseRequiredArgument().trim();
983
+ return command === "pmod" ? ` (mod ${value})` : ` (${value})`;
984
+ }
985
+ if (command === "overset" || command === "stackrel") {
986
+ const upper = this.parseRequiredArgument();
987
+ const value = this.parseRequiredArgument().trim();
988
+ return `${value}${formatScript(upper, "sup")}`;
989
+ }
990
+ if (command === "underset") {
991
+ const lower = this.parseRequiredArgument();
992
+ const value = this.parseRequiredArgument().trim();
993
+ return `${value}${formatScript(lower, "sub")}`;
994
+ }
995
+ if (PLAIN_WRAPPERS.has(command)) {
996
+ const value = this.parseRequiredArgument();
997
+ return command.startsWith("text") || command === "mbox" ? value : value.trim();
998
+ }
999
+ if (command === "begin") {
1000
+ return this.parseEnvironment();
1001
+ }
1002
+ if (command === "end") {
1003
+ this.supported = false;
1004
+ return "";
1005
+ }
1006
+ this.supported = false;
1007
+ return `\\${command}`;
1008
+ }
1009
+ parseOperator(operator, inlineLowerStyle, displayLimits, spaced = false) {
1010
+ let useDisplayLimits = displayLimits;
1011
+ let modifierPosition = this.position;
1012
+ while (modifierPosition < this.source.length && /[ \t]/.test(this.source[modifierPosition] ?? "")) {
1013
+ modifierPosition++;
1014
+ }
1015
+ const modifier = /^\\(limits|nolimits)(?![A-Za-z])/.exec(this.source.slice(modifierPosition));
1016
+ if (modifier) {
1017
+ useDisplayLimits = modifier[1] === "limits";
1018
+ this.position = modifierPosition + modifier[0].length;
1019
+ }
1020
+ let lower;
1021
+ let upper;
1022
+ while (true) {
1023
+ let scriptPosition = this.position;
1024
+ while (scriptPosition < this.source.length && /[ \t]/.test(this.source[scriptPosition] ?? "")) {
1025
+ scriptPosition++;
1026
+ }
1027
+ const kind = this.source[scriptPosition];
1028
+ if (kind !== "_" && kind !== "^") {
1029
+ break;
1030
+ }
1031
+ this.position = scriptPosition + 1;
1032
+ const value = normalizeOutput(this.parseRequiredArgument(false)).replaceAll(" ", "");
1033
+ if (kind === "_") {
1034
+ if (lower !== undefined) {
1035
+ this.supported = false;
1036
+ }
1037
+ lower = value;
1038
+ }
1039
+ else {
1040
+ if (upper !== undefined) {
1041
+ this.supported = false;
1042
+ }
1043
+ upper = value;
1044
+ }
1045
+ }
1046
+ if (this.display && useDisplayLimits && (lower !== undefined || upper !== undefined)) {
1047
+ const index = this.layoutNodes.push({ type: "operator", operator, lower, upper }) - 1;
1048
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
1049
+ }
1050
+ let rendered = operator;
1051
+ if (lower !== undefined) {
1052
+ rendered += inlineLowerStyle === "bracket" ? `[${lower}]` : formatScript(lower, "sub");
1053
+ }
1054
+ if (upper !== undefined) {
1055
+ rendered += formatScript(upper, "sup");
1056
+ }
1057
+ return spaced ? ` ${rendered} ` : rendered;
1058
+ }
1059
+ parseRequiredArgument(stackFractions = true) {
1060
+ const previousStackFractions = this.stackFractions;
1061
+ this.stackFractions = previousStackFractions && stackFractions;
1062
+ const value = this.parseRequiredArgumentValue();
1063
+ this.stackFractions = previousStackFractions;
1064
+ return value;
1065
+ }
1066
+ parseRequiredArgumentValue() {
1067
+ while (this.position < this.source.length && /[ \t]/.test(this.source[this.position] ?? "")) {
1068
+ this.position++;
1069
+ }
1070
+ if (this.position >= this.source.length) {
1071
+ this.supported = false;
1072
+ return "";
1073
+ }
1074
+ if (this.source[this.position] === "{") {
1075
+ this.position++;
1076
+ return this.parseSequence("}");
1077
+ }
1078
+ if (this.source[this.position] === "\\") {
1079
+ return this.parseCommand();
1080
+ }
1081
+ const value = this.source[this.position] ?? "";
1082
+ this.position++;
1083
+ return value;
1084
+ }
1085
+ parseOptionalArgument() {
1086
+ while (this.position < this.source.length && /[ \t]/.test(this.source[this.position] ?? "")) {
1087
+ this.position++;
1088
+ }
1089
+ if (this.source[this.position] !== "[") {
1090
+ return undefined;
1091
+ }
1092
+ const end = this.source.indexOf("]", this.position + 1);
1093
+ if (end < 0) {
1094
+ this.supported = false;
1095
+ return undefined;
1096
+ }
1097
+ const value = this.source.slice(this.position + 1, end);
1098
+ this.position = end + 1;
1099
+ return this.renderNested(value);
1100
+ }
1101
+ readRawGroup() {
1102
+ while (this.position < this.source.length && /[ \t]/.test(this.source[this.position] ?? "")) {
1103
+ this.position++;
1104
+ }
1105
+ if (this.source[this.position] !== "{") {
1106
+ this.supported = false;
1107
+ return undefined;
1108
+ }
1109
+ const start = ++this.position;
1110
+ let depth = 1;
1111
+ while (this.position < this.source.length) {
1112
+ const character = this.source[this.position];
1113
+ if (character === "\\") {
1114
+ this.position += 2;
1115
+ continue;
1116
+ }
1117
+ if (character === "{")
1118
+ depth++;
1119
+ if (character === "}")
1120
+ depth--;
1121
+ if (depth === 0) {
1122
+ const value = this.source.slice(start, this.position);
1123
+ this.position++;
1124
+ return value;
1125
+ }
1126
+ this.position++;
1127
+ }
1128
+ this.supported = false;
1129
+ return undefined;
1130
+ }
1131
+ splitEnvironmentRows(body) {
1132
+ return body.split(/\\\\(?:\[[^\]\n]*\])?/);
1133
+ }
1134
+ parseEnvironment() {
1135
+ const environment = this.readRawGroup();
1136
+ if (!environment) {
1137
+ return "";
1138
+ }
1139
+ const endMarker = `\\end{${environment}}`;
1140
+ const end = this.source.indexOf(endMarker, this.position);
1141
+ if (end < 0) {
1142
+ this.supported = false;
1143
+ return "";
1144
+ }
1145
+ const body = this.source.slice(this.position, end);
1146
+ this.position = end + endMarker.length;
1147
+ if (environment === "equation" || environment === "equation*" || environment === "displaymath") {
1148
+ return this.renderNested(body).trim();
1149
+ }
1150
+ if (environment === "aligned" ||
1151
+ environment === "align" ||
1152
+ environment === "align*" ||
1153
+ environment === "alignedat" ||
1154
+ environment === "alignat" ||
1155
+ environment === "alignat*" ||
1156
+ environment === "gather" ||
1157
+ environment === "gathered" ||
1158
+ environment === "multline" ||
1159
+ environment === "multline*" ||
1160
+ environment === "split") {
1161
+ const alignedAt = ["alignedat", "alignat", "alignat*"].includes(environment);
1162
+ const alignedBody = alignedAt ? body.replace(/^\s*\{[^}]*\}/, "") : body;
1163
+ return this.splitEnvironmentRows(alignedBody)
1164
+ .map((row) => {
1165
+ const cells = row.split("&");
1166
+ const source = alignedAt
1167
+ ? Array.from({ length: Math.ceil(cells.length / 2) }, (_, index) => cells.slice(index * 2, index * 2 + 2).join("")).join(" ")
1168
+ : cells.join("");
1169
+ return this.renderNested(source).trim();
1170
+ })
1171
+ .filter(Boolean)
1172
+ .join("\n");
1173
+ }
1174
+ if (environment === "cases" || environment === "cases*") {
1175
+ const rows = this.splitEnvironmentRows(body)
1176
+ .map((row) => row.split("&").map((cell) => this.renderNested(cell, false).trim()))
1177
+ .filter((row) => row.some(Boolean));
1178
+ return rows
1179
+ .map((row, index) => {
1180
+ const value = (row[0] ?? "").replace(/,\s*$/, "");
1181
+ const condition = row[1] ?? "";
1182
+ const delimiter = index === 0 ? "⎧" : index === rows.length - 1 ? "⎩" : "⎨";
1183
+ const conditionPrefix = /^(?:if|when|for|otherwise)\b/i.test(condition) ? " " : " if ";
1184
+ return `${delimiter} ${value}${condition ? `${conditionPrefix}${condition}` : ""}`;
1185
+ })
1186
+ .join("\n");
1187
+ }
1188
+ if (["array", "matrix", "smallmatrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix"].includes(environment)) {
1189
+ const matrixBody = environment === "array" ? body.replace(/^\s*\{[^}]*\}/, "") : body;
1190
+ return this.renderMatrix(environment, matrixBody);
1191
+ }
1192
+ this.supported = false;
1193
+ return body;
1194
+ }
1195
+ renderMatrix(environment, body) {
1196
+ const matrix = this.splitEnvironmentRows(body)
1197
+ .map((row) => row.split("&").map((cell) => this.renderNested(cell, false).trim()))
1198
+ .filter((row) => row.some(Boolean));
1199
+ const columnCount = Math.max(0, ...matrix.map((row) => row.length));
1200
+ const columnWidths = Array.from({ length: columnCount }, (_, column) => Math.max(0, ...matrix.map((row) => visibleWidth(row[column] ?? ""))));
1201
+ const rows = matrix.map((row) => Array.from({ length: columnCount }, (_, column) => {
1202
+ const cell = row[column] ?? "";
1203
+ return `${cell}${PROTECTED_SPACE.repeat(Math.max(0, (columnWidths[column] ?? 0) - visibleWidth(cell)))}`;
1204
+ }).join(" │ "));
1205
+ let lines;
1206
+ if (environment === "array" || environment === "matrix" || environment === "smallmatrix") {
1207
+ lines = rows;
1208
+ }
1209
+ else {
1210
+ const delimiters = {
1211
+ pmatrix: ["⎛", "⎞", "⎜", "⎟", "⎝", "⎠"],
1212
+ bmatrix: ["⎡", "⎤", "⎢", "⎥", "⎣", "⎦"],
1213
+ Bmatrix: ["⎧", "⎫", "⎨", "⎬", "⎩", "⎭"],
1214
+ vmatrix: ["│", "│", "│", "│", "│", "│"],
1215
+ Vmatrix: ["║", "║", "║", "║", "║", "║"],
1216
+ };
1217
+ const delimiter = delimiters[environment];
1218
+ if (!delimiter) {
1219
+ this.supported = false;
1220
+ return rows.join("\n");
1221
+ }
1222
+ lines = rows.map((row, index) => {
1223
+ const left = index === 0 ? delimiter[0] : index === rows.length - 1 ? delimiter[4] : delimiter[2];
1224
+ const right = index === 0 ? delimiter[1] : index === rows.length - 1 ? delimiter[5] : delimiter[3];
1225
+ return `${left} ${row} ${right}`;
1226
+ });
1227
+ }
1228
+ if (lines.length <= 1) {
1229
+ return lines[0] ?? "";
1230
+ }
1231
+ const index = this.layoutNodes.push({ type: "matrix", lines, baseline: 0 }) - 1;
1232
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
1233
+ }
1234
+ renderNested(source, stackFractions = true) {
1235
+ const rendered = new LatexParser(source, this.layoutNodes, this.display && stackFractions).render();
1236
+ if (rendered === undefined) {
1237
+ this.supported = false;
1238
+ return source;
1239
+ }
1240
+ return rendered;
1241
+ }
1242
+ }
1243
+ /**
1244
+ * Render a basic LaTeX math expression as terminal-friendly Unicode text.
1245
+ * Returns undefined when the expression contains unsupported or malformed syntax.
1246
+ */
1247
+ export function renderLatex(source, options = {}) {
1248
+ const layoutNodes = [];
1249
+ const rendered = new LatexParser(source, layoutNodes, options.display === true).render();
1250
+ if (rendered === undefined) {
1251
+ return undefined;
1252
+ }
1253
+ if (layoutNodes.length === 0) {
1254
+ return rendered.replaceAll(PROTECTED_SPACE, " ");
1255
+ }
1256
+ const lines = renderLayout(rendered, layoutNodes).lines;
1257
+ const indentation = Math.min(...lines.filter((line) => line.trim()).map((line) => line.length - line.trimStart().length));
1258
+ return lines
1259
+ .map((line) => line.slice(indentation).trimEnd())
1260
+ .join("\n")
1261
+ .trimEnd()
1262
+ .replaceAll(PROTECTED_SPACE, " ");
1263
+ }
1264
+ //# sourceMappingURL=latex.js.map