React + TypeScript에서 Markdown을 Mathjax + Highlight로 표시 (참고)

이럴 때 있어요? (아마)



React + TypeScript로 서버에 넣은 Markdown을 깔끔하게 표시하고 싶다! (수식, 코드도)

그래서, 상당히 막혔기 때문에 메모.

파일 로드



XMLHttpRequest를 사용하여 "source"로 Markdown을 읽습니다.

src/Md.tsx
import React, { useEffect } from 'react';
import './Md.css'

export default function Md() {
    const [source, setSource] = React.useState<string>("");
    useEffect(() => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "./Problems/p1.md");
        xhr.send();
        xhr.onload = function () {
            if (xhr.status !== 200) {
                alert("Error");
            } else {
                setSource(xhr.responseText);
            }
        }
    }, [])
    return (
        <div className="main">
            \(ax^2+bx+c=0\)
        </div>
    );
}

Mathjax 넣기



index.html에 이것을 넣으면됩니다. 간단!
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax
/2.7.7/MathJax.js?config=TeX-AMS_CHTML"></script>

아까의
\(ax^2+bx+c=0\)

수식처럼 표시됩니다.

Markdown을 HTML로 변환하고 표시



이것은 왜 모르겠지만,
npm i --save @types/marked marked

에서 JS와 TS 모두 넣어 둡니다. 어쨌든 누락되면 할 수 없었습니다. 왜

tsx 파일은 다음과 같이 수정합니다.

src/Md.tsx
import React, { useEffect } from 'react';
import marked from 'marked';
import './Md.css'

export default function Md() {
    const [source, setSource] = React.useState<string>("");
    useEffect(() => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "./Problems/p1.md");
        xhr.send();
        xhr.onload = function () {
            if (xhr.status !== 200) {
                alert("Error");
            } else {
                setSource(marked(xhr.responseText));
            }
        }
    }, [])
    return (
        <div className="main">
            <div dangerouslySetInnerHTML={{ __html: source }} />
        </div>
    );
}

이것으로 수식이 표시될 것이라고 생각하면 안 되고, 수식의 백슬래시가 marked로 사라져 버리는 것 같기 때문에 백슬래시를 2개 쓰도록 합니다.

Syntax Highlight 붙이기



코드를 표시 할 때 Syntax Highlight를 원하십니까? 난 원해.

그래서 highlight.js를 사용합니다.
npm i --save hightlight.js @types/hightlight.js

후에는 이것으로 괜찮습니다.

하이라이트의 스타일은 가득하므로, 여러가지 시험해 보세요.

src/Md.tsx
import React, { useEffect } from 'react';
import marked from 'marked';
import highlightjs from 'highlight.js';
import 'highlight.js/styles/atelier-lakeside-dark.css'
import './Md.css'

marked.setOptions({
    highlight: function (code, lang) {
        return highlightjs.highlightAuto(code, [lang]).value;
    },
});

export default function Md() {
    const [source, setSource] = React.useState<string>("");
    useEffect(() => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "./Problems/p1.md");
        xhr.send();
        xhr.onload = function () {
            if (xhr.status !== 200) {
                alert("Error");
            } else {
                setSource(marked(xhr.responseText));
            }
        }
    }, [])
    return (
        <div className="main">
            <div dangerouslySetInnerHTML={{ __html: source }} />
            \(ax^2+bc+c=0\)
        </div>
    );
}

이제 무사히 Markdown을 볼 수있었습니다. 했어!

코드의 글꼴은 우분투 모노를 사용했습니다.



(2021/2/28 추가)
기사에서 dangerouslySetInnerHTML를 사용하면 XSS를 일으킬 수 있습니다. 사용자 입력을 다룰 때는 조심하십시오.

좋은 웹페이지 즐겨찾기