Repository: ggerganov/llama.cpp
File: tools/server/webui/src/lib/components/app/misc/MarkdownContent.svelte (Svelte)

Code before:
	import rehypeKatex from 'rehype-katex';
	import rehypeStringify from 'rehype-stringify';
	import { copyCodeToClipboard } from '$lib/utils/copy';
	import { browser } from '$app/environment';
	import 'katex/dist/katex.min.css';

	import githubDarkCss from 'highlight.js/styles/github-dark.css?inline';
	import githubLightCss from 'highlight.js/styles/github.css?inline';
	import { mode } from 'mode-watcher';
	import { remarkLiteralHtml } from '$lib/markdown/literal-html';

	interface Props {
		content: string;
		class?: string;
	}

	let { content, class: className = '' }: Props = $props();

	let containerRef = $state<HTMLDivElement>();
	let processedHtml = $state('');

	function loadHighlightTheme(isDark: boolean) {
		if (!browser) return;

		const existingThemes = document.querySelectorAll('style[data-highlight-theme]');
		existingThemes.forEach((style) => style.remove());

		const style = document.createElement('style');
		style.setAttribute('data-highlight-theme', 'true');
		style.textContent = isDark ? githubDarkCss : githubLightCss;

		document.head.appendChild(style);
	}

	$effect(() => {
		const currentMode = mode.current;
		const isDark = currentMode === 'dark';

		loadHighlightTheme(isDark);
	});

	let processor = $derived(() => {
		return remark()
			.use(remarkGfm) // GitHub Flavored Markdown
			.use(remarkMath) // Parse $inline$ and $$block$$ math
			.use(remarkBreaks) // Convert line breaks to <br>
			.use(remarkLiteralHtml) // Treat raw HTML as literal text with preserved indentation
			.use(remarkRehype) // Convert Markdown AST to rehype
			.use(rehypeKatex) // Render math using KaTeX
			.use(rehypeHighlight) // Add syntax highlighting
			.use(rehypeStringify); // Convert to HTML string

Review comment (suggestion):
Svelte code won't work in preview iframe at this stage, let's just have it just for HTML/JavaScript for now 😉

```suggestion
	const previewableLanguages = new Set(['html', 'htm', 'javascript', 'js']);
```


Code after:
	import rehypeKatex from 'rehype-katex';
	import rehypeStringify from 'rehype-stringify';
	import { copyCodeToClipboard } from '$lib/utils/copy';
	import { browser } from '$app/environment';
	import 'katex/dist/katex.min.css';

	import githubDarkCss from 'highlight.js/styles/github-dark.css?inline';
	import githubLightCss from 'highlight.js/styles/github.css?inline';
	import { mode } from 'mode-watcher';
	import { remarkLiteralHtml } from '$lib/markdown/literal-html';
	import CodePreviewDialog from './CodePreviewDialog.svelte';

	interface Props {
		content: string;
		class?: string;
	}

	let { content, class: className = '' }: Props = $props();

	let containerRef = $state<HTMLDivElement>();
	let processedHtml = $state('');
	let previewDialogOpen = $state(false);
	let previewCode = $state('');
	let previewLanguage = $state('text');

	function loadHighlightTheme(isDark: boolean) {
		if (!browser) return;

		const existingThemes = document.querySelectorAll('style[data-highlight-theme]');
		existingThemes.forEach((style) => style.remove());

		const style = document.createElement('style');
		style.setAttribute('data-highlight-theme', 'true');
		style.textContent = isDark ? githubDarkCss : githubLightCss;

		document.head.appendChild(style);
	}

	$effect(() => {
		const currentMode = mode.current;
		const isDark = currentMode === 'dark';

		loadHighlightTheme(isDark);
	});

	let processor = $derived(() => {
		return remark()
			.use(remarkGfm) // GitHub Flavored Markdown
			.use(remarkMath) // Parse $inline$ and $$block$$ math
			.use(remarkBreaks) // Convert line breaks to <br>
			.use(remarkLiteralHtml) // Treat raw HTML as literal text with preserved indentation