舍得按:此文原载于舍得的新浪博客(http://blog.sina.com.cn/learningpower) 及舍得@学习力(http://blog.emagic.org.cn), 原文名为“SuperMemo UX汉化详解”,此次准备汉化SuperMemo UX 1.5.0.8版,将文章重新整理发布。

目录
一、反编译
二、汉化语言文件
三、汉化资源文件
四、编译
五、总结

 

一、反编译

目前舍得用过的最好的工具是DotNetHelper2.0,作者叫tracky,是个搞汉化的老手了.之前用过他的DotNetHelper 1.4,但没现在这个版本好用.用1.4做编译的时候,写回去的文件得手工再加上图标和版本信息,好在2.0把这个问题解决了,省了不少事.顺便说一下,DotNetHelper.exe也是编译用的工具,反编译是从源程序(SuperMemo.exe)中\"取出\"源代码和相关资源文件,而编译是将修改后的文件重新\"打包\"成SuperMemo程序,汉化就是在这过程中加点料而已.

DotNetHelper的版本信息

下面讲一讲具体操作:

运行DotNetHelper.exe,在程序的\"反编译\"区分别对程序文件和目标文件进行设置,如下图所示:

程序文件当然选supermemo.exe这个文件(只要点右侧带三个点的按钮,然后找到该文件即可,目标文件默认是放在跟supermemo.exe同一文件夹下的,考虑到反编译出来的文件较多,建议单独建立一个文件夹.这个il文件就是反编译出来的主文件,只不过它不是我们此次汉化的目标.

以上两项设置完后,其它保持默认,点击反编译按钮就可以去\"1.4.10.3\"这个文件夹里查看反编译后的文件了.

二、汉化语言文件

好几个朋友跟我说,你为什么不直接汉化德语或波兰语的资源文件,这样似乎在UX升级后可以省点事.舍得回答曰,这样最多只能省一半的事.在SuperMemo UX中,汉化是要分两步走的,一步是汉化它的语言文件,这个文件叫SMW.resources.Texts.xml,目前的版本大约有650行的内容要汉化;另一步是汉化它的资源文件,就是反编译出来的那一堆扩展名为resources的文件.这一步里的文件和朋友们提到的SuperMemo的资源文件是一致的,只是语言版本不同而已.从SuperMemo.exe里反编译出来的是英语,而从德语或波兰语的supermemo.resources.dll 文件中反编译出来的分别是德语和波兰语.既然SuperMemo汉化分成两个部分,这个SuperMemo.exe文件是无论如何都要汉化的.那汉化德语或波兰语文件就没有什么意义了.

SMW.resources.Texts文件样本

第一次\"汉化\"SMW.resources.Texts这个文件,是手工一行行翻译,总共约650行,确实有些麻烦.后来在网上看到Heartsome这款翻译软件,说可以把XML文件转成XLIFF格式,再调用翻译引擎进行汉化.于是舍得下载了一个 Heartsome,并制作了翻译记忆库,开始着手汉化,果然效率很高.如果翻译记忆库能做得更精确一些,那么基本上文件一转换后,需要翻译的地方就聊聊无几了!

用Heartsome汉化SMW.resources.Texts文件的方法,舍得在学苑中曾经发过一篇文章介绍过,这里就不再赘述了.

三、汉化资源文件

前面讲到,除了那个语言文件,要将 SuperMemo UX汉化,还必须汉化那些资源文件.1.4.10.3版的资源文件共计62个,其中最大的那个叫 SMW.Properties.Resources.resources,里面是程序用到的小图,这个不用汉化,还有6个文件里没有需要汉化的内容,因此,总共需要汉化的文件是55个.

第一次汉化UX的时候,用的是一款叫Resourcer的小工具,用它可以直接打开这些resources文件,然后一一找到需要汉化的地方进行汉化.手续很繁琐,而且这个小工具无法对字符进行搜索,所有的工作都是依赖肉眼查找,汉化完一次UX,眼睛都累得受不了.

舍得是个很习惯于偷懒的人,这种情况肯定是无法忍受的.于是放狗去网上搜.一番寻觅之后,果然被舍得找到两大神器,那就是.net自带的 RESGEN.exe和VS2008带的WINRES.exe这两个工具.严格地讲,后者还有点够不上\"神器\"的级别,因为现在舍得基本上用 RESGEN就可以搞定了.

RESGEN的主要作用是将resources文件转换为resx格式文件,这样就可以用记事本工具打开RESX进行汉化,然后再用RESGEN将resx转回到resources格式.通俗点讲就是用RESGEN先脱了它的马甲,汉化完再把马甲给它穿回去.具体的转换命令如下:

resources转resx:

resgen SMW.data.learn.LearningPlan.resources SMW.data.learn.LearningPlan.resx

resx转resources:

resgen SMW.data.learn.LearningPlan.resx SMW.data.learn.LearningPlan.resources

注意,resgen.exe文件最好跟resources文件放在同一个文件夹下.

转换得到resx后,用emeditor打开它(用普通记事本也行,那微软的记事本太垃圾),然后找\".Text\"\"和\".ToolTipText \"\"(注意多带个引号,查找会更准确些),查找结果的下一行”<value>”和\"</value>\"之间的就是我们要汉化的内容.如下图所示:

汉化1.4.6版的时候,舍得是一行行敲命令进行转换,再一行行转换回去,在汉化1.4.10.2时舍得在想,这方法太笨啦!直接写两个批处理文件不就完了?

操作起来也挺简单的,舍得先进入DOS界面,转到1.4.10.3文件夹(一般用\"在此处打开命令提示符\"),然后输入\"dir *.resources > resx.bat\",意思就是把所有resources文件的文件名存到resx.bat里,然后对resx.bat进行编辑,用正则表达式将它处理成 resources转resx的命令格式,用同样的方法做一个resx转resources的批处理,这样每次只要运行一下批处理文件就行,不用再一行行输入了.

汉化完1.4.10.2后,官方马上发布了1.4.10.3,这个更新速度确实教人咋舌.没办法,咱继续上吧.

现在手头有了1.4.10.2的汉化文件,那有没有什么方法可以偷懒呢?经过一些时间的思考和动手尝试,舍得找出了一个最最简单的汉化方式,用emeditor的宏来对这55个文件进行快速汉化!

说起来容易,操作起来还是有些复杂的.

舍得先尝试编写了一小段宏,得到这样的语句:

document.selection.Replace(\"(<data name=\\x22mCourseReset.Text\\x22 xml:space=\\x22preserve\\x22>\\\\n    <value>)Reset pro&amp;gress…(</value>)\",\"\\\\1重置进度\\(&amp;G\\)…\\\\2\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);

前面一段是英文原文,后面一段是中文,这样舍得只要提取每个文件相应的英文和译文,按上面这个宏的格式写出来就行了!

先用一个叫perfecta的宏(这个宏貌似是emeditor某个版本中带的,很管用)提取:

<data name=.*?Text\".*?$\\n.*?<value>.*?$\\n

意思就是从汉化前后的resx文件中提取需要汉化的部分内容,然后再编写两个宏分别对原文和译文提取出来的内容进行修整,原文处理的宏如下:

document.selection.Replace(\"\\x22\",\"\\\\\\\\x22\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"\\\\$\",\"\\\\\\\\$\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"\\\\(\",\"\\\\\\\\(\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"\\\\)\",\"\\\\\\\\)\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"<data name=\",\"document.selection.Replace(\\x22(<data name=\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"\\\\n    <value>\",\"\\\\\\\\\\\\\\\\n    <value>)\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"</value>\\\\n\",\"(</value>)\\x22,\\x22\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);

译文处理的宏如下:

document.selection.Replace(\"\\\\$\",\"\\\\\\\\$\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"\\\\(\",\"\\\\\\\\(\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"\\\\)\",\"\\\\\\\\)\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);document.selection.Replace(\"<data name.*?$\\\\n.*?<value>(.*?)</value>\\\\n\",\"\\\\\\\\\\\\\\\\1\\\\1\\\\\\\\\\\\\\\\2\\x22,eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);\",eeFindNext | eeFindReplaceCase | eeReplaceAll | eeFindReplaceRegExp);

把得到的两部分内容放到EXCEL合并一下,再稍作处理就变成了汉化用的宏.

因为有55个文件,舍得想让它根据文件名来自动选择相应的宏,于是在相应的宏中加入这样的判断:

if(regex == \"SMW.forms.MainForm.resx\"){}

大括号内就是MainForm用到的那一段宏,所有55个文件的宏都可以放在一起.

最后再给它加上每个文件自动保存和关闭的代码:

document.ReadOnly=false;editor.ExecuteCommandByID(4116);

这样这个宏就比较完善了.

用emeditor打开所有要汉化的resx文件,然后逐一运行上面做好的这个宏(其实就是运行55次),资源文件的汉化就基本搞定.

为保险起见,对resx文件进行一一检查,看有没有遗漏的地方,检查完后用批处理将其快速转换成resources文件即可.

 

四、编译

上述工作完成后,只要把这些文件编译成supermemo.exe,整个汉化工作就大功告成了.

编译分两个步骤:

1.生成强名

点击DotNetHelper2.0窗口下方的\"生成强名\"按钮:

然后输入一个文件名,比如说supermemo,就OK了.

2.编译

在编译框中分别设置\"IL文件\",\"资源文件\",\"强名文件\"和\"输出文件\",如下图所示:

其它的保持默认,可以勾选\"静默编译\"选项,然后点击编译按钮,就会生成一个supermemo_output.exe文件(你也可以在\"输出文件\"中指定为其它名字),只要把它改为supermemo.exe,放到SuperMemo UX的安装文件夹下,就可以使用中文版的SuperMemo UX了!

五、总结

这篇文章中涉及到的操作细节看起来繁琐,实际操作时还是比较简单的,总共就这么几步:

1.用DotNetHelper2进行反编译;

2.用HeartSome汉化SMW.resources.Texts文件;

3.用emeditor的宏汉化资源文件;

4.用DotNetHelper2编译;

相对较难的只有第2步.

 

本文版权归舍得英语魔法学苑所有,欢迎转载,转载请注明作者和出处。谢谢!

作者:舍得

首发:http://blog.sina.com.cn/learningpower