almost completely styled codeblocks in response

This commit is contained in:
perf3ct
2025-03-10 23:09:15 +00:00
parent 9834e77bb4
commit ecc183f57d
2 changed files with 47 additions and 15 deletions

View File

@@ -304,21 +304,30 @@ export default class ChatWidget extends TabAwareWidget {
formatMessageContent(content) {
if (!content) return '';
// Escape HTML
let formatted = utils.escapeHtml(content);
// Convert markdown-style code blocks to HTML
formatted = formatted.replace(/```(\w+)?\n([\s\S]+?)\n```/g, (match, language, code) => {
return `<pre class="code${language ? ' language-' + language : ''}"><code>${utils.escapeHtml(code)}</code></pre>`;
// First extract code blocks to protect them from HTML escaping
const codeBlocks = [];
let processedContent = content.replace(/```(\w+)?\n([\s\S]+?)\n```/g, (match, language, code) => {
const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`;
const languageClass = language ? ` language-${language}` : '';
codeBlocks.push(`<pre class="code${languageClass}"><code>${utils.escapeHtml(code)}</code></pre>`);
return placeholder;
});
// Convert inline code
formatted = formatted.replace(/`([^`]+)`/g, '<code>$1</code>');
// Escape HTML in the remaining content
processedContent = utils.escapeHtml(processedContent);
// Convert inline code - look for backticks that weren't part of a code block
processedContent = processedContent.replace(/`([^`]+)`/g, '<code>$1</code>');
// Convert line breaks
formatted = formatted.replace(/\n/g, '<br>');
processedContent = processedContent.replace(/\n/g, '<br>');
return formatted;
// Restore code blocks
codeBlocks.forEach((block, index) => {
processedContent = processedContent.replace(`__CODE_BLOCK_${index}__`, block);
});
return processedContent;
}
scrollToBottom() {

View File

@@ -5,6 +5,7 @@ import appContext from "../components/app_context.js";
import utils from "../services/utils.js";
import { t } from "../services/i18n.js";
import libraryLoader from "../services/library_loader.js";
import { applySyntaxHighlight } from "../services/syntax_highlight.js";
// Import the LLM Chat CSS
(async function() {
@@ -217,6 +218,8 @@ export default class LlmChatPanel extends BasicWidget {
const assistantElement = this.noteContextChatMessages.querySelector('.assistant-message:last-child .message-content');
if (assistantElement) {
assistantElement.innerHTML = this.formatMarkdown(assistantResponse);
// Apply syntax highlighting to any code blocks in the updated content
applySyntaxHighlight($(assistantElement as HTMLElement));
} else {
this.addMessageToChat('assistant', assistantResponse);
}
@@ -292,6 +295,9 @@ export default class LlmChatPanel extends BasicWidget {
this.noteContextChatMessages.appendChild(messageElement);
// Apply syntax highlighting to any code blocks in the message
applySyntaxHighlight($(contentElement));
// Scroll to bottom
this.chatContainer.scrollTop = this.chatContainer.scrollHeight;
}
@@ -382,12 +388,29 @@ export default class LlmChatPanel extends BasicWidget {
* Format markdown content for display
*/
private formatMarkdown(content: string): string {
// Simple markdown formatting - could be replaced with a proper markdown library
return content
if (!content) return '';
// First, extract code blocks to protect them from other replacements
const codeBlocks: string[] = [];
let processedContent = content.replace(/```(\w+)?\n([\s\S]+?)\n```/gs, (match, language, code) => {
const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`;
const languageClass = language ? ` language-${language}` : '';
codeBlocks.push(`<pre class="code${languageClass}"><code>${code}</code></pre>`);
return placeholder;
});
// Apply other markdown formatting
processedContent = processedContent
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/\*(.*?)\*/g, '<em>$1</em>')
.replace(/`(.*?)`/g, '<code>$1</code>')
.replace(/\n/g, '<br>')
.replace(/```(.*?)```/gs, '<pre><code>$1</code></pre>');
.replace(/`([^`]+)`/g, '<code>$1</code>')
.replace(/\n/g, '<br>');
// Restore code blocks
codeBlocks.forEach((block, index) => {
processedContent = processedContent.replace(`__CODE_BLOCK_${index}__`, block);
});
return processedContent;
}
}