PO4A.1P(1) User Contributed Perl Documentation PO4A.1P(1)


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.

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.


保留(即写入)结果文件的转换百分比的最小阈值(默认值:80)。即,默认情况下,文件必须至少翻译 80% 才能写入磁盘。
Column at which we should wrap the resulting file if the format supports it (default: 76).
要传递给格式插件的额外选项。有关有效选项及其含义的更多信息,请参阅每个插件的文档。例如,您可以将 '-o tablecells' 传递给 AsciiDoc 解析器,而文本解析器将接受 '-o tabs=split'。
始终生成 POT 和 PO 文件,即使 po4a 认为没有必要。

默认行为(未指定 --force 时)如下:

如果 POT 文件已经存在,则如果主文档或配置文件较新(除非提供了 --no-update),则会重新生成该文件。POT 文件也写入临时文档中,po4a 验证是否确实需要更改。

此外,只有当翻译的主文档、PO 文件、其中一个附录或配置文件更新时,才会重新生成翻译。要避免尝试重新生成未通过阈值测试的翻译(请参见 --KEEP),可以创建扩展名为 .po4a-stamp 的文件(请参见 --STAMP)。

如果主文档包含文件,则应使用 --force 标志,因为不会考虑这些包含文件的修改时间。

PO 文件总是基于带有 msgmerge-U 的 POT 重新生成。

告诉 po4a 在由于未达到阈值而未生成翻译时创建标记文件。这些戳记文件根据预期的翻译文档命名,扩展名为 .po4a stamp

注意:这只会激活 .po4a stamp 文件的创建。如果存在戳记文件,则始终使用它们,并使用 --rm translations 或在最终翻译文件时删除它们。

不生成翻译的文档,只更新 POT 和 PO 文件。
不要更改 POT 和 PO 文件,只能更新翻译。
即使翻译不符合 --keep 指定的阈值,也保留现有翻译文件。此选项不会创建内容很少的新翻译文件,但会保存由于主文件更改而衰减的现有翻译。

警告:此标志以一种相当剧烈的方式更改 po4a 行为:在翻译改进之前,您的翻译文件根本不会更新。仅当您希望传送过时的翻译文档而不是只传送准确的未翻译文档时,才使用此标志。

删除翻译的文件(意味着 --no translations)。
此标志自 0.41 起不起作用,可能会在以后的版本中删除。
此标志自 0.41 起不起作用,可能会在以后的版本中删除。
只翻译指定的文件。如果配置文件包含大量文件,则加快处理速度可能会很有用。请注意,此选项不更新 PO 和 POT 文件。此选项可以多次使用。
定义将在 po4a 配置文件中展开的变量。每次出现 $(var) 都将被 value 替换。此选项可以多次使用。
po4a 配置文件中指定的所有输入文档设置基本目录。

如果同时指定了 destdirsrcdir,则按顺序在以下目录中搜索输入文件:destdir、当前目录和 srcdir。如果指定,输出文件将写入 destdir 或当前目录。

po4a 配置文件中指定的所有输出文档设置基本目录(请参见上面的 --srcdir)。

选项修改 POT 头

指定引用格式。参数 type 可以是以下值之一:never 不生成任何引用;file 只指定不带行号的文件;counter 用递增的计数器替换行号;full 包含完整引用(默认值:full)。
指定应如何封装 po 文件。这使我们可以选择封装良好但可能导致 git 冲突的文件,或者更容易自动处理但对人类来说更难读取的文件。

从历史上看,gettext 套件已经重新格式化了第 77 列化妆品的 po 文件。此选项指定 po4a 的行为。如果设置为数值,po4a 将在内容中的此列和换行之后封装 po 文件。如果设置为 newlines,po4a 将只在内容中的新行之后拆分 msgid 和 msgstr。如果设置为 no,则 po4a 根本不会封装 po 文件。引用注释总是由我们在内部使用的 gettext 工具封装。

请注意,此选项对 msgid 和 msgstr 的封装方式(即,将换行符添加到这些字符串的内容中)没有影响。

包含要翻译的文档的源文件的语言。 请注意,所有主文档必须使用相同的语言。
设置 msgid 错误的报告地址。 默认情况下,创建的 POT 文件没有 Report-Msgid-Bugs-To 字段。
在 POT 标头中设置版权所有者。 默认值为“自由软件基金会有限公司。”
设置 POT 标头的程序包名称。 默认值为“封装”。
设置 POT 标头的软件包版本。 默认值为“版本”。

修改 PO 文件的选项

msgmerge(1) 的其他选项。

注意: $lang 将扩展为当前语言。

此选项从传递给 msgmerge 的选项中删除 -previous。这是支持 0.16 之前的 gettext 版本所必需的。
此选项 --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 \

但同样,这些复杂的行很难阅读和修改,例如在添加新语言时。使用 $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 \


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




如果此文件确实存在,请包括 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 \

使用此设置,将从 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)


taotieren <admin@taotieren.com>


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).

2024-06-26 perl v5.38.2