Chapter 10. 本地語言支援

Table of Contents
10.1. 寄語翻譯家
10.1.1. 要求
10.1.2. 概念
10.1.3. 建立和維護資訊表
10.1.4. 編輯 PO 文件
10.2. 寄語程式員

10.1. 寄語翻譯家

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

10.1.1. 要求

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

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

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

10.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)標志 的鍵.

10.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 擴展的.

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

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