Improve markdown rendering and syntax highlighting

This commit is contained in:
Shantur Rathore
2025-10-28 16:42:23 +00:00
parent d18e44f721
commit d743ebda29
3 changed files with 174 additions and 38 deletions

View File

@@ -3,6 +3,8 @@ import type { Highlighter } from "shiki/bundle/full"
import { useTheme } from "../lib/theme"
import { getSharedHighlighter, escapeHtml } from "../lib/markdown"
const inlineLoadedLanguages = new Set<string>()
interface CodeBlockInlineProps {
code: string
language?: string
@@ -18,7 +20,7 @@ export function CodeBlockInline(props: CodeBlockInlineProps) {
onMount(async () => {
highlighter = await getSharedHighlighter()
setReady(true)
updateHighlight()
await updateHighlight()
})
createEffect(() => {
@@ -26,11 +28,11 @@ export function CodeBlockInline(props: CodeBlockInlineProps) {
isDark()
props.code
props.language
updateHighlight()
void updateHighlight()
}
})
const updateHighlight = () => {
const updateHighlight = async () => {
if (!highlighter) return
if (!props.language) {
@@ -39,6 +41,11 @@ export function CodeBlockInline(props: CodeBlockInlineProps) {
}
try {
if (!inlineLoadedLanguages.has(props.language)) {
await highlighter.loadLanguage(props.language)
inlineLoadedLanguages.add(props.language)
}
const highlighted = highlighter.codeToHtml(props.code, {
lang: props.language,
theme: isDark() ? "github-dark" : "github-light",

View File

@@ -1,5 +1,5 @@
import { createEffect, createSignal, onMount, onCleanup } from "solid-js"
import { renderMarkdown } from "../lib/markdown"
import { renderMarkdown, onLanguagesLoaded } from "../lib/markdown"
import type { TextPart } from "../types/message"
interface MarkdownProps {
@@ -16,13 +16,13 @@ export function Markdown(props: MarkdownProps) {
const part = props.part
const text = part.text || ""
latestRequestedText = text
if (part.renderCache && part.renderCache.text === text) {
setHtml(part.renderCache.html)
return
}
latestRequestedText = text
try {
const rendered = await renderMarkdown(text)
@@ -62,8 +62,29 @@ export function Markdown(props: MarkdownProps) {
containerRef?.addEventListener("click", handleClick)
// Register listener for language loading completion
const cleanupLanguageListener = onLanguagesLoaded(async () => {
const part = props.part
const text = part.text || ""
if (latestRequestedText !== text) {
return
}
try {
const rendered = await renderMarkdown(text)
if (latestRequestedText === text) {
setHtml(rendered)
part.renderCache = { text, html: rendered }
}
} catch (error) {
console.error("Failed to re-render markdown after language load:", error)
}
})
onCleanup(() => {
containerRef?.removeEventListener("click", handleClick)
cleanupLanguageListener()
})
})