From: Kenta Murata Date: 2010-03-03T02:23:06+09:00 Subject: [ruby-dev:40533] Re: [Feature #2833] 絵文字エンコーディングの提案 むらたです。 On 2010/03/02, at 23:12, Yukihiro Matsumoto wrote: > |絵文字に対応したエンコーディングを実装しました。 > |これらを 1.9.2 のリリース前に trunk にマージすることを提案します。 > |redmine のチケットにパッチを添付しました。 > | > |このパッチは以下のエンコーディングを実装しています。 > > エンコーディングを追加することに反対しません。 ありがとうございます。 > |そして、これらのエンコーディング間における fallback なしの > |相互変換を行うための transcoder も実装しています。 > | > |fallback とは、変換先エンコーディングに対応絵文字が存在しない場合に、 > |たとえば "[稲穂]" のようなテキストへ変換する処理をいいます。 > |実用上 fallback 処理をカスタマイズ可能な機構が必要ではありますが、 > |現在の構成でも Encoding::Converter#primitive_convert を用いて対応可能です。 > > このfallbackあり/なしの変換についてもう少し解説していただけ > ませんか? 現在の実装では、例えば DoCoMo 用エンコーディングのみで定義されている 絵文字を含む文字列を KDDI 用エンコーディングへ変換しようとすると、 KDDI 用エンコーディングで未定義の文字で Encoding::UndefinedConversionError が発生するようにしています。 これが、fallback なしの変換です。 fallback ありの場合は、例えば DoCoMo だけで定義されている "\u{E6AD}" (ふくろの絵文字) を KDDI や SoftBank 用のエンコーディングへ変換するときに、 代わりの絵文字で代替させたり "[ふくろ]" のようなテキストで置き換えたりします。 この置換法則は emoji4unicode の成果物である http://www.unicode.org/~scherer/emoji4unicode/snapshot/full.html この表で定義されているものが一般的なんだと思っています。 これが一般的であるという考えは私の推測なので、 実際のところは携帯アプリケーションの開発経験をお持ちの方々に伺いたいです。 以下のような fallback つきのコンバータを標準で提供しておけば、 個々のニーズについては fallback 変換表を gem で配布してもらうだけ 済むかもしれません。 # lib/encoding/fallbacking_converter.rb class Encoding class FallbackingConverter < Converter def initialize(senc, denc, ftab, *opts) super(senc, denc, *opts) unless ftab.respond_to? :[] raise TypeError, "fallback table should have [] method" end @fallback_table = ftab end def fallbacking_convert(src) senc = self.source_encoding dst = '' while true case self.primitive_convert(src, dst) when :invalid_byte_sequence raise InvalidByteSequenceError when :undefined_conversion undef_char = self.primitive_errinfo[3].force_encoding(senc) if fallback = @fallback_table[undef_char] self.insert_output(fallback) else raise UndefinedConversionError end else break end end return dst end end end # 使用例としてのテストケース class TestFallback < Test::Unit::TestCase def setup @utf8_docomo = utf8_docomo("\u{E6AD}") @utf8_fallbacked_kddi = utf8_kddi("[\u{3075}\u{304f}\u{308d}]") # [ふくろ] @converter = Encoding::FallbackingConverter.new( "UTF8-DoCoMo", "UTF8-KDDI", @utf8_docomo => @utf8_fallbacked_kddi ) end def test_fallbacking_convert_for_non_emoji assert_equal utf8_kddi("\u{3075}"), @converter.fallbacking_convert(utf8_docomo("\u{3075}")) end def test_fallbacking_convert_for_emoji assert_equal @utf8_fallbacked_kddi, @converter.fallbacking_convert(@utf8_docomo) end end -- Kenta Murata OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC 本を書きました!! 『Ruby 逆引きレシピ』 http://www.amazon.co.jp/dp/4798119881/mrkn-22 E-mail: mrkn@mrkn.jp twitter: http://twitter.com/mrkn/ blog: http://d.hatena.ne.jp/mrkn/