在windows下使用的sougou输入法,除了经常弹出广告,没有什么异常行为,Linux下的中文输入法似乎没那么强大好用了。起初用的是Ibus中的pinyin,后来因为机缘巧合装了yong输入法,发现挺好用的,就一直用着。渐渐的发现yong输入法在一些自由软件中不起作用,有时还行为诡异,虽然大多数的时候,工作的很正常。本着程序员好奇的心态,我想打开输入法这个黑匣子,看看里面有些什么。
输入法的工作原理是击键消息(window中消息)首先送给输入法管理器(前端),输入法管理器调用输入法的转换函数(输入法引擎),输入法的转换函数得到击键消息并保存在自己的数组中,当符合规定条件时(如五笔输入法输入:四键、两键+空格等),输入法把适当的字、词返回给输入法管理器,输入法管理器再把结果字、词传给关联的应用窗口。
简单的来说,输入法就是一个查表操作,输入的信息是键盘信息,根据击键消息到表中查找对应的汉字。举个例子:将码表导入到Excel。假设码表是基于拼音的,码表分两列,一列是拼音,一列是汉字串,那么用鼠标点击编辑->查找,在查找内容框中敲入shishi,点击查找下一个按钮,黑色矩形框立即就跳到A列的shishi的行上面,对应的B列就是“试试、事事、实施、时世、史实……”等等这些汉字串,输入法的原理就是这样[2]。PS:计算机程序中都可以简化为查表程序,这个表可能是数组,字符串或者数据库。表驱动编程本质上就是从数据的角度出发,根据数据来编程(参考《代码大全 第二版》)。
由于输入法编程中涉及消息处理机制,而消息处理机制是操作系统的核心机制,理解起来比较麻烦。但是,“学习输入法编程,要带着问题学,活学活用,学用结合,急用先学,立杆见影,在“用”字上狠下功夫。为了把输入法编程的精髓真正学到手,要反复学习输入法编程的结构和算法,有些概念、算法最好要背熟,反复学习,反复运用。”[2] PS:这段话可以简化为:世上无难事,只要肯攀登。
关于在windows下学习输入法编程的资料搜集如下:
1.输入法工作原理:http://blog.csdn.net/shuilan0066/article/details/6883629
2.输入法漫谈:http://wenku.baidu.com/view/3d179422bcd126fff7050b9d.html(备注:原文发布在某论坛上,地址为:)
Linux下的输入法框架无非Scim/Ibus/Fcitx这三类。在网上搜了一通,仅发现一篇关于Scim工作原理的论文,ibus和fcitx都是相应的google代码库,估计源码和文档都应该很全。个人感觉,用scim的人不如ibus和fcitx多了,开发也不及后两者了。但是scim有这么一篇2页的论文,省去看ibus之类的文档和源码,而且既然同样都是输入法框架,总会存在一些共性的特征,相差不到那里去。
基于XIM结构的输入法与X Windows系统结合过于紧密,无法支持国际化语言环境,SCIM就是针对这些问题的。Smart Common Input Method(SCIM),SCIM输入法架构的优越性: 1.支持语言多 2.面向对象设计 3.高度模块化,功能模块,插件形式 4 编程接口简单 5. 独立于图形界面,便于开发和移植
SCIM包含的模块:
在SCIM中,输入法有三大功能模块:前端(FrontEnd),引擎(IMEngine)和后端(BackEnd)。这三大模块分别实现的功能是:
FrontEnd:主要负责用户界面的显示,以及与客户程序进行交互,将客户程序的按键请求转发给IMEngine,执行IMEngine发出的各种命令,如绘制预编辑字符串等等。FrontEndBase基类负责管理所有IMEngineInstance实例。
IMEngine:接收FrontEnd发送的按键事件,然后向FrontEnd发送相应的命令,如显示预编辑字符串、向客户程序提交字符串等等。
BackEnd:管理所有的IMEngine。如全拼、双拼、五笔、手写等。
在SCIM中最关键的部分是FrontEnd和IMEngine。这两部分的实现及其之间的通讯方式(本地socket)是SCIM较其它输入法平台最不同的地方。
FrontEnd主要完成用户界面的绘制、与客户应用程序交互,FrontEndBase基类负责管理所有IMEngineInstance实例这三方面工作。每个IMEngineInstance 实例用唯一的id进行标识,FrontEndBase类提供的函数和IMEngineInstance的id完成对IMEngineInstance的所有操作。FrontEnd派生类不需直接处理IMEngineInstance实例或者其指针。
IMEngine分为IMEngineFactory和IMengineInstance两个接口类。要实现具体的输入法,比如纵横汉字输入法,就必须提供这两个类的具体实现。IMengineFactory除了负责管理如词库等的输入法涉及的公共数据,还负责创建IMEngineInstance实例。IMEngineInstance类则负责把实际的按键转换为字符串。
FrontEnd和IMEngine之间的数据通信采用了一种松散的接口形式,即signal-slot技术,这样的方式可以简化编程接口。输入法引擎所需的所有动作都经由signal-slot发送给FrontEnd,而输入法引擎需要处理的事件则直接由FrontEnd调用IMEngineInstance类的相应函数来传递。
参考[4]的论文中存在一些文字错误,重复以及术语的前后不一致,明显有整合和拼凑的感觉,看了一下其参考文献,百度文库和一篇csdn的博客赫然在列,让我对该中文期刊的质量表示怀疑,去看了一下引用的源后,果然是整合的,前半截+图来自文库,后半截来自博客,对于这种拼接法搞学术,表示强烈的鄙视,虽然我也经常干这种事情,但是我copy & paste的技术绝对比他们好,感觉有点五十步笑百步。
强烈建立参考原出处,原出处的文章具有一致性和连贯性,不是拼接的,而且更加图文并茂:
1.SCIM输入法架构分析(上)http://blog.csdn.net/absurd/article/details/1151404
2.SCIM输入法架构分析(下)http://blog.csdn.net/absurd/article/details/1151524
Intelligent Input BUS(iBus)是一个输入法平台,可以理解为是一个已经写好的与系统交互的库,各种输入法运行在iBus上。iBus曾经是Python写的,现在已经用C++重写,效率得到很大的提高,兼容性要远远强于Scim。iBus可以让程序员专心地编写输入法功能的代码,而不是把过多的精力浪费在与系统交互上,从而增强输入法的可移植性。
Ibus的wiki上的介绍:http://en.wikipedia.org/wiki/Intelligent_Input_Bus (百度百科上的介绍过时太久了)
Ibus在Ubuntu系统上安装:http://wiki.ubuntu.org.cn/IBus
Ibus项目地址:http://code.google.com/p/ibus/
Fcitx的wiki介绍:http://en.wikipedia.org/wiki/Fcitx
Fcitx还和搜狗合作开发Linux上的搜狗输入法,其在Ubuntu(Linux Mint)的安装参考http://1.techblog.sinaapp.com/?p=283#more-283
Fcitx的google项目地址:http://code.google.com/p/fcitx/
Fcitx的GitHub地址:https://github.com/fcitx/fcitx
Fcitx的安装:http://wiki.ubuntu.org.cn/Fcitx
Yong输入法基于ibus的,但是又和Ibus上的输入法ibus-pinyin之类的不太一样。
输入法论坛及下载:http://yong.dgod.net/
安装可参考:http://blog.csdn.net/xiajian2010/article/details/9625131
具体的,我也不是特明白其实现机制,先留给伏笔,等以后我明白了再加。
仔细查看了yong提供的帮助和相关的文档,发现在当前Home目录下的.yong中存在这样的一个文件pinyin.usr,打开后可以看到如下模式的文本:
{0}aihe 爱喝 {-}anquanjiang 安全将 {0}anshenye 安神液 {0}ansong 暗送 {0}aojiao 傲骄 {0}badi 拔地 {0}baiban 白板 {0}bailv 百虑 {0}baishikuai 百十块 {0}baiyou 柏油 {1}baiyou 柏由 {0}baiyulan 白玉兰 |
在看到有一些自己常用的输入后,想到yong的帮助提到的造词和删词的功能(快捷键操作太难用),估计就是通过在文件中设置{}中的数字实现,{-}表示删除,{0}或{1}行为不太明白,在文件中添加新词表示造词。修改该文件后,发现并没有能禁止,将yong进程杀死,再重启就起效了,看来yong默认会将该文件加载到内存中去,回想上面介绍的输入法就是查表操作,这个pinyin.usr就是这样的表,除了这个表以外,还有个pinyin的主表是安装目录yong/mb/下的pinyin.txt和pypre.bin,打开pinyin.txt后,其文件内容是:
name=ƴ?? key=abcdefghijklmnopqrstuvwxyz len=63 wildcard=? pinyin=1 split=' hint=0 user=pinyin.usr assist=mb/yong.txt 2 code_a1=p.. [DATA] a ?? ?? ?? ?? ?? ?? ߹ aba ???? adou ???? aduwu ?????? |
在[DATA]目录下的字母对应的字符为不可识别,估计是对怕pypre.bin中的二进制的数据的索引,但又觉得不太像。
根据帮助文档的,将一些不需要的文件删除了,只剩下3M了,同样也能工作,感觉非常好。安装目录yong保留的文件如下:
yong目录下的:libl.so(基础库),libmb.so(码表库),yong(主程序),yong.conf(配置文件),yong.ini,yong-tool.sh(安装卸载脚本),yong.chm(帮助文档),keyboard.ini(软件盘配置文件),normal.txt
skin目录全部保留
mb目录只保留我需要的拼音输入法(pinyin.ini,pinyin.txt,pypre.bin)和english.txt
gtk-im目录下的动态连接库也需要保留,不然连输入框都不显示。
yong-config二进制程序也要保留,这个图形配置界面的程序。
备注:看到yong官方将输入法更新到了2.1,不清楚作者怎么设置版本号的,试用了一段时间,发现很不稳定,常常打字不上屏,害我要将进程杀死再重启,相当麻烦,我又退回1.7,用了很久,非常稳定。
本来想好好的了解一下输入法,以及我使用的Yong输入法的,结果只是在搜集资料,了解一些很宽范的东西。在搜集资料的时候,看到一个关于学习方法的观点:重基础胜于技巧,看书胜于看杂志,看代码胜于看文章,和朋友讨论胜于上论坛,写BLOG胜于看BLOG,以及学习方法无好坏之分,只有合适不合适之分,所谓天下殊途同归,一致百虑。
二手文献和原始文献之间,存在一条加工的沟,而且并不是所有的二手文献都比原始文献好。
Linux Mint的界面蛮好看的,有机会尝试一下。
[1]SCIM输入法架构分析:http://wenku.baidu.com/view/a33b1484bceb19e8b8f6baea.html
[2]输入法漫谈:http://wenku.baidu.com/view/3d179422bcd126fff7050b9d.html
[3]关于Ibus拼音的开发:https://www.byvoid.com/blog/join-develop-ibus-pinyin/
[4]SCIM输入法架构及其工作原理,王丽君,李培峰,China Academic Journal Electronic Publishing House
[5] 我的学习方法:http://blog.csdn.net/absurd/article/details/6475353