跳轉至

給譯者

本頁是寫給編輯目錄的人的,不是寫給寫程式的人的。它刻意寫得很短,也是為了讓人直接 連過來、或抄進某個專案自己的譯者說明裡。

這裡沒有任何一句需要你讀得懂 Python。這裡的一切都只圍著一件事轉:訊息裡被大括號 包住的那些片段。

什麼是佔位符

目錄裡的一則訊息可能含有被大括號包住的名稱:

msgid "Hello {name}"
msgstr ""

{name} 就是一個佔位符。程式顯示這則訊息時,會把 {name} 換成它自己提供的某個 值——一個人名、一個檔名、一個數字。佔位符不是一個要翻譯的字,它是一個空位。

你的翻譯寫進 msgstr,而且必須把那個空位留著:

msgid "Hello {name}"
msgstr "こんにちは {name}"

哪些可以改,哪些不可以

可以

  • 移動佔位符,放到目標語言的文法要它去的任何地方,包括句首。
  • 重複佔位符,如果那個語言需要用到這個值兩次。
  • 改寫其他每一個字,包括標點、間距與句子順序。

不可以

  • 翻譯大括號裡的名稱。 {name} 就是 {name},即使在其餘部分完全不寫拉丁字母的 語言裡也一樣。
  • 拿掉大括號,或是不加大括號就把名稱寫出來。
  • 把 ASCII 大括號 { } 換成全形的 很多輸入法產出的就是全形形式; 它們看起來幾乎一模一樣,但不會動。
  • 加上格式設定,例如 {name!r}{amount:.2f}。一個值要怎麼顯示是在程式裡 決定的,不是在目錄裡。
  • 憑空生出一個 msgid 裡沒有的佔位符。

如果某則訊息需要一個原文並沒有提供的值,那就是一則開發者必須修改的訊息。請直接說出 來,而不要想辦法繞過去。

複數形式

一則帶計數的訊息會照你的語言有幾種複數形式,就給你幾個 msgstr 空位,而有幾個是由 你的語言決定的——日文一個、德文兩個、俄文三個、阿拉伯文六個。目錄給你幾個空位,就 把它們全部填滿。

有兩條規則常常讓人栽跟頭:

  • 這些空位不是「單數、複數、更多的複數」。 每一個索引的意思,就是你的語言的複數 規則所說的那個意思。拉脫維亞文的第三種形式只給零用;斯洛維尼亞文的第二種形式只給 剛好兩個用;威爾斯文把一般情況放在索引 0,把單數放在索引 1。
  • 兩個空位放同樣的文字是合理的。 在土耳其文、匈牙利文、波斯文與孟加拉文裡,名詞 跟在數詞後面仍維持單數,所以一則帶計數訊息的兩種形式就是同一個字串。那是正確的, 不是複製貼上的疏失。

上面那些佔位符規則,對每一種形式各自獨立生效。

fuzzy 條目

一筆標上 fuzzy 的條目是一台機器的猜測:開發者改動了原本的訊息,而工具把新的文字和 你舊的翻譯配成一對,好讓你有個起點。

#, fuzzy
msgid "Welcome back, {name}"
msgstr "こんにちは {name}"

一筆 fuzzy 條目不會被程式使用——程式顯示的是未翻譯的原文——直到有人修訂了文字並 移除 fuzzy 標記為止。大多數 PO 編輯器都有一顆專門做這件事的按鈕。

讀懂一則錯誤訊息

工具會在目錄被編譯時檢查佔位符,而那些訊息是寫給你看的,不是寫給程式設計師看的。當那 幾個字元明明就在你眼前時,只報告 {name} 不見了是條死路,所以只要一個佔位符看起來 在、實際上卻不在,訊息就會說明原因。對照原文 Hello {name},下面每一種都會被報在 translation does not match the source placeholders: 之下:

你的翻譯寫成 它給出的原因
こんにちは {name} {name} is missing (the braces around it are not the ASCII { and })
こんにちは {{name}} {name} is missing (it is written {{name}}, which is how a literal brace is escaped)
こんにちは name {name} is missing (the name appears, but not inside braces)
こんにちは {名前} {name} is missing; {名前} is not in the source message

看不見的字元會得到自己的一套處理。大括號裡的 no-break space 是輸入法生出來、而任何 編輯器都不會顯示的東西,所以訊息會用 code point 把它印出來,而不是叫出一個你永遠找 不到的字元名稱:

placeholder {<U+00A0>name} has a space inside the braces; write {name}

一個字母混用了不同書寫系統的名稱——也就是同形字的情況,Cyrillic 的 а 和 Latin 的 a 分不出來——會被顯示兩次,一次是讀得出來的、一次是轉義過的,而後者是唯一能把兩者 分辨開來的形式:

translation does not match the source placeholders: {name} is missing;
{nаme} (n\u0430me) is not in the source message

當一個完全用 Greek 或 Cyrillic 寫成的名稱和 ASCII 的原文名稱相衝時,也是同樣的區辨 方式,包括單一字母的 Latin a / Cyrillic а 那種情況。

如果你碰上其中一種,而該怎麼修並不明顯,最保險的做法就是把你自己打的那個佔位符刪掉, 再從 msgid 裡把那一個複製過來。

這些檢查做不到什麼

工具能驗證的是你的佔位符完好無缺。它沒辦法判斷這則翻譯準不準確、自不自然、合不合這個 上下文——那些完全落在你身上。

有兩件事比任何檢查都更有幫助:

  • 讀那則譯者註解。 訊息上方那一行以 #. 開頭的文字,就是開發者在告訴你它出現在 哪裡、它是什麼意思。
  • msgctxt 發問。 同一個字帶著不同的上下文出現兩次,就是因為這兩者必須翻得 不一樣——例如按鈕的「Open」和狀態的「Open」。