Skip to content

Commit 8e285f8

Browse files
authored
Merge pull request velopert#141 from velopert/enhance/math-typesetting
Enhance/math typesetting
2 parents 7e98901 + fe07bb6 commit 8e285f8

File tree

5 files changed

+346
-10
lines changed

5 files changed

+346
-10
lines changed

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
"jest-environment-jsdom-fourteen": "0.1.0",
9191
"jest-resolve": "24.9.0",
9292
"jest-watch-typeahead": "0.4.2",
93+
"katex": "^0.11.1",
9394
"koa": "^2.11.0",
9495
"koa-better-http-proxy": "^0.2.4",
9596
"koa-bodyparser": "^4.2.1",
@@ -124,10 +125,15 @@
124125
"react-virtualized": "^9.21.2",
125126
"redux": "^4.0.4",
126127
"redux-devtools-extension": "^2.13.8",
128+
"rehype-katex": "^3.0.0",
129+
"rehype-raw": "^4.0.2",
130+
"rehype-stringify": "^6.0.1",
127131
"remark": "^11.0.2",
128132
"remark-breaks": "^1.0.3",
129133
"remark-highlight.js": "^5.2.0",
130134
"remark-html": "^10.0.0",
135+
"remark-math": "^2.0.1",
136+
"remark-rehype": "^6.0.0",
131137
"remark-slug": "^5.1.2",
132138
"resolve": "1.12.2",
133139
"resolve-url-loader": "3.1.1",

src/components/common/MarkdownRender.tsx

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ import parse from 'html-react-parser';
1414
import { throttle } from 'throttle-debounce';
1515
import sanitize from 'sanitize-html';
1616
import palette from '../../lib/styles/palette';
17+
import math from 'remark-math';
18+
import remark2rehype from 'remark-rehype';
19+
import katex from 'rehype-katex';
20+
import raw from 'rehype-raw';
21+
import remarkParse from 'remark-parse';
22+
import stringify from 'rehype-stringify';
23+
import { Helmet } from 'react-helmet-async';
24+
import katexWhitelist from '../../lib/katexWhitelist';
1725

1826
export interface MarkdownRenderProps {
1927
markdown: string;
@@ -150,12 +158,16 @@ function filter(html: string) {
150158
'span',
151159
'img',
152160
'del',
161+
162+
...katexWhitelist.tags,
153163
],
154164
allowedAttributes: {
155165
a: ['href', 'name', 'target'],
156166
img: ['src'],
157167
iframe: ['src', 'allow', 'allowfullscreen', 'scrolling', 'class'],
158-
'*': ['class', 'id'],
168+
'*': ['class', 'id', 'aria-hidden'],
169+
span: ['style'],
170+
...katexWhitelist.attributes,
159171
},
160172
allowedStyles: {
161173
'*': {
@@ -166,6 +178,9 @@ function filter(html: string) {
166178
],
167179
'text-align': [/^left$/, /^right$/, /^center$/],
168180
},
181+
span: {
182+
...katexWhitelist.styles,
183+
},
169184
},
170185
allowedIframeHostnames: ['www.youtube.com', 'codesandbox.io', 'codepen.io'],
171186
});
@@ -189,11 +204,16 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
189204
ssrEnabled
190205
? filter(
191206
remark()
192-
.use(breaks)
207+
.use(remarkParse)
193208
.use(prismPlugin)
194-
.use(htmlPlugin)
195209
.use(embedPlugin)
210+
.use(remark2rehype, { allowDangerousHTML: true })
211+
.use(raw)
212+
.use(breaks)
196213
.use(slug)
214+
.use(math)
215+
.use(katex)
216+
.use(stringify)
197217
.processSync(markdown)
198218
.toString(),
199219
)
@@ -211,11 +231,16 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
211231

212232
useEffect(() => {
213233
remark()
214-
.use(breaks)
234+
.use(remarkParse)
215235
.use(prismPlugin)
216-
.use(htmlPlugin)
217236
.use(embedPlugin)
237+
.use(remark2rehype, { allowDangerousHTML: true })
238+
.use(raw)
239+
.use(breaks)
218240
.use(slug)
241+
.use(math)
242+
.use(katex)
243+
.use(stringify)
219244
.process(markdown, (err: any, file: any) => {
220245
const html = String(file);
221246

@@ -241,8 +266,26 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
241266
});
242267
}, [applyElement, editing, markdown, onConvertFinish]);
243268

269+
// useEffect(() => {
270+
// if (editing) return;
271+
// const using = checkUsingMathjax(markdown);
272+
// if (using) {
273+
// loadMathjax();
274+
// }
275+
// }, [html, element, markdown, editing]);
276+
244277
return (
245278
<Typography>
279+
<Helmet>
280+
{/\$(.*)\$/.test(markdown) && (
281+
<link
282+
rel="stylesheet"
283+
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
284+
integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq"
285+
crossOrigin="anonymous"
286+
/>
287+
)}
288+
</Helmet>
246289
{editing ? (
247290
<MarkdownRenderErrorBoundary
248291
onError={() => setHasTagError(true)}

src/lib/katexWhitelist.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const tags = [
2+
'math',
3+
'annotation',
4+
'semantics',
5+
'mtext',
6+
'mn',
7+
'mo',
8+
'mi',
9+
'mspace',
10+
'mover',
11+
'munder',
12+
'munderover',
13+
'msup',
14+
'msub',
15+
'msubsup',
16+
'mfrac',
17+
'mroot',
18+
'msqrt',
19+
'mtable',
20+
'mtr',
21+
'mtd',
22+
'mlabeledtr',
23+
'mrow',
24+
'menclose',
25+
'mstyle',
26+
'mpadded',
27+
'mphantom',
28+
'mglyph',
29+
'svg',
30+
'path',
31+
'line',
32+
];
33+
34+
const attributes = tags.reduce((acc, current) => {
35+
acc[current] = ['*'];
36+
return acc;
37+
}, {} as Record<string, string[]>);
38+
39+
const styles = [
40+
'background-color',
41+
'border-bottom-width',
42+
'border-color',
43+
'border-right-style',
44+
'border-right-width',
45+
'border-top-width',
46+
'border-style',
47+
'border-width',
48+
'bottom',
49+
'color',
50+
'height',
51+
'left',
52+
'margin',
53+
'margin-left',
54+
'margin-right',
55+
'margin-top',
56+
'min-width',
57+
'padding-left',
58+
'position',
59+
'top',
60+
'width',
61+
'vertical-align',
62+
].reduce((acc, current) => {
63+
acc[current] = [/.*/];
64+
return acc;
65+
}, {} as Record<string, RegExp[]>);
66+
67+
const katexWhitelist = {
68+
tags,
69+
attributes,
70+
styles,
71+
};
72+
73+
export default katexWhitelist;

src/types/missingTypes.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,11 @@ declare module 'remark-html';
44
declare module 'remark-highlight.js';
55
declare module 'remark-breaks';
66
declare module 'remark-slug';
7+
declare module 'remark-math';
8+
declare module 'remark-rehype';
9+
declare module 'rehype-katex';
10+
declare module 'remark-parse';
11+
declare module 'rehype-stringify';
12+
declare module 'rehype-raw';
713
declare module 'unist-util-visit';
814
declare module 'strip-markdown';

0 commit comments

Comments
 (0)