Markdown の HTML 変換 - Ruby, PHP, Groovy, Scala, Node.js
Markdown 形式の文字列を HTML 変換する処理を複数のプログラム言語で試してみました。
処理としては、標準入力から UTF-8 の Markdown 形式の文字列を取得し HTML 変換した結果を標準出力へ UTF-8 で出力しています。
ちなみに、Markdown 文字列は LOGGiX プロジェクトの日本語版サンプル markdown-sample.text を使用しました。
サンプルソースは http://github.com/fits/try_samples/tree/master/blog/20120809/
Ruby の場合
Pure Ruby な kramdown モジュールを JRuby で実行してみました。
- JRuby 1.7.0 preview1
- kramdown 0.13.7
tohtml.rb
require 'kramdown' Encoding.default_external = 'utf-8' puts Kramdown::Document.new($stdin.read).to_html
実行例
jruby tohtml.rb < markdown-sample.text > ruby_result.txt
結果
特に問題なく変換されました。
更に kramdown は以下のような表組みにも対応していました。
プログラム言語 | モジュール名 ---------------|------------- PHP | Markdown Ruby | kramdown Groovy | MarkdownJ Scala | knockoff Node.js | markdown
HTML 変換結果は以下の通りです。
<table> <thead> <tr> <th>プログラム言語</th> <th>モジュール名</th> </tr> </thead> <tbody> <tr> <td>PHP</td> <td>Markdown</td> </tr> ・・・ </tbody> </table>
PHP の場合
Markdown Extra をダウンロードし、markdown.php をカレントディレクトリに配置して、実行しました。
- PHP 5.4.4
- Markdown Extra 1.2.5
tohtml.php
<?php include_once "markdown.php"; $mkStr = stream_get_contents(STDIN); echo Markdown($mkStr); ?>
実行例
php tohtml.php < markdown-sample.text > php_result.txt
結果
kramdown と同様、特に問題なく変換され表組みにも対応していました。
Extra の付いていない Markdown 1.0.1o の方は表組みに対応していないのでご注意ください。
Groovy の場合
Java 用のモジュール MarkdownJ を Groovy で使いました。
- Groovy 2.0.0
- MarkdownJ Core 0.4.1
tohtml.groovy
@Grab('com.madgag:markdownj-core:0.4.1') import com.petebevin.markdown.* def mk = new MarkdownProcessor() def enc = 'UTF-8' System.out.withWriter enc, {w -> w.print mk.markdown(System.in.getText(enc)) }
実行例
groovy tohtml.groovy < markdown-sample.text > groovy_result.txt
結果
以下のような問題が発生しました。
- 画像の「リファレンス」スタイル箇所が a タグになった *1
・・・ <p> 「リファレンス」スタイル: ! <a title="Loggix" href="../../../theme/images/loggix-logo.png">Loggix</a> </p>
Scala の場合
Scala は 2種類のモジュールを試してみました。Scala 2.9.2 用のモジュールが見当たらなかったため、2.9.1 用のモジュールを 2.9.2 でスクリプト実行しました。
tohtml.scala (Knockoff 版)
import scala.io._ import com.tristanhunt.knockoff.DefaultDiscounter._ val mkStr = new BufferedSource(System.in)(Codec.UTF8).mkString val ps = new java.io.PrintStream(System.out, false, "UTF-8") ps.println(toXHTML(knockoff(mkStr)))
実行例1 (Knockoff 版)
scala -nc -cp knockoff_2.9.1-0.8.0-16.jar tohtml.scala < markdown-sample.text > scala_result.txt
ここで -nc オプションを指定している点にご注意ください。-nc オプションを付けないとコンパイラのプロセスがリダイレクト先のファイルを開いたままになり不都合が生じます。
結果
以下のような問題が発生しました。
- '=' と '-' の見出しが正しく変換されなかった *2
- 画像の「リファレンス」スタイル箇所が a タグになった
<p>Markdown Sample ======================= </p><p>サンプルドキュメント日本語版 ----------------------- </p>
tohtml2.scala (Actuarius 版)
import scala.io._ import eu.henkelmann.actuarius.ActuariusApp val mkStr = new BufferedSource(System.in)(Codec.UTF8).mkString val ps = new java.io.PrintStream(System.out, false, "UTF-8") ps.println(ActuariusApp(mkStr))
実行例2 (Actuarius 版)
scala -nc -cp actuarius_2.9.1-0.2.3.jar tohtml2.scala < markdown-sample.text > scala_result2.txt
結果2 (Actuarius 版)
Knockoff とは別の問題が発生しました。
- '+' と '-' のリストが正しく変換されなかった
<p>(プラス記号で記述)</p> <p>+ モツァレラチーズ + パスタ + ワイン</p> <p>(ハイフン(マイナス記号)で記述)</p> <p>- モツァレラチーズ - パスタ - ワイン</p>
なお、Scala IO を使うと標準入出力まわりの処理が以下のようになります。
ToHtml.scala
package fits.sample import scalax.io.JavaConverters._ import com.tristanhunt.knockoff.DefaultDiscounter._ object ToHtml extends App { val mkStr = System.in.asUnmanagedInput.slurpString val html = toXHTML(knockoff(mkStr)).mkString System.out.asUnmanagedOutput.write(html) }
Node.js (CoffeeScript) の場合
Markdown-js を npm install markdown でインストールし、CoffeeScript で実行しました。
- Node.js 0.8.0
- CoffeeScript 1.3.3
- Markdown-js 0.4.0
tohtml.coffee
mk = require 'markdown' process.stdin.resume() process.stdin.on 'data', (data) -> console.log mk.markdown.toHTML data.toString()
実行例
coffee tohtml.coffee < markdown-sample.text > coffee_result.txt
結果
以下のような問題が発生しました。
- '=' と '-' の見出しが正しく変換されなかった
- '<' '>' '&' などの不要なエスケープが実施されてしまった
<pre><code><blockquote></code></pre> <p> <p>For example.</p> </blockquote> </p> <h3>HTMLとの共存</h3> ・・・ <p>例:April 1<sup>st</sup>