臺灣在地化社群 L10n Taiwan
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    4
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- image: https://l10n.tw/l10n-tw-logo/%E5%9C%96%E7%89%87/l10n-tw-logo.png lang: zh-tw --- # 自由軟體正體中文化工作流程規範 (Traditional Chinese L10N Translation Guidlines) <https://hackmd.io/@l10n-tw/translation_guidelines> ## 內容大綱 [TOC] ## 前言 本文目的是希望為目前正體中文翻譯環境,設立共同的譯文規範與準則。 如有任何建議,您可以在正體中文譯者郵遞論壇提出,或加入 <svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="telegram" class="svg-inline--fa fa-telegram fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512" style="width: 14px; height: 14px"><path fill="currentColor" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"></path></svg> [Telegram 群組](https://t.me/l10n_tw)一同線上討論,也竭誠歡迎您加入我們的行列。 對於自由軟體翻譯者,建議您列印本文件,以便在翻譯時隨時查閱。 ## 工作流程 不同的專案有不同的工作流程,大致分為準備、協調、翻譯和提交。 ### 準備 - 我們的原則是品質優先,請優先翻譯自己熟悉的軟體或文件 - 詳細閱讀本文件,以及全部和工作相關、要翻譯內容相關的文件 - 最好準備一本英語詞典,或者線上詞典方便查閱生字,例如:[Yahoo!奇摩字典](http://tw.dictionary.yahoo.com/);至於術語、縮寫等請先查閱 [Wikipedia](http://zh.wikipedia.org/wiki/Special:Search) 文章、查詢[微軟國際詞彙](https://www.microsoft.com/zh-tw/language)、查詢[國家教育研究院雙語詞彙、學術名詞暨辭書資訊網](https://terms.naer.edu.tw/)、[樂詞網](https//terms.naer.edu.tw/)等,或是參考 [Answers.com](http://www.answers.com/) 的內容等 - 使用線上翻譯平台的(如 Launchpad)翻譯者,在瞭解注意事項與翻譯相關格式後便可以開始進行翻譯 - 不使用線上翻譯平台的專案,請依照各專案所指定的方法取出源始碼、取得 PO 或 POT 檔,然後安裝指定的工具並開始翻譯(如要翻譯 PO 檔,強烈建議您安裝 gettext 工具組) ### 協調 協調工作的主要目的是防止多個人在互不知情的情況下同時翻譯相同的內容,一方面導致了重複勞動,另一方面也造成了合併的困難。 通常情況下的協調工作,是透過向專案翻譯小組的郵遞論壇寄送電子郵件來說明你想要負責的工作項目。若要翻譯的軟體或文件不存在,則你將自動成為其負責人並可以開始進行翻譯。 若已經有人在進行翻譯,則此後需要與之聯繫以商定分工,請在寄送認領郵件到郵遞論壇時抄送給原負責人一份,一周內無回復則視為同意你的請求。開始翻譯前若需要相關的帳號應提出申請。 GNOME 由於使用了 Damned-Lies 網站,請直接使用網站功能即可;至於線上翻譯,如 Weblate、Launchpad、Transifex、Crowdin 等,暫時還沒有進行協調工作的有效方式。 #### 正體中文譯者社群郵遞論壇 翻譯群組郵遞論壇:zh-l10n@lists.slat.org 網頁版:https://lists.slat.org/mailman3/postorius/lists/zh-l10n.lists.slat.org/ 加入論壇:發一封信到 zh-l10n-join@lists.slat.org 或是到上述網址去 subscribe 離開論壇:發一封信到 zh-l10n-leave@lists.slat.org 或是到上述網址去 unsubscribe ### 翻譯 #### PO 檔翻譯流程 **(1) 關於 GNU Gettext** GNU Gettext 是 GNU 在地化和國際化的函式庫,即 GNU Localization (l10n) & Internationalization (i18n) Library,是自由軟體國際化的常用工具。 **(2) 開始翻譯** 翻譯是我們中文化工作中的重點,在開始翻譯前請詳細閱讀本文以下章節中的各項要求,以確保品質。 PO 檔的翻譯過程中不要對 msgid 該列做任何修改,即使其中有明顯錯誤也不行,否則合併翻譯到主程式時將會發生問題。你在英文字元串上所做的變更將會喪失,且你的翻譯也不會被合併入內。在遇到來源文件有問題時,最好的辦法是向軟體開發者提交臭蟲報告。 對於翻譯時所要採用的翻譯風格,例如直譯、意譯、改寫、直譯加改寫、維持原文不翻譯等,或是對於術語在擬定譯詞的相關指引,則可參考《[自由軟體正體中文化翻譯風格指引](https://hackmd.io/@l10n-tw/translation_style_guide)》。 本文中關於 PO 檔的各項命令都假定閱讀者已經安裝了 GNU/Linux 基本系統、gettext 工具組與 intltool 工具組,或者在其他平台上安裝了相應的程式。 **(3) 檢查翻譯格式** PO 檔翻譯後請使用以下命令進行格式檢查: ```shell msgfmt --statistics -cv zh_TW.po ``` 執行以上命令後會在當前目錄下產生一個名為 `messages.mo` 的檔案,該檔案便是編譯後供機讀之用。 **(4) 校閱翻譯** 使用 PO 檔的,直接複審 PO 檔,並建議將 PO 檔編譯成 MO 檔,接著複製到相應程式的目錄下來進行實測,以確保翻譯是否有誤。 至於文件,請先建構文件並接著精讀結果文件。 如果發現問題,請回到「開始翻譯」步驟,並修正問題。 **(5) 翻譯格式設定** 因為不同的翻譯工具可能使用了不同的格式,比如標準 gettext 格式、poedit 格式等。強烈建議所有翻譯者使用標準 gettext 格式,可以使用標準的 POT 檔與 PO 檔進行合併來達到此目的: ```shell msgmerge --no-wrap -U zh_TW.po example.pot ``` #### 線上翻譯注意事項 **(1) [Weblate](https://hosted.weblate.org/)** - Weblate 目前提供兩種方式進行翻譯:「線上翻譯」與「PO 檔提交」。線上即時翻譯功能極少數會在送出翻譯後無法通過系統驗證,若有此問題請改離線翻譯再上傳提交。PO 檔提交請遵照 PO 檔翻譯流程。 **(2) [Launchpad](https://translations.launchpad.net/)** - Launchpad 平台目前提供「線上翻譯」與「PO 檔翻譯」兩種方式進行翻譯。線上翻譯時請注意以下幾點並遵照本文的翻譯要求;PO 檔翻譯請參照 PO 檔翻譯流程。 - 由於 Launchpad 沒有校閱的機制,只要是翻譯團隊的成員皆擁有所有翻譯的決定權,所以在翻譯時只要遇到不清楚原意的條目,請將「Someone should review this translation」打勾後再進行「Save & Continue」的提交動作。與其翻譯錯誤讓瞭解中文與英文的人都看不懂,更希望能保留英文起碼讓懂英文的人瞭解。 - 除了沒有校閱機制之外,Launchpad 也不會上傳該平台上的翻譯成果給非使用 Launchpad 平台的上游翻譯專案,這是目前最為人詬病的缺點。因此,使用 Launchpad 進行翻譯時,請優先翻譯以 Launchpad 平台作為其翻譯來源的軟體專案。至於那些來自非 Launchpad 平台的上游翻譯,請想要翻譯的人務必與上游保持同步狀態。 - Ubuntu 專案使用 Launchpad 平台作為其翻譯來源,Ubuntu 團隊自己開發的與經過他們修改的軟體,都可以直接進行翻譯而無須保持與上游同步。這些軟體的清單可以由[此頁面](https://wiki.ubuntu.com/Translations/TemplatesPriority)中的「Ubuntu Specific GUI Package」一節查閱。 **(3) [Transifex](http://www.transifex.net/)** - Transifex 目前提供兩種方式進行翻譯:「線上翻譯」與「PO 檔提交」。線上即時翻譯功能極少數會在送出翻譯後無法通過系統驗證,若有此問題請改離線翻譯再上傳提交。PO 檔提交請遵照 PO 檔翻譯流程。 ### PO 檔提交 #### 非翻譯平台 不同專案提交翻譯的方式不盡相同,多數情況下可以通過翻譯小組的郵遞論壇進行提交,如果您有相關項目的翻譯管理帳號則請直接提交。如果沒有負責的小組也沒有相關的帳號,請把您的翻譯發送到對應項目的翻譯者郵遞論壇 (一般名稱類似 xxx-translators、i18n、intl、l10n。 若沒有翻譯者郵遞論壇則發送到文件郵遞論壇,一般名稱類似為 xxx-doc;若還是沒有則發送到開發者郵遞論壇,一般名稱為 xxx-dev、devel、developer),或者通過填寫一個 Bug (issue) 的方式進行提交。 註:i18n 為 internationalization(國際化)簡寫,18 為該單字的字母數量;l10n 為 localization(在地化)簡寫,10 為該單字的字母數量 注意:在請別人代為提交到 TP 項目時 Last-translator 不會是您,因為 TP 要求這項需要是提交者的名字和郵件地址,您的訊息將會出現在檔頭註解的著作權列中。 提交後請根據情況再發送一封郵件來取消原來協調翻譯時的佔用聲明。 #### 翻譯平台 各個翻譯平台的提交方式都不同,請遵照各平台規定。 ## 基本守則 1. 信實傳遞原文的文化背景與情境,並以自身語言貼切表達原作者的意思 2. 請以流暢通順的中文表達。可適度依照習慣、通順程度,或前後語境,來調整句子順序,或作刪減,而不應逐句或逐字對照翻譯。例如:英文句法與中文句法經常前後相反,請適當調整 3. 譯文應該意思清晰、詞語確定情境脈絡,且符合中文表達習慣。**句子**請以整體意譯為主;至於句中**關鍵術語**,則以**情境限定下的直譯**(形式對等翻譯)為基本原則出發,再視情況作其他考量。如 Menu 會依情境直譯稱為「選單」,而非丟失情境脈絡的「菜單」 4. 原文如果表達不清晰,譯文應該補入情境脈絡,並且應根據原文上下字串和註解作推斷,並填補相應的訊息。例如 "print error" 若直譯為「列印錯誤」可能模糊不清,若**整體意譯**為「列印發生錯誤」更能避免混淆 5. 情況 4 在補入情境後即止,不要再多解釋或衍生其他補充內容 6. 原文中**約定俗成的常用語**應直譯。如常見的 Bug 稱「臭蟲」、Patch 稱「補丁」 7. **專業的晦澀黑話**維持原文不翻譯,或採作用理解式改寫。如程式開發專用的 lint(原意為毛絮)可維持原文,或依實際作用改稱為「梳理」,而 linter 則可改稱為「梳理器」 8. 多人參與專案時,應減少意譯(功能對等翻譯)個人風格(指文句個性)。程式翻譯實務作業上以「**譯完原文關鍵詞意義,並整體貼切表達**」為主。若以個人風格全意譯,不同譯者間的個人語文表達方式都有差異,最後必須有人再次以其主觀統一,重複勞動。個性化意譯僅在整套系統都能控管,人力與時間充足時採用 9. 對相同術語或短語所採用的譯詞,必須前後一致。程式翻譯與文學作品性質不同,注重再現性、重複性與一致性。並且術語盡可能一對一對應,避免讓同一個中文詞彙,重複與多個不同概念而被區分使用的英文術語對應 10. 程式中使用敬語「您」而不是「你」來表達為使用者服務,而網頁中則可採用「你」來表達親切感 11. 不要直接使用機器翻譯或 AI 翻譯的成果來提交。您可以使用機器翻譯或 AI 翻譯來幫助您理解內容,但是禁止不經思考就把自動翻譯的結果放入正式譯文中 12. 有時您可以參考簡體中文的翻譯檔,以便協助理解,但禁止不經思考只將簡體中文的翻譯檔做字元轉換後,就變成正體中文的成品。不做用詞轉換的翻譯,比不翻譯還更糟糕 ## 譯文格式規範 ### 一、標點符號 一般的原則是:除了刪節號和破折號可以視情況保留不變外,其他都應該使用中文(全形)標點符號。英文標點符號後方常常跟隨有一個半形空格,請在翻譯成中文標點符號時將其去除。 詳細的標點符號使用說明: 1. 英文中的逗號「,」在中文中可能是「,」或者「、」 2. 英文中的句號「.」在中文中應該是「,」或者「。」;其中「,」視上下文而定,多數會是「。」 3. 英文中的 \"%s\" 在圖形介面程式 (GUI) 中應該翻譯為「**%s**」, 而不是 \"%s\" 或者 \「%s\」,而且後者是不符合換碼序列要求的。即在 GUI 程式中 `something' 和 'something' 以及 \"something\" 都應翻譯為「某事」,因為教育部規範之中文標點引號為「」 4. 英文中的 \"%s\" 在命令列介面程式 (CLI) 中同樣使用全形引號,即在 CLI 程式中 `something' 和 'something' 以及 \"something\" 都應譯作「某事」 5. 英文中的 \"command -parameter argument\" 或 'command -parameter argument' 等語境為英文的字句,可將引號保持原樣,不一定要改為中文引號「」,由翻譯者自行決定 6. 英文中的「: 」應該翻譯為「:」(全形冒號),而不是「: 」(半形冒號+空格);至於作為分隔符(例如時間分隔符)的「:」請保留為英文(半形)的 :,因為這時候不是標點符號 7. 英文中的 ( ) 其**括住內容若是中文,請用全形()**;若 () 所括住的內容是英文,請使用半形小括號 ( )。 若半形小括號**前後有文字(包含中文、英文、數字)請使用空格隔開**;若小括號前後是標點,或是表示捷徑字元的小括號時,前後不應加上空格,換句話說,**標點相連之間無須補入空格** 8. 英文中的 **... 可保持不變**。由於翻譯的時候常常難以分清哪些條目是選單項,哪些條目是一般語句,而後者才能使用中文的刪節號……,所以未明者統一翻譯為...。 至於原文語句若本身已**使用刪節號「…」時,則照用**即可;一般選項內文字之刪節號請使用一個…,若為內文中之刪節號可用兩個…… 9. 英文中的 -- 可保持不變,亦可使用全形破折號 —— 10. 遇到說明英文標點的訊息時,**除了翻譯為中文外,請在譯文中加入該標點作為示範**,並在標點前後加上中文(較推薦)或英文引號。例:"separated by common" 即:以半形冒號「:」隔開;或以半形冒號 \":\" 隔開 11. 遇到說明選單的訊息時,例如:**System > Administration** ,可以見到頭文字大寫,這麼做除了模擬選單本身頭文字大寫外,還能在同是小寫的句子中吸引讀者的目光。因此請使用上下引號將選目起頭與結尾括住,除了給予強調外,亦可模擬選項之方框感、前後連貫感,達到類似效果。 如:**「系統 > 管理」**。 註:不建議採用 [] 方括號括住選項,如:[系統] > [管理] 這樣的表達方式,這是因為 [] 並非教育部規範之中文標點;然而方括號是微軟的翻譯慣例,故建議只在微軟平台專用軟體中使用這種表達方式 12. **引用軟體之名稱,可以用書名號《》括起**(軟體為著作的一種形式),例如:請使用《檔案》開啟。此例中,「檔案」是 GNOME nautilus 的在地名稱。 另外,若要引用程式中的某功能選項或按鈕,則可用「」括起,例如:點按《檔案》中的「偏好設定」,即代表點按名為檔案這個程式中的偏好設定按鈕 13. 英文中的 A, B, or C 和 A, B, and C 此類語句, 請根據中文文法翻譯為「**A、B、C 等**」 14. 遇到 `%q` 標記的時候,此標記會以可重複使用的方式輸出文字,故不需另加引號 ### 二、空格排版 為了符合英文字詞與鄰接字之間加空格之排版慣例,請在中文與英文、中文與阿拉伯數字加入一個半形空格。例如: ```po msgid "Installing driver for %1" msgstr "正在安裝 %1 的驅動程式" msgid "" "Parameter start_num specifies the character at which to start the search. " "The first character is character number 1. If start_num is omitted, it is " "assumed to be 1." msgstr "" "參數 start_num 指定開始搜尋的字元位置。第一個字元序號為 1。如果省略" "start_num,預設它為 1。" ``` 對於命令列介面 (CLI) 程式,一樣英數文字與鄰接之中文字間請補入空格: ```po msgid "Set LC_ALL='C' to work around the problem." msgstr "請設定 LC_ALL='C' 以避免出現問題。" ``` 對於小括號和半形引號,在與中文或英數文字鄰接處加入空格: ```po msgid "Original idea and author (KDE1)" msgstr "原始創意和作者 (KDE1)" msgid "" "The APM Management subsystem seems to be disabled.\n" "Try executing \"apm -e 1\" (FreeBSD) and see if \n" "that helps.\n" msgstr "" "APM 管理子系統似乎被停用了。\n" "試試執行 \"apm -e 1\" (FreeBSD) 並看看\n" "是否有用。\n" ``` 遇到斜體排版標記時,考量到中文字斜體後之傾斜部分會與後方鄰接字重疊,故斜體字詞後方若有連接「文字」請加入空格以利閱讀;而斜體內容之前如果還有文字,則請在前方也補入空格,來平衡後方加空格的排版視覺效果。 如果前後方連接的是「標點符號」,則不必加入空格。 例如: ```html 我想 <em>強調</em> 這件事;<em>然而</em>,沒有機會說出口。 ``` 至於包含 XML/HTML 語法標籤的條目,如要在標籤中的內容兩側添加空格,請把空格置於標籤外側,否則空格可能顯示不出來。 ``` 這是 &lt;b&gt;HTML&lt;/b&gt; 的語法手冊 ``` ### 三、選單項目快捷鍵字元 捷徑字元一律使用大寫字母,用小括號括起來放到選單文字的後面(如果有標點符號則放在標點符號的前面),並且小括號前後不加空格。在KDE 中,選單捷徑字元的前綴是 "&"; 在GNOME 中,選單捷徑字元的前綴是 `_`。 但是如果翻譯保留了原文的英文單詞或阿拉伯數字,且該單詞或數字正好是快速鍵所在的單詞或數字時,應保留原文的快速鍵方式(如下面的第二、四個例子),來降低雜亂感。這裡舉幾個例子: **KDE 選目:** <pre> msgid "C&lear" msgstr "清除(&L)" msgid "&Glimmer Editor" <del>msgstr "Glimmer 編輯器(&G)"</del> msgstr "&Glimmer 編輯器" </pre> **GNOME 選目:** <pre> msgid "_Setup..." msgstr "設定(_S)..." msgid "Get _CDDB Now" <del>msgstr "立刻取得 CDDB(_C)"</del> msgstr "立刻取得 _CDDB" </pre> 注意:若是小括號重複出現,應依然遵守上述括號使用方式、接著直接補入捷徑字元與包住的半形括號為後綴,遵循這兩項原則即可。 ```po msgid "_Network (IP, Wi-Fi)" msgstr "網路 (IP, Wi-Fi)(_N)" msgid "N_etwork (wired)" msgstr "網路(有線)(_E)" ``` 注意:下列情況的翻譯較特別且少見,屬於特例。由於「複製」和「剪下」均為「編輯」選單的條目,只有這樣翻譯才能保證顯示正確! ```po msgid "/_Edit" msgstr "/編輯(_E)" msgid "/Edit/C_opy" msgstr "/編輯(E)/複製(_O)" msgid "/Edit/C_ut" msgstr "/編輯(E)/剪下(_U)" ``` ### 四、譯文中的變數位置 有時候原來的變數順序不符合中文的語法,一方面,翻譯可以通過調整副詞、語序等手法來符合中文習慣。 另外一方面,在必要的情況下,需要調動變數的位置。但這樣的調序處理只能用在由支援此種交換法的語言所撰寫的軟體上。 例如在 KDE 中的 qt-format: ```po msgid "%1 articles match rule %2" msgstr "符合規則 %2 的文章有 %1 個" ``` 如果是 GNOME 中的 "c-format" 則應該這樣寫: ```po msgid "%d articles match rule %d" msgstr "符合規則 %2$d 的文章有 %1$d 個" ``` 即用`1$`、`2$`、`3$` 等符號標明變數在原文裡出現的位置。同時,任何一個變數的順序進行了調整,則在這一句譯文中所有變數都必須註明原文位置,否則無法通過格式檢查。 交換變數位置在翻譯時相當常用,請務必學會這個作法。 另外,像是「%1 of %2, %3 remaining」這類條目,是使用介面譯者很容易遇到的條目,用於描述進度,如已完成幾分之幾,剩餘幾個檔案,或推估剩餘時間多久。以下簡介幾種譯法。 「%1 of %2」基於英文 of 的用法,代表總共有 %2,已完成之中的 %1。 最簡單的譯法,就是利用數學概念的幾分之幾,將 of 改成 / 作數學式表達,即「%1 / %2」。 「%3 remaining」有兩種可能,一種是剩餘幾個檔案,一種是推估完成還要多久時間。 若是剩餘幾個檔案的情境,則為「剩餘 %3 個」;若是推估還要多久時間完成,則為「剩下 %3」,%3 會自動帶入時間,例如某分鐘等。 總合起來,就是「%1 / %2,剩餘 %3 個」或「%1 / %2,剩下 %3」。 如果想要用更多文字來表達「%1 of %2」的概念,則可以用「第 %1 個,共 %2 個」這種表達法,並依情境對應改成「第 %1 項,共 %2 項」或「第 %1 頁,共 %2 頁」⋯⋯等,諸如此類。 這種譯法需要譯者十分明白該詞條所在的情境,有時如果情境難明,就得去研究程式碼了。如果想要簡單處理這個問題,個人還是推薦數學式表達法「%1 / %2」。 目前比較進步的開發者,在變數命名上會下更多工夫,經 i18n 工具抽出作 po 檔格式處理後,譯者可以看到 %1 %2 %3 這種無意義變數代號以外,更有意義的佔位符表示法,例如「%(count)d of %(total)d, %(time)s remaining」,就可以推估知道是在講進度,一個是目前個數,一個是總數,一個是時間的文字串,更方便譯者調整順序。 ### 五、注意開發者註解 文件中有時會有給翻譯者的註解,以 `#.` 開頭,多數情況下還會有 "TRANSLATORS" 字樣提示。通常是對所翻譯內容的解釋和提示,請在翻譯過程中留意。例如: ```po #. TRANSLATORS: ls output needs to be aligned for ease of reading, #. so be wary of using variable width fields from the locale. #. Note %b is handled specially by ls and aligned correctly. #. Note also that specifying a width as in %5b is erroneous as strftime #. will count bytes rather than characters in multibyte locales. #: src/ls.c:708 msgid "%b %e %Y" msgstr "%Y年%b%e日" ``` ### 六、原文程式語言格式與 msgctxt 翻譯過程中常會遇到 "c-format" 一類的標記,-format 標記代表該段字元串需要按照指定的程式語言格式輸出,最常見的就是按照 C 語言格式輸出。其他比較常見的還有 python-format、scheme-format、perl-format、php-format、qt-format 和 kde-format 等。 msgctxt 標記(可理解為 message context)是給出字元串所處的不同情境,通常情況下同一個 msgid 只能在一個 PO 檔中出現一次,但是在有不同的 msgctxt 標記存在時,一個文件中可以出現多個相同的 msgid,因為它們各自的上下文不同,所以可能有不同的譯文。 ### 七、注意換列位置 如果原文條目 msgid 前方有 "#, c-format" 標記,或者「原文中有強迫換列標記 \n」(n 代表 newline)的情況,那就要手工調整譯文的換列處,以便能最終正確地顯示在程式界面上。 原則是譯文長度不大於原文長度,否則可能譯文超出原有顯示區域,或者譯文後面部分被截去,很難讀。對於有 HTML 標記的長譯文,還需要在瀏覽器中預覽顯示效果(如果您了解 HTML 基本語法的話),請酌情調整列寬。 例如: ```po #, c-format msgid "" "Error opening file '%s':\n" "%s" msgstr "" "開啟檔案「%s」時發生錯誤:\n" "%s" msgid "" "Parse a theme dir and generate a \n" "gkrellmrc_ksim file that KSim will understand \n" "better and exit." msgstr "" "解析主題目錄產生一個 KSim 可以理解\n" "的 gkrellmrc_ksim 檔案,然後退出。" ``` 多數 CLI 命令列程式都需要手工設定換列,這個時候希望翻譯者能夠對翻譯文件進行測試以確定每列到底應當放多少字元,尤其是翻譯命令參數的時候,如果不對長句進行強制換列處理,或者一味依照文字編輯器所顯示的視覺上與英文原文長度相同,則很容易造成在程式實際執行中的格式非常難看。 如果可能,請多測試最終實際的成果,再回頭去調整翻譯的 \n 換列處。 > 註: > 請注意「行」與「列」用詞的差別:直書為行,橫書為列,也就是「直行橫列」。請盡可能不要將兩者混淆使用。一般在文字編輯器或程式編輯器中,橫向的 line 和直向的 column,應採用「列」與「欄」。 > > 而在文書處理軟體中,則會採用 line 一詞來表示文字流,但不區分直書 line、橫書 line 的方向,所以 line 都直接沿用直書的「行」稱呼。然而,該程式在表示字元位置時,也會用 line 表示橫向,用 column 表示直向,此時才會在程式內統一用詞為「行」跟「欄」。 另外,在過去還沒有 PO 檔編輯器或網頁平台輔助翻譯時,譯者會直接以文字編輯器或程式編輯器,來修改 PO 檔。此時對於很長的譯文,就涉及到要不要換列以便閱讀的問題。多數情況下沒有限制,因為不影響最終的顯示效果,只要閱讀起來方便就行。 下面幾種直接編輯下的 PO 譯文格式都是正確的: PO 檔內容格式 ```po= msgid "" "Preview failed: neither the internal KDE PostScript viewer (KGhostView) nor " "any other external PostScript viewer could be found." msgstr "" "預覽失敗:找不到 KDE 內建的 PostScript 檢視器 (KGhostView) 或其他外部" "的 PostScript 檢視器。" --- msgid "" "Preview failed: neither the internal KDE PostScript viewer (KGhostView) nor " "any other external PostScript viewer could be found." msgstr "預覽失敗:找不到 KDE 內建的 PostScript 檢視器 (KGhostView) 或其他外部" "的 PostScript 檢視器。" --- msgid "" "Preview failed: neither the internal KDE PostScript viewer (KGhostView) nor " "any other external PostScript viewer could be found." msgstr "" "預覽失敗:找不到 KDE 內建的 PostScript 檢" "視器 (KGhostView) 或其它外部" "的 PostScript 檢視器。" ``` ### 八、「translator-credits」條目 "translator-credits" 是放置程式執行過程中查看鳴謝訊息時顯示的翻譯者條目,根據不同專案的小組可能有不同的填寫要求,最常見的填寫辦法是將名字、電子郵件地址、翻譯年份列表如下: ```po msgid "translator-credits" msgstr "" "Telsa Gwynne <hobbit@aloss.ukuug.org.uk>, 2011.\n" "Dafydd Harries <daf@muse.19inch.net>, 2012." ``` 注意在多個人名時最好每個人佔用一列,除最後一列外,每一列的結尾都要使用 \n 來換列。 ### 九、特殊字元 **(1) 標準 gettext 格式 PO 檔中的轉義字元和取消轉義** 轉義字元又稱脫逸序列 (escape sequence)。 標準 gettext 格式中的轉義字元同 C 語言中的基本相同,常用的有以下幾個: - `\n` 換列 - `\\` 反斜線 (\\) - `\t` 水平製表符 - `\v` 垂直製表符 您不需要將同樣數量的格式標記放在翻譯中,但是如果它們之一有在原文開始或者結束位置的時候,您必須在翻譯中使之包含在對應的開始或者結束之處。 如果要顯示非轉義字元,則需要使用 \ 來表明取消轉義,如 "(半形雙引號)在 PO 檔中表示字元串的開始或者結束,如果要在內容中使用該符號,則需輸入 `\"`,還可以參考以下例子: ``` \"\\t\" ``` 在執行時顯示的結果是 "\t" **(2) XML 中的角括號和「&」符號** 有一些模組中 XML 被頻繁地使用,GConf 是最明顯的。XML 將 `<`、`>` 與 `&` 視為保留字元,您不能將其直接添加到翻譯中。必須將其實體以下面的形式表示: - `&lt` 表示 < (lt 為 less than 之意) - `&gt` 表示 > (gt 為 greater than 之意) - `&amp` 表示 & (amp 為 ampersand 之意) **(3) TRUE 和 FALSE** "TRUE" 和 "FALSE" 多出現於 gtk+ 和 Gconf,以及很多 Glade 所產生的檔案中(這些檔案以 .glade 為副檔名),不要翻譯它們。如果程式找不到它們,將會出現問題。 ### 十、日期與時間表示法 鑑於關於日期與時間的譯法十分複雜,現在將國家標準中有關規定簡要介紹一下,並給出推薦譯法。 中華民國國家標準的 CNS 7648《[資料元及交換格式·資訊交換·日期及時間的表示法](http://www.cnsonline.com.tw/search/search_list_free.jsp?type=general&general_no=7648)》 (範例請見下表) 類似於 [ISO 8601](http://zh.wikipedia.org/zh-tw/ISO_8601) 國際標準。 可用公元年,也可冠以大寫 R.O.C. 字母表示民國紀元。例如,2004年(中華民國九十三年)5月3日可寫作 2004-05-03 或 R.O.C.93-05-03。 以下是最需要注意的幾個要點: 1. 從國家標準的範例看來,以「作資料交換」為目的時,日期格式中的阿拉伯數字與中文字間不應加入空格,應使用「2003年」這樣的格式。若是單純顯示資訊時的一般翻譯,仍可依照情況適當補入中英字之間的空白作排版。 2. 表示日期時,必須按照年月日的順序;年份一般用四位數字,而月、日必須使用帶前導零的兩位數字;必須使用 "-" 作為分隔符,或完全不使用分隔符。即 "2004-01-03" 或 "20040103" 來表示2004年1月3日。 3. 表示時間時,時、分、秒都必須使用兩位數字,中間用半形冒號 ":" 分隔,或完全不使用分隔符。小時計法採用 24 小時制,不區分上下午。 4. 日期和時間寫在一起的時候,應先寫日期再寫時間。在日期和時間都不使用分隔符的情況下,在中間添加字母 "T" 進行分隔,即 "19850412T101530"。 時間的表示方法同 date 命令的表示方法,現將常見的幾個對應其含義列表如下: | 代碼 | 說明 | | -------- | -------------------------------------------------------------------------------- | | `%%` | 一個 % 字元 | | `%a` | 星期幾簡寫(如「一」) | | `%A` | 星期幾(如「週一」) | | `%b` | 月份名稱縮寫(如「8月」) | | `%B` | 月份全名(如「八月」) | | `%d` | 日期數字 (01-31) | | `%-d` | 日期數字,不加入 0 排版 (1-31) | | `%D` | 日期,格式等於%m/%d/%y(例如:08/25/09) | | `%e` | 日期數字,且加入空格排版(1-31,非二位數時前方補上空格,例 %b%e日 效果為「8月 5日」) | | `%-e` | 日期數字,不加入空格排版(1-31,非二位數時前方不補空格,例 %b%-e日 效果為「8月5日」) | | `%F` | 日期,格式等於%Y-%m-%d(例如:2009-08-25) | | `%g` | ISO-8601 格式年份的最後兩位(例如:09) | | `%G` | ISO-8601 格式年份(例如:2009) | | `%h` | 同 `%b` | | `%H` | 小時 (00-23) | | `%I` | 小時 (00-12) | | `%k` | 小時 (0-23) | | `%l` | 小時 (1-12) | | `%m` | 月份 (01-12) | | `%-m` | 月份,不加入 0 排版 (1-12) | | `%M` | 分鐘 (00-59) | | `%n` | 換列 | | `%p` | 顯示「上午」或者「下午」兩個字 | | `%R` | 24 小時制小時(等同 %H:%M) | | `%S` | 秒 (00-60) | | `%t` | 製表符 (Tab) | | `%T` | 時間,等於 %H:%M:%S | | `%x` | 日期(例如:12/31/99) | | `%X` | 時間(例如:23:13:48) | | `%y` | 年份的最後兩位(例如:09) | | `%Y` | 年份(例如:2009) | **常見格式對應** | 原文 msgid | 譯文 msgstr | | ---------------- | -------------- | | `%a` | `%A` | | `%A, %B %e` | `%b%e日%A` 或 `%-m月%-d日%A` | | `%a %b %e` | `%b%e日(%a)`或 `%-m月%-d日(%a)`| | `%A, %B %d` | `%b%d日%A` 或 `%-m月%d日%A` | | `%-d %B` | `%b%-d日` 或 `%m月%-d日` | | `%A, %B %e, %Y` |`%Y年%b%e日%A`或`%Y年%-m月%-d日%A`| | `%a, %d %B %Y` |`%Y年%b%d日(%a)`或`%Y年%-m月%d日(%a)`| | `%A, %B %d, %Y` |`%Y年%b%d日%A`或`%Y年%-m月%d日%A`| | `%A, %B %-d, %Y` |`%Y年%b%-d日%A`或`%Y年%-m月%-d日%A`| | `%d %B %Y` |`%Y年%b%d日` 或`%Y年%-m月%d日`| | `%B %-d %Y` |`%Y年%b%-d日` 或 `%Y年%-m月%-d日`| **常見時間格式對應** | 原文 msgid | 譯文 msgstr | | ------------- | ------------ | | `%l:%M:%S %p` | `%p%l:%M:%S` | | `%R:%S` | `%R:%S` | 其他參考資料: [(GTK) g_date_time_format](https://docs.gtk.org/glib/method.DateTime.format.html) **常見日期加時間格式對應** 格式附底線 | 原文 msgid | 譯文 msgstr | | ----------------- | ----------------- | | `%a %b %-e_%R:%S` | `%b%-e日%A_%R:%S`或 `%-m月%-d日%A_%R:%S` | | `%b %-e_%R:%S` | `%b%-e日_%R:%s` 或 `%-m月%-d日_%R:%s` | | `%a %b %-e_%R` | `%b%-e日%A_%R` 或 `%-m月%-d日%A_%R` | | `%b %-e_%R` | `%b%-e日_%R` 或 `%-m月%-d日_%R` | |`%a %b %-e_%l:%M:%S %p`|`%b%-e日%A_%p%l:%M:%S` 或 `%-m月%-d日%A_%p%l:%M:%S` | |`%a %b %-e_%l:%M %p`|`%b%-e日%A_%p%l:%M` 或 `%-m月%-d日%A_%p%l:%M`| 格式不附底線 | 原文 msgid | 譯文 msgstr | | ---------------- | --------------- | | `%a %l:%M:%S %p` | `%A %p%l:%M:%S` | | `%a %l:%M %p` | `%A %p%l:%M` | ### 十一、語言地區表示法 Traditional Chinese 一詞,對台灣本地使用者而言,請譯為「正體中文」;至於香港,可譯為「繁體中文」。 對於語言列表的翻譯,在表中多以「語言名稱(使用的文字系統或地區)」來表達。例如列有: * Literary Chinese * Chinese (Simplified Han script) * Chinese (Simplified Han script, Singapore) * Chinese (Traditional Han script) * Chinese (Traditional Han script, Hong Kong) * Minnan (Traditional Han script) * Minnan (Pe̍h-ōe-jī) * Minnan (Tâi-lô) 等語言及文字系統的清單,此時的 Chinese 指的是正式的語言名稱,請稱呼為「漢語」。 至於台灣本地普遍通行的「國語」,英文為 Mandarin Chinese 或 Chinese, Mandarin。該原文指的是「漢語官話」,在中國又稱為「普通話」,在海外則稱為「華語」(如新加坡、馬來西亞⋯⋯等)。 #### 漢語與華語 漢語是較為中性的說法,指出自中國北方的漢民族語言。漢語也隨著外族進入中原,以及族群移動等因素持續融合影響,不斷發生變化。其中魏晉南北朝、隋、唐時期,在語言學中稱為中古漢語,並逐步演變至今日的現代漢語。 在東漢末年晉室南渡前,南方皆屬百越、蠻夷之地,如「閩」之用字,亦可知曉其地原民族與北方漢族大不同,更別說語言了。即便到了清時期,仍可見到「崔操閩音,啁啾不可辨,翁笑曰『此真南蠻鴃舌之聲也。』」這樣的小說記載。 中原南方長久以來漢化之深,語言已高度受外來的漢語影響(類同日語、韓語受中古漢語之影響,且更加深遠)。以閩南語為例,即便已有這麼多現成漢字可用,也很難以漢字作全白話文書寫表達,特別是該語言中的非漢語語源部分。 故無論從歷史回顧,以及從今日語言學的溯源研究來看,如臺語、閩南語、粵語⋯⋯等,實際上皆非漢語之下的方言,而是歸在同屬漢藏語系下的不同語言,不應以漢語族來概括所有中國統治地區的語言(即國族概念推及語族概念;而若要以地域特性統括語族,則應稱為漢地語族)。 再以臺語為例,更是融合了漢文化移民的閩南語、百越的南亞語、臺灣原住民族的南島語、荷蘭語、日語⋯⋯等的獨特語言。在國民政府來臺後,官方實施國語政策,以閩南語方言稱呼臺語並且打壓禁止。1993年後,教育部才以「鄉土語言」政策,開始鼓勵學習、運用母語。 至於華語一詞,演變自春秋時代的華、夏,如《尚書》寫到周武王伐紂時說:「華夏蠻貊,罔不率俾」,語意為華、夏各族,和蠻、貊的人民,沒有不遵從的。「華」逐漸成為周所統治黃河流域中下游一帶的稱呼,亦是後來漢族的代詞。 在隋唐期間,「華語」、「漢語」(更常見)等詞逐漸形成,來與外族的胡語、夷語區分。與「漢」相比,「華」字更具有傳承自華夏正統的意味,延續儒家華夷之辨思想。 而在今日,新加坡政府將當地福建、廣東、海南、客家⋯⋯等漢文化移民後代,也通稱為華人,並將現代標準漢語對應稱為華語,以方便與其原鄉作區分。後來此詞語也輸入至臺灣,並在流行樂、各大學語言文化教育推廣中心等領域中廣為使用。 #### 漢字體系 文字系統 Han script,一般稱為「漢字」。在漢字逐漸成熟,並開始擴大流傳,但還沒有官方規範前的時代,一個字可能有很多寫法;而為了方便流通與做政績,官方就找有學識的人來指定標準寫法,如秦朝的李斯,以小篆為標準統一了各國文字,是最早的「正體」字。 漢字的「官方標準寫法」,後來稱為「正體」字,而在唐朝的某些年代則採「定體」一詞,並將其他非標準漢字則歸類為「異體」字。在中華人民共和國成立後,推行了刻意對大多數漢字以形聲方式作人為簡化的造字政策,這批漢字特稱為簡化字。 Traditional Han script 在各地區有不同的漢字稱呼,例如在台灣,延續其古典稱呼,全名使用「正體漢字」(簡稱正體字),而香港與其他地方則多用「繁體漢字」(俗稱繁體字)等。 對於 Simplified Han script,全名稱為「簡化漢字」(俗稱簡體字)。 註:在香港一般也將 Traditional chinese 稱為「繁體漢字」,然而有許多推廣康熙標準字典體寫法的香港社群朋友,堅持應該稱為「傳承漢字」來與台灣標準寫法區分,故也可依其地方字形社群偏好來稱呼。 綜合以上,對於前述 Chinese「漢語」和 Han script「漢字」列表而言,推薦對應為: * 漢語文言文 * 漢語(簡化漢字) * 漢語(簡化漢字,新加坡) * 漢語(正體漢字) * 漢語(正體漢字,香港) 若是簡單表述法,如 Chinese (traditional) 、Chinese (simplified),則可譯為「漢語(正體字)」、「漢語(簡體字)」。 至於 Minnan「閩南語」,目前 ISO 語言中的文書系統有「傳統漢字」表示、「白話字」表示、「臺語羅馬字拼音」(簡稱臺羅)表示等方案,推薦對應為: * 閩南語(傳統漢字) * 閩南語(白話字) * 閩南語(臺羅拼音) 接下來探討其他語言與文字方案的譯法。 #### 其他語言 今日較主流的大語言,都有屬於自己對應的文字體系,不過也有些語言因為統治政權的更移,而改變了採用的文字體系,所以心中要有個概念:一個語言,可能有多種文書寫法。 例如越南語,在法國殖民前,文字體系採用漢字改來的喃字,後來才有拉丁字母演變而來的越南文字;還有蒙古語,以前用蒙古文,但後來受到俄羅斯的影響深,改用西里爾字。 又例如塞爾維亞語,同時有拉丁字體系和西里爾字體系兩種。請注意到拉丁字和西里爾字,是最常拿來表述其他語言的文字,所以要記得這裡講的不是拉丁文和西里爾文,而是單指「字」的書寫系統。 基本翻譯方式如下:先直接翻譯成某某語來表達語言,若這個語言有文字體系上的變異,後方再補上某某字來表達。 範例: * Japanese => 日本語 因為其目前的語言文字體系可直接對應到日文系統,所以就直接說「日本語」即可結案,也可簡稱「日語」。若需要表達出文字體系時,則為「日文」。 * Vietnamese => 越南語 目前越南的官方文字寫法就是越南文(以拉丁字母表示),無須特別表明文字。 * Serbian Latin => 塞爾維亞語拉丁字 Serbian Cyrillic => 塞爾維亞語西里爾字 同一個語言目前有兩種文字體系,所以要表達出文書表記寫法。 * Uzbek (Cyrillic) => 烏茲別克語(西里爾字) Uzbek (Latin) => 烏茲別克語(拉丁字) 與上述塞爾維亞語同理。 * Norwegian Bokmål => 挪威語書面文,或挪威語巴克摩文;前者為意譯(推薦採用),後者為音譯。 Norwegian Nynorsk => 挪威語新挪威文,或挪威語耐諾斯克文;前者為意譯(推薦採用),後者為音譯。 書面的挪威文形成於丹麥統治時期,受丹麥語的影響很大,可理解為書面記錄專用的「文言文」;而新的挪威文完全基於挪威民間口語,和丹麥語差別較大,可理解為口語上的「白話文」。 ### 十二、CLI 程式對齊 純粹的 CLI 命令列程式目前已少見。在 CLI 命令列程式的參數上,常會遇到對齊的問題。 英文原文一般會使用空格進行對齊,但是空格並不能使得最終執行的程式在使用中文的情況下將文字正確對齊,所以應當使用 Tab 製表符作排版。 Tab 的對齊也不總是能在文字編輯器上所見即所得,也就是說在文字編輯器上已經對齊的列,可能在實際執行時前後相差一個 Tab 的距離。如果可能,請多測試最終實際的成果,再回頭去調整翻譯的排版與對齊,以便閱讀。 ### 十三、模糊譯文 如果看到 "#, fuzzy" 標記,則表示本段譯文是由工具軟體(通常是 msgmerge 命令) 猜測翻譯得到的。有時比較準確,有時卻謬之千里。另一種情況是譯者或校對人員主動加上去的,因為他們對該條譯文沒有把握。因此請對其譯文進行修訂,然後去除模糊標記, 否則本段譯文將不能顯示在程式界面上。原則上,所有既往給出的譯文,在翻譯的時候都應該校對一遍。例如您拿到的文件中有如下列時: ```po #: groupdlg.cpp:209 groupdlg.cpp:216 groupdlg.cpp:229 #, fuzzy msgid "Get Tagged Articles" msgstr "取得文章" ``` 當您修正可能存在的錯誤後刪除整個 "#, fuzzy " 一列就可以了: ```po #: groupdlg.cpp:209 groupdlg.cpp:216 groupdlg.cpp:229 msgid "Get Tagged Articles" msgstr "取得已標籤文章" ``` 可能還會遇到下面的情形: ```po #: groupdlg.cpp:623 #, fuzzy, c-format msgid "Connecting to server %s" msgstr "正在連線至伺服器" ``` 在這裡,修正翻譯後在清除模糊標記時,"c-format" 標籤必須保留: ```po #: groupdlg.cpp:623 #, c-format msgid "Connecting to server %s" msgstr "正在連線至伺服器 %s" ``` ### 十四、已淘汰譯文 老版本的程式中總有一些訊息會在新版本中淘汰掉,這些譯文由 msgmerge 程式自動設定為以 #~ 開頭,並被置於整個 po 檔的後方,直接刪除它們不會影響當前版本的翻譯內容,但是因為這些字元串還可能在以後的版本中重新出現,屆時 msgmerge 還可以使用這些譯文來提供翻譯建議,所以如果它們沒有影響到您的工作建議不要刪除它們。例如: ```po #~ msgid "Error: no name" #~ msgstr "錯誤:沒有姓名" #~ msgid "Configure" #~ msgstr "組態" ``` ## PO 檔標頭格式規範 目前僅有少數情況需要手動設定 po 檔檔頭,例如尚未有對應翻譯語言的 po 檔,得先從 pot 檔生成;或是專案本身嚴格要求 po 檔檔頭以規範方式撰寫,例如 gnu 的 translation project 和 gnu webite translation 皆如此要求。其餘情況下,多數翻譯平臺不會仔細檢查 po 檔頭,甚至會自動產生 po 檔頭故無需設定,如 Weblate、Pootle、Launchpad、Transifex 皆是。 ### 檔案編碼格式 目前的翻譯檔案一般使用 UTF-8 編碼。所以請使用支援 UTF-8 編碼的編輯工具或者文字編輯器進行翻譯,同時需要注意檔頭的 "charset" 項設定正確。如果在編碼格式上遇到問題,請向翻譯團隊相關郵遞論壇發送郵件以尋求幫助。 可以使用 iconv 或者 msgconv 命令進行轉換,以下例子為轉換 big5 --> utf-8: ```shell iconv -f 來源文件編碼 -t 目標文件編碼 來源檔案 > 輸出檔案 iconv -f big5 -t utf-8 inputfile > outputfile ``` 或者: ```shell msgconv -t 目標文件編碼 來源檔案 -o 目標檔案 msgconv -t utf-8 inputfile -o outputfile ``` ### 檔案標頭 下面是一個使用 msginit 工具由 POT 檔產生的 PO 檔初始檔頭,使用了 msginit 的 --no-translator 選項: ```po # Chinese translations for PACKAGE package # traditional Chinese translation for PACKAGE. # Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2009. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=empathy&component=general\n" "POT-Creation-Date: 2009-08-20 17:27+0200\n" "PO-Revision-Date: 2009-08-20 17:27+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" ``` 編輯後的檔頭應為這樣,<font color="green">綠色</font>為實際文件中需要修改的,<font color="red">紅色</font>為註解: <pre> # Chinese translations for <font color="green">empathy</font> package <font color="red"><--將 PACKAGE 改為要翻譯的軟體名,本例中為 empathy</font> # traditional Chinese translation for <font color="green">empathy</font>. <font color="red"><--將 PACKAGE 改為 empathy</font> # Copyright (C) <font color="green">2003, 2004, 2005, 2009, 2010 Free Software Foundation, Inc.</font> # <font color="red">^^^這裡表示要翻譯的軟體其著作權擁有者,以及著作年份,年份則隨著下方翻譯者貢獻的年份一併更新</font> # This file is distributed under the same license as the <font color="green">empathy</font> package. # <font color="red">^^^此處 PACKAGE 替換方法同上</font> <font color="green"># Abel Cheung <abel@oaka.org>, 2003, 2004. # Chao-Hsing Liao <j_h_liau@yahoo.com.tw>, 2005. # Tryneeds translation team, 2009. # Cheng-Chia Tseng <pswo10680@gmail.com>, 2010.</font> # <font color="red">^^^此處填入翻譯者的相關訊息,格式參見上面,有的 PO 編輯器會自動更新此項,有多個年份的以逗號分隔列出,依照時間前後順序排列翻譯者</font> # <del style="color: green">#, fuzzy</del> <font color="red"><--使用 msginit 產生的 PO 檔中沒有這列,如果直接用 POT 檔進行翻譯請務必在繼續前刪除此列</font> msgid "" msgstr "" "Project-Id-Version: <font color="green">empathy master</font>\n" <font color="red"><--此處 PACKAGE 替換方法同上,VERSION 應為所對應的軟體版本</font> "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=empathy&component=general\n" <font color="red"><--此列一般不需修改,即使有的文件在產生後此項為空</font> "POT-Creation-Date: 2009-08-20 17:27+0200\n" <font color="red"><--此列一般不需修改,合併新的 POT 檔時會自動更新</font> "PO-Revision-Date: <font color="green">2010-08-24 22:25+0800</font>\n" <font color="red">^^^填入翻譯完成的時間,PO 編輯器一般能自動更新此項, +0800 代表加 8 時區</font> "Last-Translator: <font color="green">Cheng-Chia Tseng <pswo10680@gmail.com></font>\n" <font color="red"><-- 改成你的名字和電子郵件地址</font> "Language-Team: <font color="green">Chinese (traditional) <zh-l10n@lists.slat.org></font>\n" <font color="red">^^^以上這列改成你所參與的翻譯小組郵遞清單位址 ,若沒有小組就填寫可以聯繫到你的電子郵件地址</font> "MIME-Version: 1.0\n" <font color="red"><-- 不要進行更改</font> "Content-Type: text/plain; charset=UTF-8\n" <font color="red">^^^應確保上列的編碼和檔案編碼均為 UTF-8,若不是則需要將檔案編碼轉換為 UTF-8 後再將此處更改為 UTF-8</font> "Content-Transfer-Encoding: 8bit\n" <font color="red"><-- 不要進行更改</font> "Plural-Forms: <font color="green">nplurals=1; plural=0);</font>\n" <font color="red"><--正體中文若不考慮代名詞複數變化便可以這樣填,為預設形式,有的檔案可能無此列</font> </pre> 修改完檔頭以後接著就是實質性的翻譯了,PO 檔的格式是一句 msgid 跟著一句 msgstr,以 "#" 開頭的列是註解。您需要做的是把 msgid 中的英文翻譯成中文寫到 msgstr 中。例如: ```po #: app/floating_sel.c:198 msgid "" "Cannot create a new layer from the floating\n" "selection because it belongs to a\n" "layer mask or channel." msgstr "" "無法從浮動選擇區產生新的\n" "圖層,因為它屬於一個\n" "圖層遮罩或色版。" #: ../libgimp/gimpbrushselectbutton.c:170 msgid "Brush Selection" msgstr "筆刷選擇" ``` ### 複數形式 此處複數非指涉數學的 complex number。 由於某些語言的單複數變化極為複雜,為了應對這種狀況,符合國際化標準,gettext 透過讀取 PO 檔頭部如下一列中的訊息來正確顯示不同單複數的譯文: ``` "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" ``` nplurals 表示譯文單複數變化形式的總數量,它是一個正整數。plural 表示原文中表示「n 個」的概念時應用的複數形式,這裡是一個非負整數,可以是一個 C 語言表達式的值,該值必須小於 nplurals 且非負(陣列的索引)。 例如「他/她」與「他們/她們」;以及「這個」與「這些」。 考量到單複數之區分,可以設為: ``` Plural-Forms: nplurals=2; plural=(n>1); ``` 含義是單複數一共有兩種 (一與大於一),在所指對像數量超過一個的時候使用複數。 又如一些語言中只有在所指對像數量不是一的時候使用複數 (英語的預設設定): ``` Plural-Forms: nplurals=2; plural=(n!=1); ``` 含義是單複數一共有兩種 (單數與複數),僅在所指對象數量不是一的時候使用複數。 以上這兩種表示法其意義與結果都是相同的,因此都可以採用。不過設定成兩種複數形式的設定較少人採用,各大翻譯工具也都預設將中文視為單一種複數形式。 而如果不管中文裡的代名詞單複數變化(此為**預設情況與建議採用方式**),可以設定為: ``` Plural-Forms: nplurals=1; plural=0; ``` 含義是譯文的所有單複數形式只有一種,所有形式使用一種翻譯。若使用這種複數形式,當 PO 檔的訊息字串出現代名詞變化時便無法處理單數代名詞。然而目前各大翻譯平臺與工具都將中文設為一種複數形式,因此使用諸平台進行翻譯時,請略過 msgid 的單數形式,只**翻譯複數形式**。 另外,在中文語境下的英文詞彙,不需要變化成複數型。例如,義式食物 Pizza,當講到有好幾塊 Pizza 時,也只需要說 Pizza 即可,而不是好幾塊 Pizzas。 **範例一** 原文如下: ```po #. TRANSLATORS: title: show a list of fonts #: ../src/gpk-dbus-task.c:1645 #: ../src/gpk-dbus-task.c:2109 #: ../src/gpk-dbus-task.c:2498 msgid "Do you want to install this package now?" msgid_plural "Do you want to install these packages now?" msgstr[0] "" msgstr[1] "" ``` 若設定為兩種複數形式,上段內容的譯文應以下方格式寫出: ```po #. TRANSLATORS: title: show a list of fonts #: ../src/gpk-dbus-task.c:1645 #: ../src/gpk-dbus-task.c:2109 #: ../src/gpk-dbus-task.c:2498 msgid "Do you want to install this package now?" msgid_plural "Do you want to install these packages now?" msgstr[0] "是否要現在安裝這個軟體包?" msgstr[1] "是否要現在安裝這些軟體包?" ``` 其中的 `msgstr[0]` 請填入第一種複數形式,也就是「單數」的翻譯;而 `msgstr[1]` 則請填入第二種複數形式,也就是「複數」的翻譯。 若設定只有一種單複數形式,上段內容的譯文應以下面格式寫出: ```po #. TRANSLATORS: title: show a list of fonts #: ../src/gpk-dbus-task.c:1645 #: ../src/gpk-dbus-task.c:2109 #: ../src/gpk-dbus-task.c:2498 msgid "Do you want to install this package now?" msgid_plural "Do you want to install these packages now?" msgstr[0] "是否要現在安裝這些軟體包?" ``` 其中的 `msgstr[0]` 請填入唯一的單複數形式「複數」,而多餘的 msgstr 則必須要刪除。 **範例二** 原文如下: ```po #: src/msgcmp.c:338 src/po-lex.c:701 #, c-format msgid "found %d fatal error" msgid_plural "found %d fatal errors" msgstr[0] "" msgstr[1] "" ``` 若設定為兩種單複數形式,上段內容的譯文應以下面格式寫出: ```po #: src/msgcmp.c:338 src/po-lex.c:701 #, c-format msgid "found %d fatal error" msgid_plural "found %d fatal errors" msgstr[0] "找到 %d 個嚴重錯誤" msgstr[1] "找到 %d 個嚴重錯誤" ``` 其中的 `msgstr[0]` 請填入第一種複數形式,也就是「單數」的翻譯;而 `msgstr[1]` 則請填入第二種複數形式,也就是「複數」的翻譯。 若設定只有一種單複數形式,上段內容的譯文應以下面格式寫出: ```po #: src/msgcmp.c:338 src/po-lex.c:701 #, c-format msgid "found %d fatal error" msgid_plural "found %d fatal errors" msgstr[0] "找到 %d 個嚴重錯誤" ``` 多餘的 msgstr 必須刪除。 ## l10n/i18n 相關工具 ### gettext 工具集 gettext 工具集提供了一組使用 PO 檔進行翻譯時的實用工具,現在對其中比較常用的幾個做簡短介紹。 若希望了解關於此工具集的詳細訊息,請瀏覽 [GNU gettext utilities](http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/) **(1) msgfmt - 檢查格式並產生機讀的 MO 檔** 一般使用的格式為: ```shell msgfmt --statistics -cv filename.po ``` 這樣將會對翻譯格式進行檢查,如果有格式問題則會顯示錯誤原因並指明列號;如果檢查通過則顯示翻譯的進度情況並在執行目錄下產生一個名為 `message.mo` 的檔案,該檔案便是程式執行時所要讀取的二進位翻譯檔案。 在提交任何 PO 檔前都請使用 msgfmt 命令對格式進行檢查。 **(2) msgmerge - 合併檔案** 一般使用的格式為: ```shell msgmerge --no-wrap -o newfile.po fileA.po fileB.po ``` 這樣進行的結果是將檔案 A 和檔案 B 進行合併,若有不相同的地方以檔案 B 為準,最後輸出在 `newfile.po` 中。 可以使用其更新選項來合併原來的 PO 檔和最新的 POT 檔: ```shell msgmerge -U zh_TW.po example.pot ``` 這樣將會把原來的 `zh_TW.po` 另存為 `zh_TW.po~` 並更新 `zh_TW.po` 為新的內容,`zh_TW.po~` 作為備份檔案可以直接刪除。 **(3) msgconv - 轉換檔案編碼** 一般使用的格式如下,作用為把 zh_TW.po 從其他編碼轉換為 UTF-8 編碼: ```shell msgconv -t UTF-8 zh_TW.po ``` msgconv 會自動更新檔頭出的 charset 設定,但是在開始翻譯前不妨再進行一下檢查以免出現問題。 **(4) msginit -從 POT 檔建立 PO 檔** 一般的使用格式為: ```shell msginit -i example.pot -l zh_TW.UTF-8 ``` 這樣將會詢問翻譯者的電子郵件地址,然後產生一個名為 zh_TW.po,以 UTF-8 編碼的檔案。 如果執行程式的目錄下只有一個 POT 檔則 -i 選項可以省略;如果執行的 locale 為 zh_TW.UTF-8 則 -l 選項可以省略,也就是說這個命令最簡單的時候可以只輸入 msginit 如果您對 PO 檔的標頭處理還不是十分了解,則請使用此程式以避免可能出現的麻煩。 ### intltool 工具集 intltool 工具集實際上是一組命令稿 (script),用以進行一些日常的翻譯文件維護,其中部分命令除了支援 PO 檔外還支援 XML。它一共有五個命令,對於翻譯者來說比較常用的是 intltool-update 和 intltool-merge。這組工具多數需要在完整的源始碼樹中的 po/ 子目錄下執行。若要了解更多有關於 intltool 工具的訊息,請閱讀它的 man 手冊。 **(1) intltool-update - 更新 POT 檔並將 PO 檔與之合併** 通常使用它產生 POT 檔時使用以下命令: ```shell intltool-update -p ``` 這樣將會在目錄中產生一個 POT 檔。 要使用它更新原有的 PO 檔,可以這樣執行: ```shell intltool-update zh_TW ``` 這樣將會自動產生新的 POT 檔並更新 zh_TW.po,最後得到的文件是更新後的 zh_TW.po ,也可以使用 -o 選項來定義輸出到指定文件而非更新原來的 PO 檔。 使用它來查看源始碼中的 POTFILES 檔是否有正確維護,通常翻譯者不需要做這項工作: ```shell intltool-update -m ``` 如果輸出為空則代表一切正常,否則將有詳細提示。 **(2) intltool-merge - 合併翻譯檔案** 一般使用方法為: ```shell intltool-merge --utf8 po_directory input output ``` 其作用為將指定的 po_directory 目錄中的所有 PO 檔同 input 檔案合併,並將輸出寫入到 output 檔案,output 檔案包含了 input 檔案中的原始字串和其他 PO 檔中的已翻譯字串。在進行合併前會把所有檔案都自動轉換為 UTF-8 編碼。 當 input 為一個 XML 檔案時,輸出的 output 檔案也將是 XML 格式,PO 檔中翻譯的字串將作為 "xml:lang" 屬性插入到原 XML 中一併寫入 output 檔案。 ### xml2po xml2po 是 gnome-doc-utils 中的一個工具,主要用途是在 XML 和 PO 檔之間進行轉換和合併。 要從 XML 檔案產生 PO 檔案: ```shell xml2po -e -o book.pot book.xml ``` 反過來要把已翻譯的 zh_TW.po 合併回原來的 XML 檔中: ```shell /usr/bin/xml2po -e -p zh_TW.po -o book.zh_TW.xml book.xml ``` ## 附錄 - [詞彙對照表](https://hackmd.io/@l10n-tw/glossaries) ## 作者 - Aron Xu <happyaron.xu@gmail.com>, 2009. - Pellaeon Lin <nfsmwlin@gmail.com>, 2010. - Cheng-Chia Tseng <zerngjia@gmail.com>, 2010, 2015, 2017, 2018, 2024, 2025. - Mingye Wang , 2015. 本文依據《[創用 CC 姓名標示 4.0 國際](http://creativecommons.org/licenses/by-nc-sa/3.0/https://creativecommons.org/licenses/by/4.0/legalcode.zh-hant)》授權條款發行。 ### 後記 原文為《[自由软件中文化工作指南(L10N)](http://docs.google.com/View?docID=0ATMcdwxwhYuQZGM1eHJuNGtfMWZ6MjRwd2c0&revision=_latest&hgd=1)》,是 Aron Xu <happyaron.xu@gmail.com> - 2009-08-26 以 KDE 中國網站上刊載的 [I18N/L10N 工作流程](http://www.kdecn.org/l10n/method.php) 為藍本所修訂的工作指南,過程中参考了 [i18n-zh](http://groups.google.com/group/i18n-zh) 以及 [GNOME Live](http://live.gnome.org/TranslationProject/) 上的一些文章。若對於該指南内容有任何意見,請將它發送至 [i18n-zh@googlegroups.com](http://groups.google.com/group/i18n-zh)。 本文第一版為 Cheng-Chia Tseng 將 Pellaeon Lin 於 2010-02-21 對上述簡體文件譯為正體後,所發布的《自由軟體中文化工作指南(L10N)》為基礎再修改而成。 --- ## 更新紀錄 2024-11-06 @zerngjia 增補語言地區表示法的一般規範 2022-02-06 @toto6038 增加了[詞彙對照表](#附錄---詞彙對照簡表)、基本守則要求第 8 點 @pan93412-gh 把大部分的 code block 都加上語言標示 (code highlighting) 了 2022-02-03 由 @toto6038 將原 [Google 文件](https://docs.google.com/document/d/1Zs4CS_ZjN-imnImq4aEsiVYih8zkIkVZTSQim13_kYg/)手工轉換成 Markdown 版,由 @pan93412-gh 協助,並適度刪改一些。 - 用詞調整: - command 指令 -> 命令 - file 文件 -> 檔案(Document 才是文件) - project 項目 -> 專案 - 工具組 -> 工具集 - 內容補充: - 補充微軟對於按鈕文字的翻譯慣例 - 在 [工作流程 準備](#準備)一節,以微軟國際詞彙、國教院術語翻譯網替換原有 Google 連結 2018-08-21 增補關於日期和時間譯法的常見格式對應。

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully