GNU gettext を使用したソフトウェアの翻訳

GNU gettext はフリー ソフトウェアの国際化のために最も広く使われているツールの一つです。ソフトウェアを現地語化するための簡単かつ柔軟な方法を提供します。複数形に対応しており、翻訳した文字列にさらに関連情報を追加でき、関連する非常に多くのツールが作成されています。もちろん、Weblate でも優れた対応をしています(参照: GNU gettext ファイル形式の説明)。

注釈

ソフトウェアを商用利用する場合は、まずはライセンスを確認してください。

GNU gettext は、さまざまな言語(C、Python、PHP、Ruby、JavaScript、その他多数)で使用でき、通常、UI フレームワークにはすでに何らかのサポートが付属しています。標準的な使用法は、gettext() 関数呼び出しを使用します。これは、コードをより単純で読みやすくするために、多くの場合 _() にエイリアスされます。

さらに、翻訳者に追加の関連情報を提供するための pgettext() 呼び出しと、ターゲット言語用に定義された複数の型を処理できる ngettext() を提供されています。

広く普及しているツールとして、使用法を非常に簡単にする多くのラッパーがあります。以下で説明する gettext を手動で呼び出す代わりに、 intltool などを試してみてください。

ワークフローの概要

GNU gettext は、現地語化を管理するために複数のファイルを使用します。

  • PACKAGE.pot には、ソースコードから抽出された文字列が含まれています。通常は xgettext または intltool などの高レベルのラッパーを使用します。

  • LANGUAGE.po には、単一言語に翻訳された文字列が含まれています。PACKAGE.pot の更新があれば、msgmerge による更新が必要です。新しい言語ファイルは msginit を使用する、Weblate 内で作成できます。

  • LANGUAGE.mo には LANGUAGE.po のバイナリ表現が含まれ、アプリケーションの実行時に使用されます。通常、バージョン管理下には置かれませんが、コンパイル時に msgfmt を使用して生成されます。バージョン管理に含める場合は、MO ファイルの生成 アドオンを使用して Weblate で生成できます。

GNU gettext 処理の全体像:

digraph translations { graph [fontname = "sans-serif", fontsize=10]; node [fontname = "sans-serif", fontsize=10, shape=note, margin=0.1, height=0]; edge [fontname = "monospace", fontsize=10]; "Source code" -> "PACKAGE.pot" [label=" xgettext "]; "PACKAGE.pot" -> "LANGUAGE.po" [label=" msgmerge "]; "LANGUAGE.po" -> "LANGUAGE.mo" [label=" msgfmt "]; }

サンプル プログラム

C言語による gettext を使用した簡単なプログラム:

#include <libintl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int count = 1;
    setlocale(LC_ALL, "");
    bindtextdomain("hello", "/usr/share/locale");
    textdomain("hello");
    printf(
        ngettext(
            "Orangutan has %d banana.\n",
            "Orangutan has %d bananas.\n",
            count
        ),
        count
    );
    printf("%s\n", gettext("Thank you for using Weblate."));
    exit(0);
}

翻訳可能な文字列の抽出

gettext 呼び出しを使用するコードを作成したら、xgettext を使用してメッセージを抽出し、.pot に格納できます。使用方法:

$ xgettext main.c -o po/hello.pot

注釈

コードから文字列を抽出する別のプログラムもあります。例: pybabel

これによりテンプレート ファイルが作成され、新しい翻訳の開始(msginit の使用)や、コード変更後に既存の翻訳の更新(その場合は、 msgmerge の使用)に使用できます。単純に構造化されたテキスト ファイルによる結果ファイル:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"

#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""

#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""

msgid の各行は、翻訳する文字列を定義します。先頭の特別な空の文字列は、翻訳に関するメタデータを含むファイル ヘッダーです。

新しい翻訳の開始

テンプレートを用意して、最初の翻訳を開始する。開始方法:

$ msginit -i po/hello.pot -l cs --no-translator -o po/cs.po
Created cs.po.

cs.po を作成すると、あらかじめ情報が入力されています。最も重要なのは、選択した言語の適切な複数形の定義を取得したことです。複数形の数が言語に従って変化したことも確認できます。

# Czech translations for PACKAGE package.
# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Automatically generated, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-23 11:02+0200\n"
"PO-Revision-Date: 2015-10-23 11:02+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"

#: main.c:14
#, c-format
msgid "Orangutan has %d banana.\n"
msgid_plural "Orangutan has %d bananas.\n"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""

#: main.c:20
msgid "Thank you for using Weblate."
msgstr ""

このファイルは、最適化されたバイナリ形式(実行時に 'GNU gettext'_ 関数が使用する .mo )にコンパイルされます。

文字列の更新

プログラムに文字列を追加したり、文字列の変更を加えた場合、xgettext を再度実行してテンプレート ファイルを再生成してください。再生成の方法:

$ xgettext main.c -o po/hello.pot

次に、新しく作成されたテンプレートと一致するように個々の翻訳ファイルを更新します(これには、新しいテンプレートに一致するように文字列を並べ替えることも含みます) 。

$ msgmerge --previous --update po/cs.po po/hello.pot

Weblate へのインポート

翻訳を Weblate にインポートするために必要な、コンポーネント作成時の設定項目(項目の詳細については、コンポーネント構成 を確認してください):

項目

ソースコードのリポジトリ

プロジェクトを含む VCS リポジトリの URL

ファイル マスク

po/*.po

新しい翻訳のテンプレート

po/hello.pot

ファイル形式

gettext 用の PO ファイル から選択する

新しい言語

新しい言語ファイルの作成 から選択する

これで、ソフトウェアの翻訳を開始する準備が整いました!

参考

多くの言語を使用した gettext の例は、GitHub: <https://github.com/WeblateOrg/hello> の Weblate Hello プロジェクトにあります。