But sure all are confused
−− でも本当のところ、皆、混乱しているのだ
本章では、SKK風の漢字変換システムReasonableEggの設計と実装について述べます。 最初に、SKKについて簡単に説明しておきます。
SKKとは、佐藤雅彦氏により開発された日本語入力システムで、 一部に熱狂的なファン(含む筆者)を持ちます。 UN*X系OSで使われますが、もともとはEmacs-Lispの内部で閉じたシステムなので、 Windows+Meadowでも動作すると思います。
SKKは次のような特徴があります。
SKKは基本的にローマ字入力で、普通にタイプすると仮名がそのまま入力されます。 漢字を入力する時は、単語の開始位置と送り仮名の開始位置で大文字のアルファベットを 入力します。送りがなを一文字入力した時点で変換が始まり、 スペース、xで候補を選択し、Ctrl-Jで確定します。 また、候補選択中に新たに入力を開始すると、自動的に確定します(暗黙の確定)。 送り仮名を持たない単語を入力する時には、スペースを押すと変換が始まります。
たとえば、「消える飛行機雲」と入力する時には、 KiEruHikoukigumo[SPC][Ctrl-J] と入力します。
押したキー | 画面表示 | 註釈 |
---|---|---|
K | ▽k | 漢字変換位置指定 |
Ki | ▽き | |
KiE | ▼消え | 変換開始 |
KiEr | 消えr | 暗黙の確定 |
KiEru | 消える | 普通は仮名が入力される |
KiEruH | 消える▽h | |
KiEruHikoukigumo | 消える▽ひこうきぐも | |
KiEruHikoukigumo[SPC] | 消える▼飛行機雲 | |
KiEruHikoukigumo[SPC][Ctrl-J] | 消える飛行機雲 |
変換候補が見つからないとき、または、候補が出尽したときは、 自動的に辞書登録モードになります。
例えば、「見送る」という単語が辞書にない場合、MiokuRuと入力した時点で 辞書登録モードになります。そこで、どうにかして「見送」と入力すると (例えば、見る、[一文字削除]、送る、[一文字削除]、のように)、 それが辞書に登録され、同時に「見送る」が入力されます。
また、辞書登録中に変換候補が見つからなかったりした場合は、再帰的に辞書登録モード になります。
SKKは他にも便利な機能をたくさん持っていますが、 本稿の目的はSKKの宣伝では無いのでこの位にしておきます。 詳しくは、 SKK ホームページや、 SKK 9.6 のマニュアル等を参照して下さい。
ReasonableEgg(以下Regg)は、たまご(Egg)といいう名前にもかかわらずSKKライクな 漢字変換システムです。
SKKはローマ字入力が基本ですが、パイメニューではキーストロークが多すぎるので、 かな入力を採用しました。
さてSKKの辞書は、単語の読みと送り仮名の子音というエントリになっています。 SKK辞書の一部を以下に載せます。
ほほえm /微笑/頬笑/ ほふr /屠/ ほのぐらi /仄暗/ ほのm /仄/ ほのk /仄/ ほねやすm /骨休/ ほねぐm /骨組/ ほねおr /骨折/ ほどよk /程良/ ほどよi /程良/
かな入力の場合、入力された送り仮名の子音を調べる必要があるため、 かな-子音変換テーブルを使用することにしました。 今回の実装ではバイナリサーチしていますが、 テーブルエントリ数は80なので、リニアサーチでも問題ないかもしれません。
漢字変換開始位置および送り仮名の位置指定は、その文字を入力する前に Bボタンを押すことにしました。
別の案として、単語の先頭と最後でBボタンを押し、単語内の最後の文字を送り仮名と みなすという方法も考えましたが、その場合、送り仮名あり/なしを どう判別するかが問題になります。辞書の両方のエントリを調べるという方法も ありますが、これだと候補が増えてしまいます。また、送り仮名あり/なしで 別のボタンを押すという方法もありますが、ボタン数は貴重なのでやめました。
使用する文字コードは、本来ならば処理が楽なEUCを使いたいところですが、 WonderWitchはSJISがベースのようで、例えば文字フォントを取り出す関数では コードをSJISで指定するようです。 また、LSI-CはSJISリテラルは通してもEUCリテラルは通さないようです。まあ、 本来Cのソースに日本語リテラルを埋めこむべきではないのですが。
内部コードをEUC(ないし、JISコードと親和性の高いコード体系)にして、 フォント取得時にSJISに変換することも考えましたが、手元にSJISのコード範囲の 資料が無いのであきらめ(Internetで探せばあると思うけど)、 結局、内部コードとしてSJISを使用することにしました。
辞書はSKKの辞書を流用します。 現在、SKKの辞書としてS,M,Lの3種類のサイズが存在します。普通に使われるのは Lサイズのものですが、約2.8MバイトあるのでWonderWitchで使うのは無理です。 S,Mサイズはそれぞれ約50Kバイト,約150Kバイト程度ですので、このどちらかを 使用することにします。
SKKの辞書は、ソートされた単純なテキストファイルです。普通は起動時に辞書をメモリ に取り込んでしまうため、この形式で十分なのです。また、もともとSKKはEmacs-Lisp 上のシステムなので、Lispで処理しやすいような形式になっているのだと思われます。
Reggでは、辞書は/rom0上に置いておき、mmap()で直接アクセスします。そのため、 あらかじめ辞書を処理しやすいような形式にコンバートして置きます。
今回の実装では、読み+送り仮名の子音がキーのチェーンハッシュにしました。
文字の入力は、前章で説明したパイメニューによる入力方法です。 また、Y1ボタンを押すたびに、ひらがな→カタカナ→英数と切り替わるように なっています。
普段は[通常モード]です。このモードでは、入力した文字がそのまま入力されます。
Bボタンを押すと、[読み入力モード]になります。 このとき、画面上には▽が表示されます。つづけて読みを入力していきます。 例として、「映す」と入力してみましょう。
<Bボタンを押す> ▽ <「う」「つ」と入力> ▽うつ
送り仮名の直前の位置でもういちどBボタンを押します。 ▽が表示され、[送り仮名入力モード]になります。
<Bボタンを押す> ▽うつ▽
送り仮名を入力すると、[候補選択モード]になります。 送り仮名の無い単語を入力するときは、もういちどBボタンを押します。
<「す」を入力> ▼移す
BボタンまたはX2ボタンで次候補、X4ボタンで前候補が表示されます。
<BボタンまたはX2ボタンを押す> ▼映す
Aボタンを押すと確定し、[通常モード]に戻ります。
<Aボタンを押す> 映す
[読み入力モード]のときにY4ボタンを押すと、入力した読みを訂正できます。 読みが入力されていないとき(▽だけ表示されているとき)にY4ボタン またはBボタンを押すと、通常モードに戻ります。
[読み入力モード]および[候補選択モード]でY4ボタンを押すと、 [読み入力モード]に戻ります。
前回のテストプログラムにReggによる漢字変換を追加したものです。 また、カタカナ・英数の入力モードも追加しました。 あいかわらず入力、1文字削除しかできない役立たずです。
漢字変換をする場合は、辞書を/rom0に転送しておく必要があります。 辞書は2種類用意してあります。SKKのS,Mサイズ辞書をコンバートしたものです。 辞書ファイルのライセンスはGPLです。