2016/03/12

marked.js の code highlight を SyntaxHighlighter にする

このブログに [marked.js](https://github.com/chjj/marked) を適用して [Markdown でブログを書ける](https://kokufu.blogspot.jp/2016/03/blogger-markdown-blockquote.html)ようにしました。
marked.js は Code Highlighter に任意のライブラリを使用できるよう設計されている素晴らしい!ので、これまで通り[SyntaxHighlighter](http://alexgorbatchev.com/SyntaxHighlighter/) を使えるようにしました。


### Renderer を定義する
以下のように Renderer の `code`プロパティを定義すると、好みの Highlighter でコード装飾をすることができます。
```javascript
      var renderer = new marked.Renderer();
      renderer.code = function(code, lang) {
        return '
' + code + '
'; }; article.innerHTML = marked(article.innerHTML, {renderer: renderer}); ``` ### SyntaxHighlighter のパラメータを使えるようにする SyntaxHighlighter を使うメリットの一つに特定の行を強調表示できるというものがあります。 しかし、Markdown 記法でそういった表示を実現する方法はありません。 SyntaxHighlighter にパラメータを与えつつ、他の Markdown 記法に移行しても使える方法を模索した結果、 最初の一行が `` ` ``だった場合、それをパラメータとして使うという方式に落ち着きました。 コードは以下です。 ```javascript var renderer = new marked.Renderer(); renderer.code = function(code, lang) { // 1行目が ` で始まっているかどうか確認 params = code.match(/^`(.+)\n/); if (params != null) { // 1行目を削除 code = code.replace(/^`.+\n/, ''); return '
' + code + '
'; } else { return '
' + code + '
'; } }; article.innerHTML = marked(article.innerHTML, {renderer: renderer}); ``` Markedown の記述
```java
`highlight: 1;
private int x = 0;
private int y = 1;
```
実行結果 ```java `highlight: 1; private int x = 0; private int y = 1; ``` ### 他の問題も修正 使ってみると、その他にもうまく行かない場合があったので、それらを回避するコードを追加しました。 具体的には以下のようなケースです。 - Language 指定しなかった場合エラーになる - XML 等タグを含む場合表示が崩れる 最終コードは以下になりましたこのコードを Markdown から直接コピペすると正しく動作しません。
Syntax Highlighter で処理した時に正しく表示されるようにしています。
。 ```javascript var renderer = new marked.Renderer(); renderer.code = function(code, lang) { // lang 指定が無かったら text にする if (!lang) { lang = 'text'; } // タグをリプレース code = code.replace(/</g, '&lt;').replace(/>/g, '&gt;'); // 1行目が ` で始まっているかどうか確認 params = code.match(/^`(.+)\n/); if (params != null) { // 1行目を削除 code = code.replace(/^`.+\n/, ''); return '
' + code + '
'; } else { return '
' + code + '
'; } }; $('.marked').each(function(i, val) { txt = val.innerHTML.replace(/(\n+)&gt;|^&gt;/g, '$1>'); val.innerHTML = marked(txt, {renderer: renderer}); }); ```

0 件のコメント: