PO4A.7(1)

名称
po4a - 翻译文档和其他资料的框架

简介
po4a(PO For Anything) 使用经典的 gettext 工具简化了文档翻译的维护。po4a 的主要特征是它将内容翻译与文档结构分离。

本文档是对 po4a 项目的介绍，重点关注考虑是否使用此工具的潜在用户，以及想要了解事物为什么是这样的好奇用户。

为什么是 po4a？
自由软件的理念是让技术真正为每个人所用。但许可并不是唯一的考虑因素：未翻译的自由软件对非英语国家的人来说毫无用处。因此，要让每个人都可以使用软件，我们还有一些工作要做。

大多数项目都很好地理解了这种情况，现在每个人都相信有必要翻译所有的东西。然而，实际的翻译代表了许多个人的巨大努力，他们因小小的技术困难而步履蹒跚。

值得庆幸的是，使用 gettext 工具套件实际上可以很好地翻译开放源码软件。这些工具用于从程序中提取要翻译的字符串，并以标准化格式(称为 PO 文件或翻译目录)显示要翻译的字符串。一个完整的工具生态系统已经出现，可以帮助翻译人员实际翻译这些 PO 文件。然后，gettext 在运行时使用结果向最终用户显示翻译后的消息。

然而，关于文件，情况仍然有些令人失望。起初，翻译文档似乎比翻译程序更容易，因为您似乎只需复制文档源文件并开始翻译内容。然而，当原始文档被修改时，跟踪修改很快就变成了翻译人员的噩梦。如果手动完成，此任务会令人不快且容易出错。

过时的翻译往往比根本没有翻译更糟糕。最终用户可能会被描述程序旧行为的文档所欺骗。此外，他们不能直接与维护人员互动，因为他们不会说英语。此外，维护员无法修复该问题，因为他们并不了解文档翻译所用的每种语言。这些困难通常是由糟糕的工具造成的，可能会削弱志愿翻译人员的积极性，进一步加剧问题。

po4a 项目的目标是简化文档翻译人员的工作。具体地说，它使文档翻译 Maintenance 变得可维护。

我们的想法是重用 gettext 方法并使其适用于该领域。与 gettext 一样，文本从其原始位置提取，并作为 PO 翻译目录呈现给翻译人员。翻译人员可以利用经典的 gettext 工具来监控要进行的工作，并以团队形式进行协作和组织。然后，po4a 将翻译直接注入到文档结构中，以生成翻译后的源文件，可以像处理和分发英语文件一样处理和分发这些源文件。任何未翻译的段落都将以英语保留在生成的文档中，从而确保最终用户在文档中永远不会看到过时的翻译。

这使翻译维护的大部分繁琐工作自动化。发现需要更新的段落变得非常容易，当元素重新排序而不需要进一步修改时，这个过程是完全自动的。还可以使用特定验证来减少导致文档损坏的格式化错误的机会。

有关此方法的优点和缺点的更完整列表，另请参阅本文档下面的 FAQ。

  支持的格式
目前，该方法已成功应用于多种文本格式：

man (成熟解析器)
    很好的老手册页的格式，被那么多的程序使用。po4a 支持在这里非常受欢迎，因为这种格式使用起来有些困难，对新手也不是很友好。

    Locale::Po4a::Man(3pm) 模块还支持 BSD 手册页使用的 MDOC 格式(它们在 Linux 上也很常见)。

AsciiDoc (成熟的解析器)
    此格式是一种轻量级标记格式，旨在简化文档的创作。例如，它用于记录 git 系统。这些手册页是使用 po4a 翻译的。

    有关详细信息，请参阅 Locale::Po4a::AsciiDoc。

pod (成熟的解析器)
    这是 Perl 在线文档格式。除了大多数现有的 Perl 脚本之外，还使用此格式记录了语言和扩展本身。通过将文档和实际代码嵌入到同一文件中，可以轻松地使文档接近实际代码。它使程序员的工作变得更容易，但不幸的是，在您使用 po4a 之前，翻译员的工作并非如此。

    有关详细信息，请参阅 Locale::Po4a::Pod。

sgml (成熟的解析器)
    即使现在被 XML 取代，这种格式仍然用于超过几个屏幕的文档。它甚至可以用来制作完整的书籍。更新这种长度的文档可能非常困难。当原始文本在更新后重新缩进时，diff 通常显示无用。幸运的是，po4a 可以在该过程之后帮助您。

    目前只支持 DebianDoc 和 DocBook DTD，但是添加对新 DTD 的支持非常简单。通过在命令行上提供所需的信息，甚至可以在未知的 SGML DTD 上使用 po4a，而无需更改代码。有关详细信息，请参见 Locale::Po4a::Sgml(3pm)。

TeX / LaTeX (成熟的解析器)
    LaTeX 格式是自由软件世界和出版物中使用的主要文档格式。

    使用 Python 文档、一本书和一些演示文稿测试了 Locale::Po4a::LaTeX(3pm) 模块。

text (成熟解析器)
    文本格式是包括长文本块的许多格式的基本格式，包括 Markdown、Forties、YAML Front Matter 部分、Debian/Changelog 和 Debian/Control。

    这支持静态站点生成器、自述文件和其他文档系统中使用的通用格式。有关详细信息，请参阅 Locale::Po4a::Text(3pm) 。

xml 和 XHMTL (可能是成熟的解析器)
    XML 格式是许多文档格式的基本格式。

    目前，po4a 支持 DocBook DTD (有关详细信息，请参阅 Locale::Po4a::Docbook(3pm) )和 XHTML。

BibTex (可能是成熟的解析器)
    BibTex 格式与 LaTeX 一起用于设置参考文献列表 (目录) 的格式。

    有关详细信息，请参阅 Locale::Po4a::BibTex。

Docbook (可能是成熟的解析器)
    一种基于 XML 的标记语言，它使用语义标记来描述文档。

    有关更多详细信息，请参阅 Locale::Po4a:Docbook 。

Guide XML (可能是成熟的解析器)
    一种 XML 文档格式。此模块专门用于帮助支持和维护 Gentoo Linux 文档的翻译，至少到 2016 年 3 月 (基于 Wayback Machine)。Gentoo 后来转移到了 DevBook XML 格式。

    有关更多详细信息，请参阅 Locale::Po4a:Guide。

Wml (可能是成熟的解析器)
    Web 标记语言，不要将 WML 与手机上使用的 WAP 东西混淆。该模块依赖于 Xhtml 模块，而 Xhtml 模块本身又依赖于 XML 模块。

    有关更多详细信息，请参阅 Locale::Po4a::Wml。

Yaml (可能是成熟的解析器)
    JSON 的严格超集。YAML 通常用作系统或配置项目。YAML 是红帽的 Ansible 的核心。

    有关更多详细信息，请参阅 Locale::Po4a::Yaml 。

RubyDoc (可能是成熟的解析器)
    Ruby 文档 (RD) 格式，在 2002 年转换为 RDoC 之前，最初是 Ruby 和 Ruby 项目的默认文档格式。尽管显然日文版的 Ruby 参考手册仍然使用 RD。

    有关更多详细信息，请参阅 Locale::Po4a::RubyDoc。

Halibut (高度实验性的解析器)
    由 PuTTY 的开发者 Simon Tatham 开发的文档生产系统，其元素类似于 TeX、debiandoc-sgml、TeXinfo 和其他。

    有关更多详细信息，请参见 Locale::Po4a:Halibut。

Ini (高度实验性的解析器)
    MS-DOS 普及的配置文件格式。

    有关更多详细信息，请参阅 Locale::Po4a::Ini 。

texinfo (高度实验性的解析器)
    所有 GNU 文档都是以这种格式编写的(这甚至是成为正式 GNU 项目的要求之一)。po4a 中对 Locale::Po4a::Texinfo(3pm) 的支持还处于起步阶段。请报告错误和功能请求。

其他支持的格式
    Po4a 还可以处理一些比较罕见或专门的格式，比如 2.4+ Linux 内核 (Locale::Po4a::KernelHelp) 的编译选项文档或 dia 工具 (Locale::Po4a:Dia)生成的图表。添加新格式通常非常简单，主要任务是为您的目标格式提供一个解析器。有关这方面的更多信息，请参见 Locale::Po4a::TransTractor(3pm)。

不支持的格式
    不幸的是，po4a 仍然缺乏对几种文档格式的支持。它们中的许多在 po4a 中都很容易支持。这不仅包括用于文档的格式，例如软件包描述 (deb 和 rpm)、软件包安装脚本问题、软件包更改日志，以及游戏场景或 wine 资源文件等程序使用的所有专用文件格式。

使用 po4a
从历史上看，po4a 是围绕四个脚本构建的，每个脚本都完成特定的任务。po4a-gettexalize(1) 帮助引导翻译，并可选择将现有翻译项目转换为 po4a。po4a-updatepo(1) 将对原始文档的更改反映到相应的 po 文件中。po4a-late(1) 从原始文件和相应的 PO 文件构建翻译后的源文件。此外，po4a-Normalize(1) 对于调试 po4a 解析器非常有用，因为它从原始文档生成一个未翻译的文档。它使发现解析过程引入的故障变得更容易。

Most projects only require the features of po4a-updatepo(1) and po4a-translate(1), but these scripts proved to be cumbersome and error prone to use. If the documentation to translate is split over several source files, it is difficult to keep the PO files up to date and build the documentation files correctly. As an answer, a all-in-one tool was provided: po4a(1). This tool takes a configuration file describing the structure of the translation project: the location of the PO files, the list of files to translate, and the options to use, and it fully automates the process. When you invoke po4a(1), it both updates the PO files and regenerate the translation files that need to. If everything is already up to date, po4a(1) does not change any file.

本节的其余部分将概述如何使用 po4a 的脚本界面。大多数用户可能更喜欢使用 po4a(1) 文档中描述的多合一工具。

  Po4a 脚本的概述图
下面的模式概述了如何使用每个 po4a 脚本。这里，master.doc 是要翻译的文档的示例名称；XX.doc 是以 XX 语言翻译的相同文档，而 doc.XX.po 是该文档以 XX 语言翻译的目录。文档作者主要关注 master.doc (可以是手册页、XML 文档、asciidoc 文件或类似文件)；翻译人员主要关注 PO 文件，而最终用户只能看到 XX.doc 文件。

                                   master.doc
                                       |
                                       V
     +<-----<----+<-----<-----<--------+------->-------->-------+
     :           |                     |                        :
{翻译}    |         { 更新到 master.doc }             :
     :           |                     |                        :
   XX.doc        |                     V                        V
 (可选)      |                 master.doc ->-------->------>+
     :           |                   (新的)                      |
     V           V                     |                        |
  [po4a-gettextize]   doc.XX.po -->+   |                        |
          |            (旧的)       |   |                        |
          |              ^         V   V                        |
          |              |     [po4a-updatepo]                  |
          V              |           |                          V
   translation.pot       ^           V                          |
          |              |        doc.XX.po                     |
          |              |         (模糊)                      |
   { 翻译 }       |           |                          |
          |              ^           V                          V
          |              |     {手动编辑}                 |
          |              |           |                          |
          V              |           V                          V
      doc.XX.po --->---->+<---<-- doc.XX.po    addendum     master.doc
      (初始)                 (最新)  (可选)   (最新)
          :                          |            |             |
          :                          V            |             |
          +----->----->----->------> +            |             |
                                     |            |             |
                                     V            V             V
                                     +------>-----+------<------+
                                                  |
                                                  V
                                           [po4a-translate]
                                                  |
                                                  V
                                                XX.doc
                                             (最新)

此模式很复杂，但实际上，一旦设置和配置了项目，就只使用正确的部分(涉及 po4a-updatepo(1) 和 po4a-late(1) )。

左侧部分描述了如何使用 po4a-gettexalize(1) 将现有的翻译项目转换为 po4a 基础设施。此脚本获取原始文档及其翻译的副本，并尝试构建相应的 PO 文件。这种手动转换相当麻烦(有关更多详细信息，请参阅 po4a-gettexalize(1) 文档)，但转换现有翻译只需要一次。如果您没有任何要转换的翻译，您可以忘掉这一点，专注于模式的正确部分。

在右上角，描述了原始作者的操作，更新了文档。右中部分描述了 po4a-updatepo(1) 的自动操作。提取新资料，并将其与现有翻译进行比较。先前的翻译用于未更改的部分，而部分修改的部分使用“模糊”标记连接到先前的翻译，指示翻译必须更新。新的或大量修改的资料未翻译。

然后，Manual editing 报告描述了翻译人员的操作，他们修改 PO 文件，为每个原始字符串和段落提供翻译。这可以使用特定的编辑器(如 GNOME Translation Editor、KDE's Lokalize 或 poedit )或使用在线本地化平台(如 weblate 或 pootle)来完成。翻译结果是一组 PO 文件，每种语言一个。有关更多详细信息，请参阅 gettext 文档。

图的下半部分显示了 po4a-translate(1) 如何从翻译人员更新的 master.doc 原始文档和 doc.XX.po 翻译目录创建翻译的源文档。文档的结构被重用，而原始内容被其翻译的对应内容替换。或者，可以使用附录向翻译中添加一些额外的文本。这通常用于将翻译人员的姓名添加到最终文档中。详情见下文。

如前所述，po4a(1) 程序结合了分离脚本的效果，在一次调用中更新 PO 文件和翻译后的文档。基本逻辑保持不变。

  开始新的翻译
如果使用 po4a(1)，则没有特定的步骤来开始转换。您只需在配置文件中列出语言，就会自动创建丢失的 PO 文件。自然，翻译人员必须为您的文档中使用的每个内容提供翻译。po4a(1)还创建 POT 文件，即 PO 模板文件。潜在的翻译人员可以通过重命名此文件并提供其语言的翻译，将您的项目翻译成一种新的语言。

如果您喜欢单独使用各个脚本，则应该使用 po4a-gettexalize(1) 创建 POT 文件，如下所示。然后可以将该文件复制到 XX.po 以启动新的翻译。

  $ po4a-gettextize --format <format> --master <master.doc> --po <translation.pot>

Master 文档用于输入，而 POT 文件是此过程的输出。

  将更改集成到原始文档
为此使用的脚本是 po4a-updatepo(1) (有关详细信息，请参阅其文档)：

  $ po4a-updatepo --format <format> --master <new_master.doc> --po <old_doc.XX.po>

在输入中使用 master 文档，同时更新 PO 文件：它在输入和输出中都使用。

  生成翻译的文档
完成翻译后，您希望获得翻译后的文档，并将其与原始文档一起分发给用户。为此，请使用 po4a-late(1) 程序，如下所示：

  $ po4a-translate --format <format> --master <master.doc> --po <doc.XX.po> --localized <XX.doc>

Master 文件和 PO 文件都用于输入，而本地化文件是此过程的输出。

  使用附录向翻译添加额外文本
从长远来看，在手动翻译文件时，向翻译中添加新文本可能是唯一更容易的事情 :)。当您想要向翻译后的文档添加额外的部分，而不是与原始文档中的任何内容相对应时，就会发生这种情况。典型的用例是给翻译团队加分，并指出如何报告特定于翻译的问题。

对于 po4a，您必须指定 addendum 文件，这些文件在概念上可以被视为在处理后应用于本地化文档的补丁。每个附录必须作为单独的文件提供，但其格式与经典补丁程序非常不同。第一行是 header，它定义了附录的插入点(不幸的是，使用了隐晦的语法--见下文)，而文件的其余部分被逐字添加到确定的位置。

标题行必须以字符串 PO4A-HEADER: 开头，后跟分号分隔的 key=value 字段列表。

例如，下面的标题声明了一个附录，该附录必须放在翻译的最后。

 PO4A-HEADER: mode=eof

当您想要在文档中间添加额外内容时，事情会更加复杂。下面的标题声明了一个附录，翻译时必须放在包含字符串 "About this document" 的 XML 部分之后。

 PO4A-HEADER: position=关于本文档; mode=after; endboundary=</section>

实际上，当尝试应用附录时，po4a 会搜索与 "position" 参数匹配的第一行(这可以是 regexp(正则表达式))。不要忘记，po4a 在这里考虑 translated 文档。本文档是英文的，但如果您打算将附录应用于文档的法语翻译，则您的行可能应该如下所示。

 PO4A-HEADER: position=关于本文档; mode=after; endboundary=</section>

一旦在目标文档中找到 "position",po4a 就会搜索 "position" 之后的下一行，它与所提供的 "endboundary" 匹配。附录被添加到该行的右侧 after (因为我们提供了 endboundary，即结束于当前部分的边界)。

使用下面的 Header 可以获得完全相同的效果，即等效：

 PO4A-HEADER: position=关于本文档; mode=after; beginboundary=<section>

在这里，po4a 在翻译中的匹配 "About this document" 的行之后搜索与 "<section"> 匹配的第一行，并添加该行的附录 before ，因为我们提供了 beginboundary，即 边界标记下一节的开始。 因此，此标题行需要将附录放在包含 "about this document" 的部分之后，并指示 po4a 该部分以包含 "<section"> 标记的行开头。 这与前面的示例等效，因为您真正想要的是在"/section"> 之后或 "<section">之前添加此附录。

您还可以将插入mode 设置为值 "before"，具有类似的语义：将 "mode=before" 与 "endboundary" 组合将把附录正好放在匹配边界 after，即 "position" 之前的最后一条潜在边界线。将 "mode=before" 与 "beginboundary" 组合将把附录放在匹配边界 before，也就是 "position" 之前的最后一条潜在边界线。

  模式  |   边界种类   |  使用的边界  |  与边界比较的插入点
 ========|===============|========================|=========================================
 'before'(之前)| 'endboundary'(结束边界) | last before 'position'(‘位置’之前的最后一个) | Right after the selected boundary(就在所选边界之后)
 'before'(之前)|'beginboundary'(开始边界)| last before 'position' (‘位置’之前的最后一个)| Right before the selected boundary(就在所选边界之前)
 'after'(之后) | 'endboundary'(结束边界) | first after 'position'(‘位置’之后的第一个) | Right after the selected boundary(就在所选边界之后)
 'after'(之后) |'beginboundary'(开始边界)| first after 'position'(‘位置’之后的第一个) | Right before the selected boundary(就在所选边界之前)
 'eof'(EOF)   |   (none) (无)     |  n/a                   | End of file(文件结尾)

关于附录的提示和技巧

•   请记住，这些是 regexp(正则表达式)。例如，如果您希望匹配以行 ".fi" 结尾的 nroff 部分的末尾，请不要将 ".fi" 用作 endboundary，因为它将与 "the[fi]le" 匹配，这显然不是您所期望的。在这种情况下，正确的 endboundary 是："^\.fi$"。

•   空格在 "position" 和边界的内容中很重要。所以下面的两行 are different。只有在翻译的文档中有足够的尾随空格时，才会找到第二个空格。

     PO4A-HEADER: position=关于本文档; mode=after; beginboundary=<section>
     PO4A-HEADER: position=关于本文档; mode=after; beginboundary=<section>

•   尽管该上下文搜索可能被认为是对 translated 文档的每一行进行粗略操作，但它实际上是对已翻译文档的内部数据串进行操作。该内部数据串可以是跨越包含多行的段落的文本，或者可以是单独的 XML 标签。附录的确切 insertion point 必须在内部数据字符串之前或之后，并且不能在内部数据字符串内。

•   将 -vv 参数传递给 po4a 以了解如何将附录添加到翻译中。当您的附录不适用时，在调试模式下运行 po4a 以查看实际的内部数据字符串也可能会有所帮助。

附录示例

•   如果要在以下 nroff 部分之后添加内容：

      .SH "作者"

    您应该通过设置 mode=After 选择两步方法。然后，您应该使用 position 参数 regex 将搜索范围缩小到 Authors 之后的行。然后，您应该将下一节的开头(即，^\.SH)与 BEGINBOLDER 参数 regex 相匹配。这就是说：

     PO4A-HEADER:mode=after;position=作者;beginboundary=\.SH

•   如果您想要在给定行之后添加某些内容(例如，在“版权所有 Big Dude”行之后)，请使用与此行匹配的 position，mode=After，并给出与任何行匹配的 beginboundary。

     PO4A-HEADER:mode=after;position=版权所有 Big Dude，2004 年;beginboundary=^

•   如果要在文档末尾添加某些内容，请在文档的任意行加上匹配的 position (但只有一行，如果不是唯一的，po4a 将不会继续)。并给出一个不匹配的 endboundary 。这里不要使用像 "EOF" 这样的简单字符串，而要使用那些在文档中出现的机会较小的字符串。

     PO4A-HEADER:mode=after;position=关于本文档;beginboundary=FakePo4aBoundary

更详细的示例

原始文件(POD 格式)：

 |=head1 名称
 |
 |dummy - 一个虚拟程序
 |
 |=head1 作者
 |
 |我

然后，以下附录将确保在文件的末尾添加有关翻译器的部分（简体中文）（简体中文， "翻译" 表示 "TRANSLATOR"，"我" 表示 "me"）。

 |PO4A-HEADER:mode=after;position=作者;beginboundary=^=head
 |
 |=head1 翻译
 |
 |我
 |

要将附录放在作者之前，请使用以下标题：

 PO4A-HEADER:mode=after;position=名称;beginboundary=^=head1

这之所以可行，是因为“name”部分(在汉语中翻译为“名称”)之后与 beginboundary 匹配的下一行 /^=head1/ 是声明作者的那行。因此，附录将放在两个部分之间。请注意，如果稍后在名称和作者部分之间添加另一个部分，po4a 将错误地将附录放在新部分之前。

要避免出现这种情况，您可以使用 mode=BEFORE 来完成相同的操作：

 PO4A-HEADER:mode=before;position=^=head1 AUTEUR

它是如何工作的？
本章将向您简要介绍 po4a 的内部结构，以便您可以更有信心地帮助我们维护和改进它。它还可能帮助您理解为什么它没有达到您的预期，以及如何解决您的问题。

Po4a 体系结构面向对象。Locale::Po4a::TransTractor(3pm) 类是所有 po4a 解析器的共同祖先。这个奇怪的名称来自一个事实，即它同时负责翻译文档和提取字符串。

更正式地说，它需要一个要翻译的文档加上一个包含要用作输入的翻译的 PO 文件，同时生成两个单独的输出：另一个 PO 文件(从输入文档中提取可翻译字符串的结果)和一个翻译文档(结构与输入文档相同，但所有可翻译字符串都替换为输入 PO 的内容)。以下是这一点的图形表示：

   输入文档 --\                             /---> 输出文档
                     \      翻译提取器::       /       (翻译)
                      +-->--   解析()  --------+
                     /                           \
   输入 PO --------/                             \---> 输出PO
                                                         (提取)

这个小骨头是所有 po4a 架构的核心。 如果省略输入 PO 和输出文档，则得到 po4a-gettextize。 如果同时提供输入而忽略输出 PO，则得到 po4a-translate。 po4a 调用翻译提取器两次，并在这些翻译提取器调用之间调用 msgmerge -U，以提供一个配置文件的一站式解决方案。 有关更多详细信息，请参见 Locale::Po4a::TransTractor(3pm)。

使用 po4a 的开源项目
以下是在生产中使用 po4a 进行文档编制的项目的非常部分的列表。如果您想将您的项目添加到列表中，只需给我们发送电子邮件(或合并请求)即可。

•   adduser (man): 用户和组管理工具。

•   apt (man, docbook): Debian 包管理器。

•   aptitude (docbook, svg): Debian 基于终端的包管理器

•   F-Droid website <https://gitlab.com/fdroid/fdroid-website> (markdown): 适用于 Android 平台的自由与开放源码软件(FOSS)应用程序的可安装目录。

•   git <https://github.com/jnavila/git-manpages-l10n> (asciidoc): 用于跟踪源代码更改的分布式版本控制系统。

•   Linux manpages <https://salsa.debian.org/manpages-l10n-team/manpages-l10n> (man)

    该项目提供了将许多手册页翻译成不同语言的基础设施，可以集成到几个主要的发行版中(Arch Linux、Debian 和衍生品、Fedora)。

•   Stellarium <https://github.com/Stellarium/stellarium> (HTML): 为您的计算机提供免费的开源天文馆。po4a 用于翻译天空文化描述。

•   其他要排序的项目：<https://gitlab.com/fdroid/fdroid-website/> <https://github.com/fsfe/reuse-docs/pull/61>

常见问题解答

  如何发音 po4a？
我个人把它念成 pouah <https://en.wiktionary.org/wiki/pouah>，这是一个法语拟声词，我们用它来代替 yuck(雅克 ) :) 我可能有一种奇怪的幽默感 :)

  其他使用 gettext 的文档翻译工具又如何呢？
There are a few of them. Here is a possibly incomplete list, and more tools are coming at the horizon.

poxml
    这是 KDE 人员开发的处理 DocBook XML 的工具。AFAIK，它是第一个提取字符串以从文档转换为 PO 文件，并在转换后注入它们的程序。

    它只能处理 XML，并且只能处理特定的 DTD。我对列表的处理很不满意，列表以一个大的 msgid 结尾。当清单变得很大时，大块就变得更难处理了。

po-debiandoc
    这个由 Denis Barbier 完成的程序是 po4a SGML 模块的一种前身，它或多或少地弃用了它。顾名思义，它只处理 DebianDoc DTD，这或多或少是一个过时的 DTD。

xml2po.py
    Used by the GIMP Documentation Team since 2004, works quite well even if, as the name suggests, only with XML files and needs specially configured makefiles.

Sphinx
    The Sphinx Documentation Project also uses gettext extensively to manage its translations. Unfortunately, it works only for a few text formats, rest and markdown, although it is perhaps the only tool that does this managing the whole translation process.

与它们相比，po4a 的主要优势是易于添加额外内容(这一点更糟糕)，以及实现获取文本的能力。

  基于gettext 的方法的优点的摘要

•   翻译不会与原始版本一起存储，这使得可以检测翻译是否过时。

•   翻译被存储在彼此独立的文件中，从而防止了不同语言的翻译者在提交补丁时和文件编码级别上的相互干扰。

•   它在内部基于 gettext（但是 po4a 提供了一个非常简单的界面，因此您无需了解内部使用它）。 这样，我们不必重新实现，并且由于它们的广泛使用，我们可以认为这些工具或多或少没有错误。

•   最终用户没有任何变化(除了翻译有望得到更好的维护)。 分发的结果文档文件完全相同。

•   翻译员不需要学习新的文件语法，他们最喜欢的 PO 文件编辑器(如 Emacs 的 PO 模式、Lokalize 或 GTranslator)就可以很好地工作。

•   gettext 提供了一种简单的方法来获取关于已经完成的工作、应该检查和更新的工作以及仍要做的工作的统计数据。可以在这些地址找到一些示例：

     - https://docs.kde.org/stable5/en/kdesdk/lokalize/project-view.html
     - http://www.debian.org/intl/l10n/

但是，并非所有事物都是绿色的，而且这种方法还存在一些必须解决的缺点。

•   附录是…… 乍一看很奇怪。

•   您不能根据自己的喜好调整翻译后的文本，比如在这里拆分一个段落，在那里加入另外两个段落。但在某种意义上，如果原始版本有问题，无论如何都应该报告为 bug。

•   即使有一个简单的界面，它仍然是一个人们必须学习的新工具。

    我的梦想之一是以某种方式将 po4a 集成到 GTranslator 或 Lokalize 中。打开文档文件时，会自动提取字符串，并且可以将翻译后的文件 + po 文件写入磁盘。如果我们设法制作 MSWord(TM) 模块(或者至少是 RTF)，专业翻译人员甚至可以使用它。

参见

•   您应该使用的多合一工具的文档：po4a(1)。

•   单个 po4a 脚本的文档： po4a-gettextize(1)、po4a-updatepo(1)、po4a-late(1)、po4a-Normalize(1)。

•   其他帮助脚本：msgan typot(1)、po4a-display-man(1)、po4a-display-pod(1)。

•   每种格式的解析器，特别是查看每种格式接受的选项：Locale::Po4a::AsciiDoc(3pm) Locale::Po4a::Dia(3pm), Locale::Po4a::Guide(3pm), Locale::Po4a::Ini(3pm), Locale::Po4a::KernelHelp(3pm), Locale::Po4a::Man(3pm), Locale::Po4a::RubyDoc(3pm), Locale::Po4a::Texinfo(3pm), Locale::Po4a::Text(3pm), Locale::Po4a::Xhtml(3pm), Locale::Po4a::Yaml(3pm), Locale::Po4a::BibTeX(3pm), Locale::Po4a::Docbook(3pm), Locale::Po4a::Halibut(3pm), Locale::Po4a::LaTeX(3pm), Locale::Po4a::Pod(3pm), Locale::Po4a::Sgml(3pm), Locale::Po4a::TeX(3pm), Locale::Po4a::Wml(3pm), Locale::Po4a::Xml(3pm).

•   核心基础设施的实施：Locale::Po4a::TransTractor(3pm) (particularly important to understand the code organization), Locale::Po4a::Chooser(3pm), Locale::Po4a::Po(3pm), Locale::Po4a::Common(3pm). 还请检查源代码树中的 CONTRIBUTING.md 文件。

作者
 Denis Barbier <barbier,linuxfr.org>
 Martin Quinson (mquinson#debian.org)