LoginSignup
43

More than 5 years have passed since last update.

markdownを直接ReactElementに変換するコンパイラを書いた

Last updated at Posted at 2015-02-25

mizchi/md2react

デモページはここ md2react playground

作った目的

巨大なmarkdownをリアルタイムプレビューする際、ただの文字列をinnerHTMLとかで更新したりしていると、更新の度にパース処理が走ってどんどん重くなってくる。

React には dangerouslySetInnerHTML というプロパティがあって、一応それっぽい感じで差分管理してくれるが、名前の通り色々怪しい挙動をする。

なのでmarkdownのASTから直接ReactElementを吐けるようにするとReactの差分計算で描画高速化されて良いのでは、というわけで作った。これはMarkdownPreview界にとって救いとなるであろう。

どこで使う目的かはお察しください

使い方

global.React = require('react');
var md2react = require('md2react');

var md = '# Hello md2react';
var html = React.renderToString(md2react(md));

/*
<div data-reactid=".14qrwokr3sw" data-react-checksum="20987480"><h1 data-reactid=".14qrwokr3sw.$_start_root_0_heading"><span data-reactid=".14qrwokr3sw.$_start_root_0_heading.0">Hello md2react</span></h1></div>'
//'<div data-reactid=".58nba97pxc" data-react-checksum="-55236619"><h1 data-reactid=".58nba97pxc.0"><span data-reactid=".58nba97pxc.0.0">Hello</span></h1></div>'
*/

たとえばReactで使う場合、

md2react = require 'md2react'
MarkdownPreview = React.createClass
  render: ->
    md = @props.body # ここにmd本文が入っているとする
    el = md2react(md, gfm:true, breaks: true)
    React.createElement 'div', className: 'markdown-content', [el]

概要

markedをforkしたmdastってプロジェクトがあって、これはmarkdownのASTを定義している。ソースマップ的なテキストレンジもとれる。パーサの第二引数はmdastにそのまま。

一応HTMLタグが出現した時はdangerouslySet~ にするしかなくてそうしているのだけど、渡す前にdompurifyでサニタイズ処理をいれている。

wooorm/mdast

なんかバグみつけて報告したら直してくれそうだった。よい。

Parse error in bullet with space before newline · Issue #15 · wooorm/mdast https://github.com/wooorm/mdast/issues/15

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43