@lobehub/ui 2.0.16 → 2.1.0

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.
@@ -4,7 +4,6 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
4
4
  function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
5
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
6
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
- import katex from 'katex';
8
7
  import rehypeKatex from 'rehype-katex';
9
8
  import rehypeRaw from 'rehype-raw';
10
9
  import remarkBreaks from 'remark-breaks';
@@ -13,22 +12,42 @@ import remarkMath from 'remark-math';
13
12
  import { animatedPlugin } from "../../Markdown/plugins/animated";
14
13
  import { rehypeFootnoteLinks, remarkCustomFootnotes } from "../../Markdown/plugins/footnote";
15
14
  import { rehypeKatexDir } from "../../Markdown/plugins/katexDir";
15
+ import { preprocessLaTeX } from "./latex";
16
16
 
17
- // 使用普通 Map 代替 WeakMap,并限制缓存大小
17
+ // Cache configuration
18
18
  var CACHE_SIZE = 50;
19
+
20
+ /**
21
+ * Cache for storing processed content to avoid redundant processing
22
+ */
19
23
  export var contentCache = new Map();
20
24
 
21
- // 添加内容到缓存时,保持缓存大小不超过限制
25
+ /**
26
+ * Adds content to the cache with size limitation
27
+ * Removes oldest entry if cache size limit is reached
28
+ *
29
+ * @param key The cache key
30
+ * @param value The processed content to store
31
+ */
22
32
  export var addToCache = function addToCache(key, value) {
23
33
  if (contentCache.size >= CACHE_SIZE) {
24
- // 移除最早加入的缓存项
34
+ // Remove the oldest cache entry
25
35
  var firstKey = contentCache.keys().next().value;
26
36
  if (firstKey) contentCache.delete(firstKey);
27
37
  }
28
38
  contentCache.set(key, value);
29
39
  };
30
40
 
31
- // 使用工厂函数处理插件,减少组件中的逻辑负担
41
+ /**
42
+ * Plugin configuration options for markdown processing
43
+ */
44
+
45
+ /**
46
+ * Creates remark and rehype plugin lists based on configuration options
47
+ *
48
+ * @param props Plugin configuration options
49
+ * @returns Object containing remark and rehype plugin lists
50
+ */
32
51
  export var createPlugins = function createPlugins(props) {
33
52
  var allowHtml = props.allowHtml,
34
53
  enableLatex = props.enableLatex,
@@ -39,68 +58,68 @@ export var createPlugins = function createPlugins(props) {
39
58
  remarkPluginsAhead = props.remarkPluginsAhead,
40
59
  animated = props.animated;
41
60
 
42
- // 预处理插件数组
61
+ // Normalize plugin arrays
43
62
  var normalizedRehypePlugins = Array.isArray(rehypePlugins) ? rehypePlugins : rehypePlugins ? [rehypePlugins] : [];
44
63
  var normalizedRemarkPlugins = Array.isArray(remarkPlugins) ? remarkPlugins : remarkPlugins ? [remarkPlugins] : [];
45
64
  var normalizedRemarkPluginsAhead = Array.isArray(remarkPluginsAhead) ? remarkPluginsAhead : remarkPluginsAhead ? [remarkPluginsAhead] : [];
46
65
 
47
- // 创建 rehype 插件列表
66
+ // Create rehype plugins list
48
67
  var rehypePluginsList = [allowHtml && rehypeRaw, enableLatex && rehypeKatex, enableLatex && rehypeKatexDir, enableCustomFootnotes && rehypeFootnoteLinks, animated && animatedPlugin].concat(_toConsumableArray(normalizedRehypePlugins)).filter(Boolean);
49
68
 
50
- // 创建 remark 插件列表
51
- var remarkPluginsList = [].concat(_toConsumableArray(normalizedRemarkPluginsAhead), [[remarkGfm, {
69
+ // Create remark plugins list
70
+ var remarkPluginsList = [].concat(_toConsumableArray(normalizedRemarkPluginsAhead), [enableLatex && remarkMath, [remarkGfm, {
52
71
  singleTilde: false
53
- }], enableCustomFootnotes && remarkCustomFootnotes, enableLatex && remarkMath, isChatMode && remarkBreaks], _toConsumableArray(normalizedRemarkPlugins)).filter(Boolean);
72
+ }], enableCustomFootnotes && remarkCustomFootnotes, isChatMode && remarkBreaks], _toConsumableArray(normalizedRemarkPlugins)).filter(Boolean);
54
73
  return {
55
74
  rehypePluginsList: rehypePluginsList,
56
75
  remarkPluginsList: remarkPluginsList
57
76
  };
58
77
  };
59
- export function escapeBrackets(text) {
60
- var pattern = /(```[\S\s]*?```|`.*?`)|\\\[([\S\s]*?[^\\])\\]|\\\((.*?)\\\)/g;
61
- return text.replaceAll(pattern, function (match, codeBlock, squareBracket, roundBracket) {
62
- if (codeBlock) {
63
- return codeBlock;
64
- } else if (squareBracket) {
65
- return "$$".concat(squareBracket, "$$");
66
- } else if (roundBracket) {
67
- return "$".concat(roundBracket, "$");
68
- }
69
- return match;
70
- });
71
- }
72
- export function escapeMhchem(text) {
73
- return text.replaceAll('$\\ce{', '$\\\\ce{').replaceAll('$\\pu{', '$\\\\pu{');
74
- }
78
+
79
+ /**
80
+ * Fixes markdown bold syntax by adding space after closing bold markers
81
+ * when followed by non-space characters after symbols
82
+ *
83
+ * @param text The markdown text to process
84
+ * @returns The text with fixed bold syntax
85
+ */
75
86
  export function fixMarkdownBold(text) {
76
- var count = 0;
77
- var count2 = 0;
87
+ var asteriskCount = 0;
88
+ var boldMarkerCount = 0;
78
89
  var result = '';
79
90
  var inCodeBlock = false;
80
91
  var inInlineCode = false;
81
92
  for (var i = 0; i < text.length; i++) {
82
93
  var char = text[i];
94
+
95
+ // Handle code blocks
83
96
  if (text.slice(i, i + 3) === '```') {
84
97
  inCodeBlock = !inCodeBlock;
85
98
  result += '```';
86
99
  i += 2;
87
100
  continue;
88
101
  }
102
+
103
+ // Handle inline code
89
104
  if (char === '`') {
90
105
  inInlineCode = !inInlineCode;
91
106
  result += '`';
92
107
  continue;
93
108
  }
109
+
110
+ // Process asterisks only if not in code
94
111
  if (char === '*' && !inInlineCode && !inCodeBlock) {
95
- count++;
96
- if (count === 2) {
97
- count2++;
112
+ asteriskCount++;
113
+ if (asteriskCount === 2) {
114
+ boldMarkerCount++;
98
115
  }
99
- if (count > 2) {
116
+ if (asteriskCount > 2) {
100
117
  result += char;
101
118
  continue;
102
119
  }
103
- if (count === 2 && count2 % 2 === 0) {
120
+
121
+ // Add space after closing bold marker if needed
122
+ if (asteriskCount === 2 && boldMarkerCount % 2 === 0) {
104
123
  var prevChar = i > 0 ? text[i - 2] : '';
105
124
  var isPrevCharSymbol = /(?:[!-\/:-@\[-`\{-~\xA1-\xA9\xAB\xAC\xAE-\xB1\xB4\xB6-\xB8\xBB\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u037E\u0384\u0385\u0387\u03F6\u0482\u055A-\u055F\u0589\u058A\u058D-\u058F\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0606-\u060F\u061B\u061D-\u061F\u066A-\u066D\u06D4\u06DE\u06E9\u06FD\u06FE\u0700-\u070D\u07F6-\u07F9\u07FE\u07FF\u0830-\u083E\u085E\u0888\u0964\u0965\u0970\u09F2\u09F3\u09FA\u09FB\u09FD\u0A76\u0AF0\u0AF1\u0B70\u0BF3-\u0BFA\u0C77\u0C7F\u0C84\u0D4F\u0D79\u0DF4\u0E3F\u0E4F\u0E5A\u0E5B\u0F01-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F85\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE-\u0FDA\u104A-\u104F\u109E\u109F\u10FB\u1360-\u1368\u1390-\u1399\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DB\u1800-\u180A\u1940\u1944\u1945\u19DE-\u19FF\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B6A\u1B74-\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2010-\u2027\u2030-\u205E\u207A-\u207E\u208A-\u208E\u20A0-\u20C0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2775\u2794-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E5D\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3001-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u303F\u309B\u309C\u30A0\u30FB\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAA77-\uAA79\uAADE\uAADF\uAAF0\uAAF1\uAB5B\uAB6A\uAB6B\uABEB\uFB29\uFBB2-\uFBC2\uFD3E-\uFD4F\uFDCF\uFDFC-\uFDFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD00-\uDD02\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDC77\uDC78\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEC8\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3F]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFD5-\uDFF1\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3F\uDF44\uDF45]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F[\uDC9C\uDC9F]|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE8B]|\uD838[\uDD4F\uDEFF]|\uD83A[\uDD5E\uDD5F]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF76\uDF7B-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC5\uDECE-\uDEDB\uDEE0-\uDEE8\uDEF0-\uDEF8\uDF00-\uDF92\uDF94-\uDFCA])/.test(prevChar);
106
125
  result += i + 1 < text.length && text[i + 1] !== ' ' && isPrevCharSymbol ? '* ' : '*';
@@ -109,58 +128,130 @@ export function fixMarkdownBold(text) {
109
128
  }
110
129
  } else {
111
130
  result += char;
112
- count = 0;
131
+ asteriskCount = 0;
113
132
  }
114
133
  }
115
134
  return result;
116
135
  }
136
+
137
+ /**
138
+ * Transforms citation references in the format [n] to markdown links
139
+ *
140
+ * @param rawContent The markdown content with citation references
141
+ * @param length The number of citations
142
+ * @returns The content with citations transformed to markdown links
143
+ */
117
144
  export var transformCitations = function transformCitations(rawContent) {
118
145
  var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
119
146
  if (length === 0) return rawContent;
120
147
 
121
- // 生成动态正则表达式模式
122
- var idx = Array.from({
148
+ // 生成引用索引
149
+ var citationIndices = Array.from({
123
150
  length: length
124
151
  }).fill('').map(function (_, index) {
125
152
  return index + 1;
126
153
  });
127
- var pattern = new RegExp("\\[(".concat(idx.join('|'), ")\\]"), 'g');
128
- return rawContent.replaceAll(pattern, function (match, id) {
129
- return "[#citation-".concat(id, "](citation-").concat(id, ")");
130
- }).replaceAll('][', '] [');
131
- };
132
154
 
133
- // 新增: 检测LaTeX公式是否可渲染
134
- var extractFormulas = function extractFormulas(text) {
135
- // 计算$$的数量
136
- var dollarsCount = (text.match(/\$\$/g) || []).length;
155
+ // 匹配所有潜在的引用
156
+ var pattern = new RegExp("\\[(".concat(citationIndices.join('|'), ")\\]"), 'g');
157
+ var matches = [];
158
+ var match;
159
+ while ((match = pattern.exec(rawContent)) !== null) {
160
+ matches.push({
161
+ id: match[1],
162
+ index: match.index,
163
+ length: match[0].length
164
+ });
165
+ }
166
+
167
+ // 识别所有需要排除的区域
168
+ var excludedRanges = [];
169
+
170
+ // 查找LaTeX块 $$...$$
171
+ var latexBlockRegex = /\$\$([\S\s]*?)\$\$/g;
172
+ while ((match = latexBlockRegex.exec(rawContent)) !== null) {
173
+ excludedRanges.push({
174
+ end: match.index + match[0].length - 1,
175
+ start: match.index
176
+ });
177
+ }
178
+
179
+ // 查找行内LaTeX $...$
180
+ var inlineLatexRegex = /\$([^$]*?)\$/g;
181
+ while ((match = inlineLatexRegex.exec(rawContent)) !== null) {
182
+ excludedRanges.push({
183
+ end: match.index + match[0].length - 1,
184
+ start: match.index
185
+ });
186
+ }
137
187
 
138
- // 奇数个$$时,获取最后一个$$后的内容
139
- if (dollarsCount % 2 === 1) {
140
- var match = text.match(/\$\$([^]*)$/);
141
- return match ? match[1] : '';
188
+ // 查找代码块 ```...```
189
+ var codeBlockRegex = /```([\S\s]*?)```/g;
190
+ while ((match = codeBlockRegex.exec(rawContent)) !== null) {
191
+ excludedRanges.push({
192
+ end: match.index + match[0].length - 1,
193
+ start: match.index
194
+ });
195
+ }
196
+
197
+ // 查找行内代码 `...`
198
+ var inlineCodeRegex = /`([^`]*?)`/g;
199
+ while ((match = inlineCodeRegex.exec(rawContent)) !== null) {
200
+ excludedRanges.push({
201
+ end: match.index + match[0].length - 1,
202
+ start: match.index
203
+ });
142
204
  }
143
205
 
144
- // 偶数个$$时,返回空字符串
145
- return '';
206
+ // 过滤掉在排除区域内的引用
207
+ var validMatches = matches.filter(function (citation) {
208
+ return !excludedRanges.some(function (range) {
209
+ return citation.index >= range.start && citation.index <= range.end;
210
+ });
211
+ });
212
+
213
+ // 从后向前替换,避免索引变化问题
214
+ var result = rawContent;
215
+ for (var i = validMatches.length - 1; i >= 0; i--) {
216
+ var citation = validMatches[i];
217
+ var before = result.slice(0, Math.max(0, citation.index));
218
+ var after = result.slice(Math.max(0, citation.index + citation.length));
219
+ result = before + "[#citation-".concat(citation.id, "](citation-").concat(citation.id, ")") + after;
220
+ }
221
+
222
+ // 处理连续引用
223
+ return result.replaceAll('][', '] [');
146
224
  };
147
225
 
148
- // 只检查最后一个公式
149
- export var areFormulasRenderable = function areFormulasRenderable(text) {
150
- var formulas = extractFormulas(text);
226
+ /**
227
+ * Preprocessing options for markdown content
228
+ */
151
229
 
152
- // 如果没有公式,返回true
153
- if (!formulas) return true;
230
+ /**
231
+ * Preprocesses markdown content by applying various transformations:
232
+ * - LaTeX preprocessing
233
+ * - Citation transformations
234
+ * - Bold syntax fixing
235
+ *
236
+ * @param str The raw markdown content
237
+ * @param options Preprocessing options
238
+ * @returns The processed markdown content
239
+ */
240
+ export var preprocessContent = function preprocessContent(str) {
241
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
242
+ enableCustomFootnotes = _ref.enableCustomFootnotes,
243
+ enableLatex = _ref.enableLatex,
244
+ citationsLength = _ref.citationsLength;
245
+ var content = str;
154
246
 
155
- // 仅检查最后一个公式是否可渲染
156
- try {
157
- katex.renderToString(formulas, {
158
- displayMode: true,
159
- throwOnError: true
160
- });
161
- return true;
162
- } catch (error) {
163
- console.log("LaTeX\u516C\u5F0F\u6E32\u67D3\u9519\u8BEF: ".concat(error));
164
- return false;
247
+ // Process LaTeX expressions
248
+ if (enableLatex) {
249
+ content = preprocessLaTeX(content);
250
+ }
251
+
252
+ // Process custom footnotes/citations
253
+ if (enableCustomFootnotes) {
254
+ content = transformCitations(content, citationsLength);
165
255
  }
256
+ return fixMarkdownBold(content);
166
257
  };
@@ -33,7 +33,7 @@ import Alert from "../../Alert";
33
33
  import { PreviewGroup } from "../../Image";
34
34
  import { Typography } from "../../Markdown";
35
35
  import { useStyles } from "../../Markdown/style";
36
- import { escapeBrackets, escapeMhchem, fixMarkdownBold } from "../../Markdown/utils";
36
+ import { preprocessContent } from "../../hooks/useMarkdown/utils";
37
37
  import mdxComponents from "../mdxComponents";
38
38
  import CodeBlock from "../mdxComponents/CodeBlock";
39
39
  import Image from "../mdxComponents/Image";
@@ -82,8 +82,9 @@ var Mdx = /*#__PURE__*/memo(function (_ref) {
82
82
  MDXContent = _useState2[0],
83
83
  setMDXContent = _useState2[1];
84
84
  var escapedContent = useMemo(function () {
85
- if (!enableLatex) return fixMarkdownBold(children);
86
- return fixMarkdownBold(escapeMhchem(escapeBrackets(children)));
85
+ return preprocessContent(children, {
86
+ enableLatex: enableLatex
87
+ });
87
88
  }, [children, enableLatex]);
88
89
  var innerRehypePlugins = Array.isArray(rehypePlugins) ? rehypePlugins : [rehypePlugins];
89
90
  var memoRehypePlugins = useMemo(function () {
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
 
3
3
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
- var _excluded = ["fullFeatured", "fileName", "allowChangeLanguage", "language", "children", "className", "style", "variant", "icon"],
4
+ var _excluded = ["fullFeatured", "fileName", "allowChangeLanguage", "language", "children", "className", "style", "variant", "icon", "theme"],
5
5
  _excluded2 = ["language", "children", "className", "style", "variant"],
6
- _excluded3 = ["fullFeatured", "children", "className", "style", "variant"];
6
+ _excluded3 = ["fullFeatured", "children", "className", "style", "variant", "theme"];
7
7
  var _templateObject;
8
8
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
9
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -37,6 +37,7 @@ export var Pre = function Pre(_ref2) {
37
37
  _ref2$variant = _ref2.variant,
38
38
  variant = _ref2$variant === void 0 ? 'filled' : _ref2$variant,
39
39
  icon = _ref2.icon,
40
+ theme = _ref2.theme,
40
41
  rest = _objectWithoutProperties(_ref2, _excluded);
41
42
  var _useStyles = useStyles(),
42
43
  styles = _useStyles.styles,
@@ -49,6 +50,7 @@ export var Pre = function Pre(_ref2) {
49
50
  icon: icon,
50
51
  language: language,
51
52
  style: style,
53
+ theme: theme,
52
54
  variant: variant
53
55
  }, rest), {}, {
54
56
  children: children
@@ -83,6 +85,7 @@ export var PreMermaid = function PreMermaid(_ref4) {
83
85
  style = _ref4.style,
84
86
  _ref4$variant = _ref4.variant,
85
87
  variant = _ref4$variant === void 0 ? 'filled' : _ref4$variant,
88
+ theme = _ref4.theme,
86
89
  rest = _objectWithoutProperties(_ref4, _excluded3);
87
90
  var _useStyles3 = useStyles(),
88
91
  styles = _useStyles3.styles,
@@ -91,6 +94,7 @@ export var PreMermaid = function PreMermaid(_ref4) {
91
94
  className: cx(styles.container, className),
92
95
  fullFeatured: fullFeatured,
93
96
  style: style,
97
+ theme: theme,
94
98
  variant: variant
95
99
  }, rest), {}, {
96
100
  children: children
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/ui",
3
- "version": "2.0.16",
3
+ "version": "2.1.0",
4
4
  "description": "Lobe UI is an open-source UI component library for building AIGC web apps",
5
5
  "keywords": [
6
6
  "lobehub",
@@ -69,7 +69,6 @@
69
69
  "emoji-mart": "^5.6.0",
70
70
  "fast-deep-equal": "^3.1.3",
71
71
  "framer-motion": "^12.6.3",
72
- "hast": "^1.0.0",
73
72
  "immer": "^10.1.1",
74
73
  "katex": "^0.16.9",
75
74
  "leva": "^0.10.0",
@@ -86,10 +85,10 @@
86
85
  "re-resizable": "^6.11.2",
87
86
  "react-avatar-editor": "^13.0.2",
88
87
  "react-error-boundary": "^5.0.0",
89
- "react-hotkeys-hook": "^4.6.1",
88
+ "react-hotkeys-hook": "^5.1.0",
90
89
  "react-layout-kit": "^1.9.1",
91
90
  "react-markdown": "^10.1.0",
92
- "react-merge-refs": "^2.1.1",
91
+ "react-merge-refs": "^3.0.2",
93
92
  "react-rnd": "^10.5.2",
94
93
  "react-zoom-pan-pinch": "^3.7.0",
95
94
  "rehype-katex": "^7.0.1",
@@ -1,21 +0,0 @@
1
- import type { Pluggable } from 'unified';
2
- export declare const contentCache: Map<string, string>;
3
- export declare const addToCache: (key: string, value: string) => void;
4
- export declare const createPlugins: (props: {
5
- allowHtml?: boolean;
6
- animated?: boolean;
7
- enableCustomFootnotes?: boolean;
8
- enableLatex?: boolean;
9
- isChatMode: boolean;
10
- rehypePlugins?: Pluggable | Pluggable[];
11
- remarkPlugins?: Pluggable | Pluggable[];
12
- remarkPluginsAhead?: Pluggable | Pluggable[];
13
- }) => {
14
- rehypePluginsList: Pluggable[];
15
- remarkPluginsList: Pluggable[];
16
- };
17
- export declare function escapeBrackets(text: string): string;
18
- export declare function escapeMhchem(text: string): string;
19
- export declare function fixMarkdownBold(text: string): string;
20
- export declare const transformCitations: (rawContent: string, length?: number) => string;
21
- export declare const areFormulasRenderable: (text: string) => boolean;
@@ -1,166 +0,0 @@
1
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
- import katex from 'katex';
8
- import rehypeKatex from 'rehype-katex';
9
- import rehypeRaw from 'rehype-raw';
10
- import remarkBreaks from 'remark-breaks';
11
- import remarkGfm from 'remark-gfm';
12
- import remarkMath from 'remark-math';
13
- import { animatedPlugin } from "./plugins/animated";
14
- import { rehypeFootnoteLinks, remarkCustomFootnotes } from "./plugins/footnote";
15
- import { rehypeKatexDir } from "./plugins/katexDir";
16
-
17
- // 使用普通 Map 代替 WeakMap,并限制缓存大小
18
- var CACHE_SIZE = 50;
19
- export var contentCache = new Map();
20
-
21
- // 添加内容到缓存时,保持缓存大小不超过限制
22
- export var addToCache = function addToCache(key, value) {
23
- if (contentCache.size >= CACHE_SIZE) {
24
- // 移除最早加入的缓存项
25
- var firstKey = contentCache.keys().next().value;
26
- if (firstKey) contentCache.delete(firstKey);
27
- }
28
- contentCache.set(key, value);
29
- };
30
-
31
- // 使用工厂函数处理插件,减少组件中的逻辑负担
32
- export var createPlugins = function createPlugins(props) {
33
- var allowHtml = props.allowHtml,
34
- enableLatex = props.enableLatex,
35
- enableCustomFootnotes = props.enableCustomFootnotes,
36
- isChatMode = props.isChatMode,
37
- rehypePlugins = props.rehypePlugins,
38
- remarkPlugins = props.remarkPlugins,
39
- remarkPluginsAhead = props.remarkPluginsAhead,
40
- animated = props.animated;
41
-
42
- // 预处理插件数组
43
- var normalizedRehypePlugins = Array.isArray(rehypePlugins) ? rehypePlugins : rehypePlugins ? [rehypePlugins] : [];
44
- var normalizedRemarkPlugins = Array.isArray(remarkPlugins) ? remarkPlugins : remarkPlugins ? [remarkPlugins] : [];
45
- var normalizedRemarkPluginsAhead = Array.isArray(remarkPluginsAhead) ? remarkPluginsAhead : remarkPluginsAhead ? [remarkPluginsAhead] : [];
46
-
47
- // 创建 rehype 插件列表
48
- var rehypePluginsList = [allowHtml && rehypeRaw, enableLatex && rehypeKatex, enableLatex && rehypeKatexDir, enableCustomFootnotes && rehypeFootnoteLinks, animated && animatedPlugin].concat(_toConsumableArray(normalizedRehypePlugins)).filter(Boolean);
49
-
50
- // 创建 remark 插件列表
51
- var remarkPluginsList = [].concat(_toConsumableArray(normalizedRemarkPluginsAhead), [[remarkGfm, {
52
- singleTilde: false
53
- }], enableCustomFootnotes && remarkCustomFootnotes, enableLatex && remarkMath, isChatMode && remarkBreaks], _toConsumableArray(normalizedRemarkPlugins)).filter(Boolean);
54
- return {
55
- rehypePluginsList: rehypePluginsList,
56
- remarkPluginsList: remarkPluginsList
57
- };
58
- };
59
- export function escapeBrackets(text) {
60
- var pattern = /(```[\S\s]*?```|`.*?`)|\\\[([\S\s]*?[^\\])\\]|\\\((.*?)\\\)/g;
61
- return text.replaceAll(pattern, function (match, codeBlock, squareBracket, roundBracket) {
62
- if (codeBlock) {
63
- return codeBlock;
64
- } else if (squareBracket) {
65
- return "$$".concat(squareBracket, "$$");
66
- } else if (roundBracket) {
67
- return "$".concat(roundBracket, "$");
68
- }
69
- return match;
70
- });
71
- }
72
- export function escapeMhchem(text) {
73
- return text.replaceAll('$\\ce{', '$\\\\ce{').replaceAll('$\\pu{', '$\\\\pu{');
74
- }
75
- export function fixMarkdownBold(text) {
76
- var count = 0;
77
- var count2 = 0;
78
- var result = '';
79
- var inCodeBlock = false;
80
- var inInlineCode = false;
81
- for (var i = 0; i < text.length; i++) {
82
- var char = text[i];
83
- if (text.slice(i, i + 3) === '```') {
84
- inCodeBlock = !inCodeBlock;
85
- result += '```';
86
- i += 2;
87
- continue;
88
- }
89
- if (char === '`') {
90
- inInlineCode = !inInlineCode;
91
- result += '`';
92
- continue;
93
- }
94
- if (char === '*' && !inInlineCode && !inCodeBlock) {
95
- count++;
96
- if (count === 2) {
97
- count2++;
98
- }
99
- if (count > 2) {
100
- result += char;
101
- continue;
102
- }
103
- if (count === 2 && count2 % 2 === 0) {
104
- var prevChar = i > 0 ? text[i - 2] : '';
105
- var isPrevCharSymbol = /(?:[!-\/:-@\[-`\{-~\xA1-\xA9\xAB\xAC\xAE-\xB1\xB4\xB6-\xB8\xBB\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u037E\u0384\u0385\u0387\u03F6\u0482\u055A-\u055F\u0589\u058A\u058D-\u058F\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0606-\u060F\u061B\u061D-\u061F\u066A-\u066D\u06D4\u06DE\u06E9\u06FD\u06FE\u0700-\u070D\u07F6-\u07F9\u07FE\u07FF\u0830-\u083E\u085E\u0888\u0964\u0965\u0970\u09F2\u09F3\u09FA\u09FB\u09FD\u0A76\u0AF0\u0AF1\u0B70\u0BF3-\u0BFA\u0C77\u0C7F\u0C84\u0D4F\u0D79\u0DF4\u0E3F\u0E4F\u0E5A\u0E5B\u0F01-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F85\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE-\u0FDA\u104A-\u104F\u109E\u109F\u10FB\u1360-\u1368\u1390-\u1399\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DB\u1800-\u180A\u1940\u1944\u1945\u19DE-\u19FF\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B6A\u1B74-\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2010-\u2027\u2030-\u205E\u207A-\u207E\u208A-\u208E\u20A0-\u20C0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2775\u2794-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E5D\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3001-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u303F\u309B\u309C\u30A0\u30FB\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAA77-\uAA79\uAADE\uAADF\uAAF0\uAAF1\uAB5B\uAB6A\uAB6B\uABEB\uFB29\uFBB2-\uFBC2\uFD3E-\uFD4F\uFDCF\uFDFC-\uFDFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD00-\uDD02\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDC77\uDC78\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEC8\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3F]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFD5-\uDFF1\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3F\uDF44\uDF45]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F[\uDC9C\uDC9F]|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE8B]|\uD838[\uDD4F\uDEFF]|\uD83A[\uDD5E\uDD5F]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF76\uDF7B-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC5\uDECE-\uDEDB\uDEE0-\uDEE8\uDEF0-\uDEF8\uDF00-\uDF92\uDF94-\uDFCA])/.test(prevChar);
106
- result += i + 1 < text.length && text[i + 1] !== ' ' && isPrevCharSymbol ? '* ' : '*';
107
- } else {
108
- result += '*';
109
- }
110
- } else {
111
- result += char;
112
- count = 0;
113
- }
114
- }
115
- return result;
116
- }
117
- export var transformCitations = function transformCitations(rawContent) {
118
- var length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
119
- if (length === 0) return rawContent;
120
-
121
- // 生成动态正则表达式模式
122
- var idx = Array.from({
123
- length: length
124
- }).fill('').map(function (_, index) {
125
- return index + 1;
126
- });
127
- var pattern = new RegExp("\\[(".concat(idx.join('|'), ")\\]"), 'g');
128
- return rawContent.replaceAll(pattern, function (match, id) {
129
- return "[#citation-".concat(id, "](citation-").concat(id, ")");
130
- }).replaceAll('][', '] [');
131
- };
132
-
133
- // 新增: 检测LaTeX公式是否可渲染
134
- var extractFormulas = function extractFormulas(text) {
135
- // 计算$$的数量
136
- var dollarsCount = (text.match(/\$\$/g) || []).length;
137
-
138
- // 奇数个$$时,获取最后一个$$后的内容
139
- if (dollarsCount % 2 === 1) {
140
- var match = text.match(/\$\$([^]*)$/);
141
- return match ? match[1] : '';
142
- }
143
-
144
- // 偶数个$$时,返回空字符串
145
- return '';
146
- };
147
-
148
- // 只检查最后一个公式
149
- export var areFormulasRenderable = function areFormulasRenderable(text) {
150
- var formulas = extractFormulas(text);
151
-
152
- // 如果没有公式,返回true
153
- if (!formulas) return true;
154
-
155
- // 仅检查最后一个公式是否可渲染
156
- try {
157
- katex.renderToString(formulas, {
158
- displayMode: true,
159
- throwOnError: true
160
- });
161
- return true;
162
- } catch (error) {
163
- console.log("LaTeX\u516C\u5F0F\u6E32\u67D3\u9519\u8BEF: ".concat(error));
164
- return false;
165
- }
166
- };