Chapter 44. 本地語言支援

Table of Contents
44.1. 寄語翻譯家
44.1.1. 要求
44.1.2. 概念
44.1.3. 建立和維護訊息資料表
44.1.4. 編輯 PO 文件
44.2. 寄語程序員
44.2.1. 機理
44.2.2. 消息書寫教學

44.1. 寄語翻譯家

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

44.1.1. 要求

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

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

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

44.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)標誌的鍵。

44.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 擴展的文件。

44.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)可能不應該以大寫字元開頭 (如果您的語言區分大小寫的話)或者用句號結束(如果您的語言裡有符號標誌)。

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