Module: Jpmobile::Emoticon

Defined in:
lib/jpmobile/emoticon.rb,
lib/jpmobile/emoticon/z_combine.rb

Overview

絵文字関連処理

Constant Summary

GETA_CODE =
0x3013
GETA =
[GETA_CODE].pack('U')
SJIS_TO_UNICODE =
{}
UNICODE_TO_SJIS =
SJIS_TO_UNICODE.invert.freeze
SJIS_TO_EMAIL_JIS =

for au email

{0x81ac => 0x222E}
SJIS_REGEXP =
Regexp.union(*SJIS_TO_UNICODE.keys.map{|s| Jpmobile::Util.sjis_regexp(s)})
SOFTBANK_WEBCODE_REGEXP =
Regexp.union(*([/(?!)/n]+SOFTBANK_WEBCODE_TO_UNICODE.keys.map{|x| "\x1b\x24#{x}\x0f"}))
DOCOMO_SJIS_REGEXP =
Regexp.union(*DOCOMO_SJIS_TO_UNICODE.keys.map{|s| Jpmobile::Util.sjis_regexp(s)})
AU_SJIS_REGEXP =
Regexp.union(*AU_SJIS_TO_UNICODE.keys.map{|s| Jpmobile::Util.sjis_regexp(s)})
SOFTBANK_UNICODE_REGEXP =
Regexp.union(*SOFTBANK_UNICODE_TO_WEBCODE.keys.map{|x| [x].pack('U')}).freeze
EMOTICON_UNICODES =
UNICODE_TO_SJIS.keys|SOFTBANK_UNICODE_TO_WEBCODE.keys.map{|k|k+0x1000}
UTF8_REGEXP =
Regexp.union(*EMOTICON_UNICODES.map{|x| [x].pack('U')}).freeze
CONVERSION_TABLE_TO_PC_EMAIL =

for PC conversion “GETA”

Hash[*(CONVERSION_TABLE_TO_SOFTBANK.keys|CONVERSION_TABLE_TO_DOCOMO.keys|CONVERSION_TABLE_TO_AU.keys).map{|k| [k, GETA]}.flatten]
SOFTBANK_SJIS_REGEXP =
Regexp.union(*SOFTBANK_SJIS_TO_UNICODE.keys.map{|s| Jpmobile::Util.sjis_regexp(s)}).freeze
AU_EMAILJIS_REGEXP =
Regexp.union(*AU_EMAILJIS_TO_UNICODE.keys.map{|s| Jpmobile::Util.jis_regexp(s)})
UNICODE_EMOTICONS =

for unicode/google emoticons

(UNICODE_TO_DOCOMO_UNICODE.keys|UNICODE_TO_AU_UNICODE.keys|UNICODE_TO_SOFTBANK_UNICODE.keys).uniq
GOOGLE_EMOTICONS =
(GOOGLE_TO_DOCOMO_UNICODE.keys|GOOGLE_TO_AU_UNICODE.keys|GOOGLE_TO_SOFTBANK_UNICODE.keys).uniq
UNICODE_EMOTICON_REGEXP =
Regexp.union(*UNICODE_EMOTICONS.map{|x| x.kind_of?(Array) ? x.pack('UU') : [x].pack('U')}).freeze
GOOGLE_EMOTICON_REGEXP =
Regexp.union(*GOOGLE_EMOTICONS.map{|x| x.kind_of?(Array) ? x.pack('UU') : [x].pack('U')}).freeze
UNICODE_EMOTICON_TO_CARRIER_EMOTICON =
UNICODE_TO_DOCOMO_UNICODE.merge(UNICODE_TO_AU_UNICODE.merge(UNICODE_TO_SOFTBANK_UNICODE))
GOOGLE_EMOTICON_TO_CARRIER_EMOTICON =
GOOGLE_TO_SOFTBANK_UNICODE.merge(GOOGLE_TO_AU_UNICODE.merge(GOOGLE_TO_DOCOMO_UNICODE))
CONVERSION_TABLE_TO_UNICODE_EMOTICON =
Jpmobile::Util.invert_table(UNICODE_TO_DOCOMO_UNICODE).merge(
Jpmobile::Util.invert_table(UNICODE_TO_AU_UNICODE).merge(Jpmobile::Util.invert_table(UNICODE_TO_SOFTBANK_UNICODE)))
CONVERSION_TABLE_TO_GOOGLE_EMOTICON =
Jpmobile::Util.invert_table(GOOGLE_TO_SOFTBANK_UNICODE).merge(
Jpmobile::Util.invert_table(GOOGLE_TO_AU_UNICODE).merge(Jpmobile::Util.invert_table(GOOGLE_TO_DOCOMO_UNICODE)))
@@pc_emoticon_image_path =
nil
@@pc_emoticon_yaml =
nil
@@pc_emoticon_hash =
nil

Class Method Summary (collapse)

Class Method Details

+ (Object) emoticons_to_image(str)



308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/jpmobile/emoticon.rb', line 308

def self.emoticons_to_image(str)
  if @@pc_emoticon_hash
    utf8_to_unicodecr(str).gsub(/&#x([0-9a-f]{4});/i) do |match|
      img = @@pc_emoticon_hash[$1.upcase] || (@@pc_emoticon_hash[("%x" % ($1.scanf("%x").first - 0x1000)).upcase] rescue nil)
      if img
        "<img src=\"#{@@pc_emoticon_image_path}/#{img}.gif\" alt=\"#{img}\" />"
      else
        ""
      end
    end
  end
end

+ (Object) external_to_unicodecr_au(str)

str のなかでau絵文字をUnicode数値文字参照に置換した文字列を返す。



53
54
55
56
57
58
59
# File 'lib/jpmobile/emoticon.rb', line 53

def self.external_to_unicodecr_au(str)
  str.gsub(AU_SJIS_REGEXP) do |match|
    sjis = match.unpack('n').first
    unicode = AU_SJIS_TO_UNICODE[sjis]
    unicode ? ("&#x%04x;"%unicode) : match
  end
end

+ (Object) external_to_unicodecr_au_mail(in_str)

str のなかでau絵文字をUnicode数値文字参照に置換した文字列を返す。(メール専用)



62
63
64
65
66
67
68
69
70
71
# File 'lib/jpmobile/emoticon.rb', line 62

def self.external_to_unicodecr_au_mail(in_str)
  str = Jpmobile::Util.ascii_8bit(in_str)
  str.gsub(Jpmobile::Util.jis_string_regexp) do |jis_string|
    jis_string.gsub(/[\x21-\x7e]{2}/) do |match|
      jis = match.unpack('n').first
      unicode = AU_EMAILJIS_TO_UNICODE[jis]
      unicode ? Jpmobile::Util.ascii_8bit("\x1b\x28\x42&#x%04x;\x1b\x24\x42"%unicode) : match
    end
  end
end

+ (Object) external_to_unicodecr_docomo(str)

str のなかでDoCoMo絵文字をUnicode数値文字参照に置換した文字列を返す。



44
45
46
47
48
49
50
# File 'lib/jpmobile/emoticon.rb', line 44

def self.external_to_unicodecr_docomo(str)
  str.gsub(DOCOMO_SJIS_REGEXP) do |match|
    sjis = match.unpack('n').first
    unicode = DOCOMO_SJIS_TO_UNICODE[sjis]
    unicode ? ("&#x%04x;"%unicode) : match
  end
end

+ (Object) external_to_unicodecr_google(str)

Google絵文字の変換



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/jpmobile/emoticon.rb', line 118

def self.external_to_unicodecr_google(str)
  str.gsub(GOOGLE_EMOTICON_REGEXP) do |match|
    unicodes = match.unpack('U*')
    unicodes = unicodes.first if unicodes.size == 1

    if emoticon = GOOGLE_EMOTICON_TO_CARRIER_EMOTICON[unicodes]
      case emoticon
      when GETA_CODE
        GETA
      when Integer
        "&#x%04x;" % emoticon
      when String
        emoticon
      end
    else
      # 変換できなければ〓に
      GETA
    end
  end
end

+ (Object) external_to_unicodecr_softbank(str)

strのなかでUTF8のSoftBank絵文字を(+0x1000だけシフトして)Unicode数値文字参照に変換した文字列を返す。



74
75
76
77
78
79
80
# File 'lib/jpmobile/emoticon.rb', line 74

def self.external_to_unicodecr_softbank(str)
  # SoftBank Unicode
  str.gsub(SOFTBANK_UNICODE_REGEXP) do |match|
    unicode = match.unpack('U').first
    "&#x%04x;" % (unicode+0x1000)
  end
end

+ (Object) external_to_unicodecr_softbank_sjis(str)



81
82
83
84
85
86
87
88
# File 'lib/jpmobile/emoticon.rb', line 81

def self.external_to_unicodecr_softbank_sjis(str)
  # SoftBank Shift_JIS
  str.gsub(SOFTBANK_SJIS_REGEXP) do |match|
    sjis = match.unpack('n').first
    unicode = SOFTBANK_SJIS_TO_UNICODE[sjis]
    "&#x%04x;" % (unicode+0x1000)
  end
end

+ (Object) external_to_unicodecr_unicode60(str)

Unicode 6.0絵文字の変換



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/jpmobile/emoticon.rb', line 94

def self.external_to_unicodecr_unicode60(str)
  str.gsub(UNICODE_EMOTICON_REGEXP) do |match|
    unicodes = match.unpack('U*')
    unicodes = unicodes.first if unicodes.size == 1

    if (emoticon = UNICODE_EMOTICON_TO_CARRIER_EMOTICON[unicodes]) == GETA_CODE
      GETA
    elsif emoticon
      case emoticon
      when GETA_CODE
        GETA
      when Integer
        "&#x%04x;" % emoticon
      when String
        emoticon
      end
    else
      # 変換できなければ〓に
      GETA
    end
  end
end

+ (Object) external_to_unicodecr_vodafone(str)



89
90
91
# File 'lib/jpmobile/emoticon.rb', line 89

def self.external_to_unicodecr_vodafone(str)
  external_to_unicodecr_softbank(str)
end

+ (Boolean) pc_emoticon?



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/jpmobile/emoticon.rb', line 288

def self.pc_emoticon?
  if @@pc_emoticon_yaml and File.exist?(@@pc_emoticon_yaml) and @@pc_emoticon_image_path

    unless @@pc_emoticon_hash
      begin
        yaml_hash = YAML.load_file(@@pc_emoticon_yaml)
        @@pc_emoticon_hash = Hash[*(yaml_hash.values.inject([]){ |r, v| r += v.to_a.flatten; r})]
        @@pc_emoticon_image_path.chop if @@pc_emoticon_image_path.match(/\/$/)

        return true
      rescue => ex
      end
    else
      return true
    end
  end

  return false
end

+ (Object) pc_emoticon_image_path



274
275
276
# File 'lib/jpmobile/emoticon.rb', line 274

def self.pc_emoticon_image_path
  @@pc_emoticon_image_path
end

+ (Object) pc_emoticon_image_path=(path)



277
278
279
# File 'lib/jpmobile/emoticon.rb', line 277

def self.pc_emoticon_image_path=(path)
  @@pc_emoticon_image_path=(path)
end

+ (Object) pc_emoticon_yaml



284
285
286
# File 'lib/jpmobile/emoticon.rb', line 284

def self.pc_emoticon_yaml
  @@pc_emoticon_yaml
end

+ (Object) pc_emoticon_yaml=(file)



281
282
283
# File 'lib/jpmobile/emoticon.rb', line 281

def self.pc_emoticon_yaml=(file)
  @@pc_emoticon_yaml = file
end

+ (Object) unicodecr_to_au_email(in_str)

str のなかでUnicode数値文字参照で表記された絵文字をメール送信用JISコードに変換する au 専用



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/jpmobile/emoticon.rb', line 216

def self.unicodecr_to_au_email(in_str)
  str = Jpmobile::Util.ascii_8bit(in_str)
  regexp = Regexp.compile(Jpmobile::Util.ascii_8bit("&#x([0-9a-f]{4});"), Regexp::IGNORECASE)
  str = str.gsub(regexp) do |match|
    unicode = $1.scanf("%x").first
    converted = CONVERSION_TABLE_TO_AU[unicode]

    # メール用エンコーディングに変換する
    case converted
    when Integer
      if sjis = UNICODE_TO_SJIS[converted]
        if email_jis = SJIS_TO_EMAIL_JIS[sjis]
          Jpmobile::Util.ascii_8bit("\x1b\x24\x42#{[email_jis].pack('n')}\x1b\x28\x42")
        else
          Jpmobile::Util.ascii_8bit([sjis].pack('n'))
        end
      else
        match
      end
    when String
      # FIXME: 絵文字の代替が文章でいいかどうかの検証
      Jpmobile::Util.ascii_8bit(Jpmobile::Util.utf8_to_jis(converted))
    else
      match
    end
  end
  regexp = Regexp.compile(Regexp.escape(Jpmobile::Util.ascii_8bit("\x1b\x28\x42\x1b\x24\x42")), Regexp::IGNORECASE)
  str.gsub(regexp, '')
end

+ (Object) unicodecr_to_external(str, conversion_table = nil, to_sjis = true)

str のなかでUnicode数値文字参照で表記された絵文字を携帯側エンコーディングに置換する。

キャリア間の変換に conversion_table を使う。conversion_tablenilを与えると、 キャリア間の変換は行わない。

携帯側エンコーディングがShift_JIS場合は to_sjistrue を指定する。 true を指定すると変換テーブルに文字列が指定されている場合にShift_JISで出力される。



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/jpmobile/emoticon.rb', line 146

def self.unicodecr_to_external(str, conversion_table=nil, to_sjis=true)
  str.gsub(/&#x([0-9a-f]{4});/i) do |match|
    unicode = $1.scanf("%x").first

    if conversion_table
      converted = conversion_table[unicode] # キャリア間変換
    else
      converted = unicode # 変換しない
    end

    # 携帯側エンコーディングに変換する
    case converted
    when Integer
      # 変換先がUnicodeで指定されている。つまり対応する絵文字がある。
      if sjis = UNICODE_TO_SJIS[converted]
        if to_sjis
          sjis_emotion = Jpmobile::Util.sjis([sjis].pack('n'))
        else
          [converted].pack("U")
        end
      elsif webcode = SOFTBANK_UNICODE_TO_WEBCODE[converted-0x1000]
        [converted-0x1000].pack('U')
      elsif converted == GETA_CODE
        # PCで〓を表示する場合
        GETA
      elsif UNICODE_EMOTICONS.include?(converted) or GOOGLE_EMOTICONS.include?(converted)
        if unicode == GETA_CODE
          GETA
        else
          [converted].pack('U*')
        end
      else
        # キャリア変換テーブルに指定されていたUnicodeに対応する
        # 携帯側エンコーディングが見つからない(変換テーブルの不備の可能性あり)。
        match
      end
    when String
      # 変換先が数値参照だと、再変換する
      if converted.match(/&#x([0-9a-f]{4});/i)
        self.unicodecr_to_external(converted, conversion_table, to_sjis)
      else
        # 変換先が文字列で指定されている。
        to_sjis ? Jpmobile::Util.utf8_to_sjis(converted) : converted
      end
    when nil
      # 変換先が定義されていない。
      match
    end
  end
end

+ (Object) unicodecr_to_softbank_email(str)

str のなかでUnicode数値文字参照で表記された絵文字をメール送信用JISコードに変換する softbank 専用



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/jpmobile/emoticon.rb', line 248

def self.unicodecr_to_softbank_email(str)
  str.gsub(/&#x([0-9a-f]{4});/i) do |match|
    unicode = $1.scanf("%x").first
    converted = CONVERSION_TABLE_TO_SOFTBANK[unicode]

    # メール用エンコーディングに変換する
    case converted
    when Integer
      if sjis = SOFTBANK_UNICODE_TO_SJIS[converted-0x1000]
        Jpmobile::Util.sjis([sjis].pack('n'))
      else
        match
      end
    when String
      # FIXME: 絵文字の代替が文章でいいかどうかの検証
      Jpmobile::Util.utf8_to_sjis(converted)
    else
      match
    end
  end
end

+ (Object) unicodecr_to_utf8(str)

str のなかでUnicode数値文字参照で表記された絵文字をUTF-8に置換する。



197
198
199
200
201
202
203
204
205
206
# File 'lib/jpmobile/emoticon.rb', line 197

def self.unicodecr_to_utf8(str)
  str.gsub(/&#x([0-9a-f]{4});/i) do |match|
    unicode = $1.scanf("%x").first
    if UNICODE_TO_SJIS[unicode] || SOFTBANK_UNICODE_TO_WEBCODE[unicode-0x1000]
      [unicode].pack('U')
    else
      match
    end
  end
end

+ (Object) utf8_to_unicodecr(str)

str のなかでUTF-8で表記された絵文字をUnicode数値文字参照に置換する。



208
209
210
211
212
# File 'lib/jpmobile/emoticon.rb', line 208

def self.utf8_to_unicodecr(str)
  str.gsub(UTF8_REGEXP) do |match|
    "&#x%04x;" % match.unpack('U').first
  end
end