一、文件簡介
.po文件,.mo文件,.pot文件是由gettext程序生成或者使用的源代碼和編譯結果。
1、.pot文件
是一種模板文件,其實質與.po文件一樣,其中包含了從源代碼中提取所有的翻譯字符串的列表,主要提供給翻譯人員使用。
從源碼中掃描得到的翻譯模版文件,原始語言取決於源碼字符串中使用的自然語言,建議使用英文。純文本格式;
2、.po文件
根據 POT 文件建立的各種語言版本的待翻譯文件,其中包含原始語言和被翻譯的目標語言。純文本格式;
(1)用程序msginit來分析pot文件,生成各語言對應的po文件,比如中文就是zh_CN.po,法語就是fr.po文件。
(2)PO是Portable Object(可移植對象)的縮寫形式,它是面向翻譯人員的、提取於源代碼的一種資源文件。
(3).po文件可以用任何編輯器如poEdit,vi,Emacs,editplus打開,交給翻譯人員來將其中的文字翻譯成本國語言。
在我們系統中,直接新建.po文件修改即可。在診斷模式下:/usr/share/locale/zh_CN/LC_MESSAGES路勁下存放了對應的mo.po文件。目前僅支持中英文!
3、.mo文件
供最終軟件實際使用的文件,使用 PO 編譯而成。二進制格式。
(1)用msgfmt將.po文件編譯成mo文件,這是一個二進制文件,不能直接編輯。
(2)MO是Machine Object(機器對象)的縮寫形式,它是面向計算機的、由.po文件通過GNU gettext工具包編譯而成的二進制文件,應用程序通過讀取.mo文件使自身的界面轉換成用戶使用的語言,如簡體中文。
(3)可以用工具如msgunfmt命令將.mo文件反編譯爲.po文件。
gettext是一套工具集的名稱。這套工具集包含 xgettext/msginit/msgfmt 等一套建立模版(POT)、創建PO文件和編譯MO文件的工具。
gettext 包含的工具如下:
- xgettext 從源碼中生成POT模版或直接生成PO文件
- msginit 基於POT文件生成待翻譯的PO文件;
- msgfmt 將PO文件編譯成二進制的MO文件;
- msgunfmt 顧名思義,將MO文件反編譯成PO文件;
- msgmerge 將POT模版文件與PO文件合併。用於在源碼更新之後將新的待翻譯內容更新到已經翻譯的PO文件中;
- msgcat 將多個PO文件合併在一起。
來源: http://blog.csdn.net/feihu_guest/article/details/37924689
維護:
維護po的翻譯人員在每次得到從新的程序源代碼產生的po時,都用msgmerge來根據舊的已翻 譯過的po來先處理一下新的未翻譯的po。
有的msgid前面一行有fuzzy的字樣。這說明,第一這個po是被msgmerge處理過的;第二,已翻譯的po裏沒有和這個msgid完全等同的 msgid,只有非常相似的。這種情況下,msgmerge仍然會用那個相似的msgid來翻譯此msgid。不過會給這個msgid標記爲fuzzy, 表示翻譯人員仍然要翻譯這 個msgid,並在翻譯後去掉上面帶fuzzy的這一行(翻譯好後必須去掉,fuzyy。否則無法顯示譯文)。
在我們系統中,原本/usr/share/locale/zh_CN/LC_MESSAGES路勁下僅存放了對應的mo文件。爲了便於擴展,修改src/locale/zh_CN下的Makefile使得生成的po文件也保存在該路徑下。翻譯人員可以取得該po文件進行對應的翻譯。然後將該翻譯過後的po文件(例如中日,中韓)存放在/usr/share/locale/路徑下即可。最後在程序代碼中根據當前語言環境在該目錄下尋找指定的語言包進行翻譯即可。比如zhonghan.po。由於存在預加載,我們翻譯好的.po文件需要重新編譯版本下載安裝。
TIPS:假如想增加日文提示。需要在src/locale目錄下仿照zh_CN再新建一個目錄,Makefile的編寫仿照zh_CN目錄即可。然後在新建目錄下添加翻譯好的中日po文件。Makefile根據這個文件進行編譯安裝即可。同時也需要記得修改系統的查找mo文件函數。設備目前路徑是usr/share/locale//zh_CN/LC_MESSAGES/msg.po,只需要仿照即可在locale目錄下新增路徑即可。
如圖所示:傳入的lang需要和頁面進行交互討論,目前系統僅支持中文,需要新定義新的語言字段。然後下面的查找判斷再根據傳入的新語言類型增加一個判斷即可。若bindtextdomain爲空代表在當前路徑下默認綁定最先找到的mo文件。testdomain則解讀指定的mo文件,若爲空則默認讀取最新讀到的mo文件。故存在多個mo文件需要指定綁定的mo. 詳情參考man bindytextdomain 3.
PO文件詳解:
po文件都是由一對對的msgid和msgstr組成的。msgid就是原文。msgstr就是譯文。
注:對於不可能出現的提示信息可以不寫中文翻譯。
1.可以看到setlocale(LC_ALL, " ");設置語言環境,第二個參數如果爲空代表讀取當前語言環境locale。設置失敗返回NULL。“”之間不能加空格。
2.接着就是bindtextdomain("msg", LANGUAGE_PATH),參考:man 3 bindtextdomain,功能是:設置包含 LC_MESSAGES 分類 (catalog) 的 locale 目錄,程序的 .mo 文件就保存到其下的目錄中。LC_MESSAGES 是 locale 的一個分類 (catalog),和其它的分類,如:LC_TIME、LC_CTYPE,是平級的概念。domainname、locale 目錄、程序當前活動 locale,這三者會決定你需要將 .mo 放到 locale 目錄的具體位置,因爲當前locale可能是中文zh_CN,也可能是繁體中文zh_TW。最終存放路勁是: [locale 目錄]/[活動 locale]/LC_MESSAGES/msg.mo。本設備存放路徑則是usr/share/locale//zh_CN/LC_MESSAGES/msg.po
3.textdomain("msg");參考:man 3 bindtextdomain,功能是:設置後來使用 gettext() 時的 domain。示例中設置:textdomain("msg")。一般與上一步的domainname相同。若存在多個mo文件,上述函數進行多次綁定後,則該函數就特別指定當前需要綁定的mo文件。
4.gettext();參考:man 3 gettext, 功能是:根據環境讀取mo文件中的 msgid還是msgstr,並返回適當的語言類型。
總結步驟:
一般的工作流程是這樣的:
- 在源碼中使用約定的語法來書寫字符串,C語言默認是
gettext("hello, world")
。在本文中,將使用_("hello, world")
; - 使用 xgettext 從源碼中掃描出需要翻譯的文本,建立 POT 文件;
- 使用 msginit 命令根據 POT 文件建立 PO 文件。或者直接在上一步也可以直接建立 PO 文件;
- 進行人工翻譯(當然也可以進行機器翻譯),翻譯的結果保存在 PO 文件中;
- 使用 msgfmt 命令將 PO 文件編譯成 MO 文件;
- 在程序中實現調用命令,本文中是
_
函數,這個函數將讀取並解析 MO 文件,根據調用的原始語言文本返回翻譯之後的文本。
C語言簡單實例:
1.新建1.c文件如下:
2.xgettext -a 1.c -o 1.pot生成pot文件。會提取出所有的字符串,如下:
3.根據.pot文件可以產生不同.po文件。
export LANGUAGE=zh_CN設置當前語言環境爲中文。
msginit -l zh_CN.utf-8 -i 1.pot初始化1.pot文件,當前路徑會生成zh_CN.po。
進入zh_CN.po文件中增加對應字符串中文翻譯即可。(注意:將字符集從ASCII更改爲UTF-8)
4.msgfmt zh_CN.po -o zh_CN.mo根據po文件生成mo文件。
5.cp -f zh_CN.mo /usr/share/locale/zh_CN/LC_MESSAGES/test.mo。注意test.mo中的名稱需要和代碼中的domianname名稱一致。
複製mo文件到語言目錄下。
gcc 1.c,然後./a.out即可看到屏幕打印出來的是:“你好,世界”。
若export LANGUAGE=en,即可看到屏幕打印出來的是:“hello, world”。
若添加其他語言也很簡單,只需要對待一箇中文一樣,生成一個mo文件,並安裝到系統中對應的目錄然後根據系統語言環境變量來讀取即可。切換不同語言就相當於修改locale.