diff --git a/package-lock.json b/package-lock.json
index b7e714ed7..2006a3fd3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,6 +29,7 @@
"js-sha256": "^0.10.1",
"katex": "^0.16.9",
"marked": "^9.1.0",
+ "marked-katex-extension": "^5.1.1",
"mermaid": "^10.9.1",
"pyodide": "^0.26.1",
"socket.io-client": "^4.2.0",
@@ -1544,6 +1545,11 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
+ "node_modules/@types/katex": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
+ "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="
+ },
"node_modules/@types/mdast": {
"version": "3.0.15",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz",
@@ -6036,6 +6042,18 @@
"node": ">= 16"
}
},
+ "node_modules/marked-katex-extension": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/marked-katex-extension/-/marked-katex-extension-5.1.1.tgz",
+ "integrity": "sha512-piquiCyZpZ1aiocoJlJkRXr+hkk5UI4xw9GhRZiIAAgvX5rhzUDSJ0seup1JcsgueC8MLNDuqe5cRcAzkFE42Q==",
+ "dependencies": {
+ "@types/katex": "^0.16.7"
+ },
+ "peerDependencies": {
+ "katex": ">=0.16 <0.17",
+ "marked": ">=4 <15"
+ }
+ },
"node_modules/matcher-collection": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz",
diff --git a/package.json b/package.json
index 0c7a8518a..bd2b173bf 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
"js-sha256": "^0.10.1",
"katex": "^0.16.9",
"marked": "^9.1.0",
+ "marked-katex-extension": "^5.1.1",
"mermaid": "^10.9.1",
"pyodide": "^0.26.1",
"socket.io-client": "^4.2.0",
diff --git a/src/lib/components/chat/Messages/KatexRenderer.svelte b/src/lib/components/chat/Messages/KatexRenderer.svelte
new file mode 100644
index 000000000..766454c29
--- /dev/null
+++ b/src/lib/components/chat/Messages/KatexRenderer.svelte
@@ -0,0 +1,9 @@
+
+
+{@html katex.renderToString(content, { displayMode, throwOnError: false })}
diff --git a/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte b/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte
index 7f984264b..170429f4b 100644
--- a/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte
+++ b/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte
@@ -1,8 +1,11 @@
@@ -25,14 +28,21 @@
{:else if token.type === 'codespan'}
- {unescapeHtml(token.text.replaceAll('&', '&'))}
+ {revertSanitizedResponseContent(token.raw)}
{:else if token.type === 'br'}
{:else if token.type === 'del'}
+ {:else if token.type === 'inlineKatex'}
+ {#if token.text}
+
+ {/if}
{:else if token.type === 'text'}
- {unescapeHtml(token.text)}
+ {token.raw}
{/if}
{/each}
diff --git a/src/lib/components/chat/Messages/MarkdownTokens.svelte b/src/lib/components/chat/Messages/MarkdownTokens.svelte
index 1f27fb4eb..089a0847a 100644
--- a/src/lib/components/chat/Messages/MarkdownTokens.svelte
+++ b/src/lib/components/chat/Messages/MarkdownTokens.svelte
@@ -1,17 +1,22 @@
+
{#each tokens as token, tokenIdx}
{#if token.type === 'hr'}
@@ -104,6 +109,13 @@
{:else}
{unescapeHtml(token.text)}
{/if}
+ {:else if token.type === 'inlineKatex'}
+ {#if token.text}
+
+ {/if}
{:else if token.type === 'space'}
{''}
{:else}
diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte
index 1226b5231..2ecbd418c 100644
--- a/src/lib/components/chat/Messages/ResponseMessage.svelte
+++ b/src/lib/components/chat/Messages/ResponseMessage.svelte
@@ -4,7 +4,6 @@
import { marked } from 'marked';
import tippy from 'tippy.js';
import auto_render from 'katex/dist/contrib/auto-render.mjs';
- import 'katex/dist/katex.min.css';
import mermaid from 'mermaid';
import { fade } from 'svelte/transition';
@@ -79,19 +78,24 @@
let tokens;
+ import 'katex/dist/katex.min.css';
+
+ import markedKatex from '$lib/utils/katex-extension';
+
+ const options = {
+ throwOnError: false
+ };
+
+ marked.use(markedKatex(options));
+
$: (async () => {
if (message?.content) {
tokens = marked.lexer(
replaceTokens(sanitizeResponseContent(message?.content), model?.name, $user?.name)
);
- // console.log(message?.content, tokens);
}
})();
- $: if (message) {
- renderStyling();
- }
-
const renderStyling = async () => {
await tick();
diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts
index 5b5c69047..de3a2ca2c 100644
--- a/src/lib/utils/index.ts
+++ b/src/lib/utils/index.ts
@@ -25,7 +25,8 @@ const convertLatexToSingleLine = (content) => {
export const sanitizeResponseContent = (content: string) => {
// replace single backslash with double backslash
- content = content.replace(/\\/g, '\\\\');
+ content = content.replace(/\\\\/g, '\\\\\\\\');
+
content = convertLatexToSingleLine(content);
// First, temporarily replace valid