Browse Source

fix(render): highlight quill code blocks and fix light-theme contrast

- highlightHtmlCode only queried pre, but Quill v2 code blocks are
  div.ql-code-block-container > div.ql-code-block, so they never got
  highlighted; convert them to pre > code.hljs like markdown blocks
- light theme inherited github-dark's near-white base color on a light
  background; force a dark code block background in light mode
main
Mohan 1 month ago
parent
commit
93a24877b0
  1. 11
      src/assets/markdown-override.css
  2. 43
      src/utils/markdown.ts

11
src/assets/markdown-override.css

@ -83,6 +83,17 @@
word-break: normal;
}
/* 浅色主题:代码块固定深色底(与编辑器内深色代码块一致),保证 github-dark 配色可读 */
.markdown-body:not(.markdown-body-dark) pre {
background-color: #151b23;
color: #e6edf3;
border: 1px solid #3d444d;
}
.markdown-body:not(.markdown-body-dark) pre code {
color: #e6edf3;
}
.markdown-body.markdown-body-dark .ql-code-block-container {
background-color: #151b23;
border-color: #3d444d;

43
src/utils/markdown.ts

@ -16,24 +16,41 @@ marked.use(
})
)
function highlightCode(code: string, lang: string): string {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value
}
return hljs.highlightAuto(code).value
}
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')
const blocks = Array.from(doc.querySelectorAll<HTMLElement>('pre, .ql-code-block-container'))
for (const block of blocks) {
if (block.classList.contains('ql-code-block-container')) {
const lines = Array.from(block.querySelectorAll<HTMLElement>('.ql-code-block'))
const text = lines.map((el) => el.textContent ?? '').join('\n').replace(/\n$/, '')
const lang = block.getAttribute('data-language') ?? ''
const pre = doc.createElement('pre')
pre.className = 'hljs'
const code = doc.createElement('code')
code.className = lang ? `hljs language-${lang}` : 'hljs'
code.innerHTML = highlightCode(text, lang)
pre.appendChild(code)
block.replaceWith(pre)
continue
}
const container = block.closest<HTMLElement>('.ql-code-block-container')
const codeEl = block.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
}
const text = codeEl ? codeEl.textContent ?? '' : block.textContent ?? ''
const highlighted = highlightCode(text, lang)
if (codeEl) {
codeEl.innerHTML = highlighted
codeEl.classList.add('hljs')
@ -41,8 +58,8 @@ function highlightHtmlCode(html: string): string {
const newCode = doc.createElement('code')
newCode.className = 'hljs'
newCode.innerHTML = highlighted
pre.innerHTML = ''
pre.appendChild(newCode)
block.innerHTML = ''
block.appendChild(newCode)
}
}
return doc.body.innerHTML

Loading…
Cancel
Save