2016/03/12
marked.js の code highlight を SyntaxHighlighter にする
このブログに marked.js を適用して Markdown でブログを書けるようにしました。 marked.js は Code Highlighter に任意のライブラリを使用できるよう設計されている1ので、これまで通りSyntaxHighlighter を使えるようにしました。
Renderer を定義する
以下のように Renderer の code
プロパティを定義すると、好みの Highlighter でコード装飾をすることができます。
1 2 3 4 5 | var renderer = new marked.Renderer(); renderer.code = function (code, lang) { return '<pre class="brush: ' + lang + ';">' + code + '</pre>' ; }; article.innerHTML = marked(article.innerHTML, {renderer: renderer}); |
SyntaxHighlighter のパラメータを使えるようにする
SyntaxHighlighter を使うメリットの一つに特定の行を強調表示できるというものがあります。 しかし、Markdown 記法でそういった表示を実現する方法はありません。
SyntaxHighlighter にパラメータを与えつつ、他の Markdown 記法に移行しても使える方法を模索した結果、
最初の一行が `
だった場合、それをパラメータとして使うという方式に落ち着きました。
コードは以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 | var renderer = new marked.Renderer(); renderer.code = function (code, lang) { // 1行目が ` で始まっているかどうか確認 params = code.match(/^`(.+)\n/); if (params != null ) { // 1行目を削除 code = code.replace(/^`.+\n/, '' ); return '<pre class="brush: ' + lang + ';' + params[1] + '">' + code + '</pre>' ; } else { return '<pre class="brush: ' + lang + ';">' + code + '</pre>' ; } }; article.innerHTML = marked(article.innerHTML, {renderer: renderer}); |
Markedown の記述
```java `highlight: 1; private int x = 0; private int y = 1; ```
実行結果
1 2 | private int x = 0 ; private int y = 1 ; |
他の問題も修正
使ってみると、その他にもうまく行かない場合があったので、それらを回避するコードを追加しました。 具体的には以下のようなケースです。
- Language 指定しなかった場合エラーになる
- XML 等タグを含む場合表示が崩れる
最終コードは以下になりました2。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var renderer = new marked.Renderer(); renderer.code = function (code, lang) { // lang 指定が無かったら text にする if (!lang) { lang = 'text' ; } // タグをリプレース code = code.replace(/</g, '<' ).replace(/>/g, '>' ); // 1行目が ` で始まっているかどうか確認 params = code.match(/^`(.+)\n/); if (params != null ) { // 1行目を削除 code = code.replace(/^`.+\n/, '' ); return '<pre class="brush: ' + lang + ';' + params[1] + '">' + code + '</pre>' ; } else { return '<pre class="brush: ' + lang + ';">' + code + '</pre>' ; } }; $( '.marked' ).each( function (i, val) { txt = val.innerHTML.replace(/(\n+)>|^>/g, '$1>' ); val.innerHTML = marked(txt, {renderer: renderer}); }); |
0 件のコメント:
コメントを投稿