2011年6月15日水曜日

Textile(RedCloth)/Markdown(RDiscount)の利用

軽量マークアップ言語のTextileとMarkdownを利用する。
Wikipediaやwebサイトを調べる。

TextileはオリジナルはPHPで実装されている。
MarkdownはオリジナルはPerlで実装されている。
どちらも
・他の言語で再実装されている。
・BSDライセンス

WikipediaではMarkdownの日本語ページはあるけれど、Textileのは無かった。

Ruby Document format(RD)というのもあるのか。
今まで意識したことはなかった。

Rubyで利用するには、
TextileはRedCloth
MarkdownはRDiscountやBlueCloth

BlueClothのgithubを見ると、bluecloth2.0かrdiscountを使ってと記述がある。

今回はRedClothとrdiscountを使ってみる。
RDiscountとBlueClothで迷ったけれど、GitHubもあるし、最近も更新のあるrdiscountを使ってみる。



RedClothを使う
公式サイトを見る。
http://redcloth.org/

インストールの時の指定方法は、
RedClothと小文字ではなく、大文字のキャメルケースで記述

RedCloth.new("文字列").to_html
で変換する。

記述方法は、
リファレンスページの右目ニューから。
http://redcloth.org/textile/
一覧でページ内リンクで見れると便利だと思うのだけれど。

早速使ってみよう。

RedClothをインストール
gemは前回と同じようにfwifferを使ってプロジェクトを作成する。
$ rvm use 1.9.2@fwiffer
$ rails new wiki_test
$ cd wiki_test
GemfileにRedClothを利用するよう記述してインストール
#Gemfile
gem 'RedCloth'
$ bundle install
RedCloth(4.2.7)の他に、rake(0.9.2)がインストールされた。
rakeがバージョンアップしたのか。

railsのバージョンもアップしているのかな。
$ gem list -r rails
rails(3.0.8)
バージョンアップしている。2週間ほど前は3.0.7だったのに。

バージョン違いで複数インストールできるけど、
バージョンアップっていうのもあるのかな。
gemはupdateコマンドとかありそう。
$ gem update --help
あった。
試しにrailsをアップデートしてみようと思う。
rvmを使っているから、コピーを準備してそこで試してみよう。
$ rvm gemset copy 1.9.2@fwiffer 1.9.2@fwiffer2
Copying gemset from 1.9.2@fwiffer to 1.9.2@fwiffer2
Making gemset for 1.9.2@fwiffer2 pristine.

$ rvm gemset use fwiffer2
$ rvm gemset list
で確認して、
$ gem update rails
あれ?
cucumber、cucumber-railsもアップデートされた。
railsっていう指定が良くなかったのかな?
$ gem list
で確認すると、railsは3.0.7と3.0.8が、
cucumberは0.10.3と0.10.6がインストールされている。
updateというよりも、installしたのと同じだ。

gem updateについて時間を作って今度見てみよう。
fwifferに切り替えて続ける。
$ rvm gemset use fwiffer
RedClothに戻る。
簡単なフォームを作ってRedClothを利用してみる。
$ script/rails generate scaffold diary title:string body:text
$ rake db:migrate
WARNING: Global access to Rake DSL methods is deprecated.  Please include
    ...  Rake::DSL into classes and modules which use the Rake DSL methods.
WARNING: DSL method WikiTest::Application#task called at /home/k10i/.rvm/gems/ruby-1.9.2-p180@fwiffer/gems/railties-3.0.7/lib/rails/application.rb:215:in `initialize_tasks'
毎回やってしまう。rakeが0.9.2になったから対策が違ったりするかな。
herokuはこの間0.9.2だったよな。
#Rakefile
require File.expand_path('../config/application', __FILE__)
require 'rake'

module ::WikiTest
  class Application
    include Rake::DSL
  end
end

module ::RakeFileUtils
  extend Rake::FileUtilsExt
end

WikiTest::Application.load_tasks
修正してmigration
$ rake db:migrate
あれ?出力が出ない。
rvmでgemsetを切り替えるときも何もでなかったよな。
確認。
$ sqlite3 db/development.sqlite3
sqlite> .tables
diaries            schema_migrations
sqlite> .quit
きちんとできている。出力が変なだけだろう。

出力をテストしたいからもう一度migration
$ rake db:migrate
やっぱりなにも表示されない。

別ターミナルを起動させて、試す。
やっぱり何も表示されない。
原因は分からないので、次に進む。

サーバを起動して、記事を登録する。
$ rails server
bodyの部分には、textile形式で記述してみる。
RedClothのトップにある例でテスト。

登録後にbodyの部分はshowページを見ると、改行なしで一行で表示されている。

app/views/diaries/show.html.erbを編集
<%= RedCloth.new(@diary.body).to_html %>
画面を確認すると、変換されている!
ただし、erubisはhをつけないで、デフォルトでHTMLエスケープするからタグがそのまま表示される。
たしか、==がエスケープしないはず。
<%== RedCloth.new(@diary.body).to_html %>
で確認すると、うまく変換されている。

ただ、このままだと、HTMLタグを書き込むと実行されてしまうんじゃないかな?
テストでタグを入力して確認。

jsが実行できた。RedClothに渡す前にエスケープが必要。
hが使える。
<%== RedCloth.new(h @diary.body).to_html %>
確認するとこれでHTMLはエスケープされた。

直接viewに記述したけれど、実際に使うときはヘルパーを作ってあげるとよいと思う。

RedClothは以上。

Rdiscountを使う

次はmarkdownのRuby実装のRDiscountを試す

gemのページを見ると、homepageはどうやらgithubのようだ。

github rdiscount
https://github.com/rtomayko/rdiscount

使い方はRedClothと同じようにnewしてto_htmlする。
HTMLエスケープはfilter_htmlというオプションパラメータがあるのかな?

インストール
Gemfileに追加してインストール
gem 'rdiscount'
$ bundle install
bundle installとbundle updateの違いって何だろう?
bundle update xxxはgem update xxxと同じっぽいな。
http://gembundler.com/man/bundle-update.1.html

続き。
さっきのRedClothで使ったのをそのまま使う。
テストなので、RedClothの表示はもう変更してよいことにしよう。
実際に使うときは、入力時にtextileかmarkdownか選択して表示を変えると良い。

markdown形式の記事を登録する。
body部分は例題で良い。
syntaxはここ。
http://daringfireball.net/projects/markdown/syntax

app/views/diaries/show.html.erbを修正
<%== RDiscount.new(@diary.body).to_html %>
でmarkdown形式で記述。ただしこのままだとやっぱりHTMLエスケープされていない。 :filter_htmlオプションを渡すとエスケープされる。
<%== RDiscount.new(@diary.body, :filter_html).to_html %>
さらに、to_htmlは、smartオプションで置き換えれそう。
...と思ったけれど駄目だった。:smartはどんなオプションなんだろう。

ここに記述があった。
http://rdoc.info/github/rtomayko/rdiscount/master/RDiscount
smartオプションの、Smartyのようなクオート変換が行われるって、どういう事だろう。
本格的に使うときに調べれば良いかな。

RDiscountも以上。

と思ったけれど、両方ともhtmlタグは削除してテキストだけを抜き取る事は出きるのだろうか?
/diariesにアクセスして思った。
調べてみる。

...RedCloth/RDiscountどちらも見つからない。どこかにあるのかな?

RedClothは、指定したタグのみ利用可能になるエクステンションがあった。
http://jeff.jones.be/technology/articles/textile-filtering-with-redcloth/

調べていると、railsのstrip_tags関数でHTMLタグだけ抜き取る事ができるよう。
試してみる。

うまくHTMLタグを削除できた。

RedCloth
<%= strip_tags RedCloth.new(diary.body).to_html %>
RDiscount
<%= strip_tags RDiscount.new(diary.body).to_html %>
HTMLタグを削除するときは、用途にもよるけどhtmlエスケープしないでも良いかも。

以上。

0 件のコメント:

コメントを投稿