大模型输出markdown格式前端对话框
大模型输出markdown格式前端对话框
1. 先看效果
2. 安装依赖
npm install marked md-editor-v3 --save
// 下面的是我安装的版本
"marked": "^12.0.2",
"md-editor-v3": "^4.16.7",
3. 关键文件
MdPreview.vue
<template>
<MdPreview noIconfont noPrettier :codeFoldable="false" v-bind="$attrs" />
</template>
<script setup lang="ts">
import 'md-editor-v3/lib/style.css';
import { MdPreview } from 'md-editor-v3'
</script>
MdRenderer.vue
<template>
<MdPreview noIconfont editorId="preview-only" :modelValue="source" class="klb-md" />
</template>
<script setup>
import { config } from 'md-editor-v3'
import MdPreview from './MdPeview.vue'
import 'md-editor-v3/lib/style.css';
config({
markdownItConfig(md) {
md.renderer.rules.image = (tokens, idx, options, env, self) => {
tokens[idx].attrSet('style', 'display:inline-block;min-height:33px;padding:0;margin:0')
if (tokens[idx].content) {
tokens[idx].attrSet('title', tokens[idx].content)
}
tokens[idx].attrSet(
'onerror',
'this.src="/ui/assets/load_error.png";this.onerror=null;this.height="33px"'
)
return md.renderer.renderToken(tokens, idx, options)
}
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
tokens[idx].attrSet('target', '_blank')
return md.renderer.renderToken(tokens, idx, options)
}
document.appendChild
}
})
const props = defineProps({
source: String,
})
</script>
<style lang="scss" scoped>
.problem-button {
width: 100%;
border: none;
border-radius: 8px;
background: var(--app-layout-bg-color);
height: 46px;
padding: 0 12px;
line-height: 46px;
box-sizing: border-box;
color: var(--el-text-color-regular);
-webkit-line-clamp: 1;
word-break: break-all;
&:hover {
background: var(--el-color-primary-light-9);
}
&.disabled {
&:hover {
background: var(--app-layout-bg-color);
}
}
:deep(.el-icon) {
color: var(--el-color-primary);
}
}
</style>
index.vue
<template>
<MdRenderer :source="answer_text">
</MdRenderer>
</template>
<script setup>
import MdRenderer from './MdRenderer.vue'
const props = defineProps({
answer_text: String
})
判断字符串中的是不是富文本还是markdown
// 查找字符串内的所有markdown标签标签
export const findMarkdownTags = (text) => {
const patterns = {
headers: /^(#+\s+.*$)/gm,
emphasis: /(\*[^*]*\*|\_[^\_]*\_)/g,
bold: /(\*\*[^*]*\*\*|\_\_[^\_]*\_\_)/g,
links: /(\[.*?\]\(.*?\))/g,
images: /(\!\[.*?\]\(.*?\))/g,
code: /(```[\s\S]*?```|`[^`]*`)/g,
lists: /^-.*$(\n^-.*$)*/gm
};
const results = {};
for (const [tag, pattern] of Object.entries(patterns)) {
results[tag] = text.match(pattern) || [];
}
const list = []
for (let key in results) {
if (results[key].length != 0)
list.push(...results[key])
}
return list.length;
}
// 查找字符串内的所有Html标签标签
export const findHtmlTags = (str) => {
// str = '样式的字符串。'
const regex = /<\/?[\w\s="/.':;#-\(\)\?,\+&%$!\[\]*]+>/g;
const tags = str.match(regex) || []
return tags.length
}