Index: gc_core/js/lang_core/gc_engine.js ================================================================== --- gc_core/js/lang_core/gc_engine.js +++ gc_core/js/lang_core/gc_engine.js @@ -321,13 +321,13 @@ load: function (sContext="JavaScript", sPath="") { try { if (typeof(require) !== 'undefined') { var spellchecker = require("resource://grammalecte/graphspell/spellchecker.js"); - _oSpellChecker = new spellchecker.SpellChecker("${lang}", "", "${dic_main_filename_js}", "${dic_extended_filename_js}", "${dic_personal_filename_js}"); + _oSpellChecker = new spellchecker.SpellChecker("${lang}", "", "${dic_main_filename_js}", "${dic_extended_filename_js}", "${dic_community_filename_js}", "${dic_personal_filename_js}"); } else { - _oSpellChecker = new SpellChecker("${lang}", sPath, "${dic_main_filename_js}", "${dic_extended_filename_js}", "${dic_personal_filename_js}"); + _oSpellChecker = new SpellChecker("${lang}", sPath, "${dic_main_filename_js}", "${dic_extended_filename_js}", "${dic_community_filename_js}", "${dic_personal_filename_js}"); } _sAppContext = sContext; _dOptions = gc_options.getOptions(sContext).gl_shallowCopy(); // duplication necessary, to be able to reset to default } catch (e) { Index: gc_core/py/lang_core/gc_engine.py ================================================================== --- gc_core/py/lang_core/gc_engine.py +++ gc_core/py/lang_core/gc_engine.py @@ -290,11 +290,11 @@ def load (sContext="Python"): global _oSpellChecker global _sAppContext global _dOptions try: - _oSpellChecker = SpellChecker("${lang}", "${dic_main_filename_py}", "${dic_extended_filename_py}", "${dic_personal_filename_py}") + _oSpellChecker = SpellChecker("${lang}", "${dic_main_filename_py}", "${dic_extended_filename_py}", "${dic_community_filename_py}", "${dic_personal_filename_py}") _sAppContext = sContext _dOptions = dict(gc_options.getOptions(sContext)) # duplication necessary, to be able to reset to default except: traceback.print_exc() Index: gc_lang/fr/config.ini ================================================================== --- gc_lang/fr/config.ini +++ gc_lang/fr/config.ini @@ -20,10 +20,14 @@ dic_name = French # extended dictionary lexicon_extended_src = lexicons/French.extended.lex dic_extended_filename = fr.extended dic_extended_name = Français - dictionnaire étendu +# community dictionary +lexicon_extended_src = lexicons/French.community.lex +dic_extended_filename = fr.community +dic_extended_name = Français - dictionnaire communautaire # personal dictionary lexicon_personal_src = lexicons/French.personal.lex dic_personal_filename = fr.personal dic_personal_name = Français - dictionnaire personnel # Finite state automaton compression: 1, 2 (experimental) or 3 (experimental) Index: graphspell-js/spellchecker.js ================================================================== --- graphspell-js/spellchecker.js +++ graphspell-js/spellchecker.js @@ -26,18 +26,19 @@ ]); class SpellChecker { - constructor (sLangCode, sPath="", mainDic="", extentedDic="", personalDic="") { + constructor (sLangCode, sPath="", mainDic="", extentedDic="", communityDic="", personalDic="") { // returns true if the main dictionary is loaded this.sLangCode = sLangCode; if (!mainDic) { mainDic = dDefaultDictionaries.gl_get(sLangCode, ""); } this.oMainDic = this._loadDictionary(mainDic, sPath, true); this.oExtendedDic = this._loadDictionary(extentedDic, sPath); + this.oCommunityDic = this._loadDictionary(communityDic, sPath); this.oPersonalDic = this._loadDictionary(personalDic, sPath); this.oTokenizer = null; } _loadDictionary (dictionary, sPath, bNecessary=false) { @@ -87,10 +88,16 @@ setExtendedDictionary (dictionary) { // returns true if the dictionary is loaded this.oExtendedDic = this._loadDictionary(dictionary); return Boolean(this.oExtendedDic); } + + setCommunityDictionary (dictionary) { + // returns true if the dictionary is loaded + this.oCommunityDic = this._loadDictionary(dictionary); + return Boolean(this.oCommunityDic); + } setPersonalDictionary (dictionary) { // returns true if the dictionary is loaded this.oPersonalDic = this._loadDictionary(dictionary); return Boolean(this.oPersonalDic); @@ -118,10 +125,13 @@ if (this.oMainDic.isValidToken(sToken)) { return true; } if (this.oExtendedDic && this.oExtendedDic.isValidToken(sToken)) { return true; + } + if (this.oCommunityDic && this.oCommunityDic.isValidToken(sToken)) { + return true; } if (this.oPersonalDic && this.oPersonalDic.isValidToken(sToken)) { return true; } return false; @@ -132,10 +142,13 @@ if (this.oMainDic.isValid(sWord)) { return true; } if (this.oExtendedDic && this.oExtendedDic.isValid(sWord)) { return true; + } + if (this.oCommunityDic && this.oCommunityDic.isValid(sToken)) { + return true; } if (this.oPersonalDic && this.oPersonalDic.isValid(sWord)) { return true; } return false; @@ -146,10 +159,13 @@ if (this.oMainDic.lookup(sWord)) { return true; } if (this.oExtendedDic && this.oExtendedDic.lookup(sWord)) { return true; + } + if (this.oCommunityDic && this.oCommunityDic.lookup(sToken)) { + return true; } if (this.oPersonalDic && this.oPersonalDic.lookup(sWord)) { return true; } return false; @@ -159,10 +175,13 @@ // retrieves morphologies list, different casing allowed let lResult = this.oMainDic.getMorph(sWord); if (this.oExtendedDic) { lResult.push(...this.oExtendedDic.getMorph(sWord)); } + if (this.oCommunityDic) { + lResult.push(...this.oCommunityDic.getMorph(sWord)); + } if (this.oPersonalDic) { lResult.push(...this.oPersonalDic.getMorph(sWord)); } return lResult; } @@ -171,10 +190,13 @@ // generator: returns 1, 2 or 3 lists of suggestions yield this.oMainDic.suggest(sWord, nSuggLimit); if (this.oExtendedDic) { yield this.oExtendedDic.suggest(sWord, nSuggLimit); } + if (this.oCommunityDic) { + yield this.oCommunityDic.suggest(sWord, nSuggLimit); + } if (this.oPersonalDic) { yield this.oPersonalDic.suggest(sWord, nSuggLimit); } } @@ -182,14 +204,17 @@ // generator: returns all entries which morphology fits yield* this.oMainDic.select(sPattern) if (this.oExtendedDic) { yield* this.oExtendedDic.select(sPattern); } + if (this.oCommunityDic) { + yield* this.oCommunityDic.select(sPattern); + } if (this.oPersonalDic) { yield* this.oPersonalDic.select(sPattern); } } } if (typeof(exports) !== 'undefined') { exports.SpellChecker = SpellChecker; } Index: graphspell/spellchecker.py ================================================================== --- graphspell/spellchecker.py +++ graphspell/spellchecker.py @@ -20,17 +20,18 @@ } class SpellChecker (): - def __init__ (self, sLangCode, sfMainDic="", sfExtendedDic="", sfPersonalDic=""): + def __init__ (self, sLangCode, sfMainDic="", sfExtendedDic="", sfCommunityDic="", sfPersonalDic=""): "returns True if the main dictionary is loaded" self.sLangCode = sLangCode if not sfMainDic: sfMainDic = dDefaultDictionaries.get(sLangCode, "") self.oMainDic = self._loadDictionary(sfMainDic, True) self.oExtendedDic = self._loadDictionary(sfExtendedDic) + self.oCommunityDic = self._loadDictionary(sfCommunityDic) self.oPersonalDic = self._loadDictionary(sfPersonalDic) self.oTokenizer = None def _loadDictionary (self, source, bNecessary=False): "returns an IBDAWG object" @@ -60,10 +61,15 @@ def setExtendedDictionary (self, source): "returns True if the dictionary is loaded" self.oExtendedDic = self._loadDictionary(source) return bool(self.oExtendedDic) + + def setCommunityDictionary (self, source): + "returns True if the dictionary is loaded" + self.oCommunityDic = self._loadDictionary(source) + return bool(self.oPersonalDic) def setPersonalDictionary (self, source): "returns True if the dictionary is loaded" self.oPersonalDic = self._loadDictionary(source) return bool(self.oPersonalDic) @@ -105,19 +111,23 @@ "checks if sToken is valid (if there is hyphens in sToken, sToken is split, each part is checked)" if self.oMainDic.isValidToken(sToken): return True if self.oExtendedDic and self.oExtendedDic.isValidToken(sToken): return True + if self.oCommunityDic and self.oCommunityDic.isValidToken(sToken): + return True if self.oPersonalDic and self.oPersonalDic.isValidToken(sToken): return True return False def isValid (self, sWord): "checks if sWord is valid (different casing tested if the first letter is a capital)" if self.oMainDic.isValid(sWord): return True if self.oExtendedDic and self.oExtendedDic.isValid(sWord): + return True + if self.oCommunityDic and self.oCommunityDic.isValid(sToken): return True if self.oPersonalDic and self.oPersonalDic.isValid(sWord): return True return False @@ -125,19 +135,23 @@ "checks if sWord is in dictionary as is (strict verification)" if self.oMainDic.lookup(sWord): return True if self.oExtendedDic and self.oExtendedDic.lookup(sWord): return True + if self.oCommunityDic and self.oCommunityDic.lookup(sToken): + return True if self.oPersonalDic and self.oPersonalDic.lookup(sWord): return True return False def getMorph (self, sWord): "retrieves morphologies list, different casing allowed" lResult = self.oMainDic.getMorph(sWord) if self.oExtendedDic: lResult.extend(self.oExtendedDic.getMorph(sWord)) + if self.oCommunityDic: + lResult.extend(self.oCommunityDic.getMorph(sWord)) if self.oPersonalDic: lResult.extend(self.oPersonalDic.getMorph(sWord)) return lResult def getLemma (self, sWord): @@ -146,24 +160,31 @@ def suggest (self, sWord, nSuggLimit=10): "generator: returns 1, 2 or 3 lists of suggestions" yield self.oMainDic.suggest(sWord, nSuggLimit) if self.oExtendedDic: yield self.oExtendedDic.suggest(sWord, nSuggLimit) + if self.oCommunityDic: + yield self.oCommunityDic.suggest(sWord, nSuggLimit) if self.oPersonalDic: yield self.oPersonalDic.suggest(sWord, nSuggLimit) def select (self, sPattern=""): "generator: returns all entries which morphology fits " yield from self.oMainDic.select(sPattern) if self.oExtendedDic: yield from self.oExtendedDic.select(sPattern) + if self.oCommunityDic: + yield from self.oCommunityDic.select(sPattern) if self.oPersonalDic: yield from self.oPersonalDic.select(sPattern) def drawPath (self, sWord): self.oMainDic.drawPath(sWord) if self.oExtendedDic: print("-----") self.oExtendedDic.drawPath(sWord) + if self.oCommunityDic: + print("-----") + self.oCommunityDic.drawPath(sWord) if self.oPersonalDic: print("-----") self.oPersonalDic.drawPath(sWord) Index: make.py ================================================================== --- make.py +++ make.py @@ -305,20 +305,24 @@ if not os.path.isdir("graphspell-js/"+sf): file_util.copy_file("graphspell-js/"+sf, "grammalecte-js/graphspell") helpers.copyAndFileTemplate("graphspell-js/"+sf, "grammalecte-js/graphspell/"+sf, dVars) -def copyGraphspellDictionaries (dVars, bJavaScript=False, bExtendedDict=False, bPersonalDict=False): +def copyGraphspellDictionaries (dVars, bJavaScript=False, bExtendedDict=False, bCommunityDict=False, bPersonalDict=False): dVars["dic_main_filename_py"] = "" dVars["dic_main_filename_js"] = "" dVars["dic_extended_filename_py"] = "" dVars["dic_extended_filename_js"] = "" + dVars["dic_community_filename_py"] = "" + dVars["dic_community_filename_js"] = "" dVars["dic_personal_filename_py"] = "" dVars["dic_personal_filename_js"] = "" lDict = [ ("main", dVars['dic_filename']) ] if bExtendedDict: lDict.append(("extended", dVars['dic_extended_filename'])) + if bCommunityDict: + lDict.append(("community", dVars['dic_community_filename'])) if bPersonalDict: lDict.append(("personal", dVars['dic_personal_filename'])) for sType, sFileName in lDict: spfPyDic = "graphspell/_dictionaries/" + sFileName + ".bdic" spfJSDic = "graphspell-js/_dictionaries/" + sFileName + ".json" @@ -339,10 +343,14 @@ sDicName = dVars['dic_name'] elif sType == "extended": spfLexSrc = dVars['lexicon_extended_src'] sfDictDst = dVars['dic_extended_filename'] sDicName = dVars['dic_extended_name'] + elif sType == "community": + spfLexSrc = dVars['lexicon_community_src'] + sfDictDst = dVars['dic_community_filename'] + sDicName = dVars['dic_community_name'] elif sType == "personal": spfLexSrc = dVars['lexicon_personal_src'] sfDictDst = dVars['dic_personal_filename'] sDicName = dVars['dic_personal_name'] lex_build.build(spfLexSrc, dVars['lang'], dVars['lang_name'], sfDictDst, bJavaScript, sDicName, dVars['stemming_method'], int(dVars['fsa_method'])) @@ -360,10 +368,11 @@ xParser.add_argument("-t", "--tests", help="run unit tests", action="store_true") xParser.add_argument("-p", "--perf", help="run performance tests", action="store_true") xParser.add_argument("-pm", "--perf_memo", help="run performance tests and store results in perf_memo.txt", action="store_true") xParser.add_argument("-js", "--javascript", help="JavaScript build for Firefox", action="store_true") xParser.add_argument("-aed", "--add_extended_dictionary", help="add extended dictionary to the build", action="store_true") + xParser.add_argument("-acd", "--add_community_dictionary", help="add community dictionary to the build", action="store_true") xParser.add_argument("-apd", "--add_personal_dictionary", help="add personal dictionary to the build", action="store_true") xParser.add_argument("-fx", "--firefox", help="Launch Firefox Developper for WebExtension testing", action="store_true") xParser.add_argument("-we", "--web_ext", help="Launch Firefox Nightly for WebExtension testing", action="store_true") xParser.add_argument("-tb", "--thunderbird", help="Launch Thunderbird", action="store_true") xParser.add_argument("-i", "--install", help="install the extension in Writer (path of unopkg must be set in config.ini)", action="store_true") @@ -385,10 +394,12 @@ xConfig = getConfig(sLang) dVars = xConfig._sections['args'] if not dVars["lexicon_extended_src"]: xArgs.add_extended_dictionary = False + if not dVars["lexicon_community_src"]: + xArgs.add_community_dictionary = False if not dVars["lexicon_personal_src"]: xArgs.add_personal_dictionary = False # build data build_data_module = None @@ -402,17 +413,19 @@ build_data_module.before('gc_lang/'+sLang, dVars, xArgs.javascript) if xArgs.dict: buildDictionary(dVars, "main", xArgs.javascript) if xArgs.add_extended_dictionary: buildDictionary(dVars, "extended", xArgs.javascript) + if xArgs.add_community_dictionary: + buildDictionary(dVars, "community", xArgs.javascript) if xArgs.add_personal_dictionary: buildDictionary(dVars, "personal", xArgs.javascript) if build_data_module and xArgs.build_data_after: build_data_module.after('gc_lang/'+sLang, dVars, xArgs.javascript) # copy dictionaries from Graphspell - copyGraphspellDictionaries(dVars, xArgs.javascript, xArgs.add_extended_dictionary, xArgs.add_personal_dictionary) + copyGraphspellDictionaries(dVars, xArgs.javascript, xArgs.add_extended_dictionary, xArgs.add_community_dictionary, xArgs.add_personal_dictionary) # make sVersion = create(sLang, xConfig, xArgs.install, xArgs.javascript, ) # tests