blob: 7a3c7dfce77a80e2406e6835892ff4e61999aaa1 [file] [log] [blame]
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<script setup lang="ts">
import { Marked } from 'marked'
import { markedHighlight } from 'marked-highlight'
import { copyText } from '@/utils/tools'
import { message } from 'ant-design-vue'
import hljs from 'highlight.js'
type Props = {
markRaw: string
}
const props = withDefaults(defineProps<Props>(), {
markRaw: ''
})
const { t } = useI18n()
const { markRaw } = toRefs(props)
const markdownContent = computed(() => parseMDByHighlight(markRaw.value))
const copyCode = (code: string) => {
copyText(code)
.then(() => {
message.success(`${t('common.copy_success')}`)
})
.catch((err: Error) => {
message.error(`${t('common.copy_fail')}`)
console.log('err :>> ', err)
})
}
const upgradeCodeBlock = async (el: HTMLElement) => {
await nextTick()
const pres = el.querySelectorAll('pre')
pres.forEach((pre) => {
const code = pre.querySelector('code')
const langTag = pre.querySelector('#language')
const copyTag = pre.querySelector('#copy')
langTag!.textContent = (code?.classList.value.replace('hljs language-', '') as string).toLowerCase()
if (copyTag) {
copyTag.removeEventListener('click', () => copyCode(code?.textContent || ''))
copyTag.addEventListener('click', () => copyCode(code?.textContent || ''))
}
})
}
const upgradedCodeBlock = (parsedMarked: string) => {
const upgradeParts = `<pre style="padding:0"><div class="code-block-head"><label id="language">Code</label><button id="copy">${t(
'common.copy'
)}</button></div>`
return parsedMarked.replace(/<pre>/g, upgradeParts)
}
const getMarkedHighlightOps = () => {
return markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
return hljs.highlight(code, { language }).value
}
})
}
const parseMDByHighlight = (content: string) => {
const marked = new Marked(getMarkedHighlightOps())
return upgradedCodeBlock(marked.parse(content) as string)
}
const vUpgradeCodeBlock = {
updated: upgradeCodeBlock,
mounted: upgradeCodeBlock
}
</script>
<template>
<div v-upgradeCodeBlock v-dompurify-html="markdownContent" class="markdown-body"> </div>
</template>
<style lang="scss" scoped></style>