115 lines
3.7 KiB
Vue
115 lines
3.7 KiB
Vue
<script lang="ts">
|
|
import type { RootContent, Root } from 'hast';
|
|
import { Text, Comment } from 'vue';
|
|
|
|
import ProseP from '~/components/prose/ProseP.vue';
|
|
import ProseA from '~/components/prose/ProseA.vue';
|
|
import ProseBlockquote from '~/components/prose/ProseBlockquote.vue';
|
|
import ProseCallout from './prose/ProseCallout.vue';
|
|
import ProseCode from '~/components/prose/ProseCode.vue';
|
|
import ProsePre from '~/components/prose/ProsePre.vue';
|
|
import ProseEm from '~/components/prose/ProseEm.vue';
|
|
import ProseH1 from '~/components/prose/ProseH1.vue';
|
|
import ProseH2 from '~/components/prose/ProseH2.vue';
|
|
import ProseH3 from '~/components/prose/ProseH3.vue';
|
|
import ProseH4 from '~/components/prose/ProseH4.vue';
|
|
import ProseH5 from '~/components/prose/ProseH5.vue';
|
|
import ProseH6 from '~/components/prose/ProseH6.vue';
|
|
import ProseHr from '~/components/prose/ProseHr.vue';
|
|
import ProseImg from '~/components/prose/ProseImg.vue';
|
|
import ProseUl from '~/components/prose/ProseUl.vue';
|
|
import ProseOl from '~/components/prose/ProseOl.vue';
|
|
import ProseLi from '~/components/prose/ProseLi.vue';
|
|
import ProseSmall from './prose/ProseSmall.vue';
|
|
import ProseStrong from '~/components/prose/ProseStrong.vue';
|
|
import ProseTable from '~/components/prose/ProseTable.vue';
|
|
import ProseTag from '~/components/prose/ProseTag.vue';
|
|
import ProseThead from '~/components/prose/ProseThead.vue';
|
|
import ProseTbody from '~/components/prose/ProseTbody.vue';
|
|
import ProseTd from '~/components/prose/ProseTd.vue';
|
|
import ProseTh from '~/components/prose/ProseTh.vue';
|
|
import ProseTr from '~/components/prose/ProseTr.vue';
|
|
import ProseScript from '~/components/prose/ProseScript.vue';
|
|
|
|
const proseList = {
|
|
"p": ProseP,
|
|
"a": ProseA,
|
|
"blockquote": ProseBlockquote,
|
|
"callout": ProseCallout,
|
|
"code": ProseCode,
|
|
"pre": ProsePre,
|
|
"em": ProseEm,
|
|
"h1": ProseH1,
|
|
"h2": ProseH2,
|
|
"h3": ProseH3,
|
|
"h4": ProseH4,
|
|
"h5": ProseH5,
|
|
"h6": ProseH6,
|
|
"hr": ProseHr,
|
|
"img": ProseImg,
|
|
"ul": ProseUl,
|
|
"ol": ProseOl,
|
|
"li": ProseLi,
|
|
"small": ProseSmall,
|
|
"strong": ProseStrong,
|
|
"table": ProseTable,
|
|
"tag": ProseTag,
|
|
"thead": ProseThead,
|
|
"tbody": ProseTbody,
|
|
"td": ProseTd,
|
|
"th": ProseTh,
|
|
"tr": ProseTr,
|
|
"script": ProseScript
|
|
};
|
|
|
|
export default defineComponent({
|
|
name: 'MarkdownRenderer',
|
|
props: {
|
|
node: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
proses: {
|
|
type: Object,
|
|
default: () => ({})
|
|
}
|
|
},
|
|
async setup(props) {
|
|
if(props.proses)
|
|
{
|
|
for(const prose of Object.keys(props.proses))
|
|
{
|
|
if(typeof props.proses[prose] === 'string')
|
|
props.proses[prose] = await resolveComponent(props.proses[prose]);
|
|
}
|
|
}
|
|
return { tags: Object.assign({}, proseList, props.proses) };
|
|
},
|
|
render(ctx: any) {
|
|
const { node, tags } = ctx;
|
|
|
|
if(!node)
|
|
return null;
|
|
|
|
return h('div', null, {default: () => (node as Root).children.map(e => renderNode(e, tags)).filter(e => !!e)});
|
|
}
|
|
});
|
|
|
|
function renderNode(node: RootContent, tags: Record<string, any>): VNode | undefined
|
|
{
|
|
if(node.type === 'text' && node.value.length > 0 && node.value !== '\n')
|
|
{
|
|
return h(Text, node.value);
|
|
}
|
|
else if(node.type === 'comment' && node.value.length > 0 && node.value !== '\n')
|
|
{
|
|
return h(Comment, node.value);
|
|
}
|
|
else if(node.type === 'element')
|
|
{
|
|
return h(tags[node.tagName] ?? node.tagName, { ...node.properties, class: node.properties.className }, { default: () => node.children.map(e => renderNode(e, tags)).filter(e => !!e) });
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
</script> |