我们公司最近写了一个仿照gpt回答用户问题的网站
我要实现一个功能,正确展示代码,如下图:
这里面我遇到了一些问题,记录下来:
1、代码高亮
后端返回的markdown格式的字符串,所以我要用插件转化为dom结构,这里我使用的插件是:markdown-it,代码高亮我使用的插件是:highlight.js
markdonw-it官方文档:https://markdown-it.docschina.org/
我按照官方文档写了如下代码:
<span v-html="mdToHtml(content)"></span>
import hljs from "highlight.js";
import 'highlight.js/styles/a11y-dark.css'
// 通常的默认值们
var md = require('markdown-it')('commonmark', {
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return '<pre class="hljs"><code>' +
hljs.highlight(lang, str, true).value +
'</code></pre>';
} catch (__) {}
}
return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
}
});
export default {
methods: {
mdToHtml(content) {
return md.render(content)
},
}
2、系统回答问题的过程中字体忽大忽小
QQ录屏20231106180307
从视频里明显的看到材料两个字由大变小,体验不好
这个有问题的回答,后端返给我的字符串是这个:
content: "鱼香肉丝是一道经典的川菜,下面是鱼香肉丝的做法步骤:\n\n材料:\n- 猪肉(瘦肉):150克......"
把内容固定为:
<span v-html="mdToHtml(`\n\n材料:\n-`)"></span>
现在展示的样式是:
把内容固定为:
<span v-html="mdToHtml(`\n\n材料:\n- 猪肉(瘦肉)`)"></span>
现在展示的样式是:
问题这就找到了,那我想如果markdown-it遇到其他的字符串不去解析成dom,只在遇到代码字符串的时候解析成dom,这个问题就解决了
markdown-it git地址:markdown-it
在项目里找到这个文件:lib/presets/commonmark.js,把components对象复制过来,然后我试了试,只留下fence和paragraph的时候可以达到我想要的效果
md.configure({
components: {
core: {
rules: [
'normalize',
'block',
'inline',
'text_join'
]
},
block: {
rules: [
// 'blockquote',
// 'code',
'fence',
// 'heading',
// 'hr',
// 'html_block',
// 'lheading',
// 'list',
// 'reference',
'paragraph'
]
},
inline: {
rules: [
// 'autolink',
// 'backticks',
// 'emphasis',
// 'entity',
// 'escape',
// 'html_inline',
// 'image',
// 'link',
// 'newline',
// 'text'
],
rules2: [
// 'balance_pairs',
// 'emphasis',
// 'fragments_join'
]
}
}
});
这个问题就这样解决了