• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 使用 m17n 實現各國語言間代碼移植

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    為了讓 Linux 應用程序在全世界范圍都可以使用,而不會在西方語言與世界上其他語言之間產生任何區別,我們應該發行一些 本地化 后的版本,它們可以輸入、存儲、提取或呈現任何語言,而不管這些語言是多么復雜。多語言庫,或稱為 m17n,為類 UNIX 平臺上的所
    為了讓 Linux® 應用程序在全世界范圍都可以使用,而不會在西方語言與世界上其他語言之間產生任何區別,我們應該發行一些本地化后的版本,它們可以輸入、存儲、提取或呈現任何語言,而不管這些語言是多么復雜。多語言庫,或稱為 m17n,為類 UNIX® 平臺上的所有語言提供了一個國際化解決方案。

    在很短的時間之內 —— 總共還不到 20 年 —— 個人計算機已經成為我們工作和生活中的一種必需設備。受到半導體和處理器快速發展的推動,大量的供應商使得計算機的價格一落千丈,Internet 也已經在全球廣為分布,個人計算機現在已經不再是一種奢侈品,而是一種常見的家用電器了。

    實際上,在很多富裕的國家(例如美國、日本、英國),每兩個家庭就會擁有一臺計算機,并且會使用寬帶服務。就全世界來看,雖然家庭收入可能會有很大的不同,但是個人計算機都很容易購買了,即使在馬爾代夫,我們也很容易購買到筆記本。另外,如果我們碰巧說的是 Dhivehi 方言(馬爾代夫的一種方言),微軟也為我們提供了一個這種版本的 Microsoft® Windows® XP 操作系統。

    就全球廣泛接受的個人計算機來說,大部分現代操作系統都提供了一些編程庫來促進 國際化 的發展,或者將軟件調整為支持多種語言的。國際化(通常簡寫為 i18n,節選自 i-nternationalizatio-n)庫通常都會將應用程序的文本資源(按鈕標簽、用戶界面[UI] 提示和菜單選項)保存成多種語言的。在啟動國際化后的應用程序后顯示哪種語言,這要取決于用戶的區域設置 —— 通常,這是一個可配置的系統或個人帳號首選項。

    理想來說 —— 至少對于獨立軟件供應商來說 —— 相同的可執行程序以日語或希臘語運行時都能運行得一樣好。然而,構建 “本地方言” 版本的應用程序的情況遠遠沒有這么理想。包括被廣泛認可的 ISO(International Standards Organization)/IEC(International Engineering Consortium)10646 和 Unicode,沒有哪種字符編碼可以解決如何實現任意語言的輸入和呈現問題。ISO/IEC 10646 和 Unicode 只指定了如何存儲、檢索和排序字符以及字符的特殊組合。例如,這些標準并沒有規定統一的格式、嵌入式數據或標識來讓使用泰國語書寫的文檔怎樣才能按照泰國語的規范規則正確地呈現出它們的樣子來。是的,Unicode 可以維護使用泰國語書寫的文檔的內容,也可以保證這種文件在所有使用 Unicode 的平臺上都可以很好地進行移植,但是它并不能保證我們可以正確查看文件,也不能保證文檔所呈現出來的樣子與作者的意圖一致。

    我們來考慮一下這種情況:盡管 Linux GNU C 庫(glibc)提供了一些函數來處理 ISO 10646 兼容的 31 位字符,但是它并不能保證這些字符可以在顯示設備上正確進行顯示。有些 glibc 字符串函數,例如 strcat()strlen(),都可以正確地處理多字節的問題,但是要正確顯示阿拉伯語,需要雙向(bidi)顯示的功能,這種功能只有在圖形用戶界面(GUI)工具包和專用字符串顯示庫中才能找到。

    例如,GNOME 需要 GTK+ 工具包和 Pango(一個文本顯示庫)來實現對 i18n 的完整支持(然而,Pango 在解決自己用途不夠廣泛方面有一些限制。請參看側欄 pango 的問題)。其他 GUI 工具包提供了對 i18n 的支持,但卻并不總是能兼容這些標準。當然,Linux 上的圖形應用程序也需要 X Window System 的基本顯示庫 Xlib,它提供了兩種繪圖(形狀和線條)和字符顯示原語。不幸的是,Xlib 只能顯示西歐語言。

    Pango 的問題

    Pango 可以放置(布局)并顯示一些復雜的手稿,但是不能對多字節的文本進行排序或搜索功能。Pango 假設底層庫 —— 通常是使用 C 語言編寫的,可以對使用 Unicode 標準指定的所有語言都進行操作 —— 可以執行基本的文本處理操作。

    一個庫顯示所有語言

    要讓應用程序在全球都可以使用 —— 而不會在西方國家和世界上其他很多語言之間產生不公平的現象 —— 我們必須要能夠 輸入、存儲、提取并 顯示 任何語言,而不管這究竟會多么復雜。正如上面介紹的一樣,有一些廣為認可的標準為多字節存儲和可移植性提供了一些便利;然而,現在還沒有為輸入和顯示制定標準。更加糟糕的是,即使是最好的多語言文本編輯器也會被迫混合使用簡單的國際化庫和私有 GUI 工具包。添加一種語言可能會需要另外一種(很可能是新的)定制庫。

    Multilingualization Library 或 m17n 庫會盡力為類 UNIX 平臺上多種語言書寫的文本的輸入、處理和顯示提供一種單一的解決方案。另外,m17n 的目標是充分利用現有且大家都可以很好地理解的典型 UNIX 應用程序框架,而不是利用軟件開發人員的其他模型。

    最后,m17n 會努力使國際化的內容更加豐富,而不僅僅是簡單地從英語移植到另外一種語言上。使用 m17n,同一個二進制文件可以在一個系統上顯示法語,在另外一個系統上顯示蒙古語,甚至在同一個屏幕上就可以顯示多種語言的文本。更好的是,m17n 可以(令人信服地)實現諸如文本數據庫之類的功能,這使它可以存儲并處理大量的國際化內容。

    m17n 庫是在日本 Tsukuba 的 National Institute for Advanced Science and Technology 工作的 4 個日本程序員編寫的。很多年以來,日本都一直走在了國際化的前端,部分原因是日語學者一直在試圖為人文學科探索一種百科全書式的方法 —— 尤其對世界上各種語言更為關注(有關歷史上的一些內容,請參看側欄 亞洲語言的起源。)

    亞洲語言的起源

    世界上很多國家的手寫語言(這也是用戶使用的最多的形式)都是在全世界最重要的宗教之一 —— 佛教(也是日本最重要的宗教信仰)之內產生并不斷演進的。

    印度、中國以及緬甸的語言和手稿很多都是有關佛經的歷史的。日本的佛教學者也需要學習梵語、巴利語、古漢語、古藏語、中日語以及古日語的幾個變種,另外在深入研究佛教之前,還需要學習 3 本日語手稿(如果它們可以稱為手稿的話)。熟悉梵語、古漢語以及幾種古日語的變種對于佛教學者來說只是工作的一個最低需求。而且他們常常還需要了解現有佛教所使用的一些語言,例如僧伽羅人語、泰國語、現代韓語等。

    在以佛教文化為根基的外向型經濟中,要想了解世界,僅僅使用一種語言是不可想像的。

    m17n 庫是由 3 個庫和一個存儲單一腳本以及正確顯示腳本所需要的元數據的數據庫構成的:

    • m17n C 庫可以類似地實現 glibc (以及各種風格的 libc )的一些基本的文本處理功能。
    • m17n X 庫與 Xlib 是緊密對應的。它提供了基本的繪制字符的功能,并且對呈現所做的假設很少。
    • m17n 工具包提供了一些功能,可以對復雜的腳本進行處理,使它們可以準備好在屏幕上進行顯示。例如,泰國語在顯示之前,必須進行排序、合成和重新排序。
    • 最后,m17n 數據庫存儲了每種語言所特有的一些數據。例如,某種特有語言可能會需要自己的字體、一種特定的編碼以及一些特殊的機制來輸入自己的數據。m17n 庫是與語言無關的;m17n 數據庫中保存了所有與語言有關的信息。

    圖 1 給出了 m17n 的 4 個部分,以及這些庫是如何與現有的系統組件對應的。m17n 組件和傳統 UNIX 庫之間存在驚人的類似之處并不意外:m17n 的創建者希望能夠讓多語言的應用程序的編寫盡量簡單。我們只要使用一個等效的多語言庫來替換相同語義的函數即可。


    圖 1. m17n 庫的層次結構
    m17n 庫的層次結構

    (從側面來看,m17n C 和 X 庫就預示著 X 服務器可以提供國際化功能。不過,m17n 對底層操作系統和呈現機制的假設較少,因此我們可以將 m17n 移植到其他窗口系統上。實際上,將 m17n 集成到跨平臺的 GUI 工具包(例如類 UNIX 系統上使用的 Qt)正是當前的工作重點,m17n 團隊正在將自己的代碼加入 GTK 的修正版本中。)

    字符一瞥

    添加新拼字法也非常簡單:不需要改編 m17n 庫來顯示新腳本。相反,只需要創建一個新的 m17n M-text,并將 M-text 添加到 m17n 數據庫上即可。

    可以將 M-text 當作一個泛化的 C 字符串,因為這就可以將任意屬性添加到通常與 C 字符串有關的字符代碼中。一個屬性可以指定語言要顯示的字符,而另外一個屬性則可以指定特定的字體。Bidi 信息也是使用 M-text 表示來進行編碼的,并且基本的字形信息都可以出現。

    例如,圖 2(已經得到 m17n 開發人員的許可進行復制)展示了這些屬性如何用來修改文本字符串的外觀。這個字符串非常簡單,內容是 “This is sample text to show the property”。然而,每個字符串都有一個 face 屬性 —— 或多個 face 屬性 —— 它決定了要使用哪些字體來顯示字符。該圖中所顯示的 face 屬性都故意進行了簡化,但是我們可以看到這種特性所提供的靈活性,這對于世界上很多手寫語言來說都是必要的。


    圖 2. 可以單獨使用或一起使用來修改文本外觀的屬性
    m17n 屬性

    有很多腳本都需要復雜的過程來重新進行排序,或重新放置各個要顯示的復雜合成圖形。諸如泰米爾語、緬甸語和泰國語之類的腳本在進行顯示之前都需要這種重新排序過程。作為更為具體的一個例子,圖 3(也已經獲得作者許可進行復制)展示了單詞 Hindi 是如何進行處理來使用 Devanagri 腳本正確顯示的。這需要兩個階段。第一個階段是將字符序列從字節順序(字符在內存中如何存儲)轉換成正確的手寫順序(字符如何在紙面上顯示)。第二個階段負責掃描特有的字形和讀音序列(如果存在)并將這個序列替換成 “復合” 字形(英語有很多這種轉換來增強文本的可讀性。根據所使用的字體的不同, fi 序列通常都會使用一個 fi 字形代替,這要取決于我們選擇的字體)。


    圖 3. 顯示單詞 “Hindi”
    顯示 Hindi

    這個重新排序過程的通用名字是 Complex Font Layout(CFL)。通常,CFL 信息都包含在字體中,在某些情況中,已經寫死到顯示庫中了。在 m17n 中,CFL 信息可以在 FLT(Font Layout Table)中找到。有些拼字法需要少量的 FLT 數據;另外一些字符則需要很多信息來捕獲復雜的規則。

    例如, Sino-Japanese orthography 就沒有前后規則可以影響單個字形組合的復合。然而,泰國語的確有一些有趣的規則可以影響 orthography 的變化,但是它對于泰國口語不會產生任何影響。泰國語的拼字法對于周圍的文本來說非常敏感,但是對于口語來說則并非如此。印度腳本中特定的組合規則也相當復雜,必須使用 FLT 來顯示。

    最后,諸如字體、雙向顯示、Unicode 和語言之類的數據都會將文本的顯示呈現在屏幕上。下一個棘手的問題 —— 也可能是現在正出現在您腦海中的問題 —— 是我們如何以非 ASCII 字體的形式來輸入文本。

    使用有 500 個鍵的鍵盤

    對于英語和很多歐洲語言來說,一個字符映射為一個鍵(或兩個鍵)就足夠了。大寫鍵可以直接打印,鍵盤驅動程序可以對很多更為特殊的情況進行編碼,但是其模型是相同的:按下一個鍵就代表輸入某個特定的字符。

    那么,如果一種拼字法中有數百個字符,或者更特殊一點,它們之間有很多組合,情況如何呢?那么我們就不能簡單地使用一次擊鍵來實現了,而是需要使用 擊鍵序列 ,或者快速連續輸入多個鍵。有一種特別的軟件叫 輸入法,它可以將每個鍵盤序列轉換成一個字符或一系列字符。

    當然,有些擊鍵序列可能就是一次擊鍵。另外,我們可以創建一種輸入法將標準的拉丁字母鍵盤 轉換 成其他語系的拼字法。例如,老式的日語鍵盤就將拉丁字母轉換成平假名和片假名。然而,試圖使用 26 個字母(A 到 Z 的拉丁字母)表示大約 46 個平假名有些困難。

    鍵盤映射、擊鍵序列以及音譯輸入法都可以使用 m17n 數據庫來表示。這種方法很大的一個優點是可以將拼字法 的規則與應用程序代碼清楚地區分開來。應用程序代碼最適合由程序員來開發;如何顯示正確的文本則是語言學家的工作。

    獲取 m17n 庫

    正如上面介紹的一樣,m17n 包括 3 個庫和 m17n 數據庫?,F在,我們可以使用一個 m17n libc,另外還可以使用一個 Xlib 的 m17n 版本進行編碼。開發團隊正在努力編寫第 3 層的庫即 m17n X 工具包,它將成為 GTK+ 的一部分。m17n 開發人員也從事語言綁定的工作,這樣諸如 Perl 和 Ruby 之類的編程語言就都可以使用 m17n 了(這個工具包和綁定何時可用,尚沒有進度表)。m17n 庫也已經被接納為 Linux Standard Base(LSB)的一個部分,它可能會成為 Linux 國際化標準實現的一個很好的部分。

    m17n 庫的最新版本是 1.3.3,這是在 2006 年 2 月 22 日發布的。我們可以按照下面的方式來獲取 m17n 庫:

    • 下載 m17n 源代碼。這個下載頁面中還提供了使用英語和日語編寫的程序員文檔包。
    • 如果喜歡使用 CVS(Concurrent Versions System),也可以使用下面的 CVS 命令來下載代碼:
      $ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/m17n login
                      $ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/m17n co m17n-lib
                      $ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/m17n co m17n-db
                      

      從源代碼開始編譯程序也非常簡單:m17n 庫使用了典型的配置腳本來配置系統,并為編譯和安裝創建合適的 Makefile(詳細內容請參看 m17n 軟件包中的 README 文件)。

    • 如果碰巧使用的是 Debian 的發行版本,就可以使用非常方便的 APT 安裝工具來安裝 m17n 庫和它所依賴的庫。例如,要尋找 Debian 系統上所有可用的 m17n 包,就需要使用 apt-cache,例如 apt-cache search m17n。

      根據 APT 所指向的 Debian 儲存庫的不同,可能會看到如清單 1 所示的輸出內容。



      清單 1. apt-cache search m17n 命令的輸出結果
                      libm17n-0 - a multilingual text processing library - runtime
                      libm17n-dev - a multilingual text processing library - development
                      m17n-db - a multilingual text processing library - database
                      m17n-docs - a multilingual text processing library - documents
                      m17n-env - set up multilingual X environment
                      m17n-lib-bin - a multilingual text processing library - utilities
                      mlterm-im-m17nlib - MultiLingual TERMinal, m17nlib input method plugin
                      

      在找到包名之后,就可以運行 apt-get install 來自動下載并安裝 m17n 包了。根據 m17n 開發人員的說法,為 Fedora Core、Mandrake、SUSE Linux 和 Gentoo Linux 提供的包也都可以使用。

    m17n 庫依賴于幾個其他庫,這幾個庫在您的系統上可能有,也可能沒有。請閱讀前提條件中最新的列表。

    m17n 簡介

    從內部來說,m17n 庫會被組織成幾個應用程序接口(API):

    • Core:這個 API 提供了處理 M-texts 的功能。Core API 并不需要 m17n 數據庫。
    • Shell:Shell API 增加了 m17n 的數據庫查找和搜索功能。Shell 包括了這個 API 的所有功能和特性。
    • GUI:GUI API 提供了在圖形顯示設備上輸入并顯示文本的功能。GUI 隱式地包含了 Shell 和 Core API 的所有特性。
    • Miscellaneous:這個 API 定義了幾個函數來幫助對 m17n 庫進行調試和跟蹤。

    m17n 庫的使用與其他 Linux 或 UNIX 的庫的使用相同。如果要使用這個庫的所有特性,就需要在程序中包含 m17n.h 頭文件,然后在鏈接選項中加上 -lm17n 選項,這可以在 Makefile 中實現。 如果只想使用 m17n 的一部分功能,Core、Shell、GUI 以及 Miscellaneous API 每個都有單獨的包含文件。不幸的是,m17n 并沒有很多樣例代碼,很多明顯引用它們的程序,例如可以識別 m17n 的應用程序,也只有兩年的時間。然而,m17n 的軟件開發包(SDK)確實包含了一個簡單的程序,它可以使用各種編碼來顯示文件。我們可以查看一下所下載的 m17n 工具包中的 example 目錄。在這個目錄中,打開 mview.c 文件。這個文件的一部分如清單 2 所示。


    清單 2. m17n 示例文件

                ...
                325  M17N_INIT ();
                326  if (merror_code != MERROR_NONE)
                327    FATAL_ERROR ("%s\n", "Fail to initialize the m17n library.");
                328
                329  /* Decide how to decode the input stream.  */
                330  if (coding_name)
                331    {
                332      coding = mconv_resolve_coding (msymbol (coding_name));
                333      if (coding == Mnil)
                334        FATAL_ERROR ("Invalid coding: %s\n", coding_name);
                335    }
                336  else
                337    coding = Mcoding_utf_8;
                338
                339  mt = mconv_decode_stream (coding, fp);
                340  fclose (fp);
                341  if (! mt)
                342    FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
                343
                344  {
                345    MPlist *param = mplist ();
                346    MFace *face = mface ();
                347
                348    if (fontsize)
                349      mface_put_prop (face, Msize, (void *) fontsize);
                350    mplist_put (param, Mwidget, shell);
                351    mplist_put (param, Mface, face);
                352    frame = mframe (param);
                353    m17n_object_unref (param);
                354    m17n_object_unref (face);
                355  }
                356
                357  /* Create this widget hierarchy.
                358     Shell - form -+- quit
                359                   |
                360                   +- viewport - text  */
                361
                362  form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);
                363  XtSetArg (arg[0], XtNleft, XawChainLeft);
                364  XtSetArg (arg[1], XtNright, XawChainLeft);
                365  XtSetArg (arg[2], XtNtop, XawChainTop);
                366  XtSetArg (arg[3], XtNbottom, XawChainTop);
                367  XtSetArg (arg[4], XtNaclearcase/" target="_blank" >ccelerators, XtParseAcceleratorTable (quit_action));
                368  quit = XtCreateManagedWidget ("quit", commandWidgetClass, form, arg, 5);
                369  XtAddCallback (quit, XtNcallback, QuitProc, NULL);
                370
                371  viewport_width = (int) mframe_get_prop (frame, Mfont_width) * 80;
                372  viewport_height
                373    = ((int) mframe_get_prop (frame, Mfont_ascent)
                374       + (int) mframe_get_prop (frame, Mfont_descent)) * 24;
                375  XtSetArg (arg[0], XtNallowVert, True);
                376  XtSetArg (arg[1], XtNforceBars, False);
                377  XtSetArg (arg[2], XtNfromVert, quit);
                378  XtSetArg (arg[3], XtNtop, XawChainTop);
                379  XtSetArg (arg[4], XtNbottom, XawChainBottom);
                380  XtSetArg (arg[5], XtNright, XawChainRight);
                381  XtSetArg (arg[6], XtNwidth, viewport_width);
                382  XtSetArg (arg[7], XtNheight, viewport_height);
                383  viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form,
                384                                    arg, 8);
                385
                386  /* Before creating the text widget, we must calculate the height of
                387     the M-text to draw.  */
                388  control.two_dimensional = 1;
                389  control.enable_bidi = 1;
                390  control.disable_caching = 1;
                391  control.max_line_width = viewport_width;
                392  mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control,
                393                      NULL, NULL, &metric);
                ...
                

    下面對這些代碼詳細介紹一下:

    • 第 325 行負責對 m17n 庫進行初始化。
    • 第 330 行的 coding_name 變量源自于一個指定輸入文件編碼的命令行參數;如果沒有提供這種命令行,就使用 UTF-8 編碼。
    • 第 339 行讀取到達的數據,并根據編碼類型對其進行解碼,現在都反應在 coding 中。
    • 第 345 到 354 行設置要畫的文本框架。第 345 行從手頭的 M-text 中提取出一些屬性,而 346 行則提取出給定文本使用的適當字體。第 348 行設置要顯示使用的字體大?。?code>fontsize 是另外一個命令行參數),第 350 和 351 行設置該框架中要畫的其他屬性,包括要畫到哪個小部件上(前面的 shell = XtOpenApplication (&context, "M17NView", NULL, 0, &argc, argv, NULL, sessionShellWidgetClass, NULL, 0) 和最后的類型定義。
    • 第 362 到 383 行是典型的 X 工具包調用,用來設置應用程序的主窗口。第 371 到 372 行負責計算對于本地拼字法的一個 80 x 24 的窗口來說,視口應該多大。
    • 最后,在為 M-text 呈現設置一些參數之后,在 392 行就會開始顯示 m17n 文本。

    總而言之,上面對這段代碼片段的簡短分析就說明了在標準的 X 應用程序中通常要執行哪些操作。在很多情況中,創建一個多語言的應用程序只需要很少的額外代碼就可以實現,這需要采用 m17n 的函數,而不是傳統的 X 調用。

    展望

    如果沒有可以構建 m17n 代碼的系統,也不要煩惱。您仍然可以通過在線 m17n 呈現演示來體驗這個庫的作用(參看 參考資料 中的鏈接)。

    據開發人員說,他們正在繼續在 GTK+ 中集成 m17n —— 這是擴寬 m17n 的認可程度以及影響力的下一個必不可少的步驟?,F在,m17n 項目缺少樣例代碼供參考和擴展。建立更好的文檔也是另外一個需要做的工作,這與為主流平臺提供二進制文件一樣重要。然而,m17n 確實承諾會對各個省的方言也能夠實現 WYSIEYG 的編輯。這對任何語言來說都是個好消息。

    個人計算機已經不再是什么新奇的東西了。實際上,在不到 20 年的時間內,計算機已經成為了家庭的日常用品 —— 只不過它不是什么衣服之類的東西,而是用來管理信息的工具。然而,有些國家計算機的獲得和使用還并不普遍。為了平衡這種不平等,需要讓這些國家能夠獲得負擔得起的各種計算機硬件和軟件。另外,還要保證本土居民能夠以本地方言來使用計算機。

    m17n 庫構建在 Unicode 和其他標準之上,用來根據手寫語言的規則畫出任意復雜的拼字法。它將代碼與字符的格式區分開來,因此相同的代碼可以反復使用,甚至是在相同的應用程序中呈現不同的拼字法都可以。隨著這些工作的不斷進展,m17n 正在逐漸讓計算機語言變成一種全球的方言。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>