]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
webui: Fix parsing non-LaTeX occurrencies of `\(` or `\)` (#17810)
authorAleksander Grygier <redacted>
Fri, 12 Dec 2025 14:13:36 +0000 (15:13 +0100)
committerGitHub <redacted>
Fri, 12 Dec 2025 14:13:36 +0000 (15:13 +0100)
* fix: Improve latex protection logic to prevent turning non-latex `\(` into `$`

* chore: update webui build output

tools/server/public/index.html.gz
tools/server/webui/src/lib/utils/latex-protection.test.ts
tools/server/webui/src/lib/utils/latex-protection.ts

index 4cff76429e17e3278492ced5821f896eaf94decb..3fd631b77a85820f6fcec9cc3f5e9f60d5ef9fb3 100644 (file)
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
index 2354f8fa0ec5aa51170f0b07ea76f4bdfc40c56a..40fe1b0db273f5bcfda3e3a8980df5a042abbe4b 100644 (file)
@@ -303,6 +303,27 @@ $$\n\\pi_n(\\mathbb{S}^3) = \\begin{cases}
                expect(output).toBe(input); // Code blocks prevent misinterpretation
        });
 
+       test('preserves backslash parentheses in code blocks (GitHub issue)', () => {
+               const input = '```python\nfoo = "\\(bar\\)"\n```';
+               const output = preprocessLaTeX(input);
+
+               expect(output).toBe(input); // Code blocks should not have LaTeX conversion applied
+       });
+
+       test('preserves backslash brackets in code blocks', () => {
+               const input = '```python\nfoo = "\\[bar\\]"\n```';
+               const output = preprocessLaTeX(input);
+
+               expect(output).toBe(input); // Code blocks should not have LaTeX conversion applied
+       });
+
+       test('preserves backslash parentheses in inline code', () => {
+               const input = 'Use `foo = "\\(bar\\)"` in your code.';
+               const output = preprocessLaTeX(input);
+
+               expect(output).toBe(input);
+       });
+
        test('escape backslash in mchem ce', () => {
                const input = 'mchem ce:\n$\\ce{2H2(g) + O2(g) -> 2H2O(l)}$';
                const output = preprocessLaTeX(input);
index 7f5cf2cddfa20e31113331cea19b88440602b599..cafa2d4761fd65aaa5932d7b2597377899bc1837 100644 (file)
@@ -226,19 +226,16 @@ export function preprocessLaTeX(content: string): string {
                return expr;
        });
 
-       // Step 5: Restore code blocks
-       content = content.replace(/<<CODE_BLOCK_(\d+)>>/g, (_, index) => {
-               return codeBlocks[parseInt(index)];
-       });
-
-       // Step 6: Apply additional escaping functions (brackets and mhchem)
+       // Step 5: Apply additional escaping functions (brackets and mhchem)
+       // This must happen BEFORE restoring code blocks to avoid affecting code content
        content = escapeBrackets(content);
 
        if (doEscapeMhchem && (content.includes('\\ce{') || content.includes('\\pu{'))) {
                content = escapeMhchem(content);
        }
 
-       // Final pass: Convert \(...\) → $...$, \[...\] → $$...$$
+       // Step 6: Convert remaining \(...\) → $...$, \[...\] → $$...$$
+       // This must happen BEFORE restoring code blocks to avoid affecting code content
        content = content
                // Using the look‑behind pattern `(?<!\\)` we skip matches
                // that are preceded by a backslash, e.g.
@@ -248,12 +245,18 @@ export function preprocessLaTeX(content: string): string {
                        // Using the look‑behind pattern `(?<!\\)` we skip matches
                        // that are preceded by a backslash, e.g. `\\[4pt]`.
                        /(?<!\\)\\\[([\s\S]*?)\\\]/g, // display, see also PR #16599
-                       (_, prefix: string, content: string) => {
-                               return `${prefix}$$${content}$$`;
+                       (_, content: string) => {
+                               return `$$${content}$$`;
                        }
                );
 
-       // Step 7: Restore blockquote markers
+       // Step 7: Restore code blocks
+       // This happens AFTER all LaTeX conversions to preserve code content
+       content = content.replace(/<<CODE_BLOCK_(\d+)>>/g, (_, index) => {
+               return codeBlocks[parseInt(index)];
+       });
+
+       // Step 8: Restore blockquote markers
        if (blockquoteMarkers.size > 0) {
                const finalLines = content.split('\n');
                const restoredLines = finalLines.map((line, index) => {