class TestSpellChecker(unittest.TestCase): def setUp(self): self.spellChecker = SpellChecker() self.spellChecker.load_words('spell.words') def test_spell_checker(self): self.assertTrue(self.spellChecker.check_word('zygotic')) failed_words = self.spellChecker.check_words( 'zygotic mistasdas elementary') self.assertEquals(1, len(failed_words)) self.assertEquals('mistasdas', failed_words[0]['word']) self.assertEquals(1, failed_words[0]['line']) self.assertEquals(9, failed_words[0]['pos']) self.assertEquals( 0, len(self.spellChecker.check_words('our first correct sentence'))) # handle case sensitivity self.assertEquals( 0, len(self.spellChecker.check_words('Our capital sentence'))) # handle full stop self.assertEquals( 0, len(self.spellChecker.check_words('Our full stop sentence.'))) failed_words = self.spellChecker.check_words( 'zygotic mistasdas spelllleeeing elementary') self.assertEquals(2, len(failed_words)) self.assertEquals('mistasdas', failed_words[0]['word']) self.assertEquals(1, failed_words[0]['line']) self.assertEquals(9, failed_words[0]['pos']) self.assertEquals('spelllleeeing', failed_words[1]['word']) self.assertEquals(1, failed_words[1]['line']) self.assertEquals(19, failed_words[1]['pos']) self.spellChecker.check_document('stuff.txt')
class TestSpellChecker(unittest.TestCase): def setUp(self): self.spellChecker = SpellChecker() self.spellChecker.load_words('spell.words') def test_spell_checker(self): self.assertTrue(self.spellChecker.check_word('zygotic')) failed_words = self.spellChecker.check_words( 'zygotic mistasdas elementary') self.assertEquals(1, len(failed_words)) self.assertEquals('mistasdas', failed_words[0]) self.assertEquals(0, len(self.spellChecker.check_words( 'our first correct sentence'))) # handle case sensitivity self.assertEquals(0, len(self.spellChecker.check_words( 'Our first correct sentence'))) # handle full stop self.assertEquals(0, len(self.spellChecker.check_words( 'Our first correct sentence.'))) failed_words = self.spellChecker.check_words( 'zygotic mistasdas spelllleeeing elementary') self.assertEquals(2, len(failed_words)) self.assertEquals('mistasdas', failed_words[0]) self.assertEquals('spelllleeeing', failed_words[1]) # more bugs because the spell checker doesn't spell check itself correctly 21 entries not correct dictionary words need to be lower self.assertEqual(0, len(self.spellChecker.check_document('spell.words')))
class TestSpellChecker(unittest.TestCase): def setUp(self): self.spellChecker = SpellChecker() # This is the path name for our dictionary file file_name = '/Users/barrysheppard/Github/DBSDataAnalysis/' file_name = file_name + 'BigData/04Lecture/spell.words' self.spellChecker.load_words(file_name) def test_spell_checker(self): self.assertTrue(self.spellChecker.check_word('zygotic')) failed_words = self.spellChecker.check_words('zygotic mistasdas elementary') self.assertEqual(1, len(failed_words)) self.assertEqual('mistasdas', failed_words[0]['word']) self.assertEqual(1, failed_words[0]['line']) self.assertEqual(9, failed_words[0]['pos']) self.assertEqual(0, len(self.spellChecker.check_words('our first correct sentence'))) # handle case sensitivity self.assertEqual(0, len(self.spellChecker.check_words('Our capital sentence'))) # handle full stop self.assertEqual(0, len(self.spellChecker.check_words('Our full stop sentence.'))) failed_words = self.spellChecker.check_words('zygotic mistasdas spelllleeeing elementary') self.assertEqual(2, len(failed_words)) self.assertEqual('mistasdas', failed_words[0]['word']) self.assertEqual(1, failed_words[0]['line']) self.assertEqual(9, failed_words[0]['pos']) self.assertEqual('spelllleeeing', failed_words[1]['word']) self.assertEqual(1, failed_words[1]['line']) self.assertEqual(19, failed_words[1]['pos']) self.assertEqual(0, len(self.spellChecker.check_document('spell.words')))
class SpellCheckerTestCase(unittest.TestCase): def setUp(self): self.checker = SpellChecker() def test_complete(self): self.assertEqual(self.checker.complete(''), [ 'I', 'The', "I'm", 'You', 'My', 'It', 'But', 'If', 'This', "It's", 'And', 'So', 'He', 'A', 'Just', 'In', 'We', 'What', 'Why', 'No' ]) def test_correct(self): self.assertEqual(self.checker.correct('wrrong'), 'wrong') def test_guess(self): self.assertEqual(self.checker.guess('aa'), ['as', 'era'])
def init(self, file, context): """ @param file: base.File @param context: base.WindowContext """ self._log.debug("init(%s)" % file) self._file = file self._context = context self._preferences = Preferences() self._preferences.register_monitor( self) # listen to 'Show...InOutline' settings self.register_marker_type( "latex-spell", self._preferences.get("SpellingBackgroundColor"), anonymous=False) self.register_marker_type( "latex-error", self._preferences.get("ErrorBackgroundColor")) self.register_marker_type( "latex-warning", self._preferences.get("WarningBackgroundColor")) self._issue_view = context.find_view(self, "IssueView") self._outline_view = context.find_view(self, "LaTeXOutlineView") self._parser = LaTeXParser() self._outline_generator = LaTeXOutlineGenerator() self._validator = LaTeXValidator() self._document = None self._document_dirty = True # if the document is no master we display an info message on the packages to # include - _ensured_packages holds the already mentioned packages to not # annoy the user self._ensured_packages = [] # spell checking self.__spell_checker = SpellChecker() # # initially parse # self._change_reference = self.initial_timestamp self.__parse() self.__update_neighbors()
def init(self, file, context): """ @param file: base.File @param context: base.WindowContext """ self._log.debug("init(%s)" % file) self._file = file self._context = context self._preferences = Preferences() self._preferences.register_monitor(self) # listen to 'Show...InOutline' settings self.register_marker_type("latex-spell", self._preferences.get("SpellingBackgroundColor"), anonymous=False) self.register_marker_type("latex-error", self._preferences.get("ErrorBackgroundColor")) self.register_marker_type("latex-warning", self._preferences.get("WarningBackgroundColor")) self._issue_view = context.find_view(self, "IssueView") self._outline_view = context.find_view(self, "LaTeXOutlineView") self._parser = LaTeXParser() self._outline_generator = LaTeXOutlineGenerator() self._validator = LaTeXValidator() self._document = None self._document_dirty = True # if the document is no master we display an info message on the packages to # include - _ensured_packages holds the already mentioned packages to not # annoy the user self._ensured_packages = [] # spell checking self.__spell_checker = SpellChecker() # # initially parse # self._change_reference = self.initial_timestamp self.__parse() self.__update_neighbors()
class LaTeXEditor(Editor, IIssueHandler, IMisspelledWordHandler, IPreferencesMonitor): _log = getLogger("LaTeXEditor") #extensions = [".tex"] extensions = Preferences().get("LatexExtensions", ".tex").split(" ") dnd_extensions = [".png", ".pdf", ".bib", ".tex"] @property def completion_handlers(self): self.__latex_completion_handler = LaTeXCompletionHandler() self.__snippet_completion_handler = SnippetCompletionHandler() return [ self.__latex_completion_handler, self.__snippet_completion_handler ] def init(self, file, context): """ @param file: base.File @param context: base.WindowContext """ self._log.debug("init(%s)" % file) self._file = file self._context = context self._preferences = Preferences() self._preferences.register_monitor( self) # listen to 'Show...InOutline' settings self.register_marker_type( "latex-spell", self._preferences.get("SpellingBackgroundColor"), anonymous=False) self.register_marker_type( "latex-error", self._preferences.get("ErrorBackgroundColor")) self.register_marker_type( "latex-warning", self._preferences.get("WarningBackgroundColor")) self._issue_view = context.find_view(self, "IssueView") self._outline_view = context.find_view(self, "LaTeXOutlineView") self._parser = LaTeXParser() self._outline_generator = LaTeXOutlineGenerator() self._validator = LaTeXValidator() self._document = None self._document_dirty = True # if the document is no master we display an info message on the packages to # include - _ensured_packages holds the already mentioned packages to not # annoy the user self._ensured_packages = [] # spell checking self.__spell_checker = SpellChecker() # # initially parse # self._change_reference = self.initial_timestamp self.__parse() self.__update_neighbors() def _on_value_changed(self, key, new_value): # see preferences.IPreferencesMonitor._on_value_changed if key in [ "ShowLabelsInOutline", "ShowTablesInOutline", "ShowGraphicsInOutline" ]: # regenerate outline model if self._document_is_master: self._outline = self._outline_generator.generate( self._document, self) self._outline_view.set_outline(self._outline) else: # FIXME: self._document contains the full model of child and master # so we may not use it for regenerating the outline here self.__parse() elif key == "ShowLatexToolbar": show_toolbar = self._preferences.get_bool("ShowLatexToolbar", True) if show_toolbar: self._window_context._window_decorator._toolbar.show() else: self._window_context._window_decorator._toolbar.hide() def _ctrl_left_clicked(self, it): """ For synchronization by synctex """ # Editor._ctrl_left_clicked tab = self.tab_decorator.tab line = it.get_line() + 1 column = it.get_line_offset() + 1 source_file = "%s/%s" % (self._file.dirname, self._file.basename) # We use self.file and not self._file here, to get the # master document, because the output file will have the # name of the master document try: output_file = "%s.pdf" % self.file.shortname except: # Is this due to a bug ? Or is there a method I # don't know to check wether a file has/is a # master file or doesn't/couldn't have one ? self.__log.debug( "Error while trying to get the output file path. No master document ?" ) return from livepreview import LaTeXPreviews if self._window_context.latex_previews == None: self._window_context.latex_previews = LaTeXPreviews( self._window_context) latex_previews = self._window_context.latex_previews latex_previews.sync_view(tab, source_file, line, column, output_file) def drag_drop_received(self, files): # see base.Editor.drag_drop_received # TODO: we need to insert the source at the drop location - so pass it here self._log.debug("drag_drop: %s" % files) # if len(files) == 1: # file = files[0] # self._log.debug("Got one file: %s, extension: %s" % (file.path, file.extension)) # if file.extension == ".png": # self._log.debug("PNG image - including...") # source = "\\includegraphics{%s}" % file.path # self.insert(source) def insert(self, source): # see base.Editor.insert if type(source) is LaTeXSource: if source.packages and len(source.packages) > 0: self.ensure_packages(source.packages) Editor.insert(self, source.source) else: Editor.insert(self, source) POSITION_PACKAGES, POSITION_BIBLIOGRAPHY = 1, 2 def insert_at_position(self, source, position): """ Insert source at a certain position in the LaTeX document: * POSITION_PACKAGES: after the last \usepackage statement * POSITION_BIBLIOGRAPHY: before \end{document} @param source: a LaTeXSource object @param position: POSITION_PACKAGES | POSITION_BIBLIOGRAPHY """ if position == self.POSITION_BIBLIOGRAPHY: offset = self._document.end_of_document Editor.insert_at_offset(self, offset, source, True) elif position == self.POSITION_PACKAGES: offset = self._document.end_of_packages Editor.insert_at_offset(self, offset, source, False) else: raise NotImplementedError def ensure_packages(self, packages): """ Ensure that certain packages are included @param packages: a list of package names """ self.__parse() # ensure up-to-date document model if not self._document_is_master: self._log.debug("ensure_packages: document is not a master") # find the packages that haven't already been mentioned info_packages = [ p for p in packages if not p in self._ensured_packages ] if len(info_packages) > 0: # generate markup li_tags = "\n".join( [" • <tt>%s</tt>" % p for p in info_packages]) from ..util import open_info open_info( "LaTeX Package Required", "Please make sure that the following packages are included in the master document per <tt>\\usepackage</tt>: \n\n%s" % li_tags) # extend the already mentioned packages self._ensured_packages.extend(info_packages) return # find missing packages present_package_names = [p.value for p in self._outline.packages] package_names = [p for p in packages if not p in present_package_names] # insert the necessary \usepackage commands if len(package_names) > 0: source = "\n" + "\n".join( ["\\usepackage{%s}" % n for n in package_names]) self.insert_at_position(source, self.POSITION_PACKAGES) def on_save(self): """ The file has been saved Update models """ # from multiprocessing import Process # # p_parse = Process(target=self.__parse) # p_parse.start() self.__parse() def __update_neighbors(self): """ Find all files in the working directory that are relevant for LaTeX, e.g. other *.tex files or images. """ # TODO: this is only needed to feed the LaTeXCompletionHandler. So maybe it should # know the edited file and the Editor should call an update() method of the handler # when the file is saved. tex_files = self._file.find_neighbors(".tex") bib_files = self._file.find_neighbors(".bib") graphic_files = [] for extension in [".ps", ".pdf", ".png", ".jpg", ".eps"]: graphic_files.extend(self._file.find_neighbors(extension)) self.__latex_completion_handler.set_neighbors(tex_files, bib_files, graphic_files) #@verbose def __parse(self): """ Ensure that the document model is up-to-date """ if self.content_changed(self._change_reference): # content has changed so document model may be dirty self._change_reference = self.current_timestamp self._log.debug("Parsing document...") # reset highlight self.remove_markers("latex-error") self.remove_markers("latex-warning") # reset issues self._issue_view.clear() if BENCHMARK: t = time.clock() # parse document if self._document != None: self._document.destroy() del self._document self._document = self._parser.parse(self.content, self._file, self) if BENCHMARK: self._log.info("LaTeXParser.parse: %f" % (time.clock() - t)) # create a copy that won't be expanded (e.g. for spell check) #self._local_document = deepcopy(self._document) self._log.debug("Parsed %s bytes of content" % len(self.content)) # FIXME: the LaTeXChooseMasterAction enabled state has to be updated on tab change, too! if self._document.is_master: self._context.set_action_enabled("LaTeXChooseMasterAction", False) self._document_is_master = True # expand child documents expander = LaTeXReferenceExpander() expander.expand(self._document, self._file, self, self.charset) # generate outline from the expanded model self._outline = self._outline_generator.generate( self._document, self) # pass to view self._outline_view.set_outline(self._outline) # validate self._validator.validate(self._document, self._outline, self) else: self._log.debug("Document is not a master") self._context.set_action_enabled("LaTeXChooseMasterAction", True) self._document_is_master = False # the outline used by the outline view has to be created only from the child model # otherwise we see the outline of the master and get wrong offsets self._outline = self._outline_generator.generate( self._document, self) self._outline_view.set_outline(self._outline) # find master master_file = self.__master_file if master_file is None: return # parse master master_content = open(master_file.path).read() self._document = self._parser.parse(master_content, master_file, self) # expand its child documents expander = LaTeXReferenceExpander() expander.expand(self._document, master_file, self, self.charset) # create another outline of the expanded master model to make elements # from the master available (labels, colors, BibTeX files etc.) self._outline = self._outline_generator.generate( self._document, self) # validate self._validator.validate(self._document, self._outline, self) # pass outline to completion self.__latex_completion_handler.set_outline(self._outline) # pass neighbor files to completion self.__update_neighbors() self._log.debug("Parsing finished") #print self._document.xml @property @returns(File) def __master_file(self): """ Find the LaTeX master of this child @return: base.File """ # TODO: cache result property_file = PropertyFile(self._file) try: #return File(property_file["MasterFilename"]) path = property_file["MasterFilename"] # the property file may contain absolute and relative paths # because we switched in 0.2rc2 if File.is_absolute(path): self._log.debug("Path is absolute") return File(path) else: self._log.debug("Path is relative") return File.create_from_relative_path(path, self._file.dirname) except KeyError: # master filename not found # ask user master_filename = ChooseMasterDialog().run(self._file.dirname) if master_filename: # relativize the master filename master_filename = File(master_filename).relativize( self._file.dirname, True) property_file["MasterFilename"] = master_filename property_file.save() return File(master_filename) else: # no master file chosen return None def issue(self, issue): # see IIssueHandler.issue local = (issue.file == self._file) self._issue_view.append_issue(issue, local) if issue.file == self._file: if issue.severity == Issue.SEVERITY_ERROR: self.create_marker("latex-error", issue.start, issue.end) elif issue.severity == Issue.SEVERITY_WARNING: self.create_marker("latex-warning", issue.start, issue.end) # # spell checking begin # # TODO: put this in a SpellCheckDelegate or so # def spell_check(self): """ Run a spell check on the file @raise ImportError: if pyenchant is not installed """ self.remove_markers("latex-spell") self.__word_markers = {} # # FIXME: it makes no sense to pass _document here because it contains # the expanded model of the document. We must keep the the not expanded # one, too. # try: self.__spell_checker.run(self._document, self.edited_file, self) except ImportError: open_error( "Enchant is missing", "The enchant library and its Python bindings (package is propably called pyenchant) are needed for spell checking but could not be found" ) def on_misspelled_word(self, word, position): # see IMisspelledWordHandler.on_misspelled_word marker = self.create_marker("latex-spell", position, position + len(word)) self.__word_markers[marker.id] = word def on_marker_activated(self, marker, event): """ A marker has been activated """ #self._log.debug("activate_marker(%s, %s)" % (marker, event)) if marker.type == "latex-spell": word = self.__word_markers[marker.id] suggestions = self.__spell_checker.find_suggestions(word) self._log.debug(str(suggestions)) # build and show the context menu menu = self.__get_suggestions_menu(word, suggestions, marker) menu.popup(None, None, None, event.button, event.time) # swallow the signal so that the original context menu # isn't shown return True def __get_suggestions_menu(self, word, suggestions, marker): """ Return the context menu for spell check suggestions @param word: the misspelled word @param suggestions: a list of suggested words @param marker: the activated Marker """ suggestions_menu = gtk.Menu() suggestions_menu.add(gtk.SeparatorMenuItem()) item_add = gtk.ImageMenuItem(gtk.STOCK_ADD) item_add.connect("activate", self.__on_add_word_activated, marker, word) suggestions_menu.add(item_add) suggestions_menu.add(gtk.SeparatorMenuItem()) item_abort = gtk.ImageMenuItem(gtk.STOCK_CANCEL) item_abort.connect("activate", self.__on_abort_spell_check_activated) suggestions_menu.add(item_abort) suggestions_menu.show_all() # add suggestions suggestions.reverse() # we insert in reverse order, so reverse before for suggestion in suggestions: if suggestion.user_defined: item = gtk.ImageMenuItem(suggestion.word) item.set_image( gtk.image_new_from_stock(gtk.STOCK_FLOPPY, gtk.ICON_SIZE_MENU)) else: item = gtk.MenuItem(suggestion.word) item.connect("activate", self.__on_suggestion_activated, suggestion, marker) suggestions_menu.insert(item, 0) item.show() return suggestions_menu def __on_suggestion_activated(self, menu_item, suggestion, marker): """ A suggestion from the context menu has been activated @param menu_item: the activated MenuItem @param suggestion: the word """ self.replace_marker_content(marker, suggestion.word) def __on_abort_spell_check_activated(self, menu_item): """ """ self.remove_markers("latex-spell") def __on_add_word_activated(self, menu_item, marker, word): """ Add a word to the dictionary @param marker: the marker for the word @param word: the checked word """ self.__spell_checker.add_word(word) self.remove_marker(marker) # # spell checking end # def on_cursor_moved(self, offset): """ The cursor has moved """ if self._preferences.get_bool("ConnectOutlineToEditor", True): self._outline_view.select_path_by_offset(offset) @property def file(self): # overrides Editor.file # we may not call self._document.is_master because _document is always # replaced by the master model if self._document_is_master: return self._file else: return self.__master_file @property def edited_file(self): """ Always returns the really edited file instead of the master This is called by the outline view to identify foreign nodes """ return self._file def destroy(self): # stop listening preferences self._preferences.remove_monitor(self) # unreference the window context del self._context # destroy the cached document self._document.destroy() del self._document Editor.destroy(self) def __del__(self): self._log.debug("Properly destroyed %s" % self)
def setUp(self): self.spellChecker = SpellChecker() self.spellChecker.load_words('spell.words')
class TestSpellChecker(unittest.TestCase): def setUp(self): self.spellChecker = SpellChecker() self.spellChecker.load_words('spell.words') def test_spell_checker(self): self.assertEqual(53751, len(self.spellChecker.words)) self.assertTrue(self.spellChecker.check_word('zygotic')) self.assertEqual([{ 'line': 1, 'pos': 9, 'word': 'mistasdas' }], self.spellChecker.check_words('zygotic mistasdas elementary')) self.assertEqual( [], self.spellChecker.check_words('our first correct sentence')) self.assertEqual( 0, len(self.spellChecker.check_words('Our first correct sentence.'))) self.assertEqual([{ 'line': 1, 'pos': 9, 'word': 'mistasdas' }, { 'line': 1, 'pos': 19, 'word': 'spelllleeeing' }], self.spellChecker.check_words( 'zygotic mistasdas spelllleeeing elementary')) self.assertEqual( 2, len( self.spellChecker.check_words( 'zygotic mistasdas spelllleeeing elementary'))) self.assertEqual(0, len(self.spellChecker.check_document("karen.txt"))) #self.assertEqual(0, len(self.spellChecker.check_document('spell.words'))) self.assertEqual( 26, len( self.spellChecker.check_dir( "/Users/karenbyrne/Desktop/python_files/"))) self.assertEqual( 2, len( self.spellChecker.check_dir( "/Users/karenbyrne/Desktop/python_files/")))
def setUp(self): self.checker = SpellChecker()
def setUp(self): self.trie = Trie() self.checker = SpellChecker(self.trie)
class TestSpellcheckTrie(unittest.TestCase): def setUp(self): self.trie = Trie() self.checker = SpellChecker(self.trie) def tearDown(self): self.trie.reset() self.checker.reset() def test_exact_match(self): self.trie.add('bayern') self.assertEqual(self.checker.spellcheck('bayern'), 'bayern') def test_miss(self): self.trie.add('bayern') self.assertFalse(self.checker.spellcheck('byern')) def test_vowel(self): self.trie.add('bayern') self.assertEqual(self.checker.spellcheck('bayarn'), 'bayern') def test_vowel_miss(self): self.trie.add('bayern') self.assertFalse(self.checker.spellcheck('barn')) def test_vowel_last_letter(self): self.trie.add('ygapo') self.assertEqual(self.checker.spellcheck('ygapu'), 'ygapo') def test_repeating_chars(self): self.trie.add('job') self.assertEqual(self.checker.spellcheck('jjoobbb'), 'job') def test_repeating_chars_smaller_word(self): self.trie.add('cuppy') self.trie.add('cuphead') self.assertEqual(self.checker.spellcheck('ccoppphead'), 'cuphead') def test_spellcheck_backtrack(self): self.trie.add('pea') self.trie.add('peep') self.trie.add('peeper') self.trie.add('peephole') self.trie.add('peon') self.trie.add('peonage') self.trie.add('people') self.assertEqual(self.checker.spellcheck('peepple'), 'people') def test_challenge_words(self): self.trie.add('conspiracy') self.trie.add('sheep') self.trie.add('people') self.trie.add('wake') self.assertEqual(self.checker.spellcheck('CUNsperrICY'), 'conspiracy') self.assertEqual(self.checker.spellcheck('sheeeeep'), 'sheep') self.assertEqual(self.checker.spellcheck('peepple'), 'people') self.assertEqual(self.checker.spellcheck('weke'), 'wake') self.assertEqual(self.checker.spellcheck('sheeple'), 'sheep') def test_vowels_and_repeating_letters(self): self.trie.add('sdrucciola') self.assertEqual(self.checker.spellcheck('sdrucciila'), 'sdrucciola')
class LaTeXEditor(Editor, IIssueHandler, IMisspelledWordHandler, IPreferencesMonitor): _log = getLogger("LaTeXEditor") #extensions = [".tex"] extensions = Preferences().get("LatexExtensions", ".tex").split(" ") dnd_extensions = [".png", ".pdf", ".bib", ".tex"] @property def completion_handlers(self): self.__latex_completion_handler = LaTeXCompletionHandler() self.__snippet_completion_handler = SnippetCompletionHandler() return [ self.__latex_completion_handler, self.__snippet_completion_handler ] def init(self, file, context): """ @param file: base.File @param context: base.WindowContext """ self._log.debug("init(%s)" % file) self._file = file self._context = context self._preferences = Preferences() self._preferences.register_monitor(self) # listen to 'Show...InOutline' settings self.register_marker_type("latex-spell", self._preferences.get("SpellingBackgroundColor"), anonymous=False) self.register_marker_type("latex-error", self._preferences.get("ErrorBackgroundColor")) self.register_marker_type("latex-warning", self._preferences.get("WarningBackgroundColor")) self._issue_view = context.find_view(self, "IssueView") self._outline_view = context.find_view(self, "LaTeXOutlineView") self._parser = LaTeXParser() self._outline_generator = LaTeXOutlineGenerator() self._validator = LaTeXValidator() self._document = None self._document_dirty = True # if the document is no master we display an info message on the packages to # include - _ensured_packages holds the already mentioned packages to not # annoy the user self._ensured_packages = [] # spell checking self.__spell_checker = SpellChecker() # # initially parse # self._change_reference = self.initial_timestamp self.__parse() self.__update_neighbors() def _on_value_changed(self, key, new_value): # see preferences.IPreferencesMonitor._on_value_changed if key in ["ShowLabelsInOutline", "ShowTablesInOutline", "ShowGraphicsInOutline"]: # regenerate outline model if self._document_is_master: self._outline = self._outline_generator.generate(self._document, self) self._outline_view.set_outline(self._outline) else: # FIXME: self._document contains the full model of child and master # so we may not use it for regenerating the outline here self.__parse() elif key == "ShowLatexToolbar": show_toolbar = self._preferences.get_bool("ShowLatexToolbar", True) if show_toolbar: self._window_context._window_decorator._toolbar.show() else: self._window_context._window_decorator._toolbar.hide() def _ctrl_left_clicked(self, it): """ For synchronization by synctex """ # Editor._ctrl_left_clicked tab = self.tab_decorator.tab line = it.get_line() + 1 column = it.get_line_offset() + 1 source_file = "%s/%s" % (self._file.dirname, self._file.basename) # We use self.file and not self._file here, to get the # master document, because the output file will have the # name of the master document try: output_file = "%s.pdf" % self.file.shortname except: # Is this due to a bug ? Or is there a method I # don't know to check wether a file has/is a # master file or doesn't/couldn't have one ? self.__log.debug("Error while trying to get the output file path. No master document ?") return from livepreview import LaTeXPreviews if self._window_context.latex_previews == None: self._window_context.latex_previews = LaTeXPreviews(self._window_context) latex_previews = self._window_context.latex_previews latex_previews.sync_view(tab, source_file, line, column, output_file) def drag_drop_received(self, files): # see base.Editor.drag_drop_received # TODO: we need to insert the source at the drop location - so pass it here self._log.debug("drag_drop: %s" % files) # if len(files) == 1: # file = files[0] # self._log.debug("Got one file: %s, extension: %s" % (file.path, file.extension)) # if file.extension == ".png": # self._log.debug("PNG image - including...") # source = "\\includegraphics{%s}" % file.path # self.insert(source) def insert(self, source): # see base.Editor.insert if type(source) is LaTeXSource: if source.packages and len(source.packages) > 0: self.ensure_packages(source.packages) Editor.insert(self, source.source) else: Editor.insert(self, source) POSITION_PACKAGES, POSITION_BIBLIOGRAPHY = 1, 2 def insert_at_position(self, source, position): """ Insert source at a certain position in the LaTeX document: * POSITION_PACKAGES: after the last \usepackage statement * POSITION_BIBLIOGRAPHY: before \end{document} @param source: a LaTeXSource object @param position: POSITION_PACKAGES | POSITION_BIBLIOGRAPHY """ if position == self.POSITION_BIBLIOGRAPHY: offset = self._document.end_of_document Editor.insert_at_offset(self, offset, source, True) elif position == self.POSITION_PACKAGES: offset = self._document.end_of_packages Editor.insert_at_offset(self, offset, source, False) else: raise NotImplementedError def ensure_packages(self, packages): """ Ensure that certain packages are included @param packages: a list of package names """ self.__parse() # ensure up-to-date document model if not self._document_is_master: self._log.debug("ensure_packages: document is not a master") # find the packages that haven't already been mentioned info_packages = [p for p in packages if not p in self._ensured_packages] if len(info_packages) > 0: # generate markup li_tags = "\n".join([" • <tt>%s</tt>" % p for p in info_packages]) from ..util import open_info open_info("LaTeX Package Required", "Please make sure that the following packages are included in the master document per <tt>\\usepackage</tt>: \n\n%s" % li_tags) # extend the already mentioned packages self._ensured_packages.extend(info_packages) return # find missing packages present_package_names = [p.value for p in self._outline.packages] package_names = [p for p in packages if not p in present_package_names] # insert the necessary \usepackage commands if len(package_names) > 0: source = "\n" + "\n".join(["\\usepackage{%s}" % n for n in package_names]) self.insert_at_position(source, self.POSITION_PACKAGES) def on_save(self): """ The file has been saved Update models """ # from multiprocessing import Process # # p_parse = Process(target=self.__parse) # p_parse.start() self.__parse() def __update_neighbors(self): """ Find all files in the working directory that are relevant for LaTeX, e.g. other *.tex files or images. """ # TODO: this is only needed to feed the LaTeXCompletionHandler. So maybe it should # know the edited file and the Editor should call an update() method of the handler # when the file is saved. tex_files = self._file.find_neighbors(".tex") bib_files = self._file.find_neighbors(".bib") graphic_files = [] for extension in [".ps", ".pdf", ".png", ".jpg", ".eps"]: graphic_files.extend(self._file.find_neighbors(extension)) self.__latex_completion_handler.set_neighbors(tex_files, bib_files, graphic_files) #@verbose def __parse(self): """ Ensure that the document model is up-to-date """ if self.content_changed(self._change_reference): # content has changed so document model may be dirty self._change_reference = self.current_timestamp self._log.debug("Parsing document...") # reset highlight self.remove_markers("latex-error") self.remove_markers("latex-warning") # reset issues self._issue_view.clear() if BENCHMARK: t = time.clock() # parse document if self._document != None: self._document.destroy() del self._document self._document = self._parser.parse(self.content, self._file, self) if BENCHMARK: self._log.info("LaTeXParser.parse: %f" % (time.clock() - t)) # create a copy that won't be expanded (e.g. for spell check) #self._local_document = deepcopy(self._document) self._log.debug("Parsed %s bytes of content" % len(self.content)) # FIXME: the LaTeXChooseMasterAction enabled state has to be updated on tab change, too! if self._document.is_master: self._context.set_action_enabled("LaTeXChooseMasterAction", False) self._document_is_master = True # expand child documents expander = LaTeXReferenceExpander() expander.expand(self._document, self._file, self, self.charset) # generate outline from the expanded model self._outline = self._outline_generator.generate(self._document, self) # pass to view self._outline_view.set_outline(self._outline) # validate self._validator.validate(self._document, self._outline, self) else: self._log.debug("Document is not a master") self._context.set_action_enabled("LaTeXChooseMasterAction", True) self._document_is_master = False # the outline used by the outline view has to be created only from the child model # otherwise we see the outline of the master and get wrong offsets self._outline = self._outline_generator.generate(self._document, self) self._outline_view.set_outline(self._outline) # find master master_file = self.__master_file if master_file is None: return # parse master master_content = open(master_file.path).read() self._document = self._parser.parse(master_content, master_file, self) # expand its child documents expander = LaTeXReferenceExpander() expander.expand(self._document, master_file, self, self.charset) # create another outline of the expanded master model to make elements # from the master available (labels, colors, BibTeX files etc.) self._outline = self._outline_generator.generate(self._document, self) # validate self._validator.validate(self._document, self._outline, self) # pass outline to completion self.__latex_completion_handler.set_outline(self._outline) # pass neighbor files to completion self.__update_neighbors() self._log.debug("Parsing finished") #print self._document.xml @property @returns(File) def __master_file(self): """ Find the LaTeX master of this child @return: base.File """ # TODO: cache result property_file = PropertyFile(self._file) try: #return File(property_file["MasterFilename"]) path = property_file["MasterFilename"] # the property file may contain absolute and relative paths # because we switched in 0.2rc2 if File.is_absolute(path): self._log.debug("Path is absolute") return File(path) else: self._log.debug("Path is relative") return File.create_from_relative_path(path, self._file.dirname) except KeyError: # master filename not found # ask user master_filename = ChooseMasterDialog().run(self._file.dirname) if master_filename: # relativize the master filename master_filename = File(master_filename).relativize(self._file.dirname, True) property_file["MasterFilename"] = master_filename property_file.save() return File(master_filename) else: # no master file chosen return None def issue(self, issue): # see IIssueHandler.issue local = (issue.file == self._file) self._issue_view.append_issue(issue, local) if issue.file == self._file: if issue.severity == Issue.SEVERITY_ERROR: self.create_marker("latex-error", issue.start, issue.end) elif issue.severity == Issue.SEVERITY_WARNING: self.create_marker("latex-warning", issue.start, issue.end) # # spell checking begin # # TODO: put this in a SpellCheckDelegate or so # def spell_check(self): """ Run a spell check on the file @raise ImportError: if pyenchant is not installed """ self.remove_markers("latex-spell") self.__word_markers = {} # # FIXME: it makes no sense to pass _document here because it contains # the expanded model of the document. We must keep the the not expanded # one, too. # try: self.__spell_checker.run(self._document, self.edited_file, self) except ImportError: open_error("Enchant is missing", "The enchant library and its Python bindings (package is propably called pyenchant) are needed for spell checking but could not be found") def on_misspelled_word(self, word, position): # see IMisspelledWordHandler.on_misspelled_word marker = self.create_marker("latex-spell", position, position + len(word)) self.__word_markers[marker.id] = word def on_marker_activated(self, marker, event): """ A marker has been activated """ #self._log.debug("activate_marker(%s, %s)" % (marker, event)) if marker.type == "latex-spell": word = self.__word_markers[marker.id] suggestions = self.__spell_checker.find_suggestions(word) self._log.debug(str(suggestions)) # build and show the context menu menu = self.__get_suggestions_menu(word, suggestions, marker) menu.popup(None, None, None, event.button, event.time) # swallow the signal so that the original context menu # isn't shown return True def __get_suggestions_menu(self, word, suggestions, marker): """ Return the context menu for spell check suggestions @param word: the misspelled word @param suggestions: a list of suggested words @param marker: the activated Marker """ suggestions_menu = gtk.Menu() suggestions_menu.add(gtk.SeparatorMenuItem()) item_add = gtk.ImageMenuItem(gtk.STOCK_ADD) item_add.connect("activate", self.__on_add_word_activated, marker, word) suggestions_menu.add(item_add) suggestions_menu.add(gtk.SeparatorMenuItem()) item_abort = gtk.ImageMenuItem(gtk.STOCK_CANCEL) item_abort.connect("activate", self.__on_abort_spell_check_activated) suggestions_menu.add(item_abort) suggestions_menu.show_all() # add suggestions suggestions.reverse() # we insert in reverse order, so reverse before for suggestion in suggestions: if suggestion.user_defined: item = gtk.ImageMenuItem(suggestion.word) item.set_image(gtk.image_new_from_stock(gtk.STOCK_FLOPPY, gtk.ICON_SIZE_MENU)) else: item = gtk.MenuItem(suggestion.word) item.connect("activate", self.__on_suggestion_activated, suggestion, marker) suggestions_menu.insert(item, 0) item.show() return suggestions_menu def __on_suggestion_activated(self, menu_item, suggestion, marker): """ A suggestion from the context menu has been activated @param menu_item: the activated MenuItem @param suggestion: the word """ self.replace_marker_content(marker, suggestion.word) def __on_abort_spell_check_activated(self, menu_item): """ """ self.remove_markers("latex-spell") def __on_add_word_activated(self, menu_item, marker, word): """ Add a word to the dictionary @param marker: the marker for the word @param word: the checked word """ self.__spell_checker.add_word(word) self.remove_marker(marker) # # spell checking end # def on_cursor_moved(self, offset): """ The cursor has moved """ if self._preferences.get_bool("ConnectOutlineToEditor", True): self._outline_view.select_path_by_offset(offset) @property def file(self): # overrides Editor.file # we may not call self._document.is_master because _document is always # replaced by the master model if self._document_is_master: return self._file else: return self.__master_file @property def edited_file(self): """ Always returns the really edited file instead of the master This is called by the outline view to identify foreign nodes """ return self._file def destroy(self): # stop listening preferences self._preferences.remove_monitor(self) # unreference the window context del self._context # destroy the cached document self._document.destroy() del self._document Editor.destroy(self) def __del__(self): self._log.debug("Properly destroyed %s" % self)
class TestSpellChecker(unittest.TestCase): def setUp(self): self.spellChecker = SpellChecker() self.spellChecker.load_words('spell.words') def test_spell_checker(self): self.assertTrue(self.spellChecker.check_word( 'zygotic')) # Checks if (single) word is present in list failed_words = self.spellChecker.check_words( 'zygotic mistasdas tennyy elementary') # two incorrect words self.assertEquals( 2, len(failed_words) ) # Checks that failed_words has two entries, i.e. mistasdas and tennyy print('Contents of failed words array ', failed_words) # print failed_words array to see what's in it. self.assertEquals( 'mistasdas', failed_words[0]['word'] ) # Checks that the zero'th failed word in the array is mistasda self.assertEquals( 'tennyy', failed_words[1]['word'] ) # checks that the 2nd failed word (in Position 1) is tennyy self.assertEquals( { 'line': 1, 'word': 'mistasdas', 'pos': 9 }, failed_words[0] ) # checks the line number, word (mistasdas) and caret position are correct self.assertEquals( { 'line': 1, 'word': 'tennyy', 'pos': 19 }, failed_words[1] ) # checks the line number, word (tenny) and caret position are correct self.assertEquals( 1, failed_words[0]['line'] ) # Checks that the zero'th failed (mistasdas) word occurs on line 1 self.assertEquals( 19, failed_words[1]['pos'] ) # checks that the 2nd failed word occurs at caret position 19 self.assertEquals( 0, len(self.spellChecker.check_words('our first correct sentence')) ) # checks that lebgth of array is 0, i.e. includes no failed words # handle case sensitivity self.assertEquals( 0, len(self.spellChecker.check_words('Our first correct sentence'))) # handle full stop self.assertEquals( 0, len(self.spellChecker.check_words('Our first correct sentence.'))) failed_words = self.spellChecker.check_words( 'zygotic mistasdas spelllleeeing elementary') print('Contents of failed words array ', failed_words) # print failed_words array to see what's in it. self.assertEquals( 2, len(failed_words) ) # Checks that array length is 2, i.e. has two failed words self.assertEquals('mistasdas', failed_words[0]['word']) self.assertEquals( 1, failed_words[0]['line'] ) # Checks that the zero'th failed (mistasdas) word occurs on line 1 self.assertEquals( 9, failed_words[0]['pos'] ) # checks that the zero'th failed word occurs at caret position 9 self.assertEquals( 'spelllleeeing', failed_words[1] ['word']) # checks the 2nd word in the failed words array self.assertEquals( 1, failed_words[1]['line'] ) # Checks that the 2nd failed (spelllleeeing) word occurs on line 1 self.assertEquals( 19, failed_words[1]['pos'] ) # checks that the 2nd failed word occurs at caret position 19 self.assertEquals( { 'line': 1, 'word': 'mistasdas', 'pos': 9 }, failed_words[0] ) # Checks the contents of zero'th position in failed words array self.assertEquals( { 'line': 1, 'word': 'spelllleeeing', 'pos': 19 }, failed_words[1] ) # Checks the contents of 2ND position in failed words array # more bugs because the spell checker doesn’t spell check itself correctly – 0 entries when .lower is used – dictionary words need to be lower self.assertEqual(0, len(self.spellChecker.check_document('spell.words')))
class TestSpellChecker(unittest.TestCase): def setUp(self): self.spellChecker = SpellChecker() self.spellChecker.load_words('spell.words') def test_spell_checker(self): self.assertTrue(len(self.spellChecker.words) > 50000) self.assertTrue(self.spellChecker.check_word('zygotic')) self.assertFalse(self.spellChecker.check_word('zogotic')) self.assertEqual([{'line': 1, 'pos': 9, 'word': 'mistasdas'}], self.spellChecker.check_words('zygotic mistasdas elementary')) self.assertEqual([], self.spellChecker.check_words('our first correct sentence')) self.assertEqual(0, len(self.spellChecker.check_words('Our first correct sentence.'))) self.assertEqual([{'line': 1, 'pos': 9, 'word': 'mistasdas'}, {'line': 1, 'pos': 19, 'word': 'spelllleeeing'}], self.spellChecker.check_words('zygotic mistasdas spelllleeeing elementary')) self.assertEqual(2, len(self.spellChecker.check_words('zygotic mistasdas spelllleeeing elementary'))) #self.assertEqual(0, len(self.spellChecker.check_document('spell.words'))) self.assertEqual([{'line': 2, 'pos': 8, 'word': 'larn'}, {'line': 2, 'pos': 13, 'word': 'huw'}, {'line': 2, 'pos': 26, 'word': 'wurdz'}], self.spellChecker.check_document('darren.txt')) self.assertEqual({'darren.txt': [{'line': 2, 'pos': 8, 'word': 'larn'}, {'line': 2, 'pos': 13, 'word': 'huw'}, {'line': 2, 'pos': 26, 'word': 'wurdz'}]}, self.spellChecker.check_directory('*.txt'))
def setUp(self): self.spellChecker = SpellChecker() # This is the path name for our dictionary file file_name = '/Users/barrysheppard/Github/DBSDataAnalysis/' file_name = file_name + 'BigData/04Lecture/spell.words' self.spellChecker.load_words(file_name)