[轉載請註明出處] http://kezeodsnx.pixnet.net/blog

作者: kezeodsnx

Joke

會說3種語言以上的人,叫做 Multilingual(多種語言的)。
會說2種語言的人,叫做 Bilingual,(雙語的)。
那麼,只會說一種語言的人呢?
這種人,叫做 American

引言

雖然這是個Sarcasm,但也可從從這個笑話可以看的出美國文化的強大。作業系統要用美國人的Micriosoft;兩個不同國藉的人用英文溝通;甚至,寫程式都要用英文。然而,這樣的統一,有好有壞。好的就不說了,來說壞的。從軟體開發的角度,一個好用的軟體,寫的盡善盡美,user flow都定義的清晰明瞭,各式各樣的防呆一應俱全,連美工都做的很炫--這樣有代表這個軟體會被每個人接受嗎?似乎少了什麼。如果這個部落格以全英文來寫,正在看這篇文章的你,會有多少耐心把它讀完?

有時跟老外co-work時,會覺得沮喪。自己懂的東西太少,看東西速度慢,邏輯能力差。某種程度上文化產生了一些影響,也就是sense的問題。因此,先天不平等,後天當然要更努力了,高手無所不在,只是沒遇到,也不需要妄自菲薄。

I18N

"The operation by which a program, or a set of programs turned into a package, is made aware of and able to support multiple languages"

指套件中的一個程式或一套程式,被撰寫為可察覺且可支援多國語言的過程

L10N

the operation by which, in a set of programs already internationalized, one gives the program all needed information so that it can adapt itself to handle its input and output in a fashion which is correct for some native language and cultural habits.

以上是英文的文言文,讓我來localization成這個時代的白話文。

 

I18N L10N M17N G11N

Internationalization: 指的是在程式開發階段,腦子裡就有Internationalization的規劃。

Localization: 把所需Internationlization,再根據各地不同的民情風俗,如日曆,貨幣,日期格式,再做一次轉換。

Multilingualization: 有顯示,處理多國語言的能力

Globalization: I18N+L10N

舉個例子來mapping。

The gxd damn mat rempits are street racing in Nan-Liao at 100 Km/hr.

Internationalization的結果是:該死的飆車族正在南寮以時速100公里狂飆。但這樣的文字,在不習慣用公里英國人來看,會有點搞不清楚狀況,不知道100公里到底有多快。因此,Localization一下,在英國應該這樣翻:該死的飆車族正在南寮以時速62哩狂飆。這樣英國人也能了解台灣的飆車族有多囂張。如果你有能力把這句話以中,英,日,韓,台...等語言講給朋友聽,那基本上你已經做到了Multilingualization。如果你完整的把這句話以世界上所有的語言講出來,那就是Globalization。

GNU/Gettext

在GNU/Linux裡,有一套工具來達到I18N,那就是Gettext。這是GNU標準的套件,大多數的package也都技援Gettext。在開發程式時,也相當容易實作。

方法很簡單。通常要顯示訊息給使用者時,會這麼做:

printf("Hello World!!");

為了讓gettext能找到需要internalization的字串,改成:

printf(gettext("Hello World"));

而gettext會做下列的事:

  。檢查locale (LC_ALL, LC_MESSAGE or LANG)

  。搜尋id,在此例中是Hello World (在po檔中做搜尋,後面會介紹)

  。印出翻譯過後的字串

寫完code後,用以下command抓出所有需要用gettext轉換的字串,產生po檔。這個po檔就是上面提過用來搜尋id的檔案,

 xgettext  hello.c -o hello.po

這個檔內容是

#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-06-17 14:08+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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: hello.c:11
#, c-format
msgid "Hello World!!\n"
msgstr ""

開頭是一些資訊,可改可不改(Project-Id-Version,PO-Revision-Date和Last-Translator等)。其中charset要指明,不然會有warning。接下來的部分就是id和翻譯了。改過的po檔如下:

#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-06-17 14:08+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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: hello.c:11
#, c-format
msgid "Hello World!!\n"
msgstr "哈囉  世界!!\n"

請注意結尾的換行符號('\n'),如果id有的話,翻完也要加,不然也會有warning。

範例程式hello.c

#include <stdio.h>
#include <libintl.h>
#include <locale.h>
#define LOCALEDIR "/usr/share/locale"
#define PACKAGE "hello"
int main(int argc, char* argv[])
{
        setlocale(LC_ALL,"");
        textdomain(PACKAGE);
        bindtextdomain(PACKAGE,LOCALEDIR);
        printf(gettext("Hello World!!\n"));
        return 0;
}

root@user-ubuntu:/home/user/temp/ctest# gcc -o hello hello.c

root@user-ubuntu:/home/user/temp/ctest# xgettext  hello.c -o hello.po

編輯hello.po後

root@user-ubuntu:/home/user/temp/ctest# msgfmt hello.po -o hello.mo

root@user-ubuntu:/home/user/temp/ctest# cp hello.mo /usr/share/locale/zh_TW/LC_MESSAGES/

root@user-ubuntu:/home/user/temp/ctest# ./hello
哈囉 世界!!

註:

1. 在定義上,pox指的是未翻譯的po檔。也就是說pox翻完後,就變po檔。而mo檔也有類似的定義:沒被安裝到正確路徑的mo檔,叫gmo。

2. 也有開發好的應用程式poedit,可將po轉成mo。

 

kezeodsnx 發表在 痞客邦 PIXNET 留言(0) 人氣()