Ghost Blogにテーブル表示を追加する

Ghost Blog は MarkdownレンダリングにShowdownモジュールを利用しているが、何故かそれに含まれるtable拡張を利用していない。幾度か要望がでたり議論もあったりしたのだが、一向に進展しないためテーマレベルで代替策を講じることにしてみた。


jquery.ex-mark-table.js

このスクリプトはjQuery Extensionになっていて、ロードすると jQuery.markTable() メソッドが追加される。これはMarkdown形式のtable書式を含むオブジェクトを渡してやるとHTML-Tableにオンデマンドで整形する。

これをさらに次のようにしてindex.js等から呼び出す。1

呼び出しサンプル
(function pageInit () {
    $('code[class^="language-"]').each(function () {
        var $this = $(this);
        var attr = $this.attr('class').replace(/^language-?/, '');
        var match = attr.match(/title:(.*)/);
        if (match) {
            $this.parent().attr('title', match[1]);
            attr = attr.replace(/title:.*/, '');
        }
        if (attr != null && attr.match(/^table/)) {
            // マークダウンテーブル
            $this.parent().html($this.html()).markTable();
        }
    });
})();

Markdownの方では、ネイティブにMarkdownテーブル書式を書くことが出来ないので、全体をコード書式で括るようにする。このとき三連バッククォート2の直後にtableというキーワードを付与する。更にtaitle:キーワードを足すとここから行末までをテーブルキャプションにすることが出来る。3

```table title:テーブルキャプション
|foo |bar   |baz  |
|:---|:----:|----:|
|Left|center|right|
```

これを保存するとGhostは次のHTMLコードに変換する。

{gfm-js-extract-pre-1}

付与したキーワードにlanguage-前置詞が付いたclass名として埋め込まれるのがミソで、ようはこれをjQueryで検出してクライアントサイドでpreをまるごとtableセットに書き換えてやる。あとはCSSで表示を整形4してやればよい。

テーブルキャプション
foo bar baz
Leftcenterright

これの実際のHTMLはつぎのように展開されている。

<div class="mark-table">
  <table>
    <caption>テーブルキャプション</caption>
    <thead>
      <tr>
        <th class="left">foo </th>
        <th class="center">bar   </th>
        <th class="right">baz  </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="left">Left</td>
        <td class="center">center</td>
        <td class="right">right</td>
      </tr>
    </tbody>
  </table>
</div>

今後ネイティブにMarkdownテーブル記法が実装された場合は(本実装との互換性はともかく)三連バッククォートを除去するだけで対応できるはずだ。


  1. 実際のコードではここで同時に SyntaxHighliter の変換処理も行っている。

  2. プレビュー内容が改行なしで詰め込み表示になるのを避けるため、コードブロックで括るようにした。現状、これ以外の方法で改行をプレビューに反映させることはできない。

  3. class名としてHTMLに埋め込まれる都合上、titleにダブルクォートは記述できない。

  4. markTable()のオプションにtableタグのclassNameを指定でき、省略値はtable.mark-tableになっている。

RECENT LINKS