通往本地化翻译的自由之路-深入探寻
- 本文详细介绍如何利用po文件进行本地化翻译。
- 本文尚在编辑完善中,欢迎您的参与!
背景知识
关于.po文件
初识.po文件
- .po文件是什么样子的呢?下面是一个最简单的示例:
msgid "Hello World" msgstr ""
PO是什么意思?
- PO是“Portable Object”的意思。PO文件是纯文本文件,可以被任何文本处理程序编辑。.po文件用于翻译者在其中将待翻译(国际化)的字符串翻译为某种特定语言 。而且PO文件的使用跟平台无关。比如可以把GNU/Linux程序的.po文件在Microsoft Windows操作系统环境下完成翻译后再拿回来使用。这也就是PO的全名“Portable Object”的含义。(注1)
po文件的背景和原理
- 友情提示:如果对于这段内容理解有困难,可以忽略过去,不会对您使用.po文件翻译造成任何影响。
- 要理解.po翻译文件格式,就不得不提到GNU gettext。国际化是当今软件产业发展的趋势, GNU gettext作为GNU对程序信息国际化提出的一个解决方案,以其简单易行、适应面广等优点,正逐渐成为程序信息国际化的标准作法(注1)。而.po翻译文件格式就是由此产生的。
- .po文件最初是用于翻译程序源代码里的字符串的。这段内容需要一点点C语言的基础才能完全理解。
- 目前大部分自由软件实现国际化使用的是GNU gettext。国际化就是让程序可以使用多国语言来显示程序里的字符串。程序里一般都有很多字符串,菜单名也好,错误信息也好,都是字符串。
- 假设字符串为"Hello World",非国际化的程序里都是直接写"Hello World"。如果用了GNU gettext来实现国际化的话,就要写成gettext("Hello World")。有时也会看到 _("Hello World"),那实际上也是gettext,只不过通过宏的定义把 gettext改头换面了。这个"Hello World"就是msgid。
- 然后使用xgettext来从程序源代码文件产生po文件,接着交给专门的翻译人员来翻译 po文件。翻译人员根本不需要懂编程。
- 翻译完毕后,使用msgfmt来把.po文件转化成.mo文件,并安装到系统里合适的位置。程序运行时,到底显示什么字符串就是由gettext函数来决定的了。主要有两个决定因素,一个是系统的locale及相关环境变量(LANGUAGE,LC_ALL,LC_MESSAGES和LANG),一个是相关的mo文件。。
- 随着程序版本的升级,程序里的字符串的数量和内容都会发生变化,但变化不会很大,以前翻译过的.po文件里大部分msgid都能被重复利用。所以维护.po的翻译人员在每次得到从新的程序源代码产生的.po文件时,都用msgmerge工具来根据旧的已翻译过的.po文件来先处理一下新的未翻译的po。处理过后,大部分情况下新po就翻译的差不多了。翻译人员的工作量被大幅度减轻了。
- 如果您还想进一步了解.po文件和GNU gettext,可以访问GNU.org官方网站。下面给出两个基本链接。
.po文件格式解析
基本格式说明
- .po文件都是由一对对的msgid和msgstr组成的。
- msgid就是原文(Message ID)。
- msgstr就是译文(Message Translation)。
- 原文、译文相互对照,所以非常适于翻译。
基本示例
- 示例--这是未翻译的.po文件:
msgid "Welcome to ADempiere ERP" msgstr ""
- 示例--这是翻译后的.po文件:
msgid "Welcome to ADempiere ERP" msgstr "欢迎来到ADempiere ERP"
fuzzy标志
- 有的msgid前面一行有fuzzy的字样,您或许会好奇地问:这是什么意思?
- fuzzy字样说明:第一,这个.po文件是被msgmerge工具处理过的;第二,已翻译的.po文件里没有和这个msgid完全等同的msgid,只有非常相似的。这种情况下,msgmerge工具仍然会用那个相似的msgid来翻译此msgid。不过会给这个msgid标记为fuzzy,表示翻译人员仍然要翻译这 个msgid,并在翻译后去掉上面带fuzzy的这一行。
- 我们在这里举个例子。假设最新版本的ADempiere把"Welcome to ADempiere ERP"改为了"Welcome to ADempiere ERP !"(加了一个感叹号)。原有的.po文件经过msgmerge工具处理后,这个条目的msgid前将会出现fuzzy标记。
#, fuzzy msgid "Welcome to ADempiere ERP !" msgstr "欢迎来到ADempiere ERP"
.po翻译文件的优势
- 1. 原文译文相互对照,非常适于翻译;
- 2. 软件中的同一个条目(即字符串)不管出现多少次,都只需要翻译一次;
- 3. 轻松完成翻译版本转换。旧有的已翻译过的.po文件可以重复利用,不必再次翻译,且利于统一风格。
- 4. 有非常好的翻译工具,熟练使用后可大幅度提高工作效率。例如文本编辑器GNU Emacs、协作翻译平台Launchpad.net。
准备工作
- 为了利用.po文件开展翻译工作,我们需要准备好下以工具:
- 对于系统维护者:
- PO文件转换工具。常用工具为po4a、xml2po。
- 对于普通的翻译者:
- 文本编辑工具。MS Windows操作系统的写字板,Linux操作系统的Gedit或Kate,都可以完成翻译工作。我们推荐您使用GNU Emacs。
po4a
- 为了使用po来翻译,显然我们需要能够把xml转成po的工具。这里我们选用po4a有三个原因:
- po4a可支持多种文档格式,包括XML、DocBook、Latex等等。
- po4a可以根据原来的xml文档和与之对应的已经翻译过的xml文档生成po。这个功能非常有用,随后即可看到。
- po4a目前的开发维护最为活跃。xml2po的开发已经趋于停滞(待查证)。
安装po4a
- Debian/Ubuntu下的安装方法为:
# aptitude install po4a
- CentOS(redhat,Fc类似)的安装方法:
1.root登陆,或者sudo应用2.编辑/etc/yum.repos.d/CentOS-Base.repo文件,增加如下内容
[dag] name=Dag RPM Repostory for Red Hat Enterprise Linux baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag gpgcheck=1 enabled=1 gpgkey=http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt
3.执行如下命令
#yum install po4a
- 目前尚不清楚MS Windows系统下的安装方法。当然,您也可以通过VirtualBox虚拟一个迷你Linux来运行po4a工具。
文本编辑器
- 通过普通的文本编辑器,您就可以在.po文件内进行翻译了。
- 我们推荐您使用GNU Emacs。
- GNU Emacs是一款优秀的、跨平台的文本编辑器,在MS Windows、Linux等操作系统均可使用。
- GNU Emacs特有的po模式,让您的PO文件编辑更为轻松自如!
- GNU Emacs官方网站
常用命令
掌握po4a的三个命令
从xml产生未翻译po
$ po4a-gettextize -f xml -m orig.xml > untrans.po
从旧的xml原文和译文产生已经翻译过的po
$ po4a-gettextize -f xml -m orig.xml -l trans.xml > trans.po
用已经翻译过的po和xml原文来产生xml译文
$ po4a-translate -f xml -m orig.xml -p trans.po -k 1 > trans.xml
推荐翻译模式
翻译全新的文件
- 假设这个文件叫orig.xml(下同)
$ po4a-gettextize -f xml -m orig.xml > output.po $ sed -i -e "s/charset=CHARSET/charset=UTF-8/" output.po 用文本编辑器翻译output.po $ po4a-translate -f xml -m orig.xml -p output.po -k 1 > trans.xml
利用旧版的已翻译文件翻译新文件
- 假设旧版文件叫old.xml,旧版已翻译文件叫old-trans.xml,新文件叫new.xml。先对旧版已翻译文件稍作修改,比如去掉英文版guide tag里没有的lang="zh_cn",去掉所有的译者信息。
$ po4a-gettextize -f xml -m old.xml -l old-trans.xml -p old-trans.po $ po4a-updatepo -f xml -m new.xml -p old-trans.po > new-trans.po $ 用文本编辑器翻译new-trans.po $ po4a-translate -f xml -m new.xml -p new-trans.po -k 1 > new-trans.xml
关于本文
- 本文是在使用po文件翻译GuideXML的基础上修改而成的。原文版权声明转录如下:
- Date: 2007-01-28
- Version: 1.0
- Authors: 张乐
- Licence: 知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆 License
- 注1:这段文字引自文章:GNU gettext程序信息国际化解决方案,作者:权小红,常州信息职业技术学院软件学院,2009年8月。
结构化注释
每个翻译项都可能存在一些额外的信息,如一个翻译文本是从C程序里抽取出来的,可能就是需要说明这个从哪个源文件,哪个行抽取出来的。这些额外的信息通过结构注释来提供,用户可以定义自己的结构注释,当然GNU/Gettext工具集也定义了一组结构来表达相应信息。下面就针对这些GNU/Gettext定义的结构化注释结构进行讨论:
-
#
- 正常意义下的注释是开始于 “#” ,它后面紧跟着注释的文本。 #
- 翻译者留下的注释是开始于 “# ” ,也就是在“#”之后是一些空格。这样的注释是翻译者留下的,可能翻译都之间需要一个交流,或者需要告诉翻译者一些额外消息才它正确翻译。 #.
- 给翻译者的注释开始于“#.”。这些注释往往是程序员给翻译者留下的,往往是工具从源码中直接抽取出来的,所以双叫做“抽取的注释”。 #-
- 工具自动加入注释开始于“#-”。这些注释是工具为了保留额外信息的,这些信息将用于日后维护工作。 #:
- 对源码的引用注释开始于“#:”。这些注释是工具保留相应翻译项的来源。 #,
- 工具设置的一些标志注释开始于“#,”。这也提供额外信息的注释,往往用于表明程序文本是一个什么样的字符串,C语言的有转义的串,还是bash脚本里的串。 #|
- 之前的 msgid 通过开始于 “#|” 来表明。翻译译文本自身可能也存在一个更新过程,这个更新过程可能通过这个注释来体现。它存在的目的往往是为了给翻译者一个提醒,因为更新的文本可能与现在的文