Chapter 46. 本地語言支持

Table of Contents
46.1. 寄語翻譯家
46.1.1. 要求
46.1.2. 概念
46.1.3. 創建和維護信息表
46.1.4. 編輯 PO 文件
46.2. 寄語程序員
46.2.1. 機理
46.2.2. 消息書寫指導

46.1. 寄語翻譯家

PostgreSQL程序(服務器和客戶端)可以用你喜愛的語言發出信息 -- 只要那些信息被翻譯過。創建和維護翻譯過的信息集需要那些熟悉自己的語言並且希望為PostgreSQL做一些事情的人。 實際上要幹這件事你完全不必是個程序員。本章講的就是如何幫助 PostgreSQL 做這件事。

46.1.1. 要求

我們不會評判你的語言能力 -- 本章是有關軟件工具的。 理論上,你只需要一個文本編輯器。 但這種情況只存在于你不想看看自己翻譯的信息的情況下,這種情況很難發生吧。 在你配置你的源程序的時候,記住要使用 --enable-nls 選項。這樣也會檢查 libintl 庫和 msgfmt 程序,它們是所有最終用戶都需要的東西.要試驗你的工作, 遵照安裝指導中相應的部分就可以了。

如果你想開始一個新的翻譯工作或者想做信息表融合工作(下面描述), 那麼你就還分別需要有 GNU 兼容的 xgettextmsgmerge. 稍後我們將試著安排它,這樣,如果你使用的是一個打包的源碼發布, 那麼你就不再需要xgettext。(從 CVS 裡下源碼的話, 你還是需要的。)我們現在推薦 GNU Gettext 0.10.36 或者更高。

你的本地 gettext 實現應該和它自身的文檔在一起發布。 其中有一些可能和下面的內容重復,但如果要知道額外的細節,你應該看看它們。

46.1.2. 概念

信息原文(英語)和它們的(可能)翻譯過的等價物都放在信息表裡, 每個程序一個(不過相關的程序可以共享一個信息表)以及每種目標語言一個。 信息表有兩種文件格式︰第一種是 "PO"(Portable Object)文件(可移植對象),它是純文本文件,帶一些翻譯者編輯的特殊語法。 第二種是 "MO"(Machine Objece) 文件(意思是機器對象), 它是從相應的 PO 文件生成的二進制文件,在國際化了的程序運行的時候使用。 翻譯者並不處理 MO 文件;實際上幾乎沒人處理它。

信息表的文件擴展名分別是 .po.mo 就一點也不奇怪了。主文件名要麼是它對應的程序名,要麼是該文件適用的語言,視情況而定。 這種做法有點讓人混淆。例子是 psql.po(psql 的PO 文件)或者 fr.mo(法語的 MO 文件)。

PO 文件的文件格式如下所示:

# comment

msgid "original string"
msgstr "translated string"

msgid "more original"
msgstr "another translated"
"string can be broken up like this"

...

msgid 是從程序源代碼中抽取的。(其實不必是從源碼,但這是最常用的方法。) msgstr 行初始為空,由翻譯者填充有用的字串。 該字串可以包含 C 風格的逃逸字符並且可以象我們演示的那樣跨行繼續。(下一行必須從該行的開頭開始。)

# 字符引入一個注釋。如果 # 後面緊跟著空白,那麼這是翻譯者維護的注釋。 文件裡也可能有自動注釋,它們是在 # 後面緊跟著非空白字符。這些是由各種在 PO 文件上操作的工具生成的, 主要目地是幫助翻譯者。

#. automatic comment
#: filename.c:1023
#, flags, flags

#. 風格的注釋是從使用信息的源文件中抽取的。 程序員可能已經插入了一些信息給翻譯者,比如那些預期的格式等。 #: 注釋表示該信息在源程序中使用的準確位置。 翻譯者不需要查看程序源文件,不過如果他覺得翻譯得不對勁, 那麼他也可以查看。#, 注釋包含從某種程度上描述信息的標志。 目前有兩個標志:如果該信息因為程序源文件的修改變得過時了, 那麼設置 fuzzy(模糊)。翻譯者然後就可以核實這些, 然後刪除這個模糊標志。請注意模式信息是最終用戶不可見的。 另外一個標志是 c-format,它表示該信息是一個 printf風格的格式模版。 這就意味著翻譯也應該是一個格式化字串,帶有相同數目和相同類型的佔位符。 我們有用于核實這些的工具,它們生成 c 格式(c-format)標志的鍵。

46.1.3. 創建和維護信息表

好,那我們怎麼創建一個"空白"的信息表呢? 首先,進入包含你想翻譯信息的程序所在的目錄。如果那裡有一個文件叫 nls.mk, 那麼這個程序就已經準備好翻譯了。

如果目錄裡已經有一些 .po 文件了, 那麼就是有人已經做了一些翻譯工作了。這些文件是用 language.po 命名的,這裡的 language ISO639-1 規定的兩字母語言代碼(小寫),比如, fr.po 指的是法語。如果每種語言需要多過一種的翻譯,那麼這些文件也可以叫做 language_region.po 這裡的 regionISO3166-1 規定的兩字母國家代碼(大寫),比如, pt_BR.po 指的是巴西葡萄牙語。如果你找到了你想要的語言文件,那麼你就可以在那個文件上幹活。

如果你需要開始一個新的翻譯工作,那麼首先運行下面的命令

gmake init-po

這樣將創建一個文件 progname.pot (用 .pot"生產中"使用的 PO 文件區分開。T代表"template"。)把這個文件拷貝成 language.po 然後編輯它.要讓程序知道有新語言可以用,還要編輯文件 nls.mk,增加該語言(或者語言和國家)代碼到類似下面這樣的行:

AVAIL_LANGUAGES := de fr

(當然可能還有其它國家。)

隨著下層的程序或者庫的改變,程序員可能修改或者增加信息。 這個時候,你不必從頭再來。只需要運行下面的命令

gmake update-po

它將創建一個新的空信息表文件(你開始時用的 pot 文件)並且會把它和現有的 PO 文件融合起來。 如果融合算法不能確定某條具體的信息是否融合正確,那麼它就會象上面解釋那樣把它定義為 "fuzzy(模糊)"。如果有些事情真是出錯了,那麼舊的 PO 文件就會保存為帶 .po.old 擴展的文件。

46.1.4. 編輯 PO 文件

PO 文件可以用普通的文本編輯器編輯。翻譯者應該只修改那些在 msgstr 指示符後面的雙引號中間的內容, 也可以增加評注和修改模糊(fuzzy)標志。Emacs 有一個用于 PO 的模式,我覺得相當好用。

我們不需要把 PO 文件完全填滿。如果有些字串沒有翻譯(或者是一個空白的翻譯),那麼軟件會自動使用原始的字串。 也就是說提交一個未完成的翻譯包括再源碼樹中並不是一個問題; 那樣可以留下讓其它人繼續你的工作的空間。不過, 我們鼓勵你在完成一次融合之後首先消除模糊的條目。 要知道模糊的條目是不會被安裝的;它們只起到表示可能是正確翻譯的引用的作用。

下面是一些編輯翻譯信息的時候要記住的事情:

  • 確保如果原始信息是以換行結尾的話,翻譯信息也如此。類似的情況適用于 tab 等。

  • 如果最初的字串是 printf 格式的字串,那麼翻譯串也必須如此。 翻譯串還要有同樣的格式聲明詞,並且順序相同。 有時候語言的自然規則會讓這麼做幾乎不可能或者及其難看。 這時候你可以用下面的格式:

    msgstr "Die Datei %2$s hat %1$u Zeichen."

    這樣,第一個佔位符實際上使用列表裡的第二個參數。 digits$ 應該跟在 % 後面並且在其它格式操作符之前。 (這個特性實際上存在于 printf 家族函數中。 你可能從來沒有聽說過它,因為除了信息國際化以外它沒有什麼用處。)

  • 如果原始的字串包含語言錯誤,那麼請報告它(或者在程序源文件中直接修補它), 然後按照正常翻譯。正確的字串可能跟在程序源文件更新的時候融合進來。 如果最初的字串與事實不符,那麼請報告它(或者自己修補它) 但是不要翻譯它。相反,你可以在 PO 文件中用注解給該字串做個標記。

  • 維護風格和原始字串的語氣。特別是那些不成句子的信息(cannot open file %s)可能不應該以大寫字符開頭 (如果你的語言區分大小寫的話)或者用句號結束(如果你的語言裡有符號標志)。

  • 如果你不知道一條消息是什麼意思,或者它很含糊, 那麼在開發者郵遞列表上詢問。因為可能說英語的最終用戶也可能不明白它或者覺得它不好理解,所以我們最好改善這些信息。