gnu gettext簡介 - 以C語言為範例
TRANSCRIPT
GNU gettext簡介 以C語言為範例
Wen Liao
目標
簡介GNU gettext 以及其用法,以C語言為範例
Outline
● 關於GNU gettext● 使用gettext處理多國語言訊息● 參考資料● Q & A
關於gettext
● 1990年代Sun推出的軟體,用於處理Unix下面程式訊息的多國語言問題。
● 後來GNU協會也推出了GNU gettext
Outline
● 關於GNU gettext● 使用gettext處理多國語言訊息● 參考資料● Q & A
流程
● 修改程式碼○ 告訴系統使用環境變數的語言相關設定○ 告訴系統要吃那個目錄下面的哪個語文訊息相關檔案
■ 目錄:/aa/bb/cc/LC_MESSAGES■ 檔案:my_prog.mo
○ 使用gettext API描述程式訊息
● 使用工具產生portable object tempate檔案(pot)
流程
● 透過pot檔案,使用工具產生需要語言版本訊息portable object (po)檔如zh_TW.po, fr.po, ja.po
● 開始翻譯● 把翻譯好的po轉成平台可辨識的machine
object (mo)檔案
http://en.wikipedia.org/wiki/File:Gettext.svg
範例 (印出訊息,支援中文和英文)
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <locale.h>#include <libintl.h>#define MAX_CHAR (32)
int main(int argc, char **argv){ char dest[MAX_CHAR]; char transport[MAX_CHAR];
gettext和設定語系用到的header file
範例 (印出訊息,支援中文和英文)
setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE);
strncpy(dest, gettext("Taipei"), MAX_CHAR); strncpy(transport, gettext("bus"), MAX_CHAR);
printf(gettext("I will go to %s by %s.\n"), dest, transport);
return 0;}
使用環境變數設定的語言環境 指定要吃那個目錄
的哪個語言檔案c
載入語言檔案
gettext API
編譯
$ gcc -Wall -Werror -g -DPACKAGE=\"test_gettext\" -DLOCALEDIR=\"/home/user/gettext/po\" test_gettext.c -o test_gettext
使用者自行設定語言檔目錄和檔案。正式使用可放在/usr/share/locale下面對應的語系目錄。
po 目錄 tree view
$ tree po/po/└── zh_TW └── LC_MESSAGES └── test_gettext.mo
產生pot檔
xgettext -o test_gettext.pot --add-comments=- -k_ test_gettext.c
pot內容節錄
# SOME DESCRIPTIVE TITLE.# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER# This file is distributed under the same license as the PACKAGE package.# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
pot內容節錄
msgid ""msgstr """Project-Id-Version: PACKAGE VERSION\n""Report-Msgid-Bugs-To: \n""POT-Creation-Date: 2014-06-04 12:36+0800\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"
pot內容節錄
#: test_gettext.c:40msgid "Taipei"msgstr ""
#: test_gettext.c:41msgid "bus"msgstr ""
pot內容節錄
#: test_gettext.c:44#, c-formatmsgid "I will go to %s by %s\n"msgstr ""
從pot檔產生中文po檔案
● msginit --locale=zh_TW --input=test_gettext.pot --no-translator
未翻譯前po系統和手動更新部份
“POT-Creation-Date: 2014-05-30 21:18+0800\n""PO-Revision-Date: 2014-05-30 21:18+0800\n""Language-Team: Chinese (traditional) <[email protected]>\n""Language: zh_TW\n""MIME-Version: 1.0\n""Content-Type: text/plain; charset=UTF-8\n"
更新中文po檔案
● 隨著程式持續開發會新增新的訊息,此時舊的翻譯還在,所以需要比對新的pot檔並且合併到原本翻譯的po檔內。
● msgmerge zh_TW.po test_gettext.pot
翻譯po檔
msgid "Taipei"msgstr "台北"
msgid "bus"msgstr "公車"
msgid "I will go to %s by %s\n"msgstr "我搭乘%2$s到%1$s。\n"
名詞順序會隨語言不同而改變,gettext可以在翻譯時更改順序。
產生mo檔案
msgfmt zh_TW.po -o /home/user/gettext/po/zh_TW/LC_MESSAGES/test_gettext.mo
驗收成果
$ LC_ALL=en_US.utf8 ./test_gettextI will go to Taipei by bus
$ LC_ALL=zh_TW.utf8 ./test_gettext我搭乘公車到台北。
en_US.uft8等資料可以由locale -a取得
同場加映, fuzzy
#, fuzzymsgid "Taipei"msgstr "台北"
● 產生mo後執行結果
$ LC_ALL=zh_TW.utf8 ./test_gettext我搭乘公車到Taipei。 , fuzzy是gettext工具語法,表
示該翻譯尚未定案,所以執行時不會使用該翻譯。
Outline
● 關於GNU gettext● 使用gettext處理多國語言訊息● 參考資料● Q & A
參考資料
● Wikipedia: gettext○ http://en.wikipedia.org/wiki/Gettext
● gettext手冊○ http://www.gnu.org/software/gettext/manual/gettext.
html● C語言中使用gettext
○ http://wen00072-blog.logdown.com/posts/202230-study-on-gettext
Outline
● 關於GNU gettext● 使用gettext處理多國語言訊息● 參考資料● Q & A