|
|
@@ -8,8 +8,9 @@ import { CodeBlock } from './CodeBlock.tsx'
|
|
|
import 'katex/dist/katex.min.css'
|
|
|
import css from './MarkdownText.module.css'
|
|
|
|
|
|
-const remarkPlugins = [remarkGfm, remarkMath]
|
|
|
-const rehypePlugins = [rehypeKatex]
|
|
|
+const streamingRemarkPlugins = [remarkGfm]
|
|
|
+const settledRemarkPlugins = [remarkGfm, remarkMath]
|
|
|
+const settledRehypePlugins = [rehypeKatex]
|
|
|
|
|
|
function sanitizeUrl(url: string): string {
|
|
|
try {
|
|
|
@@ -92,7 +93,7 @@ const streamingComponents = buildComponents(true)
|
|
|
/**
|
|
|
* Render untrusted assistant-authored Markdown as semantic React elements.
|
|
|
* @param props - Markdown source text preserved by the session projection;
|
|
|
- * `streaming` renders fences plain (highlighting lands on the finalize swap);
|
|
|
+ * `streaming` renders fences and TeX plain (highlighting and KaTeX land on the finalize swap);
|
|
|
* `codeLabels` forwards localized copy-button labels to fence CodeBlocks —
|
|
|
* pass a reference-stable object (memoized per locale revision), because the
|
|
|
* component table memoizes on its identity and a fresh literal per render
|
|
|
@@ -113,8 +114,8 @@ export function MarkdownText({ text, streaming = false, codeLabels }: {
|
|
|
return (
|
|
|
<div className={css.markdown}>
|
|
|
<ReactMarkdown
|
|
|
- remarkPlugins={remarkPlugins}
|
|
|
- rehypePlugins={rehypePlugins}
|
|
|
+ remarkPlugins={streaming ? streamingRemarkPlugins : settledRemarkPlugins}
|
|
|
+ rehypePlugins={streaming ? undefined : settledRehypePlugins}
|
|
|
components={components}
|
|
|
urlTransform={safeUrl}
|
|
|
>
|