# -------------------------------------------------------------------- # # EmojiTrans.pm -- Emoji Translator # Copyright 2004-2005 Kawasaki Yuusuke # -------------------------------------------------------------------- # # 2004/09/22 KHandle.pm から分離 # 2004/10/01 Vodafone 絵文字対応強化 # 2004/10/18 Vodafone 絵文字コードを 〜 に変更 # 2004/10/21 KEmoji.pm から分離 # 2004/10/22 ドコモ標準絵文字機種判定追加 # 2004/10/24 一覧表を EmojiTransMap.txt に分離 # 2004/11/07 POD を少し整備しました # 2004/12/01 UP.Browser/6.0.x ではドコモ→EZネイティブ変換しない # 2005/02/02 Vodafone 3G携帯に対応 # -------------------------------------------------------------------- # package EmojiTrans; # パッケージ名は EmojiTrans use strict; use integer; use vars qw( $VERSION $DEBUG ); # ---------------------------------------------------------------- $VERSION = "0.01"; # -------------------------------------------------------------------- # =head1 NAME EmojiTrans -- Emoji Translator =head1 DESCRIPTION use EmojiTrans; EmojiTrans::translate( \$str, $ENV{HTTP_USER_AGENT} ); 第1引数で、変換対象文字列へのリファレンスを指定します。 絵文字は予め &#xHHHH; 表記にしておく必要があります。 EmojiTrans.pm モジュール単体ではバイナリ形式の絵文字は処理できませんので、 予め EscapeSJIS.pm モジュールの escape 関数などを利用して バイナリコードを &#xHHHH; 表記に変換しておく必要があります。 なおドコモ絵文字については、&#ddddd;(Shift_JISの10表記)も利用できます。 文字コードは EUC-JP、Shift_JIS、UTF-8 が利用可能です。(指定不要) 第2引数で、変換先のブラウザ名を指定します。 各キャリアごとに下記のような変換処理となります。 ドコモ標準絵文字機種 - 拡張絵文字は似た標準絵文字に差し替えます Vodafone絵文字・EZweb絵文字は利用できません ドコモ拡張絵文字機種 - 全てのドコモ絵文字(標準+拡張)を利用できます Vodafone絵文字・EZweb絵文字は利用できません Vodafone非パケット機種 - Vodafone絵文字のページ1〜3を利用できます ドコモ絵文字は似たVodafone絵文字に差し替えます Vodafoneパケット機種 - 全てのVodafone絵文字(ページ1〜6)を利用できます ドコモ絵文字は似たVodafone絵文字に差し替えます EZweb HDML機種 - ドコモ標準絵文字を &#ddddd; 形式で出力します ドコモ拡張絵文字は利用できません EZweb XHTML機種 - 全ての EZweb 絵文字を利用できます ドコモ絵文字は似たVodafone絵文字に差し替えます =head1 CONFIGURATION EmojiTransMap.txt EmojiTransMap.txt は、ドコモ⇒他キャリアの絵文字変換マップです。 EmojiTrans.pm ファイルと同じディレクトリに設置してください。 絵文字コードは3キャリアとも全て Unicode で指定されています。 (ただし Vodafone 絵文字コードは F001〜F53A に移動しています) 絵文字変換を追加・変更する場合は、EmojiTransMap.txt を更新してください。 =head1 MEMO その他の気づいたこと・雑多なメモを書いておきます。 =head2 EZweb XHTML機種の絵文字について EZweb の UP.Browser/6.0.x の XHTML 機種では、 EZweb 絵文字の &#xHHHH; 表記や Shift_JIS バイナリコードは受け付けられません。 iモード絵文字の Shift_JIS バイナリコードは (恐らくEZweb GWセンタで変換されて)正常に表示できるので、 これらの機種では、ドコモ絵文字→EZwebネイティブ絵文字の 変換は実施しない方が安全です。 それ以降の UP.Browser/6.2.x の XHTML 機種では、 EZweb 絵文字の Shift_JIS バイナリコードも受け付けられます。 (相変わらず &#xHHHH; 表記は受け付けられません) より確実には、 のタグを利用すれば EZweb のどの XHTML 機種でも表示できますが、 ドコモ・ボーダフォンとの互換性が確保できませんね。 =head2 EZweb UP.Browserバージョン番号 UP.Browser/3.04 … HDML機種 UP.Browser/6.0.x … XHTML旧機種 UP.Browser/6.1.0 … Google CHTML Proxy/1.0 UP.Browser/6.2.0 … XHTML新機種 =head1 COPYRIGHT Copyright 2004-2005 Kawasaki Yusuke http://www.kawa.net/ =cut # -------------------------------------------------------------------- # my $EMOJI_DOCOMO2VODAFONE; my $EMOJI_DOCOMO2EZWEB; my $EMOJI_DOCOMO2COLOR; my $EMOJI_DOCOMO_EXT2STD; # -------------------------------------------------------------------- # # キャリア間絵文字変換マップの初期化 # -------------------------------------------------------------------- # if ( ! ref $EMOJI_DOCOMO2EZWEB ) { my $pwd = &where_you_are(); my $file = "$pwd/EmojiTransMap.txt"; open( MAP, $file ); while( ) { next if /^\s*(#|$)/; chomp; my( $doext, $dostd, $ezweb, $voda, $color ) = split( /\t/, $_ ); $EMOJI_DOCOMO2EZWEB->{$doext} = $ezweb if ( $ezweb =~ /^E/ ); $EMOJI_DOCOMO2VODAFONE->{$doext} = $voda if ( $voda =~ /^[EF]/ ); $EMOJI_DOCOMO2COLOR->{$doext} = $color if ( $color =~ /^[0-9A-F]/i ); $EMOJI_DOCOMO_EXT2STD->{$doext} = $dostd if ( $dostd =~ /^[0-9A-F]/i ); } close( MAP ); } # -------------------------------------------------------------------- # # ドコモ標準絵文字機種一覧(今後の新機種は全て拡張絵文字対応) # http://www.nttdocomo.co.jp/p_s/imode/make/spec/index.html # iモード対応HTML1.0(501i) # iモード対応HTML2.0(502i等) # iモード対応HTML3.0(503i等) # iモード対応HTML3.0(FOMA 2001/2002/2101V) # -------------------------------------------------------------------- # my $DOCOMO_STD_EMOJI_HASH; if ( ! ref $DOCOMO_STD_EMOJI_HASH ) { my $list = [qw( D501i F501i N501i P501i D502i F502i N502i P502i NM502i SO502i F502it N502it SO502iWM SH821i N821i P821i D209i ER209i F209i KO209i N209i P209i P209is R209i R691i F210i N210i P210i KO210i F671i D210i SO210i F503i F503iS P503i P503iS N503i N503iS SO503i SO503iS D503i D503iS F211i D211i N211i N211iS P211i P211iS SO211i R211i SH251i SH251iS R692i N2001 N2002 D2101V P2101V SH2101V T2101V )]; foreach my $name ( @$list ) { $name =~ tr/A-Z/a-z/; $DOCOMO_STD_EMOJI_HASH->{$name} ++; } } # -------------------------------------------------------------------- # # HTTP_USER_AGENT により、ドコモ標準絵文字機種なら真を返す # -------------------------------------------------------------------- # sub is_docomo_std_emoji { my $agent = shift or return; my $name = ( $agent =~ m#^DoCoMo/(?:1\.0/|2\.0\s+)([A-Za-z0-9]+)# )[0]; $name =~ tr/A-Z/a-z/; $DOCOMO_STD_EMOJI_HASH->{$name}; } # -------------------------------------------------------------------- # # キャリア間の絵文字の相互変換 # -------------------------------------------------------------------- # sub translate { my $src = \$_[0]; my $ref = ref $$src ? $$src : $src; # 必ず1レベルのリファレンス my $agent = $_[1] || $ENV{HTTP_USER_AGENT}; # 互換性のため、ドコモ旧表記→新表記の変換は全機種で実施する &tran_docomo_old2new( $ref ); # → if ( $agent =~ m#^DoCoMo/# ) { # ドコモ # &tran_number2docomo( $ref ); if ( &is_docomo_std_emoji( $agent ) ) { &tran_docomo_ext2std( $ref ); # 拡張絵文字→標準絵文字 } } elsif ( $agent =~ m#^UP.Brows# ) { # EZweb HDML 機種 # &tran_number2ezweb( $ref ); &tran_docomo_ext2std( $ref ); # 拡張絵文字→標準絵文字 &tran_docomo_new2old( $ref ); # → } elsif ( $agent =~ m#^KDDI-\w+\s+UP.Browser/(?!6\.0\.)# ) { # 6.0.x は変換しない C3002K/A1101S/INFOBAR など # 6.2.x 以降は変換する A5503SA/W21H など # &tran_number2ezweb( $ref ); &tran_docomo2ezweb( $ref ); # ドコモ→EZweb絵文字 } elsif ( $agent =~ m#^(J-PHONE|Vodafone)/# ) { # &tran_number2vodafone( $ref ); &tran_docomo2vodafone( $ref ); # ドコモ→Vodafone絵文字 } elsif ( $agent =~ m#^Moz# ) { # &tran_number2marusuji( $ref ); } } # -------------------------------------------------------------------- # # ドコモ絵文字 ⇒ au 絵文字変換 # -------------------------------------------------------------------- # sub tran_docomo2ezweb { my $ref = shift or return; $$ref =~ s/(\&\#x)(E[0-9A-F]{3})(;) /$1.($EMOJI_DOCOMO2EZWEB->{$2}||$2).$3/igex; } # -------------------------------------------------------------------- # # ドコモ絵文字 ⇒ Vodafone 絵文字変換 # -------------------------------------------------------------------- # sub tran_docomo2vodafone { my $ref = shift or return; $$ref =~ s/(\&\#x)(E[0-9A-F]{3})(;) /$1.($EMOJI_DOCOMO2VODAFONE->{$2}||$2).$3/igex; } # -------------------------------------------------------------------- # # 拡張絵文字非対応機種の場合、拡張→標準変換 # -------------------------------------------------------------------- # sub tran_docomo_ext2std { my $ref = shift or return; $$ref =~ s/(\&\#x)([0-9A-F]{4})(;) /$1.($EMOJI_DOCOMO_EXT2STD->{$2}||$2).$3/igex; } # -------------------------------------------------------------------- # # iモード絵文字 →Unicode  表記変換 # ドコモの旧仕様(Shift_JISコードを使用)を新仕様に修正する # -------------------------------------------------------------------- # sub tran_docomo_old2new { my $ref = shift; $$ref =~ s/(\&\#(63[6-9][0-9][0-9]);) /&one_docomo_sjis2escape($2)||$1/gex; } # -------------------------------------------------------------------- # # iモード絵文字 Unicode → 表記変換 # EZweb HDML 機種のGWセンタ変換は、&#ddddd; 表記の方が安全 # -------------------------------------------------------------------- # sub tran_docomo_new2old { my $ref = shift; $$ref =~ s/(\&\#x(E[0-9A-F]{3});) /&one_docomo_unicode2escape(hex($2))||$1/igex; } # -------------------------------------------------------------------- # # カッコ数字表記 [0]〜[9] を絵文字にする # ⇒現在は不使用。{emoji.1} とか  とかを利用して下さい # ドコモは  〜 (1〜9、0) # EZweb は  〜 (1〜9、0) # Vodafone は  〜 (1〜9、0) # PCは ① 〜 ⑨(1〜9のみ) # -------------------------------------------------------------------- # sub tran_number2docomo { my $ref = shift; $$ref =~ s/\[([0-9])\]/sprintf("&#x%04X;",0xE6E2+($1+9)%10)/gex; } sub tran_number2ezweb { my $ref = shift; $$ref =~ s/\[([0-9])\]/sprintf("&#x%04X;",0xE522+($1+9)%10)/gex; } sub tran_number2vodafone { my $ref = shift; $$ref =~ s/\[([0-9])\]/sprintf("&#x%04X;",0xE21C+($1+9)%10)/gex; } sub tran_number2marusuji { my $ref = shift; $$ref =~ s/\[([1-9])\]/sprintf("&#x%04X;",0x2460+$1-1)/gex; } # -------------------------------------------------------------------- # # ドコモの絵文字コード(Shift_JIS値)を、Unicode &#xHHHH; 新形式に変換 # -------------------------------------------------------------------- # sub one_docomo_sjis2escape { my $sjis = shift or return; my $code; if ( $sjis >= 63647 && $sjis <= 63996 ) { if ( $sjis <= 63740 ) { $code = $sjis-4705; } elsif ( $sjis <= 63870 ) { $code = $sjis-4772; } else { $code = $sjis-4773; } } my $str = sprintf( "&#x%04X;", $code ) if $code; $str; } # -------------------------------------------------------------------- # # ドコモの絵文字コード(Unicode値)を、Shift_JIS &#ddddd; 旧形式に変換 # -------------------------------------------------------------------- # sub one_docomo_unicode2escape { my $code = shift or return; my $sjis; if ( $code >= 0xE63E && $code <= 0xE757 ) { if ( $code <= 0xE69B ) { $sjis = $code+4705; } elsif ( $code <= 0xE6DA ) { $sjis = $code+4772; } else { $sjis = $code+4773; } } my $str = sprintf( "&#%05d;", $sjis ) if $sjis; $str; } # -------------------------------------------------------------------- # # 実行中のファイル名を取り出す # -------------------------------------------------------------------- # sub where_you_are { my $path = (caller(0))[1]; # 呼び出し元が実行中のファイル名 $path =~ s#[^/]+$##s; # ディレクトリ名に変換 $path = "." if ( $path eq "" ); $path; # ディレクトリ名を返す } # -------------------------------------------------------------------- # ;1; # End of the script. # -------------------------------------------------------------------- #