Ruby GetText Package

Ruby GetText Packageとは?

Ruby GetText Package は GNU gettextによく似たライブラリです。このライブラリを使うことであなたのRubyスクリプト中の文字列を簡単にローカライズでき、国際化されたアプリケーションを作ることができます。
基本的な考え方はGNU gettextと同じです。インターネット上に解説されたものが多々ありますのでそちらをご覧になってください(← 手抜き)。

提供する機能

ユーザにお願いすること

本ライブラリを用いて開発したツールを使用する場合は、事前に以下の情報を設定してもらう必要があります。

必要環境

ダウンロード

<URL:http://ponx.s5.xrea.com/hiki/ja/ruby-gettext.html>

インストール方法

コマンドラインで以下のようにうちこんでください。UNIX 系 OS ではおそらくroot権限が必要になります。

# ruby install.rb config
# ruby install.rb setup
# ruby install.rb install

インストール先を変更したりすることもできます。その場合は ruby install.rb --help を実行してみてください。

基本用語説明

pot, poファイル

スクリプトファイルからrgettextツールを使用して生成されたテキストファイル(msgidとmsgstrの対)、および、それを翻訳したもの(言語毎に作成)。

moファイル

msgidとローカライズされた文字列の対が入っているバイナリファイル。poファイルからmsgfmtツールを使用して生成します。言語毎に必要です。

domain(TextDomain)

domainとは要はmoファイルの名称(拡張子は.mo)です。GNOME等でPACKAGE名と呼ばれることが多いです。通常はアプリケーション・ライブラリにつき1つですが、本ライブラリではクラス単位で指定できるようにしています。ただし、rgettextとの親和性を考慮すると現実的には少なくともファイル単位より大きい単位になると思います。

APIリファレンス

GetTextモジュール

GetText.bindtextdomain(domainname, path = nil, locale = nil, charset = nil)
TextDomainをバインドする。#{path}/#{locale}/LC_MESSAGES/#{domainname}.moが対象のmoファイルとなる。
GetText._(msgid)
GetText.gettext(msgid)
msgidからローカライズされた文字列を返す。指定したmoファイルが存在しない場合はmsgidをそのまま返す。
GetText.n_(msgid, msgid_plural, n)
GetText.ngettext(msgid, msgid_plural, n)
n(整数値)の値によって単数形・複数形別のローカライズされた文字列を返す。nが何の値のときに単数・複数とみなすかは言語によって異なり、言語別poファイルで指定する。
GetText.N_(msgid)
msgidをそのまま返す。これはrgettextによってローカライズする文字列の対象とさせることに使う。開発手順の章参照。
GetText.locale=(locale)
C, de, fr, it, ko, ja_JP.eucJP, zh_CN.EUCなどの文字列を指定する。
GetText.charset=(charset)
euc-jp, sjis, CP932, utf-8などの文字列を指定する。

Localeモジュール

POSIXで言うところのsetlocaleのラッパですが、MS Windowsではロケール情報を取得するモジュールです。
GetTextから呼び出されますので、これ自身を呼び出すことはほとんど無いと思います。

Locale.get
現在のロケールを返す。
Locale.set(type, locale)
Locale.setlocale(type, locale)
ロケールを設定する。
Locale.charset
Locale.codeset
文字コードを返す。
Locale::ALL
Locale::COLLATE
Locale::CTYPE
Locale::MESSAGES
Locale::MONETARY
Locale::NUMERIC
Locale::TIME
ロケール種別。POSIXのsetlocaleを参照してください。Ruby上でLocale::NUMERICをC以外に設定してしまうと、一部の機能(Marshal等)が正常に動作しなくなる可能性があります。

rgettextツール

rgettextツールは、Rubyスクリプトから文字列を抜き出してpoファイルを生成します。

使い方

$rgettext hoge.rb -o hoge.pot

rmsgfmtツール

rmsgfmtツールは、rgettextツールで生成したファイルを各言語に翻訳した後のpoファイルからmoファイルを生成します。

使い方

$rmsgfmt hoge.po -o hoge.mo

開発手順

本ライブラリを使用した開発手順を簡単に説明します。

まずはスクリプトを作る

例えば、以下のように本ライブラリを用いたスクリプトを作ります。hello.rbと言う名前で保存します。

require 'gettext'

include GetText

bindtextdomain("hello")
print _("Hello World\n")

文字列の抽出を行う(poファイルを作る)

次にrgettextを使って文字列を抽出します。

$rgettext hello.rb -o hello.pot

hello.potファイルの先頭部分はそのプロジェクトにあったコメントを追加しておくと良いでしょう。

ローカライズする

hello.potから他の言語ファイルを作ります(この例は日本語ファイルを作る場合です)。

$cp hello.pot ja.po

次に、ja.poを編集します。以下のような感じ。

"Content-Type: text/plain; charset=euc-jp\n"

#: ../hello.rb:7
msgid "Hello World\n"
msgstr "こんにちわ、世界\n"

それから、ヘッダ部分には翻訳した人・言語・時間などの情報を書きます。Content-Type行は必須です。ja.poファイル自体の文字コードを記述します。euc-jp,sjis,utf-8等が入ります。

なお、poファイルのメンテナンスにはGNU gettext付属のツール(msgmerge等)を使うことができます。
#時間があったらこの辺も書きましょう。つーか誰か書いてください(^^;)。

一応、samplesディレクトリにいくつかサンプルを入れておきますんでそちらも参考にしてください。

※ GetText.n_(msgid, msgid_plural, n)の使い方

日本語は比較的単数形と複数形を意識しないのですが、文法上、これらを明確に分けたい言語があり、GetText.n_()はそのようなメッセージを扱いたい場合に使います。
以下に例を示します。

require 'gettext'

include GetText
bindtextdomain("plural")
(0..10).each do |n|
  printf n_("%d file was removed", "%d files were removed", n), n)
end

若干冗長に感じるかもしれませんが、GetText.n_()の第3引数の数値と、printfに渡すnは別に記述します。
#これは%s等が一緒に文字列に入る場合を想定しているのでこのような形になっています。

上記の言語別実行結果がどう表示されるかというのはpoファイルのPlural-Forms行に依存します。
以下にpoファイルの抜粋を示します。

"Plural-Forms: nplurals=2; plural=(n != 1);\n"

 #: plural.rb:11
 msgid "%d file was removed"
 msgid_plural "%d files were removed"
 msgstr[0] "ファイルが削除されました"
 msgstr[1] "ファイルが%d個削除されました"

npluralsがmsgstr[]の数(この場合は2)、plural=の右辺が条件式です。true/falseかあるいは該当するmsgstrの番号を返すような条件式を書きます。この場合はnが1の時はmsgstr[0]、それ以外の場合はmsgstr[1]が使われます。
...日本語で説明するとあまりありがたみを感じられませんね。実は、日本語の場合はあまり複数形を使うような場面は無いので、以下のようにしてしまう場合が多いようです。

"Plural-Forms: nplurals=1; plural=0;\n"

 #: plural.rb:11
 msgid "%d file was removed"
 msgid_plural "%d files were removed"
 msgstr[0] "ファイルが%d個削除されました"

この場合は常に同じメッセージが表示されます。

英語などでは最初の例のように

Plural-Forms: nplurals=2; plural=n != 1;

という指定にして、1のときのみ単数形、0と2以上は複数形として扱います。
moファイルが存在しない場合にはこのルールが適用されます。

さらに言語によっていろいろな条件があるのですが、これが4つにも分かれる言語もあります。Slovenianを例にあげます。

"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;"

 #: plural.rb:11
 msgid "%d file was removed"
 msgid_plural "%d files were removed"
 msgstr[0] "...."
 msgstr[1] "...."
 msgstr[2] "...."
 msgstr[3] "...."

メッセージ部分は何を入れて良いのかさっぱりなのでごまかしました。
にしても、このように翻訳していくのは大変ですね。日本人に生まれてよかったかも(^^;)。

なお、GNU gettextのドキュメントにさらに詳細な説明があります。英語と日本語以外にも興味がある方はそちらを参照してください。

※ GetText.N_(msgid)の使い方

GetText.N_(msgid)はmsgidをローカライズせずにそのまま返します。
これは、rgettextがソースからローカライズ対象の文字列を抜き出すために必要とされます。
以下に例を示します。

require 'gettext'

include GetText
bindtextdomain("hello_noop")

msgs = [N_("Hello World"), N_("Hello World2")]

msgs.each do |msg|
  print _(msg), "\n"
end

※ fuzzy表示について

poファイルにfuzzyと表示されている場合、それを取り除かないとローカライズの対象になりません。

#: hello.rb:7
#, fuzzy
msgid "Hello World"
msgstr "こんにちわ、世界"

この場合は内容を確認した上で、fuzzy行を削除してください。

#: hello.rb:7
msgid "Hello World"
msgstr "こんにちわ、世界"

moファイルを作る

最後にmoファイルを作り、これを適切なディレクトリへ置きます。
上記例ではbindtextdomain()でmoファイルを置くディレクトリを指定していないため、/usr/share/locale/#{lang}/LC_MESSAGES/か/usr/local/share/locale/#{lang}/LC_MESSAGES/へ置く必要があります。
ここでは、/usr/local/share/locale/ja/LC_MESSAGES/へ置いてみます。

$rmsgfmt ja.po -o /usr/local/share/locale/ja/LC_MESSAGES/

※ たぶん上記のままコマンドを実行する場合はroot権限が必要だと思います。
※ rmsgfmtの代わりにGNU gettext付属のmsgfmtコマンドを使うこともできます。

実行する

$ruby hello.rb

日本語が表示されましたか? おめでとうございます、成功です。

もし表示されないようでしたら、まずは、-d付きで実行してみましょう。

$ruby -d hello.rb
Search path:["/usr/share/locale", "/usr/local/share/locale"]
locale:"ja_JP.eucJP"

MO file is not found in
      /usr/share/locale/ja_JP.eucJP/LC_MESSAGES/hello.mo
      /usr/share/locale/ja_JP/LC_MESSAGES/hello.mo
      /usr/share/locale/ja/LC_MESSAGES/hello.mo
      /usr/local/share/locale/ja_JP.eucJP/LC_MESSAGES/hello.mo
      /usr/local/share/locale/ja_JP/LC_MESSAGES/hello.mo
      /usr/local/share/locale/ja/LC_MESSAGES/hello.mo

もう一度、上記pathのいずれかにきちんとhello.moがあることを確認してください。
#これでわかんなかった場合は....どうしましょう(^^;)

GNU gettextと異なる点

最後に、GNU gettextを使っている方へ、本ライブラリとGNU gettextと異なる点を書いておきます。

ライセンス

このライブラリはRubyと同じライセンスに基づいて配布されるフリーソフトウェアです。詳しくはCOPYING.jaを参照してください。

mo.rb

Copyright (C) 2001,2002 Masahiro Sakai <s01397ms@sfc.keio.ac.jp>, Masao Mutoh <mutoh@highwhay.ne.jp>

gettext.rb

Copyright (C) 2001,2002 Masahiro Sakai <s01397ms@sfc.keio.ac.jp>, Masao Mutoh <mutoh@highwhay.ne.jp>

rgettext

Copyright (C) 2001,2002 Yasushi Shoji <yashi@yashi.com>, Masao Mutoh <mutoh@highwhay.ne.jp>

rmsgfmt

Copyright (C) 2003 Masao Mutoh <mutoh@highwhay.ne.jp>

install.rb

Copyright (C) 2000,2001 Minero Aoki <aamine@loveruby.net>
このファイルのみLGPLです。ライセンスについてはinstall.rbファイルの先頭部分を参照してください。

その他

Copyright (C) 2001-2003 Masao Mutoh <mutoh@highwhay.ne.jp>

メンテナ

本ライブラリについてのご意見・バグレポートは武藤まで。
Masao Mutoh <mutoh@highway.ne.jp>

ChangeLog

2003-12-02 Masao Mutoh <mutoh@highway.ne.jp>

2003-11-27 Masao Mutoh <mutoh@highway.ne.jp>

2003-11-12 Masao Mutoh <mutoh@highway.ne.jp>

2003-07-05 Masao Mutoh <mutoh@highway.ne.jp>

2003-07-04 Masao Mutoh <mutoh@highway.ne.jp>

2003-01-07 Masao Mutoh <mutoh@highway.ne.jp>

2002-10-21 Masao Mutoh <mutoh@highway.ne.jp>

2002-10-18 Masao Mutoh <mutoh@highway.ne.jp>

2002-07-06 Masao Mutoh <mutoh@highway.ne.jp>

2002-07-02 WATANABE Hirofumi <eban@os.rim.or.jp>

2002-07-01 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>

2002-06-30 Masao Mutoh <mutoh@highway.ne.jp>

2002-02-22 Masao Mutoh <mutoh@highway.ne.jp>

2002-02-21 Masao Mutoh <mutoh@highway.ne.jp>

2002-02-13 Masao Mutoh <mutoh@highway.ne.jp>

2002-02-03 Masao Mutoh <mutoh@highway.ne.jp>

2002-01-06 Masao Mutoh <mutoh@highway.ne.jp>

2002-01-01 Masao Mutoh <mutoh@highway.ne.jp>

2001-12-24 Masao Mutoh <mutoh@highway.ne.jp>


$Id: ruby-gettext.rd,v 1.29 2003/11/11 19:18:42 mutoh Exp $