Google App Engine(Python)でどう絵文字を扱うか悩む

Google App Engine上のサービスで絵文字対応をしたい。2010年12月現在。

「各キャリアで書き込んだ文字列が、そのまま表示される。」「他キャリアで書き込んだ文字列が、なるべく再現できる。」の2つを実現したい。 django-bpmobileでは、au/softbankの絵文字をすべてDoCoMoの絵文字に変換している。変換できない絵文字はそのままのようだ。 django-bpmobileのアプローチでは、前者の条件は満たすが、後者の条件は満たせないと思う。

emoji-pythonライブラリを使うという手もある。 http://code.google.com/p/emoji-python/ しかし、Unicode 6.0では絵文字の一部が含まれたとのことで、できればUnicode側のコードポイントを使いたい。 タグの開き文字・閉じ文字に工夫が必要な点も気になる。

django-bpmobileでは、DoCoMoの絵文字コードとの変換テーブルに、emoji4unicodeプロジェクトの成果を利用している。 PerlのEncode::JP::Emojiモジュールでも、同プロジェクトの変換テーブルを利用している。

emoji4unicodeプロジェクトでは、xml形式で絵文字変換テーブルを提供している。それをパースするPythonスクリプトも提供されている。 変換テーブルは以下のようなスクリプトで簡単に取り出せる。

#!/usr/bin/python
from e4u import emoji4unicode as e4u_google

e4u_google.Load()

def describe_code(code_table, carrier):
  print 'carrier: %s' % carrier
  code_str = code_table[carrier]
  if code_str[0] == '>':
    code_str = code_str[1:]
  if code_str:
    codes = ''
    for code_char in code_str.split('+'):
      symbol = e4u_google.all_carrier_data[carrier].SymbolFromUnicode(code_char)
      print {
        'number'    : symbol.number,
        'new_number': symbol.new_number,
        'old_number': symbol.old_number,
        'jis'       : symbol.jis,
        'shift_jis' : symbol.shift_jis,
        'uni'       : symbol.uni,
        'english_name': symbol.GetEnglishName(),
        'japanese_name': symbol.GetJapaneseName(),
        'image_html': symbol.ImageHTML(),
      }
    return codes
  return ''

def main():
  for e in e4u_google._doc.getElementsByTagName('e'):
    # convert to normal dict
    d = {}
    for k, v in e.attributes.items():
      d[k] = v
    print '*' * 40
    print d
    for carrier in ['docomo', 'kddi', 'softbank', 'google']:
      if d.has_key(carrier):
        describe_code(d, carrier)

main()

emoji4unicodeでは、Googleが内部で用いている絵文字コードとの変換表もある。この絵文字コードを採用すればいいのではないか。「Google」App Engineだし。 その場合、以下の3つが実現できればよい。 1. 各キャリアから送られる、絵文字を含んだ文字列(Shift-JIS or UTF-8)を、Googleの絵文字コードを用いたUTF-8の文字列に変換する。 2. Googleの絵文字コードを含んだUTF-8文字列を、各キャリアの絵文字コードや数値参照、タグを含んだ文字列に変換する。 3. Googleの絵文字コード、もしくは絵文字の名前を属性に持つ特殊な文字列をテンプレートに書けば、2.と同様の変換を行って表示する。

上記のスクリプトを改造して、これらの変換は実現できるだろう。PerlのEncode::JP::Emojiモジュールでも同様の変換を行い、Perlスクリプトを出力している。 Perlの場合は、trで正規表現を用いて高速に変換を行っているが、Pythonのstring.maketransはPerlのtrほど表現力はないはず。検索だけは正規表現を使うか。

Googleの絵文字コードには、現在3つの問題がある。 1. Unicodeの第15面にある私用領域(PUA)にマッピングされている。コードの範囲は、U+F0000からU+FFFFD。よって、UTF-8では4byteとなる。古いMySQLでは、保存ができない。 2. U+FEB64について、Unicode 6.0にて対応するコードポイントが2つ存在する。 3. emoji4unicodeに、willcomの絵文字との変換表がない。

1.については、MySQL 5.5.3から導入されたutf8mb4というcharsetを用いればよい。今回は、Google App Engineを用いるので、保存については問題ないだろう。 2.については、Unicode/Google絵文字コードの相互変換を行わなければさほど問題はなさそうだが、将来emoji4unicodeのマッピングが変更された場合、softbankでU+E21Aの文字列を入力した際の変換先が異なる可能性がある。なんとなくやだなー。 3.については、自らマッピングを作成するしかないだろう。

結局は、emoji-pythonライブラリで使われている、キャリア名+絵文字番号という表現形式を、1対1でUnicodeの私用領域に収めるのがいいという印象。 Unicode 6.0ですべての絵文字が採択されれば、似たような絵文字がまとめられるのもよかったかもしれないけど。 んでも、emoji-pythonもwillcomの絵文字マッピングはないのね。

絵文字対応したいという気持ちがだんだん萎えてきた!うおおお←いまここ