BLOGサブスレッドの日常

2020.04.21

TypeScript で remark-react

tama

最近いろいろ踏んでる気がします。tamaです。

フロントサイドで Markdown をフォーマットしたいと思いました。
Reactに組み込むには react-markdown というモジュールがあるようですが、
GFM(GitHub-flavored Markdown)に対応した remark-react もあるというウワサを聞きつけそちらを試してみたところ
案の定苦戦したので記録に残しておきます。

remark-react は TypeScript の型定義ファイルがないので require() で読み込みます。
いちいち型定義ファイル作るほどでもなさそう。

2〜3年前のブログ記事は process()processSync() が返すオブジェクトの .contents プロパティを表示しているようですが、
remark 12.0.0、remark-react 7.0.1 の現在、.contents は元のMarkdownテキストしか示していません。
どうも VFileインタフェースでは定義されていない .result というプロパティに react.element が格納されているもよう。

import remark from 'remark';

const remark2react = require('remark-react');

export function md2react(markdown: string, options?: any) {
    const processor = remark().use(remark2react, options);

    if (options && options.async) {
        // 非同期版
        return new Promise((accept, reject) => {
            processor.process(markdown, (error, file: any) => {
                if (error) {
                    reject(error);
                } else {
                    accept(file.result || file.contents)
                }
            });
        });
    } else {
        // 同期版
        const file: any = processor.processSync(markdown);
        return file.result || file.contents;
    }
}

というわけで雑にまとめるとこんなモジュールを用意しておけば
<div>{md2react('# title\n* __list__\n * _item_')}</div>
みたくしてReact要素化したMarkdownを錬成できそうです。

この記事を書いた人

tama