rcmdnk's blog
Last update

20131012_kramdown_200_200

OctopressのデフォルトのMarkdownパーサーはRDiscount なんですが、 UTF8関連のエラーが結構出て面倒なので Kramdown に変更してみました。

RDiscountの問題

RDiscountで見出しをつけようとした時

Liquid Exception: incompatible character encodings: UTF-8 and ASCII-8BIT in atom.xml

というエラーが出て、 これを対処するためにjekyllの中身を直接変更する必要がありました 1

取り敢えずはこれで良かったんですが、最近Octopressのアップデートを追ってみようと した所、RDiscountのバージョンが1.6.8から2.0.7に変更されていました。

取り敢えずGemfileを2.0.7に書き換えてbundle installしてからrake generate してみると

/octopress/plugins/raw.rb:11:in `gsub': invalid byte sequence in UTF-8 (ArgumentError)

こんな感じでraw.rbがUTF-8周りで嫌がられます。 これも上記の見出しの時のように治せるのかもしれませんが、 そもそもjekyllの中身の方に手を加えるのは余り気持よくないので 手元の方を変えるため、 MarkdownパーサーをRDiscountからKramdownへ変更することにしました。

以前一回断念してますが2、もう一回頑張ってみます。

Kramdownの導入

パーサーの変更

Jekyll(0.12)がKramdownに依存してるので 最近Octopressをインストールしてbundle installしていれば Kramdownもインストールされてるはずなので(bundle listでチェック)。 Gemfile等はそのままでOK3

まず、_config.ymlの中でKramdownを使うように変更します。

1
2
3
4
5
6
-markdown: rdiscount
-rdiscount:
-  extensions: ['generate_toc']
-  # Table Of Contents
-  toc_token: "{:TOC}"
+markdown: kramdown

目次(Table Of Content)の変更

RDiscountでTOCを導入した際に、上の様に{:TOC}と言う表記で 目次を出力してましたが、Kramdownでは

* Table Of Contents
{:toc}

の様に書きます。小文字のtocです。 その上にあるアスタリスクから始まる行は表示されませんし、 書いてある内容はなんでもいい、何も書かなくても

*
{:toc}

これでもOKみたいですが、何故かアスタリスクは必須です 4

TOCから外したいコンテンツがある場合は

# ignore
{:no_toc}

の様にno_tocをコンテンツ直下に書いてあげるとTOCから外してくれます。

Kramdownによって生成されるTOCはリストにmarkdown-tocというidがふられています。

1
2
3
4
5
6
7
8
<ul id="markdown-toc">
  <li><a href="#section">エラー</a></li>
  <li><a href="#section-1">対処法</a></li>
  <li><a href="#raw">キャッシュされる<code>raw</code>のコード</a></li>
  <li><a href="#gist">Gistのページを直接貼り付ける</a></li>
  <li><a href="#rake-clean-">rake cleanの 不具合?</a></li>
  <li><a href="#octopressoctopress25">Octopressのコードの表示@Octopress2.5</a></li>
</ul>

また、hrefには、もしタイトルにアルファベットが含まれてれば 日本語文字を除いたアルファベットだけから、 日本語文字だけだの場合とsectionsection-1section-2…と リファレンス名が付けられていきます。

ulにIDが付いているので、sass/custom/_styles.scss等にこれについて書いておけば

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#markdown-toc{
  margin-left:0;
  li {
    margin-left:1em;
  }
  &:before{
    content:"Contents";
    @extend .heading;
    text-rendering: optimizelegibility;
    font-weight: bold;
    font-size: 1.7em;
    line-height: 2.0em;
  }
}

こんな感じにすればTOCの上にContentsというタイトルが付きます。 線で囲ってみたり、float:right等で文書を回りこましたりしてもOK 5

これまでは{:TOC}の上に

<h1>Contents</h1>

と書いてましたがこれを削除して置き換え。

ちなみに、TOCを入れる様な場合は自分の場合は必ずexcerptする直後に入れるので、 source/_includes/custom/after_excerpt.htmlというファイルを作って 各記事中で

<!-- more -->
{% include custom/after_excerpt.html %}

の様にmoreとセットで入れて居ます。こうしておけばこのファイル内に TOCのことなどちょこちょこ書いておいて全体で一気に変更することが出来るので便利です。

footnote

これまではfootnote-octopress のプラグインを使ってfootnoteを書いてましたが、 このプラグインはRDiscountに依存してるのでそのままでは使えませんが、 70行目辺りのRDiscountを使っている所で

1
2
-ref_text = RDiscount.new("#{text}<a href='#fnref:#{@current_reference}' rev='footnote'>↩</a>").to_html
+ref_text = Kramdown::Document.new("#{text}<a href='#fnref:#{@current_reference}' rev='footnote'>↩</a>").to_html

としてやれば使えます。

ただ、KramdownではPHP Markdown Extra のFootnoteが使える様になっているのでそれも使いたい所。 (RDiscountも2.0.7では同じくこれが使えます。)

[^1]でfootnoteを入れる場所を示し、それ以降に

[^1]: foonote

と言った形で書いておくと最後にまとめてくれます。 内容は記事の途中でもどこに書いてもOKです。

ただし、footnoteを書く際には必ず上に1行空行が必要です。

aaaa[^1]
[^1]: note...

等と書いてしまうときちんと理解されません([^1]やその後がそのまま出力される)。

複数行に渡って書きたい時は、2行目以降は行頭4つスペースを入れます。 基本的に、この4つのスペースが続いている部分を1つのブロック単位と捉える様です。

footnote内にコードを書きたい時は、

[^1]: footnote with code
    write code:

        this is code

    ok.

みたいな感じで、さらに4つ字下げします(この場合は2つでもOKっぽい?)。

リスト(*や1等で書くMarkdown式のリスト)の場合も同じで、 リスト中にコードを書いて、その後同じリストのインデントで再び書きたい時は 上の様な感じで4つ字下げの中で記述します。

取り敢えず今までのものはそのままで、新しい所は この方法で、という感じで良いと思います。

出力されるのもどちらも ノートを挿入する場所は

1
<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup>

実際のノートは

1
2
3
4
5
6
7
<div class="footnotes">
  <ol>
    <li id="fn:1">
      note<a href="#fnref:1" rel="reference">&#8617;</a></p>
    </li>
  </ol>
</div>

こんな感じ。但し、footnote.rbはrel="reference"の代わりに rev='footnote'になっています。(後、最後の矢印が直接書かれている。)

従って、footnote.rbで使っていたsass/plugins/_footnote.scsssource/javascripts/footnote.js もそのまま使いまわせます。

コード

Kramdownではtriple-backtick(```)による 書き方は出来ません6

その代わりPHP Markdown Extraの Fenced Code Block (~~~で囲む)が使えます。

triple-backtickの場合と違ってきっかり3つではなくて、3つ以上、なので、 例えばコードの中に~~~を含みたい時は4つ以上の~で囲ってやれば簡単に出来ます。

KramdownのQuick Reference 等を見るとハイライトも~の右側に言語指定することで簡単に出来る様な事になってますが、 これを使うにはCodeRayというパッケージが必要です。

CodeRay用のテーマを探してくればこのコード部分を自由に変えられて7、 GitHubライクなテーマ8 とかでも遊べるようですが、これらは通常のcodeblockで作るものとは 別物になります。

別々の色や大きさにもできるので、それを良しとすればよいですが、 統一したい場合には下手に書くと違う色になってしまいます。

後、CodeRayで用意されてる言語 が結構少なくて(shが無い!)、 codeblockで使っているPygmentsの方が圧倒的です。

なのでCodeRayの方に完全移行するわけには行かないので、 通常のcodeblockでPygmentsによるハイライトを基本的に使う方がよさそうです。

Triple-backtickの部分は直さないと行けないわけですが、 今後RDiscountに戻るかもと考えると、インデントによる方法に変更して、 ~~~のFenced Code Blockもなるべく使わない様にしようと思います。

インデントコードなどの前後を必ず1行空ける

RDiscountではインデントでコードを書くとき、前後に空行を入れないでも コードだと理解してくれました。

これがKramdownではしてくれません。空行無しでインデントすると そのまま通常の書式で書かれてしまうし、 更に困るのが、下側に空行が無いと通常の文章がコードに巻き込まれます。

これと似たようなことで

  • >での引用表示

も、RDiscountでは上側空いて無くても良かったのが空けないと駄目に。 (下側はRDiscountでも空けないと駄目。)

また、

  • 章節部分(###、特に#の後すぐに##が来るような場合)
  • - - -による横線
  • <hr>による横線

の場合は、下側は続けて書いても大丈夫ですが、上側は必ず空けないといけません。

これらの所が実は一番変更が面倒でした。 RDiscountでも空けておいても何も問題ないし、通常Markdownでは空けるべき所なので 空けて書くようにすべきです。

追記: 2013/10/16

div要素など

RDiscountでは<div>等文章中に書いても そのまま理解していてくれましたが、 Kramdownでは文章途中に書くとこれらはそのまま文章として出力されてしまいます。 (<等が&lt;等になってしまう)

これを回避するためには、div, p, pre…等は必ず行頭に付けます。 それからreferenceを見るとその上を空けないで書いてあるのもあるんですが、 <div>と書く行の上は必ず空行にしないと文章中と同じく理解されて そのまま出力されます。

文章。

<div>...</div>

な感じで必ず1行空ける。ただ、一度<div>等で書き始めた行の中では 再び<div>等を書き込んでも大丈夫(みたい?)。

追記ここまで

まとめ

取り敢えず変更は済みましたが、もし変な所があったら 指摘して頂けるとありがたいですsweat

Sponsored Links
  1. 見出し目次の追加

  2. Octopressでのコードの表示やコメントのあれこれ

  3. もし入ってない場合はGemfileに

    gem 'kramdown'
    

    を書いてbundle install

  4. いくつかKramdownのTOCをの説明を探してを見てたらアスタリスク以降が バラバラなので試しにこの行を外してみたら表示されなくなってしまいました。 で、色々言葉を変えたり全て消してもアスタリスクさえあれば記述されてました。

  5. Generating a Table of Contents in Octopress

  6. Jekyll で GitHub みたいな Triple Backtick を使う。 というのがありましたが、Octopressで素直に出来るか良くわからない。 Filterみたいにしてしまえばいいのかもしれませんが。。。

  7. Octopress and the Twilight Color Scheme

  8. Code-Ray-GitHub-Theme

Sponsored Links

« Octopressでチェック用に高速にgenerate/previewする footnote-extra: Octopress用footnoteのプラグイン »

}