mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Formulas: fix rendering for OpenAI-style inline '\(' and block '\[' latex. Fixes #508
This commit is contained in:
Generated
+253
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<HTMLDivElement, BlocksRendererPro
|
||||
? <RenderCodeMemoOrNot key={'code-' + index} codeBlock={block} fitScreen={props.fitScreen} initialShowHTML={props.showUnsafeHtml} noCopyButton={props.specialDiagramMode} optimizeLightweight={!optimizeWithMemo} sx={scaledCodeSx} />
|
||||
: block.type === 'image'
|
||||
? <RenderImage key={'image-' + index} imageBlock={block} onRunAgain={props.isBottom ? props.onImageRegenerate : undefined} sx={scaledImageSx} />
|
||||
: block.type === 'latex'
|
||||
? <RenderLatex key={'latex-' + index} latexBlock={block} sx={scaledTypographySx} />
|
||||
: block.type === 'diff'
|
||||
? <RenderTextDiff key={'latex-' + index} diffBlock={block} sx={scaledTypographySx} />
|
||||
: (props.renderTextAsMarkdown && !fromSystem && !(fromUser && block.content.startsWith('/')))
|
||||
? <RenderMarkdownMemoOrNot key={'text-md-' + index} textBlock={block} sx={scaledTypographySx} />
|
||||
: <RenderChatText key={'text-' + index} textBlock={block} sx={scaledTypographySx} />;
|
||||
: block.type === 'diff'
|
||||
? <RenderTextDiff key={'text-diff-' + index} diffBlock={block} sx={scaledTypographySx} />
|
||||
: (props.renderTextAsMarkdown && !fromSystem && !(fromUser && block.content.startsWith('/')))
|
||||
? <RenderMarkdownMemoOrNot key={'text-md-' + index} textBlock={block} sx={scaledTypographySx} />
|
||||
: <RenderChatText key={'text-' + index} textBlock={block} sx={scaledTypographySx} />;
|
||||
})
|
||||
|
||||
)}
|
||||
|
||||
@@ -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 }) => <InlineMath math={props.latex} />,
|
||||
};
|
||||
});
|
||||
|
||||
export const RenderLatex = (props: { latexBlock: LatexBlock; sx?: SxProps; }) =>
|
||||
<Box
|
||||
sx={{
|
||||
mx: 1.5,
|
||||
my: '0.5em',
|
||||
textAlign: 'center',
|
||||
...props.sx,
|
||||
}}>
|
||||
<React.Suspense fallback={<div />}>
|
||||
<RenderLatexDynamic latex={props.latexBlock.latex} />
|
||||
</React.Suspense>
|
||||
</Box>;
|
||||
@@ -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: /<!DOCTYPE html>([\s\S]*?)<\/html>/g,
|
||||
svgBlock: /<svg (xmlns|width|viewBox)=([\s\S]*?)<\/svg>/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 = `<!DOCTYPE html>${match[1]}</html>`;
|
||||
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;
|
||||
|
||||
@@ -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 <ReactMarkdown components={reactMarkdownComponents} remarkPlugins={remarkPlugins} {...props} />;
|
||||
export default function CustomMarkdownRenderer(props: { content: string }) {
|
||||
return (
|
||||
<ReactMarkdown
|
||||
components={reactMarkdownComponents as any}
|
||||
remarkPlugins={[
|
||||
remarkGfm, // GitHub Flavored Markdown
|
||||
[remarkMath, { singleDollarTextMath: false }], // Math
|
||||
]}
|
||||
rehypePlugins={[
|
||||
rehypeKatex, // KaTeX
|
||||
]}
|
||||
>
|
||||
{preprocessMarkdown(props.content)}
|
||||
</ReactMarkdown>
|
||||
);
|
||||
}
|
||||
@@ -32,9 +32,7 @@ export function RenderMarkdown(props: { textBlock: TextBlock; sx?: SxProps; }) {
|
||||
sx={props.sx}
|
||||
>
|
||||
<React.Suspense fallback={<div>Loading...</div>}>
|
||||
<DynamicMarkdownRenderer>
|
||||
{props.textBlock.content}
|
||||
</DynamicMarkdownRenderer>
|
||||
<DynamicMarkdownRenderer content={props.textBlock.content} />
|
||||
</React.Suspense>
|
||||
</RenderMarkdownBox>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user