Markdown 処理系の比較
Markdown の基本文法は Markdown。
PHP Markdown Extra にいくつか拡張文法が定義されている。PHP Markdown という名前だけど、他の Markdown 処理系でもこのうちのいくつかが実装されている。
拡張機能の比較
- no intra emphasis
- 単語区切りのアンダースコアで斜体にしない
- tables
- PHP Markdown Extra 参照
- fenced code blocks
- GFM 参照
- autolink
<と>で囲まなくても URL を自動的にリンクにする。なくても必要なときに<と>を囲むだけ- hard wrap
- 段落中の改行を
<br>に変換する。なくても 2 つ以上のスペースで行を終わればいいだけ - definition lists
- PHP Markdown Extra 参照
- syntax highlighting
- Pygments や CodeRay を用いる
| extras \ library | Sundown 系 | Python-Markdown | python-markdown2 | cMarkdown |
|---|---|---|---|---|
| no intra emphasis | YES | YES (3) | YES | YES (3) |
| tables | YES | YES | NO | NO |
| fenced code blocks | YES | YES | YES | YES |
| autolink | YES | NO | NO | YES |
| hard wrap | (1) | YES | NO | YES |
| definition lists | NO (2) | YES | NO | NO |
- (1) Redcarpet と misaka は対応、Robotskirt は未対応
- (2) 一応、対応検討中?
- (3) デフォルトで YES
Sundown
- C で書かれた Markdown 処理系
-
複数の言語のバインディングがある
- Redcarpet
- Ruby バインディング
- Robotskirt
- Node バインディング
- misaka
- Python バインディング
Python-Markdown
- Pure Python
python-markdown2
- Pure Python
- Python-Markdown より速くて正確って作者は言ってる
cMarkdown
- upskirt の Python バインディング
- upskirt は Sundown の古いバージョン
- Unicode 非対応
- cMarkdown を選ぶなら misaka でいいと思う
ベンチマークによる比較
Python用のMarkdownを扱うモジュールを比較してみた参照。
python-markdown2 は Python-Markdown より確かに速いけど Sundown 系に比べるとずっと遅い。
コマンドラインサポート
すべてのライブラリで、コマンドラインで使うためのスクリプトが用意されている。でもカスタマイズ性に乏しい。
シンタックスハイライト
フラグでシンタックスハイライトを有効にできるのは Python-Markdown と python-markdown2 だけ。
Redcarpet
#!/usr/bin/env ruby
require 'redcarpet'
require 'pygments'
# from https://github.com/vmg/redcarpet
class HTMLwithPygments < Redcarpet::Render::HTML
def block_code(code, language)
Pygments.highlight(code, :lexer => language)
end
end
parse_extensions = {
:no_intra_emphasis => true,
:tables => true,
:fenced_code_blocks => true,
:autolink => true
}
render_extensinos = {
:hard_wrap => true
}
STDOUT.write Redcarpet::Markdown.new(HTMLwithPygments.new(render_extensinos),
parse_extensions).render(ARGF.read)
で <div class="highlight"><pre>...</pre></div> なコードブロックが生成される。
misaka
#!/usr/bin/env python
import codecs
import sys
import houdini as h
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
import misaka
# from http://misaka.61924.nl/manual/
class BleepRenderer(misaka.HtmlRenderer, misaka.SmartyPants):
def block_code(self, text, lang):
if not lang:
return '\n<pre><code>%s</code></pre>\n' % \
h.escape_html(text.strip())
lexer = get_lexer_by_name(lang, stripall=True)
formatter = HtmlFormatter()
return highlight(text, lexer, formatter)
extensions = (misaka.EXT_NO_INTRA_EMPHASIS |
misaka.EXT_TABLES |
misaka.EXT_FENCED_CODE |
misaka.EXT_AUTOLINK |
misaka.HTML_HARD_WRAP)
if len(sys.argv) > 1:
text = codecs.open(sys.argv[1], 'r', encoding='utf-8').read()
else:
text = sys.stdin.read().decode(sys.stdin.encoding or 'utf-8')
sys.stdout.write(misaka.html(text, extensions=extensions)
.encode(sys.stdout.encoding or 'utf-8'))
で <div class="highlight"><pre>...</pre></div> なコードブロックが生成される。lang 指定なしの場合は <pre><code>...</code></pre>(でもこれは BleepRenderer の定義次第)。
Python-Markdown
Pygments をインストールして codehilite を指定すればシンタックスハイライトされて、<div class="codehilite"><pre>...</pre></div> なコードブロックが生成される。
css クラス名を変更するにはコードを書く必要がある。
#!/usr/bin/env python
import codecs
import sys
import markdown
if len(sys.argv) > 1:
text = codecs.open(sys.argv[1], 'r', encoding='utf-8').read()
else:
text = sys.stdin.read().decode(sys.stdin.encoding or 'utf-8')
sys.stdout.write(
markdown.markdown(
text,
extensions=['tables', 'fenced_code', 'codehilite', 'nl2br', 'def_list'],
extension_configs={'codehilite': {'css_class': 'highlight'}})
.encode(sys.stdout.encoding or 'utf-8'))
python-markdown2
Pygments がインストール済みで fenced-code-blocks を指定すれば自動的にシンタックスハイライトされて<div class="codehilite"><pre><code>...</code></pre></div> なコードブロックが生成される(<code> タグあり)。
css クラス名を変更するにはコードを書く必要がある。
#!/usr/bin/env python
import codecs
import sys
import markdown2
if len(sys.argv) > 1:
text = codecs.open(sys.argv[1], 'r', encoding='utf-8').read()
else:
text = sys.stdin.read().decode(sys.stdin.encoding or 'utf-8')
sys.stdout.write(
markdown2.markdown(
text,
extras={'code-friendly': 1,
'fenced-code-blocks': {'cssclass': 'highlight'}})
.encode(sys.stdout.encoding or 'utf-8'))