日本語メッセージ for 8.4（gettextへのいざない）
2009/04/28
日本PostgreSQLユーザ会
文書・書籍関連分科会
堀田 倫英

講師紹介
• 堀田 倫英（ほった みちひで）• ネットワーク管理者
ネットワーク管理者（管理者（の卵）養成講座– http://net-newbie.com/ since 1998/02• 青年海外協力隊(1989-1991)– SunOS(-4.1.2?)との出会い(1991?)• 地銀系ソフトハウス(1993-2004)– Linux(-0.99?)との出会い(1994?)– PostgreSQL(-6.3.1?)との出会い(1998/05)• 長崎県立大学(2004-現在)

今日のお題はやっとPostgreSQLも…
$ psql --help|head
psql は PostgreSQL の会話型ターミナルです。
使用方法:
psql [オプション]... [データベース名 [ユーザ名]]
一般的なオプション：-c, --command=コマンド (SQLまたは内部の)単一コマンドを一つだけ実行して終了-d, --dbnme=DB名接続するデータベース名を指定(デフォルト: "m-hotta")-f, --file=ファイル名
ファイルからコマンドを読み込んで実行後、終了-l(エル), --list
使用可能なデータベース一覧を表示して終了のようになるというお話のようになるというお話です。
です。

PostgreSQLのNLS対応• 組み込み方：$ ls

COPYRIGHT

GNUmakefile.in

READMEconfigcontrib

src

CVS

MIGRATION

README.CVS configure

doc

ChangeLogs

Makefile

configure.in

migration

aclocal.m4$ ./configure –enable-nls [...その他のオプション]$ make$ make install

NLS とは• NLS(National Language Support)• コマンドからのメッセージを、各国語で出力するしくみ• 環境変数により、実行時に言語を選択可能• gettextライブラリを使って実現– $ rpm -q gettext– gettext-0.14.6-4.el5• 多くのOSSプロダクトで実装済み

使い方$ head -1 /etc/issue
CentOS release 5.2 (Final)$ env|grep LANG
LANG=ja_JP.UTF-8$ psql --help|head -1
psql は PostgreSQL の会話型ターミナル、psql 8.3.0 です。
$ LANG=C psql --help|head -1
This is psql 8.3.0, the PostgreSQL interactive terminal.
$ LANG=fr_FR.UTF=8 psql --help|head -1
Bienvenue dans psql 8.3.0, l'interface interactive dePostgreSQL.

自動文字コード変換（端末コード＝UTF-8）$ psql --help|head -1
こちらは PostgreSQL の会話型ターミナル、psql 8.3.0 です。
（端末コードをEUC-JPに変更）$ psql --help|head -1▒▒＜▒・PostgreSQL ▒・▒荅怨▒帥若▒▒・psql 8.3.0 ▒с▒$ psql --help|head -1|nkf -e
こちらは PostgreSQL の会話型ターミナル、psql 8.3.0 です。
$ LANG=ja_JP.EUC-JP psql --help|head -1
こちらは PostgreSQL の会話型ターミナル、psql 8.3.0 です。

ネタの出所$ cd /usr/share/locale/ja/LC_MESSAGES$ ls pg_*
pg_config.mo pg_controldata.mo pg_ctl.mo
pg_dump.mo pg_resetxlog.mo$ msgunfmt pg_dump.mo（中身を見る）--（中略）--msgid """¥n""Connection options:¥n"msgstr """¥n""接続オプション:¥n"環境変数LANG
LANG=CC_LL.EEEE
CC:言語コード（ISO639-1）：日本語＝ja※ ISO639-1は２文字、ISO-639-2は３文字
現在545言語。

LL：国コード（ISO3166-1）：日本＝JP※現在246か国
EEEE：文字コードセット※詳しくはWebで(ﾟ∀ﾟ)メッセージ出力の進化• 原文（原文（世界の世界の共通語）共通語）
printf(““My name is %s.¥n””, my_name);// 英語は英語は必須です
必須です• 各国語に語パッチ）
各国語に書き換え（XX語パッチ）
printf(““私の名前は名前は %s です¥n”です ”, my_name); // 独りよがり– 初期の日本語パッチ
初期のpsql日本語
日本語パッチはこの
パッチはこの方式
はこの方式• コンパイルオプションでコンパイルオプションで切り替え#ifdef LANG_JAPAN
printf(““私の名前は
名前は %s です¥n”
です ”, my_name);#endif#ifdef LANG_．．．
．．．

// できたバイナリ
できたバイナリは
バイナリは、どれか１どれか１つしか話つしか話せない• 多言語対応された多言語対応されたソース
されたソースprintf(_(““My name is %s.¥n””), my_name);// これで各国語対応可能
これで各国語対応可能

GNU gettext
a.c$ xgettext-a a.c-o hoge.po

翻訳（人手）

hoge.pohoge.mo$ cc –ohoge a.c#: a.c:7
msgid "My name is %s.¥n"msgstr ""$ msgfmt
hoge.po-o hoge.mohoge#: a.c:7
msgid "My name is %s.¥n"
私の名前は
msgstr “私
名前は %s です。
です。¥n"

私の名前はです。
名前はXXですです。

poファイルヘッダ"Project-Id-Version: PostgreSQL 8.4beta1¥n""Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org¥n""POT-Creation-Date: 2009-04-11 10:30+0900¥n""PO-Revision-Date: 2009-04-11 10:31+0900¥n""Last-Translator: HOTTA Michihide <hotta@netnewbie.com>¥n""Language-Team: Japan PostgreSQL Users Group <jpugdoc@ml.postgresql.jp>¥n""MIME-Version: 1.0¥n""Content-Type: text/plain; charset=UTF-8¥n""Content-Transfer-Encoding: 8bit¥n""Plural-Forms: nplurals=1; plural=0;¥n"初めて翻訳
めて翻訳する翻訳する場合
する場合• 各国語部分を各国語部分を切り出す$ make init-po（テンプレート作成）
po/hoge.potができる#: src/name.c:36
msgid "My name is %s.¥n"msgstr ""• 日本語の日本語のテンプレートをテンプレートを作成$ msginit --locale=ja --input=hoge.pot
po/ja.poができる ←翻訳対象

ソースがアップデートされた場合（po/ja.poがある前提で）– ソースをソースを再スキャンしてスキャンして既存して既存の既存の翻訳と翻訳とマージ$ make update-po$ po/ja.po.newができる$ cd po$ mv ja.po ja.po.orig$ mv ja.po.new ja.po ←翻訳対象
翻訳対象

マージ結果• 変更なし変更なし、なし、単純文字列#: utils/misc/tzparser.c:72（ソース中の位置）
msgid ...
• 変更なし書式文字列を変更なし、なし、 printf書式文字列
書式文字列を含む#: utils/misc/tzparser.c:72#, c-format
msgid ...
• 新規メッセージ
新規メッセージ／メッセージ／変更あり
変更あり#: utils/misc/tzparser.c:72# fuzzy → 基本的にはここだけの基本的にはここだけの作業にはここだけの作業で作業で可
msgid ..

ひたすら msgid を翻訳してmsgstrにセット• 行末の行末の改行を改行を合わせる
msgid “My name is %s.¥n” （改行あり）
msgstr “私の名前は %s です¥n“
msgid “out of memory”（改行なし）
msgstr “メモリ不足です”• 訳文が訳文が長くなる場合
くなる場合
msgid "could not rename file ¥"%s¥" to ¥"%s¥": %m"
msgstr “”（ここでいったん改行）"ファイル¥"%s¥"の名前を¥"%s¥"に変更できませんでし
た: %m"

語順の変更を伴う場合
msgid ""
"time zone abbreviation ¥"%s¥" is too long(maximum %d characters) in time ""zone file ¥"%s¥", line %d"
msgstr ""“タイムゾーンファイル¥”%3$s¥“の%4$d行目にある省略形¥"%1$s¥"が長すぎます（最大%2$d文字）“‘数字$’
数字 ’ でパラメータ位置パラメータ位置を位置を指定可能

単数形と複数形"Plural-Forms: nplurals=1; plural=0;¥n“
msgid "Expected sequence of %d argument, got %d: %s"
msgid_plural "Expected sequence of %d arguments,
got %d: %s"
msgstr[0] "%d 番目の引数はシーケンスを期待していましたが、%d が現れました：%s“
msgstr[1] "%d 番目の引数はシーケンスを期待していましたが、%d が現れました：%s“結果の確認• ビルド$ makepo/ja.mo,es.mo, fr.mo ．．． ができる

• インストール
コマンド名と同じ$ make install
po/*.mo が psql.mo（一例）として以下に設置される/usr/local/share/locale/言語/LC_MESSAGES/• 実行$ psql（psql.mo が動的に読み込まれる）

本家にコミット• $ mv ja.po /path/to/psql.po• cvs commit
本体開発者

翻訳者

コミット

コミット

本体リポジトリ

マージ

メッセージ
リポジトリ

翻訳ネタ
$ find . -name nls.mk -exec grep
CATALOG_NAME {} ¥; | awk '{print $3}'| sort
ecpg
pg_ctlplpython
ecpglibpg_dumppltcl
initdbpg_resetxlog postgres
libpq
pgscripts
psql
pg_config
plperlpg_controldata plpgsql

競争心をあおるしくみ

NLS - その意義は？
• バリバリコードが書ける人は英語も読める– （ことが多い）– 英語に不自由しない人には無用の長物• 日本語になると誰が嬉しいのか？
• 翻訳するヒマがあればコードを書け?
• ．．．
• でも、少しでもPostgreSQLへの敷居が下がれば嬉しい。。。かも。。。

翻訳者を翻訳者を絶賛募集中です
絶賛募集中です!!
です!!

日本PostgreSQLユーザー
ユーザー会
日本ユーザー会:
文書・文書・書籍関連分科会
http://www.postgresql.jp/wg/jpugdoc/
へどうぞ。

ご清聴ありがとうございました。