PageRenderTime 37ms CodeModel.GetById 20ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/python/engine/PinYin/QuanPin.py

http://scim-python.googlecode.com/
Python | 198 lines | 171 code | 2 blank | 25 comment | 1 complexity | ea563582f37f3c72924ea36599526202 MD5 | raw file
  1# -*- coding: utf-8 -*-
  2# vim: set noet ts=4:
  3#
  4# scim-python
  5#
  6# Copyright (c) 2007-2008 Yu Fan <yufanyufan@gmail.com>
  7#
  8#
  9# This library is free software; you can redistribute it and/or
 10# modify it under the terms of the GNU Lesser General Public
 11# License as published by the Free Software Foundation; either
 12# version 2 of the License, or (at your option) any later version.
 13#
 14# This library is distributed in the hope that it will be useful,
 15# but WITHOUT ANY WARRANTY; without even the implied warranty of
 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17# GNU Lesser General Public License for more details.
 18#
 19# You should have received a copy of the GNU Lesser General Public
 20# License along with this program; if not, write to the
 21# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 22# Boston, MA  02111-1307  USA
 23#
 24# $Id: $
 25#
 26
 27from ZhengJu import *
 28import scim
 29import os
 30from scim import KeyCode
 31from scim import KeyMask
 32from scim import Property
 33import traceback
 34import sys
 35from PYDict import *
 36from gettext import dgettext
 37
 38_ = lambda a : dgettext ("scim-python", a)
 39strip = lambda a: a if a == "" or a == "'" or a[0]!="'" else a[1:]
 40class QuanPinEngine(Engine):
 41	def __init__ (self, factory, config, encoding, id):
 42		Engine.__init__(self, factory, config, encoding, id)
 43
 44	def clear(self):
 45		self.extra_string = ""
 46		Engine.clear(self)
 47
 48	def get_extra_string(self):
 49		return self.extra_string
 50
 51	def is_valid_head(self, str):
 52		#~ print str
 53		if str == "'" or strip(str)[0] in SHENGMU_LIST and (strip(str) in PINYIN_LIST or strip(str) in PINYIN_PARTIAL_LIST):
 54			return True
 55		for i in range(len(str), 0, -1):
 56			if strip(str)[0] in SHENGMU_LIST and strip(str[:i]) in PINYIN_LIST:
 57				return True
 58		return False
 59
 60	def split(self, strs):
 61		if strip(strs) in PINYIN_LIST \
 62			or strip(strs) in PINYIN_PARTIAL_LIST	\
 63			or strip(strs) in SHENGMU_LIST \
 64			or strs == "'":
 65			yield (strs,  "")
 66		else:
 67			for i in range(len(strs), 0, -1):
 68				if strs[:i][-1] == "'":
 69					continue
 70				if strip(strs[:i]) in PINYIN_LIST:
 71					yield ( strs[:i], strs[i:] )
 72					if strip(strs[:i-1]) in PINYIN_LIST and strip(strs[:i])[-1] in SHENGMU_LIST and self.is_valid_head(strs[i-1:]):
 73						yield ( strs[:i-1], strs[i-1:])
 74					break
 75
 76	def recursive_parse(self, str):
 77		for (word, strleft) in self.split(str):
 78			if strleft:
 79				for pinyinlist in self.recursive_parse(strleft):
 80					yield [word] + pinyinlist
 81			else:
 82				yield [word]
 83		
 84	def process_pinyin(self, c):
 85		p = u"".join( i.get_screen_pinyin() for i in self._editor.pinyinlist) + c
 86		all =  list(self.recursive_parse(p))
 87		if not all:
 88			raise InputException()
 89		min_len = 100
 90		freq = 0
 91		for q in all:
 92			pinyinlist = []
 93			for i in q:
 94				#~ print i,
 95				pinyinlist.append(PinYinWord(pinyin=i))
 96			#~ print len(pinyinlist)
 97			predicts = self._editor.get_predict_pinyinlist(pinyinlist)
 98			#~ print len(predicts)
 99			if len(predicts) < min_len:
100				min_len = len(predicts)
101				#~ freq = sum([i[ADJ_FREQ] for i in predicts])
102				if len(predicts)>1:
103					freq = self._editor.freq_alg(predicts[0],predicts[1])
104				else:
105					freq = predicts[0][ADJ_FREQ]
106				#~ print freq
107				best = (pinyinlist,predicts)
108			elif len(predicts) == min_len:
109					if len(predicts)>1:
110						tfreq = self._editor.freq_alg(predicts[0],predicts[1])
111					else:
112						tfreq = predicts[0][ADJ_FREQ]
113					#~ print tfreq
114					if tfreq > freq:
115						freq = tfreq
116					best = (pinyinlist,predicts)
117		self._editor.pinyinlist = best[0]
118		self._editor.predict = best[1]
119
120	def chinese_process_key_event (self, key):
121		if key.mask == KeyMask.NullMask and (\
122			(key.code >= KeyCode.KEY_a and key.code <= KeyCode.KEY_z) or \
123			key.code == KeyCode.KEY_apostrophe):
124			self.process_pinyin(unichr (key.code))
125			self._editor.auto_convert_quanpin ()
126			return True
127		elif self._editor.pinyinlist and key.code == KeyCode.KEY_BackSpace:
128			p = self._editor.pinyinlist[-1].get_screen_pinyin()
129			if len(p)>1:
130				self._editor.pinyinlist[-1].set_pinyin(p[:-1])
131			else:
132				del self._editor.pinyinlist[-1]
133			self._editor.update ()
134			return True
135		elif (self.extra_string or self._editor.pinyinlist) and (key.code == KeyCode.KEY_Left or (key.code == KeyCode.KEY_b and key.mask & KeyMask.ControlMask)):
136			if self._editor.pinyinlist:
137				p = self._editor.pinyinlist[-1].get_screen_pinyin()
138				self.extra_string = p + self.extra_string
139				del self._editor.pinyinlist[-1]
140				self._editor.update ()
141			return True
142		elif (self.extra_string or self._editor.pinyinlist) and (key.code == KeyCode.KEY_Right or (key.code == KeyCode.KEY_f and key.mask & KeyMask.ControlMask)):
143			if self.extra_string:
144				#~ print self.extra_string[0]
145				self.process_pinyin( self.extra_string[0])
146				self.extra_string = self.extra_string[1:]
147				self._editor.auto_convert_quanpin ()
148			else:
149				self.extra_string = u"".join( i.get_screen_pinyin() for i in self._editor.pinyinlist)
150				self._editor.pinyinlist = []
151				self._editor.update()
152			return True
153		elif self.extra_string and key.code == KeyCode.KEY_Delete:
154			if self.extra_string:
155				self.extra_string = self.extra_string[1:]
156				return True
157			else:
158				raise InputException()
159		elif self.extra_string and key.code in (KeyCode.KEY_KP_Space, KeyCode.KEY_space):
160			p = u"".join( i.get_screen_pinyin() for i in self._editor.pinyinlist)
161			c = ""
162			while True:
163				c += self.extra_string[0]
164				if list(self.recursive_parse(p+c)):
165					self.extra_string = self.extra_string[1:]
166				else:
167					break				
168				if not self.extra_string:
169					break
170			if c:
171				while c:
172					self.process_pinyin(c[0])
173					self._editor.auto_convert_quanpin ()
174					c = c[1:]
175				return True
176			else:
177				raise InputException()
178		elif Engine.chinese_process_key_event (self,key):
179			return True;
180		return False
181
182class QuanPinFactory (IMEngineFactory):
183	def __init__ (self, config):
184		IMEngineFactory.__init__ (self, config)
185		self.name 		= _(u"QuanPin")
186		self.uuid 		= "00c1690f-214c-447c-be18-1db199bae183"
187		self.authors	= u"Yu Fan <yufanyufan@gmail.com>"
188		self.icon_file 	= "/usr/share/scim/icons/scim-python.png"
189		self.credits 	= u"GPL"
190		self.help		= _(u"Help For QuanPin")
191		self.set_languages ("zh")
192		self._config	= config
193	def create_instance (self, encoding, id):
194		engine =  QuanPinEngine (self, self._config, encoding, id)
195		return engine
196
197	def reload_config (self, config):
198		pass