开发喵星球

实现GPT输出格式化

实现GPT输出格式化

一、还原里面的富文本展示

chatgpt返回结果是这样的

"冒泡排序是一种简单直观的排序算法,它重复地比较相邻的两个元素,如果顺序错误就交换它们的位置,直到没有任何一对数字需要比较为止。以下是 JavaScript 实现冒泡排序的代码:\n\n```\nfunction bubbleSort(arr) {\n  var len = arr.length;\n  for (var i = 0; i < len - 1; i++) {\n    for (var j = 0; j < len - 1 - i; j++) {\n      if (arr[j] > arr[j + 1]) {\n        // 交换相邻两个元素\n        var temp = arr[j];\n        arr[j] = arr[j + 1];\n        arr[j + 1] = temp;\n      }\n    }\n  }\n  return arr;\n}\n\n// 测试代码\nvar arr = [5, 2, 4, 6, 1, 3];\nconsole.log(bubbleSort(arr)); // [1, 2, 3, 4, 5, 6]\n```\n\n上述代码中,外层循环执行 len - 1 次,内层循环执行 len - 1 - i 次。如果 arr[j] 大于 arr[j + 1],则交换它们的位置。最后返回排好序的数组 arr。"

最终实现效果

image-20240318142447749

这里不仅还原了文本格式的展示,而且也还原了代码高亮。
可以看出chatgpt返回的是markdawn文本格式,要对markdawn文本格式做下处理,采用的是很强大的marked.js工具,感情兴趣的可以到官网看看:https://marked.js.org/

// Create reference instance
import { marked } from 'marked';

// Set options
// `highlight` example uses https://highlightjs.org
marked.setOptions({
  renderer: new marked.Renderer(),
  highlight: function(code, lang) {
    const hljs = require('highlight.js');
    const language = hljs.getLanguage(lang) ? lang : 'plaintext';
    return hljs.highlight(code, { language }).value;
  },
  langPrefix: 'hljs language-', // highlight.js css expects a top-level 'hljs' class.
  pedantic: false,
  gfm: true,
  breaks: false,
  sanitize: false,
  smartypants: false,
  xhtml: false
});

// Compile
console.log(marked.parse(markdownString));

这是给出的官方示例,开箱即用。

项目里面引入marked.min.js和highlight.min.js文件

项目初始化时引入上面配置,marked.parse()方法会把markdawn格式转化为html格式。

二、消息发送框还原文本格式

消息发送框一共有两种实现方案: div模拟和textarea

div模拟textarea

效果如图

image-20240318143013472

这里保留了原问题的换行符等格式,一开始实现简单的消息发送,采用的是input框,当然input框肯定保留不了文本格式,看了一下chatgpt网站,发现他们使用的是textarea文本框,textarea文本框可以保留文本格式,我就采用dom的一个属性 contenteditable 去模拟了一个textarea

image-20240318143114352

去掉粘贴文本格式

paste(event) {
    let e = event || window.event
    // 阻止默认粘贴
    e.preventDefault();
    let text =  (e.originalEvent || e).clipboardData.getData('text/plain');
    document.execCommand("insertText", false, text);

}

设置placeholder

.ask-input:empty:before{
    content: attr(placeholder);
    color:#bbb;
}

文本折行

.input-container .ask-input-box .ask-input * {
    word-break: break-all;
    white-space: pre-wrap !important;
} 

去掉滚动条

.ask-input::-webkit-scrollbar {
    display: none
};

image-20240318143357788

image-20240318143439488

编辑的时候做了一个简单切换,这样也就能保留原来文本格式

textarea实现高度自适应

textareaHeight1: 22

autoResize1() {
    this.textareaHeight1 = 22; // 自适应减小
    this.nextTick(() => {
        this.textareaHeight1 = this.refs.textarea1.scrollHeight;
    });
},
.input-container .ask-input-box textarea {
    width: 100%;
    max-height: 200px !important;
    color: var(--vscode-foreground);
    font-size: 14px;
    /* 去掉默认字体样式 */
    font-family: inherit; 
    font-weight: inherit;
    border: 1px solid #ccc;
    border-radius: 4px;
    resize: none;
    padding: 0;
    border: none;
    outline: none;
}

实现起来也很简单!

使用innerHTML一样显示html标签
为了保留文本的原格式我们都会设置innerHTML,但是有一个缺陷就是 如果想显示标签怎么办,html标签可以做转义处理

str.replaceAll('<', '<').replaceAll('>', '>')

其他的就不多讲了,感兴趣的小伙伴可以自己动手实现。

   
分类:未分类 作者:荡荡, 浩浩 发表于:2024-03-18 14:37:45 阅读量:13
<<   >>


powered by kaifamiao