2016/02/26 16:21
|
commonmark.js + highlight.js + mathjax.jsでちょっとリッチなエディタを作ってみた(1/2)
|
こんばんは、お久しぶりです。
ブログを始めて間もないですが、最近は仕事の合間に機械学習を雑に勉強しつつ、自作ブログの機能を充実させるということをしています。
その中で、タイトルの通リ
*commonmark.js + highlight.js + mathjax.jsでリッチなMarkdownエディタ*
を作ってみたので、JS BINというサービスを使って説明してみます。
(また、おまけ機能でdrag & dropでの画像アップロード機能も載せています)
##### サンプル(JS Bin)
<a class="jsbin-embed" href="http://jsbin.com/picoyuyupo/embed?html,css,js">JS Bin on jsbin.com</a><script src="http://static.jsbin.com/js/embed.min.js?4.1.1"></script>
##### エディタを実現している各種ライブラリ
###### ▶ [commonmark.js](https://github.com/jgm/commonmark.js)
- Markdown -> HTMLを実現するJavaScriptライブラリ
- Markdownの形式は[Commonmark](http://commonmark.org/)という記法に則ったものを使用しています。
- 色々派生が多いので迷ったのですが、jsのライブラリで採用されているものが多いということでこれを使用。
- 実装方法はざっと⇣の感じ
``` javascript
// ライブラリからrendereとparserを読み込み
var GL ={};
GL.commonmark = window.commonmark;
GL.writer = new commonmark.HtmlRenderer({sourcepos: true});
GL.reader = new commonmark.Parser();
// Parsing
var textarea = $("#input_area");
var parsed = GL.reader.parse(textarea.val());
// Rendering
$("div#preview_area").html(GL.writer.render(parsed));
```
###### ▶ [highlight.js](https://highlightjs.org/)
- \<code\>\<\/code\>の内容をsyntax highlight(IDEのように文法によって色分け)するJavaScriptライブラリ
- このsyntax highlightを実装するjsライブラリも多くの種類があります。
- 実装方法
- 特に変数や関数のオーバーライドは必要なく、\<code\>タグの要素を順に入れていくだけでOK
``` javascript
// Syntax Highlight (Use "highlight.js")
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
```
###### ▶ [MathJax](https://www.mathjax.org/)
- ”Beautiful math in all browsers”というイカしたキャッチフレーズを持つ数式描画用Javascriptライブラリです。
> MathJax はMathML、LaTeX、ASCIIMathML(英語版)で記述された数式をウェブブラウザ上で表示するクロスブラウザ(英語版)のJavaScriptライブラリである
> ([wikipedia](https://ja.wikipedia.org/wiki/MathJax)より引用)
【コード(テキストエリア上に入力)】
```javascript
$
\sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}
\tag{1}
$
```
【実行結果】
$
\sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}
\tag{1}
$
- 実装方法([公式ドキュメント](https://docs.mathjax.org/en/v2.0-latest/typeset.html))
- typesetというのは、英語的には*属性を明示する*などという意味ですが、[公式ドキュメント](https://docs.mathjax.org/en/v2.0-latest/typeset.html)を見る限り、入力をコンパイル・レンダリングする事を指しているように思いますので、ここではmarkdownを入力としてHTMLを生成し#preview_areaに反映させることを指しているのではないかと考えられます。
- MathJaxは数式をSVGなどで描画する処理負荷の高いライブラリなので、例えば一文字一文字のTextareaの入力の変化毎に数式を再レンダリングをすることは現実的ではありません。
- そこでmarkdownを変更したタイミングでtypesetを実施すべき、とこのドキュメントでは言っているのだと理解しています(違ったらコメントください・・・)
###### HTMLのheadにて明記
``` html
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
processEscapes: true
},
CommonHTML: { matchFontHeight: false },
displayAlign: "left",
displayIndent: "2em"
});
</script>
```
###### markdownをhtmlに反映後に処理
``` javascript
MathJax.Hub.Typeset(["Typeset",MathJax.Hub, "posts-preview"]);
```
##### まとめ
活用した外部ライブラリは以上です。
今回作成した簡易エディタは色んなライブラリのごった煮ではあります。しかし、組合せるだけでQitaが実装しているようなエディタは簡単に実装できるということを紹介するのが本投稿の目的でした。
(もちろん、Qitaには魅力的な他の機能も多くあります)
その他の機能として、
- drag & dropでの画像アップローダ
- 入力文字の時間差反映
なども自作しているのですが、少し記事が長くなるので、別日に更新します。