Index: gc_lang/fr/config.ini
==================================================================
--- gc_lang/fr/config.ini
+++ gc_lang/fr/config.ini
@@ -14,12 +14,15 @@
 extras = README_fr.txt
 logo = logo.png
 
 # main dictionary
 lexicon_src = lexicons/French.lex
-dic_filename = fr
-dic_name = French
+dic_filenames = fr-allvars,fr-classic,fr-reform
+dic_name = Français,Français (Classique/Moderne),Français (Réforme 1990)
+dic_filter = ,[*CMPX]$,[*RPX]$
+dic_default_filename_py = fr-allvars
+dic_default_filename_js = fr-allvars
 # extended dictionary
 lexicon_extended_src = lexicons/French.extended.lex
 dic_extended_filename = fr.extended
 dic_extended_name = Français - dictionnaire étendu
 # community dictionary

Index: gc_lang/fr/dictionnaire/genfrdic.py
==================================================================
--- gc_lang/fr/dictionnaire/genfrdic.py
+++ gc_lang/fr/dictionnaire/genfrdic.py
@@ -61,18 +61,10 @@
                'mozAsciiName': 'fr-FR-classic',
                'subDicts': '*MCX',
                'mozId': 'fr-dicollecte-classique',
                'description': "Dictionnaire français “Classique”" }
 
-dCLASSIQUEX = { 'name': 'DICTIONNAIRE ORTHOGRAPHIQUE FRANÇAIS “CLASSIQUE ÉTENDU”',
-                'shortname': '“Classique étendu”',
-                'asciiName': 'fr-classique-ext',
-                'mozAsciiName': 'fr-FR-classic-ext',
-                'subDicts': '*MCX',
-                'mozId': 'fr-dicollecte-classique-ext',
-                'description': "Dictionnaire français “Classique étendu”" }
-
 dREFORME1990 = { 'name': 'DICTIONNAIRE ORTHOGRAPHIQUE FRANÇAIS “RÉFORME 1990”',
                  'shortname': '“Réforme 1990”',
                  'asciiName': 'fr-reforme1990',
                  'mozAsciiName': 'fr-FR-reform',
                  'subDicts': '*RX',

Index: gc_lang/fr/modules/tests.py
==================================================================
--- gc_lang/fr/modules/tests.py
+++ gc_lang/fr/modules/tests.py
@@ -22,11 +22,11 @@
 
 class TestDictionary (unittest.TestCase):
 
     @classmethod
     def setUpClass (cls):
-        cls.oDic = IBDAWG("${dic_filename}.bdic")
+        cls.oDic = IBDAWG("${dic_main_filename_py}")
 
     def test_lookup (self):
         for sWord in ["branche", "Émilie"]:
             self.assertTrue(self.oDic.lookup(sWord), sWord)
 

Index: gc_lang/fr/oxt/ContextMenu/ContextMenu.py
==================================================================
--- gc_lang/fr/oxt/ContextMenu/ContextMenu.py
+++ gc_lang/fr/oxt/ContextMenu/ContextMenu.py
@@ -129,11 +129,11 @@
                 oGC = self.ctx.ServiceManager.createInstanceWithContext("org.openoffice.comp.pyuno.Lightproof.grammalecte", self.ctx)
                 if hasattr(oGC, "getSpellChecker"):
                     # https://bugs.documentfoundation.org/show_bug.cgi?id=97790
                     oSpellChecker = oGC.getSpellChecker()
                 else:
-                    oSpellChecker = SpellChecker("${lang}", "${dic_filename}.bdic")
+                    oSpellChecker = SpellChecker("${lang}", "fr-allvars.bdic")
             if not oLexicographe:
                 oLexicographe = lxg.Lexicographe(oSpellChecker)
         except:
             traceback.print_exc()
         

Index: gc_lang/fr/oxt/Graphspell.py
==================================================================
--- gc_lang/fr/oxt/Graphspell.py
+++ gc_lang/fr/oxt/Graphspell.py
@@ -63,11 +63,11 @@
                     try:
                         personal_dic = json.loads(sPersonalDicJSON)
                     except:
                         print("Graphspell: wrong personal_dic")
                         traceback.print_exc()
-            self.oGraphspell = SpellChecker("fr", "fr.bdic", "", "", personal_dic)
+            self.oGraphspell = SpellChecker("fr", "fr-allvars.bdic", "", "", personal_dic)
             self.loadHunspell()
             # print("Graphspell: init done")
         except:
             print("Graphspell: init failed")
             traceback.print_exc()

Index: gc_lang/fr/rules.grx
==================================================================
--- gc_lang/fr/rules.grx
+++ gc_lang/fr/rules.grx
@@ -11496,11 +11496,11 @@
 
 TEST: Tu ne {{ment}} jamais.
 TEST: Tu {{a}} mal ?
 TEST: Tu ne le lui {{prend}} pas.
 TEST: Tu ne m’{{attendra}} pas.
-TEST: toi qui n’y {{connait}} rien, ne nous ennuie pas avec tes théories.
+TEST: toi qui n’y {{connaît}} rien, ne nous ennuie pas avec tes théories.
 
 
 ## 3sg
 __[i]/conj(conj_il)__
     (?<!t’)(il) +({w_1})  @@0,$

Index: graphspell/dawg.py
==================================================================
--- graphspell/dawg.py
+++ graphspell/dawg.py
@@ -12,10 +12,12 @@
 import sys
 import os
 import collections
 import json
 import time
+import re
+import traceback
 
 from . import str_transform as st
 from .progressbar import ProgressBar
 
 
@@ -61,10 +63,11 @@
 
         try:
             zFilter = re.compile(sSelectFilterRegex)  if sSelectFilterRegex  else None
         except:
             print(" # Error. Wrong filter regex. Filter ignored.")
+            traceback.print_exc()
             zFilter = None
 
         # read lexicon
         if type(src) is str:
             iterable = readFile(src)
@@ -97,10 +100,11 @@
         if not aEntry:
             raise ValueError("# Error. Empty lexicon")
         
         # Preparing DAWG
         print(" > Preparing list of words")
+        print(" Filter: " + (sSelectFilterRegex or "[None]"))
         lVal = lChar + lAff + lTag
         lWord = [ [dChar[c] for c in sFlex] + [iAff+nChar] + [iTag+nChar+nAff]  for sFlex, iAff, iTag in aEntry ]
         aEntry = None
         
         # Dictionary of arc values occurrency, to sort arcs of each node

Index: lex_build.py
==================================================================
--- lex_build.py
+++ lex_build.py
@@ -7,13 +7,13 @@
 
 import graphspell.dawg as fsa
 from graphspell.ibdawg import IBDAWG
 
 
-def build (spfSrc, sLangCode, sLangName, sfDict, bJSON=False, sDicName="", cStemmingMethod="S", nCompressMethod=1):
+def build (spfSrc, sLangCode, sLangName, sfDict, bJSON=False, sDicName="", sFilter="", cStemmingMethod="S", nCompressMethod=1):
     "transform a text lexicon as a binary indexable dictionary"
-    oDAWG = fsa.DAWG(spfSrc, cStemmingMethod, sLangCode, sLangName, sDicName)
+    oDAWG = fsa.DAWG(spfSrc, cStemmingMethod, sLangCode, sLangName, sDicName, sFilter)
     dir_util.mkpath("graphspell/_dictionaries")
     oDAWG.writeInfo("graphspell/_dictionaries/" + sfDict + ".info.txt")
     oDAWG.writeBinary("graphspell/_dictionaries/" + sfDict + ".bdic", int(nCompressMethod))
     if bJSON:
         dir_util.mkpath("graphspell-js/_dictionaries")

Index: make.py
==================================================================
--- make.py
+++ make.py
@@ -314,11 +314,11 @@
     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']) ]
+    lDict = [ ("main", s)  for s in dVars['dic_filenames'].split(",") ]
     if bExtendedDict:
         lDict.append(("extended", dVars['dic_extended_filename']))
     if bCommunityDict:
         lDict.append(("community", dVars['dic_community_filename']))
     if bPersonalDict:
@@ -330,32 +330,39 @@
             buildDictionary(dVars, sType, bJavaScript)
         print(spfPyDic)
         file_util.copy_file(spfPyDic, "grammalecte/graphspell/_dictionaries")
         dVars['dic_'+sType+'_filename_py'] = sFileName + '.bdic'
         if bJavaScript:
+            print(spfJSDic)
             file_util.copy_file(spfJSDic, "grammalecte-js/graphspell/_dictionaries")
             dVars['dic_'+sType+'_filename_js'] = sFileName + '.json'
+    dVars['dic_main_filename_py'] = dVars['dic_default_filename_py'] + ".bdic"
+    dVars['dic_main_filename_js'] = dVars['dic_default_filename_js'] + ".json"
 
 
 def buildDictionary (dVars, sType, bJavaScript=False):
     if sType == "main":
         spfLexSrc = dVars['lexicon_src']
-        sfDictDst = dVars['dic_filename']
-        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']))
+        l_sfDictDst = dVars['dic_filenames'].split(",")
+        l_sDicName = dVars['dic_name'].split(",")
+        l_sFilter = dVars['dic_filter'].split(",")
+        for sfDictDst, sDicName, sFilter in zip(l_sfDictDst, l_sDicName, l_sFilter):
+            lex_build.build(spfLexSrc, dVars['lang'], dVars['lang_name'], sfDictDst, bJavaScript, sDicName, sFilter, dVars['stemming_method'], int(dVars['fsa_method']))
+    else:
+        if 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']))
 
 
 
 def main ():
     print("Python: " + sys.version)