|
5 | 5 | import DOMPurify from 'dompurify'; |
6 | 6 | import { settings } from '$lib/stores'; |
7 | 7 | import { isCodeFile, highlightCode } from '$lib/utils/codeHighlight'; |
| 8 | + import { initMermaid, renderMermaidDiagram } from '$lib/utils'; |
8 | 9 | import Spinner from '../../common/Spinner.svelte'; |
9 | 10 | import PDFViewer from '../../common/PDFViewer.svelte'; |
10 | 11 | import JsonTreeView from './JsonTreeView.svelte'; |
|
92 | 93 | ? DOMPurify.sanitize(marked.parse(fileContent, { async: false }) as string) |
93 | 94 | : ''; |
94 | 95 |
|
| 96 | + let markdownEl: HTMLDivElement; |
| 97 | + let mermaidInstance: any = null; |
| 98 | +
|
| 99 | + const renderMermaidBlocks = async (el: HTMLDivElement) => { |
| 100 | + if (!el) return; |
| 101 | + const codeEls = el.querySelectorAll('code.language-mermaid'); |
| 102 | + if (codeEls.length === 0) return; |
| 103 | +
|
| 104 | + if (!mermaidInstance) { |
| 105 | + mermaidInstance = await initMermaid(); |
| 106 | + } |
| 107 | +
|
| 108 | + for (const codeEl of codeEls) { |
| 109 | + const pre = codeEl.parentElement; |
| 110 | + if (!pre || pre.tagName !== 'PRE' || pre.dataset.mermaidRendered) continue; |
| 111 | + pre.dataset.mermaidRendered = 'true'; |
| 112 | +
|
| 113 | + try { |
| 114 | + const svg = await renderMermaidDiagram(mermaidInstance, codeEl.textContent ?? ''); |
| 115 | + if (svg) { |
| 116 | + const wrapper = document.createElement('div'); |
| 117 | + wrapper.className = 'mermaid-diagram flex justify-center py-2'; |
| 118 | + wrapper.innerHTML = svg; |
| 119 | + pre.replaceWith(wrapper); |
| 120 | + } |
| 121 | + } catch (e) { |
| 122 | + console.error('Mermaid render error:', e); |
| 123 | + } |
| 124 | + } |
| 125 | + }; |
| 126 | +
|
| 127 | + $: if (renderedHtml && markdownEl) { |
| 128 | + tick().then(() => renderMermaidBlocks(markdownEl)); |
| 129 | + } |
| 130 | +
|
95 | 131 | // Simple CSV parser that handles quoted fields |
96 | 132 | const parseCsv = (text: string, delimiter: string): string[][] => { |
97 | 133 | const rows: string[][] = []; |
|
341 | 377 | title="HTML Preview" |
342 | 378 | /> |
343 | 379 | {:else if isMarkdown && !showRaw} |
344 | | - <div class="prose dark:prose-invert max-w-full text-sm p-3"> |
| 380 | + <div bind:this={markdownEl} class="prose dark:prose-invert max-w-full text-sm p-3"> |
345 | 381 | {@html renderedHtml} |
346 | 382 | </div> |
347 | 383 | {:else if isCsv && !showRaw && csvRows.length > 0} |
|
0 commit comments