From ab6346ea1cbda41ea587633bf790eb7781257028 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Mon, 5 Aug 2024 17:47:18 +0200 Subject: [PATCH 1/3] refac: markdown rendering Co-Authored-By: Jun Siang Cheah --- .../chat/Messages/MarkdownInlineTokens.svelte | 44 +++++++ .../chat/Messages/MarkdownTokens.svelte | 118 ++++++++++++++++++ .../chat/Messages/ResponseMessage.svelte | 12 +- .../chat/Messages/TokenRenderer.svelte | 97 -------------- src/lib/components/common/Image.svelte | 4 +- src/lib/utils/index.ts | 5 + 6 files changed, 173 insertions(+), 107 deletions(-) create mode 100644 src/lib/components/chat/Messages/MarkdownInlineTokens.svelte create mode 100644 src/lib/components/chat/Messages/MarkdownTokens.svelte delete mode 100644 src/lib/components/chat/Messages/TokenRenderer.svelte diff --git a/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte b/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte new file mode 100644 index 000000000..82090d7bb --- /dev/null +++ b/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte @@ -0,0 +1,44 @@ + + +{#each tokens as token} + {#if token.type === 'escape'} + {unescapeHtml(token.text)} + {:else if token.type === 'html'} + {@html token.text} + {:else if token.type === 'link'} + {token.text} + {:else if token.type === 'image'} + {token.text} + {:else if token.type === 'strong'} + + + + {:else if token.type === 'em'} + + + + {:else if token.type === 'codespan'} + {unescapeHtml(token.text.replaceAll('&', '&'))} + {:else if token.type === 'br'} +
+ {:else if token.type === 'del'} + + + + {:else if token.type === 'text'} + {unescapeHtml(token.text)} + {/if} +{/each} diff --git a/src/lib/components/chat/Messages/MarkdownTokens.svelte b/src/lib/components/chat/Messages/MarkdownTokens.svelte new file mode 100644 index 000000000..fd86a586c --- /dev/null +++ b/src/lib/components/chat/Messages/MarkdownTokens.svelte @@ -0,0 +1,118 @@ + + +{#each tokens as token, tokenIdx} + {#if token.type === 'hr'} +
+ {:else if token.type === 'heading'} + + + + {:else if token.type === 'code'} + + {:else if token.type === 'table'} + + + + {#each token.header as header, headerIdx} + + {/each} + + + + {#each token.rows as row, rowIdx} + + {#each row ?? [] as cell, cellIdx} + + {/each} + + {/each} + +
+ +
+ +
+ {:else if token.type === 'blockquote'} +
+ +
+ {:else if token.type === 'list'} + {#if token.ordered} +
    + {#each token.items as item, itemIdx} +
  1. + +
  2. + {/each} +
+ {:else} +
    + {#each token.items as item, itemIdx} +
  • + +
  • + {/each} +
+ {/if} + {:else if token.type === 'html'} + {@html token.text} + {:else if token.type === 'paragraph'} +

+ +

+ {:else if token.type === 'text'} + {#if top} +

+ {#if token.tokens} + + {:else} + {unescapeHtml(token.text)} + {/if} +

+ {:else if token.tokens} + + {:else} + {unescapeHtml(token.text)} + {/if} + {:else if token.type === 'space'} + {''} + {:else} + {console.log('Unknown token', token)} + {/if} +{/each} diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 5cb0cbeef..10ded00fd 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -38,7 +38,7 @@ import Spinner from '$lib/components/common/Spinner.svelte'; import WebSearchResults from './ResponseMessage/WebSearchResults.svelte'; import Sparkles from '$lib/components/icons/Sparkles.svelte'; - import TokenRenderer from './TokenRenderer.svelte'; + import MarkdownTokens from './MarkdownTokens.svelte'; export let message; export let siblings; @@ -77,9 +77,7 @@ let selectedCitation = null; - $: tokens = marked.lexer( - replaceTokens(sanitizeResponseContent(message?.content), model?.name, $user?.name) - ); + $: tokens = marked.lexer(sanitizeResponseContent(message?.content)); $: if (message) { renderStyling(); @@ -413,7 +411,7 @@ {/if}
{#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0} @@ -499,9 +497,7 @@ {:else if message.content && message.error !== true} - {#each tokens as token, tokenIdx} - - {/each} + {/if} {#if message.error} diff --git a/src/lib/components/chat/Messages/TokenRenderer.svelte b/src/lib/components/chat/Messages/TokenRenderer.svelte deleted file mode 100644 index ce0c38d41..000000000 --- a/src/lib/components/chat/Messages/TokenRenderer.svelte +++ /dev/null @@ -1,97 +0,0 @@ - - -
- {#if token.type === 'code'} - {#if token.lang === 'mermaid'} -
{revertSanitizedResponseContent(token.text)}
- {:else} - - {/if} - {:else if token.type === 'image'} - {token.text} - {:else} - {#each content as part} - {@html part.startsWith('{{@IMAGE ') || part.startsWith('{{@CODE ') ? '' : part} - - {#if images.length > 0 && part.startsWith('{{@IMAGE ')} - {@const img = images[parseInt(part.match(/{{@IMAGE (\d+)}}/)[1])]} - -
- -
- {:else if codes.length > 0 && part.startsWith('{{@CODE ')} - {@const _code = codes[parseInt(part.match(/{{@CODE (\d+)}}/)[1])]} -
- -
- {/if} - {/each} - {/if} -
diff --git a/src/lib/components/common/Image.svelte b/src/lib/components/common/Image.svelte index 425b9bc4f..99f1eb405 100644 --- a/src/lib/components/common/Image.svelte +++ b/src/lib/components/common/Image.svelte @@ -17,9 +17,9 @@ on:click={() => { showImagePreview = true; }} - class="w-full" + class=" w-fit" > - +
diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 9200de968..385b006ab 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -90,6 +90,11 @@ export const revertSanitizedResponseContent = (content: string) => { return content.replaceAll('<', '<').replaceAll('>', '>'); }; +export function unescapeHtml(html: string) { + const doc = new DOMParser().parseFromString(html, 'text/html'); + return doc.documentElement.textContent; +} + export const capitalizeFirstLetter = (string) => { return string.charAt(0).toUpperCase() + string.slice(1); }; From 37b117a84c2fca1ad27ecb279aebe5c1f75e1b73 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Mon, 5 Aug 2024 18:00:04 +0200 Subject: [PATCH 2/3] fix: styling --- .../chat/Messages/ResponseMessage.svelte | 2 +- src/lib/components/common/Image.svelte | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 10ded00fd..d6245d83d 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -411,7 +411,7 @@ {/if}
{#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0} diff --git a/src/lib/components/common/Image.svelte b/src/lib/components/common/Image.svelte index 99f1eb405..020e016e8 100644 --- a/src/lib/components/common/Image.svelte +++ b/src/lib/components/common/Image.svelte @@ -5,21 +5,26 @@ export let src = ''; export let alt = ''; - let _src = ''; + export let className = ''; + let _src = ''; $: _src = src.startsWith('/') ? `${WEBUI_BASE_URL}${src}` : src; let showImagePreview = false; -
- + src={_src} + {alt} + class=" rounded-lg" + draggable="false" + data-cy="image" + />
From ac3c6573156d3ac8b9a28ca8b751de7f28d8cd44 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Mon, 5 Aug 2024 18:00:55 +0200 Subject: [PATCH 3/3] refac --- src/lib/components/chat/Messages/ResponseMessage.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index d6245d83d..9924c0931 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -411,7 +411,7 @@ {/if}
{#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0}