python-codex 0.2.4__py3-none-any.whl → 0.2.6__py3-none-any.whl
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.
- pycodex/context.py +4 -18
- pycodex/interactive_session.py +15 -1
- pycodex/model.py +153 -11
- pycodex/model_metadata.py +31 -0
- pycodex/prompts/models.json +334 -0
- pycodex/tools/unified_exec_manager.py +32 -1
- pycodex/utils/compactor.py +5 -87
- {python_codex-0.2.4.dist-info → python_codex-0.2.6.dist-info}/METADATA +34 -6
- {python_codex-0.2.4.dist-info → python_codex-0.2.6.dist-info}/RECORD +14 -13
- workspace_server/app.py +57 -1
- workspace_server/workspace.html +309 -72
- {python_codex-0.2.4.dist-info → python_codex-0.2.6.dist-info}/WHEEL +0 -0
- {python_codex-0.2.4.dist-info → python_codex-0.2.6.dist-info}/entry_points.txt +0 -0
- {python_codex-0.2.4.dist-info → python_codex-0.2.6.dist-info}/licenses/LICENSE +0 -0
workspace_server/workspace.html
CHANGED
|
@@ -4,25 +4,37 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>__WORKSPACE_TITLE__</title>
|
|
7
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
|
|
7
8
|
<style>
|
|
8
9
|
:root {
|
|
9
10
|
color-scheme: light;
|
|
10
|
-
--bg: #
|
|
11
|
-
--panel: #
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
11
|
+
--bg: #eef3f6;
|
|
12
|
+
--panel: #f8fbfd;
|
|
13
|
+
--panel-deep: #f2f6f8;
|
|
14
|
+
--panel-raised: #ffffff;
|
|
15
|
+
--panel-hover: #e8f1f5;
|
|
16
|
+
--board-chrome: #ffffff;
|
|
17
|
+
--ink: #172630;
|
|
18
|
+
--muted: #60727d;
|
|
19
|
+
--line: #cbd8df;
|
|
20
|
+
--line-strong: #aebfc9;
|
|
21
|
+
--accent: #087f9a;
|
|
16
22
|
--accent-ink: #ffffff;
|
|
17
|
-
--
|
|
18
|
-
--
|
|
19
|
-
--
|
|
20
|
-
--
|
|
21
|
-
--
|
|
22
|
-
--
|
|
23
|
-
--
|
|
24
|
-
--
|
|
25
|
-
--
|
|
23
|
+
--accent-soft: #e6f6f8;
|
|
24
|
+
--warn: #b77908;
|
|
25
|
+
--warn-ink: #62480c;
|
|
26
|
+
--warn-soft: #fff7df;
|
|
27
|
+
--info: #2868b2;
|
|
28
|
+
--info-soft: #edf5ff;
|
|
29
|
+
--success: #247a52;
|
|
30
|
+
--success-line: #8bc9a8;
|
|
31
|
+
--success-soft: #edf9f2;
|
|
32
|
+
--danger: #b33d50;
|
|
33
|
+
--danger-soft: #fff0f2;
|
|
34
|
+
--violet: #6850a4;
|
|
35
|
+
--violet-soft: #f4f0ff;
|
|
36
|
+
--code: #f1f5f7;
|
|
37
|
+
--entry-shadow: 0 1px 2px rgba(27, 57, 72, 0.06);
|
|
26
38
|
--space-1: 2px;
|
|
27
39
|
--space-2: 4px;
|
|
28
40
|
--space-3: 6px;
|
|
@@ -51,14 +63,14 @@
|
|
|
51
63
|
min-width: 0;
|
|
52
64
|
}
|
|
53
65
|
.workspace.collapsed .splitter::after {
|
|
54
|
-
background:
|
|
66
|
+
background: var(--accent);
|
|
55
67
|
}
|
|
56
68
|
.board-pane {
|
|
57
69
|
min-width: 0;
|
|
58
70
|
height: 100dvh;
|
|
59
71
|
display: grid;
|
|
60
72
|
grid-template-rows: auto minmax(0, 1fr);
|
|
61
|
-
background:
|
|
73
|
+
background: var(--board-chrome);
|
|
62
74
|
}
|
|
63
75
|
.boardbar {
|
|
64
76
|
min-width: 0;
|
|
@@ -100,10 +112,10 @@
|
|
|
100
112
|
text-decoration: none;
|
|
101
113
|
}
|
|
102
114
|
.workspace-back:hover {
|
|
103
|
-
background:
|
|
115
|
+
background: var(--accent-soft);
|
|
104
116
|
}
|
|
105
117
|
.workspace-back:focus {
|
|
106
|
-
outline: 2px solid
|
|
118
|
+
outline: 2px solid var(--accent);
|
|
107
119
|
outline-offset: 1px;
|
|
108
120
|
}
|
|
109
121
|
.workspace-back::before {
|
|
@@ -119,16 +131,16 @@
|
|
|
119
131
|
min-width: 0;
|
|
120
132
|
width: 100%;
|
|
121
133
|
height: 100%;
|
|
122
|
-
background:
|
|
134
|
+
background: var(--board-chrome);
|
|
123
135
|
}
|
|
124
136
|
.splitter {
|
|
125
137
|
position: relative;
|
|
126
138
|
width: 8px;
|
|
127
139
|
height: 100dvh;
|
|
128
140
|
border: 0;
|
|
129
|
-
border-left: 1px solid
|
|
130
|
-
border-right: 1px solid
|
|
131
|
-
background:
|
|
141
|
+
border-left: 1px solid var(--line);
|
|
142
|
+
border-right: 1px solid var(--line);
|
|
143
|
+
background: var(--panel-hover);
|
|
132
144
|
cursor: col-resize;
|
|
133
145
|
padding: 0;
|
|
134
146
|
touch-action: none;
|
|
@@ -141,17 +153,17 @@
|
|
|
141
153
|
width: 3px;
|
|
142
154
|
height: 42px;
|
|
143
155
|
border-radius: 999px;
|
|
144
|
-
background:
|
|
156
|
+
background: var(--muted);
|
|
145
157
|
transform: translate(-50%, -50%);
|
|
146
158
|
}
|
|
147
159
|
.splitter:hover,
|
|
148
160
|
.workspace.resizing .splitter {
|
|
149
|
-
background: #
|
|
150
|
-
border-color:
|
|
161
|
+
background: #dce9ee;
|
|
162
|
+
border-color: var(--line-strong);
|
|
151
163
|
}
|
|
152
164
|
.splitter:hover::after,
|
|
153
165
|
.workspace.resizing .splitter::after {
|
|
154
|
-
background:
|
|
166
|
+
background: var(--accent);
|
|
155
167
|
}
|
|
156
168
|
.workspace.resizing,
|
|
157
169
|
.workspace.resizing * {
|
|
@@ -189,8 +201,8 @@
|
|
|
189
201
|
width: var(--context-meter-size);
|
|
190
202
|
height: var(--context-meter-size);
|
|
191
203
|
border-radius: 999px;
|
|
192
|
-
background: conic-gradient(
|
|
193
|
-
color:
|
|
204
|
+
background: conic-gradient(var(--accent) 0 var(--context-remaining), var(--line-strong) 0 100%);
|
|
205
|
+
color: var(--muted);
|
|
194
206
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
195
207
|
font-size: 9px;
|
|
196
208
|
line-height: 1;
|
|
@@ -204,7 +216,7 @@
|
|
|
204
216
|
position: absolute;
|
|
205
217
|
inset: 4px;
|
|
206
218
|
border-radius: 999px;
|
|
207
|
-
background:
|
|
219
|
+
background: var(--panel);
|
|
208
220
|
}
|
|
209
221
|
.context-meter-value {
|
|
210
222
|
position: relative;
|
|
@@ -226,9 +238,9 @@
|
|
|
226
238
|
min-width: 88px;
|
|
227
239
|
max-width: 180px;
|
|
228
240
|
height: 31px;
|
|
229
|
-
border: 1px solid
|
|
241
|
+
border: 1px solid var(--line);
|
|
230
242
|
border-radius: var(--radius-sm);
|
|
231
|
-
background:
|
|
243
|
+
background: var(--panel-raised);
|
|
232
244
|
color: var(--ink);
|
|
233
245
|
padding: 0 var(--space-3) 0 var(--space-4);
|
|
234
246
|
font: inherit;
|
|
@@ -237,12 +249,12 @@
|
|
|
237
249
|
}
|
|
238
250
|
.tab:focus-within,
|
|
239
251
|
.tab-new:focus {
|
|
240
|
-
outline: 2px solid
|
|
252
|
+
outline: 2px solid var(--accent);
|
|
241
253
|
outline-offset: 1px;
|
|
242
254
|
}
|
|
243
255
|
.tab.active {
|
|
244
|
-
border-color:
|
|
245
|
-
background:
|
|
256
|
+
border-color: var(--accent);
|
|
257
|
+
background: var(--accent-soft);
|
|
246
258
|
box-shadow: inset 0 -2px 0 var(--accent);
|
|
247
259
|
}
|
|
248
260
|
.tab-status {
|
|
@@ -280,7 +292,7 @@
|
|
|
280
292
|
height: 31px;
|
|
281
293
|
border: 1px solid var(--line);
|
|
282
294
|
border-radius: var(--radius-md);
|
|
283
|
-
background:
|
|
295
|
+
background: var(--panel-raised);
|
|
284
296
|
color: var(--muted);
|
|
285
297
|
padding: 0;
|
|
286
298
|
line-height: 1;
|
|
@@ -314,7 +326,7 @@
|
|
|
314
326
|
.tab-close:hover,
|
|
315
327
|
.tab-new:hover {
|
|
316
328
|
color: var(--ink);
|
|
317
|
-
background:
|
|
329
|
+
background: var(--panel-hover);
|
|
318
330
|
}
|
|
319
331
|
.log {
|
|
320
332
|
min-height: 0;
|
|
@@ -324,45 +336,45 @@
|
|
|
324
336
|
display: flex;
|
|
325
337
|
flex-direction: column;
|
|
326
338
|
gap: var(--space-4);
|
|
327
|
-
background:
|
|
339
|
+
background: var(--bg);
|
|
328
340
|
}
|
|
329
341
|
.entry {
|
|
330
342
|
min-width: 0;
|
|
331
343
|
border: 1px solid var(--line);
|
|
332
344
|
border-radius: var(--radius-sm);
|
|
333
345
|
padding: var(--space-4) var(--space-5);
|
|
334
|
-
background:
|
|
346
|
+
background: var(--panel-raised);
|
|
335
347
|
box-shadow: var(--entry-shadow);
|
|
336
348
|
}
|
|
337
349
|
.entry.user {
|
|
338
|
-
border-color:
|
|
350
|
+
border-color: var(--warn);
|
|
339
351
|
background: var(--warn-soft);
|
|
340
|
-
color:
|
|
352
|
+
color: var(--warn-ink);
|
|
341
353
|
}
|
|
342
354
|
.entry.response,
|
|
343
355
|
.entry.assistant {
|
|
344
|
-
border-color:
|
|
345
|
-
background:
|
|
356
|
+
border-color: var(--line);
|
|
357
|
+
background: var(--panel-raised);
|
|
346
358
|
}
|
|
347
359
|
.entry.thinking {
|
|
348
|
-
border-color:
|
|
349
|
-
background:
|
|
350
|
-
color:
|
|
360
|
+
border-color: var(--success-line);
|
|
361
|
+
background: var(--success-soft);
|
|
362
|
+
color: var(--success);
|
|
351
363
|
animation: thinking-breathe 4.8s ease-in-out infinite;
|
|
352
364
|
}
|
|
353
365
|
.entry.control {
|
|
354
|
-
border-color: #
|
|
366
|
+
border-color: #b7d3ee;
|
|
355
367
|
background: var(--info-soft);
|
|
356
368
|
color: var(--info);
|
|
357
369
|
}
|
|
358
370
|
.entry.tool {
|
|
359
|
-
border-color: #
|
|
371
|
+
border-color: #d8cdf1;
|
|
360
372
|
background: var(--violet-soft);
|
|
361
373
|
color: var(--violet);
|
|
362
374
|
font-size: 12px;
|
|
363
375
|
}
|
|
364
376
|
.entry.error {
|
|
365
|
-
border-color: #
|
|
377
|
+
border-color: #efb8c1;
|
|
366
378
|
background: var(--danger-soft);
|
|
367
379
|
color: var(--danger);
|
|
368
380
|
}
|
|
@@ -421,16 +433,35 @@
|
|
|
421
433
|
vertical-align: top;
|
|
422
434
|
}
|
|
423
435
|
.markdown th {
|
|
424
|
-
background:
|
|
436
|
+
background: var(--accent-soft);
|
|
425
437
|
font-weight: 650;
|
|
426
438
|
}
|
|
427
439
|
.markdown a {
|
|
428
|
-
color:
|
|
440
|
+
color: var(--info);
|
|
429
441
|
text-decoration: none;
|
|
430
442
|
}
|
|
431
443
|
.markdown a:hover {
|
|
432
444
|
text-decoration: underline;
|
|
433
445
|
}
|
|
446
|
+
.markdown .katex-display {
|
|
447
|
+
margin: 0 0 var(--space-4);
|
|
448
|
+
overflow-x: auto;
|
|
449
|
+
overflow-y: hidden;
|
|
450
|
+
overflow-wrap: normal;
|
|
451
|
+
word-break: normal;
|
|
452
|
+
}
|
|
453
|
+
.markdown .katex {
|
|
454
|
+
overflow-wrap: normal;
|
|
455
|
+
word-break: normal;
|
|
456
|
+
}
|
|
457
|
+
.markdown .katex .text {
|
|
458
|
+
white-space: normal;
|
|
459
|
+
overflow-wrap: normal;
|
|
460
|
+
word-break: normal;
|
|
461
|
+
}
|
|
462
|
+
.markdown .katex-display:last-child {
|
|
463
|
+
margin-bottom: 0;
|
|
464
|
+
}
|
|
434
465
|
.composer {
|
|
435
466
|
position: relative;
|
|
436
467
|
min-width: 0;
|
|
@@ -438,7 +469,7 @@
|
|
|
438
469
|
display: grid;
|
|
439
470
|
gap: var(--space-3);
|
|
440
471
|
align-content: end;
|
|
441
|
-
background:
|
|
472
|
+
background: var(--panel);
|
|
442
473
|
}
|
|
443
474
|
textarea {
|
|
444
475
|
min-width: 0;
|
|
@@ -448,15 +479,15 @@
|
|
|
448
479
|
border: 1px solid var(--line);
|
|
449
480
|
border-radius: var(--radius-sm);
|
|
450
481
|
padding: var(--space-4) var(--space-5);
|
|
451
|
-
background:
|
|
482
|
+
background: var(--panel-deep);
|
|
452
483
|
color: var(--ink);
|
|
453
484
|
font: inherit;
|
|
454
485
|
line-height: 1.4;
|
|
455
486
|
overflow-y: auto;
|
|
456
487
|
}
|
|
457
488
|
textarea:focus {
|
|
458
|
-
border-color:
|
|
459
|
-
box-shadow: 0 0 0 3px rgba(
|
|
489
|
+
border-color: var(--accent);
|
|
490
|
+
box-shadow: 0 0 0 3px rgba(8, 127, 154, 0.18);
|
|
460
491
|
outline: 0;
|
|
461
492
|
}
|
|
462
493
|
.actions {
|
|
@@ -492,8 +523,8 @@
|
|
|
492
523
|
text-overflow: ellipsis;
|
|
493
524
|
padding: var(--space-1) var(--space-4) var(--space-1) 18px;
|
|
494
525
|
border-radius: 999px;
|
|
495
|
-
background: rgba(
|
|
496
|
-
border: 1px solid rgba(
|
|
526
|
+
background: rgba(230, 246, 248, 0.96);
|
|
527
|
+
border: 1px solid rgba(8, 127, 154, 0.35);
|
|
497
528
|
font: inherit;
|
|
498
529
|
font-size: 12px;
|
|
499
530
|
cursor: pointer;
|
|
@@ -505,8 +536,8 @@
|
|
|
505
536
|
display: none;
|
|
506
537
|
}
|
|
507
538
|
.spinner:focus-visible {
|
|
508
|
-
border-color:
|
|
509
|
-
box-shadow: 0 0 0 3px rgba(
|
|
539
|
+
border-color: var(--accent);
|
|
540
|
+
box-shadow: 0 0 0 3px rgba(8, 127, 154, 0.18);
|
|
510
541
|
outline: 0;
|
|
511
542
|
}
|
|
512
543
|
.spinner-wrap:has(.spinner:not(:empty)) {
|
|
@@ -525,12 +556,12 @@
|
|
|
525
556
|
animation: spinner-pulse 1.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
526
557
|
}
|
|
527
558
|
.spinner.notify-enabled {
|
|
528
|
-
color:
|
|
529
|
-
background:
|
|
530
|
-
border-color:
|
|
559
|
+
color: var(--success);
|
|
560
|
+
background: var(--success-soft);
|
|
561
|
+
border-color: var(--success-line);
|
|
531
562
|
box-shadow:
|
|
532
|
-
inset 0 1px 2px rgba(
|
|
533
|
-
inset 0 0 0 1px rgba(
|
|
563
|
+
inset 0 1px 2px rgba(27, 57, 72, 0.08),
|
|
564
|
+
inset 0 0 0 1px rgba(36, 122, 82, 0.1);
|
|
534
565
|
}
|
|
535
566
|
.toast {
|
|
536
567
|
position: absolute;
|
|
@@ -539,11 +570,11 @@
|
|
|
539
570
|
z-index: 5;
|
|
540
571
|
width: max-content;
|
|
541
572
|
max-width: min(320px, calc(100vw - var(--space-6) * 2));
|
|
542
|
-
border: 1px solid
|
|
573
|
+
border: 1px solid var(--line-strong);
|
|
543
574
|
border-radius: var(--radius-sm);
|
|
544
|
-
background:
|
|
575
|
+
background: var(--panel-raised);
|
|
545
576
|
color: var(--ink);
|
|
546
|
-
box-shadow: 0 8px 20px rgba(
|
|
577
|
+
box-shadow: 0 8px 20px rgba(27, 57, 72, 0.14);
|
|
547
578
|
padding: var(--space-4) var(--space-6);
|
|
548
579
|
font-size: 12px;
|
|
549
580
|
opacity: 0;
|
|
@@ -568,14 +599,14 @@
|
|
|
568
599
|
}
|
|
569
600
|
@keyframes thinking-breathe {
|
|
570
601
|
0%, 100% {
|
|
571
|
-
border-color:
|
|
602
|
+
border-color: var(--success-line);
|
|
572
603
|
box-shadow: var(--entry-shadow);
|
|
573
604
|
}
|
|
574
605
|
50% {
|
|
575
|
-
border-color:
|
|
606
|
+
border-color: var(--success);
|
|
576
607
|
box-shadow:
|
|
577
|
-
0 0 0 2px rgba(
|
|
578
|
-
0 2px 7px rgba(
|
|
608
|
+
0 0 0 2px rgba(36, 122, 82, 0.14),
|
|
609
|
+
0 2px 7px rgba(27, 57, 72, 0.08);
|
|
579
610
|
}
|
|
580
611
|
}
|
|
581
612
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -641,6 +672,8 @@
|
|
|
641
672
|
</div>
|
|
642
673
|
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
|
|
643
674
|
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.6/dist/purify.min.js"></script>
|
|
675
|
+
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js"></script>
|
|
676
|
+
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/contrib/auto-render.min.js"></script>
|
|
644
677
|
<script>
|
|
645
678
|
const log = document.getElementById("log");
|
|
646
679
|
const spinner = document.getElementById("spinner");
|
|
@@ -672,6 +705,14 @@
|
|
|
672
705
|
const markdownRenderer = window.markdownit
|
|
673
706
|
? window.markdownit({html: false, linkify: true, breaks: false})
|
|
674
707
|
: null;
|
|
708
|
+
const mathDelimiters = [
|
|
709
|
+
{left: "$$", right: "$$", display: true},
|
|
710
|
+
{left: "\\[", right: "\\]", display: true},
|
|
711
|
+
{left: "\\(", right: "\\)", display: false},
|
|
712
|
+
{left: "$", right: "$", display: false},
|
|
713
|
+
];
|
|
714
|
+
const mathTokenPrefix = "\uE000math";
|
|
715
|
+
const mathTokenSuffix = "\uE001";
|
|
675
716
|
|
|
676
717
|
function relativeUrl(path) {
|
|
677
718
|
return new URL(path, window.location.href).toString();
|
|
@@ -708,17 +749,213 @@
|
|
|
708
749
|
root.textContent = source || "";
|
|
709
750
|
return;
|
|
710
751
|
}
|
|
711
|
-
const
|
|
752
|
+
const protectedMath = protectMath(String(source || ""));
|
|
753
|
+
const dirtyHtml = markdownRenderer.render(protectedMath.source);
|
|
712
754
|
root.innerHTML = window.DOMPurify.sanitize(dirtyHtml, {
|
|
713
755
|
USE_PROFILES: {html: true},
|
|
714
756
|
ADD_ATTR: ["target", "rel"],
|
|
715
757
|
});
|
|
758
|
+
renderProtectedMath(root, protectedMath.expressions);
|
|
716
759
|
root.querySelectorAll("a").forEach((anchor) => {
|
|
717
760
|
anchor.target = "_blank";
|
|
718
761
|
anchor.rel = "noopener noreferrer";
|
|
719
762
|
});
|
|
720
763
|
}
|
|
721
764
|
|
|
765
|
+
function isEscapedAt(source, index) {
|
|
766
|
+
let slashCount = 0;
|
|
767
|
+
for (let cursor = index - 1; cursor >= 0 && source[cursor] === "\\"; cursor -= 1) {
|
|
768
|
+
slashCount += 1;
|
|
769
|
+
}
|
|
770
|
+
return slashCount % 2 === 1;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
function countBackticks(source, index) {
|
|
774
|
+
let count = 0;
|
|
775
|
+
while (source[index + count] === "`") {
|
|
776
|
+
count += 1;
|
|
777
|
+
}
|
|
778
|
+
return count;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
function findMathEnd(source, start, delimiter) {
|
|
782
|
+
let searchFrom = start + delimiter.left.length;
|
|
783
|
+
while (searchFrom < source.length) {
|
|
784
|
+
const end = source.indexOf(delimiter.right, searchFrom);
|
|
785
|
+
if (end < 0) {
|
|
786
|
+
return -1;
|
|
787
|
+
}
|
|
788
|
+
if (!isEscapedAt(source, end)) {
|
|
789
|
+
if (
|
|
790
|
+
delimiter.left === "$" &&
|
|
791
|
+
(source[end - 1] === "$" || source[end + 1] === "$")
|
|
792
|
+
) {
|
|
793
|
+
searchFrom = end + delimiter.right.length;
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
return end;
|
|
797
|
+
}
|
|
798
|
+
searchFrom = end + delimiter.right.length;
|
|
799
|
+
}
|
|
800
|
+
return -1;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
function protectMath(source) {
|
|
804
|
+
const expressions = [];
|
|
805
|
+
let protectedSource = "";
|
|
806
|
+
let index = 0;
|
|
807
|
+
while (index < source.length) {
|
|
808
|
+
if (source[index] === "`") {
|
|
809
|
+
const tickCount = countBackticks(source, index);
|
|
810
|
+
const fence = "`".repeat(tickCount);
|
|
811
|
+
const close = source.indexOf(fence, index + tickCount);
|
|
812
|
+
if (close >= 0) {
|
|
813
|
+
const end = close + tickCount;
|
|
814
|
+
protectedSource += source.slice(index, end);
|
|
815
|
+
index = end;
|
|
816
|
+
continue;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
let matched = null;
|
|
821
|
+
if (!isEscapedAt(source, index)) {
|
|
822
|
+
for (const delimiter of mathDelimiters) {
|
|
823
|
+
if (
|
|
824
|
+
source.indexOf(delimiter.left, index) !== index ||
|
|
825
|
+
(delimiter.left === "$" && source[index + 1] === "$")
|
|
826
|
+
) {
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
const end = findMathEnd(source, index, delimiter);
|
|
830
|
+
if (end > index + delimiter.left.length) {
|
|
831
|
+
matched = {
|
|
832
|
+
delimiter: delimiter,
|
|
833
|
+
start: index,
|
|
834
|
+
end: end,
|
|
835
|
+
};
|
|
836
|
+
break;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (matched) {
|
|
842
|
+
const expressionIndex = expressions.length;
|
|
843
|
+
expressions.push({
|
|
844
|
+
body: source.slice(
|
|
845
|
+
matched.start + matched.delimiter.left.length,
|
|
846
|
+
matched.end,
|
|
847
|
+
),
|
|
848
|
+
delimiter: matched.delimiter,
|
|
849
|
+
});
|
|
850
|
+
protectedSource += mathTokenPrefix + expressionIndex + mathTokenSuffix;
|
|
851
|
+
index = matched.end + matched.delimiter.right.length;
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
protectedSource += source[index];
|
|
856
|
+
index += 1;
|
|
857
|
+
}
|
|
858
|
+
return {
|
|
859
|
+
source: protectedSource,
|
|
860
|
+
expressions: expressions,
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function renderProtectedMath(root, expressions) {
|
|
865
|
+
if (!expressions.length) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
const expressionByToken = new Map();
|
|
869
|
+
expressions.forEach((expression, index) => {
|
|
870
|
+
expressionByToken.set(
|
|
871
|
+
mathTokenPrefix + index + mathTokenSuffix,
|
|
872
|
+
expression,
|
|
873
|
+
);
|
|
874
|
+
});
|
|
875
|
+
const textWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
876
|
+
const textNodes = [];
|
|
877
|
+
let textNode = textWalker.nextNode();
|
|
878
|
+
while (textNode) {
|
|
879
|
+
textNodes.push(textNode);
|
|
880
|
+
textNode = textWalker.nextNode();
|
|
881
|
+
}
|
|
882
|
+
for (const textNode of textNodes) {
|
|
883
|
+
let value = textNode.nodeValue || "";
|
|
884
|
+
let cursor = 0;
|
|
885
|
+
let tokenIndex = value.indexOf(mathTokenPrefix, cursor);
|
|
886
|
+
if (tokenIndex < 0) {
|
|
887
|
+
continue;
|
|
888
|
+
}
|
|
889
|
+
const fragment = document.createDocumentFragment();
|
|
890
|
+
while (tokenIndex >= 0) {
|
|
891
|
+
const tokenEnd = value.indexOf(mathTokenSuffix, tokenIndex);
|
|
892
|
+
if (tokenEnd < 0) {
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
895
|
+
const token = value.slice(tokenIndex, tokenEnd + mathTokenSuffix.length);
|
|
896
|
+
const expression = expressionByToken.get(token);
|
|
897
|
+
if (!expression) {
|
|
898
|
+
break;
|
|
899
|
+
}
|
|
900
|
+
if (tokenIndex > cursor) {
|
|
901
|
+
fragment.appendChild(
|
|
902
|
+
document.createTextNode(value.slice(cursor, tokenIndex)),
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
const mathNode = document.createElement("span");
|
|
906
|
+
const sourceText =
|
|
907
|
+
expression.delimiter.left +
|
|
908
|
+
expression.body +
|
|
909
|
+
expression.delimiter.right;
|
|
910
|
+
if (window.renderMathInElement) {
|
|
911
|
+
mathNode.textContent = sourceText;
|
|
912
|
+
window.renderMathInElement(mathNode, {
|
|
913
|
+
delimiters: [
|
|
914
|
+
{
|
|
915
|
+
left: expression.delimiter.left,
|
|
916
|
+
right: expression.delimiter.right,
|
|
917
|
+
display: expression.delimiter.display,
|
|
918
|
+
},
|
|
919
|
+
],
|
|
920
|
+
throwOnError: false,
|
|
921
|
+
trust: false,
|
|
922
|
+
});
|
|
923
|
+
} else {
|
|
924
|
+
mathNode.textContent = expression.body;
|
|
925
|
+
}
|
|
926
|
+
fragment.appendChild(mathNode);
|
|
927
|
+
cursor = tokenEnd + mathTokenSuffix.length;
|
|
928
|
+
tokenIndex = value.indexOf(mathTokenPrefix, cursor);
|
|
929
|
+
}
|
|
930
|
+
if (cursor > 0) {
|
|
931
|
+
if (cursor < value.length) {
|
|
932
|
+
fragment.appendChild(document.createTextNode(value.slice(cursor)));
|
|
933
|
+
}
|
|
934
|
+
if (textNode.parentNode) {
|
|
935
|
+
textNode.parentNode.replaceChild(fragment, textNode);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
restoreUnrenderedMathTokens(root, expressionByToken);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
function restoreUnrenderedMathTokens(root, expressionByToken) {
|
|
943
|
+
const textWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
944
|
+
let textNode = textWalker.nextNode();
|
|
945
|
+
while (textNode) {
|
|
946
|
+
let value = textNode.nodeValue || "";
|
|
947
|
+
expressionByToken.forEach((expression, token) => {
|
|
948
|
+
const sourceText =
|
|
949
|
+
expression.delimiter.left +
|
|
950
|
+
expression.body +
|
|
951
|
+
expression.delimiter.right;
|
|
952
|
+
value = value.split(token).join(sourceText);
|
|
953
|
+
});
|
|
954
|
+
textNode.nodeValue = value;
|
|
955
|
+
textNode = textWalker.nextNode();
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
722
959
|
function loadChatWidth() {
|
|
723
960
|
const stored = Number(window.localStorage.getItem("pycodex.workspace.chatWidth") || 0);
|
|
724
961
|
if (stored > 0) setChatWidth(stored);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|