poファイル翻訳において前バージョン翻訳済みpoを効果的に利用する方法


序文

linuxでのアプリの翻訳にはGNU gettextというツールが使用されています。このツールは未翻訳の英文メッセージと翻訳済みメッセージの対応付けをpoファイルという形式に保存してロケールに合わせて翻訳済みメッセージを表示します。

gettextは本来、プログラムソース中のユーザーの目に触れる文字列リソース(GUIメニュー文字列やメッセージ文字列など)を対象としたものですが、gettextのpoファイル形式はgettextが対応していないドキュメントの翻訳にも多用されるようになりました。

かくいう私もpo4aというツールでgettextやemacsのマニュアルを、infoドキュメントの元となるtexiドキュメントからpoファイルを生成、翻訳したりしました。

アプリのドキュメントというものは、アプリのバージョンアップとともにバージョンアップされます。poファイル翻訳において、前バージョンの翻訳済みファイルを新バージョンの未翻訳ファイルに適用するためのツールがgettextには存在するのですがあまり情報がなく、わたし自身も翻訳を中断・再開するたびに「あれ、どーやんだっけ?」とマニュアルを調べ直すことも多く、備忘録を兼ねてここに記します。

なお、ここではpoファイル生成にはわたしが翻訳したtexiファイルに対応しているpo4aを、翻訳ツールとしてemacsを例としますが、それぞれのソース形式に応じたpoファイルツールや、emacs以外にもpoファイル編集のための専用翻訳ツールがあるので、それらを使用されている人は適宜読み替えてください。

初版の翻訳

とりあえずemacs-24.5のマニュアルを例にします。自分で試したい人はgit clone https://github.com/ayatakesi/emacs-24.5-doc-emacs.gitしてください。

poファイル作成

まずpo4aによりインストールされるpo4a-gettextizeにより、texinfoファイルからpoファイルを生成します。

po4a-gettextize -M utf8 -f texinfo -m custom.texi -p custom.texi.po

以下のようなpoファイルが生成されます。

custom.texi.po
# SOME DESCRIPTIVE TITLE
# Copyright (C) YEAR Free Software Foundation, Inc.
# 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"
"POT-Creation-Date: 2018-01-03 18:45+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#. type: chapter
#: custom.texi:5 custom.texi:6
#, no-wrap
msgid "Customization"
msgstr ""

#. type: cindex
#: custom.texi:7
#, no-wrap
msgid "customization"
msgstr ""

翻訳

poファイルのmsgidに対応する翻訳をmsgstrに記述していきます。poファイルのフォーマットにはお約束があって、コメントにも#.#:#,のようにいくつか種類があります(詳細はマニュアル、または拙訳を参照してください)。poファイル編集のためのツールが各種ありますが、いずれもこれらフォーマットの約束事を自動的に処理してくれるので、poファイルの編集にはそれらの使用をお勧めします(vimなどでもシンタックスハイライトくらいはしてくれますが、手編集ではフォーマットを壊してしまうかもしれませんよ)。

わたしはemacs+gettextとともにインストールされるpo-modeを使用しています。po-modeのために必要なファイルはgettextインストールとともに適切な場所にインストールされるはずですが、インストールされない場合(apt-getなどでインストール時)は、{gettext's source directory}/gettext-tools/misc/*.elをEmacsのload-pathにコピーしてください。

po-modeではエントリー間の移動にn(po-next-entry)p(po-previous-entry)u(po-next-untranslated-entry)f(po-next-fuzzy-entry)などを使用します。またエントリーのステータスの変更は{TAB}(po-unfuzzy)でfuzzy→翻訳ずみ、{Backspace}(po-fade-out-entry)で翻訳済み→fuzzy→obsoleteに変更します。詳しい使用法はマニュアル、または拙訳を参照してください。

他のツールは知りませんが、po-modeではpoヘッダー(msgidが""のエントリー。通常はpoファイルの最初にある。)のcharset=CHARSETに適切な文字セットを指定しないと日本語が入力できません。はやる気持ちを抑えて、charset=UTF-8に修正します。

ポイント位置のエントリーを翻訳するには{RET}(po-edit-msgstr)を押下します。すると翻訳を編集するためのウィンドウが開くので、そこでpoヘッダーを修正します。charset以外の項目(POT-Creation-Dateはpo作成ツール、PO-Revision-Dateはpoエディターなどにより自動的に更新されるので編集不要)も修正します。

翻訳したらC-c C-c(po-subedit-exit)でコミット(取り消す場合はC-c C-k(po-subedit-abort))して、C-x C-s(save-buffer)で保存、q(po-confirm-and-quit)で閉じて、再度開き直します。

翻訳したものがこちらです。

翻訳済みpoファイルから元ドキュメントを翻訳

翻訳したpoファイルから翻訳済みtexinfoを作成するにはpo4a-translateを使用します。

po4a-translate -f texinfo -k 0 -M utf8 -m custom.texi.orig -p custom.texi.po -l custom.texi

ここで、custom.texi.origは翻訳前のオリジナルtexinfoファイル、custom.texi.poは翻訳済みpoファイル、custom.texiが生成する翻訳済みtexinfoファイルです。翻訳済みのtexinfoはこちらを参照してください(poファイルで対応が難しいメッセージは一部perlのsedエミュレーションを使用して置換してます)。

改訂版の翻訳

emacs-24.5からemacs-25.1へのマニュアルバージョンアップを例にします。自分で試したい人はgit clone https://github.com/ayatakesi/emacs-25.1-doc-emacs.gitしてください。

poファイル作成

初版と同様です。作成した未翻訳のpoファイルはcustom.texi.po.25.1とでもしておきます。

旧版翻訳済みpoファイルのマージ

旧版の翻訳済みpoファイルはcustom.texi.po.24.5とします。作成される旧版翻訳マージ後のpoファイルがcustom.texi.poです。ここではcompendiumオプションとpreviousオプション、およびここに説明されている方法を使用してます。

msgmerge --previous --compendium custom.texi.po.24.5 -o custom.texi.po /dev/null custom.texi.po.25.1

マージされたpoファイルは以下のようになります。

custom.texi.po
#. type: cindex
#: custom.texi:1767
#, no-wrap
msgid "modifier keys"
msgstr "modifier keys"

#. type: Plain text
#: custom.texi:1775
#, fuzzy
#| msgid ""
#| "The default key bindings in Emacs are set up so that modified "
#| "alphabetical characters are case-insensitive.  In other words, @kbd{C-A} "
#| "does the same thing as @kbd{C-a}, and @kbd{M-A} does the same thing as "
#| "@kbd{M-a}.  This concerns only alphabetical characters, and does not "
#| "apply to ``shifted'' versions of other keys; for instance, @kbd{C-@@} is "
#| "not the same as @kbd{C-2}."
msgid ""
"The default key bindings in Emacs are set up so that modified alphabetical "
"characters are case-insensitive.  In other words, @kbd{C-A} does the same "
"thing as @kbd{C-a}, and @kbd{M-A} does the same thing as @kbd{M-a}.  This "
"concerns only alphabetical characters, and does not apply to shifted "
"versions of other keys; for instance, @kbd{C-@@} is not the same as "
"@kbd{C-2}."
msgstr ""
"Emacsでは、デフォルトのキーバインディングがセットアップされているので、修飾さ"
"れたアルファベット文字は大文字小文字が区別されません。つまり@kbd{C-A}は"
"@kbd{C-a}と同じことを行い、@kbd{M-A}は@kbd{M-a}と同じことを行ないます。これは"
"アルファベット文字だけに当てはまり、他のキーの``シフトキーが押された"
"(shifted)''バージョンには適用されません。たとえば、@kbd{C-@@}は@kbd{C-2}と同"
"じではありません。"

msgidには新版の英文、msgstrには旧版の翻訳がセットされます。#|で始まるコメントが旧版の英文です。

翻訳

untranslatedとfuzzyを潰していきます。untranslatedは1から翻訳ですが、fuzzyに関しては--previousにより、旧英文と新英文、旧翻訳を見比べて翻訳できます。見ていただくとわかると思いますが、旧版/新版の英文目視diffは結構辛いものがあります。

以前使用したことのある翻訳ツールではvirtaalが差分表示に対応してました。

スクショで推測できると思いますが、わたしはAndroid上のtermuxのemacsで翻訳しているんですが、Xアプリはいまいちトロくて使い勝手が悪く、Emacsのediff-window-wordwiseを改造したものでdiffをとってます(とても公開できる代物ではありませんが、ソースはこちら。現在elisp勉強中です)。

翻訳済みpoファイルから元ドキュメントを翻訳

初版と同様です。

結び

巷では翻訳マニュアルは英語習得の妨げになるという意見も目立ちますが、わたしは違う意見です。自分が本当に興味をもっている分野ではオリジナルの英文をよみますが、自分の興味がある分野の前提知識を調べるときに、いちいち英文を読むのは正直かったるいです。htmlの知識が0だったとして、最初に英文情報を当たることはまずありません。日本語情報でザクっと調べて、その上で特定の情報を調べるとき英文を読む感じです。そもそも、今のわたしが英文を読めるようになったのは、豊富な日本語情報が背景にあったわけですから。この投稿が日本語情報の充実に役立つことを願います。おわり