1818#
1919# ==========================================================================*/
2020
21- """ spell check the comments in code. """
21+ """spell check the comments in code."""
2222
2323import sys
2424import os
2929from pathlib import Path
3030from importlib .metadata import version , PackageNotFoundError
3131
32- from enchant .checker import SpellChecker
33- from enchant .tokenize import EmailFilter , URLFilter
34- from enchant import Dict
35-
3632from comment_parser import comment_parser
3733
38- try :
39- from comment_spell_check . lib import bibtex_loader
40- except ImportError :
41- from lib import bibtex_loader
34+ from spellchecker import SpellChecker
35+
36+ from lib import bibtex_loader
37+ from lib import create_checker
4238
4339__version__ = "unknown"
4440
@@ -113,13 +109,31 @@ def load_text_file(filename):
113109def spell_check_words (spell_checker : SpellChecker , words : list [str ]):
114110 """Check each word and report False if at least one has an spelling error."""
115111 for word in words :
116- if not spell_checker . check ( word ):
112+ if not ( word in spell_checker or word . lower () in spell_checker ):
117113 return False
118114 return True
119115
120116
117+ def find_misspellings (
118+ spell : SpellChecker , line : str , verbose : bool = False
119+ ) -> list [str ]:
120+ """Find misspellings in a line of text."""
121+
122+ l2 = re .sub (r"[^a-zA-Z]" , " " , line )
123+ words = l2 .split ()
124+
125+ mistakes = []
126+
127+ for word in words :
128+ if not (word .lower () in spell or word in spell ):
129+ if verbose :
130+ print (f"Misspelled word: { word } " )
131+ mistakes .append (word )
132+ return mistakes
133+
134+
121135def spell_check_comment (
122- spell_checker : SpellChecker ,
136+ spell : SpellChecker ,
123137 c : comment_parser .common .Comment ,
124138 prefixes : list [str ] = None ,
125139 output_lvl = 2 ,
@@ -129,12 +143,10 @@ def spell_check_comment(
129143 if output_lvl > 1 :
130144 print (f"Line { c .line_number ()} : { c } " )
131145
132- mistakes = []
133- spell_checker .set_text (c .text ())
134-
135- for error in spell_checker :
136- error_word = error .word
146+ bad_words = find_misspellings (spell , c .text (), verbose = output_lvl > 1 )
137147
148+ mistakes = []
149+ for error_word in bad_words :
138150 if output_lvl > 1 :
139151 print (f" Error: { error_word } " )
140152
@@ -150,8 +162,7 @@ def spell_check_comment(
150162 " Stripping contraction: "
151163 + f"{ original_error_word } -> { error_word } "
152164 )
153- if spell_checker .check (error_word ):
154- valid = True
165+ valid = error_word in spell
155166 break
156167
157168 if valid :
@@ -177,18 +188,13 @@ def spell_check_comment(
177188 if output_lvl > 1 :
178189 print (f" Trying without '{ pre } ' prefix: { error_word } -> { wrd } " )
179190 try :
180- if spell_checker .check (wrd ):
181- valid = True
182- else :
191+ valid = wrd in spell
192+ if not valid :
183193 # Try splitting camel case words and checking each sub-words
184194 if output_lvl > 1 :
185- print (f" Trying splitting camel case word: { wrd } " )
195+ print (" Trying splitting camel case word: {wrd}" )
186196 sub_words = split_camel_case (wrd )
187- if output_lvl > 1 :
188- print (" Sub-words: " , sub_words )
189- if len (sub_words ) > 1 and spell_check_words (
190- spell_checker , sub_words
191- ):
197+ if len (sub_words ) > 1 and spell_check_words (spell , sub_words ):
192198 valid = True
193199 break
194200 except TypeError :
@@ -201,11 +207,14 @@ def spell_check_comment(
201207 if output_lvl > 1 :
202208 print (f" Trying splitting camel case word: { error_word } " )
203209 sub_words = split_camel_case (error_word )
204- if len (sub_words ) > 1 and spell_check_words (spell_checker , sub_words ):
210+ if len (sub_words ) > 1 and spell_check_words (spell , sub_words ):
205211 continue
206212
207213 if output_lvl > 1 :
208- msg = f" Error: '{ error_word } ', suggestions: { spell_checker .suggest ()} "
214+ msg = (
215+ f" error: '{ error_word } ', "
216+ + f"suggestions: { spell .candidates (error_word )} "
217+ )
209218 else :
210219 msg = error_word
211220 mistakes .append (msg )
@@ -426,33 +435,33 @@ def add_dict(enchant_dict, filename, verbose=False):
426435 enchant_dict .add (wrd )
427436
428437
429- def create_spell_checker (args , output_lvl ):
430- """Create a SpellChecker."""
431-
432- my_dict = Dict ("en_US" )
433-
434- # Load the dictionary files
435- #
438+ def build_dictionary_list (args ):
439+ """build a list of dictionaries to use for spell checking."""
440+ dict_list = []
436441 initial_dct = Path (__file__ ).parent / "additional_dictionary.txt"
437- if not initial_dct .exists ():
438- initial_dct = None
442+
443+ if initial_dct .exists ():
444+ dict_list .append (initial_dct )
439445 else :
440- add_dict ( my_dict , str ( initial_dct ), any ([ args . brief , output_lvl >= 0 ]) )
446+ print ( "Warning: initial dictionary not found." , initial_dct )
441447
442- if args .dict is not None :
443- for d in args .dict :
444- add_dict (my_dict , d , any ([args .brief , output_lvl >= 0 ]))
448+ if not isinstance (args .dict , list ):
449+ return dict_list
445450
446- # Load the bibliography files
447- #
448- if args .bibtex is not None :
449- for bib in args .bibtex :
450- bibtex_loader .add_bibtex (my_dict , bib , any ([args .brief , output_lvl >= 0 ]))
451+ for d in args .dict :
452+ dpath = Path (d )
453+ if dpath .exists ():
454+ dict_list .append (dpath )
451455
452- # Create the spell checking object
453- spell_checker = SpellChecker (my_dict , filters = [EmailFilter , URLFilter ])
456+ return dict_list
454457
455- return spell_checker
458+
459+ def add_bibtex_words (spell , bibtex_files , verbose = False ):
460+ """Add words from bibtex files to the spell checker."""
461+ for bibtex_file in bibtex_files :
462+ if verbose :
463+ print (f"Loading bibtex file: { bibtex_file } " )
464+ bibtex_loader .add_bibtex (spell , bibtex_file , verbose = verbose )
456465
457466
458467def main ():
@@ -469,7 +478,12 @@ def main():
469478 if args .miss :
470479 output_lvl = - 1
471480
472- spell_checker = create_spell_checker (args , output_lvl )
481+ dict_list = build_dictionary_list (args )
482+
483+ spell = create_checker .create_checker (dict_list , output_lvl > 1 )
484+
485+ if args .bibtex :
486+ add_bibtex_words (spell , args .bibtex , verbose = output_lvl > 1 )
473487
474488 file_list = []
475489 if len (args .filenames ):
@@ -515,7 +529,7 @@ def main():
515529 print (f"\n Checking { x } " )
516530 result = spell_check_file (
517531 x ,
518- spell_checker ,
532+ spell ,
519533 args .mime_type ,
520534 output_lvl = output_lvl ,
521535 prefixes = prefixes ,
@@ -532,7 +546,7 @@ def main():
532546 # f is a file, so spell check it
533547 result = spell_check_file (
534548 f ,
535- spell_checker ,
549+ spell ,
536550 args .mime_type ,
537551 output_lvl = output_lvl ,
538552 prefixes = prefixes ,
0 commit comments