Skip to content

Commit d508ce1

Browse files
committed
fix: markdown rendering
1 parent 62b82f6 commit d508ce1

File tree

1 file changed

+30
-32
lines changed

1 file changed

+30
-32
lines changed

src/lib/components/chat/MarkdownRenderer.svelte

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import type { WebSearchSource } from "$lib/types/WebSearch";
33
import katex from "katex";
44
import DOMPurify from "isomorphic-dompurify";
5-
import { marked, type MarkedOptions } from "marked";
5+
import { Marked } from "marked";
66
import CodeBlock from "../CodeBlock.svelte";
77
88
export let content: string;
@@ -30,24 +30,6 @@
3030
});
3131
}
3232
33-
const renderer = new marked.Renderer();
34-
35-
// For code blocks with simple backticks
36-
renderer.codespan = (code) => {
37-
// Unsanitize double-sanitized code
38-
return `<code>${code.replaceAll("&amp;", "&")}</code>`;
39-
};
40-
41-
renderer.link = (href, title, text) => {
42-
return `<a href="${href?.replace(/>$/, "")}" target="_blank" rel="noreferrer">${text}</a>`;
43-
};
44-
45-
const options: MarkedOptions = {
46-
gfm: true,
47-
// breaks: true,
48-
renderer,
49-
};
50-
5133
function escapeHTML(content: string) {
5234
return content.replace(
5335
/[<>&\n]/g,
@@ -60,8 +42,6 @@
6042
);
6143
}
6244
63-
$: tokens = marked.lexer(addInlineCitations(content, sources));
64-
6545
function processLatex(parsed: string) {
6646
const delimiters = [
6747
{ left: "$$", right: "$$", display: true },
@@ -98,6 +78,21 @@
9878
return parsed;
9979
}
10080
81+
const marked = new Marked({
82+
hooks: {
83+
preprocess: (md) => addInlineCitations(escapeHTML(md), sources),
84+
postprocess: (html) => {
85+
return DOMPurify.sanitize(processLatex(html));
86+
},
87+
},
88+
renderer: {
89+
codespan: (code) => `<code>${code.replaceAll("&amp;", "&")}</code>`,
90+
link: (href, title, text) =>
91+
`<a href="${href?.replace(/>$/, "")}" target="_blank" rel="noreferrer">${text}</a>`,
92+
},
93+
gfm: true,
94+
});
95+
10196
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
10297
if (node.tagName === "A") {
10398
node.setAttribute("rel", "noreferrer");
@@ -106,17 +101,20 @@
106101
});
107102
</script>
108103

109-
{#each tokens as token}
110-
{#if token.type === "code"}
111-
<CodeBlock lang={token.lang} code={token.text} />
112-
{:else}
113-
{@const parsed = marked.parse(processLatex(escapeHTML(token.raw)), options)}
114-
{#await parsed then parsed}
115-
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
116-
{@html DOMPurify.sanitize(parsed)}
117-
{/await}
118-
{/if}
119-
{/each}
104+
<div
105+
class="prose max-w-none dark:prose-invert max-sm:prose-sm prose-headings:font-semibold prose-h1:text-lg prose-h2:text-base prose-h3:text-base prose-pre:bg-gray-800 dark:prose-pre:bg-gray-900"
106+
>
107+
{#each marked.lexer(content) as token}
108+
{#if token.type === "code"}
109+
<CodeBlock lang={token.lang} code={token.text} />
110+
{:else}
111+
{#await marked.parse(token.raw) then parsed}
112+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
113+
{@html parsed}
114+
{/await}
115+
{/if}
116+
{/each}
117+
</div>
120118

121119
<style lang="postcss">
122120
:global(.katex-display) {

0 commit comments

Comments
 (0)