PO4A(1p)

名稱
po4a - 一次性更新 PO 檔案和翻譯文件

簡介
po4a [options] config_file

描述
po4a (PO 代表任何東西)使用經典的 gettext 工具簡化了文件翻譯的維護。po4a 的主要特點是將內容的翻譯與文件結構分離。請參閱 po4a(7) 頁瞭解本專案的詳細介紹。

Upon execution, po4a parses all documentation files specified in its configuration file. It updates the PO files (containing the translation) to reflect any change to the documentation, and produce a translated documentation by injecting the content's translation (found in the PO files) into the structure of the original master document.

At first, the PO files only contain the strings to translate from the original documentation. This file format allows the translators to manually provide a translation for each paragraph extracted by po4a. If the documentation is modified after translation, po4a marks the corresponding translations as "fuzzy" in the PO file to request a manual review by the translators. The translators can also provide so-called "addendum", that are extra content stating for example who did the translation and how to report bugs.

 master documents ---+---->-------->---------+
  (doc authoring)    |                       |
                     V   (po4a executions)   >-----+--> translated
                     |                       |     |     documents
 existing PO files -->--> updated PO files >-+     |
      ^                            |               |
      |                            V               |
      +----------<---------<-------+               ^
       (manual translation process)                |
                                                   |
 addendum -->--------------------------------------+

The workflow of po4a is asynchronous, as suited to open-source projects. The documentation writers author the master documents at their own pace. The translators review and update the translations in the PO files. The maintainers rerun po4a on need, to reflect any change to the original documentation to the PO files, and to produce updated documentation translations, by injecting the latest translation into the latest document structure.

By default, a given translated document is produced when at least 80% of its content is translated. The untranslated text is kept in the original language. The produced documentation thus mixes languages if the translation is not complete. You can change the 80% threshold with the --keep option described below. Note however that discarding translations as soon as they are not 100% may be discouraging for the translators whose work will almost never be shown to the users, while showing "translations" that are too incomplete may be troubling for the end users.

Storing the translated documentation files in the version control system is probably a bad idea, since they are automatically generated. The precious files are the PO files, that contain the hard work of your fellow translators. Also, some people find it easier to interact with the translators through an online platform such as weblate, but this is naturally fully optional.

  Quick start tutorial
Let's assume you maintain a program named foo which has a man page man/foo.1 written in English (the bridge language in most open-source projects, but po4a can be used from or to any language). Some times ago, someone provided a German translation named man/foo.de.1 and disappeared. This is a problem because you just got a bug report saying that your documentation contains a gravely misleading information that must be fixed in all languages, but you don't speak German so you can only modify the original, not the translation. Now, another contributor wants to contribute a translation to Japanese, a language that you don't master either.

It is time to convert your documentation to po4a to solve your documentation maintenance nightmares. You want to update the doc when needed, you want to ease the work of your fellow translators, and you want to ensure that your users never see any outdated and thus misleading documentation.

The conversion includes two steps: setup the po4a infrastructure, and convert the previous German translation to salvage the previous work. This latter part is done using po4a-gettextize, as follows. As detailed in the documentation of po4a-gettextize(1), this process rarely fully automatic, but once it's done, the de.po file containing the German translation can be integrated in your po4a workflow.

  po4a-gettextize --format man --master foo.1 --localized foo.de.1 --po de.po

Let's now configure po4a. With the appropriate file layout, your configuration file could be as simple as this:

 [po_directory] man/po4a/

 [type: man] man/foo.1 $lang:man/translated/foo.$lang.1

It specifies that all PO files (containing the work of the translators) are in the man/po4a/ directory, and that you have only one master file, man/foo.1. If you had several master files, you would have several lines similar to the second one. Each such line also specify where to write the corresponding translation files. Here, the German translation of man/foo.1 is in man/translated/foo.de.1.

The last thing we need to complete the configuration of po4a is a POT file containing the template material that should be used to start a new translation. Simply create an empty file with the .pot extension in the specified po_directory (e.g. man/po4a/foo.pot), and po4a will fill it with the expected content.

Here is a recap of the files in this setup:

  ├── man/
  │   ├── foo.1        <- The original man page, in English
  │   ├── po4a/
  │   │   ├── de.po    <- The German PO translation, from gettextization
  │   │   └── foo.pot  <- The POT template of future translations (empty at first)
  │   └── translated/  <- Directory where the translations will be created
  └── po4a.cfg         <- The configuration file

Once setup, executing po4a will parse your documentation, update the POT template file, use it to update the PO translation files, and use them to update the documentation translation files. All in one command:

        po4a --verbose po4a.cfg

This is it. po4a is now fully configured. Once you've fixed your error in man/foo.1, the offending paragraph in the German translation will be replaced by the fixed text in English. Mixing languages is not optimal, but it's the only way to remove errors in translations that you don't even understand, and ensure that the content presented to the users is never misleading. Updating the German translation is also much easier in the corresponding PO file, so the language mix-up may not last long. Finally, when a Japanese translator wants to contribute a new translation, she should rename the foo.pot into ja.po and complete the translation. Once you have this file, just drop it in man/po4a/po/. A translated page will appear as man/translated/foo.ja.1 (provided that enough content is translated) when you run po4a again.

選項

-k, --keep
    保留(即寫入)結果檔案的轉換百分比的最小閾值(預設值：80)。即，預設情況下，檔案必須至少翻譯 80% 才能寫入磁碟。

-h, --help
    顯示簡短的幫助訊息。

-M, --master-charset
    包含要翻譯的文件的檔案字符集。請注意，所有主文件必須使用相同的字符集。

-L, --localized-charset
    包含本地化文件的檔案字符集。請注意，所有翻譯的文件將使用相同的字符集。

-A, --addendum-charset
    附錄的字符集。請注意，所有附錄應使用相同的字符集。

-V, --version
    顯示指令碼的版本並退出。

-v, --verbose
    增加程式的冗長程度。

-q, --quiet
    減少程式的冗長。

-d, --debug
    輸出一些除錯資訊。

-o, --option
    要傳遞給格式外掛的額外選項。有關有效選項及其含義的更多資訊，請參閱每個外掛的文件。例如，您可以將 '-o tablecells' 傳遞給 AsciiDoc 解析器，而文字解析器將接受 '-o tabs=split'。

-f, --force
    始終生成 POT 和 PO 檔案，即使 po4a 認為沒有必要。

    預設行為(未指定 --force 時)如下：

        如果 POT 檔案已經存在，則如果主文件或配置檔案較新(除非提供了 --no-update)，則會重新生成該檔案。POT 檔案也寫入臨時文件中，po4a 驗證是否確實需要更改。

        此外，只有當翻譯的主文件、PO 檔案、其中一個附錄或配置檔案更新時，才會重新生成翻譯。要避免嘗試重新生成未透過閾值測試的翻譯(請參見 --KEEP)，可以建立擴充套件名為 .po4a-stamp 的檔案(請參見 --STAMP)。

    如果主文件包含檔案，則應使用 --force 標誌，因為不會考慮這些包含檔案的修改時間。

    PO 檔案總是基於帶有 msgmerge-U 的 POT 重新生成。

--stamp
    告訴 po4a 在由於未達到閾值而未生成翻譯時建立標記檔案。這些戳記檔案根據預期的翻譯文件命名，副檔名為 .po4a stamp。

    注意：這隻會啟用 .po4a stamp 檔案的建立。如果存在戳記檔案，則始終使用它們，並使用 --rm translations 或在最終翻譯檔案時刪除它們。

--no-translations
    不生成翻譯的文件，只更新 POT 和 PO 檔案。

--no-update
    不要更改 POT 和 PO 檔案，只能更新翻譯。

--keep-translations
    即使翻譯不符合 --keep 指定的閾值，也保留現有翻譯檔案。此選項不會建立內容很少的新翻譯檔案，但會儲存由於主檔案更改而衰減的現有翻譯。

    警告：此標誌以一種相當劇烈的方式更改 po4a 行為：在翻譯改進之前，您的翻譯檔案根本不會更新。僅當您希望傳送過時的翻譯文件而不是隻傳送準確的未翻譯文件時，才使用此標誌。

--rm-translations
    刪除翻譯的檔案（意味著 --no translations）。

--no-backups
    此標誌自 0.41 起不起作用，可能會在以後的版本中刪除。

--rm-backups
    此標誌自 0.41 起不起作用，可能會在以後的版本中刪除。

--translate-only translated-file
    只翻譯指定的檔案。如果配置檔案包含大量檔案，則加快處理速度可能會很有用。請注意，此選項不更新 PO 和 POT 檔案。此選項可以多次使用。

--variable var=value
    定義將在 po4a 配置檔案中展開的變數。每次出現 $(var) 都將被 value 替換。此選項可以多次使用。

--srcdir SRCDIR
    為 po4a 配置檔案中指定的所有輸入文件設定基本目錄。

    如果同時指定了 destdir 和 srcdir，則按順序在以下目錄中搜索輸入檔案：destdir、當前目錄和 srcdir。如果指定，輸出檔案將寫入 destdir 或當前目錄。

--destdir DESTDIR
    為 po4a 配置檔案中指定的所有輸出文件設定基本目錄（請參見上面的 --srcdir）。

  選項修改 POT 頭

--porefs type
    指定引用格式。引數 type 可以是以下值之一：never 不生成任何引用；file 只指定不帶行號的檔案；counter 用遞增的計數器替換行號；full 包含完整引用（預設值：full）。

--wrap-po no|newlines|number (default: 76)
    指定應如何封裝 po 檔案。這使我們可以選擇封裝良好但可能導致 git 衝突的檔案，或者更容易自動處理但對人類來說更難讀取的檔案。

    從歷史上看，gettext 套件已經重新格式化了第 77 列化妝品的 po 檔案。此選項指定 po4a 的行為。如果設定為數值，po4a 將在內容中的此列和換行之後封裝 po 檔案。如果設定為 newlines，po4a 將只在內容中的新行之後拆分 msgid 和 msgstr。如果設置為 no，則 po4a 根本不會封裝 po 檔案。引用註釋總是由我們在內部使用的 gettext 工具封裝。

    請注意，此選項對 msgid 和 msgstr 的封裝方式（即，將換行符新增到這些字串的內容中）沒有影響。

--master-language
    包含要翻譯的文件的原始檔的語言。 請注意，所有主文件必須使用相同的語言。

--msgid-bugs-address email@address
    設定 msgid 錯誤的報告地址。 預設情況下，建立的 POT 檔案沒有 Report-Msgid-Bugs-To 欄位。

--copyright-holder string
    在 POT 標頭中設定版權所有者。 預設值為“自由軟體基金會有限公司。”

--package-name string
    設定 POT 標頭的程式包名稱。 預設值為“封裝”。

--package-version string
    設定 POT 標頭的軟體包版本。 預設值為“版本”。

  修改 PO 檔案的選項

--msgmerge-opt options
    msgmerge(1) 的其他選項。

    注意： $lang 將擴充套件為當前語言。

--no-previous
    此選項從傳遞給 msgmerge 的選項中刪除 -previous。這是支援 0.16 之前的 gettext 版本所必需的。

--previous
    此選項 --previous 新增到傳遞給 msgmerge 的選項中。它需要 gettext 0.16 或更高版本，並在預設情況下啟用。

配置檔案
po4a 需要一個配置檔案作為引數。此檔案必須包含以下元素：

•   PO 檔案的路徑和專案中存在的語言列表;

•   可選地，一些全域性選項和所謂的配置別名，用作配置單個主檔案的模板;

•   要轉換的每個主檔案的列表以及特定引數。

所有行在方括號之間都包含一個命令，後跟其引數。註釋以字元 '#' 開頭，並一直執行到行的末尾。您可以轉義行尾，將命令分散到幾行。

本頁提供了一些完整的示例，而其他示例可以在原始碼分發的 "t/cfg" 目錄中找到。

  查詢 PO 和 POT 檔案
最簡單的解決方案是顯式指定 POT 和 PO 檔案的路徑，如下所示：

 [po4a_paths] man/po/project.pot de:man/po/de.po fr:man/po/fr.po

首先指定 POT 檔案的路徑，然後指定德語和法語 PO 檔案的路徑。

可以按如下方式寫入相同的資訊，以降低複製/貼上錯誤的風險：

 [po4a_langs] fr de
 [po4a_paths] man/po/project.pot $lang:man/po/$lang.po

$lang 元件使用提供的語言列表自動展開，減少了新增新語言時出現複製/貼上錯誤的風險。

透過只提供包含翻譯專案的目錄的路徑，您可以進一步壓縮相同的資訊，如下所示。

 [po_directory] man/po/

提供的目錄必須包含一組 PO 檔案，每個檔名為 XX.po，"XX" 為此檔案中使用的語言的 ISO 639-1。該目錄還必須包含單個 POT 檔案，副檔名為 ".pot"。在第一次執行時，該檔案可以是空的，但必須存在(po4a 無法猜測要在副檔名之前使用的名稱)。

請注意，您只能在 "po_資料夾" 和 "po4a_路徑" 之間選擇一個。第一個 ("po_檔案夾") 更緊湊，進一步降低了複製/貼上錯誤的風險，但強制您使用預期的專案結構和文件名。第二個 ("po4a_路徑") 更明確，可能更具可讀性，建議您在使用 po4a 設定第一個專案時使用。

集中或拆分 PO 檔案？

預設情況下，po4a 為每種目標語言生成一個 PO 檔案，其中包含翻譯專案的全部內容。隨著專案的增長，這些檔案的大小可能會出現問題。使用 weblate 時，可以為每個翻譯段（即 msgid）指定優先順序，以便首先翻譯重要的部分。儘管如此，一些翻譯團隊還是喜歡將內容分成幾個檔案。

要在每個主檔案中有一個 PO 檔案，只需在 "[po4a_paths]" 行上的 PO 檔名中使用字串 $master，如下所示。

 [po4a_paths] doc/$master/$master.pot $lang:doc/$master/$lang.po

With this line, po4a will produce separate POT and PO files for each document to translate. For example, if you have 3 documents and 5 languages, this will result in 3 POT files and 15 PO files. These files are named as specified on the "po4a_paths" template, with $master substituted to the basename of each document to translate. In case of name conflict, you can specify the POT file to use as follows, with the "pot=" parameter.

This feature can also be used to group several translated files into the same POT file. The following example only produces 2 POT files: l10n/po/foo.pot (containing the material from foo/gui.xml) and l10n/po/bar.pot (containing the material from both bar/gui.xml and bar/cli.xml).

 [po4a_langs] de fr ja
 [po4a_paths] l10n/po/$master.pot $lang:l10n/po/$master.$lang.po
 [type: xml] foo/gui.xml $lang:foo/gui.$lang.xml pot=foo
 [type: xml] bar/gui.xml $lang:bar/gui.$lang.xml pot=bar
 [type: xml] bar/cli.xml $lang:bar/cli.$lang.xml pot=bar

在 split 模式下，po4a 在 PO 更新期間構建一個臨時概要，以便在所有 PO 檔案之間共享翻譯。如果兩個 PO 檔案對同一字串有不同的翻譯，po4a 將此字串標記為 fuzzy，並將在包含此字串的所有 PO 檔案中提交兩個翻譯。當翻譯人員解除困惑時，翻譯將自動用於每個 PO 檔案中。

  指定要翻譯的文件
You must also list the documents that should be translated. For each master file, you must specify the format parser to use, the location of the translated document to produce, and optionally some configuration. File names should be quoted or escaped if they contain spaces. Here is an example:

 [type: sgml] "doc/my stuff.sgml"  "fr:doc/fr/mon truc.sgml"  de:doc/de/mein\ kram.sgml
 [type: man] script fr:doc/fr/script.1 de:doc/de/script.1
 [type: docbook] doc/script.xml fr:doc/fr/script.xml \
             de:doc/de/script.xml

但同樣，這些複雜的行很難閱讀和修改，例如在新增新語言時。使用 $lang 模板重新組織內容要簡單得多，如下所示：

 [type: sgml]    doc/my_stuff.sgml $lang:doc/$lang/my_stuff.sgml
 [type: man]     script.1          $lang:po/$lang/script.1
 [type: docbook] doc/script.xml    $lang:doc/$lang/script.xml

  指定選項
有兩種型別的選項：po4a options 是 po4a 命令列選項的預設值，而 format options 用於更改格式分析器的行為。作為 po4a options，您可以在配置檔案中指定 --keep 命令列引數的預設值是 50%，而不是 80%。Format options 記錄在每個解析模組的特定頁面上，例如 Locale::Po4a::Xml(3pm)。例如，您可以將 nostrip 傳遞給 XML 解析器，以不除去提取的字串周圍的空格。

您可以為特定主檔案傳遞這些選項，甚至為該檔案的特定翻譯傳遞這些選項，使用 "opt:" 和 "opt_XX:" 作為 "XX" 語言。在下面的示例中， nostrip 選項被傳遞給 XML 解析器（對於所有語言），而對於法語翻譯，閾值將降低到 0%（因此始終保持）。

 [type:xml] toto.xml $lang:toto.$lang.xml opt:"-o nostrip" opt_fr:"--keep 0"

無論如何，這些配置塊必須位於行的末尾。必須先宣告檔案，然後才是附錄（如有）（見下文），然後才是選項。配置塊的分組不是很重要，因為元素在內部連線為字元串。以下示例都是等效的：

  [type:xml] toto.xml $lang:toto.$lang.xml opt:"--keep 20" opt:"-o nostrip" opt_fr:"--keep 0"
  [type:xml] toto.xml $lang:toto.$lang.xml opt:"--keep 20 -o nostrip" opt_fr:"--keep 0"
  [type:xml] toto.xml $lang:toto.$lang.xml opt:--keep opt:20 opt:-o opt:nostrip opt_fr:--keep opt_fr:0

請注意，生成 POT 檔案時不使用特定於語言的選項。例如，僅在構建法語翻譯時，不可能將 nostrip 傳遞給解析器，因為同一 POT 檔案用於更新每種語言。因此，唯一可以特定於語言的選項是生成翻譯時使用的選項，如 "--keep" 選項。

配置別名

要將相同的選項傳遞給多個檔案，最好的方法是按如下所示定義類型別名。在下一個示例中，使用此 "test" 型別（即 "man" 型別的擴充套件）將 "--keep 0" 傳遞給每個意大利語翻譯。

  [po4a_alias:test] man opt_it:"--keep 0"
  [type: test] man/page.1 $lang:man/$lang/page.1

還可以對現有型別進行擴充套件，對別名使用相同的名稱，如下所示。這不是一個錯誤的遞歸定義。

  [po4a_alias:man] man opt_it:"--keep 0"
  [type: man] man/page.1 $lang:man/$lang/page.1

全域性預設選項

您還可以使用 "[options]" 行定義必須用於所有檔案的選項，無論其型別如何。

  [options] --keep 20 --option nostrip

與命令列選項一樣，您可以縮寫配置檔案中傳遞的引數：

  [options] -k 20 -o nostrip

選項優先權

每個源的選項都是串聯的，確保預設值可以很容易地被更具體的選項覆蓋。順序如下：

•   "[options]" 行提供可由任何其他源重寫的預設值。

•   然後使用類型別名。特定於語言的設定將覆蓋適用於所有語言的設定。

•   特定於給定主檔案的設定將同時覆蓋預設設定和來自類型別名的設定。在這種情況下，特定於語言的設定也會覆蓋全域性設定。

•   最後，po4a 命令列上提供的引數會覆蓋配置檔案中的任何設定。

示例

下面是一個示例，演示如何引用空格和引號：

 [po_directory] man/po/

 [options] --master-charset UTF-8

 [po4a_alias:man] man opt:"-o \"mdoc=NAME,SEE ALSO\""
 [type:man] t-05-config/test02_man.1 $lang:tmp/test02_man.$lang.1 \
            opt:"-k 75" opt_it:"-L UTF-8" opt_fr:--verbose

  附錄：在譯文中增加額外內容
如果您想在翻譯中新增一個額外的部分，例如給翻譯人員加學分，那麼您需要在定義主檔案的行中定義一個附錄。有關附錄檔案語法的更多詳細資訊，請參閱第 po4a(7) 頁。

 [type: pod] script fr:doc/fr/script.1 \
             add_fr:doc/l10n/script.fr.add

您還可以使用語言模板，如下所示：

 [type: pod] script $lang:doc/$lang/script.1 \
             add_$lang:doc/l10n/script.$lang.add

如果補遺不適用，翻譯將被丟棄。

附錄宣告的修飾符

在並非所有語言都提供附錄的情況下，或者當附錄列表從一種語言更改為另一種語言時，附錄修飾符可以簡化配置檔案。修飾符是位於檔名之前的單個字元。

?   如果此檔案確實存在，請包括 appendment_path，否則不執行任何操作。

@   addendment_path 不是常規的附錄，而是一個逐行包含附錄列表的檔案。每個附錄前面都可以加上修飾符。

!   appendment_path 被丟棄，它不會被載入，也不會被任何進一步的附錄規範載入。

以下內容包括任何語言的附錄，但前提是該附錄存在。如果附錄不存在，則不會報告任何錯誤。

 [type: pod] script $lang:doc/$lang/script.1  add_$lang:?doc/l10n/script.$lang.add

以下為每種語言的附錄清單：

 [type: pod] script $lang:doc/$lang/script.1  add_$lang:@doc/l10n/script.$lang.add

  過濾翻譯的字串
有時候，你想在翻譯過程中隱藏一些字串。為此，可以為主檔案指定一個 "pot_in" 引數，以指定在生成 pot 檔案時要使用的檔名，而不是實際的主檔名。下面是一個例子：

  [type:docbook] book.xml          \
          pot_in:book-filtered.xml \
          $lang:book.$lang.xml

使用此設定，將從 book-filtered.xml （必須在呼叫 po4a 之前生成），而轉換後的檔案將從生成 book.xml 檔案. 因此，任何屬於F的字串 book.xml 檔案但不在 book-filtered.xml 不會包含在 PO 檔案中，從而阻止翻譯人員為其提供翻譯。因此，在生成翻譯的文件時，這些字串將保持不變。這自然會降低翻譯的級別，因此您可能需要使用 "--keep" 選項來確保無論如何都會生成文件。

另請參見
po4a-gettextize(1), po4a(7).

作者
 Denis Barbier <barbier@linuxfr.org>
 Nicolas François <nicolas.francois@centraliens.net>
 Martin Quinson (mquinson#debian.org)

版權和許可
Copyright 2002-2023 by SPI, inc.

This program is free software; you may redistribute it and/or modify it under the terms of GPL v2.0 or later (see the COPYING file).