Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GNU gettext簡介 - 以C語言為範例

GNU gettext簡介 - 以C語言為範例

E48bd6aeb77b88d5762cd5d96e2c397d?s=128

Wen_Liao

June 04, 2014
Tweet

More Decks by Wen_Liao

Other Decks in Technology

Transcript

  1. GNU gettext簡介 以C語言為範例 Wen Liao

  2. 目標 簡介GNU gettext 以及其用法,以C語言為範例

  3. Outline • 關於GNU gettext • 使用gettext處理多國語言訊息 • 參考資料 • Q

    & A
  4. 關於gettext • 1990年代Sun推出的軟體,用於處理Unix下面 程式訊息的多國語言問題。 • 後來GNU協會也推出了GNU gettext

  5. Outline • 關於GNU gettext • 使用gettext處理多國語言訊息 • 參考資料 • Q

    & A
  6. 流程 • 修改程式碼 ◦ 告訴系統使用環境變數的語言相關設定 ◦ 告訴系統要吃那個目錄下面的哪個語文訊息相關檔案 ▪ 目錄:/aa/bb/cc/LC_MESSAGES ▪

    檔案:my_prog.mo ◦ 使用gettext API描述程式訊息 • 使用工具產生portable object tempate檔案 (pot)
  7. 流程 • 透過pot檔案,使用工具產生需要語言版本訊 息portable object (po)檔如zh_TW.po, fr.po, ja.po • 開始翻譯

    • 把翻譯好的po轉成平台可辨識的machine object (mo)檔案
  8. http://en.wikipedia.org/wiki/File:Gettext.svg

  9. 範例 (印出訊息,支援中文和英文) #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
  10. 範例 (印出訊息,支援中文和英文) 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
  11. 編譯 $ gcc -Wall -Werror -g -DPACKAGE=\" test_gettext\" -DLOCALEDIR=\" /home/user/gettext/po\"

    test_gettext.c -o test_gettext 使用者自行設定語言檔 目錄和檔案。正式使用 可放在/usr/share/locale 下面對應的語系目錄。
  12. po 目錄 tree view $ tree po/ po/ └── zh_TW

    └── LC_MESSAGES └── test_gettext.mo
  13. 產生pot檔 xgettext -o test_gettext.pot --add-comments=- - k_ test_gettext.c

  14. 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.
  15. 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 <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n"
  16. pot內容節錄 #: test_gettext.c:40 msgid "Taipei" msgstr "" #: test_gettext.c:41 msgid

    "bus" msgstr ""
  17. pot內容節錄 #: test_gettext.c:44 #, c-format msgid "I will go to

    %s by %s\n" msgstr ""
  18. 從pot檔產生中文po檔案 • msginit --locale=zh_TW --input=test_gettext. pot --no-translator

  19. 未翻譯前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)

    <zh- l10n@linux.org.tw>\n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n"
  20. 更新中文po檔案 • 隨著程式持續開發會新增新的訊息,此時舊的 翻譯還在,所以需要比對新的pot檔並且合併 到原本翻譯的po檔內。 • msgmerge zh_TW.po test_gettext.pot

  21. 翻譯po檔 msgid "Taipei" msgstr "台北" msgid "bus" msgstr "公車" msgid

    "I will go to %s by %s\n" msgstr "我搭乘%2$s到%1$s。\n" 名詞順序會隨語言不同 而改變,gettext可以在翻 譯時更改順序。
  22. 產生mo檔案 msgfmt zh_TW.po -o /home/user/gettext/po/zh_TW/LC_MESSAGES/ test_gettext.mo

  23. 驗收成果 $ LC_ALL=en_US.utf8 ./test_gettext I will go to Taipei by

    bus $ LC_ALL=zh_TW.utf8 ./test_gettext 我搭乘公車到台北。 en_US.uft8等資料可以 由locale -a取得
  24. 同場加映, fuzzy #, fuzzy msgid "Taipei" msgstr "台北" • 產生mo後執行結果

    $ LC_ALL=zh_TW.utf8 ./test_gettext 我搭乘公車到Taipei。 , fuzzy是gettext工具語法,表 示該翻譯尚未定案,所以執行 時不會使用該翻譯。
  25. Outline • 關於GNU gettext • 使用gettext處理多國語言訊息 • 參考資料 • Q

    & A
  26. 參考資料 • 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
  27. Outline • 關於GNU gettext • 使用gettext處理多國語言訊息 • 參考資料 • Q

    & A