DrGeoIIをgettext対応させる(開発環境編)

アップデート1716〜1719で、先月から開発してきた gettextエミュレーションエンジンがOLPC EToysのイメージに組み込まれました(id:propellaさんに感謝)。
これにより以下のことが可能になります。

  • イメージの外部に置いたMOファイル形式の翻訳データを実行時に使って、プログラム中に現れるフレーズを翻訳することができます。
  • gettextと同様に、翻訳辞書はテキストドメイン(通常アプリケーションパッケージに対応)の単位で分割管理できます。アドオン用のMOを所定の場所に置けばそれが使われます。

早速、http://d.hatena.ne.jp/korakurider/20071012/p1 でも取り上げた DrGeoII をこの変更に対応させてみて、課題を検討してみます。

ステップ1:Squeakの実行環境をgettextベースに切り替える

update 1716-1719で、翻訳関係のフレームワークが大幅に変更されています。
Squeakが起動した時インストールされているMOファイルを探して、ある言語用のMOファイルが配置されていれば、その言語用にはgettextをエミュレートする翻訳エンジン(GetTextTranslator)が使われます。MOがなければ、イメージ内部の辞書を使う翻訳エンジン(InternalTranslator、従来のNaturalLanguageTranslatorに相当)が使われます。
実行時に、どちらの辞書が使われているかは、以下をPrintItすれば見ることができます。

NaturalLanguageTranslator translators 
a Dictionary(de->GetTextTranslator(de) en->GetTextTranslator(en) es->GetTextTranslator(es) fr->GetTextTranslator(fr) ja->GetTextTranslator(ja) pt->InternalTranslator(pt) ptx->GetTextTranslator(ptx) )

この例は、de,en,es,fr,jaの各言語のMOを配置した環境で実行したものです。もともとあったpt(ポルトガル語)のMOを ptxという言語用にフォルダを改名して置いています。すると、ptx用にGetTextTranslatorが動的に作成されています。つまり、所定の命名規則でMOを置けば、自動的にそのロケールIDが使用可能になっています。そしてポルトガル語用には、イメージ内の翻訳辞書が使われるようになっています。

OLPC Etoysのパッケージには etoys.poおよびそれをコンパイルした etoys.moが含まれます。
それを イメージの下の lang/言語/LC_MESSAGE の下に置いておくと、Squeak起動時に自動的に認識され、gettextエミュレーションが使われます。

ステップ2:開発環境としてのDrGeoIIのインストール

このパッケージはSARとして配布されており、その中にはすでにいくつかの言語用の翻訳データ(*.po)が含まれています。しかし、ここではアドオンパッケージを開発する過程をシミュレーションするため、パッケージに入っているpoは使いません。
ダウンロードしたDrGeoII.sar の拡張子をzipに変更してから解凍し、中に入っているDrGeoII-jhr.79.mczをイメージにロードします。

ステップ3:アドオンパッケージに対応するテキストドメインを登録する

テキストドメインを分割するには、それに属するクラスカテゴリを登録することが必要です。以下をDoItします。(ドメイン名は DrGeoIIとします)

TextDomainManager registerClassCategory: 'DrGeoII-AppDomain' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-AppDomain-Builder' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-AppDomain-Command' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-AppDomain-MathItem' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-AppModel' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-AppView' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-GeometryView' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-GeometryPresenter' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-GeometryModel' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-Graphics' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-Infrastructure' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-Script' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-Tree' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-UI' domain: 'DrGeoII'.
TextDomainManager registerClassCategory: 'DrGeoII-Morphic' domain: 'DrGeoII'.

ステップ4:POT(翻訳データのテンプレート)を切り出す

すでに実現されている切り出し機能を実行します。以下をDoItすると、poフォルダ以下に各ドメインのテンプレートが生成されます。DrGeoII用のものは、po/DrGeoII/DrGeoII.pot として生成されます。

GetTextExporter2 exportTemplate

ステップ5:特定言語用の翻訳データを作る

POTを編集してPOファイルを作成し、これをコンパイルしてMOファイルを作成します。このプロセスは通常のgettext関係のツールによる作業です。
そして、Squeakのイメージがある場所の下の lang/<言語>/LC_MESSAGES の下に その言語用のMOファイルを置きます。

次のステップと課題

  • 実は、String>>translated がまだ複数ドメインに対応できていませんので、まずこれを実装することが必要です。今のままだと、アドオンの追加MOが使われません。
  • 現状TextDomainManagerのAPIは貧弱なため、ステップ3のコードは無駄が多くなっています。パッケージ名のように、カテゴリ名の先頭部分を与えることで、一致するものすべてがそのドメインに含まれるという指定のしかたができると便利そうです。
  • #translatedでのドメイン名の動的解決に使われるので、カテゴリやドメインはシンボルで取り扱うようにしたほうがよさそうです。
  • ステップ4の操作など、GetTextExporter2の機能は登録されている全ドメインを対象にして一括処理しているので、特定ドメイン単位の処理もできるとよさそうです。