Simplenote でブックマークレットで GitHub Flavored Markdown (GFM)

## 最初に
Evernote で Markdown 記法を使いたくて使えなくて震えてる方が、2015/12/06 (日) 現在も一定数いるのではないでしょうか。

> 「evernote markdown」のYahoo!検索（リアルタイム） - Twitter（ツイッター）、Facebookをリアルタイム検索
> http://realtime.search.yahoo.co.jp/search?p=evernote+markdown


## Markdown 記法を使って Evernote のようにメモをとりたい
選択肢はいくつかあるようです。
その内の１つ、Simplenote ( http://simplenote.com/ ) は以下のような特徴をもったウェブサービスです。

* WordPress で有名な Automattic 社が運営している
* ウェブ上でノートの追加・削除・編集が行える
* Markdown 記法をサポートしている ← <font color='darkorange'>★★★</font>


## Simplenote の Markdown
これで快適な Markdown 生活をー…と思ったところ、Simplenote は基本的な記法のみをサポートし、GitHub Flavored Markdown (GFM) 記法をサポートしていない様子です。

### GFM 記法で記載した場合の一例（2015/12/05 (土) 確認）

#### 1.ノートに記載した Markdown テキスト
<pre>
```perl
$sum = 0;
for ($i = 0; $i &lt; 10; $i++) {
  $sum += $i;
}
print $sum;
```
</pre>

#### 2.Markdown テキストから生成された HTML

```
<p>```perl
$sum = 0;</p>
<p>for ($i = 0; $i &lt; 10; $i++) {
  $sum += $i;
}</p>
<p>print $sum;
```</p>
```

#### 3.HTML をもとに画面に描画したテキスト

```
```perl $sum = 0;
for ($i = 0; $i < 10; $i++) { $sum += $i; }
print $sum; ```
```


## Simplenote で GFM を使いたい
本題です。
タイトルのように Simplenote 用ブックマークレットを追加して対応しようと思います。
補足として Simplenote の Markdown 記法モードは以下のように動作します。

### Simplenote の Markdown その2
* 以下のように「表示箇所 (static_content)」と「編集箇所 (txtarea)」の表示・非表示を切り替えることで、モードを切り替えています。

```
<div id="static_content" style="display: block;">...</div>
<textarea id="txtarea" style="display: none;"></textarea>
```

* 「編集箇所 (txtarea)」の Markdown テキストをコンパイルして、「表示箇所 (static_content)」に反映させています。


### 追加するブックマークレット
今回は marked.js を利用して、Markdown テキストを別途コンパイルし、Simplenote 側でのコンパイル結果を上書きします。

```js:sn-bookmarklet.user.js
// ==UserScript==
// @name        sn-bookmarklet
// @namespace   https://yourhost.name/
// @version     1.0
// @description sn-bookmarklet
// @include     https://app.simplenote.com/*
// ==/UserScript==

(function(callback) {
    'use strict';

    // Markdown コンパイラ marked.js
    var scriptMarkedJs = document.createElement('script');
    scriptMarkedJs.src = '//cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js';
    scriptMarkedJs.type = 'text/javascript';
    document.head.appendChild(scriptMarkedJs);

    // シンタックスハイライター highlight.js
    var scriptHighlightJs = document.createElement('script');
    scriptHighlightJs.src = '//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js';
    scriptHighlightJs.type = 'text/javascript';
    document.head.appendChild(scriptHighlightJs);

    // highlight.js シンタックスハイライトテーマ
    var linkHighlightCss = document.createElement('link');
    linkHighlightCss.href = '//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/tomorrow-night-bright.min.css';
    linkHighlightCss.media = 'all';
    linkHighlightCss.rel = 'stylesheet';
    linkHighlightCss.type = 'text/css';
    document.head.appendChild(linkHighlightCss);

    // page context の window.marked を参照してイベントリスナーを登録
    var script = document.createElement('script');
    script.textContent = '(' + callback.toString() + ')();';
    document.body.appendChild(script);

})(function() {

    var compileMarkdown = function() {
      var myRenderer = new marked.Renderer();

      if (!marked.hasCustomOptions) {
        marked.setOptions({
          highlight: function(code) {
            return hljs.highlightAuto(code).value;
          },
          langPrefix: 'hljs ',
          renderer: myRenderer
        });

        marked.hasCustomOptions = true;
      }

      // marked.js でコンパイル
      var markdownText = document.getElementById('txtarea').value;
      var highlightHTML = marked(markdownText);

      // Simplenote 側で生成した HTML を上書き
      var staticContent = document.getElementById('static_content');
      staticContent.innerHTML = highlightHTML;
    };

    // Preview ボタンクリック時に、コンパイル実行
    var previewButton = document.getElementById('view_mode_markdown');
    previewButton.addEventListener('click', compileMarkdown);
});
```

### 対応結果
GFM な Markdown テキストを記載し Preview ボタンをクリックすると、
<pre>
```perl
$sum = 0;

for ($i = 0; $i &lt; 10; $i++) {
  $sum += $i;
}

print $sum;
```

|title1|title2|title3|
|-|-|-|
|value1|value2|value3|
</pre>

GFM を考慮した HTML が出力されました。

```
<pre>
<code class="hljs perl">
<span class="hljs-variable">$sum</span> = <span class="hljs-number">0</span>;

<span class="hljs-keyword">for</span> (<span class="hljs-variable">$i</span> = <span class="hljs-number">0</span>; <span class="hljs-variable">$i</span> &lt; <span class="hljs-number">10</span>; <span class="hljs-variable">$i</span>++) {
  <span class="hljs-variable">$sum</span> += <span class="hljs-variable">$i</span>;
}

<span class="hljs-built_in">print</span> <span class="hljs-variable">$sum</span>;
</code>
</pre>
<table>
<thead>
<tr>
<th>title1</th>
<th>title2</th>
<th>title3</th>
</tr>
</thead>
<tbody>
<tr>
<td>value1</td>
<td>value2</td>
<td>value3</td>
</tr>
</tbody>
</table>
```

見た目はこんな感じ
![screenshot.jpeg](https://qiita-image-store.s3.amazonaws.com/0/58153/fa888a82-88a1-567a-127b-4404764aeb4c.jpeg)


## 参考
* marked.js : https://github.com/chjj/marked
* highlight.js : https://highlightjs.org/
* tomorrow-night-bright.css : http://jmblog.github.io/color-themes-for-highlightjs/tomorrow-night-bright/