From 372b19a0571fcbb6e6883368be8de2273ef6e3ba Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Mon, 22 Apr 2024 04:39:12 -0700 Subject: [PATCH] Formulas: fix rendering for OpenAI-style inline '\(' and block '\[' latex. Fixes #508 --- package-lock.json | 253 ++++++++++++++++++ package.json | 2 + src/modules/blocks/BlocksRenderer.tsx | 13 +- src/modules/blocks/RenderLatex.tsx | 28 -- src/modules/blocks/blocks.ts | 15 +- .../markdown/CustomMarkdownRenderer.tsx | 35 ++- .../blocks/markdown/RenderMarkdown.tsx | 4 +- 7 files changed, 289 insertions(+), 61 deletions(-) delete mode 100644 src/modules/blocks/RenderLatex.tsx diff --git a/package-lock.json b/package-lock.json index 2fde45553..7198dc3ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,9 @@ "react-player": "^2.16.0", "react-resizable-panels": "^2.0.18", "react-timeago": "^7.2.0", + "rehype-katex": "^7.0.0", "remark-gfm": "^4.0.0", + "remark-math": "^6.0.0", "sharp": "^0.33.3", "superjson": "^2.2.1", "tesseract.js": "^5.0.5", @@ -1795,6 +1797,11 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" + }, "node_modules/@types/mdast": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", @@ -3134,6 +3141,17 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4289,6 +4307,95 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", + "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^8.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", + "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", @@ -4315,6 +4422,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -4327,6 +4449,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -5310,6 +5448,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", @@ -5627,6 +5783,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.0.0.tgz", + "integrity": "sha512-iJ2Q28vBoEovLN5o3GO12CpqorQRYDPT+p4zW50tGwTfJB+iv/VnB6Ini+gqa24K97DwptMBBIvVX6Bjk49oyQ==", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", @@ -6467,6 +6641,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6964,6 +7149,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/rehype-katex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz", + "integrity": "sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", @@ -6981,6 +7184,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -8062,6 +8280,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -8223,6 +8454,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", @@ -8241,6 +8485,15 @@ "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.6.1.tgz", "integrity": "sha512-R1i9ED8UlLu/foILNB1ck9XS63vdtqU/tP1MCugVekETp/ySCrBZRk5I/zI67cI1wlQYeSonNm1PLjDHZDNg6g==" }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index c1bf3d045..60f129f57 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,9 @@ "react-player": "^2.16.0", "react-resizable-panels": "^2.0.18", "react-timeago": "^7.2.0", + "rehype-katex": "^7.0.0", "remark-gfm": "^4.0.0", + "remark-math": "^6.0.0", "sharp": "^0.33.3", "superjson": "^2.2.1", "tesseract.js": "^5.0.5", diff --git a/src/modules/blocks/BlocksRenderer.tsx b/src/modules/blocks/BlocksRenderer.tsx index ed02bdd93..5f64c146f 100644 --- a/src/modules/blocks/BlocksRenderer.tsx +++ b/src/modules/blocks/BlocksRenderer.tsx @@ -14,7 +14,6 @@ import { InlineError } from '~/common/components/InlineError'; import { RenderCode, RenderCodeMemo } from './code/RenderCode'; import { RenderHtml } from './RenderHtml'; import { RenderImage } from './RenderImage'; -import { RenderLatex } from './RenderLatex'; import { RenderMarkdown, RenderMarkdownMemo } from './markdown/RenderMarkdown'; import { RenderChatText } from './RenderChatText'; import { RenderTextDiff } from './RenderTextDiff'; @@ -210,13 +209,11 @@ export const BlocksRenderer = React.forwardRef : block.type === 'image' ? - : block.type === 'latex' - ? - : block.type === 'diff' - ? - : (props.renderTextAsMarkdown && !fromSystem && !(fromUser && block.content.startsWith('/'))) - ? - : ; + : block.type === 'diff' + ? + : (props.renderTextAsMarkdown && !fromSystem && !(fromUser && block.content.startsWith('/'))) + ? + : ; }) )} diff --git a/src/modules/blocks/RenderLatex.tsx b/src/modules/blocks/RenderLatex.tsx deleted file mode 100644 index a751ae9d6..000000000 --- a/src/modules/blocks/RenderLatex.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; - -import { Box } from '@mui/joy'; -import { SxProps } from '@mui/joy/styles/types'; - -import type { LatexBlock } from './blocks'; - - -// Dynamically import the Katex functions -const RenderLatexDynamic = React.lazy(async () => { - const { InlineMath } = await import('react-katex'); - return { - default: (props: { latex: string }) => , - }; -}); - -export const RenderLatex = (props: { latexBlock: LatexBlock; sx?: SxProps; }) => - - }> - - - ; \ No newline at end of file diff --git a/src/modules/blocks/blocks.ts b/src/modules/blocks/blocks.ts index a5f47b4f9..d97c5ab10 100644 --- a/src/modules/blocks/blocks.ts +++ b/src/modules/blocks/blocks.ts @@ -4,12 +4,11 @@ import { heuristicIsHtml } from './RenderHtml'; import { heuristicLegacyImageBlocks, heuristicMarkdownImageReferenceBlocks } from './RenderImage'; // Block types -export type Block = CodeBlock | DiffBlock | HtmlBlock | ImageBlock | LatexBlock | TextBlock; +export type Block = CodeBlock | DiffBlock | HtmlBlock | ImageBlock | TextBlock; export type CodeBlock = { type: 'code'; blockTitle: string; blockCode: string; complete: boolean; }; export type DiffBlock = { type: 'diff'; textDiffs: TextDiff[] }; export type HtmlBlock = { type: 'html'; html: string; }; export type ImageBlock = { type: 'image'; url: string; alt?: string }; // Added optional alt property -export type LatexBlock = { type: 'latex'; latex: string; }; export type TextBlock = { type: 'text'; content: string; }; // for Text or Markdown @@ -26,8 +25,6 @@ export function areBlocksEqual(a: Block, b: Block): boolean { return a.html === (b as HtmlBlock).html; case 'image': return a.url === (b as ImageBlock).url && a.alt === (b as ImageBlock).alt; - case 'latex': - return a.latex === (b as LatexBlock).latex; case 'text': return a.content === (b as TextBlock).content; } @@ -59,9 +56,6 @@ export function parseMessageBlocks(text: string, disableParsing: boolean, forceT codeBlock: /`{3,}([\w\x20\\.+-_]+)?\n([\s\S]*?)(`{3,}\n?|$)/g, htmlCodeBlock: /([\s\S]*?)<\/html>/g, svgBlock: //g, - latexBlock: /\$\$([\s\S]*?)\$\$\n?/g, - latexBlock2: /\\\[\n([\s\S]*?)\n\s*\\]\n/g, - // latexBlockOrInline: /\$\$([\s\S]*?)\$\$|\$([^$]*?)\$/g, }; const blocks: Block[] = []; @@ -97,18 +91,11 @@ export function parseMessageBlocks(text: string, disableParsing: boolean, forceT blocks.push({ type: 'code', blockTitle, blockCode, complete: blockEnd.startsWith('```') }); break; - case 'htmlCodeBlock': const html: string = `${match[1]}`; blocks.push({ type: 'code', blockTitle: 'html', blockCode: html, complete: true }); break; - case 'latexBlock': - case 'latexBlock2': - const latex: string = match[1]; - blocks.push({ type: 'latex', latex }); - break; - case 'svgBlock': blocks.push({ type: 'code', blockTitle: 'svg', blockCode: match[0], complete: true }); break; diff --git a/src/modules/blocks/markdown/CustomMarkdownRenderer.tsx b/src/modules/blocks/markdown/CustomMarkdownRenderer.tsx index 27a52ae2a..82de11b8b 100644 --- a/src/modules/blocks/markdown/CustomMarkdownRenderer.tsx +++ b/src/modules/blocks/markdown/CustomMarkdownRenderer.tsx @@ -2,7 +2,9 @@ import * as React from 'react'; import { CSVLink } from 'react-csv'; import { default as ReactMarkdown } from 'react-markdown'; +import { default as rehypeKatex } from 'rehype-katex'; import { default as remarkGfm } from 'remark-gfm'; +import { default as remarkMath } from 'remark-math'; import { Button } from '@mui/joy'; import DownloadIcon from '@mui/icons-material/Download'; @@ -98,16 +100,33 @@ const LinkRenderer = ({ children, node, ...props }: LinkRendererProps) => ( const reactMarkdownComponents = { a: LinkRenderer, // override the link renderer to add target="_blank" table: TableRenderer, // override the table renderer to show the download CSV links + // math/inlineMath components are not needed, rehype-katex handles this automatically }; -// Custom plugins: GFM (GitHub Flavored Markdown) +/* + * Convert OpenAI-style markdown with LaTeX to 'remark-math' compatible format. + * Note that inline or block will both be converted to $$...$$ format, and we + * disable on purpose the single dollar sign for inline math, as it can clash + * with other markdown syntax. + */ +const preprocessMarkdown = (markdownText: string) => markdownText + .replace(/\s\\\((.*?)\\\)/gs, (_match, p1) => ` $$${p1}$$`) // Replace inline LaTeX delimiters \( and \) with $$ + .replace(/\s\\\[(.*?)\\]/gs, (_match, p1) => ` $$${p1}$$`); // Replace block LaTeX delimiters \[ and \] with $$ -const remarkPlugins = [ - remarkGfm, -]; - - -export default function CustomMarkdownRenderer(props: any) { - return ; +export default function CustomMarkdownRenderer(props: { content: string }) { + return ( + + {preprocessMarkdown(props.content)} + + ); } \ No newline at end of file diff --git a/src/modules/blocks/markdown/RenderMarkdown.tsx b/src/modules/blocks/markdown/RenderMarkdown.tsx index 211cd4b62..9125a3521 100644 --- a/src/modules/blocks/markdown/RenderMarkdown.tsx +++ b/src/modules/blocks/markdown/RenderMarkdown.tsx @@ -32,9 +32,7 @@ export function RenderMarkdown(props: { textBlock: TextBlock; sx?: SxProps; }) { sx={props.sx} > Loading...}> - - {props.textBlock.content} - + );