import os, popen2 import cache _speller = None _can_spell = os.system('which ispell > /dev/null 2>&1') == 0 def can_spell(): global _can_spell return _can_spell def get_speller(): global _speller return _speller class Speller(object): def __init__(self, cmd='ispell'): self.pipe = None self.cache = cache.CacheDict() self.cmd = cmd self.start() def start(self): assert self.pipe is None self.pipe = popen2.Popen3('%s -a' % self.cmd, 'rw') self.pipe.childerr.close() self.pipe.fromchild.readline() def stop(self): self.pipe.tochild.close() self.pipe.fromchild.close() self.pipe = None def restart(self): self.stop() self.start() def flush(self, word): if word in self.cache: del self.cache[word] def check(self, word, caps=False, title=True): # here are some quick checks: # 1. zero-length words # 2. all-caps word # 3. words whose first letter is capitalized if len(word) == 0: return True elif not caps and word.isupper(): return True elif not title and word[0].isupper(): return True result = False if word in self.cache: result = self.cache[word] else: if self.pipe.poll() >= 0: self.pipe = None self.start() self.pipe.tochild.write("%s\n" % (word)) self.pipe.tochild.flush() l = self.pipe.fromchild.readline() if l.startswith("*") or l.startswith("+") or l.startswith("-"): result = True while True: l = self.pipe.fromchild.readline() if l == "\n": break self.cache[word] = result return result def learn(self, word): if self.pipe.poll() >= 0: self.pipe = None self.start() self.pipe.tochild.write("*%s\n" % (word)) self.pipe.tochild.flush() self.flush(word) if _can_spell: _speller = Speller()