open-webui / src /lib /components /chat /Messages /Markdown.svelte
github-actions[bot]
GitHub deploy: 114f709337283743a81be86c3a39cf0feb28014a
bf4f454
Raw
History Blame Contribute Delete
2.36 kB
<script>
import { onDestroy } from 'svelte';
import { marked } from 'marked';
import { replaceTokens, processResponseContent } from '$lib/utils';
import { user } from '$lib/stores';
import markedExtension from '$lib/utils/marked/extension';
import markedKatexExtension from '$lib/utils/marked/katex-extension';
import { disableSingleTilde } from '$lib/utils/marked/strikethrough-extension';
import { mentionExtension } from '$lib/utils/marked/mention-extension';
import MarkdownTokens from './Markdown/MarkdownTokens.svelte';
import footnoteExtension from '$lib/utils/marked/footnote-extension';
import citationExtension from '$lib/utils/marked/citation-extension';
export let id = '';
export let content;
export let done = true;
export let model = null;
export let save = false;
export let preview = false;
export let paragraphTag = 'p';
export let editCodeBlock = true;
export let topPadding = false;
export let sourceIds = [];
export let onSave = () => {};
export let onUpdate = () => {};
export let onPreview = () => {};
export let onSourceClick = () => {};
export let onTaskClick = () => {};
let tokens = [];
let pendingUpdate = null;
const options = {
throwOnError: false,
breaks: true
};
marked.use(markedKatexExtension(options));
marked.use(markedExtension(options));
marked.use(citationExtension(options));
marked.use(footnoteExtension(options));
marked.use(disableSingleTilde);
marked.use({
extensions: [
mentionExtension({ triggerChar: '@' }),
mentionExtension({ triggerChar: '#' }),
mentionExtension({ triggerChar: '$' })
]
});
const parseTokens = () => {
tokens = marked.lexer(replaceTokens(processResponseContent(content), model?.name, $user?.name));
};
// Throttle parsing to once per animation frame while streaming
$: if (content) {
if (done) {
cancelAnimationFrame(pendingUpdate);
pendingUpdate = null;
parseTokens();
} else if (!pendingUpdate) {
pendingUpdate = requestAnimationFrame(() => {
pendingUpdate = null;
parseTokens();
});
}
}
onDestroy(() => {
cancelAnimationFrame(pendingUpdate);
});
</script>
{#key id}
<MarkdownTokens
{tokens}
{id}
{done}
{save}
{preview}
{paragraphTag}
{editCodeBlock}
{sourceIds}
{topPadding}
{onTaskClick}
{onSourceClick}
{onSave}
{onUpdate}
{onPreview}
/>
{/key}