Msgcat Tcl

ReferenceTOPKeywords

解説

msgcatパッケージは多言語のユーザーインタフェースを管理するために使われる関数セットを提供します。 テキスト文字列はアプリケーションから独立していて、アプリケーションソースコードを修正せずに編集またはローカライズされる”メッセージ カタログ”において定義されます。 新しい言語またはローカル版は新しいファイルをメッセージカタログに追加することによって提供されます。

アプリケーションまたはパッケージにとってメッセージカタログの使用は省略可能なオプションですが、アプリケーションまたはパッケージが多言語のアプリケーションを可能にする場合、使用することを薦めます。

構文

package require Tcl 8.2
package require msgcat 1.3
::msgcat::mc src-string ?arg arg ...?
::msgcat::mcmax ?src-string src-string ...?
::msgcat::mclocale ?newLocale?
::msgcat::mcpreferences
::msgcat::mcload dirname
::msgcat::mcset locale src-string ?translate-string?
::msgcat::mcmset locale src-trans-list
::msgcat::mcunknown locale src-string

コマンド

::msgcat::mc src‐string ?arg arg ... ?
ユーザーの現在のロケールに従ってssrc‐string の翻訳を返します。src‐string への追加引数が与えられたら、 formatコマンドはsrc‐string の翻訳の追加引数を置換するために使われます。 src‐string の翻訳に対して、::msgcat::mcは現在のネームスペースで定義されたメッセージを検索します。何も発見されない場合、 現在ネームスペースの親スペースにおいて検索を試みます。 発見されるまでグローバルネームスペースに達するまで繰り返します。 翻訳文字列が存在しない場合、::msgcat::mcunknownは呼ばれ、::msgcat::mcunknownから返された文字列が返されます。

::msgcat::mcはアプリケーションをローカル化するのに使われる主な関数です。 英語の文字列を直接、使う代りにアプリケーションは::msgcat::mcに英語の文字列を渡し、その結果 を使います。 アプリケーションがこの方式で単一言語のために書かれたものでも、単に新しいメッセージカタログエントリを定義することによって、後でほかの言語へのサポートを加えることは容易になります。

::msgcat::mcmax ?ssrc‐string src‐string ...?
いくらかのソース文字列を与えられ、::msgcat::mcmaxは最長の変換された文字列の長さを返します。 これはローカル化したGUIを設計することに役に立ちます。 このようなGUIは、例えば、 全てのボタンが固定した幅(それが一番幅広いボタンの幅である)であることを必要とするかもしれません。

::msgcat::mclocale ?newLocale ?
この関数はロケールをnewLocaleに設定します。 newLocaleが省略されると、現在のロケールは返されます。そうでないと、現在のロケールはnewLocale に設定されます。msgcatは大小文字を区別しない方法でロケールを保存と異なり、小文字でロケールを返します。 最初のロケール情報はユーザーの環境に指定されたロケールによって決定されます。 ロケール文字列の格式に関する記述は下述のLOCALE SPECIFICATION を参照して下さい。

::msgcat::mcpreferences
ユーザーの言語設定に基づいて、ユーザーによって選択されたロケールの順番リストを返します。このリストは最も好むものから最も好まないものへの順番で返されます。 このリストはmsgcat::mclocaleによってmsgcatに設定された現在のロケールから得られるが、独立して設定されることができません。例えば、 現在のロケールがen_US_funkyであると、msgcat::mcpreferencesは{ en_US_funky en_US en }を返します。

::msgcat::mcload dirname
::msgcat::mcpreferences から返された言語指定 ( これらの全てが小文字であることに注意しましょう )にマッチした拡張子”.msg”を持つファイルを、指定されたディレクトリから検索します。 各マッチしたファイルはUTF-8エンコーディングと仮定され、順番に読まれます。 ファイル内容はTclスクリプトとして評価されます。 これは非ラテン文字が直接メッセージファイルに現れることを意味します。 UTF-8エンコーディングされた形式になっているか、あるいはTcl評価で識別されたバックスラッシュ‐u引用になっています。 言語にマッチしてロードされたメッセージファイルの数が返されます。

::msgcat::mcset locale src‐string ?translate-string?
translate‐stringに、指定されたlocale 及び現在のネームスペースのsrc‐string の翻訳を設定します。 translate‐string が指定されないと、src‐string は両方の引数として使われます。この関数は translate‐string を返します。

::msgcat::mcmset locale src-trans-list
src-trans-listに指定されたlocale、及び現在のネームスペースで多重ソース文字列の翻訳を設定します。src-trans-list は偶数個の要素を持っていなければならず、そして{src‐string translatestring  ?src‐string translatestring ...?} のような形式です。msgcat::mcmsetmsgcat::mcsetの多重呼び出しよりかなり速いです。 この関数は翻訳セットの数を返します。

::msgcat::mcunknown locale src‐string 
src‐string の翻訳が現在のロケールで定義されない場合、このルーチンは::msgcat::mcによって呼ばれます。 デフォルト動作はsrc‐string を返します。 このプロシージャはアプリケーションによって再定義されることが可能です。 例えば、各未知の文字列に対するエラーメッセージを記録します。  ::msgcat::mcunknownプロシージャは::msgcat::mcへの呼び出しと同じスタック文脈で呼び出されます。 ::msgcat::mcunknownの返り値は::msgcat::mcへの呼び出しの返り値として使われます。

ロケール仕様

msgcatに対するロケール指定は、::msgcat::mclocaleへ渡したロケール文字列によって行います。 ロケール文字列は言語コード、選択可能な国コード、 そして選択可能なシステム‐特定のコードから成り、”_”によってそれぞれ区切られます。 国と言語コードは標準ISO-639とISO-3166で指定されます。 例えば、ロケール”en”は英語を指定し、”en_US”は米国の英語を指定します。

msgcatパッケージが最初にロードされるとき、ロケールはユーザーの環境に従って初期化されます。変数env ( LC_ALL ) env ( LC_MESSAGES ) 、そしてenv ( LANG ) は順番に検査されます。それらのうち最初非空値を持つものは最初のロケールを決定するために使われます。 この値は下記XPG4パターンに従って解析され、そのパーツを抽出します。

language[_country][.codeset][@modifier]

最初のロケールは以下の引数を使ってmsgcat::mclocaleを呼ぶことによって設定されます。

language[_country][_modifier]

Windowsで、これらの環境変数のいずれも設定されないと、msgcatはレジストリからロケール情報を抽出しようと試みます。 ユーザーの環境から最初のロケール情報を検索するための全ての試みが失敗した場合、msgcatは”C”の最初のロケールにデフォルトにします。

ロケールがユーザーに指定されるとき、文字列の翻訳では”best match”検索で行われます。 例えば、ユーザーがen_GB_Funkyを指定するならば、 マッチしている翻訳文字列を発見するまで、ロケール”en_GB_Funky”、”en_GB”、そして”en”は順番に検索されます。 利用可能な翻訳文字列がない場合、::msgcat::unknownは呼び出されます。

ネームスペースとメッセージカタログ

メッセージカタログに格納される文字列は、加えられたネームスペースに相対的に格納されます。 これは多重パッケージが他のパッケージと衝突することなく、同じ文字列を使うことを可能にします。 そして、これはより短く、出力エラーの少ないソース文字列を許可します。

例えば、下のコードの実行では

mcset en hello "hello from ::"
namespace eval foo {mcset en hello "hello from ::foo"}
puts [mc hello]
namespace eval foo {puts [mc hello]}

以下のものを出力します。

hello from ::
hello from ::foo

メッセージの翻訳を検索するとき、メッセージカタログは最初に現在のネームスペースを検索し、そして現在のネームスペースの親を検索します。 グローバルネームスペースに到達するまで繰り返します。これはサブネームスペースが親ネームスペースからメッセージを”継承”することを可能にします。

例えば、 (”en”ロケールで ) 下記のコードの実行では

mcset en m1 ":: message1"
mcset en m2 ":: message2"
mcset en m3 ":: message3"
namespace eval ::foo {
    mcset en m2 "::foo message2"
    mcset en m3 "::foo message3"
}
namespace eval ::foo::bar {
    mcset en m3 "::foo::bar message3"
}
puts "[mc m1]; [mc m2]; [mc m3]"
namespace eval ::foo {puts "[mc m1]; [mc m2]; [mc m3]"}
namespace eval ::foo::bar {puts "[mc m1]; [mc m2]; [mc m3]"}

以下のものを出力します。

:: message1; :: message2; :: message3
:: message1; ::foo message2; ::foo message3
:: message1; ::foo message2; ::foo::bar message3

メッセージファイルのロケーションとフォーマット

メッセージファイルは次の条件に合えば、あらゆるディレクトリに置けます。

[1]
単一パッケージの全てのメッセージファイルが同じディレクトリにある場合。
[2]
メッセージファイル名が”.msg”が付いているmsgcatロケール指定子(全部小文字)。例えば
es.msg    -- spanish
en_gb.msg -- United Kingdom English
[3]
mcsetmcmsetへの一連の呼び出しを含み、言語の必要な翻訳文字列を設定したファイル。 これらの呼び出しは、全てのソース文字列がパッケージのネームスペースに縛り付けられるために、namespace evalに納められるでしょう。 例えば、短いes.msgは以下の情報を含むでしょう。
namespace eval ::mypackage {
    ::msgcat::mcset es "Free Beer!" "Cerveza Gracias!"
}

推薦パッケージのメッセージ設定

パッケージがtcl_pkgPathのサブディレクトリにインストールされ、package requireによってロードされる場合、次の手順が薦められます。

[1]
パッケージインストール時に、パッケージディレクトリの中でサブディレクトリmsgsを作成します。
[2]
*.msgファイルをそのディレクトリにコピーする。
[3]
次のコマンドをパッケージ初期化スクリプトに加える。
# load language files, stored in msgs subdirectory
::msgcat::mcload [file join [file dirname [info script]] msgs]

フォーマットとスキャンコマンドの位取りコード

formatへの引数として使われるメッセージ文字列として、再び位 置を決める必要がある、位置依存のパラメータを持つことは可能です。 例えば、翻訳している間に、文の構造を再整理することは文法的に望ましいことです。

format "We produced %d units in location %s" $num $city
format "In location %s we produced %d units" $city $num

これは位取りパラメータを使うことによって扱えます。

format "We produced %1\$d units in location %2\$s" $num $city
format "In location %2\$s we produced %1\$d units" $num $city

同様に、位取りパラメータは国際化された文字列から値を抽出する scanに使われます。

感謝

メッセージカタログコードは Mark Harrisonによって開発されました。

参照

format, scan, namespace, package

キーワード

internationalization, i18n, localization, l10n, message, text, translation


Copyright © 1998 Mark Harrison. Copyright © 1995-1997 Roger E. Critchlow Jr.