PO4A(1p)

名称
po4a - 一次性更新 PO 文件和翻译文档

简介
po4a [options] config_file

描述
po4a (PO 代表任何东西)使用经典的 gettext 工具简化了文档翻译的维护。po4a 的主要特点是将内容的翻译与文档结构分离。请参阅 po4a(7) 页了解本项目的详细介绍。

当您第一次运行 po4a 程序时，只有一个配置文件和要翻译的文档（称为主文档），它会生成一个 POT 文件（也称为翻译模板），其中包含文档中的所有可翻译字符串，格式可以简化翻译器的工作。

这些 POT 文件可以使用特定的编辑器（如 GNOME Translation editor、KDE 的 Lokalize 或 poedit）进行翻译，也可以集成到在线本地化平台（如 weblate 或 pootle）中。翻译结果是一组 PO 文件，每种语言一个。

当您使用主文档和 PO 文件运行 po4a 程序时，它通过将内容的翻译（在 PO 文件中找到）注入到原始主文档的结构中来生成翻译后的文档。

如果主文档同时发生了变化，po4a 将相应地更新 PO 和 POT 文件，以便翻译人员能够轻松地检测到修改并更新他们的工作。根据您的设置，po4a 将丢弃部分翻译的文档，或者生成一个混合了英语（对于新的或修改过的段落）和目标语言（对于翻译已经在 PO 文件中的段落）的文档。

默认情况下，翻译后的文档在至少 80% 的内容被翻译时生成（请参见下面的 --keep 选项）。在翻译不到 100% 时立即丢弃译文可能会让译者感到沮丧，而显示太不完整的“译文”可能会让最终用户感到不安。

  概述图
 主文档       ---+---->-------->---------+
  （文档编写）    |                       |
                V  （po4a 执行）         >----+--> 翻译
                |                       |     |
现有的 PO 文件  -->--> 更新的 PO 文件>    -+|
      ^                  |               |
      |                  V               |
      +----<------<------+               ^
          （人工翻译过程）                  |
                                         |
附录 -->--------------------------- ------+

主文档由文档作者编写。任何更改都会由 po4a 自动反映在 PO 文件中，然后由翻译人员进行更新。对采购订单文件的所有更改（手动或通过 po4a）都会自动反映在翻译的文档中。您可以使用 makefile 中的 po4a updatepo(1) 和 po4a translate(1) 脚本模拟此行为，但这很快就会变得麻烦和重复（请参见 po4a(7)）。强烈建议在构建过程中使用 po4a程序。

选项

-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。 这允许支持 gettext 早于 0.16 的版本。

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

如果由于多个文件具有相同的文件名而导致名称冲突，则可以通过添加 "master:file="name 选项：

 [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 master:file=foo-gui
 [type: xml] bar/gui.xml $lang:bar/gui.$lang.xml master:file=bar-gui

在 split 模式下，po4a 在 PO 更新期间构建一个临时概要，以便在所有 PO 文件之间共享翻译。如果两个 PO 文件对同一字符串有不同的翻译，po4a 将此字符串标记为 fuzzy，并将在包含此字符串的所有 PO 文件中提交两个翻译。当翻译人员解除困惑时，翻译将自动用于每个 PO 文件中。

  指定要翻译的文档
您还必须列出应翻译的文档。对于每个主文件，必须指定要使用的格式解析器、要生成的转换文档的位置，以及一些可选的配置。下面是一个例子：

 [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" 选项来确保无论如何都会生成文档。

  配置示例
待办事项：这部分真的有用吗？

假设您维护一个名为 foo 的程序，该程序有一个手册页 man/foo.1，该手册页自然只以英语维护。现在，作为上游或下游维护者，您需要创建和维护转换。首先，需要创建 POT 文件，以便使用 po4a-gettextize(1) 发送给转换器。

因此，对于我们的情况，我们会将其称为

 cd man && po4a-gettextize -f man -m foo.1 -p foo.pot

然后，您可以将此文件发送到适当的语言列表，或在您的网站上的某个位置提供下载。

现在假设您在下一个版本发布之前收到了三个翻译：de.po（包括附录 de.po)， sv.po 和 pt.po. 由于您不想在新的翻译到达时更改 Makefile，因此可以在 Makefile 中使用 po4a 和适当的配置文件。我们称之为 po4a.cfg。在我们的示例中，如下所示：

 [po_directory] man/po4a/po/

 [type: man] man/foo.1 $lang:man/translated/$lang/foo.1 \
            add_$lang:?man/po4a/add_$lang/$lang.add opt:"-k 80"

在这个例子中，我们假设您生成的手册页（以及所有的 PO 和 addenda 文件）应该存储在当前目录下的 man/translated/$lang/（分别存储在 man/po4a/PO/ 和 man/po4a/add\$lang/）中。在我们的示例中，man/po4a/po/ 目录将包括 de.po，de.po 和de.po，并且 man/po4a/add_de/ 目录将包括 de.add.

注意修饰语 ? 的用法，因为只有德语翻译(de.po)附有附录。

要实际构建翻译后的手册页，您需要(只需一次！)。在相应 Makefile 的 build 目标中添加以下行：

        po4a po4a.cfg

设置好后，当新的翻译版本到达时，您不需要创建 Makefile，也就是说，如果法国团队向您发送 fr.po 和 fr.add，那么您只需将它们分别放在 man/po4a/po/ 和 man/po4a/add_fr/ 中，下一次构建程序时，法语翻译也会自动在 F 中构建。

请注意，您仍然需要一个合适的目标来安装带有英文的本地化手册页。

最后，如果您没有将生成的文件存储到版本控制系统中， 您的 clean 目标中也需要一行：
        -rm -rf man/translated

参见
po4a-gettextize(1), po4a-normalize(1), po4a-translate(1), po4a-updatepo(1), po4a(7).

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

版权和许可
版权所有 2002-2020，SPI，Inc.

此程序是自由软件；您可以根据 GPL 条款重新分发和/或修改它(请参阅复制文件)。