[32]
The TECkit language
(.map
ファイル)
は、
TECkit
で使われている文字コードの変換の規則を記述するファイル形式です。
[1] >>11 は言語仕様というよりは利用の手引の類で、その種のものにしては細かく説明しているものの、 ファイル形式の形式と意味の規定としてみると精密さに欠けます。
[33] >>11 の他に TECkit のプログラムの挙動やソースコード、
あるいは実際の .map
ファイルの利用事例を見て研究する必要があります。
[48] 主に文字コード変換に使われます。 Unicode ではない従来の文字コードと Unicode との相互変換の方法を記述することができます。
[49] 文字コードの変換の実装は多く存在しますが、 TECkit は主に東欧から中東、南アジアにかけての地域などの文字を使う研究者に使われることが多いようです。 そうした研究者はいわゆるフォント依存符号化のような専用の文字コード体系を20世紀末から21世紀初期に使っていましたが、 欧米の商用製品が実装している文字コード体系とは違うものが多く、 当該地域の一般住民の使っていた文字コード体系とも必ずしも一致していないので、 専用の実装を必要としています。
[51]
.map
は1対1の単純な写像だけでなく、
前後の文脈に応じた複雑な変換処理を記述できます。
記述能力は正則表現に近いですが、
無限の反復を認めないなど制限があります。
[66]
Unicode 以前の文字コードと Unicode とでは基底文字と結合文字の順序が逆のことがあり (
[67] 印度系文字の文字コードと Unicode とでは文字の扱い方が大きくことなる場合がほとんどです。 従来文字コード、特にフォント依存符号化は8ビット符号用フォントの限られた字数の制約と既存の文字のレンダリングの仕組みの流用という仕組み上、 文字の素朴な見た目をそのまま順番に表現していることが多いです。 一方 Unicode は Unicode 独自の理論に整合する一貫した方法を採用しているので、 かなり複雑な組み合わせで記述することになります。 文字のレンダリングの際には complex script の処理と言われる複雑な手順で Unicode文字列をグリフ列に置換することになりますが、 おおよそこれに相当する変換処理が必要になります。
[68]
南アジアの現地住民による実装などを除けば、汎用のソフトウェア (Webブラウザー等)
の文字コードの変換の処理では >>67 のような複雑なものはほとんど実装事例がなく、
TECkit や .map
の大きな特徴といえます。
[50]
.map
では変換の一方を左辺 (LHS)、他方を右辺 (RHS) と呼んでいます。
順方向の変換 >
は左辺から右辺に、
逆方向の変換 <
は右辺から左辺にと行われます。
演算子 >
, <
, <>
を使い分けて1つのファイルで両方向の関係を同時に記述します。
[52]
.map
では
Unicode でない文字コードを byte、
Unicode のことを Unicode や uni と呼んでいます。
[53]
.map
は変換を多段で記述でき、
各段のことを pass と呼んでいます。
順方向では前 pass の右辺が次 pass の左辺になります。
pass の入出力は byte または unicode で4種類あり、
byte_unicode
(左辺 byte, 右辺 unicode)、
unicode_byte
、
byte
、
unicode
と呼ばれています。
[54]
>>53 の他に NFC や NFD の適用を表す pass があります
(必然的にそれらは unicode から unicode への変換になります)。
また、
LHSFlags
や RHSFlags
に
ExpectsNFC
, ExpectsNFD
という値があり、入力が NFC, NFD であることを期待する指定ができます。
.map
の処理の前段階として適用することになります。
LHSFlags
や RHSFlags
には
GenratesNFC
, GeneratesNFD
という値もありますが、どちらかというと処理の指定ではなく処理結果を表明するもののようです
(保証するわけではありません)。.map
を書く分には使っても構わないのでしょう。
適切に使えば写像を単純化できます (Unicode に合成済文字が多いラテン文字で特に有用そうです)。[57]
pass が明示されていないと、全体が byte_unicode
の1つの pass になります。
[58] pass の数や種類には制限がないようです。 ただし前段の出力と後段の入力が矛盾するものは認められません。 多段化することで複雑な変換を単純に書けることもある一方で、 全体の入力と出力の関係性が非常にわかりにくくなります。
[59] すべての pass を組み合わせた全体としては byte から unicode となるものが多いですが、 そうでないものもあります。
[60] 変換の両辺は byte や unicode の文字1つと一致することもあれば、 いくつかの文字の列と一致することもあります。 空に置換される (削除される) こともあります。
[62] 変換の両辺には一致部分の他に、直前の条件や直後の条件やその両方を書くこともできます。
[63] 一致や条件は反復数を指定することもできます。ただし15個までに制限されていて、 無限の連続は指定できません。
[64]
条件には文字の他に境界を表す #
も指定できます。
[61]
変換の規則は何個でも書くことができます。
複数の規則に一致する場合は、一致部分 (前後の条件も含む。) の文字数が長いものが優先されます。
同数なら .map
の先のものが優先されます。
(.map
に記述した要素数ではなく一致した文字数です。)
[65]
>>61 のために .map
の解析は一見して感じられるものよりかなり複雑になります。
単純に変換処理をしたいだけなら上から順にすべて処理して選べばいいだけですが、
変換表の性質を理解したいときは前後の条件や文字クラスや反復が相互にどう作用するのか見極める必要が出てきます。
regions/Asia/PH/legacy/sil-phil-ansi/mappings/PhilAnsiSIL.map
scripts/Grek/legacy/sil-galatia/mappings/SILGreek.map
scripts/Ethi/legacy/geez/mappings/Geez to Unicode.map
scripts/Arab/SenAjami/mappings/SenAjami.map
scripts/Ethi/legacy/sil-eth-m/mappings/SIL Eth M.map
scripts/Plrd/legacy/lipo3/mappings/lipo3.map
scripts/Latn/legacy/windows-symbol-cp1252/mappings/Windows-SymbolEncodedFont.map
regions/Americas/MX/legacy/sil-mexico/mappings/CHNCCR1.map
langs/r/rap/legacy/sil-rap/mappings/SIL_RAP.map
scripts/Deva/legacy/annapurna/mappings/Annapurna.map
scripts/Sinh/legacy/sinhala_07/sinhala_07.map
scripts/Talu/logical2visual/logical2visual.map
regions/Americas/MX/legacy/sil-mexico/mappings/MTCSTDMR.map
langs/m/mav/marktnr_satere/mav_satere.map
scripts/Music/legacy/musique/mappings/SIL-SA_MUSIQUE-2007.map
scripts/Grek/legacy/wingreek/mappings/WinGreek.map
scripts/Latn/legacy/windows-symbol-cp1252/mappings/Windows-SymbolEncodedFont.map
scripts/Latn/legacy/windows-symbol-cp42/mappings/Windows-SymbolEncodedFont2SymbolCP.map
scripts/Telu/legacy/nlci-winscript-telugu/mappings/WinScrTel.map
[4] >>3 注釈に ISO/IEC 8859-1 と思われる文字
[16] >>13 Copyright
の値 (文字列リテラル) に UTF-8 文字©
を含む事例
[18] >>8 に含まれる .map
ファイルの限りにおいては考慮するべき非ASCII文字は
>>16 のような©
(UTF-8) のみのことがほとんどです。それ以外は注釈に非ASCII文字が含まれることも少なくありませんが、
UTF-8 のものだけでなく >>4 のような事例も紛れ込んでいるので注意が必要です。
[36] >>34 は例外で、変換式の文字列リテラルでも UTF-8 文字を使っています。
[39] UTF-8 BOM
が先頭についているファイルがあります。
[23] >>21 "
, >>22 '
で始まる文字列リテラルが改行まで閉じられていない事例
[24] TECkit のソースコードを見ると改行もリテラルの終わりと明示的に作られていて、 エラーメッセージも特に出していません。
EncodingName "a canonical name that uniquely identifies this mapping table from all others" DescriptiveName "a string that describes the mapping" Version "1" Contact "mailto:user@addr" RegistrationAuthority "the organization responsible for the encoding" RegistrationName "the name and version of the mapping, as recognized by that authority" Copyright "© 2017 <CompanyName>. All rights reserved."
とあまりに雑なメタデータ。 そう、処理に使われないメタデータは真面目に書いてもらえない(ことがよくある)、 これは世界の普遍の法則。
Contact "mailto:(@sil.org)"
なんだこの mailto:
URL は。 mailto:
の続きは RFC 822
メールアドレスなので括弧に含まれるのは注釈。・・・ではさすがにないと思われるが。
[76]
なお公式ドキュメント >>11 では Contact の値は
mailto:
URL が typical form と書いているだけなので、
実は何でもいいということに。実際
>>74
は
Contact 'Bob Hallissy at SIL'
としていてもはやメールアドレスですらない。
[38] >>37 VisualOrder
を指定した事例 (他にほとんどない)
[72] >>71 左辺が byte であるにも関わらず LHSFlags
に ExpectsNFC
を指定した事例
[7] >>6 ByteDefault
に 0x3F 以外を指定した事例
[73]
ドキュメントによると ByteDefault
, UniDefault
は byte_unicode
, unicode_byte
の pass に属するべきものです。ところが
>>70 は .map
上に明記された pass は1つで unicode
。
その直前の pass に属さない部分に UniDefault
があります。
byte との変換が発生し得ないのでこの UniDefault
には意味がありません。
[47] >>46 は Unicode - Unicode 変換という形式になっているが、 左辺の Unicode は実際には Windows-1252 のフォントの一部文字を独自に差し替えたもの。 CR に Windows-1252 が割り当てた文字があるので Latin1 以外の領域の Unicode文字も左辺に入ってくる。
[75] >>74 は Unicode から Unicode への変換ファイルの事例
[80]
>>79 は Unicode から byte への変換ファイルの事例。 pass が Unicode_Byte
になっているのは非常に珍しい。
注釈によると UTF-8 に誤変換されたデータを処理するときに前段としてこれで8ビット符号に戻すために使うとのこと。
[5] >>3 バイトクラス・Unicodeクラスで定義されている対応と直接記述されている対応で重複がある
(どちらの定義も同等)。 U+00D1
, U+00D2
, U+00D3
, U+00D4
この他にも何らかの理由重複される変換式があって一方が常に無視されるものが含まれるファイルはかなりある。
(双方向の変換式でうち一方向が無視されるものもある。)
[26]
>>25 >>40
PUA
という謎の値が出現する事例。ドキュメントにある字句の中だと定義 (マクロ) か、
そうでなければ文字の名前扱いになるはずだが、
そのような定義は無いし、
文字の名前が PUA
であるものは存在しない。また、
PUA
というクラスが定義されているわけでもないし、
クラスは構文も違う。
このような PUA
が変換式に含まれるファイルは他にもいくつかある。
0xD7 <> U+256B BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -- SILID 9090* + SILID 0129 (space glyph ignored) + SILID 9090* + SILID 9090* + SILID 9090* + SILID 9075*
なんだこの行は。他の行と比べると本来 BOX
の前に ;
が入って注釈になるべきが何らかの理由で消えてしまったか。
しかしこのファイルで TECkit は読み込めるのか。
それともコミット後に誰も使っていないのか。
[12] >>9 変換先が U+FFFD
を含む文字列の事例 (人間向けに注釈あり)
[43] この他 ByteDefault
や UniDefault
が変換式に直接出てくる事例はいくつもある。
変換先が存在しないものであることを明示的に示したかったのか、
あるいは変換式同士の優先順位の関係で明示しないといけないケースもときにはあるのか。
[44] <>
なのに変換先が U+FFFD
のものが複数ある
(つまり逆変換が重複しているので1つ以外は無視される)
というケースもたまにあって、そういうのは何も考えて無さそう。
[28]
>>27 'id '
から始まるおもしろい変換式。 \id
から始まる行は通常の変換ではなくそのまま ASCII から Unicode
に写像する意図らしい。 .map
の表現力で無理矢理記述した結果と思われる。
言語仕様ドキュメントではクラスはその位置で対応付けるとしか説明がなく、
クラス以外の字句の扱いが不明瞭だし、 .map
の字句の位置なのか一致した文字列の数(?)なのかよくわからない。ソースコードを読んだ感じだと、
.map
上の字句の数で対応付けているように見える。
が、そうだとするとこの変換は正しく処理されないような気もするが...
なお同じ変換式があるファイルが他にもいくつかある。
[30]
>>29 (X=a | Y=b) <> @a @b
型の変換式がある。
|
による選択があることに注意。 <>
なので両方向の変換に使われる。
左辺から右辺への変換は良いが、右辺から左辺への変換でこれが何を表すのか、
言語仕様ドキュメントを読んでも判然としない。
他のいくつかのファイルにもこの形式の変換式がある。
[45]
ファイル仕様上はすべてのファイルが正方向と逆方向の両方の変換に対応することになっていそうだが、
実際のファイルでどこまでしっかり作り込まれているのかは怪しい。正方向が動作するのは当然として、
逆方向が不安なものもちらほら。また、 >
ばかりで逆方向の変換が皆無のファイルもあって、
当然逆方向に変換しても意味がない (未対応という意味で意図的にそうしているのかも)。
[131]
>>129 build/
で make
したら .map
が生成される
[134]
>>129 deva-san.map
が pass 10段階
[135]
>>129 独自?の PUA に変換しているものも多い。 U+FFFD
に変換しているものも多い。
[86] >>84 Define U
している事例。字句解析で気をつけないと
U+1234
の U
を置換してしまう。
[87] >>84, >>96 条件付きの削除 (右辺空) の事例
[136]
>>137 arabtex-farsi-fullvoc.map
に ^#
の事例
[83] >>82 UTF-8 文字の文字列リテラルを利用。
[119]
>>117 変換式の末尾の文字列リテラルを閉じる "
がない事例
U+0905U+0902<>U+1E43;अं ṃ U+0905U+0903<>U+1E25;अः ḥ U+0905U+0901<>U+006FU+0302;अँ ô
のように U+ 字句の間に空白がない事例
[98] >>89 U+1E6D 'U+1E6C h' 'U+1E6D h' U+1E0C
のような値がある。
ただの文字列リテラル。何を意図していたものか。
[99]
>>89 UniClass
の定義中に文字列リテラル。UTF-8 文字も。
[126] >>123 pass が11段もある事例。流通しているファイルの中ではこれが最大か?
[127]
>>123 ([X])=a <> ([Y])=a
型のグループ化で一見隠された文字クラス同士の対応関係を使う事例
[100] >>91 は Unihan から機械的に生成したらしいファイル。 >>88 にもある。
[101] >>91 はとても雑で、 Unihan が異体字を列挙 (or) したものまでそのままにしているので、 異体字が並んだ文字列が変換結果になってしまっているw データの意味も理解しないで雑に処理して検証もしていないということ。
[102] なお簡体字・繁体字の変換は中華圏で需要が多く専門のソフトウェアやデータが盛んに開発されていて、
そちらの方がより正確で豊富。
[103] >>91 はおそらく .map
として流通しているものの中でも変換式の量は最大級なので、
そういう検証には有用。ただ .map
としての複雑度は簡単な部類。 >>102
のようなデータは (.map
ではないが) もっと複雑なことをしている。
TECkit が簡体字と繁体字の変換にも適用可能かというのは理論的に面白いテーマではある
(>>91 はその回答にはまったくなっていないが)。
[120] Bibledit, , https://web.archive.org/web/20210618185016/https://www.nongnu.org/bibledit/teckit_mapping_rules_reference.html