feat: support more markdown syntaxes

closes #102, partial #40
This commit is contained in:
三咲智子 2022-11-26 04:19:45 +08:00
parent adf8c5cc1e
commit c9ae7cf942
No known key found for this signature in database
GPG key ID: 69992F2250DFD93E
4 changed files with 62 additions and 10 deletions

View file

@ -4,6 +4,7 @@ import { parseFragment } from 'parse5'
import type { Component, VNode } from 'vue'
import { Fragment, h, isVNode } from 'vue'
import { RouterLink } from 'vue-router'
import MarkdownIt from 'markdown-it'
import ContentCode from '~/components/content/ContentCode.vue'
type Node = DefaultTreeAdapterMap['childNode']
@ -46,11 +47,17 @@ function handleNode(el: Element) {
return handleBlocks(el) || handleMention(el) || el
}
const md = new MarkdownIt()
md.renderer.rules.fence = (tokens, idx) => {
const token = tokens[idx]
return `<custom-code lang="${token.info.trim().toLowerCase() || ''}" code="${encodeURIComponent(token.content)}"></custom-code>\n`
}
export function contentToVNode(
content: string,
customEmojis: Record<string, Emoji> = {},
): VNode {
content = content
content = md.render(htmlToText(content)
.trim()
// handle custom emojis
.replace(/:([\w-]+?):/g, (_, name) => {
@ -58,13 +65,7 @@ export function contentToVNode(
if (emoji)
return `<img src="${emoji.url}" alt="${name}" class="custom-emoji" />`
return `:${name}:`
})
// handle code frames
.replace(/<p>(```|~~~)([\s\S]+?)\1/g, (_1, _2, raw) => {
const plain = htmlToText(`<p>${raw}</p>`).trim()
const [lang, ...rest] = plain.split(/\n/)
return `<custom-code lang="${lang?.trim().toLowerCase() || ''}" code="${encodeURIComponent(rest.join('\n'))}"></custom-code>`
})
}))
const tree = parseFragment(content)
return h(Fragment, tree.childNodes.map(n => treeToVNode(n)))