オートマトンは、xjsi やuum のローマ字かな変換を実現している機能です。変換内容を設定した表 (変換表) を変えることで 、任意の変換に変更することができます。
オートマトンは、変換表に従って直列に結ばれた 3 つの変換 (順に、前処理、本処理、後処理) を行い、その最終結果を出力します。3 つの処理では、それぞれの変換表に基づいて変換を行います。また、オートマトンはモード機能を持っています。モードを切り替えることにより、3 つの処理で使用する表の組み合わせを動的に変更できます。このモードの設定、切り替えコードの設定も変換表で行います。
変換表はテキストファイルであるため、容易に任意の変換表に変更できます。また、1 つの変換を行なったあと次の変換を行うまでは、バックスペースにより変換の 1 つ前の状態に戻すことができます。
xjsi のローマ字かな変換では、本処理で「英大文字からひらがな」の変換しか行えませんが、前処理で「英大文字から英大文字」、「英小文字から英大文字」の切り替え、また後処理では「ひらがなからひらがな」、「ひらがなからカタカナ」、「ひら がなから半角カタカナ」の切り替えを行うことにより、ローマ字かな変換の入力と出力のさまざまな状況に対処しています。
オートマトンは次のように処理されます。
入力。英 (半角) の大文字と小文字
前処理。小文字は大文字に変換
本処理。英大文字からひらがなへの変換表に基づいて変換
後処理。ひらがなを必要に応じてカタカナや半角カナに変換
出力。
オートマトンは、変換表として次の表を使用します。
モード定義表
モード宣言や使用する対応表を指定する表。ファイル名は mode
前処理
前処理で使用する対応表。1 で始まるファイル名
本処理表
本処理で使用する対応表。2 で始まるファイル名
後処理表
後処理で使用する対応表。3 で始まるファイル名
モード定義表には、モードの宣言、各モードで使用する対応表の組み合わせとその決定規則を記述します。
対応表には、入力コードと出力コードとの対応が記述されます。対応表は、前処理、本処理、後処理の 3 つに分かれ、それぞれ、任意の数の表を使用できます。
xjsi は、モード定義表を以下の順番で探します。
xjsi 初期化ファイル uumrc の setrkfile エントリによる指定
ファイル名 /usr/lib/locale/ja/wnn/ja/rk/mode
以下のモード定義表と対応表の説明では、次の表記法を使用しています。
. . . は、0 回以上の繰り返し
. . . . . . は、1 回以上の繰り返し
[ ] は、省略可能
モード定義表には、モード宣言、各モードで使用する対応表の組み合わせとその決定規則、モード表示文字列を記述します。
モード定義表は、次の 1、2、3、4 で構成されます。ただし、行の先頭または空白文字 (タブを含む) に続き、しかもエスケープされていないセミコロン (;) から行末までの文は、注釈文として扱われます。
特殊パス表記としては、以下に示すものがあります。
環境変数 HOME
モード定義表の存在するディレクトリ
/usr/lib/locale/ja/wnn/
user がユーザー名であれば、そのユーザーのホームディレクトリ名
自分のホームディレクトリ名
モード宣言の書式は、次のとおりです。
mode_name は、英数字を指定します。[on|off] は初期状態を表します。デフォルトは off です。[r|nr] はローマ字かな変換モードをオートマトンに認識させるためのフラグです。r が設定されているモードは、F6 キーなどでひらがな変換を行う際に、その時のモードに関わらず使用されます。デフォルトは nr です。
モード宣言は、そのモードを使用する前に行います。
対応表の検索指定の書式は、次のとおりです。
モード定義表で指定された対応表がモード定義表と同じディレクトリにない場合、指定された directory を検索します。directory は、空白で区切って複数指定できます。search は、対応表の指定より前に指定してください。
対応表を検索するディレクトリパスを無効にし、引数に指定された directory を検索するように設定します。 directory は、空白で区切って複数指定できます。 path は、対応表の指定より前に 指定してください。
指定方法は、次の 3 つがあります。
対応表のファイル名またはモード表示文字列
if 条件式。対応表の指定またはモード表示文字列
when 条件式。対応表の指定またはモード表示文字列
対応表は、(1)、(2)、(3) のいずれかで始まるファイル名を指定します。パスによる指定もできます。モード表示文字列は、そのときのモードを表す二重引用符 (“) で囲んだ文字列です。
“string“
変換が on のときのモード表示文字列を表します。
(on_dispmode “string“)
変換が on のときのモード表示文字列を表します。
(off_dispmode “string“)
変換が off のときのモード表示文字列を表します。
(on_unchg)
変換が on のときのモード表示文字列をモード変換する前と同じモード表示文字列を表します。
(off_unchg)
変換が off のときのモード表示文字列をモード変換する前と同じモード表示文字列を表します。
xjsi では、この文字列がモード表示に使用されます。
(2)、(3) は、条件によって選択する対応表を変えるときに使用します。(2) の if 文 は、その条件式の結果が真であれば、if 文内の指定を参照し、if 文の次の指定は参照しません。条件式が偽であれば、すぐ if 文を抜け出して if 文の次の指定を参照します。
(3) の when 文は、その条件式の結果が真であれば、when 文内の指定を参照し、偽であれば参照しません。しかし、if 文と異なり、条件式の真偽にかかわらず when 文の次の指定を参照します。
なお、(2)、(3) で対応表を指定する場合には、(2) または (3) を再帰的に定義できます。
条件式には次のうち 1 つを記述します。
モード名 | モードの状態が on のとき真 |
---|---|
(and 条件式 条件式) | 2 つの条件式が真のとき真 |
(or 条件式 条件式) | どちらか条件式が真のとき真 |
(not 条件式) | 条件式が偽のとき真 |
(false) | 常に偽 |
(true) | 常に真 |
たとえば、モード定義に (defmode kana) と (defmode romajikana) があり、双方のモードが on のとき、(and kana romajikana) は真になります。
ここで、条件式を○◎●で表し、変換表の名前を ABC. . . で表すという規則において、たとえば次のように書かれていたとします。
(when ○ A (if ◎ B) C) (if ● D) E
この条件式○◎●が、すべて成り立っているとします。この並びを最初から見ていくと、まず、(when ○ A (if ◎ B) C)と あります。ここでは○は成り立つので、「A (if ◎ B) C」という並びを見ます。はじめに、表 A を選択します。
次に (if ◎ B)がきて、しかも◎が成り立つので、表 B を選択します。この文は if 文で、しかも条件式が成り立っているので、現在注目している並びの 「A (if ◎ B) C」のうち残りの部分は見ません。これで、「A(if ◎ B) C」という並びを見終えたことになりますが、この並びを含んでいたものは、when 文なので、さらに「(when ○ A (if ◎ B) C) (if ● D) E」という並びの、残りの部分を見ます。
次に書かれているのは、(if ● D)です。●が成り立つので、表 D を選択しますが、if 文なので、「(when ○ A (if ◎ B ) C ) (if ● D ) E」と いう並びのうち、残りの部分は見ません。こうして、表 A、B、D が選択されます。
次に、xjsi が使用するモード定義表を例に挙げます。
このモード定義表では、3 のモードが定義されています。そのあとの 2A_CTRL から最後までが使用する対応表とモード表示文字列の指定です。モードが変わるごとに、この表を見て、上記のようにして使用する表の選択を行います。
(defmode romkan) (defmode katakana) (defmode zenkaku) 2A_CTRL (if romkan 1B_TOUPPER 2B_ROMKANA 2B_JIS (if (not katakana) "[あr]") (if zenkaku 3B_KATAKANA "[アr]") 3B_HANKATA "[アイr]") ;「ア」と「イ」は半角のカタカナを示す 2B_DAKUTEN (if (not katakana) 1B_ZENHIRA (if zenkaku 3B_ZENKAKU "[あ ]") "[Aあ]") (if zenkaku 1B_ZENKATA 3B_ZENKAKU "[ア ]") "[アイA]" ;「ア」と「イ」は半角のカタカナを示す
初期状態は、romkan、katakana、zenkaku のモードすべてが off です。このとき表は、始めに 2A_CTRL を選択します。romkan が off なので、次の if 文は参照しません。そして 2B_DAKUTEN を選択します。次の if 文の条件式 (not katakana) は、katakana が off なので真となります。そこで if 文内を参照し、 1B_ZENHIRA を選択します。次に if 文内の if 文を参照します。この if 文では zenkaku が off になっているため、条件式が偽になります。したがって、 この if 文は参照しません。
次に、モード表示文字列「[Aあ]」を選択します。残りの変換表並びは見ません。
対応表には、前処理、本処理、後処理のそれぞれが行う変換データ (入力コードと出力コードとの対応) が記述されます。
前処理、後処理は、本処理の補助という位置付けになっています。そのため、前処理、後処理の対応表には次の制限があります。
下記の (2) の記述ができません。また、(1) の入力コードと出力コードには、それぞれ評価すると文字になる式が 1 つだけ書けます バッファー残りには書けません。
下記の (2) の記述ができません。また、(1) の入力コードには、評価すると文字になる式が 1 つだけ書けます。バッファー残りには書けません。
対応表の行のうちのある行は、次の (1) から (3) のうちのいずれか、または空行です。 この繰り返しで対応表が構成されます。
入力コード [出力コード [バッファー残り]]
入力コード 機能
変数宣言
これらは、2 行にわたって記述することはできません。改行または空白文字 (タブを含む) に続き、かつエスケープされていないセミコロン (;) から行末までの文は、注釈文として扱われます。
出力コードを省略した場合やバッファー残りを省略した場合は、NULL 文字列の文として扱われます。入力コード、出力コード、およびバッファー残りに記述できるのは、「評価すると文字になる式」と「評価すると文字列になる式」を空白なしに並べたものです。
ここで、「評価すると文字になる式」または「評価すると文字列になる式」とは、その式によって文字あるいは文字列に置き換わる式を指します。
「評価すると文字になる式」には、次のものがあります。
次のような文字表記になります (「評価すると文字列になる式」の文字表記とは異なります)。
「(」、「)」、「'」、「"」、「\」、「;」、「 」(空白文字) を除く文字。
「'」、「\」、「^」を除く文字。
コントロール文字を表します。文字は ASCIIコードの 32 から 126 の文字です。 「^?」は DEL コードを表します
文字は、数字と「o」「d」「x」は除きます。「\n」、「\t」、「\b」、「\r」、「\f」 は C 言語のエスケープ符号列と同じ文字を表します。「\e」、「\E」は ESC 文字を表します。他の文字は、その文字自身を表します。
指定された 8 進コードに相当する文字を表します。
指定された 8 進コードに相当する文字を表します。
指定された 10 進コードに相当する文字を表します。
指定された 16 進コードに相当する文字を表します。
関数名 | 機能 |
---|---|
toupper | 引数が ASCII 英小文字であれば大文字に変える 例: (toupper a) -> A |
tolower | 引数が ASCII 英大文字であれば小文字に変える 例: (tolower A) -> a |
toupdown | 引数が ASCII 英小 (大) 文字であれば大 (小) 文字に変える 例: (toupdown a) -> A (toupdown A) -> a |
tozenalpha | 引数が ASCII 文字であれば対応する全角文字に変える 例: (tozenalpha A) -> A |
tohira | 引数が全角カタカナであればひらがなに変える 例: (tohira ア) -> あ |
tokata | 引数がひらがなであれば全角カタカナに変える 例: (tokata あ) -> ア |
tozenhira | 引数が半角カタカナであればひらがなに変える 例: (tozenhira ア) -> あ ; 「ア」は半角カタカナ |
tozenkata | 引数が半角カタカナであれば全角カタカナに変える 例: (tozenkata ア) -> ア ; 「ア」は半角カタカナ |
value | 引数の文字コードを実際の数値にする 例: value 0 -> '\x0' value A -> '\xA' value F -> '\xf' |
関数名 | 機能 |
---|---|
+ | 引数の和を値にする 例: (+ あ '\d256') -> ア (+ 0 (value 3)) -> 3 |
– | 引数の差を値にする |
* | 引数の積を値にする |
/ | 引数の商を値にする |
関数名、機能、宣言名 (defvar) といずれも 一致しない英字で始まる英数字からなる文字列 (変数の項参照)。ただし、'_' も英字とみなします。
以下に、評価すると文字列になる式を示します。
次のような文字表記になります (「評価すると文字になる式」 の文字表記とは異なります)。
「"」、「^」、「\」を除く文字
コントロール文字を表します。文字は ASCIIコードの 32 から 126 の文字です。^? は、DELコードを表します。
数字と「o」「d」「x」を除く文字。「\n」、「\t」、「\b」、「\r」、「\f」 は C 言語のエスケープ符号列と同じです。
指定された 8 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) を指定します。
指定された 8 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) を指定します。
指定された 10 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) を指定します。
指定された 16 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) を指定します。
関数名 | 機能 |
---|---|
tohankata | 引数が全角ひらがなまたは全角カタカナであれば半角カタカナに変える 例: tohankata が -> ガ (半角) |
last= | 最後に照合した文字列の最後の文字と関数の引数 (評価すると文字になる式) が一致するかどうかを検査し、一致する場合 (last= 評価すると文字になる式) は空文字列になる。 例: last= A -> あ ただし、last= は入力コードにだけ記述できる。 |
todigit | 第 1 引数で与えられたコードを第 2 引数のコードの進法の数に変換する。 |
dakuadd | 引数の後ろに濁点を付ける。 |
handakuadd | 引数の後ろに半濁点を付ける。 |
モード名はモード定義表で宣言された名前にしてください。
関数名 | 機能 |
---|---|
if | 引数であるモードが on の場合、(if mode_name) は空文字列になる 例: (if katakana)VU ヴ |
unless | 引数であるモードが off の場合、(unless mode_name) は空文字列になる 例: (unless katakana)VU ぶ |
on | 引数であるモードを on にする 例: (on katakana) |
off | 引数であるモードを off にする 例: (off katakana) |
switch | 引数であるモードが on なら off に、off なら on にする 例: (switch katakana) |
ただし、if、unless は、入力コードにだけ記述できます。また、on、off、switch は、本処理表の出力コードにだけ記述できます。
本処理表の出力コードにだけ記述できます。
関数名 | 機能 |
---|---|
allon | すべてのモードを on にする |
alloff | すべてのモードを off にする |
関数は「評価すると文字になる式」または 「評価すると文字列になる式」であるため、(toupper (tolower Y)) と書けます。しかし、次のように評価すると文字列になる関数は他の関数の引数にできません。
(toupper (tohankata か))
次の 2 つがあり、それぞれ単独で用いられます。
入力コードの部分のコードが入力された場合、エラーとみなします。
前回のモード定義表をあらためて読み込んで変換の再設定を行います。新しい変換表にエラーがあればエラーメッセージを表示したあと、元の変換表の設定に戻します。
list は、その引数の文字を変域とします。
all は、すべての文字を変域とします。
between は、コード順に並べた時に、文字表記 1 と文字表記 2 の間に含まれる文字 (両端を含む) を変域とします。
「評価すると文字になる式」として使用する変数とその変域を定義します。変数は、それを使用する表の中で宣言します。
変数表記は、変数名、または (変数名. . . . . .) です。文字表記は、「評価すると文字になる式」の文字表記と同じです。
変数の定義は、その表全体で有効になります。1 つの表の中で、同名の変数を 2 度 defvar で宣言することはできません。
1 つの表で a1 という変数を定義し、別の表でまた a1という変数を別仕様で定義することができます。この 2 つの a1 という変数は別々に処理されます。
変数は同一パターンの変換が何通りもある場合に効果を発揮します。次に例を示します。
(defvar a1 (list K S T H Y R W G Z D B P)) (a1)(a1) っ (a1)
KK | っ | K |
SS | っ | S |
TT | っ | T |
. . . | ||
(中略) | ||
PP | っ | P |
変数宣言で行われた変域の文字について処理されます。
(between A E) は (list A B C D E) と同じです。
使用する変数はその表の中において変数宣言で定義してください。
1 つの表で a1 という変数を定義し、別の表で a1 という変数を別様に定義することができます。この 2 つの a1 は別の変数として扱われます。変数の定義はその表の中全体で有効です。1 つの表の中で同名の変数を 2 度変数宣言することはできません。
対応表の 1 行の中では、同名の変数は常に同じ値をもちます。
(defvar a1 (list A B)) (a1)(tolower (a1)) 3
この場合、「Aa 」、「Bb」という文字列が「3」に変換されます。「Ab」、「Ba」は変換されません。
入力コードと表の入力コード部との照合は左から行われます。このため、表の入力コード部を左から見た場合、ある変数が特定の文字に 一致する前に関数の引数として現れることはできません。
(defvar a1 (list a b)) (toupper (a1))(a1) 3
この場合、「Aa」と入力しても、「3」には変換されません。これは、値が特定されていない状態で a1 が (toupper (a1)) に引数として現れるからです。このような設定は、表読み込み時にチェックされます。
この場合、次のように変更すれば期待する動作を得ることができます。
(defvar a1 (list a b)) (a1)(toupper (a1)) 3
(defvar a1 (list A B)) (a1)(toupper (a1)) 3
「Aa」「Bb」を入力すると「 3」に変換します。
変数を出力コード部やバッファー残り部に書く場合も、入力コード部に現れた (つまり、入力コードとの 照合で何らかの値を代入された) 変数でなければなりません。
(defvar a1 (list K S)) (defvar a2 (list a)) (a1)(a1) (a2) (a1)
この場合、入力コード部で照合が行われない 変数 a2 が出力コード部に現れているので誤設定になります。
まず、入力されるコードを文字単位にまとめます (2 バイトコードの文字も 1 文字として扱います)。これを入力コードといいます。
前処理では、入力コード 1 つに対して出力コード 1 つが対応付けられます。この出力コードが本処理での入力コードになります。
前処理表のうち現在使用されている表の入力コードの部分を上から順に見ます。最初に実際の入力コードと合致したところで、その行の出力コードの部分に当たるコードが出力されます。
ただし、表が複数選択されているときは、モード定義表で先に参照されたものから見ています。また、実際の入力コードと 合致するものが表にないとき (表が 1 つも選択されない時も含む) は、入力コ ードがそのまま出力されます。これは、本処理、後処理においても同様です。
本処理では、入力コードが表の入力コードの部分と合致する可能性がある (入力コードの部分の先頭から何文字かは一致している状態) 限り、入力コードは バッファーに追加されます。
バッファーに入力コードが追加されるごとに、本処理表の入力コードの部分を上から順に見て、バッファーと比較されます。ここで、バッファーの内容が表の入力コードの部分の最長のものと合致する可能性 (入力 コード部分に、先頭から何文字かは一致している状態) があれば、変換未確定となり、変換を行わずに次の入力コードを待ちます。ただし、画面処理などの都合上、バッファー内のコードは未確定文字として出力されます。
その他、入力エラー、モード変更などを知らせるコードも出力されます。これらの出力コードは本来の出力コードとは区別され、後処理は行われません。バッファーの内容が表の入力コードの部分の最長のものと合致すると (同じ長さのものがあれば先に見つかったものと合致します)、その出力コードが出力されます。バッファー残りの部分がなければ、バッファー内の合致した部分が消されます。バッファー残りの部分があれば、バッファー内の合致した部分と入れ替わり、以上の操作が繰り返されます。
表に合致する可能性のあるものが見つからなかった場合、バッファーの先頭の 1 文字がそのまま出力されます。合致したけれども出力コードの部分がモードの状態を変える関数 (on、off、switch など) である場合、使用される対応表がモー ド定義表の記述にしたがって変更されます。これらのモードを変える関数は、モ ードの状態 (on、off) に関係なく、常に使用される表に記述してください。
また、機能の (restart) の入力コードの部分に合致した場合は、モード定義表そのものが再度読み込まれます。ただし、そのモード定義表は前回と同じファイルです。この機能を使うことで、オートマトンの使用中に修正した変換表 (モード定義表を含む) を、オートマトンを終了せずに読み込み直すことができます。
後処理では、1 つの入力コードに対して 1 つ以上の出力コードが最終出力として出力されます。出力コードが 1 つ以上出力されることを除いて「前処理」と同じです。
以下の例では、「Ls」または「LS」が入力されたとき「ls –la (改行)」が出力されます。