@ai-react-markdown/core 1.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,407 @@
1
+ "use client";
2
+
3
+ // src/index.tsx
4
+ import { useMemo as useMemo3, memo as memo3 } from "react";
5
+
6
+ // src/context.tsx
7
+ import { createContext, useContext, useMemo } from "react";
8
+ import cloneDeep from "lodash/cloneDeep";
9
+ import mergeWith from "lodash/mergeWith";
10
+
11
+ // src/defs.ts
12
+ var AIMarkdownRenderExtraSyntax = /* @__PURE__ */ ((AIMarkdownRenderExtraSyntax2) => {
13
+ AIMarkdownRenderExtraSyntax2["HIGHLIGHT"] = "HIGHLIGHT";
14
+ AIMarkdownRenderExtraSyntax2["DEFINITION_LIST"] = "DEFINITION_LIST";
15
+ AIMarkdownRenderExtraSyntax2["SUBSCRIPT"] = "SUBSCRIPT";
16
+ return AIMarkdownRenderExtraSyntax2;
17
+ })(AIMarkdownRenderExtraSyntax || {});
18
+ var AIMarkdownRenderDisplayOptimizeAbility = /* @__PURE__ */ ((AIMarkdownRenderDisplayOptimizeAbility2) => {
19
+ AIMarkdownRenderDisplayOptimizeAbility2["REMOVE_COMMENTS"] = "REMOVE_COMMENTS";
20
+ AIMarkdownRenderDisplayOptimizeAbility2["SMARTYPANTS"] = "SMARTYPANTS";
21
+ AIMarkdownRenderDisplayOptimizeAbility2["PANGU"] = "PANGU";
22
+ return AIMarkdownRenderDisplayOptimizeAbility2;
23
+ })(AIMarkdownRenderDisplayOptimizeAbility || {});
24
+ var defaultMRMarkdownRenderConfig = {
25
+ extraSyntaxSupported: [
26
+ "HIGHLIGHT" /* HIGHLIGHT */,
27
+ "DEFINITION_LIST" /* DEFINITION_LIST */,
28
+ "SUBSCRIPT" /* SUBSCRIPT */
29
+ ],
30
+ displayOptimizeAbilities: [
31
+ "REMOVE_COMMENTS" /* REMOVE_COMMENTS */,
32
+ "SMARTYPANTS" /* SMARTYPANTS */,
33
+ "PANGU" /* PANGU */
34
+ ]
35
+ };
36
+
37
+ // src/context.tsx
38
+ import { jsx } from "react/jsx-runtime";
39
+ var AIMarkdownRenderStateContext = createContext(null);
40
+ function useAIMarkdownRenderState() {
41
+ const context = useContext(AIMarkdownRenderStateContext);
42
+ if (!context) {
43
+ throw new Error("useAIMarkdownRenderState must be used within an <AIMarkdown /> component.");
44
+ }
45
+ return context;
46
+ }
47
+ var configMergeCustomizer = (_objValue, srcValue, _key, _object, _source, _stack) => {
48
+ if (Array.isArray(srcValue)) {
49
+ return srcValue;
50
+ }
51
+ };
52
+ var AIMarkdownRenderStateProvider = ({
53
+ streaming,
54
+ fontSize,
55
+ config,
56
+ metadata,
57
+ children
58
+ }) => {
59
+ const mergedConfig = useMemo(
60
+ () => config ? mergeWith(cloneDeep(defaultMRMarkdownRenderConfig), config, configMergeCustomizer) : defaultMRMarkdownRenderConfig,
61
+ [config]
62
+ );
63
+ const state = useMemo(
64
+ () => ({
65
+ streaming,
66
+ fontSize,
67
+ config: mergedConfig,
68
+ metadata
69
+ }),
70
+ [streaming, fontSize, mergedConfig, metadata]
71
+ );
72
+ return /* @__PURE__ */ jsx(AIMarkdownRenderStateContext.Provider, { value: state, children });
73
+ };
74
+ var context_default = AIMarkdownRenderStateProvider;
75
+
76
+ // src/preprocessors/latex.ts
77
+ function escapeMhchemCommands(text) {
78
+ return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
79
+ }
80
+ function findCodeBlockRegions(content) {
81
+ const regions = [];
82
+ let inlineStart = -1;
83
+ let multilineStart = -1;
84
+ for (let i = 0; i < content.length; i++) {
85
+ const char = content[i];
86
+ if (char === "`" && i + 2 < content.length && content[i + 1] === "`" && content[i + 2] === "`") {
87
+ if (multilineStart === -1) {
88
+ multilineStart = i;
89
+ i += 2;
90
+ } else {
91
+ regions.push([multilineStart, i + 2]);
92
+ multilineStart = -1;
93
+ i += 2;
94
+ }
95
+ } else if (char === "`" && multilineStart === -1) {
96
+ if (inlineStart === -1) {
97
+ inlineStart = i;
98
+ } else {
99
+ regions.push([inlineStart, i]);
100
+ inlineStart = -1;
101
+ }
102
+ }
103
+ }
104
+ return regions;
105
+ }
106
+ function isInCodeBlock(position, codeRegions) {
107
+ let left = 0;
108
+ let right = codeRegions.length - 1;
109
+ while (left <= right) {
110
+ const mid = Math.floor((left + right) / 2);
111
+ const [start, end] = codeRegions[mid];
112
+ if (position >= start && position <= end) {
113
+ return true;
114
+ } else if (position < start) {
115
+ right = mid - 1;
116
+ } else {
117
+ left = mid + 1;
118
+ }
119
+ }
120
+ return false;
121
+ }
122
+ var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
123
+ var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
124
+ var DELIMITERS_REGEX = /\\\[([\S\s]*?[^\\])\\]|\\\((.*?)\\\)/g;
125
+ var UNESCAPED_PIPES_REGEX = /(?<!\\)\|/g;
126
+ var LATEX_BLOCK_REGEX = /\$\$([\S\s]*?)\$\$|(?<![\\$])\$(?!\$)((?:.|\n)*?)(?<![\\`])\$(?!\$)/g;
127
+ var ESCAPE_TEXT_UNDERSCORES_REGEX = /\\text{([^}]*)}/g;
128
+ var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
129
+ function convertLatexDelimiters(text, codeRegions) {
130
+ return text.replaceAll(
131
+ DELIMITERS_REGEX,
132
+ (match, squareBracket, roundBracket, index) => {
133
+ if (isInCodeBlock(index, codeRegions)) {
134
+ return match;
135
+ }
136
+ if (squareBracket !== void 0) {
137
+ return `$$${squareBracket}$$`;
138
+ } else if (roundBracket !== void 0) {
139
+ return `$${roundBracket}$`;
140
+ }
141
+ return match;
142
+ }
143
+ );
144
+ }
145
+ var replaceUnescapedPipes = (formula) => (
146
+ // Use \vert{} so the control sequence terminates before the next token
147
+ formula.replaceAll(UNESCAPED_PIPES_REGEX, "\\vert{}")
148
+ );
149
+ function escapeLatexPipes(text, codeRegions) {
150
+ return text.replaceAll(LATEX_BLOCK_REGEX, (match, display, inline, index) => {
151
+ if (isInCodeBlock(index, codeRegions)) {
152
+ return match;
153
+ }
154
+ if (display !== void 0) return `$$${replaceUnescapedPipes(display)}$$`;
155
+ if (inline !== void 0) return `$${replaceUnescapedPipes(inline)}$`;
156
+ return match;
157
+ });
158
+ }
159
+ function escapeTextUnderscores(text, codeRegions) {
160
+ return text.replaceAll(ESCAPE_TEXT_UNDERSCORES_REGEX, (match, textContent, index) => {
161
+ if (isInCodeBlock(index, codeRegions)) {
162
+ return match;
163
+ }
164
+ const escapedTextContent = textContent.replaceAll(/(?<!\\)_/g, "\\_");
165
+ return `\\text{${escapedTextContent}}`;
166
+ });
167
+ }
168
+ function preprocessLaTeX(str) {
169
+ if (!str.includes("$") && !str.includes("\\[") && !str.includes("\\(")) return str;
170
+ let processed = str;
171
+ processed = escapeMhchemCommands(processed);
172
+ const codeRegions = findCodeBlockRegions(processed);
173
+ const parts = [];
174
+ let lastIndex = 0;
175
+ const currencyMatchesIterator = processed.matchAll(CURRENCY_REGEX);
176
+ const currencyMatches = Array.from(currencyMatchesIterator);
177
+ for (let i = 0; i < currencyMatches.length; i++) {
178
+ const match = currencyMatches[i];
179
+ parts.push(processed.substring(lastIndex, match.index));
180
+ let needEscape = true;
181
+ if (!isInCodeBlock(match.index, codeRegions)) {
182
+ let restBeforeNextMatchOrEnd = "";
183
+ if (i < currencyMatches.length - 1) {
184
+ const nextMatch = currencyMatches[i + 1];
185
+ if (nextMatch.index - match.index > 1) {
186
+ restBeforeNextMatchOrEnd = processed.substring(match.index + 1, nextMatch.index);
187
+ }
188
+ } else {
189
+ restBeforeNextMatchOrEnd = processed.substring(match.index + 1, processed.length);
190
+ }
191
+ const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
192
+ if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
193
+ const previousNewCotent = parts.join("");
194
+ const previousLastLineContent = previousNewCotent.split(/\r\n|\r|\n/g).pop();
195
+ const wholeLineBeforeNextMatchWithoutCurrentDollar = previousLastLineContent + firstLineBeforeNextMatch;
196
+ if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
197
+ needEscape = false;
198
+ }
199
+ }
200
+ } else {
201
+ needEscape = false;
202
+ }
203
+ parts.push(needEscape ? "\\$" : "$");
204
+ lastIndex = match.index + 1;
205
+ }
206
+ parts.push(processed.substring(lastIndex));
207
+ processed = parts.join("");
208
+ console.log("processed", processed);
209
+ processed = convertLatexDelimiters(processed, codeRegions);
210
+ processed = escapeLatexPipes(processed, codeRegions);
211
+ processed = escapeTextUnderscores(processed, codeRegions);
212
+ const result = [];
213
+ lastIndex = 0;
214
+ const singleDollarMatchesIterator = processed.matchAll(SINGLE_DOLLAR_REGEX);
215
+ for (const match of singleDollarMatchesIterator) {
216
+ if (!isInCodeBlock(match.index, codeRegions)) {
217
+ result.push(processed.substring(lastIndex, match.index));
218
+ result.push(`$$${match[1]}$$`);
219
+ lastIndex = match.index + match[0].length;
220
+ }
221
+ }
222
+ result.push(processed.substring(lastIndex));
223
+ return result.join("");
224
+ }
225
+
226
+ // src/preprocessors/index.ts
227
+ function applyPreprocessors(value, ...fns) {
228
+ return fns.reduce((result, fn) => fn(result), value);
229
+ }
230
+ var defaultExtraPreprocessors = [];
231
+ function preprocessAIMDContent(content, extraPreprocessors = defaultExtraPreprocessors) {
232
+ return applyPreprocessors(content, preprocessLaTeX, ...extraPreprocessors);
233
+ }
234
+
235
+ // src/components/MarkdownContent.tsx
236
+ import { memo, useMemo as useMemo2 } from "react";
237
+ import ReactMarkdown from "react-markdown";
238
+ import rehypeKatex from "rehype-katex";
239
+ import rehypeRaw from "rehype-raw";
240
+ import rehypeUnwrapImages from "rehype-unwrap-images";
241
+ import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
242
+ import remarkBreaks from "remark-breaks";
243
+ import remarkCjkFriendly from "remark-cjk-friendly";
244
+ import remarkCjkFriendlyGfmStrikethrough from "remark-cjk-friendly-gfm-strikethrough";
245
+ import remarkEmoji from "remark-emoji";
246
+ import remarkGfm from "remark-gfm";
247
+ import remarkMath from "remark-math";
248
+ import { remarkDefinitionList, defListHastHandlers } from "remark-definition-list";
249
+ import remarkSupersub from "remark-supersub";
250
+ import { remarkMark as remarkMarkHighlight } from "remark-mark-highlight";
251
+ import remarkSqueezeParagraphs from "remark-squeeze-paragraphs";
252
+ import remarkSmartypants from "remark-smartypants";
253
+ import remarkPangu from "remark-pangu";
254
+ import remarkRemoveComments from "remark-remove-comments";
255
+ import { jsx as jsx2 } from "react/jsx-runtime";
256
+ var DisplayOptimizeRemarkPluginMap = {
257
+ ["REMOVE_COMMENTS" /* REMOVE_COMMENTS */]: remarkRemoveComments,
258
+ ["SMARTYPANTS" /* SMARTYPANTS */]: remarkSmartypants,
259
+ ["PANGU" /* PANGU */]: remarkPangu
260
+ };
261
+ var ExtraSyntaxRemarkPluginMap = {
262
+ ["HIGHLIGHT" /* HIGHLIGHT */]: remarkMarkHighlight,
263
+ ["DEFINITION_LIST" /* DEFINITION_LIST */]: remarkDefinitionList,
264
+ ["SUBSCRIPT" /* SUBSCRIPT */]: remarkSupersub
265
+ };
266
+ var DefaultCustomComponents = {};
267
+ var AIMarkdownContent = memo(({ content, customComponents }) => {
268
+ const { config } = useAIMarkdownRenderState();
269
+ const { extraSyntaxRemarkPlugins, enableDefinitionList } = useMemo2(
270
+ () => ({
271
+ extraSyntaxRemarkPlugins: config.extraSyntaxSupported.map((syntax) => ExtraSyntaxRemarkPluginMap[syntax]),
272
+ enableDefinitionList: config.extraSyntaxSupported.includes("DEFINITION_LIST" /* DEFINITION_LIST */)
273
+ }),
274
+ [config.extraSyntaxSupported]
275
+ );
276
+ const displayOptimizeRemarkPlugins = useMemo2(() => {
277
+ return config.displayOptimizeAbilities.map((ability) => DisplayOptimizeRemarkPluginMap[ability]);
278
+ }, [config.displayOptimizeAbilities]);
279
+ const usedComponents = useMemo2(() => {
280
+ return customComponents ? { ...DefaultCustomComponents, ...customComponents } : DefaultCustomComponents;
281
+ }, [customComponents]);
282
+ return /* @__PURE__ */ jsx2(
283
+ ReactMarkdown,
284
+ {
285
+ remarkPlugins: [
286
+ remarkGfm,
287
+ [
288
+ remarkMath,
289
+ {
290
+ singleDollarTextMath: false
291
+ }
292
+ ],
293
+ ...extraSyntaxRemarkPlugins,
294
+ remarkBreaks,
295
+ remarkEmoji,
296
+ remarkSqueezeParagraphs,
297
+ remarkCjkFriendly,
298
+ remarkCjkFriendlyGfmStrikethrough,
299
+ ...displayOptimizeRemarkPlugins
300
+ ],
301
+ rehypePlugins: [
302
+ [
303
+ rehypeRaw,
304
+ {
305
+ passThrough: []
306
+ }
307
+ ],
308
+ [
309
+ rehypeSanitize,
310
+ {
311
+ ...defaultSchema,
312
+ tagNames: [...defaultSchema.tagNames || [], "mark"],
313
+ attributes: {
314
+ ...defaultSchema.attributes,
315
+ // The `language-*` regex is allowed by default.
316
+ code: [["className", /^language-./, "math-inline", "math-display"]]
317
+ }
318
+ }
319
+ ],
320
+ rehypeKatex,
321
+ rehypeUnwrapImages
322
+ ],
323
+ remarkRehypeOptions: {
324
+ allowDangerousHtml: true,
325
+ handlers: {
326
+ ...enableDefinitionList ? defListHastHandlers : {}
327
+ }
328
+ },
329
+ components: usedComponents,
330
+ children: content
331
+ }
332
+ );
333
+ });
334
+ AIMarkdownContent.displayName = "AIMarkdownContent";
335
+ var MarkdownContent_default = AIMarkdownContent;
336
+
337
+ // src/hooks/useStableValue.ts
338
+ import { useRef, useEffect } from "react";
339
+ import isEqual from "lodash/isEqual";
340
+ function useStableValue(value) {
341
+ const ref = useRef(value);
342
+ const prev = ref.current;
343
+ const stableValue = isEqual(prev, value) ? prev : value;
344
+ useEffect(() => {
345
+ ref.current = stableValue;
346
+ }, [stableValue]);
347
+ return stableValue;
348
+ }
349
+
350
+ // src/components/typography/Default.tsx
351
+ import { memo as memo2 } from "react";
352
+ import { jsx as jsx3 } from "react/jsx-runtime";
353
+ var DefaultTypography = memo2(({ children, fontSize, variant, colorScheme }) => /* @__PURE__ */ jsx3(
354
+ "div",
355
+ {
356
+ className: `aim-typography-root ${variant ?? ""} ${colorScheme ?? ""}`.trim(),
357
+ style: { width: "100%", fontSize },
358
+ children
359
+ }
360
+ ));
361
+ DefaultTypography.displayName = "DefaultTypography";
362
+ var Default_default = DefaultTypography;
363
+
364
+ // src/index.tsx
365
+ import { jsx as jsx4 } from "react/jsx-runtime";
366
+ var AIMarkdownComponent = ({
367
+ streaming = false,
368
+ content,
369
+ fontSize,
370
+ contentPreprocessors,
371
+ customComponents,
372
+ config,
373
+ metadata,
374
+ typography: Typography = Default_default,
375
+ extraStyle: ExtraStyle,
376
+ variant = "default",
377
+ colorScheme = "light"
378
+ }) => {
379
+ const usedFontSize = fontSize ? typeof fontSize === "number" ? `${fontSize}px` : fontSize : "0.875rem";
380
+ const stableConfig = useStableValue(config);
381
+ const stablePreprocessors = useStableValue(contentPreprocessors);
382
+ const stableCustomComponents = useStableValue(customComponents);
383
+ const usedContent = useMemo3(
384
+ () => content ? preprocessAIMDContent(content, stablePreprocessors) : content,
385
+ [content, stablePreprocessors]
386
+ );
387
+ return /* @__PURE__ */ jsx4(
388
+ context_default,
389
+ {
390
+ streaming,
391
+ fontSize: usedFontSize,
392
+ config: stableConfig,
393
+ metadata,
394
+ children: /* @__PURE__ */ jsx4(Typography, { fontSize: usedFontSize, variant, colorScheme, children: ExtraStyle ? /* @__PURE__ */ jsx4(ExtraStyle, { children: /* @__PURE__ */ jsx4(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) }) : /* @__PURE__ */ jsx4(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) })
395
+ }
396
+ );
397
+ };
398
+ var AIMarkdown = memo3(AIMarkdownComponent);
399
+ AIMarkdown.displayName = "AIMarkdown";
400
+ var index_default = AIMarkdown;
401
+ export {
402
+ AIMarkdownRenderDisplayOptimizeAbility,
403
+ AIMarkdownRenderExtraSyntax,
404
+ index_default as default,
405
+ useAIMarkdownRenderState
406
+ };
407
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx","../src/context.tsx","../src/defs.ts","../src/preprocessors/latex.ts","../src/preprocessors/index.ts","../src/components/MarkdownContent.tsx","../src/hooks/useStableValue.ts","../src/components/typography/Default.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo, memo } from 'react';\nimport AIMarkdownRenderStateProvider, { AIMarkdownRenderStateProviderProps } from './context';\nimport { AIMDContentPreprocessor } from './preprocessors/defs';\nimport preprocessAIMDContent from './preprocessors';\nimport AIMarkdownContent from './components/MarkdownContent';\nimport { Components } from 'react-markdown';\nimport {\n AIMarkdownRenderConfig,\n AIMarkdownMetadata,\n AIMarkdownTypographyComponent,\n AIMarkdownExtraStyleComponent,\n AIMarkdownVariant,\n AIMarkdownColorScheme,\n} from './defs';\nimport useStableValue from './hooks/useStableValue';\nimport DefaultTypography from './components/typography/Default';\n\nexport interface AIMarkdownProps<\n TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig,\n TRenderData extends AIMarkdownMetadata = AIMarkdownMetadata,\n> extends Omit<AIMarkdownRenderStateProviderProps<TConfig, TRenderData>, 'fontSize'> {\n fontSize?: number | string;\n content: string;\n contentPreprocessors?: AIMDContentPreprocessor[];\n customComponents?: Components;\n typography?: AIMarkdownTypographyComponent;\n extraStyle?: AIMarkdownExtraStyleComponent;\n variant?: AIMarkdownVariant;\n colorScheme?: AIMarkdownColorScheme;\n}\n\nconst AIMarkdownComponent = <\n TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig,\n TRenderData extends AIMarkdownMetadata = AIMarkdownMetadata,\n>({\n streaming = false,\n content,\n fontSize,\n contentPreprocessors,\n customComponents,\n config,\n metadata,\n typography: Typography = DefaultTypography,\n extraStyle: ExtraStyle,\n variant = 'default',\n colorScheme = 'light',\n}: AIMarkdownProps<TConfig, TRenderData>) => {\n const usedFontSize = fontSize ? (typeof fontSize === 'number' ? `${fontSize}px` : fontSize) : '0.875rem';\n\n const stableConfig = useStableValue(config);\n const stablePreprocessors = useStableValue(contentPreprocessors);\n const stableCustomComponents = useStableValue(customComponents);\n\n const usedContent = useMemo(\n () => (content ? preprocessAIMDContent(content, stablePreprocessors) : content),\n [content, stablePreprocessors]\n );\n\n return (\n <AIMarkdownRenderStateProvider<TConfig, TRenderData>\n streaming={streaming}\n fontSize={usedFontSize}\n config={stableConfig}\n metadata={metadata}\n >\n <Typography fontSize={usedFontSize} variant={variant} colorScheme={colorScheme}>\n {ExtraStyle ? (\n <ExtraStyle>\n <AIMarkdownContent content={usedContent} customComponents={stableCustomComponents} />\n </ExtraStyle>\n ) : (\n <AIMarkdownContent content={usedContent} customComponents={stableCustomComponents} />\n )}\n </Typography>\n </AIMarkdownRenderStateProvider>\n );\n};\n\nconst AIMarkdown = memo(AIMarkdownComponent);\nAIMarkdown.displayName = 'AIMarkdown';\n\nexport default AIMarkdown as typeof AIMarkdownComponent;\n\n// Types\nexport type { AIMDContentPreprocessor };\nexport type {\n AIMarkdownRenderConfig,\n AIMarkdownRenderState,\n AIMarkdownMetadata,\n AIMarkdownTypographyProps,\n AIMarkdownTypographyComponent,\n AIMarkdownExtraStyleProps,\n AIMarkdownExtraStyleComponent,\n AIMarkdownVariant,\n AIMarkdownColorScheme,\n} from './defs';\n\n// Enums\nexport { AIMarkdownRenderExtraSyntax, AIMarkdownRenderDisplayOptimizeAbility } from './defs';\n\n// Hook — for custom components to access render state\nexport { useAIMarkdownRenderState } from './context';\n","import { PropsWithChildren, createContext, useContext, useMemo } from 'react';\nimport cloneDeep from 'lodash/cloneDeep';\nimport mergeWith from 'lodash/mergeWith';\nimport {\n AIMarkdownRenderConfig,\n AIMarkdownMetadata,\n AIMarkdownRenderState,\n defaultMRMarkdownRenderConfig,\n} from './defs';\nimport { DeepPartial } from './utils/ts-util';\n\nconst AIMarkdownRenderStateContext = createContext<AIMarkdownRenderState<\n AIMarkdownRenderConfig,\n AIMarkdownMetadata\n> | null>(null);\n\nexport function useAIMarkdownRenderState<\n TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig,\n TMetadata extends AIMarkdownMetadata = AIMarkdownMetadata,\n>() {\n const context = useContext(AIMarkdownRenderStateContext) as AIMarkdownRenderState<TConfig, TMetadata>;\n\n if (!context) {\n throw new Error('useAIMarkdownRenderState must be used within an <AIMarkdown /> component.');\n }\n\n return context;\n}\n\nexport interface AIMarkdownRenderStateProviderProps<\n TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig,\n TMetadata extends AIMarkdownMetadata = AIMarkdownMetadata,\n> extends PropsWithChildren {\n streaming: boolean;\n fontSize: string;\n config?: DeepPartial<TConfig>;\n metadata?: TMetadata;\n}\n\n/**\n * When merging config, arrays from the source (user config) should fully replace\n * the target (default config) instead of being merged by index.\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst configMergeCustomizer = (\n _objValue: any,\n srcValue: any,\n _key: string,\n _object: any,\n _source: any,\n _stack: any\n) => {\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst AIMarkdownRenderStateProvider = <\n RCT extends AIMarkdownRenderConfig = AIMarkdownRenderConfig,\n RDT extends AIMarkdownMetadata = AIMarkdownMetadata,\n>({\n streaming,\n fontSize,\n config,\n metadata,\n children,\n}: AIMarkdownRenderStateProviderProps<RCT, RDT>) => {\n const mergedConfig = useMemo(\n () =>\n config\n ? mergeWith(cloneDeep(defaultMRMarkdownRenderConfig), config, configMergeCustomizer)\n : defaultMRMarkdownRenderConfig,\n [config]\n );\n\n const state = useMemo(\n () => ({\n streaming,\n fontSize,\n config: mergedConfig,\n metadata,\n }),\n [streaming, fontSize, mergedConfig, metadata]\n );\n\n return <AIMarkdownRenderStateContext.Provider value={state}>{children}</AIMarkdownRenderStateContext.Provider>;\n};\n\nexport default AIMarkdownRenderStateProvider;\n","import { ComponentType, PropsWithChildren } from 'react';\n\nexport enum AIMarkdownRenderExtraSyntax {\n HIGHLIGHT = 'HIGHLIGHT', // support ==Highlight==\n DEFINITION_LIST = 'DEFINITION_LIST', // support Definition List https://michelf.ca/projects/php-markdown/extra/#def-list\n SUBSCRIPT = 'SUBSCRIPT', // support superscript and subscript\n}\n\nexport enum AIMarkdownRenderDisplayOptimizeAbility {\n REMOVE_COMMENTS = 'REMOVE_COMMENTS', // remove comments\n SMARTYPANTS = 'SMARTYPANTS', // make conent more typographic by SmartyPants https://www.npmjs.com/package/smartypants\n PANGU = 'PANGU', // auto add space between CJK and English\n}\n\nexport interface AIMarkdownRenderConfig {\n extraSyntaxSupported: AIMarkdownRenderExtraSyntax[];\n displayOptimizeAbilities: AIMarkdownRenderDisplayOptimizeAbility[];\n}\n\nexport const defaultMRMarkdownRenderConfig: AIMarkdownRenderConfig = {\n extraSyntaxSupported: [\n AIMarkdownRenderExtraSyntax.HIGHLIGHT,\n AIMarkdownRenderExtraSyntax.DEFINITION_LIST,\n AIMarkdownRenderExtraSyntax.SUBSCRIPT,\n ],\n displayOptimizeAbilities: [\n AIMarkdownRenderDisplayOptimizeAbility.REMOVE_COMMENTS,\n AIMarkdownRenderDisplayOptimizeAbility.SMARTYPANTS,\n AIMarkdownRenderDisplayOptimizeAbility.PANGU,\n ],\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface AIMarkdownMetadata extends Record<string, any> {}\n\nexport type AIMarkdownVariant = 'default' | (string & {});\nexport type AIMarkdownColorScheme = 'light' | 'dark' | (string & {});\n\nexport interface AIMarkdownTypographyProps extends PropsWithChildren {\n fontSize: string;\n variant?: AIMarkdownVariant;\n colorScheme?: AIMarkdownColorScheme;\n}\nexport type AIMarkdownTypographyComponent = ComponentType<AIMarkdownTypographyProps>;\n\nexport interface AIMarkdownExtraStyleProps extends PropsWithChildren {}\nexport type AIMarkdownExtraStyleComponent = ComponentType<AIMarkdownExtraStyleProps>;\n\nexport interface AIMarkdownRenderState<\n TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig,\n TMetadata extends AIMarkdownMetadata = AIMarkdownMetadata,\n> {\n streaming: boolean;\n fontSize: string;\n config: TConfig;\n metadata?: TMetadata;\n}\n","/**\n * LaTeX preprocess functions\n * Thanks the implementations from the following repositories:\n * - https://github.com/lobehub/lobe-ui/blob/master/src/hooks/useMarkdown/latex.ts\n * - https://github.com/danny-avila/LibreChat/blob/main/client/src/utils/latex.ts\n */\n\n/**\n * Escape mhchem commands in LaTeX expressions to ensure proper rendering.\n *\n * @param text Input string containing LaTeX expressions with mhchem commands\n * @returns String with escaped mhchem commands\n * @from https://github.com/lobehub/lobe-ui/blob/master/src/hooks/useMarkdown/latex.ts\n */\nfunction escapeMhchemCommands(text: string) {\n return text.replaceAll('$\\\\ce{', '$\\\\\\\\ce{').replaceAll('$\\\\pu{', '$\\\\\\\\pu{');\n}\n\n/**\n * Efficiently finds all code block regions in the content\n * @param content The content to analyze\n * @returns Array of code block regions [start, end]\n * @from https://github.com/danny-avila/LibreChat/blob/main/client/src/utils/latex.ts\n */\nfunction findCodeBlockRegions(content: string): Array<[number, number]> {\n const regions: Array<[number, number]> = [];\n let inlineStart = -1;\n let multilineStart = -1;\n\n for (let i = 0; i < content.length; i++) {\n const char = content[i];\n\n // Check for multiline code blocks\n if (char === '`' && i + 2 < content.length && content[i + 1] === '`' && content[i + 2] === '`') {\n if (multilineStart === -1) {\n multilineStart = i;\n i += 2; // Skip the next two backticks\n } else {\n regions.push([multilineStart, i + 2]);\n multilineStart = -1;\n i += 2;\n }\n }\n // Check for inline code blocks (only if not in multiline)\n else if (char === '`' && multilineStart === -1) {\n if (inlineStart === -1) {\n inlineStart = i;\n } else {\n regions.push([inlineStart, i]);\n inlineStart = -1;\n }\n }\n }\n\n return regions;\n}\n\n/**\n * Checks if a position is inside any code block region using binary search\n * @param position The position to check\n * @param codeRegions Array of code block regions\n * @returns True if position is inside a code block\n * @from https://github.com/danny-avila/LibreChat/blob/main/client/src/utils/latex.ts\n */\nfunction isInCodeBlock(position: number, codeRegions: Array<[number, number]>): boolean {\n let left = 0;\n let right = codeRegions.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const [start, end] = codeRegions[mid];\n\n if (position >= start && position <= end) {\n return true;\n } else if (position < start) {\n right = mid - 1;\n } else {\n left = mid + 1;\n }\n }\n\n return false;\n}\n\nconst CURRENCY_REGEX = /(?<![\\\\$])\\$(?!\\$)(?=\\d+(?:,\\d{3})*(?:\\.\\d+)?(?:[KMBkmb])?(?:\\s|$|[^a-zA-Z\\d]))/g;\nconst NO_ESCAPED_DOLLAR_REGEX = /(?<![\\\\$])\\$(?!\\$)/g;\nconst DELIMITERS_REGEX = /\\\\\\[([\\S\\s]*?[^\\\\])\\\\]|\\\\\\((.*?)\\\\\\)/g;\nconst UNESCAPED_PIPES_REGEX = /(?<!\\\\)\\|/g;\nconst LATEX_BLOCK_REGEX = /\\$\\$([\\S\\s]*?)\\$\\$|(?<![\\\\$])\\$(?!\\$)((?:.|\\n)*?)(?<![\\\\`])\\$(?!\\$)/g;\nconst ESCAPE_TEXT_UNDERSCORES_REGEX = /\\\\text{([^}]*)}/g;\nconst SINGLE_DOLLAR_REGEX = /(?<![\\\\$])\\$(?!\\$)((?:[^$\\n]|\\\\[$])+?)(?<!\\\\)(?<!`)\\$(?!\\$)/g;\n\n/**\n * Convert LaTeX bracket delimiters to dollar sign delimiters.\n * Converts \\[...\\] to $$...$$ and \\(...\\) to $...$\n * Preserves code blocks during conversion.\n *\n * @param text Input string containing LaTeX expressions\n * @returns String with LaTeX bracket delimiters converted to dollar sign delimiters\n * @modified from https://github.com/lobehub/lobe-ui/blob/master/src/hooks/useMarkdown/latex.ts\n */\nfunction convertLatexDelimiters(text: string, codeRegions: Array<[number, number]>): string {\n return text.replaceAll(\n DELIMITERS_REGEX,\n (match: string, squareBracket: string | undefined, roundBracket: string | undefined, index: number): string => {\n if (isInCodeBlock(index, codeRegions)) {\n return match;\n }\n if (squareBracket !== undefined) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket !== undefined) {\n return `$${roundBracket}$`;\n }\n return match;\n }\n );\n}\n\n/**\n * Helper function: replace unescaped pipes with \\vert in LaTeX math fragments\n * @from https://github.com/lobehub/lobe-ui/blob/master/src/hooks/useMarkdown/latex.ts\n */\nconst replaceUnescapedPipes = (formula: string): string =>\n // Use \\vert{} so the control sequence terminates before the next token\n formula.replaceAll(UNESCAPED_PIPES_REGEX, '\\\\vert{}');\n/**\n * Escape pipes in LaTeX expressions to prevent them from being interpreted as\n * column separators in markdown tables.\n *\n * @param text Input string containing LaTeX expressions\n * @returns String with pipes escaped in LaTeX expressions\n * @modified from https://github.com/lobehub/lobe-ui/blob/master/src/hooks/useMarkdown/latex.ts\n */\nfunction escapeLatexPipes(text: string, codeRegions: Array<[number, number]>): string {\n // Replace unescaped '|' with '\\vert' within LaTeX math ranges so that\n // remark-gfm table parsing doesn't treat them as column separators.\n // Keep code blocks/inline code unchanged.\n return text.replaceAll(LATEX_BLOCK_REGEX, (match, display, inline, index) => {\n if (isInCodeBlock(index, codeRegions)) {\n return match;\n }\n if (display !== undefined) return `$$${replaceUnescapedPipes(display)}$$`;\n if (inline !== undefined) return `$${replaceUnescapedPipes(inline)}$`;\n return match;\n });\n}\n\n/**\n * Escape unescaped underscores within \\text{...} commands in LaTeX expressions.\n * For example, \\text{node_domain} becomes \\text{node\\_domain},\n * but \\text{node\\_domain} remains \\text{node\\_domain}.\n *\n * @param text Input string that may contain LaTeX expressions\n * @returns String with unescaped underscores escaped within \\text{...} commands\n * @modified from https://github.com/lobehub/lobe-ui/blob/master/src/hooks/useMarkdown/latex.ts\n */\nfunction escapeTextUnderscores(text: string, codeRegions: Array<[number, number]>): string {\n return text.replaceAll(ESCAPE_TEXT_UNDERSCORES_REGEX, (match, textContent: string, index: number) => {\n if (isInCodeBlock(index, codeRegions)) {\n return match;\n }\n // textContent is the content within the braces, e.g., \"node_domain\" or \"already\\_escaped\"\n // Replace '_' with '\\_' only when the underscore '_' is not preceded by a backslash '\\'.\n // (?<!\\\\) is a negative lookbehind assertion that ensures the character before '_' is not '\\'.\n const escapedTextContent = textContent.replaceAll(/(?<!\\\\)_/g, '\\\\_');\n return `\\\\text{${escapedTextContent}}`;\n });\n}\n\nexport function preprocessLaTeX(str: string): string {\n // Step 0: return early if no LaTeX patterns are found\n if (!str.includes('$') && !str.includes('\\\\[') && !str.includes('\\\\(')) return str;\n\n let processed = str;\n\n // Step 1: escape mhchem commands\n processed = escapeMhchemCommands(processed);\n\n // Step 2: find code block regions\n const codeRegions = findCodeBlockRegions(processed);\n\n // Step 3: escape currency dollar signs\n const parts = [];\n let lastIndex = 0;\n const currencyMatchesIterator = processed.matchAll(CURRENCY_REGEX);\n const currencyMatches = Array.from(currencyMatchesIterator);\n for (let i = 0; i < currencyMatches.length; i++) {\n const match = currencyMatches[i];\n parts.push(processed.substring(lastIndex, match.index));\n let needEscape = true;\n if (!isInCodeBlock(match.index, codeRegions)) {\n let restBeforeNextMatchOrEnd = '';\n if (i < currencyMatches.length - 1) {\n const nextMatch = currencyMatches[i + 1];\n if (nextMatch.index - match.index > 1) {\n restBeforeNextMatchOrEnd = processed.substring(match.index + 1, nextMatch.index);\n }\n } else {\n restBeforeNextMatchOrEnd = processed.substring(match.index + 1, processed.length);\n }\n const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\\r\\n|\\r|\\n/g)[0];\n if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {\n const previousNewCotent = parts.join('');\n const previousLastLineContent = previousNewCotent.split(/\\r\\n|\\r|\\n/g).pop();\n const wholeLineBeforeNextMatchWithoutCurrentDollar = previousLastLineContent + firstLineBeforeNextMatch;\n if (\n Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !==\n 0\n ) {\n needEscape = false;\n }\n }\n } else {\n needEscape = false;\n }\n parts.push(needEscape ? '\\\\$' : '$');\n lastIndex = match.index + 1;\n }\n parts.push(processed.substring(lastIndex));\n processed = parts.join('');\n console.log('processed', processed);\n\n // Step 4: convert LaTeX delimiters\n processed = convertLatexDelimiters(processed, codeRegions);\n\n // Step 5: escape LaTeX pipes\n processed = escapeLatexPipes(processed, codeRegions);\n\n // Step 6: escape text underscores\n processed = escapeTextUnderscores(processed, codeRegions);\n\n // Step 7: convert single dollar delimiters to double dollars\n const result: string[] = [];\n lastIndex = 0;\n const singleDollarMatchesIterator = processed.matchAll(SINGLE_DOLLAR_REGEX);\n for (const match of singleDollarMatchesIterator) {\n if (!isInCodeBlock(match.index, codeRegions)) {\n result.push(processed.substring(lastIndex, match.index));\n result.push(`$$${match[1]}$$`);\n lastIndex = match.index + match[0].length;\n }\n }\n result.push(processed.substring(lastIndex));\n\n return result.join('');\n}\n","import { AIMDContentPreprocessor } from './defs';\nimport { preprocessLaTeX } from './latex';\n\nfunction applyPreprocessors(value: string, ...fns: Array<AIMDContentPreprocessor>): string {\n return fns.reduce((result, fn) => fn(result), value);\n}\n\nconst defaultExtraPreprocessors: AIMDContentPreprocessor[] = [];\n\nexport default function preprocessAIMDContent(\n content: string,\n extraPreprocessors: AIMDContentPreprocessor[] = defaultExtraPreprocessors\n) {\n return applyPreprocessors(content, preprocessLaTeX, ...extraPreprocessors);\n}\n","import { memo, useMemo } from 'react';\nimport ReactMarkdown, { Components } from 'react-markdown';\nimport rehypeKatex from 'rehype-katex';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeUnwrapImages from 'rehype-unwrap-images';\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize';\nimport remarkBreaks from 'remark-breaks';\nimport remarkCjkFriendly from 'remark-cjk-friendly';\nimport remarkCjkFriendlyGfmStrikethrough from 'remark-cjk-friendly-gfm-strikethrough';\nimport remarkEmoji from 'remark-emoji';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport { remarkDefinitionList, defListHastHandlers } from 'remark-definition-list';\nimport remarkSupersub from 'remark-supersub';\nimport { remarkMark as remarkMarkHighlight } from 'remark-mark-highlight';\nimport remarkSqueezeParagraphs from 'remark-squeeze-paragraphs';\nimport remarkSmartypants from 'remark-smartypants';\nimport remarkPangu from 'remark-pangu';\nimport remarkRemoveComments from 'remark-remove-comments';\nimport { useAIMarkdownRenderState } from '../context';\nimport { AIMarkdownRenderDisplayOptimizeAbility, AIMarkdownRenderExtraSyntax } from '../defs';\n\nconst DisplayOptimizeRemarkPluginMap = {\n [AIMarkdownRenderDisplayOptimizeAbility.REMOVE_COMMENTS]: remarkRemoveComments,\n [AIMarkdownRenderDisplayOptimizeAbility.SMARTYPANTS]: remarkSmartypants,\n [AIMarkdownRenderDisplayOptimizeAbility.PANGU]: remarkPangu,\n};\n\nconst ExtraSyntaxRemarkPluginMap = {\n [AIMarkdownRenderExtraSyntax.HIGHLIGHT]: remarkMarkHighlight,\n [AIMarkdownRenderExtraSyntax.DEFINITION_LIST]: remarkDefinitionList,\n [AIMarkdownRenderExtraSyntax.SUBSCRIPT]: remarkSupersub,\n};\n\nconst DefaultCustomComponents: Components = {};\n\ninterface AIMarkdownContentProps {\n content: string;\n customComponents?: Components;\n}\n\nconst AIMarkdownContent = memo(({ content, customComponents }: AIMarkdownContentProps) => {\n const { config } = useAIMarkdownRenderState();\n\n const { extraSyntaxRemarkPlugins, enableDefinitionList } = useMemo(\n () => ({\n extraSyntaxRemarkPlugins: config.extraSyntaxSupported.map((syntax) => ExtraSyntaxRemarkPluginMap[syntax]),\n enableDefinitionList: config.extraSyntaxSupported.includes(AIMarkdownRenderExtraSyntax.DEFINITION_LIST),\n }),\n [config.extraSyntaxSupported]\n );\n\n const displayOptimizeRemarkPlugins = useMemo(() => {\n return config.displayOptimizeAbilities.map((ability) => DisplayOptimizeRemarkPluginMap[ability]);\n }, [config.displayOptimizeAbilities]);\n\n const usedComponents = useMemo(() => {\n return customComponents ? { ...DefaultCustomComponents, ...customComponents } : DefaultCustomComponents;\n }, [customComponents]);\n\n return (\n <ReactMarkdown\n remarkPlugins={[\n remarkGfm,\n [\n remarkMath,\n {\n singleDollarTextMath: false,\n },\n ],\n ...extraSyntaxRemarkPlugins,\n remarkBreaks,\n remarkEmoji,\n remarkSqueezeParagraphs,\n remarkCjkFriendly,\n remarkCjkFriendlyGfmStrikethrough,\n ...displayOptimizeRemarkPlugins,\n ]}\n rehypePlugins={[\n [\n rehypeRaw,\n {\n passThrough: [],\n },\n ],\n [\n rehypeSanitize,\n {\n ...defaultSchema,\n tagNames: [...(defaultSchema.tagNames || []), 'mark'],\n attributes: {\n ...defaultSchema.attributes,\n // The `language-*` regex is allowed by default.\n code: [['className', /^language-./, 'math-inline', 'math-display']],\n },\n },\n ],\n rehypeKatex,\n rehypeUnwrapImages,\n ]}\n remarkRehypeOptions={{\n allowDangerousHtml: true,\n handlers: {\n ...(enableDefinitionList ? defListHastHandlers : {}),\n },\n }}\n components={usedComponents}\n // By default, the defaultUrlTransform function in Windows environments treats local paths, such as those starting with C:/, as unsafe and replaces them with an empty string. Hence, in this case, it simply returns the URL that it has identified without any modification.\n // urlTransform={(url: string) => url}\n >\n {content}\n </ReactMarkdown>\n );\n});\n\nAIMarkdownContent.displayName = 'AIMarkdownContent';\n\nexport default AIMarkdownContent;\n","import { useRef, useEffect } from 'react';\nimport isEqual from 'lodash/isEqual';\n\nexport default function useStableValue<T>(value: T): T {\n const ref = useRef(value);\n\n // eslint-disable-next-line react-hooks/refs\n const prev = ref.current;\n const stableValue = isEqual(prev, value) ? prev : value;\n\n useEffect(() => {\n ref.current = stableValue;\n }, [stableValue]);\n\n return stableValue;\n}\n","import { memo } from 'react';\nimport type { AIMarkdownTypographyProps } from '../../defs';\n\nconst DefaultTypography = memo(({ children, fontSize, variant, colorScheme }: AIMarkdownTypographyProps) => (\n <div\n className={`aim-typography-root ${variant ?? ''} ${colorScheme ?? ''}`.trim()}\n style={{ width: '100%', fontSize }}\n >\n {children}\n </div>\n));\n\nDefaultTypography.displayName = 'DefaultTypography';\n\nexport default DefaultTypography;\n"],"mappings":"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","names":["useMemo","memo","AIMarkdownRenderExtraSyntax","AIMarkdownRenderDisplayOptimizeAbility","useMemo","jsx","useMemo","memo","jsx","jsx","useMemo","memo"]}