Spaces:
Running
Running
Update templates/index.html
Browse files- templates/index.html +142 -133
templates/index.html
CHANGED
@@ -126,36 +126,53 @@
|
|
126 |
text-align: left;
|
127 |
line-height: 1.8;
|
128 |
font-size: 16px;
|
129 |
-
background-color: transparent;
|
130 |
box-shadow: var(--box-shadow);
|
131 |
-
overflow: hidden;
|
132 |
}
|
133 |
|
134 |
-
|
135 |
-
|
136 |
padding: 20px;
|
137 |
-
|
|
|
138 |
overflow-x: auto;
|
139 |
-
background-color: #f9f9f9;
|
|
|
|
|
|
|
140 |
}
|
141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
.step-section {
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
|
|
148 |
}
|
149 |
|
150 |
-
/* Improved LaTeX styling */
|
151 |
.step-section .mjx-chtml {
|
152 |
-
/* Default MathJax inline styling */
|
153 |
display: inline-block;
|
154 |
line-height: 0;
|
155 |
text-indent: 0;
|
156 |
text-align: left;
|
157 |
text-transform: none;
|
158 |
-
font-size:
|
159 |
font-style: normal;
|
160 |
font-weight: normal;
|
161 |
font-family: MJXZERO, MJXTEX;
|
@@ -164,13 +181,16 @@
|
|
164 |
margin: 0 0.2em; /* Small horizontal margin */
|
165 |
}
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
|
|
|
|
172 |
}
|
173 |
|
|
|
174 |
/* Fix for inline math to prevent weird line breaks */
|
175 |
.step-section p {
|
176 |
display: block; /* Paragraphs should be block elements */
|
@@ -180,21 +200,6 @@
|
|
180 |
margin-inline-end: 0px;
|
181 |
}
|
182 |
|
183 |
-
/* Improve display for block equations */
|
184 |
-
.latex-display {
|
185 |
-
overflow-x: auto;
|
186 |
-
padding: 10px 0;
|
187 |
-
margin: 15px 0;
|
188 |
-
text-align: center;
|
189 |
-
display: block;
|
190 |
-
width: 100%;
|
191 |
-
}
|
192 |
-
|
193 |
-
.code-section {
|
194 |
-
background-color: transparent; /* Background handled by code-content */
|
195 |
-
padding: 0; /* Padding handled by code-content */
|
196 |
-
border-left: none; /* No left border */
|
197 |
-
}
|
198 |
|
199 |
.code-header {
|
200 |
background-color: #343a40;
|
@@ -205,9 +210,9 @@
|
|
205 |
display: flex;
|
206 |
justify-content: space-between;
|
207 |
align-items: center;
|
208 |
-
/* Border radius handled by first
|
209 |
-
border-top-left-radius:
|
210 |
-
border-top-right-radius:
|
211 |
}
|
212 |
|
213 |
.code-content {
|
@@ -219,81 +224,85 @@
|
|
219 |
font-family: 'Courier New', monospace;
|
220 |
font-size: 14px;
|
221 |
line-height: 1.5;
|
222 |
-
/* Border radius handled by
|
223 |
-
|
224 |
-
|
225 |
}
|
226 |
|
227 |
-
.output-section {
|
228 |
-
background-color: var(--output-bg);
|
229 |
-
padding: 15px;
|
230 |
-
border-top: 1px solid #ddd;
|
231 |
-
color: #333;
|
232 |
-
font-family: 'Courier New', monospace;
|
233 |
-
font-size: 14px;
|
234 |
-
white-space: pre-wrap;
|
235 |
-
overflow-x: auto;
|
236 |
-
border-left: none; /* No left border */
|
237 |
-
/* Border radius handled by first/last child rules */
|
238 |
-
border-bottom-left-radius: 0px;
|
239 |
-
border-bottom-right-radius: 0px;
|
240 |
-
}
|
241 |
|
242 |
-
/* Add border-radius back to the very first and very last child
|
|
|
|
|
243 |
#solution > div:first-child {
|
244 |
border-top-left-radius: 8px;
|
245 |
border-top-right-radius: 8px;
|
246 |
}
|
247 |
-
|
248 |
-
#solution >
|
|
|
|
|
|
|
|
|
|
|
249 |
border-top-left-radius: 8px;
|
250 |
border-top-right-radius: 8px;
|
251 |
}
|
252 |
|
253 |
|
|
|
254 |
#solution > div:last-child {
|
255 |
border-bottom-left-radius: 8px;
|
256 |
border-bottom-right-radius: 8px;
|
257 |
-
|
258 |
}
|
259 |
-
|
260 |
#solution > .code-section:last-child .code-content {
|
261 |
-
border-bottom-left-radius: 8px;
|
262 |
-
border-bottom-right-radius: 8px;
|
263 |
-
}
|
264 |
-
|
265 |
-
/* Specific case for a single code section */
|
266 |
-
#solution > .code-section:only-child .code-header {
|
267 |
-
border-top-left-radius: 8px;
|
268 |
-
border-top-right-radius: 8px;
|
269 |
-
}
|
270 |
-
#solution > .code-section:only-child .code-content {
|
271 |
border-bottom-left-radius: 8px;
|
272 |
border-bottom-right-radius: 8px;
|
273 |
}
|
274 |
-
|
275 |
-
|
276 |
-
#solution > .output-section:last-child {
|
277 |
border-bottom-left-radius: 8px;
|
278 |
border-bottom-right-radius: 8px;
|
279 |
-
|
280 |
}
|
281 |
|
282 |
-
|
283 |
-
|
|
|
|
|
|
|
|
|
|
|
284 |
border-top-left-radius: 8px;
|
285 |
border-top-right-radius: 8px;
|
|
|
|
|
286 |
border-bottom-left-radius: 8px;
|
287 |
border-bottom-right-radius: 8px;
|
288 |
-
|
|
|
|
|
|
|
289 |
}
|
290 |
|
291 |
-
|
292 |
-
/*
|
|
|
293 |
#solution > div:not(:last-child) {
|
294 |
-
|
295 |
}
|
296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
|
298 |
/* Fixed display of MathJax content */
|
299 |
.mjx-container {
|
@@ -306,14 +315,6 @@
|
|
306 |
vertical-align: middle; /* Better vertical alignment for inline math */
|
307 |
}
|
308 |
|
309 |
-
.mjx-container.MJX-display {
|
310 |
-
display: block !important;
|
311 |
-
margin: 1em auto !important;
|
312 |
-
text-align: center !important;
|
313 |
-
max-width: 100%;
|
314 |
-
overflow-x: auto; /* Allow horizontal scrolling for large block equations */
|
315 |
-
overflow-y: hidden;
|
316 |
-
}
|
317 |
|
318 |
/* Fix markdown list rendering */
|
319 |
.step-section ul, .step-section ol {
|
@@ -368,18 +369,10 @@
|
|
368 |
|
369 |
/* Unified consistent LaTeX size for all equations */
|
370 |
/* Ensure MathJax respects container font size */
|
371 |
-
.step-section .MathJax,
|
372 |
.step-section .mjx-container {
|
373 |
-
font-size:
|
374 |
}
|
375 |
|
376 |
-
.step-section .MathJax_Display {
|
377 |
-
text-align: center !important;
|
378 |
-
margin: 1em auto !important;
|
379 |
-
display: block !important;
|
380 |
-
overflow-x: auto;
|
381 |
-
overflow-y: hidden;
|
382 |
-
}
|
383 |
</style>
|
384 |
</head>
|
385 |
<body>
|
@@ -454,8 +447,8 @@
|
|
454 |
<script>
|
455 |
window.MathJax = {
|
456 |
tex: {
|
457 |
-
inlineMath: [['$', '$'], ['\\(', '\\)']], //
|
458 |
-
displayMath: [['$$', '$$'], ['\\[', '\\]']], //
|
459 |
processEscapes: true,
|
460 |
processEnvironments: true,
|
461 |
packages: {'[+]': ['noerrors', 'physics', 'cancel', 'color']}
|
@@ -532,6 +525,7 @@
|
|
532 |
if (done) {
|
533 |
loadingIndicator.style.display = 'none';
|
534 |
// Force MathJax to reprocess entire solution when done
|
|
|
535 |
if (typeof MathJax !== 'undefined') {
|
536 |
MathJax.typesetPromise([solutionContainer]).catch(e => console.error('MathJax final typesetting error:', e));
|
537 |
}
|
@@ -539,15 +533,15 @@
|
|
539 |
}
|
540 |
|
541 |
buffer += decoder.decode(value, { stream: true });
|
542 |
-
// Split by double newline to separate
|
543 |
-
const
|
544 |
-
buffer =
|
545 |
|
546 |
-
for (const
|
547 |
// Only process lines that start with 'data: ' for SSE
|
548 |
-
if (
|
549 |
try {
|
550 |
-
const data = JSON.parse(
|
551 |
|
552 |
// Handle mode updates
|
553 |
if (data.mode) {
|
@@ -561,10 +555,12 @@
|
|
561 |
if (modeInfo) {
|
562 |
loadingIndicator.className = modeInfo.class; // Update class for styling
|
563 |
loadingIndicator.innerHTML = `<i class="fas ${modeInfo.icon} indicator-icon"></i><span>${modeInfo.text}</span>`; // Update icon and text
|
|
|
564 |
} else {
|
565 |
// Default or unknown mode
|
566 |
loadingIndicator.className = 'thinking-indicator';
|
567 |
loadingIndicator.innerHTML = `<i class="fas fa-sync-alt indicator-icon fa-spin"></i><span>Traitement...</span>`;
|
|
|
568 |
}
|
569 |
}
|
570 |
|
@@ -572,7 +568,7 @@
|
|
572 |
if (data.content) {
|
573 |
const content = data.content;
|
574 |
const tempDiv = document.createElement('div');
|
575 |
-
tempDiv.innerHTML = content; // Parse HTML chunk
|
576 |
|
577 |
const codeSection = tempDiv.querySelector('.code-section');
|
578 |
const outputSection = tempDiv.querySelector('.output-section');
|
@@ -583,8 +579,10 @@
|
|
583 |
codeSection.querySelectorAll('pre code').forEach((block) => {
|
584 |
hljs.highlightElement(block);
|
585 |
});
|
|
|
586 |
} else if (outputSection) {
|
587 |
solutionContainer.appendChild(outputSection);
|
|
|
588 |
} else {
|
589 |
// Process regular text/LaTeX step section
|
590 |
const stepDiv = document.createElement('div');
|
@@ -594,53 +592,64 @@
|
|
594 |
let processedContent = content;
|
595 |
|
596 |
// Convert markdown lists to HTML lists
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
// Wrap consecutive list items in ul/ol tags
|
601 |
-
let listHtml = '';
|
602 |
let inList = false;
|
603 |
let listType = ''; // 'ul' or 'ol'
|
604 |
|
605 |
-
|
606 |
-
|
607 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
608 |
if (!inList) {
|
609 |
-
|
610 |
-
listHtml += `<${listType}>${line}`;
|
611 |
inList = true;
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
listHtml += `</${listType}><${itemType}>${line}`;
|
617 |
-
listType = itemType;
|
618 |
}
|
|
|
619 |
} else {
|
620 |
if (inList) {
|
621 |
-
|
622 |
inList = false;
|
623 |
}
|
624 |
-
|
|
|
|
|
|
|
625 |
}
|
626 |
-
}
|
627 |
|
628 |
if (inList) {
|
629 |
-
|
630 |
}
|
631 |
|
632 |
-
//
|
633 |
-
|
634 |
-
|
635 |
|
636 |
-
stepDiv.innerHTML =
|
637 |
solutionContainer.appendChild(stepDiv);
|
638 |
|
639 |
-
// Process MathJax for this section (will process the new content)
|
640 |
if (typeof MathJax !== 'undefined') {
|
|
|
641 |
MathJax.typesetPromise([stepDiv]).catch(e => console.error('MathJax typesetting error:', e));
|
642 |
}
|
643 |
}
|
|
|
|
|
644 |
}
|
645 |
|
646 |
// Handle error messages
|
@@ -655,18 +664,18 @@
|
|
655 |
loadingIndicator.style.display = 'none'; // Hide loading indicator on error
|
656 |
}
|
657 |
} catch (e) {
|
658 |
-
console.error('Error parsing JSON or processing
|
659 |
// Display a client-side processing error message
|
660 |
const errorDiv = document.createElement('div');
|
661 |
errorDiv.className = 'step-section';
|
662 |
errorDiv.style.color = 'orange';
|
663 |
-
errorDiv.textContent = `Erreur traitement
|
664 |
solutionContainer.appendChild(errorDiv);
|
665 |
loadingIndicator.style.display = 'none';
|
666 |
}
|
667 |
} else {
|
668 |
// Handle potential non-data lines if necessary, or ignore
|
669 |
-
console.warn("Received non-data line:",
|
670 |
}
|
671 |
}
|
672 |
|
|
|
126 |
text-align: left;
|
127 |
line-height: 1.8;
|
128 |
font-size: 16px;
|
129 |
+
background-color: transparent; /* Background of the container itself */
|
130 |
box-shadow: var(--box-shadow);
|
131 |
+
overflow: hidden; /* Clip children borders to parent radius */
|
132 |
}
|
133 |
|
134 |
+
/* Apply common padding and margin to sections */
|
135 |
+
#solution > div {
|
136 |
padding: 20px;
|
137 |
+
margin: 0; /* Remove default margin */
|
138 |
+
border-radius: 0; /* Reset radius, applied to first/last children */
|
139 |
overflow-x: auto;
|
140 |
+
background-color: #f9f9f9; /* Default background */
|
141 |
+
border-left: 4px solid var(--primary-color); /* Default left border */
|
142 |
+
/* Added border-bottom to create separation between sections */
|
143 |
+
border-bottom: 1px solid #eee;
|
144 |
}
|
145 |
|
146 |
+
.code-section {
|
147 |
+
background-color: transparent !important; /* Background handled by code-content */
|
148 |
+
padding: 0 !important; /* Padding handled by code-content */
|
149 |
+
border-left: none !important; /* No left border for code section parent */
|
150 |
+
border-bottom: none !important; /* No border bottom on code section parent */
|
151 |
+
}
|
152 |
+
|
153 |
+
.output-section {
|
154 |
+
background-color: var(--output-bg) !important; /* Override default section background */
|
155 |
+
border-left: none !important; /* No left border for output section parent */
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
.step-section {
|
160 |
+
/* Specific styles for steps */
|
161 |
+
border-left: 4px solid var(--primary-color);
|
162 |
+
padding-left: calc(20px - 4px); /* Adjust padding to account for border */
|
163 |
+
background-color: #f9f9f9;
|
164 |
+
font-size: 16px;
|
165 |
+
line-height: 1.8;
|
166 |
}
|
167 |
|
168 |
+
/* Improved LaTeX styling (MathJax v3 specific) */
|
169 |
.step-section .mjx-chtml {
|
|
|
170 |
display: inline-block;
|
171 |
line-height: 0;
|
172 |
text-indent: 0;
|
173 |
text-align: left;
|
174 |
text-transform: none;
|
175 |
+
font-size: 1em !important; /* Ensure inline MathJax respects container font size */
|
176 |
font-style: normal;
|
177 |
font-weight: normal;
|
178 |
font-family: MJXZERO, MJXTEX;
|
|
|
181 |
margin: 0 0.2em; /* Small horizontal margin */
|
182 |
}
|
183 |
|
184 |
+
.step-section .mjx-container.MJX-display {
|
185 |
+
display: block !important;
|
186 |
+
margin: 1em auto !important;
|
187 |
+
text-align: center !important;
|
188 |
+
max-width: 100%;
|
189 |
+
overflow-x: auto; /* Allow horizontal scrolling for large block equations */
|
190 |
+
overflow-y: hidden;
|
191 |
}
|
192 |
|
193 |
+
|
194 |
/* Fix for inline math to prevent weird line breaks */
|
195 |
.step-section p {
|
196 |
display: block; /* Paragraphs should be block elements */
|
|
|
200 |
margin-inline-end: 0px;
|
201 |
}
|
202 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
|
204 |
.code-header {
|
205 |
background-color: #343a40;
|
|
|
210 |
display: flex;
|
211 |
justify-content: space-between;
|
212 |
align-items: center;
|
213 |
+
/* Border radius handled by first child rules below */
|
214 |
+
border-top-left-radius: 0;
|
215 |
+
border-top-right-radius: 0;
|
216 |
}
|
217 |
|
218 |
.code-content {
|
|
|
224 |
font-family: 'Courier New', monospace;
|
225 |
font-size: 14px;
|
226 |
line-height: 1.5;
|
227 |
+
/* Border radius handled by last child rules below */
|
228 |
+
border-bottom-left-radius: 0;
|
229 |
+
border-bottom-right-radius: 0;
|
230 |
}
|
231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
|
233 |
+
/* Add border-radius back to the very first and very last child INSIDE #solution */
|
234 |
+
|
235 |
+
/* First child in #solution */
|
236 |
#solution > div:first-child {
|
237 |
border-top-left-radius: 8px;
|
238 |
border-top-right-radius: 8px;
|
239 |
}
|
240 |
+
/* Special handling for the first child if it's a code section (header needs radius) */
|
241 |
+
#solution > .code-section:first-child .code-header {
|
242 |
+
border-top-left-radius: 8px;
|
243 |
+
border-top-right-radius: 8px;
|
244 |
+
}
|
245 |
+
/* Special handling for the first child if it's an output section */
|
246 |
+
#solution > .output-section:first-child {
|
247 |
border-top-left-radius: 8px;
|
248 |
border-top-right-radius: 8px;
|
249 |
}
|
250 |
|
251 |
|
252 |
+
/* Last child in #solution */
|
253 |
#solution > div:last-child {
|
254 |
border-bottom-left-radius: 8px;
|
255 |
border-bottom-right-radius: 8px;
|
256 |
+
border-bottom: none; /* Remove the bottom border on the very last section */
|
257 |
}
|
258 |
+
/* Special handling for the last child if it's a code section (content needs radius) */
|
259 |
#solution > .code-section:last-child .code-content {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
border-bottom-left-radius: 8px;
|
261 |
border-bottom-right-radius: 8px;
|
262 |
}
|
263 |
+
/* Special handling for the last child if it's an output section */
|
264 |
+
#solution > .output-section:last-child {
|
|
|
265 |
border-bottom-left-radius: 8px;
|
266 |
border-bottom-right-radius: 8px;
|
267 |
+
border-bottom: none;
|
268 |
}
|
269 |
|
270 |
+
|
271 |
+
/* Specific case for a single child (both first and last) */
|
272 |
+
#solution > div:only-child {
|
273 |
+
border-radius: 8px;
|
274 |
+
border-bottom: none;
|
275 |
+
}
|
276 |
+
#solution > .code-section:only-child .code-header {
|
277 |
border-top-left-radius: 8px;
|
278 |
border-top-right-radius: 8px;
|
279 |
+
}
|
280 |
+
#solution > .code-section:only-child .code-content {
|
281 |
border-bottom-left-radius: 8px;
|
282 |
border-bottom-right-radius: 8px;
|
283 |
+
}
|
284 |
+
#solution > .output-section:only-child {
|
285 |
+
border-radius: 8px;
|
286 |
+
border-bottom: none;
|
287 |
}
|
288 |
|
289 |
+
|
290 |
+
/* Remove bottom border for sections that are not the last child,
|
291 |
+
to make them appear connected to the next section */
|
292 |
#solution > div:not(:last-child) {
|
293 |
+
border-bottom: 1px solid #eee;
|
294 |
}
|
295 |
|
296 |
+
/* Code section should not have a bottom border even if not last */
|
297 |
+
#solution > .code-section {
|
298 |
+
border-bottom: none;
|
299 |
+
}
|
300 |
+
|
301 |
+
/* Output section should not have a bottom border even if not last */
|
302 |
+
#solution > .output-section:not(:last-child) {
|
303 |
+
border-bottom: 1px solid #ddd; /* Keep the separator line */
|
304 |
+
}
|
305 |
+
|
306 |
|
307 |
/* Fixed display of MathJax content */
|
308 |
.mjx-container {
|
|
|
315 |
vertical-align: middle; /* Better vertical alignment for inline math */
|
316 |
}
|
317 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
318 |
|
319 |
/* Fix markdown list rendering */
|
320 |
.step-section ul, .step-section ol {
|
|
|
369 |
|
370 |
/* Unified consistent LaTeX size for all equations */
|
371 |
/* Ensure MathJax respects container font size */
|
|
|
372 |
.step-section .mjx-container {
|
373 |
+
font-size: 1em !important; /* Use relative units */
|
374 |
}
|
375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
</style>
|
377 |
</head>
|
378 |
<body>
|
|
|
447 |
<script>
|
448 |
window.MathJax = {
|
449 |
tex: {
|
450 |
+
inlineMath: [['$', '$'], ['\\(', '\\)']], // Standard inline delimiters
|
451 |
+
displayMath: [['$$', '$$'], ['\\[', '\\]']], // Standard block delimiters
|
452 |
processEscapes: true,
|
453 |
processEnvironments: true,
|
454 |
packages: {'[+]': ['noerrors', 'physics', 'cancel', 'color']}
|
|
|
525 |
if (done) {
|
526 |
loadingIndicator.style.display = 'none';
|
527 |
// Force MathJax to reprocess entire solution when done
|
528 |
+
// Use the specific container element
|
529 |
if (typeof MathJax !== 'undefined') {
|
530 |
MathJax.typesetPromise([solutionContainer]).catch(e => console.error('MathJax final typesetting error:', e));
|
531 |
}
|
|
|
533 |
}
|
534 |
|
535 |
buffer += decoder.decode(value, { stream: true });
|
536 |
+
// Split by double newline to separate SSE messages, but keep the last incomplete chunk in buffer
|
537 |
+
const messages = buffer.split(/\r?\n\r?\n/);
|
538 |
+
buffer = messages.pop(); // Store the last potentially incomplete chunk
|
539 |
|
540 |
+
for (const message of messages) {
|
541 |
// Only process lines that start with 'data: ' for SSE
|
542 |
+
if (message.startsWith('data: ')) {
|
543 |
try {
|
544 |
+
const data = JSON.parse(message.substr(6)); // Extract JSON after 'data: '
|
545 |
|
546 |
// Handle mode updates
|
547 |
if (data.mode) {
|
|
|
555 |
if (modeInfo) {
|
556 |
loadingIndicator.className = modeInfo.class; // Update class for styling
|
557 |
loadingIndicator.innerHTML = `<i class="fas ${modeInfo.icon} indicator-icon"></i><span>${modeInfo.text}</span>`; // Update icon and text
|
558 |
+
loadingIndicator.style.display = 'flex'; // Ensure indicator is visible when a mode is set
|
559 |
} else {
|
560 |
// Default or unknown mode
|
561 |
loadingIndicator.className = 'thinking-indicator';
|
562 |
loadingIndicator.innerHTML = `<i class="fas fa-sync-alt indicator-icon fa-spin"></i><span>Traitement...</span>`;
|
563 |
+
loadingIndicator.style.display = 'flex';
|
564 |
}
|
565 |
}
|
566 |
|
|
|
568 |
if (data.content) {
|
569 |
const content = data.content;
|
570 |
const tempDiv = document.createElement('div');
|
571 |
+
tempDiv.innerHTML = content; // Parse HTML chunk received from server
|
572 |
|
573 |
const codeSection = tempDiv.querySelector('.code-section');
|
574 |
const outputSection = tempDiv.querySelector('.output-section');
|
|
|
579 |
codeSection.querySelectorAll('pre code').forEach((block) => {
|
580 |
hljs.highlightElement(block);
|
581 |
});
|
582 |
+
// MathJax should ignore code blocks based on options
|
583 |
} else if (outputSection) {
|
584 |
solutionContainer.appendChild(outputSection);
|
585 |
+
// MathJax should ignore output blocks based on options
|
586 |
} else {
|
587 |
// Process regular text/LaTeX step section
|
588 |
const stepDiv = document.createElement('div');
|
|
|
592 |
let processedContent = content;
|
593 |
|
594 |
// Convert markdown lists to HTML lists
|
595 |
+
// This is a basic approach and might not cover all markdown complexities
|
596 |
+
const lines = processedContent.split('\n');
|
597 |
+
let htmlOutput = '';
|
|
|
|
|
598 |
let inList = false;
|
599 |
let listType = ''; // 'ul' or 'ol'
|
600 |
|
601 |
+
for (const line of lines) {
|
602 |
+
const trimmedLine = line.trim();
|
603 |
+
if (trimmedLine.match(/^(-|\*|\+)\s/)) { // Unordered list item
|
604 |
+
if (!inList) {
|
605 |
+
htmlOutput += '<ul>';
|
606 |
+
inList = true;
|
607 |
+
listType = 'ul';
|
608 |
+
} else if (listType !== 'ul') {
|
609 |
+
htmlOutput += `</${listType}><ul>`;
|
610 |
+
listType = 'ul';
|
611 |
+
}
|
612 |
+
htmlOutput += `<li>${trimmedLine.replace(/^(-|\*|\+)\s+/, '')}</li>`;
|
613 |
+
} else if (trimmedLine.match(/^(\d+)\.\s/)) { // Ordered list item
|
614 |
if (!inList) {
|
615 |
+
htmlOutput += '<ol>';
|
|
|
616 |
inList = true;
|
617 |
+
listType = 'ol';
|
618 |
+
} else if (listType !== 'ol') {
|
619 |
+
htmlOutput += `</${listType}><ol>`;
|
620 |
+
listType = 'ol';
|
|
|
|
|
621 |
}
|
622 |
+
htmlOutput += `<li>${trimmedLine.replace(/^(\d+)\.\s+/, '')}</li>`;
|
623 |
} else {
|
624 |
if (inList) {
|
625 |
+
htmlOutput += `</${listType}>`;
|
626 |
inList = false;
|
627 |
}
|
628 |
+
// Add non-list content wrapped in paragraphs, handling double newlines
|
629 |
+
if (line.trim() !== '') {
|
630 |
+
htmlOutput += `<p>${line}</p>`;
|
631 |
+
}
|
632 |
}
|
633 |
+
}
|
634 |
|
635 |
if (inList) {
|
636 |
+
htmlOutput += `</${listType}>`;
|
637 |
}
|
638 |
|
639 |
+
// Remove empty paragraph tags that might have been created
|
640 |
+
htmlOutput = htmlOutput.replace(/<p>\s*<\/p>/g, '');
|
|
|
641 |
|
642 |
+
stepDiv.innerHTML = htmlOutput; // Use the processed HTML
|
643 |
solutionContainer.appendChild(stepDiv);
|
644 |
|
645 |
+
// Process MathJax for this specific section (will process the new content)
|
646 |
if (typeof MathJax !== 'undefined') {
|
647 |
+
// Use typesetPromise and target the newly added stepDiv
|
648 |
MathJax.typesetPromise([stepDiv]).catch(e => console.error('MathJax typesetting error:', e));
|
649 |
}
|
650 |
}
|
651 |
+
// Hide the loading indicator once content starts arriving (optional, but can feel more responsive)
|
652 |
+
// loadingIndicator.style.display = 'none'; // Keep it visible to show mode changes
|
653 |
}
|
654 |
|
655 |
// Handle error messages
|
|
|
664 |
loadingIndicator.style.display = 'none'; // Hide loading indicator on error
|
665 |
}
|
666 |
} catch (e) {
|
667 |
+
console.error('Error parsing JSON or processing message:', e, message);
|
668 |
// Display a client-side processing error message
|
669 |
const errorDiv = document.createElement('div');
|
670 |
errorDiv.className = 'step-section';
|
671 |
errorDiv.style.color = 'orange';
|
672 |
+
errorDiv.textContent = `Erreur traitement message: ${message.substring(0, 100)}...`; // Show a snippet of the problematic line
|
673 |
solutionContainer.appendChild(errorDiv);
|
674 |
loadingIndicator.style.display = 'none';
|
675 |
}
|
676 |
} else {
|
677 |
// Handle potential non-data lines if necessary, or ignore
|
678 |
+
// console.warn("Received non-data line:", message); // Uncomment for debugging
|
679 |
}
|
680 |
}
|
681 |
|