Skip to content

Commit

Permalink
Remove mathjax and replace it with ReactMarkdown
Browse files Browse the repository at this point in the history
  • Loading branch information
vgeffer committed Dec 14, 2024
1 parent 500385b commit 883a0de
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 178 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
"clsx": "^2.1.1",
"katex": "^0.16.11",
"luxon": "^3.5.0",
"mathjax-full": "^3.2.2",
"mathjax-react": "^2.0.1",
"next": "15.0.3",
"ra-i18n-polyglot": "^5.4.0",
"ra-language-slovak": "^3.6.2",
Expand All @@ -42,6 +40,7 @@
"react-hook-form": "^7.53.2",
"react-markdown": "^9.0.1",
"rehype-katex": "^7.0.1",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"typescript": "^5.7.2",
Expand Down
98 changes: 36 additions & 62 deletions src/components/Latex/Latex.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,37 @@
import {Typography} from '@mui/material'
import {MathComponentProps} from 'mathjax-react/dist/components/MathComponent'
import dynamic from 'next/dynamic'
import {FC, Fragment} from 'react'

import styles from './Latex.module.scss'

// mathjax-react musi byt renderovany client-side (spolieha sa na browser `window`): https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr
const MathComponent = dynamic<MathComponentProps>(
() => import('mathjax-react').then(({MathComponent}) => MathComponent),
{ssr: false},
import 'katex/dist/katex.min.css'

import {FC} from 'react'
import ReactMarkdown from 'react-markdown'
import rehypeKatex from 'rehype-katex'
import rehypeRaw from 'rehype-raw'
import remarkGfm from 'remark-gfm'
import remarkMath from 'remark-math'

import {H1, H2, H3, MarkdownLink, Ol, P, Table, Td, Th, Ul} from '../StaticSites/Texts'

const Empty: FC = () => <></>

export const Latex: FC<{children: string}> = ({children}) => (
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeKatex, rehypeRaw]}
components={{
a: MarkdownLink,
table: Table,
th: Th,
td: Td,
p: P,
h1: H1,
h2: H2,
h3: H3,
h4: H3,
h5: H3,
h6: H3,
ol: Ol,
ul: Ul,
script: Empty,
}}
>
{children}
</ReactMarkdown>
)

// toto je regex, ktory matchuje LaTeX matematiku: $$.$$ \[.\] $.$ \(.\)
const re = /((?<!(\\|\$))\$(?!\$).+?(?<!(\\|\$))\$(?!\$))|(\$\$.+?\$\$)|(\\\[.+?\\\])|(\\\(.+?\\\))/gsu

const trim = (str: string) => {
if (str[0] === '$' && str[1] !== '$') {
return str.slice(1, -1)
} else {
return str.slice(2, -2)
}
}

export const Latex: FC<{children: string}> = ({children}) => {
const matches = Array.from(children.matchAll(re))

if (matches.length === 0) {
return <Typography variant="body1" dangerouslySetInnerHTML={{__html: `${children}`}} />
}

const result = []
let currentPosition = 0

for (const m of matches) {
result.push(
<Typography variant="body1" dangerouslySetInnerHTML={{__html: `${children.slice(currentPosition, m.index)}`}} />,
<MathComponent tex={trim(m[0])} display={m[0].slice(0, 2) === '\\[' || m[0].slice(0, 2) === '$$'} />,
)

if (typeof m.index !== 'undefined') {
currentPosition = m.index + m[0].length
}
}

result.push(
<Typography
variant="body1"
dangerouslySetInnerHTML={{__html: `${children.slice(Math.max(0, currentPosition))}`}}
/>,
)

return (
// nas globalny CSS reset nastavuje SVGcka na display:block, tak to tu resetneme nazad na inline
// - MathComponent totiz pouziva SVGcka na LaTex vyrazy a rata s tym, ze su inline
<div className={styles.inlineSvgs}>
{result.map((child, index) => (
// kazdy element listu potrebuje key, inak mame react warning
<Fragment key={index}>{child}</Fragment>
))}
</div>
)
}
169 changes: 55 additions & 114 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4333,20 +4333,6 @@ __metadata:
languageName: node
linkType: hard

"commander@npm:9.2.0":
version: 9.2.0
resolution: "commander@npm:9.2.0"
checksum: 10/db4855c6cd7694d4117e17ec353c7fcc678695e008e12dd5cd45ebaf3fd15607a476df690bf658c7a20a661743580fb0150c825087d773847a24392891e7b4bc
languageName: node
linkType: hard

"commander@npm:^6.0.0":
version: 6.2.1
resolution: "commander@npm:6.2.1"
checksum: 10/25b88c2efd0380c84f7844b39cf18510da7bfc5013692d68cdc65f764a1c34e6c8a36ea6d72b6620e3710a930cf8fab2695bdec2bf7107a0f4fa30a3ef3b7d0e
languageName: node
linkType: hard

"commander@npm:^7.2.0":
version: 7.2.0
resolution: "commander@npm:7.2.0"
Expand Down Expand Up @@ -5938,13 +5924,6 @@ __metadata:
languageName: node
linkType: hard

"esm@npm:^3.2.25":
version: 3.2.25
resolution: "esm@npm:3.2.25"
checksum: 10/ee96b8202b76dd1841c55e8a066608d6f0ae0333012be5c77829ccadcd21114283b4d7bf9ac1b8c09853258829c7843e9c6d7e0594acbc5e813cb37d82728d4b
languageName: node
linkType: hard

"espree@npm:^9.6.0, espree@npm:^9.6.1":
version: 9.6.1
resolution: "espree@npm:9.6.1"
Expand Down Expand Up @@ -6771,6 +6750,27 @@ __metadata:
languageName: node
linkType: hard

"hast-util-raw@npm:^9.0.0":
version: 9.1.0
resolution: "hast-util-raw@npm:9.1.0"
dependencies:
"@types/hast": "npm:^3.0.0"
"@types/unist": "npm:^3.0.0"
"@ungap/structured-clone": "npm:^1.0.0"
hast-util-from-parse5: "npm:^8.0.0"
hast-util-to-parse5: "npm:^8.0.0"
html-void-elements: "npm:^3.0.0"
mdast-util-to-hast: "npm:^13.0.0"
parse5: "npm:^7.0.0"
unist-util-position: "npm:^5.0.0"
unist-util-visit: "npm:^5.0.0"
vfile: "npm:^6.0.0"
web-namespaces: "npm:^2.0.0"
zwitch: "npm:^2.0.0"
checksum: 10/fa304d08a9fce0f54b2baa18d15c45cb5cac695cbee3567b8ccbd9a57fa295c0fb23d238daca1cf0135ad8d538bb341dcd7d9da03f8b7d12e6980a9f8c4340ae
languageName: node
linkType: hard

"hast-util-to-jsx-runtime@npm:^2.0.0":
version: 2.3.2
resolution: "hast-util-to-jsx-runtime@npm:2.3.2"
Expand All @@ -6794,6 +6794,21 @@ __metadata:
languageName: node
linkType: hard

"hast-util-to-parse5@npm:^8.0.0":
version: 8.0.0
resolution: "hast-util-to-parse5@npm:8.0.0"
dependencies:
"@types/hast": "npm:^3.0.0"
comma-separated-tokens: "npm:^2.0.0"
devlop: "npm:^1.0.0"
property-information: "npm:^6.0.0"
space-separated-tokens: "npm:^2.0.0"
web-namespaces: "npm:^2.0.0"
zwitch: "npm:^2.0.0"
checksum: 10/ba59d0913ba7e914d8b0a50955c06806a6868445c56796ac9129d58185e86d7ff24037246767aba2ea904d9dee8c09b8ff303630bcd854431fdc1bbee2164c36
languageName: node
linkType: hard

"hast-util-to-text@npm:^4.0.0":
version: 4.0.2
resolution: "hast-util-to-text@npm:4.0.2"
Expand Down Expand Up @@ -6861,6 +6876,13 @@ __metadata:
languageName: node
linkType: hard

"html-void-elements@npm:^3.0.0":
version: 3.0.0
resolution: "html-void-elements@npm:3.0.0"
checksum: 10/59be397525465a7489028afa064c55763d9cccd1d7d9f630cca47137317f0e897a9ca26cef7e745e7cff1abc44260cfa407742b243a54261dfacd42230e94fce
languageName: node
linkType: hard

"http-cache-semantics@npm:^4.1.0":
version: 4.1.1
resolution: "http-cache-semantics@npm:4.1.1"
Expand Down Expand Up @@ -7999,43 +8021,6 @@ __metadata:
languageName: node
linkType: hard

"mathjax-full@npm:^3.0.4":
version: 3.1.2
resolution: "mathjax-full@npm:3.1.2"
dependencies:
esm: "npm:^3.2.25"
mj-context-menu: "npm:^0.6.1"
speech-rule-engine: "npm:^3.1.1"
checksum: 10/8c6af903b8a8c82ccc2d79a50a15438255e4c07e3c858277cc94017c7bc5153403ee673ae3108588cd1b247c84cdc214e232709070ff8d574c31c2f611e7a607
languageName: node
linkType: hard

"mathjax-full@npm:^3.2.2":
version: 3.2.2
resolution: "mathjax-full@npm:3.2.2"
dependencies:
esm: "npm:^3.2.25"
mhchemparser: "npm:^4.1.0"
mj-context-menu: "npm:^0.6.1"
speech-rule-engine: "npm:^4.0.6"
checksum: 10/1091a1773f736c00723ce4db35f9f0f04f4e54b8af51cf1b916ea0e1f90411e64521970f9ec5f760a7b490956f54cf2a5ddda2a2d762eddf65d6cd63494c4f8c
languageName: node
linkType: hard

"mathjax-react@npm:^2.0.1":
version: 2.0.1
resolution: "mathjax-react@npm:2.0.1"
dependencies:
mathjax-full: "npm:^3.0.4"
peerDependencies:
mathjax-full: ^3.0.4
prop-types: ^15.5.4
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
checksum: 10/7063827c5cb4b35caf016df202d41e3957f006b146f7800931b791c39eb355c805e2542faa1b5bbb13f36128e4b63bd469eb697782f51efa43dbcd62b54ed7d5
languageName: node
linkType: hard

"mdast-util-find-and-replace@npm:^3.0.0":
version: 3.0.1
resolution: "mdast-util-find-and-replace@npm:3.0.1"
Expand Down Expand Up @@ -8282,13 +8267,6 @@ __metadata:
languageName: node
linkType: hard

"mhchemparser@npm:^4.1.0":
version: 4.1.1
resolution: "mhchemparser@npm:4.1.1"
checksum: 10/51c5ed19371dac646a08aad29fd427554d33c21cadb6fa433c6da27e97f5f30523975e49b0ab866784ba1f0bac433c35bda99a978adc57307960c8da5aae86ba
languageName: node
linkType: hard

"micromark-core-commonmark@npm:^2.0.0":
version: 2.0.2
resolution: "micromark-core-commonmark@npm:2.0.2"
Expand Down Expand Up @@ -8803,13 +8781,6 @@ __metadata:
languageName: node
linkType: hard

"mj-context-menu@npm:^0.6.1":
version: 0.6.1
resolution: "mj-context-menu@npm:0.6.1"
checksum: 10/5b9d6e3dabd9098eb37b9583a55b5e23d9d4f80a97c295c2f4ca318233801519e5abc7b5d7907817fea5cc7dcf334f192ac9622e2d4da55d350b78c8e31e7e3a
languageName: node
linkType: hard

"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
version: 1.0.4
resolution: "mkdirp@npm:1.0.4"
Expand Down Expand Up @@ -10129,6 +10100,17 @@ __metadata:
languageName: node
linkType: hard

"rehype-raw@npm:^7.0.0":
version: 7.0.0
resolution: "rehype-raw@npm:7.0.0"
dependencies:
"@types/hast": "npm:^3.0.0"
hast-util-raw: "npm:^9.0.0"
vfile: "npm:^6.0.0"
checksum: 10/65dd5809f95410ca5056efe50f5b16cb08a69c0785c6d4ec80c9280487efbaec81d342084f6cfdca5624134c1c4018705d97c37b5c0a21d9625ed8a3c88700f1
languageName: node
linkType: hard

"remark-gfm@npm:^4.0.0":
version: 4.0.0
resolution: "remark-gfm@npm:4.0.0"
Expand Down Expand Up @@ -10831,32 +10813,6 @@ __metadata:
languageName: node
linkType: hard

"speech-rule-engine@npm:^3.1.1":
version: 3.1.1
resolution: "speech-rule-engine@npm:3.1.1"
dependencies:
commander: "npm:^6.0.0"
wicked-good-xpath: "npm:^1.3.0"
xmldom-sre: "npm:^0.1.31"
bin:
sre: bin/sre
checksum: 10/4bb502d5a900d19fb1680928bbd85c226d0acdd1c16f89ebad963d6c3d3146a23218c1ed393cd408dd2598f24cc3d0b18c61550e426d4ba08c2dad7240ecb8ed
languageName: node
linkType: hard

"speech-rule-engine@npm:^4.0.6":
version: 4.0.7
resolution: "speech-rule-engine@npm:4.0.7"
dependencies:
commander: "npm:9.2.0"
wicked-good-xpath: "npm:1.3.0"
xmldom-sre: "npm:0.1.31"
bin:
sre: bin/sre
checksum: 10/a5b670f1f3503c79830e90cc2bcf308c148108c02cd5f1cabd2c1a8f7407d5139eb095c1933d79bd1de995a71082d258171081edc86e23152785adb4c22dceba
languageName: node
linkType: hard

"split-on-first@npm:^1.0.0":
version: 1.1.0
resolution: "split-on-first@npm:1.1.0"
Expand Down Expand Up @@ -11805,8 +11761,6 @@ __metadata:
eslint-plugin-unicorn: "npm:^56.0.1"
katex: "npm:^0.16.11"
luxon: "npm:^3.5.0"
mathjax-full: "npm:^3.2.2"
mathjax-react: "npm:^2.0.1"
next: "npm:15.0.3"
prettier: "npm:^3.3.3"
ra-i18n-polyglot: "npm:^5.4.0"
Expand All @@ -11819,6 +11773,7 @@ __metadata:
react-hook-form: "npm:^7.53.2"
react-markdown: "npm:^9.0.1"
rehype-katex: "npm:^7.0.1"
rehype-raw: "npm:^7.0.0"
remark-gfm: "npm:^4.0.0"
remark-math: "npm:^6.0.0"
sass: "npm:^1.81.0"
Expand Down Expand Up @@ -11924,13 +11879,6 @@ __metadata:
languageName: node
linkType: hard

"wicked-good-xpath@npm:1.3.0, wicked-good-xpath@npm:^1.3.0":
version: 1.3.0
resolution: "wicked-good-xpath@npm:1.3.0"
checksum: 10/e4d7d6c1b48ccb4f406d69217b2fe1073988bcb970645c64be359a1cc81e5aec49d348a7763ad54c7c4a05b6a92986dff7c23edcc5462b54bf1260d52217ace4
languageName: node
linkType: hard

"wide-align@npm:^1.1.5":
version: 1.1.5
resolution: "wide-align@npm:1.1.5"
Expand Down Expand Up @@ -11965,13 +11913,6 @@ __metadata:
languageName: node
linkType: hard

"xmldom-sre@npm:0.1.31, xmldom-sre@npm:^0.1.31":
version: 0.1.31
resolution: "xmldom-sre@npm:0.1.31"
checksum: 10/0aad5fda92cab061cb47be4b5e50dedef007dbd394f3ce9134c957203561aace5bd0b5fac10cb573fc326440e852390de74110424d6afd7a7d700466b1b171d9
languageName: node
linkType: hard

"y18n@npm:^5.0.5":
version: 5.0.8
resolution: "y18n@npm:5.0.8"
Expand Down

0 comments on commit 883a0de

Please sign in to comment.