最近随着chatGPT越来越火,各大公司都基于gpt衍生了一些业务,其中比较多的是使用openAI搭建自己公司内部使用的问答项目,搭配回答问题中,嵌入公司自身的产品等。
openAI接口,返回的回答通过div中dangerouslySetInnerHTML属性嵌入,能够有较好的显示样式,但是对越代码块部分,显示不够显眼,对其中的代码进行高亮和支持代码复制功能变得必不可少。
使用效果:
marked
是一个流行的 JavaScript 库,用于将 Markdown 格式的文本转换为 HTML。它提供了简单易用的 API,使得在网页中渲染和展示 Markdown 内容变得非常方便。
要使用 marked
插件,首先需要引入 marked
库。你可以通过以下几种方式之一来获取并引入 marked
:
- 通过 CDN 引入:
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
- 使用 NPM 安装:
npm install marked
然后在你的 JavaScript 文件中导入 marked
:
import marked from 'marked';
- 使用marked对代码块进行高亮显示和增加复制功能:
<div className={styles["content-items"]}
dangerouslySetInnerHTML={{ __html:
marked(item.content, {
highlight: function (code, language) {
// 通过时间戳生成唯一标识
const codeIndex = parseInt(Date.now() + "") + Math.floor(Math.random() * 10000000);
// 格式化第一行是右侧language和 “复制” 按钮;
let html = `
<div class=${styles["code-block-header"]}>
<span>${language}</span>
<span id='copy-btn'data-clipboard-action="copy" data-clipboard-target="#copy${codeIndex}">复制代码</span>
</div>
`;
//代码部分
if (code) {
try {
// 使用 highlight.js 对代码进行高亮显示
const preCode = hljs.highlightAuto(code).value;
// 将代码包裹在 textarea 中,由于防止textarea渲染出现问题,这里将 "<" 用 "<" 代替,不影响复制功能
return `<pre class='${styles["hljs-customer"]} hljs'>
<code>${preCode}</code>
</pre>
<textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy${codeIndex}">${code.replace(/<\/textarea>/g,"</textarea>")}</textarea>`;
} catch (error) {
console.log(error);
}
}
}}) as string,
=}}
/>
</div>
- 复制部分代码:
const clipboard = new Clipboard("#copy-btn");
// 复制成功失败的提示
clipboard.on("success", (e) => {
message.success(
intl.formatMessage({
id: "contentPage.复制成功",
})
);
});
clipboard.on("error", (e) => {
message.error(
intl.formatMessage({
id: "contentPage.复制失败",
})
);
});
放在项目组件初始化的生命周期函数中,react放在useEffect中,vue放在mounted中。
5.根据喜好,选择不同的highlight样式: highlight.js提供了多种高亮显示样式,官网链接
引入样式方式:
import "highlight.js/styles/paraiso-light.css";