@ant-design/agentic-ui 2.14.1 → 2.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Bubble/BubbleBeforeNode.js +9 -9
- package/dist/Bubble/List/PureBubbleList.js +1 -1
- package/dist/Bubble/MessagesContent/EXCEPTION.js +1 -1
- package/dist/ChatLayout/style.js +16 -17
- package/dist/Constants/mobile.d.ts +3 -0
- package/dist/Constants/mobile.js +7 -0
- package/dist/Hooks/useLanguage.d.ts +2 -0
- package/dist/I18n/locales.d.ts +2 -0
- package/dist/I18n/locales.js +4 -0
- package/dist/MarkdownEditor/BaseMarkdownEditor.js +1 -1
- package/dist/MarkdownEditor/editor/Editor.js +16 -8
- package/dist/MarkdownEditor/editor/code.css +2 -2
- package/dist/MarkdownEditor/editor/elements/Code.js +11 -6
- package/dist/MarkdownEditor/editor/elements/FootnoteDefinition.js +2 -1
- package/dist/MarkdownEditor/editor/elements/FootnoteReference.js +2 -1
- package/dist/MarkdownEditor/editor/elements/Head.d.ts +1 -0
- package/dist/MarkdownEditor/editor/elements/Head.js +1 -1
- package/dist/MarkdownEditor/editor/elements/Image/index.js +19 -7
- package/dist/MarkdownEditor/editor/elements/LinkCard/index.js +2 -1
- package/dist/MarkdownEditor/editor/elements/LinkCard/style.js +1 -1
- package/dist/MarkdownEditor/editor/elements/List/ListItem.js +1 -0
- package/dist/MarkdownEditor/editor/elements/List/style.js +2 -2
- package/dist/MarkdownEditor/editor/elements/Media.js +22 -10
- package/dist/MarkdownEditor/editor/elements/Paragraph.js +2 -1
- package/dist/MarkdownEditor/editor/elements/Schema.js +1 -1
- package/dist/MarkdownEditor/editor/elements/Table/ReadonlyTableComponent.js +16 -4
- package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +17 -2
- package/dist/MarkdownEditor/editor/elements/Table/Table.js +155 -20
- package/dist/MarkdownEditor/editor/elements/Table/Td/style.js +5 -2
- package/dist/MarkdownEditor/editor/elements/Table/index.js +0 -2
- package/dist/MarkdownEditor/editor/elements/Table/style.js +7 -8
- package/dist/MarkdownEditor/editor/elements/TagPopup/index.js +5 -3
- package/dist/MarkdownEditor/editor/elements/TagPopup/style.js +2 -2
- package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.d.ts +100 -1
- package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +781 -240
- package/dist/MarkdownEditor/editor/plugins/useKeyboard.js +8 -19
- package/dist/MarkdownEditor/editor/store.js +3 -3
- package/dist/MarkdownEditor/editor/style.js +41 -6
- package/dist/MarkdownEditor/editor/tools/DragHandle.js +3 -3
- package/dist/MarkdownEditor/editor/types/Table.d.ts +1 -0
- package/dist/MarkdownEditor/editor/utils/findMatchingClose.d.ts +36 -0
- package/dist/MarkdownEditor/editor/utils/findMatchingClose.js +158 -0
- package/dist/MarkdownEditor/editor/utils/markdownToHtml.d.ts +41 -2
- package/dist/MarkdownEditor/editor/utils/markdownToHtml.js +159 -7
- package/dist/MarkdownEditor/style.js +8 -2
- package/dist/MarkdownEditor/types.d.ts +1 -1
- package/dist/MarkdownEditor/utils/exportHtml.js +1 -1
- package/dist/MarkdownInputField/MarkdownInputField.d.ts +7 -7
- package/dist/MarkdownInputField/MarkdownInputField.js +11 -35
- package/dist/MarkdownInputField/SendButton/index.js +17 -3
- package/dist/MarkdownInputField/style.js +23 -2
- package/dist/Plugins/chart/AreaChart/index.d.ts +12 -0
- package/dist/Plugins/chart/AreaChart/index.js +14 -188
- package/dist/Plugins/chart/BarChart/index.d.ts +2 -0
- package/dist/Plugins/chart/BarChart/index.js +3 -12
- package/dist/Plugins/chart/ChartMark/Container.js +5 -2
- package/dist/Plugins/chart/ChartRender.d.ts +1 -0
- package/dist/Plugins/chart/ChartRender.js +104 -43
- package/dist/Plugins/chart/DonutChart/index.js +4 -2
- package/dist/Plugins/chart/DonutChart/types.d.ts +2 -0
- package/dist/Plugins/chart/FunnelChart/index.d.ts +2 -0
- package/dist/Plugins/chart/FunnelChart/index.js +4 -2
- package/dist/Plugins/chart/LineChart/index.d.ts +2 -0
- package/dist/Plugins/chart/LineChart/index.js +17 -162
- package/dist/Plugins/chart/RadarChart/index.d.ts +2 -0
- package/dist/Plugins/chart/RadarChart/index.js +8 -4
- package/dist/Plugins/chart/ScatterChart/index.d.ts +2 -0
- package/dist/Plugins/chart/ScatterChart/index.js +8 -4
- package/dist/Plugins/chart/components/ChartContainer/ChartContainer.d.ts +1 -0
- package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundaryExample.js +1 -1
- package/dist/Plugins/chart/components/ChartFilter/ChartFilter.d.ts +1 -1
- package/dist/Plugins/chart/components/ChartFilter/ChartFilter.js +210 -16
- package/dist/Plugins/chart/components/ChartToolBar/ChartToolBar.d.ts +2 -0
- package/dist/Plugins/chart/components/ChartToolBar/ChartToolBar.js +9 -2
- package/dist/Plugins/chart/components/ChartToolBar/style.js +3 -1
- package/dist/Plugins/chart/hooks/index.d.ts +10 -0
- package/dist/Plugins/chart/hooks/index.js +8 -0
- package/dist/Plugins/chart/hooks/useChartDataFilter.d.ts +46 -0
- package/dist/Plugins/chart/hooks/useChartDataFilter.js +182 -0
- package/dist/Plugins/chart/hooks/useChartStatistics.d.ts +17 -0
- package/dist/Plugins/chart/hooks/useChartStatistics.js +25 -0
- package/dist/Plugins/chart/hooks/useChartTheme.d.ts +20 -0
- package/dist/Plugins/chart/hooks/useChartTheme.js +30 -0
- package/dist/Plugins/chart/hooks/useResponsiveSize.d.ts +23 -0
- package/dist/Plugins/chart/hooks/useResponsiveSize.js +94 -0
- package/dist/Plugins/chart/index.js +94 -10
- package/dist/Plugins/chart/utils/registerChart.d.ts +35 -0
- package/dist/Plugins/chart/utils/registerChart.js +54 -0
- package/dist/Plugins/chart/utils.d.ts +19 -0
- package/dist/Plugins/chart/utils.js +27 -0
- package/dist/Plugins/code/components/CodeContainer.js +2 -3
- package/dist/Plugins/code/components/CodeRenderer.js +53 -2
- package/dist/Plugins/code/components/CodeToolbar.js +22 -3
- package/dist/Plugins/katex/InlineKatex.js +1 -1
- package/dist/Plugins/katex/Katex.js +1 -1
- package/dist/Plugins/mermaid/Mermaid.js +66 -66
- package/dist/Plugins/mermaid/index.js +1 -1
- package/dist/ThoughtChainList/index.js +21 -2
- package/dist/ThoughtChainList/style.js +1 -0
- package/dist/Utils/loadCSS.js +6 -6
- package/dist/WelcomeMessage/index.js +21 -2
- package/dist/Workspace/Task/index.js +1 -1
- package/package.json +2 -2
|
@@ -101,7 +101,7 @@ import { useEditorStore } from "../store";
|
|
|
101
101
|
var enter = new EnterKey(store, backspace);
|
|
102
102
|
var match = new MatchKey(markdownEditorRef.current);
|
|
103
103
|
return function(e) {
|
|
104
|
-
var _props_markdown,
|
|
104
|
+
var _props_markdown, _node_;
|
|
105
105
|
// 处理表格键盘事件
|
|
106
106
|
if (NativeTableKeyboard.shouldHandle(markdownEditorRef.current)) {
|
|
107
107
|
if (NativeTableKeyboard.handleKeyDown(markdownEditorRef.current, e.nativeEvent)) {
|
|
@@ -190,27 +190,16 @@ import { useEditorStore } from "../store";
|
|
|
190
190
|
return;
|
|
191
191
|
}
|
|
192
192
|
if (e.key === 'Tab') tab.run(e);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
e.stopPropagation();
|
|
196
|
-
e.preventDefault();
|
|
197
|
-
enter.run(e);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (((_props_textAreaProps1 = props.textAreaProps) === null || _props_textAreaProps1 === void 0 ? void 0 : _props_textAreaProps1.triggerSendKey) === 'Mod+Enter') {
|
|
203
|
-
if (e.key === 'Enter' && !(e.ctrlKey || e.metaKey)) {
|
|
204
|
-
e.stopPropagation();
|
|
205
|
-
e.preventDefault();
|
|
206
|
-
enter.run(e);
|
|
207
|
-
}
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (e.key === 'Enter' && !(e.ctrlKey || e.metaKey)) {
|
|
193
|
+
// Enter 发送,Shift+Enter 换行
|
|
194
|
+
if (e.key === 'Enter' && e.shiftKey && !(e.ctrlKey || e.metaKey)) {
|
|
211
195
|
e.stopPropagation();
|
|
212
196
|
e.preventDefault();
|
|
213
197
|
enter.run(e);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// Enter 键(无 Shift)由 MarkdownInputField 处理发送,这里不处理
|
|
201
|
+
if (e.key === 'Enter' && !(e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
|
202
|
+
return;
|
|
214
203
|
}
|
|
215
204
|
var _Editor_nodes1 = _sliced_to_array(Editor.nodes(markdownEditorRef.current, {
|
|
216
205
|
match: function(n) {
|
|
@@ -1606,9 +1606,9 @@ export var EditorStoreContext = createContext(null);
|
|
|
1606
1606
|
var el = _step.value;
|
|
1607
1607
|
var _this_draggedElement1;
|
|
1608
1608
|
if (!ableToEnter.has(el.dataset.be)) continue;
|
|
1609
|
-
if (el.
|
|
1609
|
+
if (el.hasAttribute('data-frontmatter')) continue;
|
|
1610
1610
|
var pre = el.previousSibling;
|
|
1611
|
-
if (el.dataset.be === 'paragraph' && ((_this_draggedElement1 = this.draggedElement) === null || _this_draggedElement1 === void 0 ? void 0 : _this_draggedElement1.dataset.be) === 'list-item' && (!pre || pre.
|
|
1611
|
+
if (el.dataset.be === 'paragraph' && ((_this_draggedElement1 = this.draggedElement) === null || _this_draggedElement1 === void 0 ? void 0 : _this_draggedElement1.dataset.be) === 'list-item' && (!pre || pre.hasAttribute('data-check-item'))) {
|
|
1612
1612
|
continue;
|
|
1613
1613
|
}
|
|
1614
1614
|
if (el === this.draggedElement) continue;
|
|
@@ -1679,7 +1679,7 @@ export var EditorStoreContext = createContext(null);
|
|
|
1679
1679
|
var width = last.el.dataset.be === 'list-item' ? last.el.clientWidth + 20 + 'px' : last.el.clientWidth + 'px';
|
|
1680
1680
|
if (!mark) {
|
|
1681
1681
|
mark = document.createElement('div');
|
|
1682
|
-
mark.
|
|
1682
|
+
mark.setAttribute('data-move-mark', '');
|
|
1683
1683
|
mark.style.width = width;
|
|
1684
1684
|
mark.style.height = '2px';
|
|
1685
1685
|
mark.style.transform = "translate(".concat(last.left - rect.left - scrollLeft, "px, ").concat(last.top - rect.top - scrollTop, "px)");
|
|
@@ -51,6 +51,7 @@ function _object_spread_props(target, source) {
|
|
|
51
51
|
return target;
|
|
52
52
|
}
|
|
53
53
|
import { Keyframes } from "@ant-design/cssinjs";
|
|
54
|
+
import { MOBILE_BREAKPOINT } from "../../Constants/mobile";
|
|
54
55
|
import { resetComponent, useEditorStyleRegister } from "../../Hooks/useStyle";
|
|
55
56
|
import "./code.css";
|
|
56
57
|
// 导入统一的标签样式配置
|
|
@@ -80,7 +81,7 @@ var genStyle = function(token) {
|
|
|
80
81
|
var _obj;
|
|
81
82
|
return _obj = {
|
|
82
83
|
// 拖拽手柄样式
|
|
83
|
-
'
|
|
84
|
+
'[data-drag-handle]': {
|
|
84
85
|
position: 'absolute',
|
|
85
86
|
display: 'flex',
|
|
86
87
|
userSelect: 'none',
|
|
@@ -93,7 +94,7 @@ var genStyle = function(token) {
|
|
|
93
94
|
top: 'calc(3px + 0.75em - 14px)'
|
|
94
95
|
},
|
|
95
96
|
// 拖拽图标样式
|
|
96
|
-
'
|
|
97
|
+
'[data-drag-icon]': {
|
|
97
98
|
display: 'flex',
|
|
98
99
|
alignItems: 'center',
|
|
99
100
|
borderRadius: '18px',
|
|
@@ -106,7 +107,7 @@ var genStyle = function(token) {
|
|
|
106
107
|
}
|
|
107
108
|
},
|
|
108
109
|
// 拖拽元素悬浮效果
|
|
109
|
-
'
|
|
110
|
+
'[data-drag-el]:hover > [data-drag-handle]': {
|
|
110
111
|
opacity: 1
|
|
111
112
|
},
|
|
112
113
|
// 可调整大小组件样式
|
|
@@ -144,7 +145,7 @@ var genStyle = function(token) {
|
|
|
144
145
|
pointerEvents: 'all'
|
|
145
146
|
},
|
|
146
147
|
// 移动标记样式
|
|
147
|
-
'
|
|
148
|
+
'[data-move-mark]': {
|
|
148
149
|
height: '0.125em',
|
|
149
150
|
backgroundColor: 'var(--color-primary-control-fill-primary)',
|
|
150
151
|
left: 0,
|
|
@@ -156,7 +157,7 @@ var genStyle = function(token) {
|
|
|
156
157
|
transitionDuration: '200ms'
|
|
157
158
|
},
|
|
158
159
|
// 隐藏样式
|
|
159
|
-
'
|
|
160
|
+
'[data-hidden]': {
|
|
160
161
|
display: 'none'
|
|
161
162
|
},
|
|
162
163
|
// KaTeX容器样式
|
|
@@ -275,7 +276,7 @@ var genStyle = function(token) {
|
|
|
275
276
|
'h1,h2,h3,h4,h5,h6': {
|
|
276
277
|
position: 'relative',
|
|
277
278
|
textWrap: 'balance',
|
|
278
|
-
'
|
|
279
|
+
'[data-drag-handle]': {
|
|
279
280
|
top: 'calc(3px + 0.05em) !important'
|
|
280
281
|
}
|
|
281
282
|
},
|
|
@@ -424,6 +425,34 @@ var genStyle = function(token) {
|
|
|
424
425
|
},
|
|
425
426
|
'ol,ul': {
|
|
426
427
|
paddingLeft: '1em'
|
|
428
|
+
},
|
|
429
|
+
// 移动端图片和视频响应式样式
|
|
430
|
+
'[data-be="image"], [data-be="media"]': {
|
|
431
|
+
width: '100%',
|
|
432
|
+
maxWidth: '100%',
|
|
433
|
+
boxSizing: 'border-box',
|
|
434
|
+
overflow: 'hidden',
|
|
435
|
+
'[data-be="media-container"]': {
|
|
436
|
+
width: '100%',
|
|
437
|
+
maxWidth: '100%',
|
|
438
|
+
padding: '2px',
|
|
439
|
+
boxSizing: 'border-box'
|
|
440
|
+
},
|
|
441
|
+
'img, video': {
|
|
442
|
+
maxWidth: '100%',
|
|
443
|
+
height: 'auto',
|
|
444
|
+
display: 'block'
|
|
445
|
+
},
|
|
446
|
+
'[data-testid="resize-image-container"]': {
|
|
447
|
+
maxWidth: '100%',
|
|
448
|
+
width: '100% !important',
|
|
449
|
+
boxSizing: 'border-box'
|
|
450
|
+
},
|
|
451
|
+
'[data-testid="video-element"]': {
|
|
452
|
+
maxWidth: '100%',
|
|
453
|
+
width: '100% !important',
|
|
454
|
+
height: 'auto'
|
|
455
|
+
}
|
|
427
456
|
}
|
|
428
457
|
},
|
|
429
458
|
'[data-be]:not(p):not(data-be="list")': {
|
|
@@ -521,6 +550,12 @@ var genStyle = function(token) {
|
|
|
521
550
|
marginTop: '0.3em',
|
|
522
551
|
marginBottom: '0.3em'
|
|
523
552
|
}
|
|
553
|
+
}), _define_property(_obj, "@media (max-width: ".concat(MOBILE_BREAKPOINT, ")"), {
|
|
554
|
+
'div[data-be="paragraph"]': {
|
|
555
|
+
fontSize: '0.95em',
|
|
556
|
+
lineHeight: '1.4em',
|
|
557
|
+
margin: 'var(--margin-1x) 0'
|
|
558
|
+
}
|
|
524
559
|
}), _obj;
|
|
525
560
|
};
|
|
526
561
|
var genSlideStyle = function(token) {
|
|
@@ -40,7 +40,7 @@ export var DragHandle = function(props) {
|
|
|
40
40
|
return /*#__PURE__*/ React.createElement(Tooltip, {
|
|
41
41
|
title: "拖拽移动"
|
|
42
42
|
}, /*#__PURE__*/ React.createElement("span", {
|
|
43
|
-
|
|
43
|
+
"data-drag-handle": true,
|
|
44
44
|
"data-testid": "drag-handle",
|
|
45
45
|
style: _object_spread({}, props.style),
|
|
46
46
|
contentEditable: false,
|
|
@@ -49,7 +49,7 @@ export var DragHandle = function(props) {
|
|
|
49
49
|
var _parent_parentElement;
|
|
50
50
|
var parent = ref.current.parentElement;
|
|
51
51
|
if (((_parent_parentElement = parent.parentElement) === null || _parent_parentElement === void 0 ? void 0 : _parent_parentElement.dataset.be) === 'list-item') {
|
|
52
|
-
if (!parent.previousSibling || parent.previousSibling.
|
|
52
|
+
if (!parent.previousSibling || parent.previousSibling.hasAttribute('data-check-item')) {
|
|
53
53
|
parent = parent.parentElement;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -58,6 +58,6 @@ export var DragHandle = function(props) {
|
|
|
58
58
|
store.draggedElement = parent;
|
|
59
59
|
}
|
|
60
60
|
}, /*#__PURE__*/ React.createElement("div", {
|
|
61
|
-
|
|
61
|
+
"data-drag-icon": true
|
|
62
62
|
}, /*#__PURE__*/ React.createElement(HolderOutlined, null))));
|
|
63
63
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 查找匹配的闭合标记
|
|
3
|
+
*
|
|
4
|
+
* 用于流式解析代码块(特别是 Mermaid 代码块)时,判断代码块是否完整。
|
|
5
|
+
* 通过查找匹配的闭合标记来确定代码块是否已经完成输入。
|
|
6
|
+
*
|
|
7
|
+
* @param src - 源字符串
|
|
8
|
+
* @param startIdx - 开始搜索的索引位置
|
|
9
|
+
* @param open - 开始标记(如 "```", "$$", "(" 等)
|
|
10
|
+
* @param close - 结束标记(如 "```", "$$", ")" 等)
|
|
11
|
+
* @returns 匹配的闭合标记的索引位置,如果未找到则返回 -1
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // 查找代码块的闭合标记
|
|
16
|
+
* const code = "```javascript\nconsole.log('hello');\n```";
|
|
17
|
+
* const closeIdx = findMatchingClose(code, 0, "```", "```");
|
|
18
|
+
* // 返回: 42 (第二个 ``` 的位置)
|
|
19
|
+
*
|
|
20
|
+
* // 查找数学公式的闭合标记
|
|
21
|
+
* const math = "$$\\sum_{i=1}^{n} x_i$$";
|
|
22
|
+
* const closeIdx = findMatchingClose(math, 0, "$$", "$$");
|
|
23
|
+
* // 返回: 最后一个 $ 的位置
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function findMatchingClose(src: string, startIdx: number, open: string, close: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* 检查代码块是否完整(基于代码内容)
|
|
29
|
+
* 用于流式输入时判断代码块是否已经完成
|
|
30
|
+
*
|
|
31
|
+
* @param code - 代码内容
|
|
32
|
+
* @param language - 代码语言(如 'mermaid', 'javascript' 等)
|
|
33
|
+
* @returns 是否可能完整
|
|
34
|
+
*/
|
|
35
|
+
export declare function isCodeBlockLikelyComplete(code: string, language?: string): boolean;
|
|
36
|
+
export default findMatchingClose;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 查找匹配的闭合标记
|
|
3
|
+
*
|
|
4
|
+
* 用于流式解析代码块(特别是 Mermaid 代码块)时,判断代码块是否完整。
|
|
5
|
+
* 通过查找匹配的闭合标记来确定代码块是否已经完成输入。
|
|
6
|
+
*
|
|
7
|
+
* @param src - 源字符串
|
|
8
|
+
* @param startIdx - 开始搜索的索引位置
|
|
9
|
+
* @param open - 开始标记(如 "```", "$$", "(" 等)
|
|
10
|
+
* @param close - 结束标记(如 "```", "$$", ")" 等)
|
|
11
|
+
* @returns 匹配的闭合标记的索引位置,如果未找到则返回 -1
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // 查找代码块的闭合标记
|
|
16
|
+
* const code = "```javascript\nconsole.log('hello');\n```";
|
|
17
|
+
* const closeIdx = findMatchingClose(code, 0, "```", "```");
|
|
18
|
+
* // 返回: 42 (第二个 ``` 的位置)
|
|
19
|
+
*
|
|
20
|
+
* // 查找数学公式的闭合标记
|
|
21
|
+
* const math = "$$\\sum_{i=1}^{n} x_i$$";
|
|
22
|
+
* const closeIdx = findMatchingClose(math, 0, "$$", "$$");
|
|
23
|
+
* // 返回: 最后一个 $ 的位置
|
|
24
|
+
* ```
|
|
25
|
+
*/ export function findMatchingClose(src, startIdx, open, close) {
|
|
26
|
+
var len = src.length;
|
|
27
|
+
// 特殊处理 $$ 因为它是两个字符的分隔符,不应该被解释为嵌套的括号
|
|
28
|
+
if (open === '$$' && close === '$$') {
|
|
29
|
+
var i = startIdx;
|
|
30
|
+
while(i < len - 1){
|
|
31
|
+
if (src[i] === '$' && src[i + 1] === '$') {
|
|
32
|
+
// 确保没有被转义
|
|
33
|
+
var k = i - 1;
|
|
34
|
+
var backslashes = 0;
|
|
35
|
+
while(k >= 0 && src[k] === '\\'){
|
|
36
|
+
backslashes++;
|
|
37
|
+
k--;
|
|
38
|
+
}
|
|
39
|
+
// 如果反斜杠数量是偶数,说明没有被转义
|
|
40
|
+
if (backslashes % 2 === 0) return i;
|
|
41
|
+
}
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
var openChar = open[open.length - 1];
|
|
47
|
+
var closeSeq = close;
|
|
48
|
+
var depth = 0;
|
|
49
|
+
var i1 = startIdx;
|
|
50
|
+
while(i1 < len){
|
|
51
|
+
// 如果这里有一个未转义的闭合序列
|
|
52
|
+
if (src.slice(i1, i1 + closeSeq.length) === closeSeq) {
|
|
53
|
+
var k1 = i1 - 1;
|
|
54
|
+
var backslashes1 = 0;
|
|
55
|
+
while(k1 >= 0 && src[k1] === '\\'){
|
|
56
|
+
backslashes1++;
|
|
57
|
+
k1--;
|
|
58
|
+
}
|
|
59
|
+
// 如果反斜杠数量是偶数,说明没有被转义
|
|
60
|
+
if (backslashes1 % 2 === 0) {
|
|
61
|
+
if (depth === 0) return i1;
|
|
62
|
+
depth--;
|
|
63
|
+
i1 += closeSeq.length;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
var ch = src[i1];
|
|
68
|
+
// 跳过转义字符
|
|
69
|
+
if (ch === '\\') {
|
|
70
|
+
i1 += 2;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// 如果遇到开始字符,增加深度
|
|
74
|
+
if (ch === openChar) {
|
|
75
|
+
depth++;
|
|
76
|
+
} else if (ch === closeSeq[closeSeq.length - 1]) {
|
|
77
|
+
if (depth > 0) depth--;
|
|
78
|
+
}
|
|
79
|
+
i1++;
|
|
80
|
+
}
|
|
81
|
+
return -1;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 检查字符串中是否有未闭合的括号
|
|
85
|
+
*/ function checkUnclosedBrackets(code) {
|
|
86
|
+
// 检查圆括号
|
|
87
|
+
var openParen = findMatchingClose(code, 0, '(', ')');
|
|
88
|
+
if (openParen === -1 && code.includes('(')) {
|
|
89
|
+
// 有开括号但没有匹配的闭括号
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
// 检查方括号
|
|
93
|
+
var openBracket = findMatchingClose(code, 0, '[', ']');
|
|
94
|
+
if (openBracket === -1 && code.includes('[')) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
// 检查花括号
|
|
98
|
+
var openBrace = findMatchingClose(code, 0, '{', '}');
|
|
99
|
+
if (openBrace === -1 && code.includes('{')) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 检查 Mermaid 代码是否完整
|
|
106
|
+
*/ function isMermaidCodeComplete(code) {
|
|
107
|
+
// 检查是否包含基本的 Mermaid 图表类型关键字
|
|
108
|
+
var hasChartType = code.includes('graph') || code.includes('sequenceDiagram') || code.includes('gantt') || code.includes('pie') || code.includes('classDiagram') || code.includes('stateDiagram') || code.includes('erDiagram') || code.includes('journey') || code.includes('gitgraph') || code.includes('flowchart');
|
|
109
|
+
if (!hasChartType) return false;
|
|
110
|
+
// 检查基本结构完整性
|
|
111
|
+
if (code.length < 10) return false;
|
|
112
|
+
// 检查括号匹配
|
|
113
|
+
var hasUnclosedBrackets = checkUnclosedBrackets(code);
|
|
114
|
+
if (hasUnclosedBrackets) return false;
|
|
115
|
+
// 检查是否以常见的不完整模式结尾
|
|
116
|
+
var incompletePatterns = [
|
|
117
|
+
/graph\s*$/i,
|
|
118
|
+
/-->?\s*$/
|
|
119
|
+
];
|
|
120
|
+
var endsWithIncomplete = incompletePatterns.some(function(pattern) {
|
|
121
|
+
return pattern.test(code);
|
|
122
|
+
});
|
|
123
|
+
return !endsWithIncomplete;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 检查代码块是否完整(基于代码内容)
|
|
127
|
+
* 用于流式输入时判断代码块是否已经完成
|
|
128
|
+
*
|
|
129
|
+
* @param code - 代码内容
|
|
130
|
+
* @param language - 代码语言(如 'mermaid', 'javascript' 等)
|
|
131
|
+
* @returns 是否可能完整
|
|
132
|
+
*/ export function isCodeBlockLikelyComplete(code, language) {
|
|
133
|
+
var trimmed = code.trim();
|
|
134
|
+
if (!trimmed) return false;
|
|
135
|
+
// 对于 Mermaid,使用更严格的检查
|
|
136
|
+
if (language === 'mermaid') {
|
|
137
|
+
return isMermaidCodeComplete(trimmed);
|
|
138
|
+
}
|
|
139
|
+
// 对于其他语言,检查基本的完整性
|
|
140
|
+
// 如果代码很短,可能是正在输入中
|
|
141
|
+
if (trimmed.length < 5) return false;
|
|
142
|
+
// 检查是否以常见的不完整模式结尾
|
|
143
|
+
var incompletePatterns = [
|
|
144
|
+
/\\$/,
|
|
145
|
+
/\/\*[\s\S]*$/,
|
|
146
|
+
/\/\/.*$/,
|
|
147
|
+
/['"`][^'"`]*$/
|
|
148
|
+
];
|
|
149
|
+
// 检查括号匹配
|
|
150
|
+
var hasUnclosedBrackets = checkUnclosedBrackets(trimmed);
|
|
151
|
+
if (hasUnclosedBrackets) return false;
|
|
152
|
+
// 如果匹配不完整模式,可能还在输入中
|
|
153
|
+
var endsWithIncomplete = incompletePatterns.some(function(pattern) {
|
|
154
|
+
return pattern.test(trimmed);
|
|
155
|
+
});
|
|
156
|
+
return !endsWithIncomplete;
|
|
157
|
+
}
|
|
158
|
+
export default findMatchingClose;
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import type { Plugin } from 'unified';
|
|
2
2
|
export type MarkdownRemarkPlugin = Plugin | [Plugin, ...unknown[]];
|
|
3
3
|
export type MarkdownToHtmlOptions = MarkdownRemarkPlugin[];
|
|
4
|
+
/**
|
|
5
|
+
* Markdown 转 HTML 的配置选项
|
|
6
|
+
*/
|
|
7
|
+
export interface MarkdownToHtmlConfig {
|
|
8
|
+
/** 是否在新标签页打开链接 */
|
|
9
|
+
openLinksInNewTab?: boolean;
|
|
10
|
+
/** 自定义段落标签,默认为 'p' */
|
|
11
|
+
paragraphTag?: string;
|
|
12
|
+
/** 用户自定义的 unified 插件配置 */
|
|
13
|
+
markedConfig?: MarkdownRemarkPlugin[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* HTML 转义函数
|
|
17
|
+
* @param html - 要转义的 HTML 字符串
|
|
18
|
+
* @param encode - 是否编码所有特殊字符(包括 &)
|
|
19
|
+
* @returns 转义后的字符串
|
|
20
|
+
*/
|
|
21
|
+
export declare function escapeHtml(html: string, encode?: boolean): string;
|
|
4
22
|
export declare const DEFAULT_MARKDOWN_REMARK_PLUGINS: readonly MarkdownRemarkPlugin[];
|
|
5
23
|
/**
|
|
6
24
|
* 将 Markdown 内容转换为 HTML(异步版本)
|
|
@@ -11,19 +29,31 @@ export declare const DEFAULT_MARKDOWN_REMARK_PLUGINS: readonly MarkdownRemarkPlu
|
|
|
11
29
|
* - 前置元数据 (Frontmatter)
|
|
12
30
|
* - 特殊字符修复
|
|
13
31
|
* - 原始 HTML 标签
|
|
32
|
+
* - 链接在新标签页打开(可选)
|
|
33
|
+
* - 自定义段落标签(可选)
|
|
34
|
+
* - 代码块流式状态支持
|
|
14
35
|
*
|
|
15
36
|
* @param markdown - 要转换的 Markdown 字符串
|
|
37
|
+
* @param plugins - 可选的 unified 插件配置
|
|
38
|
+
* @param config - 可选的渲染配置选项
|
|
16
39
|
* @returns Promise<string> - 从 Markdown 生成的 HTML 字符串
|
|
17
40
|
*
|
|
18
41
|
* @example
|
|
19
42
|
* ```typescript
|
|
20
43
|
* const html = await markdownToHtml('# 标题\n\n这是**粗体**文本');
|
|
21
44
|
* console.log(html); // '<h1>标题</h1><p>这是<strong>粗体</strong>文本</p>'
|
|
45
|
+
*
|
|
46
|
+
* // 使用配置选项
|
|
47
|
+
* const htmlWithConfig = await markdownToHtml(
|
|
48
|
+
* '[链接](https://example.com)',
|
|
49
|
+
* undefined,
|
|
50
|
+
* { openLinksInNewTab: true, paragraphTag: 'div' }
|
|
51
|
+
* );
|
|
22
52
|
* ```
|
|
23
53
|
*
|
|
24
54
|
* @throws {Error} 当转换过程中发生错误时返回空字符串
|
|
25
55
|
*/
|
|
26
|
-
export declare const markdownToHtml: (markdown: string, plugins?: MarkdownToHtmlOptions) => Promise<string>;
|
|
56
|
+
export declare const markdownToHtml: (markdown: string, plugins?: MarkdownToHtmlOptions, config?: MarkdownToHtmlConfig) => Promise<string>;
|
|
27
57
|
/**
|
|
28
58
|
* 将 Markdown 内容转换为 HTML(同步版本)
|
|
29
59
|
*
|
|
@@ -31,12 +61,21 @@ export declare const markdownToHtml: (markdown: string, plugins?: MarkdownToHtml
|
|
|
31
61
|
* 适用于不需要异步处理的场景,但可能会阻塞主线程。
|
|
32
62
|
*
|
|
33
63
|
* @param markdown - 要转换的 Markdown 字符串
|
|
64
|
+
* @param plugins - 可选的 unified 插件配置
|
|
65
|
+
* @param config - 可选的渲染配置选项
|
|
34
66
|
* @returns string - 从 Markdown 生成的 HTML 字符串
|
|
35
67
|
*
|
|
36
68
|
* @example
|
|
37
69
|
* ```typescript
|
|
38
70
|
* const html = markdownToHtmlSync('## 副标题\n\n- 列表项1\n- 列表项2');
|
|
39
71
|
* console.log(html); // '<h2>副标题</h2><ul><li>列表项1</li><li>列表项2</li></ul>'
|
|
72
|
+
*
|
|
73
|
+
* // 使用配置选项
|
|
74
|
+
* const htmlWithConfig = markdownToHtmlSync(
|
|
75
|
+
* '[链接](https://example.com)',
|
|
76
|
+
* undefined,
|
|
77
|
+
* { openLinksInNewTab: true }
|
|
78
|
+
* );
|
|
40
79
|
* ```
|
|
41
80
|
*
|
|
42
81
|
* @throws {Error} 当转换过程中发生错误时返回空字符串
|
|
@@ -45,4 +84,4 @@ export declare const markdownToHtml: (markdown: string, plugins?: MarkdownToHtml
|
|
|
45
84
|
* - 建议在可能的情况下使用异步版本 `markdownToHtml`
|
|
46
85
|
* - 同步版本可能影响用户界面响应性
|
|
47
86
|
*/
|
|
48
|
-
export declare const markdownToHtmlSync: (markdown: string, plugins?: MarkdownToHtmlOptions) => string;
|
|
87
|
+
export declare const markdownToHtmlSync: (markdown: string, plugins?: MarkdownToHtmlOptions, config?: MarkdownToHtmlConfig) => string;
|