mirror of
https://github.com/siteboon/claudecodeui.git
synced 2025-12-13 05:39:41 +00:00
fix: protect LaTeX formulas when unescaping JSONL escape sequences
This commit is contained in:
@@ -59,6 +59,37 @@ function normalizeInlineCodeFences(text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unescape \n, \t, \r while protecting LaTeX formulas ($...$ and $$...$$) from being corrupted
|
||||||
|
function unescapeWithMathProtection(text) {
|
||||||
|
if (!text || typeof text !== 'string') return text;
|
||||||
|
|
||||||
|
const mathBlocks = [];
|
||||||
|
const PLACEHOLDER_PREFIX = '__MATH_BLOCK_';
|
||||||
|
const PLACEHOLDER_SUFFIX = '__';
|
||||||
|
|
||||||
|
// Extract and protect math formulas
|
||||||
|
let processedText = text.replace(/\$\$([\s\S]*?)\$\$|\$([^\$\n]+?)\$/g, (match) => {
|
||||||
|
const index = mathBlocks.length;
|
||||||
|
mathBlocks.push(match);
|
||||||
|
return `${PLACEHOLDER_PREFIX}${index}${PLACEHOLDER_SUFFIX}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Process escape sequences on non-math content
|
||||||
|
processedText = processedText.replace(/\\n/g, '\n')
|
||||||
|
.replace(/\\t/g, '\t')
|
||||||
|
.replace(/\\r/g, '\r');
|
||||||
|
|
||||||
|
// Restore math formulas
|
||||||
|
processedText = processedText.replace(
|
||||||
|
new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUFFIX}`, 'g'),
|
||||||
|
(match, index) => {
|
||||||
|
return mathBlocks[parseInt(index)];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return processedText;
|
||||||
|
}
|
||||||
|
|
||||||
// Small wrapper to keep markdown behavior consistent in one place
|
// Small wrapper to keep markdown behavior consistent in one place
|
||||||
const Markdown = ({ children, className }) => {
|
const Markdown = ({ children, className }) => {
|
||||||
const content = normalizeInlineCodeFences(String(children ?? ''));
|
const content = normalizeInlineCodeFences(String(children ?? ''));
|
||||||
@@ -2532,10 +2563,8 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess
|
|||||||
content.startsWith('[Request interrupted');
|
content.startsWith('[Request interrupted');
|
||||||
|
|
||||||
if (!shouldSkip) {
|
if (!shouldSkip) {
|
||||||
// Unescape double-escaped newlines and other escape sequences
|
// Unescape with math formula protection
|
||||||
content = content.replace(/\\n/g, '\n')
|
content = unescapeWithMathProtection(content);
|
||||||
.replace(/\\t/g, '\t')
|
|
||||||
.replace(/\\r/g, '\r');
|
|
||||||
converted.push({
|
converted.push({
|
||||||
type: messageType,
|
type: messageType,
|
||||||
content: content,
|
content: content,
|
||||||
@@ -2549,12 +2578,10 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess
|
|||||||
if (Array.isArray(msg.message.content)) {
|
if (Array.isArray(msg.message.content)) {
|
||||||
for (const part of msg.message.content) {
|
for (const part of msg.message.content) {
|
||||||
if (part.type === 'text') {
|
if (part.type === 'text') {
|
||||||
// Unescape double-escaped newlines and other escape sequences
|
// Unescape with math formula protection
|
||||||
let text = part.text;
|
let text = part.text;
|
||||||
if (typeof text === 'string') {
|
if (typeof text === 'string') {
|
||||||
text = text.replace(/\\n/g, '\n')
|
text = unescapeWithMathProtection(text);
|
||||||
.replace(/\\t/g, '\t')
|
|
||||||
.replace(/\\r/g, '\r');
|
|
||||||
}
|
}
|
||||||
converted.push({
|
converted.push({
|
||||||
type: 'assistant',
|
type: 'assistant',
|
||||||
@@ -2583,11 +2610,9 @@ function ChatInterface({ selectedProject, selectedSession, ws, sendMessage, mess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (typeof msg.message.content === 'string') {
|
} else if (typeof msg.message.content === 'string') {
|
||||||
// Unescape double-escaped newlines and other escape sequences
|
// Unescape with math formula protection
|
||||||
let text = msg.message.content;
|
let text = msg.message.content;
|
||||||
text = text.replace(/\\n/g, '\n')
|
text = unescapeWithMathProtection(text);
|
||||||
.replace(/\\t/g, '\t')
|
|
||||||
.replace(/\\r/g, '\r');
|
|
||||||
converted.push({
|
converted.push({
|
||||||
type: 'assistant',
|
type: 'assistant',
|
||||||
content: text,
|
content: text,
|
||||||
|
|||||||
Reference in New Issue
Block a user