latex support

This commit is contained in:
josc146 2024-03-13 21:37:48 +08:00
parent 5692579f56
commit 4bed070556
4 changed files with 188 additions and 2 deletions

View File

@ -19,6 +19,7 @@
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"html-midi-player": "^1.5.0", "html-midi-player": "^1.5.0",
"i18next": "^22.4.15", "i18next": "^22.4.15",
"katex": "^0.16.9",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mobx": "^6.9.0", "mobx": "^6.9.0",
"mobx-react-lite": "^3.4.3", "mobx-react-lite": "^3.4.3",
@ -34,9 +35,11 @@
"react-router-dom": "^6.11.1", "react-router-dom": "^6.11.1",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"rehype-highlight": "^6.0.0", "rehype-highlight": "^6.0.0",
"rehype-katex": "^6.0.3",
"rehype-raw": "^6.1.1", "rehype-raw": "^6.1.1",
"remark-breaks": "^3.0.3", "remark-breaks": "^3.0.3",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"usehooks-ts": "^2.9.1", "usehooks-ts": "^2.9.1",
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },
@ -2565,6 +2568,11 @@
"hoist-non-react-statics": "^3.3.0" "hoist-non-react-statics": "^3.3.0"
} }
}, },
"node_modules/@types/katex": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz",
"integrity": "sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA=="
},
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.14.202", "version": "4.14.202",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz",
@ -3492,6 +3500,17 @@
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
}, },
"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/esbuild": { "node_modules/esbuild": {
"version": "0.17.19", "version": "0.17.19",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.17.19.tgz", "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.17.19.tgz",
@ -3888,6 +3907,61 @@
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
"optional": true "optional": true
}, },
"node_modules/hast-util-from-dom": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz",
"integrity": "sha512-t1RJW/OpJbCAJQeKi3Qrj1cAOLA0+av/iPFori112+0X7R3wng+jxLA+kXec8K4szqPRGI8vPxbbpEYvvpwaeQ==",
"dependencies": {
"hastscript": "^7.0.0",
"web-namespaces": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-from-html": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-1.0.2.tgz",
"integrity": "sha512-LhrTA2gfCbLOGJq2u/asp4kwuG0y6NhWTXiPKP+n0qNukKy7hc10whqqCFfyvIA1Q5U5d0sp9HhNim9gglEH4A==",
"dependencies": {
"@types/hast": "^2.0.0",
"hast-util-from-parse5": "^7.0.0",
"parse5": "^7.0.0",
"vfile": "^5.0.0",
"vfile-message": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-from-html-isomorphic": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-1.0.0.tgz",
"integrity": "sha512-Yu480AKeOEN/+l5LA674a+7BmIvtDj24GvOt7MtQWuhzUwlaaRWdEPXAh3Qm5vhuthpAipFb2vTetKXWOjmTvw==",
"dependencies": {
"@types/hast": "^2.0.0",
"hast-util-from-dom": "^4.0.0",
"hast-util-from-html": "^1.0.0",
"unist-util-remove-position": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-from-html/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/hast-util-from-parse5": { "node_modules/hast-util-from-parse5": {
"version": "7.1.2", "version": "7.1.2",
"resolved": "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", "resolved": "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz",
@ -4214,6 +4288,29 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/katex": {
"version": "0.16.9",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz",
"integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==",
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
],
"dependencies": {
"commander": "^8.3.0"
},
"bin": {
"katex": "cli.js"
}
},
"node_modules/katex/node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"engines": {
"node": ">= 12"
}
},
"node_modules/keyborg": { "node_modules/keyborg": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/keyborg/-/keyborg-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/keyborg/-/keyborg-2.0.0.tgz",
@ -4469,6 +4566,20 @@
"mdast-util-to-markdown": "^1.3.0" "mdast-util-to-markdown": "^1.3.0"
} }
}, },
"node_modules/mdast-util-math": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-2.0.2.tgz",
"integrity": "sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ==",
"dependencies": {
"@types/mdast": "^3.0.0",
"longest-streak": "^3.0.0",
"mdast-util-to-markdown": "^1.3.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-newline-to-break": { "node_modules/mdast-util-newline-to-break": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/mdast-util-newline-to-break/-/mdast-util-newline-to-break-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/mdast-util-newline-to-break/-/mdast-util-newline-to-break-1.0.0.tgz",
@ -4672,6 +4783,29 @@
"uvu": "^0.5.0" "uvu": "^0.5.0"
} }
}, },
"node_modules/micromark-extension-math": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-2.1.2.tgz",
"integrity": "sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg==",
"dependencies": {
"@types/katex": "^0.16.0",
"katex": "^0.16.0",
"micromark-factory-space": "^1.0.0",
"micromark-util-character": "^1.0.0",
"micromark-util-symbol": "^1.0.0",
"micromark-util-types": "^1.0.0",
"uvu": "^0.5.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/micromark-extension-math/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/micromark-factory-destination": { "node_modules/micromark-factory-destination": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz",
@ -5697,6 +5831,23 @@
"unist-util-visit": "^4.0.0" "unist-util-visit": "^4.0.0"
} }
}, },
"node_modules/rehype-katex": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-6.0.3.tgz",
"integrity": "sha512-ByZlRwRUcWegNbF70CVRm2h/7xy7jQ3R9LaY4VVSvjnoVWwWVhNL60DiZsBpC5tSzYQOCvDbzncIpIjPZWodZA==",
"dependencies": {
"@types/hast": "^2.0.0",
"@types/katex": "^0.14.0",
"hast-util-from-html-isomorphic": "^1.0.0",
"hast-util-to-text": "^3.1.0",
"katex": "^0.16.0",
"unist-util-visit": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-raw": { "node_modules/rehype-raw": {
"version": "6.1.1", "version": "6.1.1",
"resolved": "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-6.1.1.tgz", "resolved": "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-6.1.1.tgz",
@ -5728,6 +5879,21 @@
"unified": "^10.0.0" "unified": "^10.0.0"
} }
}, },
"node_modules/remark-math": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/remark-math/-/remark-math-5.1.1.tgz",
"integrity": "sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw==",
"dependencies": {
"@types/mdast": "^3.0.0",
"mdast-util-math": "^2.0.0",
"micromark-extension-math": "^2.0.0",
"unified": "^10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-parse": { "node_modules/remark-parse": {
"version": "10.0.2", "version": "10.0.2",
"resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-10.0.2.tgz", "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-10.0.2.tgz",
@ -6590,6 +6756,19 @@
"@types/unist": "^2.0.0" "@types/unist": "^2.0.0"
} }
}, },
"node_modules/unist-util-remove-position": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz",
"integrity": "sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==",
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-visit": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-stringify-position": { "node_modules/unist-util-stringify-position": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", "resolved": "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",

View File

@ -20,6 +20,7 @@
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"html-midi-player": "^1.5.0", "html-midi-player": "^1.5.0",
"i18next": "^22.4.15", "i18next": "^22.4.15",
"katex": "^0.16.9",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mobx": "^6.9.0", "mobx": "^6.9.0",
"mobx-react-lite": "^3.4.3", "mobx-react-lite": "^3.4.3",
@ -35,9 +36,11 @@
"react-router-dom": "^6.11.1", "react-router-dom": "^6.11.1",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"rehype-highlight": "^6.0.0", "rehype-highlight": "^6.0.0",
"rehype-katex": "^6.0.3",
"rehype-raw": "^6.1.1", "rehype-raw": "^6.1.1",
"remark-breaks": "^3.0.3", "remark-breaks": "^3.0.3",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"usehooks-ts": "^2.9.1", "usehooks-ts": "^2.9.1",
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },

View File

@ -1,6 +1,9 @@
import 'katex/dist/katex.min.css';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import rehypeRaw from 'rehype-raw'; import rehypeRaw from 'rehype-raw';
import rehypeHighlight from 'rehype-highlight'; import rehypeHighlight from 'rehype-highlight';
import rehypeKatex from 'rehype-katex';
import remarkMath from 'remark-math';
import remarkGfm from 'remark-gfm'; import remarkGfm from 'remark-gfm';
import remarkBreaks from 'remark-breaks'; import remarkBreaks from 'remark-breaks';
import { FC } from 'react'; import { FC } from 'react';
@ -90,8 +93,9 @@ const MarkdownRender: FC<ReactMarkdownOptions & { disabled?: boolean }> = (props
'cite' 'cite'
]} ]}
unwrapDisallowed={true} unwrapDisallowed={true}
remarkPlugins={[remarkGfm, remarkBreaks]} remarkPlugins={[remarkMath, remarkGfm, remarkBreaks]}
rehypePlugins={[ rehypePlugins={[
rehypeKatex,
rehypeRaw, rehypeRaw,
[ [
rehypeHighlight, rehypeHighlight,

View File

@ -23,7 +23,7 @@ const embedded = [
'react-beautiful-dnd', 'react-beautiful-dnd',
'react-draggable', 'react-draggable',
'@magenta/music', 'html-midi-player', '@magenta/music', 'html-midi-player',
'react-markdown', 'rehype-highlight', 'rehype-raw', 'remark-breaks', 'remark-gfm' 'react-markdown', 'rehype-highlight', 'rehype-raw', 'remark-breaks', 'remark-gfm', 'remark-math', 'rehype-katex', 'katex'
]; ];
function renderChunks(deps: Record<string, string>) { function renderChunks(deps: Record<string, string>) {