这是针对英文原版页面的中文翻译。

GNU 中文翻译组工作流程(草案)

GNU 中文翻译组 (GNU Chinese Translation Team, GNU CTT) 负责 GNU 官方网站的翻译工作。

以下工作流程适用于一般网页翻译工作,有任何特殊情况或不确定,可以通过邮件列表提出。

如何选择一个要翻译的页面

根据 GNU Web 翻译手册 要求,结合 GNU CTT 的实际情况,以下内容应当优先得到翻译:

  • 中文翻译报告 中所列出的需要优先处理的页面(其中数字表示状态:已翻译/模糊的翻译/待翻译)。
  • 中文翻译差异报告 中所列出的有差异的页面。
  • 以下目录中的页面:philosophy, gnu, copyleftlicenses
  • 链接到已翻译页面的页面。(如果一个已经翻译的页面没有任何别的页面存在链接链向它,则它很难被访问到)

原则上不要翻译以下页面:

  • software/pkg/:所有的软件包的相关翻译由各个软件包的维护者负责。
  • brave-gnu-world:The Brave GNU World活动已经被废弃,不必要翻译相关的页面。
  • home.shtmlserver/whatsnew.html:GNU 首页和最近新闻页面更新较快,如果没有足够的精力,不要优先翻译这些页面。

如何开始一个新的翻译

在开始翻译之前,有必要简单了解一下gnu.org网站背后的一些技术细节。

GNU的每个页面都是静态HTML页面,但是翻译工作不是直接编辑HTML文件。而是通过.po(Portable Object)来进行翻译的。这样,在翻译的过程中,翻译人员不必(完全)了解HTML的语法以及各种琐碎细节而是通过.po(Portable Object)来进行翻译的,从而可以更专注于翻译本身。如果你之前不了解.po文件的格式也不必担心,后面我们会有介绍。

GNU的维护者首先发布英文的原文,之后,通过定时运行的GNUN程序生成PO模板文件(文件名通常以.pot结尾)。这个HTML文件和PO模板文件都会出现在GNU网页的CVS版本库中。翻译人员根据PO模板文件,创建PO文件,并将翻译放入PO文件。定时运行的GNUN程序则会自动根据PO文件,生成对应翻译的HTML文件。

任何人都可以通过CVS来把整个页面下载到自己的计算机上。可以使用这个命令来同步下整个GNU网页以及它的版本信息:

export CVS_RSH=ssh
cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/web/www co www

下载下整个网站信息后,可以简单浏览一下它的结构(如果只是像浏览一下目录结构,可以访问这个链接)。对于每个目录,都有一个名为po/的子目录,里面包含着po/目录的父目录的所有文章的对应PO文件和PO模板文件。例如,在philosophy/目录下有一篇文章,文件名是open-source-misses-the-point.html,对应的页面URL为https://www.gnu.org/philosophy/open-source-misses-the-point.html。那么,这篇文章对应的PO模板文件则存在philosophy/po/目录下,文件名为open-source-misses-the-point.pot。对应的简体中文翻译存在philosophy/po/目录下的open-source-misses-the-point.zh-cn.po文件中。

从以上描述的目录结构看,就不难理解翻译的流程了(注意:这个不是最终流程!)。首先,选定一篇gnu.org上的文章,根据URL,找到CVS版本库中对应的文件。然后,根据这个文件名,找到对应的PO模板文件。最后,从PO模板文件,翻译成最终的PO文件。

我们继续以open-source-misses-the-point.html这篇文章为例。它的URL是https://www.gnu.org/philosophy/open-source-misses-the-point.html。从这个URL,我知道它在版本库的philosophy/目录下,文件名是open-source-misses-the-point.html(如果没有用cvs下载整个代码库,可以通过浏览器浏览GNU www的版本库。这个文件就在这里)。之后,根据这个文件的文件名,和它所在的目录,我知道它的PO模板文件存在philosophy/po/open-source-misses-the-point.pot中(通过网页浏览版本库的话,是在这里)。假设我希望把这篇文章翻译为简体中文,那么,我先把这个模板文件复制成open-source-misses-the-point.zh-cn.po,同样放在philosophy/po/目录下。对open-source-misses-the-point.zh-cn.po进行编辑(即,翻译)。具体如何通过编辑PO文件来翻译,我们之后会介绍。翻译完,把这个PO文件提交到版本库中。等待一段时间,就会在philosophy/目录下,出现一个名为open-source-misses-the-point.zh-cn.html的文件。这个时候,再使用浏览器打开https://www.gnu.org/philosophy/open-source-misses-the-point.zh-cn.html,就可以看到翻译好的文章了。

以上这个流程虽然简单有效,但是有一个致命的缺陷:任何人都应该有资格贡献自己的翻译,但是并不是所有人都有资格去修改gnu.org的版本库。修改版本库,就意味着修改gnu.org上面的信息。如果谁都可以修改,gnu.org也就不复存在了。因此,只有经过GNU翻译组认证的协调员,才有权限去修改gnu.org网页的版本库。每个语言,都有对应的翻译组,而每个翻译组都会有一个或多个协调员。翻译任何通过把翻译好的PO文件交给协调员,经审核后,由协调员将PO文件提交到gnu.org网页的版本库中,从而更新网页信息

那么,如何与协调员沟通呢?每个翻译小组,都会在savannah上有一个对应的项目。从而又各有一个对应的CVS版本库。以中文翻译组为例,对应的翻译组项目在https://savannah.gnu.org/projects/www-zh-cn/上。在这个项目页面,可以找到对应CVS版本库的信息。

各个语言的翻译小组,都会有各自的邮件列表。中文翻译小组的邮件列表是www-zh-cn-translators@gnu.org。可以通过这个页面来加入邮件列表并与大家交流。

如果你希望翻译某篇文章,可以先加入中文翻译小组的邮件列表,告诉大家你希望翻译哪篇文章。我们也欢迎你在savannah上注册一个帐号,并加入中文翻译小组。之后,把想要翻译的文章的PO模板文件(.pot)翻译成PO文件。如果你已经加入中文翻译组,那么你将可以修改中文翻译组的CVS版本库,你可以提交你的翻译到版本库中的对应位置,然后在邮件列表上通知大家。如果你还没有加入中文翻译小组,可以考虑将PO文件的链接发到邮件列表上,我们会尽快审校并传到中文翻译组的版本库中。一旦文章通过审校,将会由中文翻译组的协调员将对应文件传到GNU网页的版本库中。等待大约一天的时间,你的翻译就会出现在gnu.org上。

当然,如果你熟悉savannah的环境,我们更推荐你使用以下流程来提交翻译:

  1. 确定要翻译的页面,比如foo/bar.html。
  2. 访问 GNU CTT 的 Savannah 上的 Task 列表,检查有没有人正在翻译这个页面。如果有人正在翻译或曾经翻译过,请参考已有的进度做相应的后续工作。
  3. 新建一个 Task,标题为“Translate Bar - foo/bar.zh-cn.po”。把 Status 设为“In Progress”,把 Assigned to 设为自己。
  4. 从www组的CVS中获取最新的pot文件(或zh-cn.po文件,如果存在)。使用命令cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/web/www co www/foo/po/bar.pot。
  5. 把获取的foo/po/bar.pot文件放到 GNU CTT 的 CVS 中,命名为:foo/bar.zh-cn.po。
  6. 翻译foo/bar.zh-cn.po。
  7. 把翻译完的foo/bar.zh-cn.po 提交到 GNU CTT 的 CVS 中。
  8. 更新 Savannah 上的 Task,记录必要的信息,把 Status 设为 “Read For Test”,把 Assigned to 设为审阅人或 None (如果没有审阅人)。
  9. (可选)在邮件列表中通知翻译完成,寻找审阅人或请协调人协调审阅工作。

PO文件,PO模板文件,如何编辑?

PO文件中,记录着原文和对应的翻译。PO模板文件,或者叫POT文件,则只记录着原文和格式信息。翻译的主要工作,是将一个PO模板文件里的原文,翻译好,另存为PO文件。这么说来也许太抽象,以下是一个实际的例子。

我们以Optionally Free Is Not Enough这篇文章为例。它的PO模板文件的开头看起来是这个样子的:

# LANGUAGE translation of https://www.gnu.org/distros/optionally-free-not-enough.html
# Copyright (C) YEAR Free Software Foundation, Inc.
# This file is distributed under the same license as the original article.
# FIRST AUTHOR , YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: optionally-free-not-enough.html\n"
"POT-Creation-Date: 2014-04-04 23:58+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING"

文件开头包含的信息有文件的创建时间,翻译的语言,翻译者的姓名等等。翻译 的第一个工作,就是把PO模板文件复制为PO文件,并把PO文件中开头部分填写称 正确的信息。以下是这个实例的PO文件开头翻译:(注意其中的粗体中文是解释)

# Simplified Chinese translation of https://www.gnu.org/distros/optionally-free-not-enough.html
# Copyright (C) 2018 Free Software Foundation, Inc.
# This file is distributed under the same license as the original article.
# FIRST AUTHOR , YEAR. 此处根据情况写入首个版本的译者。
# OTHER AUTHOR , YEAR. 此处根据情况写入中间各个版本的译者。
# LAST AUTHOR , YEAR. 此处根据情况写入最后版本的译者。
#
msgid ""
msgstr ""
"Project-Id-Version: optionally-free-not-enough.html\n"
"POT-Creation-Date: 2014-04-04 23:58+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" Emacs会自动填充
"Last-Translator: LAST AUTHOR \n"  此处只写最后版本的译者
"Language-Team: Chinese \n"
"Language: zh_CN\n" 添加此项
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit"

需要注意的是:文件的编码一律要采用UTF-8,而不能使用GB系列或BIG-5系列编码。

再往下看这个信息,可以看到一段一段的原文,翻译者则需要把翻译好的语句放 在对应原文的下面。例如,以下是最后一段还没有翻译的文件:


#. TRANSLATORS: Use space (SPC) as msgstr if you don't have notes.
#. type: Content of: <div>
msgid "*GNUN-SLOT: TRANSLATOR'S NOTES*"
msgstr ""

#. type: Content of: <div><div><p>
msgid ""
"Please send general FSF &amp; GNU inquiries to <a "
"href=\"mailto:gnu@gnu.org\">&lt;gnu@gnu.org&gt;</a>.  There are also <a "
"href=\"/contact/\">other ways to contact</a> the FSF.  Broken links and "
"other corrections or suggestions can be sent to <a "
"href=\"mailto:webmasters@gnu.org\">&lt;webmasters@gnu.org&gt;</a>."
msgstr ""

#.  TRANSLATORS: Ignore the original text in this paragraph,
#.         replace it with the translation of these two:
#
#.         We work hard and do our best to provide accurate, good quality
#.         translations.  However, we are not exempt from imperfection.
#.         Please send your comments and general suggestions in this regard
#.         to <a href="mailto:web-translators@gnu.org">
#
#.         &lt;web-translators@gnu.org&gt;</a>.</p>
#
#.         <p>For information on coordinating and submitting translations of
#.         our web pages, see <a
#.         href="/server/standards/README.translations.html">Translations
#.         README</a>.
#. type: Content of: <div><div><p>
msgid ""
"Please see the <a "
"href=\"/server/standards/README.translations.html\">Translations README</a> "
"for information on coordinating and submitting translations of this article."
msgstr ""

#. type: Content of: <div><p>
msgid "Copyright &copy; 2014 Free Software Foundation, Inc."
msgstr ""

#. type: Content of: <div><p>
msgid ""
"This page is licensed under a <a rel=\"license\" "
"href=\"https://creativecommons.org/licenses/by-nd/3.0/us/\">Creative Commons "
"Attribution-NoDerivs 3.0 United States License</a>."
msgstr ""

#. TRANSLATORS: Use space (SPC) as msgstr if you don't want credits.
#. type: Content of: <div><div>
msgid "*GNUN-SLOT: TRANSLATOR'S CREDITS*"
msgstr ""

#.  timestamp start
#. type: Content of: <div><p>
msgid "Updated:"
msgstr ""

翻译人员主要关注的,是msgid中的原文信息和msgstr中的翻译。即,将msgid中的原文翻译好后,放在msgstr里。例如,上文中的内容翻译好后将会是:(注意其中的粗体中文是解释)


#. TRANSLATORS: Use space (SPC) as msgstr if you don't have notes.
#. type: Content of: <div>
msgid "*GNUN-SLOT: TRANSLATOR'S NOTES*"
msgstr "" 此处是译注。如果没有,请输入一个空格。如果有,首先要在正文处要注释的地方加上索引,如
<sup><a href="#TransNote1">1</a></sup>
然后在此处添加相应的注解,如

<h3>译注</h3>
<ol>
<li id="TransNote1">Original text:注解。</li>
</ol><



#. type: Content of: <div><div><p>
msgid ""
"Please send general FSF &amp; GNU inquiries to <a href=\"mailto:gnu@gnu.org"
"\">&lt;gnu@gnu.org&gt;</a>.  There are also <a href=\"/contact/\">other ways "
"to contact</a> the FSF.  Broken links and other corrections or suggestions "
"can be sent to <a href=\"mailto:webmasters@gnu.org\">&lt;webmasters@gnu."
"org&gt;</a>."
msgstr ""
"请将有关自由软件基金会(FSF)&amp;GNU的一般性问题发送到<a href=\"mailto:"
"gnu@gnu.org\">&lt;gnu@gnu.org&gt;</a>。也可以通过<a href=\"/contact/\">其他联"
"系方法</a>联系自由软件基金会(FSF)。请将无效链接,其他错误或建议发送给<a href="
"\"mailto:webmasters@gnu.org\">&lt;webmasters@gnu.org&gt;</a>。"

#
#
#
#.  TRANSLATORS: Ignore the original text in this paragraph,
#.         replace it with the translation of these two:
#.         We work hard and do our best to provide accurate, good quality
#.         translations.  However, we are not exempt from imperfection.
#.         Please send your comments and general suggestions in this regard
#.         to <a href="mailto:web-translators@gnu.org">
#.         &lt;web-translators@gnu.org&gt;</a>.</p>
#.         <p>For information on coordinating and submitting translations of
#.         our web pages, see <a
#.         href="/server/standards/README.translations.html">Translations
#.         README</a>.
#. type: Content of: <div><div><p>
msgid ""
"Please see the <a href=\"/server/standards/README.translations.html"
"\">Translations README</a> for information on coordinating and submitting "
"translations of this article."
msgstr ""
"若您想翻译本文,请参看<a href=\"/server/standards/README.translations.html\">"
"翻译须知</a>。"

#. type: Content of: <div><p>
msgid "Copyright &copy; 2014 Free Software Foundation, Inc."
msgstr "Copyright &copy; 2014 Free Software Foundation, Inc." 照抄。

#. type: Content of: <div><p>
msgid ""
"This page is licensed under a <a rel=\"license\" href=\"https://"
"creativecommons.org/licenses/by-nd/3.0/us/\">Creative Commons Attribution-"
"NoDerivs 3.0 United States License</a>."
msgstr ""
"本页面使用<a rel=\"license\" href=\"https://creativecommons.org/licenses/by-"
"nd/3.0/us/\">Creative Commons Attribution-NoDerivs 3.0 United States "
"License</a>授权。"

#. TRANSLATORS: Use space (SPC) as msgstr if you don't want credits.
#. type: Content of: <div><div>
msgid "*GNUN-SLOT: TRANSLATOR'S CREDITS*"
msgstr ""
"<b>翻译<b>:<a href=\"mailto:hagb_green@qq.com\">&lt;Hagb (郭俊余)&gt;</"
"a>,2018。<br></br>\n" 如果译者要求,请在此列出译者。
"<b>审校<b>:<a href=\"mailto:hagb_green@qq.com\">&lt;Hagb (郭俊余)&gt;</"
"a>,2018。<br></br>\n" 征得审校译者同意,请在此列出审校者。
"<b>翻译团队<b>:<a rel=\"team\" href=\"https://savannah.gnu.org/projects/"
"www-zh-cn/\">&lt;CTT&gt;</a>,2018。" 必填。

#.  timestamp start
#. type: Content of: <div><p>
msgid "Updated:"
msgstr "最后更新:"

这说起来也许容易,但是因为PO文件涉及到很多琐碎的格式细节,我们强烈建议使用一款可以专门针对PO文件格式进行编辑的编辑器。例如,我们推荐使用GNU Emacs配合PO-mode插件来编辑PO文件。这样,可以极大地减少因PO格式问题引起的各种不必要的麻烦。GNUN里也提供了一些PO文件处理技巧

可以考虑使用

msgfmt -cv filename.zh-cn.po
命令来检查文件格式以及翻译进度。例如:

$ msgfmt -cv free-sw.zh-tw.po
56 translated messages, 22 untranslated messages.

这就显示,有56条信息已经翻译,还有22条没有翻译。

如何进行审阅

  1. 确定一个页面进行审阅,可能是被翻译人或协调人指定的,也可以是在邮件列表中自己提出要进行审阅的,也可以自行在 Savannah 中寻找 Status 为“Read For Test”的 Task 。
  2. 把 Savannah 中的 Task 的 Assigned to 设为自己(如果原来是 None 的话)。
  3. 从 GNU CTT 的 CVS 中获取最新版本的foo/bar.zh-cn.po文件。
  4. 进行审阅。如有问题可直接与翻译人或通过邮件列表沟通。
  5. 审阅完成后,可以在*GNUN-SLOT: TRANSLATOR'S CREDITS*中加入审阅人信息,提交必要的改动。
  6. 更新 Savannah 上的 Task,记录必要的信息,把 Assigned to 设为提交人(依次为: wxie, monnand)

如何进行提交

  1. 提交人收到提交请求后,从 GNU CTT 的 CVS 中获取最新的foo/bar.zh-cn.po文件。
  2. 再次做基本的审阅,确定没有明显的错误。
  3. 在 GNU CTT 的 CVS 中的所有po文件中查找指向foo/bar.html的链接,把它们更新为foo/bar.zh-cn.html。
  4. 更新www组的相关文件,确保在该页面页脚的“其他翻译”中包含“简体中文 [zh-cn]”。
  5. 在 GNU CTT 的 CVS 的根目录中运行“make report”,再次确认文件的状态。
  6. 把所有更新完的po文件提交到www组和GNU CTT的CVS。
  7. 更新 Savannah 上的 Task,记录必要的信息,把 Assigned to 设为 None,把 Status 设为 Done,把 Open/Closed 设为 Closed。

如何更新翻译

  1. 确定要更新的页面,比如foo/bar.zh-cn.html。
  2. 访问 GNU CTT 的 Savannah 上的 Task 列表,找到相应的 Task ,把 Open/Closed 设为 Open,把 Status 设为“In Progress”,把 Assigned to 设为自己。
  3. 从 GNU CTT 的 CVS 中获取最新的foo/bar.zh-cn.po。
  4. 如果 www 组相应的 foo/po/bar.pot 文件发生变化,则从 www 组的 CVS 中获取最新的 pot 文件,在 GNU CTT 的 CVS 根目录中运行“make sync”,更新 foo/bar.zh-cn.po 文件。
  5. 翻译更新foo/bar.zh-cn.po。
  6. 把更新完的foo/bar.zh-cn.po 提交到 GNU CTT 的 CVS 中。
  7. 更新 Savannah 上的 Task,记录必要的信息,把 Status 设为 “Read For Test”,把 Assigned to 设为审阅人或上一次的审阅人。

如何保证翻译质量

翻译工作本身是一个再创作的过程,很多情况下,译者可以根据自身喜好为翻译 的作品赋予不同的风格。但是在为了维护整体的统一性,需要有一些基本的约束:

如何使用 compendium.po 文件

compendium.po 文件是一个集合了多个固定翻译的 po 文件。使用 compendium.po 文件可以帮 助译者减少重复工作,也有利于保持翻译文本的一致性。CTT 项目已经其项目路径下编辑 了 compendium.po 文件。其使用方法是在 GNU/Linux 执行以下 bash 命令:

msgmerge --compendium compendium.po -o $1.zh-cn.po /dev/null $1.pot

其中,$1.pot 是 从 待翻译文章 处下载的初始待翻译文章。命令执行之后产生的 $1.zh-cn.po 是添加了固定翻译的待工作文章——译者可以直接从这个文件开始工作。