Ab.の日記: ATOK 2009 hack
まずはカナ側がunicodeなのではないかという淡い期待を抱いて unicode で矢印等を登録…全然駄目でした。
…にしたい y. がなぜか「&」として出てきてしまう以外、四方向の矢印はすべて全角スペースにされてしまいます。
これは下手すると配列の範囲外の所を読んでたりすると嫌だなという事で記号を直接出す方向は却下にしました。
まぁ、カナの側のデータが濁点半濁点が分離されているという時点である程度予想のうちでしたが。
というわけで、こうなったらもう記号を直接ローマ字テーブルに入れられないのは仕方ないということで、変換一回で済ますように yを「みぎやじるし」、y_を「したやじるし」、y^を「うえやじるし」、というローマ字として登録して、それぞれ単語登録を行えばそれなりに使えることになるんじゃないだろうかという事で方針を転換。
試してみたところ ATOK のシステム上の制限でローマ字のカナ側の方は半角カナで6文字までという事になっているらしく、「ミギヤジルシ」一つだけなら「みぎやじ」とローマ字登録エディタ上では表示されているけど、実際に y> と叩くと「みぎやじるし」と出るのですが、続けて「ヒダリヤジルシ」の登録を追加すると登録エディタで確認のために眺めると落っこちてしまいました。
試しにローマ字の登録のダイアログを叩いてみると半角カナで6文字分までしか入りません。アプリ側なのかシステム側なのかどちらの制限か分かりませんが、 記号が直接入らない時点でもはやそんな事はどうでもいい事なので無理矢理6文字に縮めた形で登録を強行する事にします。
というわけで下にはそのスクリプトを掲載。たぶん shift jis でないとちゃんと動きません。
参考にさせていただいたコードやら資料やらに感謝です。
これで登録してから「てんてんてん」→「…」、「みゃじるし」→「→」、「ひゃじるし」→「←」、「うゃじるし」→「↑」、「しゃじるし」→「↓」の辞書登録をすれば、変換の分一手間かかるけど一応これらの記号の短縮入力は可能になりました。
うーむ、今打っていても手が覚えてるからどうしても未変換のまま確定しちゃうなぁ。
まぁ慣れではありますが、VJEの方の環境も一回変換を叩くように変えないと慣れないかなぁ。
# 既存の ATOK style ファイルのローマ字テーブルに変更を加えて出力する perl script
#
# usage:
# modify-roma-sty.pl <org-style-file> > new-style-file
#
# 参考:
# http://www.massangeana.com/mas/charsets/hana/hana-atok.pl
# http://d.hatena.ne.jp/itouhiro/20080520
# http://hossy.info/tdiary/?date=1105
my $style_setting;
while (<>) {
next if (/^[ \t]*\;/);
if (/^ロ.*マ字=(.*)/) {
$style_setting = $1;
$style_setting =~ s/[\r\n]*$//;
$_ = 'ローマ字=' . &modify_style($style_setting) . "\n";
}
print;
}
sub nhex {
my ($val, $wid) = @_;
sprintf("%0${wid}x", $val);
}
sub stroke {
join(" ", map { &nhex($_, 4) } unpack('C*', $_[0]));
}
sub kanadata {
join(" ", map { &nhex($_ - 0xa0 + 0xff60, 4) } unpack('C*', $_[0]));
}
sub modify_style {
my $entries = hex(substr($style_setting, 0, 8));
my $style_header = substr($style_setting, 8, 8);
my @input;
for (my $i=16+96*8+$entries*8; $i<length($style_setting); $i+=4) {
push @input, substr($style_setting, $i, 4);
}
#foreach my $k (@input) { print "$k\n"; } exit;
my %romatbl;
while ($#input >= 0) {
my $roma, $kana = ();
while ($#input>=0 && ($input[0]=~m/^00/ && $input[0]!~m/^001[0-4]/)) {
$roma .= shift @input;
$roma .= " ";
}
while ($#input>=0 && ($input[0]!~m/^00/ || $input[0]=~m/^001[0-4]/)) {
$kana .= " ";
$kana .= shift @input;
}
$romatbl{$roma} = $kana;
}
if (1) {
sub settable {
my ($roma, $kana) = @_;
my ($rdata, $kdata) = (&stroke($roma), &kanadata($kana));
$romatbl{$rdata} = $kdata;
#print "$rdata = $kdata\n";
}
# 何か追加するならここで
# 仮名の方は半角カナ6文字までの模様
&settable(";", "ッ");
&settable("y.", "テンテンテン");
#&settable("y>", "ミギヤジルシ"); # これだけなら平気(表示は「みぎやじ」止まり)
#&settable("y<", "ヒダリヤジルシ"); # これも入れると飛ぶ
&settable("y>", "ミャジルシ");
&settable("y<", "ヒャジルシ");
&settable("y^", "ウャジルシ");
&settable("y_", "シャジルシ");
}
#printf("%d\n", 0+(keys %romatbl)); exit;
#{ my $c=0; foreach my $k (keys %romatbl) { $c++; print "$c: $k = $romatbl{$k}\n";} exit; }
my $result = &nhex(0+(keys %romatbl), 8) . $style_header;
my @freq;
for (keys %romatbl) {
/^([[:xdigit:]]{4})/;
$freq{hex($1)}++;
#printf("%s : [%s] %d\n", $_, hex($1), $freq{hex($1)});
}
{
my $sum = 0;
for (my $i=0x20; $i<=0x7f; $i++) {
my $c = pack('C', $i);
$result .= &nhex($sum, 4) . &nhex($freq{$i}, 4);
$sum += $freq{$i};
}
}
if (0) {
my $sum = 0;
for (my $i=0x20; $i<=0x7f; $i++) {
printf("%02x[%s] %d\n", $i, pack('C', $i), $freq{$i});
}
exit;
}
{
my $sum = 0;
for my $r (sort keys %romatbl) {
my $k = $romatbl{$r};
$r =~ s/\s//g;
$k =~ s/\s//g;
my $nroma = length($r)/4;
my $nkana = length($k)/4;
#print "$r-$k, $nroma, $nkana\n"; exit;
$result .= &nhex($sum, 4) . &nhex($nroma, 2) . &nhex($nkana, 2);
$sum += $nroma + $nkana;
}
}
for my $k (sort keys %romatbl) {
my $v = $k.$romatbl{$k};
$v =~ s/[ =]//g;
$result .= $v;
}
$result;
}
しまった、%romatbl 組み立てるところ、変にヒューリスティックな方法をとらずに手前にテーブルあるんだからそっちのデータを元に切り出せば良かった。
ATOK 2009 hack More ログイン