| 1 | #!/usr/bin/perl |
|---|
| 2 | use strict; |
|---|
| 3 | use warnings; |
|---|
| 4 | use FindBin; |
|---|
| 5 | use Path::Class; |
|---|
| 6 | use YAML; |
|---|
| 7 | use Encode; |
|---|
| 8 | use Encode::JP::Mobile; |
|---|
| 9 | |
|---|
| 10 | my @encodings = ( |
|---|
| 11 | +{ |
|---|
| 12 | name => 'x-sjis-airh-raw', |
|---|
| 13 | alias => "x-sjis-airedge-raw", |
|---|
| 14 | carrier => 'AirHPhone', |
|---|
| 15 | table_maker => \&airh_table, |
|---|
| 16 | }, |
|---|
| 17 | +{ |
|---|
| 18 | name => 'x-sjis-docomo-raw', |
|---|
| 19 | alias => 'x-sjis-imode-raw', |
|---|
| 20 | carrier => 'DoCoMo', |
|---|
| 21 | table_maker => table_maker_maker( 'docomo-table.yaml' ), |
|---|
| 22 | }, |
|---|
| 23 | +{ |
|---|
| 24 | name => 'x-sjis-kddi-auto-raw', |
|---|
| 25 | alias => 'x-sjis-ezweb-auto-raw', |
|---|
| 26 | carrier => 'KDDI/AU', |
|---|
| 27 | table_maker => table_maker_maker( 'kddi-table.yaml', 'unicode_auto' ), |
|---|
| 28 | }, |
|---|
| 29 | +{ |
|---|
| 30 | name => 'x-sjis-kddi-cp932-raw', |
|---|
| 31 | alias => 'x-sjis-ezweb-cp932-raw', |
|---|
| 32 | carrier => 'KDDI/AU', |
|---|
| 33 | table_maker => table_maker_maker( 'kddi-table.yaml' ), |
|---|
| 34 | }, |
|---|
| 35 | +{ |
|---|
| 36 | name => 'x-sjis-softbank-auto-raw', |
|---|
| 37 | alias => 'x-sjis-vodafone-auto-raw', |
|---|
| 38 | carrier => 'SoftBank', |
|---|
| 39 | table_maker => table_maker_maker( 'softbank-table.yaml', 'unicode', 'sjis_auto' ), |
|---|
| 40 | is_skip => \&is_skip_softbank_auto, |
|---|
| 41 | }, |
|---|
| 42 | ); |
|---|
| 43 | |
|---|
| 44 | &main;exit; |
|---|
| 45 | |
|---|
| 46 | sub airh_table { |
|---|
| 47 | my $sort_key = shift; |
|---|
| 48 | |
|---|
| 49 | my @ret; |
|---|
| 50 | my $add_to_ret = sub { |
|---|
| 51 | my $x = shift; |
|---|
| 52 | push @ret, |
|---|
| 53 | +{ |
|---|
| 54 | unicode => sprintf('%X', $x ), |
|---|
| 55 | sjis => unpack( 'H*', encode( 'cp932', chr $x ) ), |
|---|
| 56 | }; |
|---|
| 57 | }; |
|---|
| 58 | my $map = join "", Encode::JP::Mobile::InAirEdgePictograms(), Encode::JP::Mobile::InDoCoMoPictograms(); |
|---|
| 59 | for my $line (split /\n/, $map) { |
|---|
| 60 | if ($line =~ /\t/) { |
|---|
| 61 | my ($min, $max) = map { hex $_ } split /\t/, $line; |
|---|
| 62 | my $i = $min; |
|---|
| 63 | while ($i <= $max) { |
|---|
| 64 | $add_to_ret->($i); |
|---|
| 65 | $i++; |
|---|
| 66 | } |
|---|
| 67 | } else { |
|---|
| 68 | $add_to_ret->(hex $line); |
|---|
| 69 | } |
|---|
| 70 | } |
|---|
| 71 | @ret; |
|---|
| 72 | } |
|---|
| 73 | |
|---|
| 74 | sub table_maker_maker { |
|---|
| 75 | my ($file, $unicode_key, $sjis_key) = @_; |
|---|
| 76 | $unicode_key ||= 'unicode'; |
|---|
| 77 | $sjis_key ||= 'sjis'; |
|---|
| 78 | |
|---|
| 79 | sub { |
|---|
| 80 | map { +{ unicode => $_->{$unicode_key}, sjis => $_->{$sjis_key} } } |
|---|
| 81 | grep { $_->{$sjis_key} } |
|---|
| 82 | sort { hex( $a->{$unicode_key} ) <=> hex( $b->{$unicode_key} ) } |
|---|
| 83 | @{ YAML::LoadFile( file( $FindBin::Bin, '..', 'dat', $file ) ) }; |
|---|
| 84 | }; |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | sub is_skip_softbank_auto { |
|---|
| 88 | my $line = shift; |
|---|
| 89 | |
|---|
| 90 | # x-sjis-softbank-auto ではIBM拡張漢字の領域をつぶして絵文字用につかっている模様。 |
|---|
| 91 | # たとえば、U+52AF は IBM EXT では \xFB\x77 で、NEC EXT. では \xEE\x5B と表現できる(see cp932.ucm) |
|---|
| 92 | # このうち、\xFB\x77 の方を絵文字領域として使用しているのだ。 |
|---|
| 93 | if ($line =~ /^<U[0-9A-F]+> (\S+) \|\d/) { |
|---|
| 94 | if (in_softbank_pictogram($1)) { |
|---|
| 95 | return 1; |
|---|
| 96 | } |
|---|
| 97 | } |
|---|
| 98 | return; |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | my $sjis_auto_map; |
|---|
| 102 | sub in_softbank_pictogram { |
|---|
| 103 | my $sjis = shift; |
|---|
| 104 | $sjis_auto_map ||= |
|---|
| 105 | +{ map { ( uc hexify( $_->{sjis} ) ) => 1 } |
|---|
| 106 | grep { $_->{sjis} } |
|---|
| 107 | table_maker_maker( 'softbank-table.yaml', 'unicode', 'sjis_auto' )->() |
|---|
| 108 | }; |
|---|
| 109 | return $sjis_auto_map->{uc $sjis}; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | sub hexify { |
|---|
| 113 | local $_ = shift; |
|---|
| 114 | s/(..)/\\x$1/g; |
|---|
| 115 | $_; |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | sub header { |
|---|
| 119 | my $encoding = shift; |
|---|
| 120 | |
|---|
| 121 | return <<"..."; |
|---|
| 122 | <code_set_name> "$encoding->{name}" |
|---|
| 123 | <code_set_alias> "$encoding->{alias}" |
|---|
| 124 | ... |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | sub footer() { |
|---|
| 128 | return <<'...'; |
|---|
| 129 | END CHARMAP |
|---|
| 130 | ... |
|---|
| 131 | } |
|---|
| 132 | |
|---|
| 133 | sub generate_ucm { |
|---|
| 134 | my $encoding = shift; |
|---|
| 135 | my $cp932 = file($FindBin::Bin, '..', 'ucm', 'cp932.ucm')->openr; |
|---|
| 136 | |
|---|
| 137 | my $fh = file($FindBin::Bin, '..', 'ucm', "$encoding->{name}.ucm")->openw; |
|---|
| 138 | $fh->print(header($encoding)); |
|---|
| 139 | while (<$cp932>) { |
|---|
| 140 | next if /^#/; |
|---|
| 141 | next if /<code_set_name> "cp932"/; |
|---|
| 142 | next if /PRIVATE USE AREA/; |
|---|
| 143 | next if /END CHARMAP/; |
|---|
| 144 | next if $encoding->{is_skip} && $encoding->{is_skip}->($_); |
|---|
| 145 | $fh->print($_); |
|---|
| 146 | } |
|---|
| 147 | $fh->print('<U301C> \x81\x60 |1 # WAVE DUSH', "\n"); # ad-hoc solution for FULLWIDTH TILDE Problem. |
|---|
| 148 | $fh->print("# below are copied from $encoding->{carrier}'s pictogram map\n"); |
|---|
| 149 | for my $row ($encoding->{table_maker}->()) { |
|---|
| 150 | $fh->print(sprintf "<U%s> %s |0 # $encoding->{carrier} Pictogram\n", $row->{'unicode'}, hexify($row->{sjis})); |
|---|
| 151 | } |
|---|
| 152 | $fh->print(footer); |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | sub main { |
|---|
| 156 | for my $encoding (@encodings) { |
|---|
| 157 | generate_ucm($encoding); |
|---|
| 158 | } |
|---|
| 159 | } |
|---|
| 160 | |
|---|