From ebc8338488cbfe1299aedb503fc94e11e45e7d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?sunsonliu=28=E5=88=98=E9=98=B3=29?= Date: Mon, 27 May 2024 11:56:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=92=8C=E5=8A=A0=E7=B2=97=E6=96=9C=E4=BD=93=E8=AF=AD=E6=B3=95?= =?UTF-8?q?=E5=AF=B9=E6=B5=81=E5=BC=8F=E8=BE=93=E5=87=BA=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E7=9A=84=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/ai_chat.html | 6 +++--- examples/scripts/ai-chat-demo.js | 14 ++++++++++++-- src/Cherry.config.js | 2 ++ src/Engine.js | 31 +++++++++++++++++++++++++++++++ src/core/hooks/Table.js | 7 +++++++ 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/examples/ai_chat.html b/examples/ai_chat.html index eac63b82..0860b7cf 100644 --- a/examples/ai_chat.html +++ b/examples/ai_chat.html @@ -13,8 +13,6 @@ margin-right: auto; padding: 0; width: 70%; - min-width: 800px; - height: 100%; } .one-msg { margin-top: 50px; @@ -38,9 +36,11 @@ } .chat-one-msg { display: inline-block; + max-width: 600px; } .buttons { margin-top: 50px; + margin-bottom: 100px; } .button { display: inline-block; @@ -78,7 +78,7 @@
- 获取消息() + 获取消息(剩余条消息)
开启流式适配 diff --git a/examples/scripts/ai-chat-demo.js b/examples/scripts/ai-chat-demo.js index 2a6d40db..0ec578b0 100644 --- a/examples/scripts/ai-chat-demo.js +++ b/examples/scripts/ai-chat-demo.js @@ -14,6 +14,12 @@ var cherryConfig = { }, header: { anchorStyle: 'none', + }, + table: { + selfClosing: false, + }, + fontEmphasis: { + selfClosing: false, } } }, @@ -24,8 +30,12 @@ var cherryConfig = { }; const msgList = [ - '在流式输出的情况下,文字会一个一个的输出到页面上\n在输出代码块时,cherry会自动补全代码块:\n```\nalert("hello world");\nalert("hello world");\n```\n代码块输出结束了。', - '在输出无序列表的时候,cherry会自动修复无序列表的内容,是内容在输出时不会命中标题语法:\n- 无序列表第一行\n- 无序列表第二行\n- 无序列表第三行\n\n无序列表结束了。\n用短横线命中标题\n--\n标题结束了。', + '在流式输出的情况下cherry提供了更快的渲染频率(最快每**10ms渲染一次**)\n在关闭流式输出时,cherry的渲染频率为最快**50ms渲染一次**。', + '在流式输出的情况下输出**加粗文字时,cherry会自动补全加粗文字**。\n在流式输出的情况下输出*斜体文字时,cherry会自动补全斜体文字*。', + '在流式输出的情况下,文字会一个一个的输出到页面上\n在输出**代码块**时,cherry会自动补全代码块:\n```\nalert("hello world");\nalert("hello world");\n```\n代码块输出结束了。', + '在流式输出的情况下输出**无序列表**的时候,cherry会自动修复无序列表的内容,使内容在输出时不会命中标题语法:\n- 无序列表第一行\n- 无序列表第二行\n- 无序列表第三行\n\n无序列表结束了。\n用短横线命中标题\n--\n标题结束了。', + '在流式输出的情况下输出**表格**时,在输出第一行表格内容后,cherry自动补全表格的第二行:\n|项目(居中对齐)|价格(右对齐)|数量(左对齐)|\n|:-:|-:|:-|\n|计算机|¥1600|5|\n|手机机|¥12|50|\n表格输出结束了。', + '输出比较丰富的富媒体内容:\n## 字体样式\n\n**说明**\n\n- 使用`*(或_)` 和 `**(或__)` 表示*斜体*和 **粗体**\n- 使用 `/` 表示 /下划线/ ,使用`~~` 表示~~删除线~~\n- 使用`^(或^^)`表示^上标^或^^下标^^\n- 使用 ! 号+数字 表示字体 !24 大! !12 小! [^专有语法提醒]\n- 使用两个(三个)!号+RGB 颜色 表示!!#ff0000 字体颜色!!(!!!#f9cb9c 背景颜色!!!)[^专有语法提醒]\n\n**示例**\n\n```markdown\n[!!#ff0000 红色超链接!!](http://www.qq.com)\n[!!#ffffff !!!#000000 黑底白字超链接!!!!!](http://www.qq.com)\n[新窗口打开](http://www.qq.com){target=_blank}\n鞋子 !32 特大号!\n大头 ^`儿子`^ 和小头 ^^`爸爸`^^\n爱在~~西元前~~**当下**\n```\n\n**效果**\n[!!#ff0000 红色超链接!!](http://www.qq.com)\n[!!#ffffff !!!#000000 黑底白字超链接!!!!!](http://www.qq.com)\n[新窗口打开](http://www.qq.com){target=_blank}\n鞋子 !32 特大号!\n大头 ^`儿子`^ 和小头 ^^`爸爸`^^\n爱在~~西元前~~**当下**\n\n---\n\n## 标题设置\n\n**说明**\n\n- 在文字下方加 === 可使上一行文字变成一级标题\n- 在文字下方加 --- 可使上一行文字变成二级标题\n- 在行首加井号(#)表示不同级别的标题,例如:# H1, ##H2, ###H3\n\n---\n## 信息面板\n\n**说明**\n使用连续三个冒号`:::`和关键字(`[primary | info | warning | danger | success]`)来声明\n\n```markdown\n:::primary // [primary | info | warning | danger | success] 标题\n内容\n:::\n```\n\n**效果**\n:::p 标题\n内容\n:::\n:::success\n内容\n:::\n\n---\n\n## 手风琴\n\n**说明**\n使用连续三个加号`+++`和关键字(`[ + | - ]`)来声明,关键字`+`表示默认收起,关键字`-`表示默认展开\n\n```markdown\n+++ 点击展开更多\n内容\n++- 默认展开\n内容\n++ 默认收起\n内容\n+++\n```\n\n**效果**\n+++ 点击展开更多\n内容\n++- 默认展开\n内容\n++ 默认收起\n内容\n+++', ]; const dialog = document.querySelector('.j-dialog'); diff --git a/src/Cherry.config.js b/src/Cherry.config.js index 83ece13f..418e858d 100644 --- a/src/Cherry.config.js +++ b/src/Cherry.config.js @@ -154,6 +154,7 @@ const defaultConfig = { }, table: { enableChart: false, + selfClosing: false, // 自动闭合,为true时,当输入第一行table内容时,cherry会自动按表格进行解析 // chartRenderEngine: EChartsTableEngine, // externals: ['echarts'], }, @@ -203,6 +204,7 @@ const defaultConfig = { * __hello__ ====> hello */ allowWhitespace: false, + selfClosing: false, // 自动闭合,为true时,当输入**XXX时,会自动在末尾追加** }, strikethrough: { /** diff --git a/src/Engine.js b/src/Engine.js index d877aec9..f64df1e4 100644 --- a/src/Engine.js +++ b/src/Engine.js @@ -104,6 +104,37 @@ export default class Engine { $str = $str.replace(/\$/g, '~D'); $str = $str.replace(/\r\n/g, '\n'); // DOS to Unix $str = $str.replace(/\r/g, '\n'); // Mac to Unix + if ( + // @ts-ignore + this.$cherry.options.engine.syntax.fontEmphasis.selfClosing || + this.$cherry.options.engine.global.flowSessionContext + ) { + // 自动补全最后一行的加粗、斜体语法 + if (/(^|\n)[^\n]*\*{1,3}[^\n]+$/.test($str) && $str.match(/(^|\n)([^\n]+)$/)) { + const lastLineStr = $str.match(/(^|\n)([^\n]+)$/)[2].split(/(\*{1,3})/g); + const emphasis = []; + for (let i = 0; i < lastLineStr.length; i++) { + if (/\*{1,3}/.test(lastLineStr[i])) { + const current = lastLineStr[i]; + if (emphasis.length <= 0) { + emphasis.push(current); + } else { + if (emphasis[emphasis.length - 1] === current) { + emphasis.pop(); + } else { + emphasis.push(current); + } + } + } + } + if (emphasis.length === 1) { + $str = $str.replace(/(\*{1,3})(\s*)([^*\n]+?)$/, '$1$2$3$2$1'); + } + if (emphasis.length === 2) { + $str = $str.replace(/(\*{1,3})(\s*)([^*\n]+?)\*{0,2}$/, '$1$2$3$2$1'); + } + } + } // 避免正则性能问题,如/.+\n/.test(' '.repeat(99999)), 回溯次数过多 // 参考文章:http://www.alloyteam.com/2019/07/13574/ if ($str[$str.length - 1] !== '\n') { diff --git a/src/core/hooks/Table.js b/src/core/hooks/Table.js index 56f0e356..ba42723a 100644 --- a/src/core/hooks/Table.js +++ b/src/core/hooks/Table.js @@ -26,11 +26,13 @@ export default class Table extends ParagraphBase { super({ needCache: true }); const { enableChart, + selfClosing, chartRenderEngine: ChartRenderEngine, externals: requiredPackages, chartEngineOptions = {}, } = config; this.chartRenderEngine = null; + this.selfClosing = selfClosing; if (enableChart === true) { try { this.chartRenderEngine = new ChartRenderEngine({ @@ -223,6 +225,11 @@ export default class Table extends ParagraphBase { makeHtml(str, sentenceMakeFunc) { let $str = str; + if (this.$engine.$cherry.options.engine.global.flowSessionContext || this.selfClosing) { + if (/(^|^[^|][^\n]*\n|\n\n|\n[^|][^\n]*\n)\s*\|[^\n]+\n{0,1}[|:-\s]*\n*$/.test($str)) { + $str = `${$str.replace(/\n[|:-\s]*\n*$/, '')}\n|-|`; + } + } // strict fenced mode if (this.test($str, TABLE_STRICT)) { $str = $str.replace(this.RULE[TABLE_STRICT].reg, (match, leading) => {