Pelican ブログで Github-Flavored-Markdown を使う


この記事は古いので無視してね！
=======
redtree様からのご指摘により、現在の Pelican はデフォルトで github スタイルのコードブロック記法が使えるようになっていることを知りました。

ということなのでこの記事の内容は無視してください！
Pelican 最高！

はじめに
======

ぼくはブログを書くツールとして Pelican を使っています。
ところで、子供の頃、庭に出るといきなり目の前にペリカンがいたことがありました。
呆気にとられているぼくの目の前で、ペリカンは「ガー」と鳴いてパタパタと飛んでいきました。

そのことを人に話しても、誰にも信じてもらえず悔しい思いをしていましたが、
時が経って記憶が薄れてくると、自分でも、
「あれは本当にペリカンだったのだろうか。ペリカン便の見間違いではなかろうか」
などと思うこともあります。

さて、Pelican ブログは Markdown 記法を使って書くことができますが、
特にソースコードをいっぱい書く人は、素の Markdown より
Github-Flavored-Markdown (GFM) の方が
慣れているので書きやすいという人も多いのではないかと思います。

残念ながら、通常は GFM を使うことはできません。

Python には misaka という GFM 記法を使えるライブラリがあるので、それを使えるようにしてみます。

ソースコードを修正する
================

無意味に長い「はじめに」を読んでくれた人には申しわけないのですが、
ぶっちゃけ、かなりやっつけの修正になります。
本来はプラグインなどで実現すべきことだと思いますが、面倒くさくて。

ちなみに Python のバージョンは、Pelican が推奨してる 2.7 で試してます。
OS は Mac OS 10.9 です。


misaka のインストール
------------------------------
pipでインストールします。

```
$ pip install misaka
```

ソース修正
------------

Markdown のパースは、`readers.py` というファイルの中で実行されるので、
そのファイルを直でいじってしまいます。

どこにファイルがあるか分からなければ、`pip show` で探しましょう。

```
(pelican)comme@garcons$ pip show pelican                                                                   
---
Name: pelican
Version: 3.3
Location: /Users/comme/.virtualenvs/pelican/lib/python2.7/site-packages
Requires: feedgenerator, jinja2, pygments, docutils, pytz, blinker, unidecode, six
```

location で表示されたディレクトリの、`pelican` ディレクトリの中に、`readers.py` があります。

19行目くらいのここを修正

```python
try:
    from markdown import Markdown
except ImportError:
    Markdown = False  # NOQA
```

↓こう修正する

```python
try:
    from markdown import Markdown
    import misaka
    import pygments
except ImportError:
    Markdown = False  # NOQA
```

215行目あたりのここを修正

```python
    def read(self, source_path):
        """Parse content and metadata of markdown files"""

        self._md = Markdown(extensions=self.extensions)
        with pelican_open(source_path) as text:
            content = self._md.convert(text)

        metadata = self._parse_metadata(self._md.Meta)
        return content, metadata
```

↓こう修正する

```python
    def read(self, source_path):
        """Parse content and metadata of markdown files"""

        self._md = Markdown(extensions=self.extensions)
        with pelican_open(source_path) as text:
            content = self._md.convert(text)

        metadata = self._parse_metadata(self._md.Meta)
   
        renderer = self.BleepRenderer()
        misaka_md = misaka.Markdown(renderer,
            extensions=misaka.EXT_FENCED_CODE | misaka.EXT_NO_INTRA_EMPHASIS)
        with pelican_open(source_path) as text:
            misaka_content = misaka_md.render(text)

        return misaka_content, metadata

    class BleepRenderer(misaka.HtmlRenderer, misaka.SmartyPants):
        def block_code(self, text, lang):
            if not lang:
                return '\n<pre><code>%s</code></pre>\n' % escape(text.strip())
            lexer = pygments.lexers.get_lexer_by_name(lang, stripall=True)
            formatter = pygments.formatters.HtmlFormatter()
            return pygments.highlight(text, lexer, formatter) 
```


おしまい。

これで、kobito や github と同じように、

    ```python
    def func():
        print('uuuuuuuuuuwaaaaaaaaaaaaaaaaaaahhhhhhhh')
    ```

みたいに書いて、`make html` すれば期待通りの html ができます。

diff
-----

```diff
--- a/readers.py
+++ b/readers.py
@@ -18,6 +18,8 @@ except ImportError:
     docutils = False
 try:
     from markdown import Markdown
+    import misaka
+    import pygments
 except ImportError:
     Markdown = False  # NOQA
 try:
@@ -215,7 +217,22 @@ class MarkdownReader(BaseReader):
             content = self._md.convert(text)

         metadata = self._parse_metadata(self._md.Meta)
-        return content, metadata
+
+        renderer = self.BleepRenderer()
+        misaka_md = misaka.Markdown(renderer,
+            extensions=misaka.EXT_FENCED_CODE | misaka.EXT_NO_INTRA_EMPHASIS)
+        with pelican_open(source_path) as text:
+            misaka_content = misaka_md.render(text)
+
+        return misaka_content, metadata
+
+    class BleepRenderer(misaka.HtmlRenderer, misaka.SmartyPants):
+        def block_code(self, text, lang):
+            if not lang:
+                return '\n<pre><code>%s</code></pre>\n' % escape(text.strip())
+            lexer = pygments.lexers.get_lexer_by_name(lang, stripall=True)
+            formatter = pygments.formatters.HtmlFormatter()
+            return pygments.highlight(text, lexer, formatter)


 class HTMLReader(BaseReader):
```