Browse Source

feat(render): highlight quill code blocks with language

main
Mohan 1 month ago
parent
commit
60fe06841e
  1. 16
      src/assets/markdown-override.css
  2. 35
      src/utils/markdown.ts

16
src/assets/markdown-override.css

@ -66,8 +66,20 @@
}
.markdown-body .ql-code-block {
white-space: pre-wrap;
word-break: break-word;
white-space: pre;
word-break: normal;
overflow-x: auto;
}
/* Markdown code blocks: horizontal scroll, no wrapping */
.markdown-body pre {
overflow-x: auto;
}
.markdown-body pre code {
white-space: pre;
word-break: normal;
overflow-x: auto;
}
.markdown-body.markdown-body-dark .ql-code-block-container {

35
src/utils/markdown.ts

@ -16,9 +16,42 @@ marked.use(
})
)
function highlightHtmlCode(html: string): string {
const doc = new DOMParser().parseFromString(html, 'text/html')
const blocks = Array.from(doc.querySelectorAll<HTMLElement>('pre'))
for (const pre of blocks) {
const container = pre.closest<HTMLElement>('.ql-code-block-container')
const codeEl = pre.querySelector<HTMLElement>('code')
let lang = container?.getAttribute('data-language') ?? ''
if (!lang && codeEl) {
const m = (codeEl.className || '').match(/language-([\w-]+)/)
if (m) lang = m[1]
}
const text = codeEl ? codeEl.textContent ?? '' : pre.textContent ?? ''
let highlighted: string
if (lang && hljs.getLanguage(lang)) {
highlighted = hljs.highlight(text, { language: lang }).value
} else {
highlighted = hljs.highlightAuto(text).value
}
if (codeEl) {
codeEl.innerHTML = highlighted
codeEl.classList.add('hljs')
} else {
const newCode = doc.createElement('code')
newCode.className = 'hljs'
newCode.innerHTML = highlighted
pre.innerHTML = ''
pre.appendChild(newCode)
}
}
return doc.body.innerHTML
}
export function renderArticle(content: string): string {
if (content.trimStart().startsWith('<')) {
return DOMPurify.sanitize(content)
const safe = DOMPurify.sanitize(content)
return highlightHtmlCode(safe)
}
const rawHtml = marked.parse(content, { async: false }) as string
return DOMPurify.sanitize(rawHtml)
Loading…
Cancel
Save