act-emoticon.rb
Qwikに絵文字を表示するプラグインを作成してみる。
手順
- act-emoticon.rbとしてソースを
/lib/qwik下に保存 - 絵文字ファイルを
/lib/theme/images/emoticons/ 下に用意 - Jive Emoticons という画像がおすすめだがダウンロードできないhttp://jivesoftware.com/downloads-other.jsp
- {{emoticon hello:)}}等のように使う。複数行対応済。
感想
- 単純な文字列の置き換えだろうとたかをくくっていたら意外とてこずる。正規表現に引っかかる文字列のエスケープ、Wabisabi構造の生成、正規表現パターン生成など。
- if elseの羅列や、str.scan, str.gsubの繰り返しにしたくなかったので、正規表現で一発でマッチングさせるようにした。しかし、非マッチ文字列を強引にPOPさせるために苦しい定義に。しかも、パターンマッチした後再度置き換え操作でHashを見に行ってしまっている。
- 正規表現で|(並列)記号でパターンを羅列するときに、優先度を設定できるといいのに
- パターンがマッチしたときに、マッチ文字列を返す前に、プロしジャーをそのまま呼び出せるといいのに(JavaccやRaccのようなイメージ)
- でもそこまでやると正規表現でコンパイラ作れちゃうな、、だったらコンパイラでやれってことか、、
- 鬼車という正規表現エンジンが面白そう(上記の事は今は出来るわけじゃないが) ruby 1.9で標準装備だとか http://www.geocities.jp/kosako3/oniguruma/ ちょっとソースなどを見てみよう
- テストコードを先に書くのはなかなかなれないとつらい
- qwikは楽しい
act-emoticon.rb ソース
$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib") module Qwik class Action def plg_emoticon(text_arg=nil) initializeEmoticons unless defined? @emoticons ar = [] if text_arg then ar.push(*text_arg.scan(@emoticon_regex)) else text = yield text.each{|line| ar.push(*line.scan(@emoticon_regex)) } end ret = [] ar.each{|item| if @emoticons.member?(Regexp.escape(item.to_s)) then ret << [:img,{:src=>".theme/images/emoticons/"+@emoticons[Regexp.escape(item.to_s)]+".gif"}] else ret << item.to_s end } ret end def initializeEmoticons @emoticons = Hash.new @emoticons[Regexp.escape(">(")]="angry" @emoticons[Regexp.escape("*^_^*")]="blush" @emoticons[Regexp.escape("`:|")]="confused" @emoticons[Regexp.escape("])")]="cool" @emoticons[Regexp.escape(":'(")]="cry" @emoticons[Regexp.escape("})")]="devil" @emoticons[Regexp.escape(":D")]="grin" @emoticons[Regexp.escape(":)")]="happy" @emoticons[Regexp.escape("(D")]="laugh" @emoticons[Regexp.escape("<3")]="love" @emoticons[Regexp.escape(";7)")]="mischief" @emoticons[Regexp.escape(":|")]="plain" @emoticons[Regexp.escape(":(")]="sad" @emoticons[Regexp.escape(":O")]="shocked" @emoticons[Regexp.escape(":P")]="silly" @emoticons[Regexp.escape(";)")]="wink" @em_reg_arr = [] @emoticons.keys.each{|key| @em_reg_arr<<key} @emoticon_regex = Regexp.compile("("+@em_reg_arr.join("|")+")|(\\w+)|(\s+)|(\\W+)") # @emoticon_regex = Regexp.compile("("+@em_reg_arr.join("|")+")|(.)") end end end if $0 == __FILE__ require "qwik/test-common" $debug = true end if defined?($debug) && $debug class TestActEmoticon < Test::Unit::TestCase include TestSession def test_plg_happy ok_wi( [:img,{:src=>".theme/images/emoticons/happy.gif"}], "{{emoticon(:))}}") ok_wi( [:img,{:src=>".theme/images/emoticons/grin.gif"}], "{{emoticon(:D)}}") ok_wi( [:img,{:src=>".theme/images/emoticons/love.gif"}], "{{emoticon(<3)}}") end end end