Improve copying message with math, file links to clipboard on web app

This commit is contained in:
Debanjum
2025-08-25 12:36:15 -07:00
parent 15d1f39d0b
commit e150dc5a91
2 changed files with 22 additions and 19 deletions

View File

@@ -466,23 +466,9 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>((props, ref) =>
setMermaidjsData(props.chatMessage.mermaidjsDiagram); setMermaidjsData(props.chatMessage.mermaidjsDiagram);
} }
// Replace LaTeX delimiters with placeholders
message = message
.replace(/\\\(/g, "LEFTPAREN")
.replace(/\\\)/g, "RIGHTPAREN")
.replace(/\\\[/g, "LEFTBRACKET")
.replace(/\\\]/g, "RIGHTBRACKET");
// Replace file links with base64 data // Replace file links with base64 data
message = renderCodeGenImageInline(message, props.chatMessage.codeContext); message = renderCodeGenImageInline(message, props.chatMessage.codeContext);
// Preprocess file:// links so markdown-it processes them
// We convert them to a custom scheme (filelink://) and handle in the plugin
message = message.replace(/\[([^\]]+)\]\(file:\/\/([^)]+)\)/g, (match, text, path) => {
// Use a special scheme that markdown-it will process
return `[${text}](filelink://${path})`;
});
// Add code context files to the message // Add code context files to the message
if (props.chatMessage.codeContext) { if (props.chatMessage.codeContext) {
Object.entries(props.chatMessage.codeContext).forEach(([key, value]) => { Object.entries(props.chatMessage.codeContext).forEach(([key, value]) => {
@@ -497,7 +483,7 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>((props, ref) =>
}); });
} }
// Handle user attached images rendering // Handle rendering user attached or khoj generated images
let messageForClipboard = message; let messageForClipboard = message;
let messageToRender = message; let messageToRender = message;
if (props.chatMessage.images && props.chatMessage.images.length > 0) { if (props.chatMessage.images && props.chatMessage.images.length > 0) {
@@ -509,12 +495,12 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>((props, ref) =>
}); });
const imagesInMd = sanitizedImages const imagesInMd = sanitizedImages
.map((sanitizedImage, index) => { .map((sanitizedImage, index) => {
return `![uploaded image ${index + 1}](${sanitizedImage})`; return `![rendered image ${index + 1}](${sanitizedImage})`;
}) })
.join("\n"); .join("\n");
const imagesInHtml = sanitizedImages const imagesInHtml = sanitizedImages
.map((sanitizedImage, index) => { .map((sanitizedImage, index) => {
return `<div class="${styles.imageWrapper}"><img src="${sanitizedImage}" alt="uploaded image ${index + 1}" /></div>`; return `<div class="${styles.imageWrapper}"><img src="${sanitizedImage}" alt="rendered image ${index + 1}" /></div>`;
}) })
.join(""); .join("");
const userImagesInHtml = `<div class="${styles.imagesContainer}">${imagesInHtml}</div>`; const userImagesInHtml = `<div class="${styles.imagesContainer}">${imagesInHtml}</div>`;
@@ -525,10 +511,27 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>((props, ref) =>
// Set the message text // Set the message text
setTextRendered(messageForClipboard); setTextRendered(messageForClipboard);
// Replace LaTeX delimiters with placeholders
messageToRender = messageToRender
.replace(/\\\(/g, "LEFTPAREN")
.replace(/\\\)/g, "RIGHTPAREN")
.replace(/\\\[/g, "LEFTBRACKET")
.replace(/\\\]/g, "RIGHTBRACKET");
// Preprocess file:// links so markdown-it processes them
// We convert them to a custom scheme (filelink://) and handle in the plugin
messageToRender = messageToRender.replace(
/\[([^\]]+)\]\(file:\/\/([^)]+)\)/g,
(match, text, path) => {
// Use a special scheme that markdown-it will process
return `[${text}](filelink://${path})`;
},
);
// Render the markdown // Render the markdown
let markdownRendered = md.render(messageToRender); let markdownRendered = md.render(messageToRender);
// Replace placeholders with LaTeX delimiters // Revert placeholders with LaTeX delimiters
markdownRendered = markdownRendered markdownRendered = markdownRendered
.replace(/LEFTPAREN/g, "\\(") .replace(/LEFTPAREN/g, "\\(")
.replace(/RIGHTPAREN/g, "\\)") .replace(/RIGHTPAREN/g, "\\)")

View File

@@ -55,7 +55,7 @@
"input-otp": "^1.2.4", "input-otp": "^1.2.4",
"intl-tel-input": "^23.8.1", "intl-tel-input": "^23.8.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"katex": "^0.16.21", "katex": "^0.16.22",
"libphonenumber-js": "^1.11.4", "libphonenumber-js": "^1.11.4",
"lucide-react": "^0.468.0", "lucide-react": "^0.468.0",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",