😽
Next.jsで究極のマークダウンエディタを作成する話 その2
ReactMarkdownを使うのが良さそう
前回までの調査でmarkdownをリアルタイムプレビューには成功しました
今回は拡張で欲しい機能を追加できるものの調査と設計をしていきます
1 スタイリングを当てられる
2 コードブロックに言語に応じたハイライトがある
3 htmlを埋め込める
4 github準拠のものが使える
5 Texを用いて数式を扱える
1.スタイリングを当てる
こちらのものを使わせていただきました
npm install github-markdown-css
をして、
import "github-markdown-css";
を追記
<ReactMarkdown className="markdown-body">
{markdown}
</ReactMarkdown>
と変更するだけ
となります!👏
2.コードブロックに言語に応じたハイライトがある
どうやらHighlightのライブラリがたくさんあるらしい
どれを使ってもうまくいかないので現在調査中です
3.htmlを埋め込める
npm i rehype-raw rehype-sanitize
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";
...
<ReactMarkdown
rehypePlugins={[rehypeRaw, rehypeSanitize]}
>
{markdown}
</ReactMarkdown>
4.github準拠のものが使える
npm i remark-gfm
import remarkGfm from "remark-gfm";
...
<ReactMarkdown remarkPlugins={[remarkGfm]}>
{markdown}
</ReactMarkdown>
5.Texを用いて数式を扱える
remark-math rehype-katex
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
...
<ReactMarkdown remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex]}>
{markdown}
</ReactMarkdown>
import "katex/dist/katex.min.css";
全てを詰め合わせたサンプル
import { useState, useRef, useEffect } from "react";
import remarkGfm from "remark-gfm";
import ReactMarkdown from "react-markdown";
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";
export function MarkdownEditor() {
const [markdown, setMarkdown] = useState("");
return (
<div className="flex gap-5 p-5">
<div className="flex-1">
<textarea
className="w-full p-3 text-lg border border-gray-300 rounded resize-none"
placeholder="Write your Markdown here..."
value={markdown}
onChange={(e) => setMarkdown(e.target.value)}
/>
</div>
<div className="flex-1 p-3 border rounded overflow-y-auto max-h-[400px]">
<ReactMarkdown
remarkPlugins={[remarkMath, remarkGfm]}
rehypePlugins={[rehypeRaw, rehypeSanitize,rehypeKatex]}
className="markdown-body"
>
{markdown}
</ReactMarkdown>
</div>
</div>
);
}
:::note warn
rehypePlugins={[rehypeRaw, rehypeSanitize,rehypeKatex]}
はこの順番でないと正常動作しません
:::
Discussion