OLD | NEW |
1 # ##### BEGIN GPL LICENSE BLOCK ##### | 1 # ##### BEGIN GPL LICENSE BLOCK ##### |
2 # | 2 # |
3 # This program is free software; you can redistribute it and/or | 3 # This program is free software; you can redistribute it and/or |
4 # modify it under the terms of the GNU General Public License | 4 # modify it under the terms of the GNU General Public License |
5 # as published by the Free Software Foundation; either version 2 | 5 # as published by the Free Software Foundation; either version 2 |
6 # of the License, or (at your option) any later version. | 6 # of the License, or (at your option) any later version. |
7 # | 7 # |
8 # This program is distributed in the hope that it will be useful, | 8 # This program is distributed in the hope that it will be useful, |
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 # GNU General Public License for more details. | 11 # GNU General Public License for more details. |
12 # | 12 # |
13 # You should have received a copy of the GNU General Public License | 13 # You should have received a copy of the GNU General Public License |
14 # along with this program; if not, write to the Free Software Foundation, | 14 # along with this program; if not, write to the Free Software Foundation, |
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 # | 16 # |
17 # ##### END GPL LICENSE BLOCK ##### | 17 # ##### END GPL LICENSE BLOCK ##### |
18 | 18 |
19 # <pep8 compliant> | 19 # <pep8 compliant> |
20 | 20 |
21 import enchant | |
22 import os | |
23 import pickle | |
24 import re | 21 import re |
25 | 22 |
26 | 23 |
27 class SpellChecker(): | 24 _valid_before = "(?<=[\\s*'\"`])|(?<=[a-zA-Z][/-])|(?<=^)" |
28 """ | 25 _valid_after = "(?=[\\s'\"`.!?,;:])|(?=[/-]\\s*[a-zA-Z])|(?=$)" |
29 A basic spell checker. | 26 _valid_words = "(?:{})(?:(?:[A-Z]+[a-z]*)|[A-Z]*|[a-z]*)(?:{})".format(_valid_be
fore, _valid_after) |
30 """ | 27 _reg = re.compile(_valid_words) |
| 28 |
| 29 |
| 30 def split_words(text): |
| 31 return [w for w in _reg.findall(text) if w] |
| 32 |
31 | 33 |
32 # These must be all lower case for comparisons | 34 # These must be all lower case for comparisons |
33 uimsgs = { | 35 dict_uimsgs = { |
34 # OK words | 36 # OK words |
35 "aren", # aren't | 37 "aren", # aren't |
36 "betweens", # yuck! in-betweens! | 38 "betweens", # yuck! in-betweens! |
37 "boolean", "booleans", | 39 "boolean", "booleans", |
38 "couldn", # couldn't | 40 "couldn", # couldn't |
39 "decrement", | 41 "decrement", |
40 "derivate", | 42 "derivate", |
41 "doesn", # doesn't | 43 "doesn", # doesn't |
42 "fader", | 44 "fader", |
43 "hasn", # hasn't | 45 "hasn", # hasn't |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 "targa", "tga", | 526 "targa", "tga", |
525 "tiff", | 527 "tiff", |
526 "theora", | 528 "theora", |
527 "vorbis", | 529 "vorbis", |
528 "wav", | 530 "wav", |
529 "xiph", | 531 "xiph", |
530 "xml", | 532 "xml", |
531 "xna", | 533 "xna", |
532 "xvid", | 534 "xvid", |
533 } | 535 } |
534 | |
535 _valid_before = "(?<=[\\s*'\"`])|(?<=[a-zA-Z][/-])|(?<=^)" | |
536 _valid_after = "(?=[\\s'\"`.!?,;:])|(?=[/-]\\s*[a-zA-Z])|(?=$)" | |
537 _valid_words = "(?:{})(?:(?:[A-Z]+[a-z]*)|[A-Z]*|[a-z]*)(?:{})".format(_vali
d_before, _valid_after) | |
538 _split_words = re.compile(_valid_words).findall | |
539 | |
540 @classmethod | |
541 def split_words(cls, text): | |
542 return [w for w in cls._split_words(text) if w] | |
543 | |
544 def __init__(self, settings, lang="en_US"): | |
545 self.settings = settings | |
546 self.dict_spelling = enchant.Dict(lang) | |
547 self.cache = set(self.uimsgs) | |
548 | |
549 cache = self.settings.SPELL_CACHE | |
550 if cache and os.path.exists(cache): | |
551 with open(cache, 'rb') as f: | |
552 self.cache |= set(pickle.load(f)) | |
553 | |
554 def __del__(self): | |
555 cache = self.settings.SPELL_CACHE | |
556 if cache and os.path.exists(cache): | |
557 with open(cache, 'wb') as f: | |
558 pickle.dump(self.cache, f) | |
559 | |
560 def check(self, txt): | |
561 ret = [] | |
562 | |
563 if txt in self.cache: | |
564 return ret | |
565 | |
566 for w in self.split_words(txt): | |
567 w_lower = w.lower() | |
568 if w_lower in self.cache: | |
569 continue | |
570 if not self.dict_spelling.check(w): | |
571 ret.append((w, self.dict_spelling.suggest(w))) | |
572 else: | |
573 self.cache.add(w_lower) | |
574 | |
575 if not ret: | |
576 self.cache.add(txt) | |
577 | |
578 return ret | |
OLD | NEW |