pmacs3/ispell.py

106 lines
2.8 KiB
Python

#!/usr/bin/env python
import os, sys
from subprocess import Popen, PIPE, STDOUT
import cache
_speller = None
_can_spell = os.system('which ispell > /dev/null 2>&1') == 0
def can_spell():
return _can_spell
def get_speller():
global _speller
if _can_spell and not _speller:
_speller = Speller()
return _speller
def free():
global _speller
if _speller:
_speller.stop()
_speller = None
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 = Popen('%s -a' % self.cmd, shell=True, stdin=PIPE, stdout=PIPE)
self.pipe.stdout.readline()
def stop(self):
self.pipe.stdin.close()
self.pipe.stdout.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:
res = self.pipe.poll()
if res is None or res >= 0:
self.pipe = None
self.start()
self.pipe.stdin.write(word.encode('utf-8') + b'\n') #"%s\n" % (word))
self.pipe.stdin.flush()
l = self.pipe.stdout.readline()
if l.startswith(b"*") or l.startswith(b"+") or l.startswith(b"-"):
result = True
while True:
l = self.pipe.stdout.readline()
if l == b"\n":
break
self.cache[word] = result
return result
def learn(self, word):
if self.pipe.poll() >= 0:
self.pipe = None
self.start()
self.pipe.stdin.write("*%s\n" % (word))
self.pipe.stdin.flush()
self.flush(word)
if __name__ == "__main__":
s = Speller()
while True:
sys.stdout.write('enter a word: ')
line = sys.stdin.readline()
if not line:
print()
break
elif line == '\n':
continue
elif ' ' in line:
print('please enter a single world')
continue
for word in line.split('-'):
word = word.strip()
if s.check(word):
print('%s: ok' % word)
else:
print('%s: misspelled' % word)