デモページはここ 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でサニタイズ処理をいれている。
なんかバグみつけて報告したら直してくれそうだった。よい。
Parse error in bullet with space before newline · Issue #15 · wooorm/mdast https://github.com/wooorm/mdast/issues/15