fix: render code block without language (#276)
parent
18d5fd4804
commit
0f06653636
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
code: string
|
code: string
|
||||||
lang: string
|
lang?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const raw = $computed(() => decodeURIComponent(props.code).replace(/'/g, '\''))
|
const raw = $computed(() => decodeURIComponent(props.code).replace(/'/g, '\''))
|
||||||
|
@ -13,7 +13,7 @@ const langMap: Record<string, string> = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlighted = computed(() => {
|
const highlighted = computed(() => {
|
||||||
return props.lang ? highlightCode(raw, langMap[props.lang] || props.lang as any) : raw
|
return props.lang ? highlightCode(raw, (langMap[props.lang] || props.lang) as any) : raw
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ function handleCodeBlock(el: Element) {
|
||||||
const codeEl = el.childNodes[0] as Element
|
const codeEl = el.childNodes[0] as Element
|
||||||
const classes = codeEl.attrs.find(i => i.name === 'class')?.value
|
const classes = codeEl.attrs.find(i => i.name === 'class')?.value
|
||||||
const lang = classes?.split(/\s/g).find(i => i.startsWith('language-'))?.replace('language-', '')
|
const lang = classes?.split(/\s/g).find(i => i.startsWith('language-'))?.replace('language-', '')
|
||||||
const code = treeToText(codeEl.childNodes[0])
|
const code = codeEl.childNodes[0] ? treeToText(codeEl.childNodes[0]) : ''
|
||||||
return h(ContentCode, { lang, code: encodeURIComponent(code) })
|
return h(ContentCode, { lang, code: encodeURIComponent(code) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,10 @@ export function parseMastodonHTML(html: string, customEmojis: Record<string, Emo
|
||||||
return `:${name}:`
|
return `:${name}:`
|
||||||
})
|
})
|
||||||
// handle code blocks
|
// handle code blocks
|
||||||
.replace(/>(```|~~~)([\s\S]+?)\1/g, (_1, _2, raw) => {
|
.replace(/>(```|~~~)(\w*)([\s\S]+?)\1/g, (_1, _2, lang, raw) => {
|
||||||
const plain = htmlToText(raw)
|
const code = htmlToText(raw)
|
||||||
const [lang, ...code] = plain.split('\n')
|
|
||||||
const classes = lang ? ` class="language-${lang}"` : ''
|
const classes = lang ? ` class="language-${lang}"` : ''
|
||||||
return `><pre><code${classes}>${code.join('\n')}</code></pre>`
|
return `><pre><code${classes}>${code}</code></pre>`
|
||||||
})
|
})
|
||||||
|
|
||||||
const tree = parseFragment(processed)
|
const tree = parseFragment(processed)
|
||||||
|
|
|
@ -25,6 +25,22 @@ exports[`content-rich > code frame 2 1`] = `
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`content-rich > code frame empty 1`] = `
|
||||||
|
"<p></p>
|
||||||
|
<pre></pre>
|
||||||
|
<br />
|
||||||
|
<p></p>
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`content-rich > code frame no lang 1`] = `
|
||||||
|
"<p></p>
|
||||||
|
<pre>hello world</pre>
|
||||||
|
<br />no lang
|
||||||
|
<p></p>
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`content-rich > custom emoji 1`] = `
|
exports[`content-rich > custom emoji 1`] = `
|
||||||
"Daniel Roe
|
"Daniel Roe
|
||||||
<img
|
<img
|
||||||
|
|
|
@ -39,6 +39,16 @@ describe('content-rich', () => {
|
||||||
const { formatted } = await render('<p><span class=\"h-card\"><a href=\"https://mas.to/@antfu\" class=\"u-url mention\">@<span>antfu</span></a></span> Testing<br />```ts<br />const a = hello<br />```</p>')
|
const { formatted } = await render('<p><span class=\"h-card\"><a href=\"https://mas.to/@antfu\" class=\"u-url mention\">@<span>antfu</span></a></span> Testing<br />```ts<br />const a = hello<br />```</p>')
|
||||||
expect(formatted).toMatchSnapshot()
|
expect(formatted).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('code frame no lang', async () => {
|
||||||
|
const { formatted } = await render('<p>```<br />hello world<br />```<br />no lang</p>')
|
||||||
|
expect(formatted).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('code frame empty', async () => {
|
||||||
|
const { formatted } = await render('<p>```<br /><br />```<br /></p>')
|
||||||
|
expect(formatted).toMatchSnapshot()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
async function render(content: string, emojis?: Record<string, Emoji>) {
|
async function render(content: string, emojis?: Record<string, Emoji>) {
|
||||||
|
|
Loading…
Reference in New Issue