Index: compile_rules.py
==================================================================
--- compile_rules.py
+++ compile_rules.py
@@ -1,11 +1,15 @@
+"""
+Grammalecte: compile rules
+"""
 
 import re
 import traceback
 import json
 
 import compile_rules_js_convert as jsconv
+import compile_rules_graph as crg
 
 
 dDEF = {}
 lFUNCTIONS = []
 
@@ -17,10 +21,11 @@
 sWORDLIMITLEFT  = r"(?<![\w.,–-])"   # r"(?<![-.,—])\b"  seems slower
 sWORDLIMITRIGHT = r"(?![\w–-])"      # r"\b(?!-—)"       seems slower
 
 
 def prepareFunction (s):
+    "convert simple rule syntax to a string of Python code"
     s = s.replace("__also__", "bCondMemo")
     s = s.replace("__else__", "not bCondMemo")
     s = re.sub(r"isStart *\(\)", 'before("^ *$|, *$")', s)
     s = re.sub(r"isRealStart *\(\)", 'before("^ *$")', s)
     s = re.sub(r"isStart0 *\(\)", 'before0("^ *$|, *$")', s)
@@ -27,35 +32,35 @@
     s = re.sub(r"isRealStart0 *\(\)", 'before0("^ *$")', s)
     s = re.sub(r"isEnd *\(\)", 'after("^ *$|^,")', s)
     s = re.sub(r"isRealEnd *\(\)", 'after("^ *$")', s)
     s = re.sub(r"isEnd0 *\(\)", 'after0("^ *$|^,")', s)
     s = re.sub(r"isRealEnd0 *\(\)", 'after0("^ *$")', s)
-    s = re.sub(r"(select|exclude)[(][\\](\d+)", '\\1(dDA, m.start(\\2), m.group(\\2)', s)
-    s = re.sub(r"define[(][\\](\d+)", 'define(dDA, m.start(\\1)', s)
+    s = re.sub(r"(select|exclude)[(][\\](\d+)", '\\1(dTokenPos, m.start(\\2), m.group(\\2)', s)
+    s = re.sub(r"define[(][\\](\d+)", 'define(dTokenPos, m.start(\\1)', s)
     s = re.sub(r"(morph|morphex|displayInfo)[(][\\](\d+)", '\\1((m.start(\\2), m.group(\\2))', s)
-    s = re.sub(r"(morph|morphex|displayInfo)[(]", '\\1(dDA, ', s)
+    s = re.sub(r"(morph|morphex|displayInfo)[(]", '\\1(dTokenPos, ', s)
     s = re.sub(r"(sugg\w+|switch\w+)\(@", '\\1(m.group(i[4])', s)
     s = re.sub(r"word\(\s*1\b", 'nextword1(s, m.end()', s)                                  # word(1)
     s = re.sub(r"word\(\s*-1\b", 'prevword1(s, m.start()', s)                               # word(-1)
     s = re.sub(r"word\(\s*(\d)", 'nextword(s, m.end(), \\1', s)                             # word(n)
     s = re.sub(r"word\(\s*-(\d)", 'prevword(s, m.start(), \\1', s)                          # word(-n)
     s = re.sub(r"before\(\s*", 'look(s[:m.start()], ', s)                                   # before(s)
     s = re.sub(r"after\(\s*", 'look(s[m.end():], ', s)                                      # after(s)
     s = re.sub(r"textarea\(\s*", 'look(s, ', s)                                             # textarea(s)
-    s = re.sub(r"before_chk1\(\s*", 'look_chk1(dDA, s[:m.start()], 0, ', s)                 # before_chk1(s)
-    s = re.sub(r"after_chk1\(\s*", 'look_chk1(dDA, s[m.end():], m.end(), ', s)              # after_chk1(s)
-    s = re.sub(r"textarea_chk1\(\s*", 'look_chk1(dDA, s, 0, ', s)                           # textarea_chk1(s)
+    s = re.sub(r"before_chk1\(\s*", 'look_chk1(dTokenPos, s[:m.start()], 0, ', s)           # before_chk1(s)
+    s = re.sub(r"after_chk1\(\s*", 'look_chk1(dTokenPos, s[m.end():], m.end(), ', s)        # after_chk1(s)
+    s = re.sub(r"textarea_chk1\(\s*", 'look_chk1(dTokenPos, s, 0, ', s)                     # textarea_chk1(s)
     s = re.sub(r"/0", 'sx[m.start():m.end()]', s)                                           # /0
     s = re.sub(r"before0\(\s*", 'look(sx[:m.start()], ', s)                                 # before0(s)
     s = re.sub(r"after0\(\s*", 'look(sx[m.end():], ', s)                                    # after0(s)
     s = re.sub(r"textarea0\(\s*", 'look(sx, ', s)                                           # textarea0(s)
-    s = re.sub(r"before0_chk1\(\s*", 'look_chk1(dDA, sx[:m.start()], 0, ', s)               # before0_chk1(s)
-    s = re.sub(r"after0_chk1\(\s*", 'look_chk1(dDA, sx[m.end():], m.end(), ', s)            # after0_chk1(s)
-    s = re.sub(r"textarea0_chk1\(\s*", 'look_chk1(dDA, sx, 0, ', s)                         # textarea0_chk1(s)
-    s = re.sub(r"isEndOfNG\(\s*\)", 'isEndOfNG(dDA, s[m.end():], m.end())', s)              # isEndOfNG(s)
-    s = re.sub(r"isNextNotCOD\(\s*\)", 'isNextNotCOD(dDA, s[m.end():], m.end())', s)        # isNextNotCOD(s)
-    s = re.sub(r"isNextVerb\(\s*\)", 'isNextVerb(dDA, s[m.end():], m.end())', s)            # isNextVerb(s)
+    s = re.sub(r"before0_chk1\(\s*", 'look_chk1(dTokenPos, sx[:m.start()], 0, ', s)         # before0_chk1(s)
+    s = re.sub(r"after0_chk1\(\s*", 'look_chk1(dTokenPos, sx[m.end():], m.end(), ', s)      # after0_chk1(s)
+    s = re.sub(r"textarea0_chk1\(\s*", 'look_chk1(dTokenPos, sx, 0, ', s)                   # textarea0_chk1(s)
+    s = re.sub(r"isEndOfNG\(\s*\)", 'isEndOfNG(dTokenPos, s[m.end():], m.end())', s)        # isEndOfNG(s)
+    s = re.sub(r"isNextNotCOD\(\s*\)", 'isNextNotCOD(dTokenPos, s[m.end():], m.end())', s)  # isNextNotCOD(s)
+    s = re.sub(r"isNextVerb\(\s*\)", 'isNextVerb(dTokenPos, s[m.end():], m.end())', s)      # isNextVerb(s)
     s = re.sub(r"\bspell *[(]", '_oSpellChecker.isValid(', s)
     s = re.sub(r"[\\](\d+)", 'm.group(\\1)', s)
     return s
 
 
@@ -97,10 +102,11 @@
             nState = 0
     return sUp
 
 
 def countGroupInRegex (sRegex):
+    "returns the number of groups in <sRegex>"
     try:
         return re.compile(sRegex).groups
     except:
         traceback.print_exc()
         print(sRegex)
@@ -110,13 +116,21 @@
 def createRule (s, nIdLine, sLang, bParagraph, dOptPriority):
     "returns rule as list [option name, regex, bCaseInsensitive, identifier, list of actions]"
     global dJSREGEXES
     global nRULEWITHOUTNAME
 
-    #### OPTIONS
     sLineId = str(nIdLine) + ("p" if bParagraph else "s")
     sRuleId = sLineId
+
+    #### GRAPH CALL
+    if s.startswith("@@@@"):
+        if bParagraph:
+            print("Error. Graph call can be made only after the first pass (sentence by sentence)")
+            exit()
+        return ["@@@@", s[4:], sLineId]
+
+    #### OPTIONS
     sOption = False         # False or [a-z0-9]+ name
     nPriority = 4           # Default is 4, value must be between 0 and 9
     tGroups = None          # code for groups positioning (only useful for JavaScript)
     cCaseMode = 'i'         # i: case insensitive,  s: case sensitive,  u: uppercasing allowed
     cWordLimitLeft = '['    # [: word limit, <: no specific limit
@@ -147,11 +161,11 @@
     if i == -1:
         print("# Error: no condition at line " + sLineId)
         return None
     sRegex = s[:i].strip()
     s = s[i+4:]
-    
+
     # JS groups positioning codes
     m = re.search("@@\\S+", sRegex)
     if m:
         tGroups = jsconv.groupsPositioningCodeToList(sRegex[m.start()+2:])
         sRegex = sRegex[:m.start()].strip()
@@ -202,18 +216,18 @@
     else:
         print("# Unknown case mode [" + cCaseMode + "] at line " + sLineId)
 
     ## check regex
     try:
-        z = re.compile(sRegex)
+        re.compile(sRegex)
     except:
         print("# Regex error at line ", nIdLine)
         print(sRegex)
         traceback.print_exc()
         return None
     ## groups in non grouping parenthesis
-    for x in re.finditer("\(\?:[^)]*\([[\w -]", sRegex):
+    for x in re.finditer(r"\(\?:[^)]*\([[\w -]", sRegex):
         print("# Warning: groups inside non grouping parenthesis in regex at line " + sLineId)
 
     #### PARSE ACTIONS
     lActions = []
     nAction = 1
@@ -225,39 +239,50 @@
     if not lActions:
         return None
 
     return [sOption, sRegex, bCaseInsensitive, sLineId, sRuleId, nPriority, lActions, tGroups]
 
+
+def checkReferenceNumbers (sText, sActionId, nToken):
+    "check if token references in <sText> greater than <nToken> (debugging)"
+    for x in re.finditer(r"\\(\d+)", sText):
+        if int(x.group(1)) > nToken:
+            print("# Error in token index at line " + sActionId + " ("+str(nToken)+" tokens only)")
+            print(sText)
+
+
+def checkIfThereIsCode (sText, sActionId):
+    "check if there is code in <sText> (debugging)"
+    if re.search("[.]\\w+[(]|sugg\\w+[(]|\\([0-9]|\\[[0-9]", sText):
+        print("# Warning at line " + sActionId + ":  This message looks like code. Line should probably begin with =")
+        print(sText)
+
 
 def createAction (sIdAction, sAction, nGroup):
     "returns an action to perform as a tuple (condition, action type, action[, iGroup [, message, URL ]])"
-    global lFUNCTIONS
-
     m = re.search(r"([-~=>])(\d*|)>>", sAction)
     if not m:
         print("# No action at line " + sIdAction)
         return None
 
     #### CONDITION
     sCondition = sAction[:m.start()].strip()
     if sCondition:
         sCondition = prepareFunction(sCondition)
-        lFUNCTIONS.append(("c_"+sIdAction, sCondition))
-        for x in re.finditer("[.](?:group|start|end)[(](\d+)[)]", sCondition):
-            if int(x.group(1)) > nGroup:
-                print("# Error in groups in condition at line " + sIdAction + " ("+str(nGroup)+" groups only)")
+        lFUNCTIONS.append(("_c_"+sIdAction, sCondition))
+        checkReferenceNumbers(sCondition, sIdAction, nGroup)
         if ".match" in sCondition:
             print("# Error. JS compatibility. Don't use .match() in condition, use .search()")
-        sCondition = "c_"+sIdAction
+        sCondition = "_c_"+sIdAction
     else:
         sCondition = None
 
     #### iGroup / positioning
     iGroup = int(m.group(2)) if m.group(2) else 0
     if iGroup > nGroup:
         print("# Selected group > group number in regex at line " + sIdAction)
-    
+
     #### ACTION
     sAction = sAction[m.end():].strip()
     cAction = m.group(1)
     if cAction == "-":
         ## error
@@ -272,87 +297,78 @@
             sURL = ""
             mURL = re.search("[|] *(https?://.*)", sMsg)
             if mURL:
                 sURL = mURL.group(1).strip()
                 sMsg = sMsg[:mURL.start(0)].strip()
+            checkReferenceNumbers(sMsg, sIdAction, nGroup)
             if sMsg[0:1] == "=":
                 sMsg = prepareFunction(sMsg[1:])
-                lFUNCTIONS.append(("m_"+sIdAction, sMsg))
-                for x in re.finditer("group[(](\d+)[)]", sMsg):
-                    if int(x.group(1)) > nGroup:
-                        print("# Error in groups in message at line " + sIdAction + " ("+str(nGroup)+" groups only)")
-                sMsg = "=m_"+sIdAction
+                lFUNCTIONS.append(("_m_"+sIdAction, sMsg))
+                sMsg = "=_m_"+sIdAction
             else:
-                for x in re.finditer(r"\\(\d+)", sMsg):
-                    if int(x.group(1)) > nGroup:
-                        print("# Error in groups in message at line " + sIdAction + " ("+str(nGroup)+" groups only)")
-                if re.search("[.]\\w+[(]", sMsg):
-                    print("# Error in message at line " + sIdAction + ":  This message looks like code. Line should begin with =")
-            
+                checkIfThereIsCode(sMsg, sIdAction)
+
+    checkReferenceNumbers(sAction, sIdAction, nGroup)
     if sAction[0:1] == "=" or cAction == "=":
-        if "define" in sAction and not re.search(r"define\(\\\d+ *, *\[.*\] *\)", sAction):
-            print("# Error in action at line " + sIdAction + ": second argument for define must be a list of strings")
         sAction = prepareFunction(sAction)
         sAction = sAction.replace("m.group(i[4])", "m.group("+str(iGroup)+")")
-        for x in re.finditer("group[(](\d+)[)]", sAction):
-            if int(x.group(1)) > nGroup:
-                print("# Error in groups in replacement at line " + sIdAction + " ("+str(nGroup)+" groups only)")
     else:
-        for x in re.finditer(r"\\(\d+)", sAction):
-            if int(x.group(1)) > nGroup:
-                print("# Error in groups in replacement at line " + sIdAction + " ("+str(nGroup)+" groups only)")
-        if re.search("[.]\\w+[(]|sugg\\w+[(]", sAction):
-            print("# Error in action at line " + sIdAction + ":  This action looks like code. Line should begin with =")
+        checkIfThereIsCode(sAction, sIdAction)
+
+    if cAction == ">":
+        ## no action, break loop if condition is False
+        return [sCondition, cAction, ""]
+
+    if not sAction:
+        print("# Error in action at line " + sIdAction + ":  This action is empty.")
+        return None
 
     if cAction == "-":
         ## error detected --> suggestion
-        if not sAction:
-            print("# Error in action at line " + sIdAction + ":  This action is empty.")
         if sAction[0:1] == "=":
-            lFUNCTIONS.append(("s_"+sIdAction, sAction[1:]))
-            sAction = "=s_"+sIdAction
+            lFUNCTIONS.append(("_s_"+sIdAction, sAction[1:]))
+            sAction = "=_s_"+sIdAction
         elif sAction.startswith('"') and sAction.endswith('"'):
             sAction = sAction[1:-1]
         if not sMsg:
             print("# Error in action at line " + sIdAction + ":  the message is empty.")
         return [sCondition, cAction, sAction, iGroup, sMsg, sURL]
     elif cAction == "~":
         ## text processor
-        if not sAction:
-            print("# Error in action at line " + sIdAction + ":  This action is empty.")
         if sAction[0:1] == "=":
-            lFUNCTIONS.append(("p_"+sIdAction, sAction[1:]))
-            sAction = "=p_"+sIdAction
+            lFUNCTIONS.append(("_p_"+sIdAction, sAction[1:]))
+            sAction = "=_p_"+sIdAction
         elif sAction.startswith('"') and sAction.endswith('"'):
             sAction = sAction[1:-1]
         return [sCondition, cAction, sAction, iGroup]
     elif cAction == "=":
         ## disambiguator
         if sAction[0:1] == "=":
             sAction = sAction[1:]
-        if not sAction:
-            print("# Error in action at line " + sIdAction + ":  This action is empty.")
-        lFUNCTIONS.append(("d_"+sIdAction, sAction))
-        sAction = "d_"+sIdAction
+        if "define" in sAction and not re.search(r"define\(dTokenPos, *m\.start.*, \[.*\] *\)", sAction):
+            print("# Error in action at line " + sIdAction + ": second argument for define must be a list of strings")
+            print(sAction)
+        lFUNCTIONS.append(("_d_"+sIdAction, sAction))
+        sAction = "_d_"+sIdAction
         return [sCondition, cAction, sAction]
-    elif cAction == ">":
-        ## no action, break loop if condition is False
-        return [sCondition, cAction, ""]
     else:
         print("# Unknown action at line " + sIdAction)
         return None
 
 
 def _calcRulesStats (lRules):
+    "count rules and actions"
     d = {'=':0, '~': 0, '-': 0, '>': 0}
     for aRule in lRules:
-        for aAction in aRule[6]:
-            d[aAction[1]] = d[aAction[1]] + 1
+        if aRule[0] != "@@@@":
+            for aAction in aRule[6]:
+                d[aAction[1]] = d[aAction[1]] + 1
     return (d, len(lRules))
 
 
 def displayStats (lParagraphRules, lSentenceRules):
+    "display rules numbers"
     print("  {:>18} {:>18} {:>18} {:>18}".format("DISAMBIGUATOR", "TEXT PROCESSOR", "GRAMMAR CHECKING", "REGEX"))
     d, nRule = _calcRulesStats(lParagraphRules)
     print("§ {:>10} actions {:>10} actions {:>10} actions  in {:>8} rules".format(d['='], d['~'], d['-'], nRule))
     d, nRule = _calcRulesStats(lSentenceRules)
     print("s {:>10} actions {:>10} actions {:>10} actions  in {:>8} rules".format(d['='], d['~'], d['-'], nRule))
@@ -391,11 +407,11 @@
         elif sLine.startswith("OPTSOFTWARE:"):
             lOpt = [ [s, {}]  for s in sLine[12:].strip().split() ]  # don’t use tuples (s, {}), because unknown to JS
         elif sLine.startswith("OPT/"):
             m = re.match("OPT/([a-z0-9]+):(.+)$", sLine)
             for i, sOpt in enumerate(m.group(2).split()):
-                lOpt[i][1][m.group(1)] =  eval(sOpt)
+                lOpt[i][1][m.group(1)] = eval(sOpt)
         elif sLine.startswith("OPTPRIORITY/"):
             m = re.match("OPTPRIORITY/([a-z0-9]+): *([0-9])$", sLine)
             dOptPriority[m.group(1)] = int(m.group(2))
         elif sLine.startswith("OPTLANG/"):
             m = re.match("OPTLANG/([a-z][a-z](?:_[A-Z][A-Z]|)):(.+)$", sLine)
@@ -415,10 +431,11 @@
     dOptions.update({ "dOpt"+k: v  for k, v in lOpt })
     return dOptions, dOptPriority
 
 
 def printBookmark (nLevel, sComment, nLine):
+    "print bookmark within the rules file"
     print("  {:>6}:  {}".format(nLine, "  " * nLevel + sComment))
 
 
 def make (spLang, sLang, bJavaScript):
     "compile rules, returns a dictionary of values"
@@ -431,52 +448,73 @@
         print("Error. Rules file in project [" + sLang + "] not found.")
         exit()
 
     # removing comments, zeroing empty lines, creating definitions, storing tests, merging rule lines
     print("  parsing rules...")
-    global dDEF
-    lLine = []
     lRuleLine = []
     lTest = []
     lOpt = []
-    zBookmark = re.compile("^!!+")
-    zGraphLink = re.compile(r"^@@@@GRAPHLINK>(\w+)@@@@")
+    bGraph = False
+    lGraphRule = []
 
     for i, sLine in enumerate(lRules, 1):
         if sLine.startswith('#END'):
+            # arbitrary end
             printBookmark(0, "BREAK BY #END", i)
             break
         elif sLine.startswith("#"):
+            # comment
             pass
-        elif sLine.startswith("@@@@"):
-            m = re.match(r"^@@@@GRAPHLINK>(\w+)@@@@", sLine.strip())
-            if m:
-                #lRuleLine.append(["@GRAPHLINK", m.group(1)])
-                printBookmark(1, "@GRAPHLINK: " + m.group(1), i)
         elif sLine.startswith("DEF:"):
+            # definition
             m = re.match("DEF: +([a-zA-Z_][a-zA-Z_0-9]*) +(.+)$", sLine.strip())
             if m:
                 dDEF["{"+m.group(1)+"}"] = m.group(2)
             else:
                 print("Error in definition: ", end="")
                 print(sLine.strip())
         elif sLine.startswith("TEST:"):
+            # test
             lTest.append("{:<8}".format(i) + "  " + sLine[5:].strip())
         elif sLine.startswith("TODO:"):
+            # todo
             pass
         elif sLine.startswith(("OPTGROUP/", "OPTSOFTWARE:", "OPT/", "OPTLANG/", "OPTDEFAULTUILANG:", "OPTLABEL/", "OPTPRIORITY/")):
+            # options
             lOpt.append(sLine)
-        elif re.match("[  \t]*$", sLine):
-            pass
         elif sLine.startswith("!!"):
-            m = zBookmark.search(sLine)
+            # bookmark
+            m = re.match("!!+", sLine)
             nExMk = len(m.group(0))
             if sLine[nExMk:].strip():
-                printBookmark(nExMk-2, sLine[nExMk:].strip(), i)
+                printBookmark(nExMk-2, sLine[nExMk:-3].strip(), i)
+        # Graph rules
+        elif sLine.startswith("@@@@GRAPH:"):
+            # rules graph call
+            m = re.match(r"@@@@GRAPH: *(\w+)", sLine.strip())
+            if m:
+                printBookmark(1, "____ GRAPH: " + m.group(1) + " ____", i)
+                lRuleLine.append([i, "@@@@"+m.group(1)])
+                bGraph = True
+            lGraphRule.append([i, sLine])
+            bGraph = True
+        elif sLine.startswith("@@@@END_GRAPH"):
+            #lGraphRule.append([i, sLine])
+            bGraph = False
+        elif re.match("@@@@ *$", sLine):
+            pass
+        elif bGraph:
+            lGraphRule.append([i, sLine])
+        # Regex rules
+        elif re.match("[  \t]*$", sLine):
+            # empty line
+            pass
         elif sLine.startswith(("    ", "\t")):
-            lRuleLine[len(lRuleLine)-1][1] += " " + sLine.strip()
+            # rule (continuation)
+            lRuleLine[-1][1] += " " + sLine.strip()
         else:
+            # new rule
             lRuleLine.append([i, sLine.strip()])
 
     # generating options files
     print("  parsing options...")
     try:
@@ -515,21 +553,20 @@
     # creating file with all functions callable by rules
     print("  creating callables...")
     sPyCallables = "# generated code, do not edit\n"
     sJSCallables = "// generated code, do not edit\nconst oEvalFunc = {\n"
     for sFuncName, sReturn in lFUNCTIONS:
-        cType = sFuncName[0:1]
-        if cType == "c": # condition
-            sParams = "s, sx, m, dDA, sCountry, bCondMemo"
-        elif cType == "m": # message
-            sParams = "s, m"
-        elif cType == "s": # suggestion
-            sParams = "s, m"
-        elif cType == "p": # preprocessor
-            sParams = "s, m"
-        elif cType == "d": # disambiguator
-            sParams = "s, m, dDA"
+        if sFuncName.startswith("_c_"): # condition
+            sParams = "s, sx, m, dTokenPos, sCountry, bCondMemo"
+        elif sFuncName.startswith("_m_"): # message
+            sParams = "s, m"
+        elif sFuncName.startswith("_s_"): # suggestion
+            sParams = "s, m"
+        elif sFuncName.startswith("_p_"): # preprocessor
+            sParams = "s, m"
+        elif sFuncName.startswith("_d_"): # disambiguator
+            sParams = "s, m, dTokenPos"
         else:
             print("# Unknown function type in [" + sFuncName + "]")
             continue
         sPyCallables += "def {} ({}):\n".format(sFuncName, sParams)
         sPyCallables += "    return " + sReturn + "\n"
@@ -540,16 +577,20 @@
 
     displayStats(lParagraphRules, lSentenceRules)
 
     print("Unnamed rules: " + str(nRULEWITHOUTNAME))
 
-    d = { "callables": sPyCallables,
-          "callablesJS": sJSCallables,
-          "gctests": sGCTests,
-          "gctestsJS": sGCTestsJS,
-          "paragraph_rules": mergeRulesByOption(lParagraphRules),
-          "sentence_rules": mergeRulesByOption(lSentenceRules),
-          "paragraph_rules_JS": jsconv.writeRulesToJSArray(mergeRulesByOption(lParagraphRulesJS)),
-          "sentence_rules_JS": jsconv.writeRulesToJSArray(mergeRulesByOption(lSentenceRulesJS)) }
-    d.update(dOptions)
-
-    return d
+    dVars = {   "callables": sPyCallables,
+                "callablesJS": sJSCallables,
+                "gctests": sGCTests,
+                "gctestsJS": sGCTestsJS,
+                "paragraph_rules": mergeRulesByOption(lParagraphRules),
+                "sentence_rules": mergeRulesByOption(lSentenceRules),
+                "paragraph_rules_JS": jsconv.writeRulesToJSArray(mergeRulesByOption(lParagraphRulesJS)),
+                "sentence_rules_JS": jsconv.writeRulesToJSArray(mergeRulesByOption(lSentenceRulesJS)) }
+    dVars.update(dOptions)
+
+    # compile graph rules
+    dVars2 = crg.make(lGraphRule, dDEF, sLang, bJavaScript)
+    dVars.update(dVars2)
+
+    return dVars

ADDED   compile_rules_graph.py
Index: compile_rules_graph.py
==================================================================
--- /dev/null
+++ compile_rules_graph.py
@@ -0,0 +1,392 @@
+"""
+Grammalecte: compile rules
+Create a Direct Acyclic Rule Graphs (DARGs)
+"""
+
+import re
+import traceback
+import json
+
+import darg
+
+
+dACTIONS = {}
+dFUNCTIONS = {}
+
+
+def prepareFunction (s, bTokenValue=False):
+    "convert simple rule syntax to a string of Python code"
+    s = s.replace("__also__", "bCondMemo")
+    s = s.replace("__else__", "not bCondMemo")
+    s = re.sub(r"(morph|analyse|value|displayInfo)[(]\\(\d+)", 'g_\\1(lToken[\\2+nTokenOffset]', s)
+    s = re.sub(r"(select|exclude|define)[(][\\](\d+)", 'g_\\1(lToken[\\2+nTokenOffset]', s)
+    s = re.sub(r"(tag_before|tag_after)[(][\\](\d+)", 'g_\\1(lToken[\\2+nTokenOffset], dTags', s)
+    s = re.sub(r"(switchGender|has(?:(?:Mas|Fem)Form)|Simil)[(]\\(\d+)", '\\1(lToken[\\2+nTokenOffset]["sValue"]', s)
+    s = re.sub(r"(morph|analyse|value)\(>1", 'g_\\1(lToken[nLastToken+1]', s)                       # next token
+    s = re.sub(r"(morph|analyse|value)\(<1", 'g_\\1(lToken[nTokenOffset]', s)                       # previous token
+    s = re.sub(r"[\\](\d+)\.is(upper|lower|title)\(\)", 'lToken[\\1+nTokenOffset]["sValue"].is\\2()', s)
+    s = re.sub(r"[\\](\d+)\.(startswith|endswith)\(", 'lToken[\\1+nTokenOffset]["sValue"].\\2(', s)
+    s = re.sub(r"\bspell *[(]", '_oSpellChecker.isValid(', s)
+    s = re.sub(r"\bbefore\(\s*", 'look(sSentence[:lToken[1+nTokenOffset]["nStart"]], ', s)          # before(s)
+    s = re.sub(r"\bafter\(\s*", 'look(sSentence[lToken[nLastToken]["nEnd"]:], ', s)                 # after(s)
+    s = re.sub(r"\bbefore0\(\s*", 'look(sSentence0[:lToken[1+nTokenOffset]["nStart"]], ', s)        # before0(s)
+    s = re.sub(r"\bafter0\(\s*", 'look(sSentence[lToken[nLastToken]["nEnd"]:], ', s)                # after0(s)
+    if bTokenValue:
+        # token values are used as parameter
+        s = re.sub(r"[\\](\d+)", 'lToken[\\1+nTokenOffset]["sValue"]', s)
+    else:
+        # tokens used as parameter
+        s = re.sub(r"[\\](\d+)", 'lToken[\\1+nTokenOffset]', s)
+    return s
+
+
+def genTokenLines (sTokenLine, dDef):
+    "tokenize a string and return a list of lines of tokens"
+    lToken = sTokenLine.split()
+    lTokenLines = None
+    for sToken in lToken:
+        # optional token?
+        bNullPossible = sToken.startswith("?") and sToken.endswith("¿")
+        if bNullPossible:
+            sToken = sToken[1:-1]
+        # token with definition?
+        if sToken.startswith("({") and sToken.endswith("})") and sToken[1:-1] in dDef:
+            sToken = "(" + dDef[sToken[1:-1]] + ")"
+        elif sToken.startswith("{") and sToken.endswith("}") and sToken in dDef:
+            sToken = dDef[sToken]
+        if ( (sToken.startswith("[") and sToken.endswith("]")) or (sToken.startswith("([") and sToken.endswith("])")) ):
+            # multiple token
+            bSelectedGroup = sToken.startswith("(") and sToken.endswith(")")
+            if bSelectedGroup:
+                sToken = sToken[1:-1]
+            lNewToken = sToken[1:-1].split("|")
+            if not lTokenLines:
+                lTokenLines = [ [s]  for s  in lNewToken ]
+                if bNullPossible:
+                    lTokenLines.extend([ []  for i  in range(len(lNewToken)+1) ])
+            else:
+                lNewTemp = []
+                if bNullPossible:
+                    for aRule in lTokenLines:
+                        for sElem in lNewToken:
+                            aNewRule = list(aRule)
+                            aNewRule.append(sElem)
+                            lNewTemp.append(aNewRule)
+                else:
+                    sElem1 = lNewToken.pop(0)
+                    for aRule in lTokenLines:
+                        for sElem in lNewToken:
+                            aNewRule = list(aRule)
+                            aNewRule.append("(" + sElem + ")"  if bSelectedGroup  else sElem)
+                            lNewTemp.append(aNewRule)
+                        aRule.append("(" + sElem1 + ")"  if bSelectedGroup  else sElem1)
+                lTokenLines.extend(lNewTemp)
+        else:
+            # simple token
+            if not lTokenLines:
+                lTokenLines = [[sToken], []]  if bNullPossible  else [[sToken]]
+            else:
+                if bNullPossible:
+                    lNewTemp = []
+                    for aRule in lTokenLines:
+                        lNew = list(aRule)
+                        lNew.append(sToken)
+                        lNewTemp.append(lNew)
+                    lTokenLines.extend(lNewTemp)
+                else:
+                    for aRule in lTokenLines:
+                        aRule.append(sToken)
+    for aRule in lTokenLines:
+        yield aRule
+
+
+def createRule (iLine, sRuleName, sTokenLine, iActionBlock, sActions, nPriority, dDef):
+    "generator: create rule as list"
+    # print(iLine, "//", sRuleName, "//", sTokenLine, "//", sActions, "//", nPriority)
+    for lToken in genTokenLines(sTokenLine, dDef):
+        # Calculate positions
+        dPos = {}   # key: iGroup, value: iToken
+        iGroup = 0
+        for i, sToken in enumerate(lToken):
+            if sToken.startswith("(") and sToken.endswith(")"):
+                lToken[i] = sToken[1:-1]
+                iGroup += 1
+                dPos[iGroup] = i + 1    # we add 1, for we count tokens from 1 to n (not from 0)
+
+        # Parse actions
+        for iAction, sAction in enumerate(sActions.split(" <<- ")):
+            sAction = sAction.strip()
+            if sAction:
+                sActionId = sRuleName + "__b" + str(iActionBlock) + "_a" + str(iAction) + "_" + str(len(lToken))
+                aAction = createAction(sActionId, sAction, nPriority, len(lToken), dPos)
+                if aAction:
+                    dACTIONS[sActionId] = aAction
+                    lResult = list(lToken)
+                    lResult.extend(["##"+str(iLine), sActionId])
+                    yield lResult
+
+
+def changeReferenceToken (sText, dPos):
+    "change group reference in <sText> with values in <dPos>"
+    for i in range(len(dPos), 0, -1):
+        sText = sText.replace("\\"+str(i), "\\"+str(dPos[i]))
+    return sText
+
+
+def checkTokenNumbers (sText, sActionId, nToken):
+    "check if token references in <sText> greater than <nToken> (debugging)"
+    for x in re.finditer(r"\\(\d+)", sText):
+        if int(x.group(1)) > nToken:
+            print("# Error in token index at line " + sActionId + " ("+str(nToken)+" tokens only)")
+            print(sText)
+
+
+def checkIfThereIsCode (sText, sActionId):
+    "check if there is code in <sText> (debugging)"
+    if re.search("[.]\\w+[(]|sugg\\w+[(]|\\([0-9]|\\[[0-9]", sText):
+        print("# Warning at line " + sActionId + ":  This message looks like code. Line should probably begin with =")
+        print(sText)
+
+
+def createAction (sActionId, sAction, nPriority, nToken, dPos):
+    "create action rule as a list"
+    # Option
+    sOption = False
+    m = re.match("/(\\w+)/", sAction)
+    if m:
+        sOption = m.group(1)
+        sAction = sAction[m.end():].strip()
+    # valid action?
+    m = re.search(r"(?P<action>[-~=/>])(?P<start>\d+|)(?P<end>:\d+|)>>", sAction)
+    if not m:
+        print(" # Error. No action found at: ", sActionId)
+        print("   ==", sAction, "==")
+        return None
+    # Condition
+    sCondition = sAction[:m.start()].strip()
+    if sCondition:
+        sCondition = prepareFunction(sCondition)
+        sCondition = changeReferenceToken(sCondition, dPos)
+        dFUNCTIONS["_g_c_"+sActionId] = sCondition
+        sCondition = "_g_c_"+sActionId
+    else:
+        sCondition = ""
+    # Action
+    cAction = m.group("action")
+    sAction = sAction[m.end():].strip()
+    sAction = changeReferenceToken(sAction, dPos)
+    if not m.group("start"):
+        iStartAction = 1
+        iEndAction = 0
+    else:
+        iStartAction = int(m.group("start"))
+        iEndAction = int(m.group("end")[1:])  if m.group("end")  else iStartAction
+    if dPos and m.group("start"):
+        try:
+            iStartAction = dPos[iStartAction]
+            if iEndAction:
+                iEndAction = dPos[iEndAction]
+        except:
+            print("# Error. Wrong groups in: " + sActionId)
+            print("  iStartAction:", iStartAction, "iEndAction:", iEndAction)
+            print(" ", dPos)
+
+    if cAction == "-":
+        ## error
+        iMsg = sAction.find(" # ")
+        if iMsg == -1:
+            sMsg = "# Error. Error message not found."
+            sURL = ""
+            print(sMsg + " Action id: " + sActionId)
+        else:
+            sMsg = sAction[iMsg+3:].strip()
+            sAction = sAction[:iMsg].strip()
+            sURL = ""
+            mURL = re.search("[|] *(https?://.*)", sMsg)
+            if mURL:
+                sURL = mURL.group(1).strip()
+                sMsg = sMsg[:mURL.start(0)].strip()
+            checkTokenNumbers(sMsg, sActionId, nToken)
+            if sMsg[0:1] == "=":
+                sMsg = prepareFunction(sMsg[1:], True)
+                dFUNCTIONS["g_m_"+sActionId] = sMsg
+                sMsg = "=g_m_"+sActionId
+            else:
+                checkIfThereIsCode(sMsg, sActionId)
+
+    # checking consistancy
+    checkTokenNumbers(sAction, sActionId, nToken)
+
+    if cAction == ">":
+        ## no action, break loop if condition is False
+        return [sOption, sCondition, cAction, ""]
+
+    if not sAction:
+        print("# Error in action at line " + sActionId + ":  This action is empty.")
+
+    if sAction[0:1] != "=":
+        checkIfThereIsCode(sAction, sActionId)
+
+    if cAction == "-":
+        ## error detected --> suggestion
+        if sAction[0:1] == "=":
+            sAction = prepareFunction(sAction, True)
+            dFUNCTIONS["_g_s_"+sActionId] = sAction[1:]
+            sAction = "=_g_s_"+sActionId
+        elif sAction.startswith('"') and sAction.endswith('"'):
+            sAction = sAction[1:-1]
+        if not sMsg:
+            print("# Error in action at line " + sActionId + ":  The message is empty.")
+        return [sOption, sCondition, cAction, sAction, iStartAction, iEndAction, nPriority, sMsg, sURL]
+    elif cAction == "~":
+        ## text processor
+        if sAction[0:1] == "=":
+            sAction = prepareFunction(sAction, True)
+            dFUNCTIONS["_g_p_"+sActionId] = sAction[1:]
+            sAction = "=_g_p_"+sActionId
+        elif sAction.startswith('"') and sAction.endswith('"'):
+            sAction = sAction[1:-1]
+        return [sOption, sCondition, cAction, sAction, iStartAction, iEndAction]
+    elif cAction == "/":
+        ## tags
+        return [sOption, sCondition, cAction, sAction, iStartAction, iEndAction]
+    elif cAction == "=":
+        ## disambiguator
+        if sAction[0:1] == "=":
+            sAction = sAction[1:]
+        if "define" in sAction and not re.search(r"define\(\\\d+ *, *\[.*\] *\)", sAction):
+            print("# Error in action at line " + sActionId + ": second argument for <define> must be a list of strings")
+        sAction = prepareFunction(sAction)
+        dFUNCTIONS["_g_d_"+sActionId] = sAction
+        sAction = "_g_d_"+sActionId
+        return [sOption, sCondition, cAction, sAction]
+    else:
+        print("# Unknown action at line " + sActionId)
+        return None
+
+
+def make (lRule, dDef, sLang, bJavaScript):
+    "compile rules, returns a dictionary of values"
+    # for clarity purpose, don’t create any file here
+
+    # removing comments, zeroing empty lines, creating definitions, storing tests, merging rule lines
+    print("  parsing rules...")
+    lTokenLine = []
+    sActions = ""
+    nPriority = 4
+    dAllGraph = {}
+    sGraphName = ""
+    iActionBlock = 0
+
+    for i, sLine in lRule:
+        sLine = sLine.rstrip()
+        if "\t" in sLine:
+            # tabulation not allowed
+            print("Error. Tabulation at line: ", i)
+            exit()
+        elif sLine.startswith("@@@@GRAPH: "):
+            # rules graph call
+            m = re.match(r"@@@@GRAPH: *(\w+)", sLine.strip())
+            if m:
+                sGraphName = m.group(1)
+                if sGraphName in dAllGraph:
+                    print("Error. Group name " + sGraphName + " already exists.")
+                    exit()
+                dAllGraph[sGraphName] = []
+            else:
+                print("Error. Graph name not found at line", i)
+                exit()
+        elif sLine.startswith("__") and sLine.endswith("__"):
+            # new rule group
+            m = re.match("__(\\w+)(!\\d|)__", sLine)
+            if m:
+                sRuleName = m.group(1)
+                iActionBlock = 1
+                nPriority = int(m.group(2)[1:]) if m.group(2)  else 4
+            else:
+                print("Error at rule group: ", sLine, " -- line:", i)
+                break
+        elif re.search("^    +<<- ", sLine) or sLine.startswith("        ") \
+                or re.search("^    +#", sLine) or re.search(r"^    [-~=>/](?:\d(?::\d+|)|)>> ", sLine) :
+            # actions
+            sActions += " " + sLine.strip()
+        elif re.match("[  ]*$", sLine):
+            # empty line to end merging
+            if not lTokenLine:
+                continue
+            if not sActions:
+                print("Error. No action found at line:", i)
+                exit()
+            if not sGraphName:
+                print("Error. All rules must belong to a named graph. Line: ", i)
+                exit()
+            for j, sTokenLine in lTokenLine:
+                dAllGraph[sGraphName].append((j, sRuleName, sTokenLine, iActionBlock, sActions, nPriority))
+            lTokenLine.clear()
+            sActions = ""
+            iActionBlock += 1
+        elif sLine.startswith(("    ")):
+            # tokens
+            lTokenLine.append([i, sLine.strip()])
+        else:
+            print("Unknown line:")
+            print(sLine)
+
+    # processing rules
+    print("  preparing rules...")
+    for sGraphName, lRuleLine in dAllGraph.items():
+        lPreparedRule = []
+        for i, sRuleGroup, sTokenLine, iActionBlock, sActions, nPriority in lRuleLine:
+            for lRule in createRule(i, sRuleGroup, sTokenLine, iActionBlock, sActions, nPriority, dDef):
+                lPreparedRule.append(lRule)
+        # Graph creation
+        oDARG = darg.DARG(lPreparedRule, sLang)
+        dAllGraph[sGraphName] = oDARG.createGraph()
+        # Debugging
+        #print("\nGRAPH:", sGraphName)
+        #for e in lPreparedRule:
+        #    if e[-2] == "##4239":
+        #        print(e)
+        #    print(e)
+        #for k, v in dAllGraph[sGraphName].items():
+        #    print(k, "\t", v)
+
+    # creating file with all functions callable by rules
+    print("  creating callables...")
+    sPyCallables = "# generated code, do not edit\n"
+    #sJSCallables = "// generated code, do not edit\nconst oEvalFunc = {\n"
+    for sFuncName, sReturn in dFUNCTIONS.items():
+        if sFuncName.startswith("_g_c_"): # condition
+            sParams = "lToken, nTokenOffset, nLastToken, sCountry, bCondMemo, dTags, sSentence, sSentence0"
+        elif sFuncName.startswith("g_m_"): # message
+            sParams = "lToken, nTokenOffset"
+        elif sFuncName.startswith("_g_s_"): # suggestion
+            sParams = "lToken, nTokenOffset"
+        elif sFuncName.startswith("_g_p_"): # preprocessor
+            sParams = "lToken, nTokenOffset"
+        elif sFuncName.startswith("_g_d_"): # disambiguator
+            sParams = "lToken, nTokenOffset"
+        else:
+            print("# Unknown function type in [" + sFuncName + "]")
+            continue
+        sPyCallables += "def {} ({}):\n".format(sFuncName, sParams)
+        sPyCallables += "    return " + sReturn + "\n"
+        #sJSCallables += "    {}: function ({})".format(sFuncName, sParams) + " {\n"
+        #sJSCallables += "        return " + jsconv.py2js(sReturn) + ";\n"
+        #sJSCallables += "    },\n"
+    #sJSCallables += "}\n"
+
+    # Debugging
+    if False:
+        print("\nActions:")
+        for sActionName, aAction in dACTIONS.items():
+            print(sActionName, aAction)
+        print("\nFunctions:")
+        print(sPyCallables)
+
+    # Result
+    return {
+        "graph_callables": sPyCallables,
+        "rules_graphs": dAllGraph,
+        "rules_actions": dACTIONS
+    }

Index: compile_rules_js_convert.py
==================================================================
--- compile_rules_js_convert.py
+++ compile_rules_js_convert.py
@@ -1,6 +1,8 @@
-# Convert Python code to JavaScript code
+"""
+Convert Python code and regexes to JavaScript code
+"""
 
 import copy
 import re
 import json
 
@@ -116,11 +118,15 @@
         lNegLookBeforeRegex = None
     return (sRegex, lNegLookBeforeRegex)
 
 
 def pyRuleToJS (lRule, dJSREGEXES, sWORDLIMITLEFT):
+    "modify Python rules -> JS rules"
     lRuleJS = copy.deepcopy(lRule)
+    # graph rules
+    if lRuleJS[0] == "@@@@":
+        return lRuleJS
     del lRule[-1] # tGroups positioning codes are useless for Python
     # error messages
     for aAction in lRuleJS[6]:
         if aAction[1] == "-":
             aAction[2] = aAction[2].replace(" ", " ") # nbsp --> nnbsp
@@ -130,27 +136,35 @@
     lRuleJS.append(lNegLookBehindRegex)
     return lRuleJS
 
 
 def writeRulesToJSArray (lRules):
+    "create rules as a string of arrays (to be bundled in a JSON string)"
     sArray = "[\n"
     for sOption, aRuleGroup in lRules:
-        sArray += '  ["' + sOption + '", [\n'  if sOption  else  "  [false, [\n"
-        for sRegex, bCaseInsensitive, sLineId, sRuleId, nPriority, lActions, aGroups, aNegLookBehindRegex in aRuleGroup:
-            sArray += '    [' + sRegex + ", "
-            sArray += "true, " if bCaseInsensitive  else "false, "
-            sArray += '"' + sLineId + '", '
-            sArray += '"' + sRuleId + '", '
-            sArray += str(nPriority) + ", "
-            sArray += json.dumps(lActions, ensure_ascii=False) + ", "
-            sArray += json.dumps(aGroups, ensure_ascii=False) + ", "
-            sArray += json.dumps(aNegLookBehindRegex, ensure_ascii=False) + "],\n"
-        sArray += "  ]],\n"
+        if sOption != "@@@@":
+            sArray += '  ["' + sOption + '", [\n'  if sOption  else  "  [false, [\n"
+            for sRegex, bCaseInsensitive, sLineId, sRuleId, nPriority, lActions, aGroups, aNegLookBehindRegex in aRuleGroup:
+                sArray += '    [' + sRegex + ", "
+                sArray += "true, " if bCaseInsensitive  else "false, "
+                sArray += '"' + sLineId + '", '
+                sArray += '"' + sRuleId + '", '
+                sArray += str(nPriority) + ", "
+                sArray += json.dumps(lActions, ensure_ascii=False) + ", "
+                sArray += json.dumps(aGroups, ensure_ascii=False) + ", "
+                sArray += json.dumps(aNegLookBehindRegex, ensure_ascii=False) + "],\n"
+            sArray += "  ]],\n"
+        else:
+            sArray += '  ["' + sOption + '", [\n'
+            for sGraphName, sLineId in aRuleGroup:
+                sArray += '    ["' + sGraphName + '", "' + sLineId + '"],\n"'
+            sArray += "  ]],\n"
     sArray += "]"
     return sArray
 
 
 def groupsPositioningCodeToList (sGroupsPositioningCode):
+    "convert <sGroupsPositioningCode> to a list of codes (numbers or strings)"
     if not sGroupsPositioningCode:
         return None
     return [ int(sCode)  if sCode.isdigit() or (sCode[0:1] == "-" and sCode[1:].isdigit())  else sCode \
              for sCode in sGroupsPositioningCode.split(",") ]

ADDED   darg.py
Index: darg.py
==================================================================
--- /dev/null
+++ darg.py
@@ -0,0 +1,254 @@
+#!python3
+
+"""
+RULE GRAPH BUILDER
+"""
+
+# by Olivier R.
+# License: MPL 2
+
+import re
+import traceback
+
+
+from graphspell.progressbar import ProgressBar
+
+
+class DARG:
+    """DIRECT ACYCLIC RULE GRAPH"""
+    # This code is inspired from Steve Hanov’s DAWG, 2011. (http://stevehanov.ca/blog/index.php?id=115)
+
+    def __init__ (self, lRule, sLangCode):
+        print("===== Direct Acyclic Rule Graph - Minimal Acyclic Finite State Automaton =====")
+
+        # Preparing DARG
+        print(" > Preparing list of tokens")
+        self.sLangCode = sLangCode
+        self.nRule = len(lRule)
+        self.aPreviousRule = []
+        Node.resetNextId()
+        self.oRoot = Node()
+        self.lUncheckedNodes = []  # list of nodes that have not been checked for duplication.
+        self.lMinimizedNodes = {}  # list of unique nodes that have been checked for duplication.
+        self.nNode = 0
+        self.nArc = 0
+
+        # build
+        lRule.sort()
+        oProgBar = ProgressBar(0, len(lRule))
+        for aRule in lRule:
+            self.insert(aRule)
+            oProgBar.increment(1)
+        oProgBar.done()
+        self.finish()
+        self.countNodes()
+        self.countArcs()
+        self.displayInfo()
+
+    # BUILD DARG
+    def insert (self, aRule):
+        "insert a new rule (tokens must be inserted in order)"
+        if aRule < self.aPreviousRule:
+            exit("# Error: tokens must be inserted in order.")
+
+        # find common prefix between word and previous word
+        nCommonPrefix = 0
+        for i in range(min(len(aRule), len(self.aPreviousRule))):
+            if aRule[i] != self.aPreviousRule[i]:
+                break
+            nCommonPrefix += 1
+
+        # Check the lUncheckedNodes for redundant nodes, proceeding from last
+        # one down to the common prefix size. Then truncate the list at that point.
+        self._minimize(nCommonPrefix)
+
+        # add the suffix, starting from the correct node mid-way through the graph
+        if len(self.lUncheckedNodes) == 0:
+            oNode = self.oRoot
+        else:
+            oNode = self.lUncheckedNodes[-1][2]
+
+        iToken = nCommonPrefix
+        for sToken in aRule[nCommonPrefix:]:
+            oNextNode = Node()
+            oNode.dArcs[sToken] = oNextNode
+            self.lUncheckedNodes.append((oNode, sToken, oNextNode))
+            if iToken == (len(aRule) - 2):
+                oNode.bFinal = True
+            iToken += 1
+            oNode = oNextNode
+        oNode.bFinal = True
+        self.aPreviousRule = aRule
+
+    def finish (self):
+        "minimize unchecked nodes"
+        self._minimize(0)
+
+    def _minimize (self, downTo):
+        # proceed from the leaf up to a certain point
+        for i in range( len(self.lUncheckedNodes)-1, downTo-1, -1 ):
+            oNode, sToken, oChildNode = self.lUncheckedNodes[i]
+            if oChildNode in self.lMinimizedNodes:
+                # replace the child with the previously encountered one
+                oNode.dArcs[sToken] = self.lMinimizedNodes[oChildNode]
+            else:
+                # add the state to the minimized nodes.
+                self.lMinimizedNodes[oChildNode] = oChildNode
+            self.lUncheckedNodes.pop()
+
+    def countNodes (self):
+        "count nodes within the whole graph"
+        self.nNode = len(self.lMinimizedNodes)
+
+    def countArcs (self):
+        "count arcs within the whole graph"
+        self.nArc = 0
+        for oNode in self.lMinimizedNodes:
+            self.nArc += len(oNode.dArcs)
+
+    def displayInfo (self):
+        "display informations about the rule graph"
+        print(" * {:<12} {:>16,}".format("Rules:", self.nRule))
+        print(" * {:<12} {:>16,}".format("Nodes:", self.nNode))
+        print(" * {:<12} {:>16,}".format("Arcs:", self.nArc))
+
+    def createGraph (self):
+        "create the graph as a dictionary"
+        dGraph = { 0: self.oRoot.getNodeAsDict() }
+        for oNode in self.lMinimizedNodes:
+            sHashId = oNode.__hash__()
+            if sHashId not in dGraph:
+                dGraph[sHashId] = oNode.getNodeAsDict()
+            else:
+                print("Error. Double node… same id: ", sHashId)
+                print(str(oNode.getNodeAsDict()))
+        dGraph = self._rewriteKeysOfDARG(dGraph)
+        self._checkRegexes(dGraph)
+        return dGraph
+
+    def _rewriteKeysOfDARG (self, dGraph):
+        "keys of DARG are long numbers (hashes): this function replace these hashes with smaller numbers (to reduce storing size)"
+        # create translation dictionary
+        dKeyTrans = {}
+        for i, nKey in enumerate(dGraph):
+            dKeyTrans[nKey] = i
+        # replace keys
+        dNewGraph = {}
+        for nKey, dVal in dGraph.items():
+            dNewGraph[dKeyTrans[nKey]] = dVal
+        for nKey, dVal in dGraph.items():
+            for sArc, val in dVal.items():
+                if type(val) is int:
+                    dVal[sArc] = dKeyTrans[val]
+                else:
+                    for sArc, nKey in val.items():
+                        val[sArc] = dKeyTrans[nKey]
+        return dNewGraph
+
+    def _checkRegexes (self, dGraph):
+        "check validity of regexes"
+        aRegex = set()
+        for nKey, dVal in dGraph.items():
+            if "<re_value>" in dVal:
+                for sRegex in dVal["<re_value>"]:
+                    if sRegex not in aRegex:
+                        self._checkRegex(sRegex)
+                        aRegex.add(sRegex)
+            if "<re_morph>" in dVal:
+                for sRegex in dVal["<re_morph>"]:
+                    if sRegex not in aRegex:
+                        self._checkRegex(sRegex)
+                        aRegex.add(sRegex)
+        aRegex.clear()
+
+    def _checkRegex (self, sRegex):
+        #print(sRegex)
+        if "¬" in sRegex:
+            sPattern, sNegPattern = sRegex.split("¬")
+            try:
+                if not sNegPattern:
+                    print("# Warning! Empty negpattern:", sRegex)
+                re.compile(sPattern)
+                if sNegPattern != "*":
+                    re.compile(sNegPattern)
+            except:
+                print("# Error. Wrong regex:", sRegex)
+                exit()
+        else:
+            try:
+                if not sRegex:
+                    print("# Warning! Empty pattern:", sRegex)
+                re.compile(sRegex)
+            except:
+                print("# Error. Wrong regex:", sRegex)
+                exit()
+
+
+class Node:
+    """Node of the rule graph"""
+
+    NextId = 0
+
+    def __init__ (self):
+        self.i = Node.NextId
+        Node.NextId += 1
+        self.bFinal = False
+        self.dArcs = {}          # key: arc value; value: a node
+
+    @classmethod
+    def resetNextId (cls):
+        "reset to 0 the node counter"
+        cls.NextId = 0
+
+    def __str__ (self):
+        # Caution! this function is used for hashing and comparison!
+        cFinal = "1"  if self.bFinal  else "0"
+        l = [cFinal]
+        for (key, oNode) in self.dArcs.items():
+            l.append(str(key))
+            l.append(str(oNode.i))
+        return "_".join(l)
+
+    def __hash__ (self):
+        # Used as a key in a python dictionary.
+        return self.__str__().__hash__()
+
+    def __eq__ (self, other):
+        # Used as a key in a python dictionary.
+        # Nodes are equivalent if they have identical arcs, and each identical arc leads to identical states.
+        return self.__str__() == other.__str__()
+
+    def getNodeAsDict (self):
+        "returns the node as a dictionary structure"
+        dNode = {}
+        dReValue = {}
+        dReMorph = {}
+        dRule = {}
+        dLemma = {}
+        dMeta = {}
+        for sArc, oNode in self.dArcs.items():
+            if sArc.startswith("@") and len(sArc) > 1:
+                dReMorph[sArc[1:]] = oNode.__hash__()
+            elif sArc.startswith("~") and len(sArc) > 1:
+                dReValue[sArc[1:]] = oNode.__hash__()
+            elif sArc.startswith(">") and len(sArc) > 1:
+                dLemma[sArc[1:]] = oNode.__hash__()
+            elif sArc.startswith("*") and len(sArc) > 1:
+                dMeta[sArc[1:]] = oNode.__hash__()
+            elif sArc.startswith("##"):
+                dRule[sArc[1:]] = oNode.__hash__()
+            else:
+                dNode[sArc] = oNode.__hash__()
+        if dReValue:
+            dNode["<re_value>"] = dReValue
+        if dReMorph:
+            dNode["<re_morph>"] = dReMorph
+        if dLemma:
+            dNode["<lemmas>"] = dLemma
+        if dMeta:
+            dNode["<meta>"] = dMeta
+        if dRule:
+            dNode["<rules>"] = dRule
+        #if self.bFinal:
+        #    dNode["<final>"] = 1
+        return dNode

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
@@ -37,11 +37,10 @@
 // data
 let _sAppContext = "";                                  // what software is running
 let _dOptions = null;
 let _aIgnoredRules = new Set();
 let _oSpellChecker = null;
-let _dAnalyses = new Map();                             // cache for data from dictionary
 
 
 var gc_engine = {
 
     //// Informations
@@ -327,10 +326,11 @@
             } else {
                 _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
+            _oSpellChecker.activateStorage();
         }
         catch (e) {
             helpers.logerror(e);
         }
     },
@@ -376,39 +376,30 @@
     // for debugging: info of word
     if (!aWord) {
         helpers.echo("> nothing to find");
         return true;
     }
-    if (!_dAnalyses.has(aWord[1]) && !_storeMorphFromFSA(aWord[1])) {
-        helpers.echo("> not in FSA");
+    let lMorph = _oSpellChecker.getMorph(aWord[1]);
+    if (lMorph.length === 0) {
+        helpers.echo("> not in dictionary");
         return true;
     }
     if (dDA.has(aWord[0])) {
         helpers.echo("DA: " + dDA.get(aWord[0]));
     }
-    helpers.echo("FSA: " + _dAnalyses.get(aWord[1]));
+    helpers.echo("FSA: " + lMorph);
     return true;
 }
 
-function _storeMorphFromFSA (sWord) {
-    // retrieves morphologies list from _oSpellChecker -> _dAnalyses
-    //helpers.echo("register: "+sWord + " " + _oSpellChecker.getMorph(sWord).toString())
-    _dAnalyses.set(sWord, _oSpellChecker.getMorph(sWord));
-    return !!_dAnalyses.get(sWord);
-}
-
 function morph (dDA, aWord, sPattern, bStrict=true, bNoWord=false) {
     // analyse a tuple (position, word), return true if sPattern in morphologies (disambiguation on)
     if (!aWord) {
         //helpers.echo("morph: noword, returns " + bNoWord);
         return bNoWord;
     }
     //helpers.echo("aWord: "+aWord.toString());
-    if (!_dAnalyses.has(aWord[1]) && !_storeMorphFromFSA(aWord[1])) {
-        return false;
-    }
-    let lMorph = dDA.has(aWord[0]) ? dDA.get(aWord[0]) : _dAnalyses.get(aWord[1]);
+    let lMorph = dDA.has(aWord[0]) ? dDA.get(aWord[0]) : _oSpellChecker.getMorph(aWord[1]);
     //helpers.echo("lMorph: "+lMorph.toString());
     if (lMorph.length === 0) {
         return false;
     }
     //helpers.echo("***");
@@ -423,14 +414,11 @@
     if (!aWord) {
         //helpers.echo("morph: noword, returns " + bNoWord);
         return bNoWord;
     }
     //helpers.echo("aWord: "+aWord.toString());
-    if (!_dAnalyses.has(aWord[1]) && !_storeMorphFromFSA(aWord[1])) {
-        return false;
-    }
-    let lMorph = dDA.has(aWord[0]) ? dDA.get(aWord[0]) : _dAnalyses.get(aWord[1]);
+    let lMorph = dDA.has(aWord[0]) ? dDA.get(aWord[0]) : _oSpellChecker.getMorph(aWord[1]);
     //helpers.echo("lMorph: "+lMorph.toString());
     if (lMorph.length === 0) {
         return false;
     }
     //helpers.echo("***");
@@ -442,41 +430,32 @@
     return lMorph.some(s  =>  (s.search(sPattern) !== -1));
 }
 
 function analyse (sWord, sPattern, bStrict=true) {
     // analyse a word, return true if sPattern in morphologies (disambiguation off)
-    if (!_dAnalyses.has(sWord) && !_storeMorphFromFSA(sWord)) {
+    let lMorph = _oSpellChecker.getMorph(sWord);
+    if (lMorph.length === 0) {
         return false;
     }
     if (bStrict) {
-        return _dAnalyses.get(sWord).every(s  =>  (s.search(sPattern) !== -1));
+        return lMorph.every(s  =>  (s.search(sPattern) !== -1));
     }
-    return _dAnalyses.get(sWord).some(s  =>  (s.search(sPattern) !== -1));
+    return lMorph.some(s  =>  (s.search(sPattern) !== -1));
 }
 
 function analysex (sWord, sPattern, sNegPattern) {
     // analyse a word, returns True if not sNegPattern in word morphologies and sPattern in word morphologies (disambiguation off)
-    if (!_dAnalyses.has(sWord) && !_storeMorphFromFSA(sWord)) {
+    let lMorph = _oSpellChecker.getMorph(sWord);
+    if (lMorph.length === 0) {
         return false;
     }
     // check negative condition
-    if (_dAnalyses.get(sWord).some(s  =>  (s.search(sNegPattern) !== -1))) {
+    if (lMorph.some(s  =>  (s.search(sNegPattern) !== -1))) {
         return false;
     }
     // search sPattern
-    return _dAnalyses.get(sWord).some(s  =>  (s.search(sPattern) !== -1));
-}
-
-function stem (sWord) {
-    // returns a list of sWord's stems
-    if (!sWord) {
-        return [];
-    }
-    if (!_dAnalyses.has(sWord) && !_storeMorphFromFSA(sWord)) {
-        return [];
-    }
-    return _dAnalyses.get(sWord).map( s => s.slice(1, s.indexOf(" ")) );
+    return lMorph.some(s  =>  (s.search(sPattern) !== -1));
 }
 
 
 //// functions to get text outside pattern scope
 
@@ -565,19 +544,17 @@
         return true;
     }
     if (dDA.has(nPos)) {
         return true;
     }
-    if (!_dAnalyses.has(sWord) && !_storeMorphFromFSA(sWord)) {
+    let lMorph = _oSpellChecker.getMorph(sWord);
+    if (lMorph.length === 0  ||  lMorph.length === 1) {
         return true;
     }
-    if (_dAnalyses.get(sWord).length === 1) {
-        return true;
-    }
-    let lSelect = _dAnalyses.get(sWord).filter( sMorph => sMorph.search(sPattern) !== -1 );
+    let lSelect = lMorph.filter( sMorph => sMorph.search(sPattern) !== -1 );
     if (lSelect.length > 0) {
-        if (lSelect.length != _dAnalyses.get(sWord).length) {
+        if (lSelect.length != lMorph.length) {
             dDA.set(nPos, lSelect);
         }
     } else if (lDefault) {
         dDA.set(nPos, lDefaul);
     }
@@ -589,19 +566,17 @@
         return true;
     }
     if (dDA.has(nPos)) {
         return true;
     }
-    if (!_dAnalyses.has(sWord) && !_storeMorphFromFSA(sWord)) {
+    let lMorph = _oSpellChecker.getMorph(sWord);
+    if (lMorph.length === 0  ||  lMorph.length === 1) {
         return true;
     }
-    if (_dAnalyses.get(sWord).length === 1) {
-        return true;
-    }
-    let lSelect = _dAnalyses.get(sWord).filter( sMorph => sMorph.search(sPattern) === -1 );
+    let lSelect = lMorph.filter( sMorph => sMorph.search(sPattern) === -1 );
     if (lSelect.length > 0) {
-        if (lSelect.length != _dAnalyses.get(sWord).length) {
+        if (lSelect.length != lMorph.length) {
             dDA.set(nPos, lSelect);
         }
     } else if (lDefault) {
         dDA.set(nPos, lDefault);
     }

Index: gc_core/py/__init__.py
==================================================================
--- gc_core/py/__init__.py
+++ gc_core/py/__init__.py
@@ -1,2 +1,5 @@
+"""
+Grammar checker
+"""
 
 from .grammar_checker import *

Index: gc_core/py/grammar_checker.py
==================================================================
--- gc_core/py/grammar_checker.py
+++ gc_core/py/grammar_checker.py
@@ -1,15 +1,17 @@
-# Grammalecte
-# Main class: wrapper
+"""
+Grammalecte, grammar checker
+"""
 
 import importlib
 import json
 
 from . import text
 
 
 class GrammarChecker:
+    "GrammarChecker: Wrapper for the grammar checker engine"
 
     def __init__ (self, sLangCode, sContext="Python"):
         self.sLangCode = sLangCode
         # Grammar checker engine
         self.gce = importlib.import_module("."+sLangCode, "grammalecte")
@@ -20,49 +22,58 @@
         self.oLexicographer = None
         # Text formatter
         self.oTextFormatter = None
 
     def getGCEngine (self):
+        "return the grammar checker object"
         return self.gce
 
     def getSpellChecker (self):
+        "return the spell checker object"
         return self.oSpellChecker
 
     def getTextFormatter (self):
-        if self.oTextFormatter == None:
-            self.tf = importlib.import_module("."+self.sLangCode+".textformatter", "grammalecte")
-        self.oTextFormatter = self.tf.TextFormatter()
+        "load and return the text formatter"
+        if self.oTextFormatter is None:
+            tf = importlib.import_module("."+self.sLangCode+".textformatter", "grammalecte")
+            self.oTextFormatter = tf.TextFormatter()
         return self.oTextFormatter
 
     def getLexicographer (self):
-        if self.oLexicographer == None:
-            self.lxg = importlib.import_module("."+self.sLangCode+".lexicographe", "grammalecte")
-        self.oLexicographer = self.lxg.Lexicographe(self.oSpellChecker)
+        "load and return the lexicographer"
+        if self.oLexicographer is None:
+            lxg = importlib.import_module("."+self.sLangCode+".lexicographe", "grammalecte")
+            self.oLexicographer = lxg.Lexicographe(self.oSpellChecker)
         return self.oLexicographer
 
     def displayGCOptions (self):
+        "display the grammar checker options"
         self.gce.displayOptions()
 
     def getParagraphErrors (self, sText, dOptions=None, bContext=False, bSpellSugg=False, bDebug=False):
         "returns a tuple: (grammar errors, spelling errors)"
         aGrammErrs = self.gce.parse(sText, "FR", bDebug=bDebug, dOptions=dOptions, bContext=bContext)
         aSpellErrs = self.oSpellChecker.parseParagraph(sText, bSpellSugg)
         return aGrammErrs, aSpellErrs
 
     def generateText (self, sText, bEmptyIfNoErrors=False, bSpellSugg=False, nWidth=100, bDebug=False):
+        "[todo]"
         pass
 
     def generateTextAsJSON (self, sText, bContext=False, bEmptyIfNoErrors=False, bSpellSugg=False, bReturnText=False, bDebug=False):
+        "[todo]"
         pass
 
     def generateParagraph (self, sText, dOptions=None, bEmptyIfNoErrors=False, bSpellSugg=False, nWidth=100, bDebug=False):
+        "parse text and return a readable text with underline errors"
         aGrammErrs, aSpellErrs = self.getParagraphErrors(sText, dOptions, False, bSpellSugg, bDebug)
         if bEmptyIfNoErrors and not aGrammErrs and not aSpellErrs:
             return ""
         return text.generateParagraph(sText, aGrammErrs, aSpellErrs, nWidth)
 
     def generateParagraphAsJSON (self, iIndex, sText, dOptions=None, bContext=False, bEmptyIfNoErrors=False, bSpellSugg=False, bReturnText=False, lLineSet=None, bDebug=False):
+        "parse text and return errors as a JSON string"
         aGrammErrs, aSpellErrs = self.getParagraphErrors(sText, dOptions, bContext, bSpellSugg, bDebug)
         aGrammErrs = list(aGrammErrs)
         if bEmptyIfNoErrors and not aGrammErrs and not aSpellErrs:
             return ""
         if lLineSet:

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
@@ -1,7 +1,9 @@
-# Grammalecte
-# Grammar checker engine
+"""
+Grammalecte
+Grammar checker engine
+"""
 
 import re
 import sys
 import os
 import traceback
@@ -9,10 +11,23 @@
 from itertools import chain
 
 from ..graphspell.spellchecker import SpellChecker
 from ..graphspell.echo import echo
 from . import gc_options
+
+from ..graphspell.tokenizer import Tokenizer
+from .gc_rules_graph import dAllGraph, dRule
+
+try:
+    # LibreOffice / OpenOffice
+    from com.sun.star.linguistic2 import SingleProofreadingError
+    from com.sun.star.text.TextMarkupType import PROOFREADING
+    from com.sun.star.beans import PropertyValue
+    #import lightproof_handler_${implname} as opt
+    _bWriterError = True
+except ImportError:
+    _bWriterError = False
 
 
 __all__ = [ "lang", "locales", "pkg", "name", "version", "author", \
             "load", "parse", "getSpellChecker", \
             "setOption", "setOptions", "getOptions", "getDefaultOptions", "getOptionsLabels", "resetOptions", "displayOptions", \
@@ -31,313 +46,33 @@
 _rules = None                               # module gc_rules
 
 # data
 _sAppContext = ""                           # what software is running
 _dOptions = None
-_aIgnoredRules = set()
 _oSpellChecker = None
-_dAnalyses = {}                             # cache for data from dictionary
-
-
-
-#### Parsing
-
-def parse (sText, sCountry="${country_default}", bDebug=False, dOptions=None, bContext=False):
-    "analyses the paragraph sText and returns list of errors"
-    #sText = unicodedata.normalize("NFC", sText)
-    aErrors = None
-    sAlt = sText
-    dDA = {}        # Disambiguisator. Key = position; value = list of morphologies
-    dPriority = {}  # Key = position; value = priority
-    dOpt = _dOptions  if not dOptions  else dOptions
-
-    # parse paragraph
-    try:
-        sNew, aErrors = _proofread(sText, sAlt, 0, True, dDA, dPriority, sCountry, dOpt, bDebug, bContext)
-        if sNew:
-            sText = sNew
-    except:
-        raise
-
-    # cleanup
-    if " " in sText:
-        sText = sText.replace(" ", ' ') # nbsp
-    if " " in sText:
-        sText = sText.replace(" ", ' ') # nnbsp
-    if "'" in sText:
-        sText = sText.replace("'", "’")
-    if "‑" in sText:
-        sText = sText.replace("‑", "-") # nobreakdash
-
-    # parse sentences
-    for iStart, iEnd in _getSentenceBoundaries(sText):
-        if 4 < (iEnd - iStart) < 2000:
-            dDA.clear()
-            try:
-                _, errs = _proofread(sText[iStart:iEnd], sAlt[iStart:iEnd], iStart, False, dDA, dPriority, sCountry, dOpt, bDebug, bContext)
-                aErrors.update(errs)
-            except:
-                raise
-    return aErrors.values() # this is a view (iterable)
-
-
-def _getSentenceBoundaries (sText):
-    iStart = _zBeginOfParagraph.match(sText).end()
-    for m in _zEndOfSentence.finditer(sText):
-        yield (iStart, m.end())
-        iStart = m.end()
-
-
-def _proofread (s, sx, nOffset, bParagraph, dDA, dPriority, sCountry, dOptions, bDebug, bContext):
-    dErrs = {}
-    bChange = False
-    bIdRule = option('idrule')
-
-    for sOption, lRuleGroup in _getRules(bParagraph):
-        if not sOption or dOptions.get(sOption, False):
-            for zRegex, bUppercase, sLineId, sRuleId, nPriority, lActions in lRuleGroup:
-                if sRuleId not in _aIgnoredRules:
-                    for m in zRegex.finditer(s):
-                        bCondMemo = None
-                        for sFuncCond, cActionType, sWhat, *eAct in lActions:
-                            # action in lActions: [ condition, action type, replacement/suggestion/action[, iGroup[, message, URL]] ]
-                            try:
-                                bCondMemo = not sFuncCond or globals()[sFuncCond](s, sx, m, dDA, sCountry, bCondMemo)
-                                if bCondMemo:
-                                    if cActionType == "-":
-                                        # grammar error
-                                        nErrorStart = nOffset + m.start(eAct[0])
-                                        if nErrorStart not in dErrs or nPriority > dPriority[nErrorStart]:
-                                            dErrs[nErrorStart] = _createError(s, sx, sWhat, nOffset, m, eAct[0], sLineId, sRuleId, bUppercase, eAct[1], eAct[2], bIdRule, sOption, bContext)
-                                            dPriority[nErrorStart] = nPriority
-                                    elif cActionType == "~":
-                                        # text processor
-                                        s = _rewrite(s, sWhat, eAct[0], m, bUppercase)
-                                        bChange = True
-                                        if bDebug:
-                                            echo("~ " + s + "  -- " + m.group(eAct[0]) + "  # " + sLineId)
-                                    elif cActionType == "=":
-                                        # disambiguation
-                                        globals()[sWhat](s, m, dDA)
-                                        if bDebug:
-                                            echo("= " + m.group(0) + "  # " + sLineId + "\nDA: " + str(dDA))
-                                    elif cActionType == ">":
-                                        # we do nothing, this test is just a condition to apply all following actions
-                                        pass
-                                    else:
-                                        echo("# error: unknown action at " + sLineId)
-                                elif cActionType == ">":
-                                    break
-                            except Exception as e:
-                                raise Exception(str(e), "# " + sLineId + " # " + sRuleId)
-    if bChange:
-        return (s, dErrs)
-    return (False, dErrs)
-
-
-def _createWriterError (s, sx, sRepl, nOffset, m, iGroup, sLineId, sRuleId, bUppercase, sMsg, sURL, bIdRule, sOption, bContext):
-    "error for Writer (LO/OO)"
-    xErr = SingleProofreadingError()
-    #xErr = uno.createUnoStruct( "com.sun.star.linguistic2.SingleProofreadingError" )
-    xErr.nErrorStart = nOffset + m.start(iGroup)
-    xErr.nErrorLength = m.end(iGroup) - m.start(iGroup)
-    xErr.nErrorType = PROOFREADING
-    xErr.aRuleIdentifier = sRuleId
-    # suggestions
-    if sRepl[0:1] == "=":
-        sugg = globals()[sRepl[1:]](s, m)
-        if sugg:
-            if bUppercase and m.group(iGroup)[0:1].isupper():
-                xErr.aSuggestions = tuple(map(str.capitalize, sugg.split("|")))
-            else:
-                xErr.aSuggestions = tuple(sugg.split("|"))
-        else:
-            xErr.aSuggestions = ()
-    elif sRepl == "_":
-        xErr.aSuggestions = ()
-    else:
-        if bUppercase and m.group(iGroup)[0:1].isupper():
-            xErr.aSuggestions = tuple(map(str.capitalize, m.expand(sRepl).split("|")))
-        else:
-            xErr.aSuggestions = tuple(m.expand(sRepl).split("|"))
-    # Message
-    if sMsg[0:1] == "=":
-        sMessage = globals()[sMsg[1:]](s, m)
-    else:
-        sMessage = m.expand(sMsg)
-    xErr.aShortComment = sMessage   # sMessage.split("|")[0]     # in context menu
-    xErr.aFullComment = sMessage   # sMessage.split("|")[-1]    # in dialog
-    if bIdRule:
-        xErr.aShortComment += "  # " + sLineId + " # " + sRuleId
-    # URL
-    if sURL:
-        p = PropertyValue()
-        p.Name = "FullCommentURL"
-        p.Value = sURL
-        xErr.aProperties = (p,)
-    else:
-        xErr.aProperties = ()
-    return xErr
-
-
-def _createDictError (s, sx, sRepl, nOffset, m, iGroup, sLineId, sRuleId, bUppercase, sMsg, sURL, bIdRule, sOption, bContext):
-    "error as a dictionary"
-    dErr = {}
-    dErr["nStart"] = nOffset + m.start(iGroup)
-    dErr["nEnd"] = nOffset + m.end(iGroup)
-    dErr["sLineId"] = sLineId
-    dErr["sRuleId"] = sRuleId
-    dErr["sType"] = sOption  if sOption  else "notype"
-    # suggestions
-    if sRepl[0:1] == "=":
-        sugg = globals()[sRepl[1:]](s, m)
-        if sugg:
-            if bUppercase and m.group(iGroup)[0:1].isupper():
-                dErr["aSuggestions"] = list(map(str.capitalize, sugg.split("|")))
-            else:
-                dErr["aSuggestions"] = sugg.split("|")
-        else:
-            dErr["aSuggestions"] = ()
-    elif sRepl == "_":
-        dErr["aSuggestions"] = ()
-    else:
-        if bUppercase and m.group(iGroup)[0:1].isupper():
-            dErr["aSuggestions"] = list(map(str.capitalize, m.expand(sRepl).split("|")))
-        else:
-            dErr["aSuggestions"] = m.expand(sRepl).split("|")
-    # Message
-    if sMsg[0:1] == "=":
-        sMessage = globals()[sMsg[1:]](s, m)
-    else:
-        sMessage = m.expand(sMsg)
-    dErr["sMessage"] = sMessage
-    if bIdRule:
-        dErr["sMessage"] += "  # " + sLineId + " # " + sRuleId
-    # URL
-    dErr["URL"] = sURL  if sURL  else ""
-    # Context
-    if bContext:
-        dErr['sUnderlined'] = sx[m.start(iGroup):m.end(iGroup)]
-        dErr['sBefore'] = sx[max(0,m.start(iGroup)-80):m.start(iGroup)]
-        dErr['sAfter'] = sx[m.end(iGroup):m.end(iGroup)+80]
-    return dErr
-
-
-def _rewrite (s, sRepl, iGroup, m, bUppercase):
-    "text processor: write sRepl in s at iGroup position"
-    nLen = m.end(iGroup) - m.start(iGroup)
-    if sRepl == "*":
-        sNew = " " * nLen
-    elif sRepl == ">" or sRepl == "_" or sRepl == "~":
-        sNew = sRepl + " " * (nLen-1)
-    elif sRepl == "@":
-        sNew = "@" * nLen
-    elif sRepl[0:1] == "=":
-        sNew = globals()[sRepl[1:]](s, m)
-        sNew = sNew + " " * (nLen-len(sNew))
-        if bUppercase and m.group(iGroup)[0:1].isupper():
-            sNew = sNew.capitalize()
-    else:
-        sNew = m.expand(sRepl)
-        sNew = sNew + " " * (nLen-len(sNew))
-    return s[0:m.start(iGroup)] + sNew + s[m.end(iGroup):]
-
-
-def ignoreRule (sRuleId):
-    _aIgnoredRules.add(sRuleId)
-
-
-def resetIgnoreRules ():
-    _aIgnoredRules.clear()
-
-
-def reactivateRule (sRuleId):
-    _aIgnoredRules.discard(sRuleId)
-
-
-def listRules (sFilter=None):
-    "generator: returns typle (sOption, sLineId, sRuleId)"
-    if sFilter:
-        try:
-            zFilter = re.compile(sFilter)
-        except:
-            echo("# Error. List rules: wrong regex.")
-            sFilter = None
-    for sOption, lRuleGroup in chain(_getRules(True), _getRules(False)):
-        for _, _, sLineId, sRuleId, _, _ in lRuleGroup:
-            if not sFilter or zFilter.search(sRuleId):
-                yield (sOption, sLineId, sRuleId)
-
-
-def displayRules (sFilter=None):
-    echo("List of rules. Filter: << " + str(sFilter) + " >>")
-    for sOption, sLineId, sRuleId in listRules(sFilter):
-        echo("{:<10} {:<10} {}".format(sOption, sLineId, sRuleId))
-
-
-#### init
-
-try:
-    # LibreOffice / OpenOffice
-    from com.sun.star.linguistic2 import SingleProofreadingError
-    from com.sun.star.text.TextMarkupType import PROOFREADING
-    from com.sun.star.beans import PropertyValue
-    #import lightproof_handler_${implname} as opt
-    _createError = _createWriterError
-except ImportError:
-    _createError = _createDictError
-
+_oTokenizer = None
+_aIgnoredRules = set()
+
+
+
+#### Initialization
 
 def load (sContext="Python"):
+    "initialization of the grammar checker"
     global _oSpellChecker
     global _sAppContext
     global _dOptions
+    global _oTokenizer
     try:
         _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
+        _oTokenizer = _oSpellChecker.getTokenizer()
+        _oSpellChecker.activateStorage()
     except:
         traceback.print_exc()
 
-
-def setOption (sOpt, bVal):
-    if sOpt in _dOptions:
-        _dOptions[sOpt] = bVal
-
-
-def setOptions (dOpt):
-    for sKey, bVal in dOpt.items():
-        if sKey in _dOptions:
-            _dOptions[sKey] = bVal
-
-
-def getOptions ():
-    return _dOptions
-
-
-def getDefaultOptions ():
-    return dict(gc_options.getOptions(_sAppContext))
-
-
-def getOptionsLabels (sLang):
-    return gc_options.getUI(sLang)
-
-
-def displayOptions (sLang):
-    echo("List of options")
-    echo("\n".join( [ k+":\t"+str(v)+"\t"+gc_options.getUI(sLang).get(k, ("?", ""))[0]  for k, v  in sorted(_dOptions.items()) ] ))
-    echo("")
-
-
-def resetOptions ():
-    global _dOptions
-    _dOptions = dict(gc_options.getOptions(_sAppContext))
-
-
-def getSpellChecker ():
-    return _oSpellChecker
-
 
 def _getRules (bParagraph):
     try:
         if not bParagraph:
             return _rules.lSentenceRules
@@ -352,129 +87,379 @@
 def _loadRules ():
     from . import gc_rules
     global _rules
     _rules = gc_rules
     # compile rules regex
-    for lRuleGroup in chain(_rules.lParagraphRules, _rules.lSentenceRules):
-        for rule in lRuleGroup[1]:
+    for sOption, lRuleGroup in chain(_rules.lParagraphRules, _rules.lSentenceRules):
+        if sOption != "@@@@":
+            for aRule in lRuleGroup:
+                try:
+                    aRule[0] = re.compile(aRule[0])
+                except:
+                    echo("Bad regular expression in # " + str(aRule[2]))
+                    aRule[0] = "(?i)<Grammalecte>"
+
+
+#### Parsing
+
+_zEndOfSentence = re.compile(r'([.?!:;…][ .?!… »”")]*|.$)')
+_zBeginOfParagraph = re.compile(r"^\W*")
+_zEndOfParagraph = re.compile(r"\W*$")
+
+def _getSentenceBoundaries (sText):
+    iStart = _zBeginOfParagraph.match(sText).end()
+    for m in _zEndOfSentence.finditer(sText):
+        yield (iStart, m.end())
+        iStart = m.end()
+
+
+def parse (sText, sCountry="${country_default}", bDebug=False, dOptions=None, bContext=False):
+    "analyses the paragraph sText and returns list of errors"
+    #sText = unicodedata.normalize("NFC", sText)
+    dErrors = {}
+    sRealText = sText
+    dPriority = {}  # Key = position; value = priority
+    dOpt = _dOptions  if not dOptions  else dOptions
+    bShowRuleId = option('idrule')
+
+    # parse paragraph
+    try:
+        sNew, dErrors = _proofread(None, sText, sRealText, 0, True, dErrors, dPriority, sCountry, dOpt, bShowRuleId, bDebug, bContext)
+        if sNew:
+            sText = sNew
+    except:
+        raise
+
+    # cleanup
+    if " " in sText:
+        sText = sText.replace(" ", ' ') # nbsp
+    if " " in sText:
+        sText = sText.replace(" ", ' ') # nnbsp
+    if "'" in sText:
+        sText = sText.replace("'", "’")
+    if "‑" in sText:
+        sText = sText.replace("‑", "-") # nobreakdash
+
+    # parse sentences
+    for iStart, iEnd in _getSentenceBoundaries(sText):
+        if 4 < (iEnd - iStart) < 2000:
             try:
-                rule[0] = re.compile(rule[0])
+                oSentence = TokenSentence(sText[iStart:iEnd], sRealText[iStart:iEnd], iStart)
+                _, dErrors = _proofread(oSentence, sText[iStart:iEnd], sRealText[iStart:iEnd], iStart, False, dErrors, dPriority, sCountry, dOpt, bShowRuleId, bDebug, bContext)
             except:
-                echo("Bad regular expression in # " + str(rule[2]))
-                rule[0] = "(?i)<Grammalecte>"
+                raise
+    return dErrors.values() # this is a view (iterable)
+
+
+def _proofread (oSentence, s, sx, nOffset, bParagraph, dErrors, dPriority, sCountry, dOptions, bShowRuleId, bDebug, bContext):
+    bParagraphChange = False
+    bSentenceChange = False
+    dTokenPos = oSentence.dTokenPos if oSentence else {}
+    for sOption, lRuleGroup in _getRules(bParagraph):
+        if sOption == "@@@@":
+            # graph rules
+            oSentence.dError = dErrors
+            if not bParagraph and bSentenceChange:
+                oSentence.update(s, bDebug)
+                bSentenceChange = False
+            for sGraphName, sLineId in lRuleGroup:
+                if bDebug:
+                    print("\n>>>> GRAPH:", sGraphName, sLineId)
+                bParagraphChange, s = oSentence.parse(dAllGraph[sGraphName], dPriority, sCountry, dOptions, bShowRuleId, bDebug, bContext)
+                dErrors.update(oSentence.dError)
+                dTokenPos = oSentence.dTokenPos
+        elif not sOption or dOptions.get(sOption, False):
+            # regex rules
+            for zRegex, bUppercase, sLineId, sRuleId, nPriority, lActions in lRuleGroup:
+                if sRuleId not in _aIgnoredRules:
+                    for m in zRegex.finditer(s):
+                        bCondMemo = None
+                        for sFuncCond, cActionType, sWhat, *eAct in lActions:
+                            # action in lActions: [ condition, action type, replacement/suggestion/action[, iGroup[, message, URL]] ]
+                            try:
+                                bCondMemo = not sFuncCond or globals()[sFuncCond](s, sx, m, dTokenPos, sCountry, bCondMemo)
+                                if bCondMemo:
+                                    if bDebug:
+                                        print("RULE:", sLineId)
+                                    if cActionType == "-":
+                                        # grammar error
+                                        nErrorStart = nOffset + m.start(eAct[0])
+                                        if nErrorStart not in dErrors or nPriority > dPriority.get(nErrorStart, -1):
+                                            dErrors[nErrorStart] = _createError(s, sx, sWhat, nOffset, m, eAct[0], sLineId, sRuleId, bUppercase, eAct[1], eAct[2], bShowRuleId, sOption, bContext)
+                                            dPriority[nErrorStart] = nPriority
+                                    elif cActionType == "~":
+                                        # text processor
+                                        s = _rewrite(s, sWhat, eAct[0], m, bUppercase)
+                                        bParagraphChange = True
+                                        bSentenceChange = True
+                                        if bDebug:
+                                            echo("~ " + s + "  -- " + m.group(eAct[0]) + "  # " + sLineId)
+                                    elif cActionType == "=":
+                                        # disambiguation
+                                        if not bParagraph:
+                                            globals()[sWhat](s, m, dTokenPos)
+                                            if bDebug:
+                                                echo("= " + m.group(0) + "  # " + sLineId)
+                                    elif cActionType == ">":
+                                        # we do nothing, this test is just a condition to apply all following actions
+                                        pass
+                                    else:
+                                        echo("# error: unknown action at " + sLineId)
+                                elif cActionType == ">":
+                                    break
+                            except Exception as e:
+                                raise Exception(str(e), "# " + sLineId + " # " + sRuleId)
+    if bParagraphChange:
+        return (s, dErrors)
+    return (False, dErrors)
+
+
+def _createError (s, sx, sRepl, nOffset, m, iGroup, sLineId, sRuleId, bUppercase, sMsg, sURL, bShowRuleId, sOption, bContext):
+    nStart = nOffset + m.start(iGroup)
+    nEnd = nOffset + m.end(iGroup)
+    # suggestions
+    if sRepl[0:1] == "=":
+        sSugg = globals()[sRepl[1:]](s, m)
+        lSugg = sSugg.split("|")  if sSugg  else []
+    elif sRepl == "_":
+        lSugg = []
+    else:
+        lSugg = m.expand(sRepl).split("|")
+    if bUppercase and lSugg and m.group(iGroup)[0:1].isupper():
+        lSugg = list(map(str.capitalize, lSugg))
+    # Message
+    sMessage = globals()[sMsg[1:]](s, m)  if sMsg[0:1] == "="  else  m.expand(sMsg)
+    if bShowRuleId:
+        sMessage += "  # " + sLineId + " # " + sRuleId
+    #
+    if _bWriterError:
+        xErr = SingleProofreadingError()    # uno.createUnoStruct( "com.sun.star.linguistic2.SingleProofreadingError" )
+        xErr.nErrorStart = nStart
+        xErr.nErrorLength = nEnd - nStart
+        xErr.nErrorType = PROOFREADING
+        xErr.aRuleIdentifier = sRuleId
+        xErr.aShortComment = sMessage   # sMessage.split("|")[0]     # in context menu
+        xErr.aFullComment = sMessage   # sMessage.split("|")[-1]    # in dialog
+        if bShowRuleId:
+            xErr.aShortComment += "  " + sLineId + " # " + sRuleId
+        xErr.aSuggestions = tuple(lSugg)
+        if sURL:
+            xProperty = PropertyValue()
+            xProperty.Name = "FullCommentURL"
+            xProperty.Value = sURL
+            xErr.aProperties = (xProperty,)
+        else:
+            xErr.aProperties = ()
+        return xErr
+    else:
+        dErr = {}
+        dErr["nStart"] = nStart
+        dErr["nEnd"] = nEnd
+        dErr["sLineId"] = sLineId
+        dErr["sRuleId"] = sRuleId
+        dErr["sType"] = sOption  if sOption  else "notype"
+        dErr["sMessage"] = sMessage
+        dErr["aSuggestions"] = lSugg
+        dErr["URL"] = sURL  if sURL  else ""
+        if bContext:
+            dErr['sUnderlined'] = self.sSentence0[nStart:nEnd]
+            dErr['sBefore'] = self.sSentence0[max(0,nStart-80):nStart]
+            dErr['sAfter'] = self.sSentence0[nEnd:nEnd+80]
+        return dErr
+
+
+def _rewrite (sSentence, sRepl, iGroup, m, bUppercase):
+    "text processor: write <sRepl> in <sSentence> at <iGroup> position"
+    nLen = m.end(iGroup) - m.start(iGroup)
+    if sRepl == "*":
+        sNew = " " * nLen
+    elif sRepl == "_":
+        sNew = sRepl + " " * (nLen-1)
+    elif sRepl[0:1] == "=":
+        sNew = globals()[sRepl[1:]](sSentence, m)
+        sNew = sNew + " " * (nLen-len(sNew))
+        if bUppercase and m.group(iGroup)[0:1].isupper():
+            sNew = sNew.capitalize()
+    else:
+        sNew = m.expand(sRepl)
+        sNew = sNew + " " * (nLen-len(sNew))
+    return sSentence[0:m.start(iGroup)] + sNew + sSentence[m.end(iGroup):]
+
+
+def ignoreRule (sRuleId):
+    "disable rule <sRuleId>"
+    _aIgnoredRules.add(sRuleId)
+
+
+def resetIgnoreRules ():
+    "clear all ignored rules"
+    _aIgnoredRules.clear()
+
+
+def reactivateRule (sRuleId):
+    "(re)activate rule <sRuleId>"
+    _aIgnoredRules.discard(sRuleId)
+
+
+def listRules (sFilter=None):
+    "generator: returns typle (sOption, sLineId, sRuleId)"
+    if sFilter:
+        try:
+            zFilter = re.compile(sFilter)
+        except:
+            echo("# Error. List rules: wrong regex.")
+            sFilter = None
+    for sOption, lRuleGroup in chain(_getRules(True), _getRules(False)):
+        if sOption != "@@@@":
+            for _, _, sLineId, sRuleId, _, _ in lRuleGroup:
+                if not sFilter or zFilter.search(sRuleId):
+                    yield (sOption, sLineId, sRuleId)
+
+
+def displayRules (sFilter=None):
+    "display the name of rules, with the filter <sFilter>"
+    echo("List of rules. Filter: << " + str(sFilter) + " >>")
+    for sOption, sLineId, sRuleId in listRules(sFilter):
+        echo("{:<10} {:<10} {}".format(sOption, sLineId, sRuleId))
+
+
+def setOption (sOpt, bVal):
+    "set option <sOpt> with <bVal> if it exists"
+    if sOpt in _dOptions:
+        _dOptions[sOpt] = bVal
+
+
+def setOptions (dOpt):
+    "update the dictionary of options with <dOpt>"
+    for sKey, bVal in dOpt.items():
+        if sKey in _dOptions:
+            _dOptions[sKey] = bVal
+
+
+def getOptions ():
+    "return the dictionary of current options"
+    return _dOptions
+
+
+def getDefaultOptions ():
+    "return the dictionary of default options"
+    return dict(gc_options.getOptions(_sAppContext))
+
+
+def getOptionsLabels (sLang):
+    "return options labels"
+    return gc_options.getUI(sLang)
+
+
+def displayOptions (sLang):
+    "display the list of grammar checking options"
+    echo("List of options")
+    echo("\n".join( [ k+":\t"+str(v)+"\t"+gc_options.getUI(sLang).get(k, ("?", ""))[0]  for k, v  in sorted(_dOptions.items()) ] ))
+    echo("")
+
+
+def resetOptions ():
+    "set options to default values"
+    global _dOptions
+    _dOptions = dict(gc_options.getOptions(_sAppContext))
+
+
+def getSpellChecker ():
+    "return the spellchecker object"
+    return _oSpellChecker
 
 
 def _getPath ():
     return os.path.join(os.path.dirname(sys.modules[__name__].__file__), __name__ + ".py")
 
 
 
 #### common functions
-
-# common regexes
-_zEndOfSentence = re.compile('([.?!:;…][ .?!… »”")]*|.$)')
-_zBeginOfParagraph = re.compile("^\W*")
-_zEndOfParagraph = re.compile("\W*$")
-_zNextWord = re.compile(" +(\w[\w-]*)")
-_zPrevWord = re.compile("(\w[\w-]*) +$")
-
 
 def option (sOpt):
-    "return True if option sOpt is active"
+    "return True if option <sOpt> is active"
     return _dOptions.get(sOpt, False)
 
 
-def displayInfo (dDA, tWord):
+def displayInfo (dTokenPos, tWord):
     "for debugging: retrieve info of word"
     if not tWord:
         echo("> nothing to find")
         return True
-    if tWord[1] not in _dAnalyses and not _storeMorphFromFSA(tWord[1]):
-        echo("> not in FSA")
+    lMorph = _oSpellChecker.getMorph(tWord[1])
+    if not lMorph:
+        echo("> not in dictionary")
         return True
-    if tWord[0] in dDA:
-        echo("DA: " + str(dDA[tWord[0]]))
-    echo("FSA: " + str(_dAnalyses[tWord[1]]))
+    print("TOKENS:", dTokenPos)
+    if tWord[0] in dTokenPos and "lMorph" in dTokenPos[tWord[0]]:
+        echo("DA: " + str(dTokenPos[tWord[0]]["lMorph"]))
+    echo("FSA: " + str(lMorph))
     return True
 
 
-def _storeMorphFromFSA (sWord):
-    "retrieves morphologies list from _oSpellChecker -> _dAnalyses"
-    global _dAnalyses
-    _dAnalyses[sWord] = _oSpellChecker.getMorph(sWord)
-    return True  if _dAnalyses[sWord]  else False
-
-
-def morph (dDA, tWord, sPattern, bStrict=True, bNoWord=False):
+def morph (dTokenPos, tWord, sPattern, bStrict=True, bNoWord=False):
     "analyse a tuple (position, word), return True if sPattern in morphologies (disambiguation on)"
     if not tWord:
         return bNoWord
-    if tWord[1] not in _dAnalyses and not _storeMorphFromFSA(tWord[1]):
-        return False
-    lMorph = dDA[tWord[0]]  if tWord[0] in dDA  else _dAnalyses[tWord[1]]
+    lMorph = dTokenPos[tWord[0]]["lMorph"]  if tWord[0] in dTokenPos and "lMorph" in dTokenPos[tWord[0]]  else _oSpellChecker.getMorph(tWord[1])
     if not lMorph:
         return False
-    p = re.compile(sPattern)
+    zPattern = re.compile(sPattern)
     if bStrict:
-        return all(p.search(s)  for s in lMorph)
-    return any(p.search(s)  for s in lMorph)
+        return bool(lMorph) and all(zPattern.search(s)  for s in lMorph)
+    return any(zPattern.search(s)  for s in lMorph)
 
 
-def morphex (dDA, tWord, sPattern, sNegPattern, bNoWord=False):
+def morphex (dTokenPos, tWord, sPattern, sNegPattern, bNoWord=False):
     "analyse a tuple (position, word), returns True if not sNegPattern in word morphologies and sPattern in word morphologies (disambiguation on)"
     if not tWord:
         return bNoWord
-    if tWord[1] not in _dAnalyses and not _storeMorphFromFSA(tWord[1]):
+    lMorph = dTokenPos[tWord[0]]["lMorph"]  if tWord[0] in dTokenPos and "lMorph" in dTokenPos[tWord[0]]  else _oSpellChecker.getMorph(tWord[1])
+    if not lMorph:
         return False
-    lMorph = dDA[tWord[0]]  if tWord[0] in dDA  else _dAnalyses[tWord[1]]
     # check negative condition
-    np = re.compile(sNegPattern)
-    if any(np.search(s)  for s in lMorph):
+    zNegPattern = re.compile(sNegPattern)
+    if any(zNegPattern.search(s)  for s in lMorph):
         return False
     # search sPattern
-    p = re.compile(sPattern)
-    return any(p.search(s)  for s in lMorph)
+    zPattern = re.compile(sPattern)
+    return any(zPattern.search(s)  for s in lMorph)
 
 
 def analyse (sWord, sPattern, bStrict=True):
     "analyse a word, return True if sPattern in morphologies (disambiguation off)"
-    if sWord not in _dAnalyses and not _storeMorphFromFSA(sWord):
+    lMorph = _oSpellChecker.getMorph(sWord)
+    if not lMorph:
         return False
-    if not _dAnalyses[sWord]:
-        return False
-    p = re.compile(sPattern)
+    zPattern = re.compile(sPattern)
     if bStrict:
-        return all(p.search(s)  for s in _dAnalyses[sWord])
-    return any(p.search(s)  for s in _dAnalyses[sWord])
+        return bool(lMorph) and all(zPattern.search(s)  for s in lMorph)
+    return any(zPattern.search(s)  for s in lMorph)
 
 
 def analysex (sWord, sPattern, sNegPattern):
     "analyse a word, returns True if not sNegPattern in word morphologies and sPattern in word morphologies (disambiguation off)"
-    if sWord not in _dAnalyses and not _storeMorphFromFSA(sWord):
+    lMorph = _oSpellChecker.getMorph(sWord)
+    if not lMorph:
         return False
     # check negative condition
-    np = re.compile(sNegPattern)
-    if any(np.search(s)  for s in _dAnalyses[sWord]):
+    zNegPattern = re.compile(sNegPattern)
+    if any(zNegPattern.search(s)  for s in lMorph):
         return False
     # search sPattern
-    p = re.compile(sPattern)
-    return any(p.search(s)  for s in _dAnalyses[sWord])
-
-
-def stem (sWord):
-    "returns a list of sWord's stems"
-    if not sWord:
-        return []
-    if sWord not in _dAnalyses and not _storeMorphFromFSA(sWord):
-        return []
-    return [ s[1:s.find(" ")]  for s in _dAnalyses[sWord] ]
+    zPattern = re.compile(sPattern)
+    return any(zPattern.search(s)  for s in lMorph)
+
 
 
 ## functions to get text outside pattern scope
 
 # warning: check compile_rules.py to understand how it works
 
+_zNextWord = re.compile(r" +(\w[\w-]*)")
+_zPrevWord = re.compile(r"(\w[\w-]*) +$")
+
 def nextword (s, iStart, n):
     "get the nth word of the input string or empty string"
     m = re.match("(?: +[\\w%-]+){" + str(n-1) + "} +([\\w%-]+)", s[iStart:])
     if not m:
         return None
@@ -512,11 +497,11 @@
     if re.search(sPattern, s):
         return True
     return False
 
 
-def look_chk1 (dDA, s, nOffset, sPattern, sPatternGroup1, sNegPatternGroup1=None):
+def look_chk1 (dTokenPos, s, nOffset, sPattern, sPatternGroup1, sNegPatternGroup1=None):
     "returns True if s has pattern sPattern and m.group(1) has pattern sPatternGroup1"
     m = re.search(sPattern, s)
     if not m:
         return False
     try:
@@ -523,63 +508,615 @@
         sWord = m.group(1)
         nPos = m.start(1) + nOffset
     except:
         return False
     if sNegPatternGroup1:
-        return morphex(dDA, (nPos, sWord), sPatternGroup1, sNegPatternGroup1)
-    return morph(dDA, (nPos, sWord), sPatternGroup1, False)
+        return morphex(dTokenPos, (nPos, sWord), sPatternGroup1, sNegPatternGroup1)
+    return morph(dTokenPos, (nPos, sWord), sPatternGroup1, False)
+
+
+#### Disambiguator
+
+def select (dTokenPos, nPos, sWord, sPattern, lDefault=None):
+    "Disambiguation: select morphologies of <sWord> matching <sPattern>"
+    if not sWord:
+        return True
+    if nPos not in dTokenPos:
+        print("Error. There should be a token at this position: ", nPos)
+        return True
+    lMorph = _oSpellChecker.getMorph(sWord)
+    if not lMorph or len(lMorph) == 1:
+        return True
+    lSelect = [ sMorph  for sMorph in lMorph  if re.search(sPattern, sMorph) ]
+    if lSelect:
+        if len(lSelect) != len(lMorph):
+            dTokenPos[nPos]["lMorph"] = lSelect
+    elif lDefault:
+        dTokenPos[nPos]["lMorph"] = lDefault
+    return True
+
+
+def exclude (dTokenPos, nPos, sWord, sPattern, lDefault=None):
+    "Disambiguation: exclude morphologies of <sWord> matching <sPattern>"
+    if not sWord:
+        return True
+    if nPos not in dTokenPos:
+        print("Error. There should be a token at this position: ", nPos)
+        return True
+    lMorph = _oSpellChecker.getMorph(sWord)
+    if not lMorph or len(lMorph) == 1:
+        return True
+    lSelect = [ sMorph  for sMorph in lMorph  if not re.search(sPattern, sMorph) ]
+    if lSelect:
+        if len(lSelect) != len(lMorph):
+            dTokenPos[nPos]["lMorph"] = lSelect
+    elif lDefault:
+        dTokenPos[nPos]["lMorph"] = lDefault
+    return True
+
+
+def define (dTokenPos, nPos, lMorph):
+    "Disambiguation: set morphologies of token at <nPos> with <lMorph>"
+    if nPos not in dTokenPos:
+        print("Error. There should be a token at this position: ", nPos)
+        return True
+    dTokenPos[nPos]["lMorph"] = lMorph
+    return True
+
+
+
+
+#### TOKEN SENTENCE CHECKER
+
+class TokenSentence:
+    "Text parser"
+
+    def __init__ (self, sSentence, sSentence0, nOffset):
+        self.sSentence = sSentence
+        self.sSentence0 = sSentence0
+        self.nOffsetWithinParagraph = nOffset
+        self.lToken = list(_oTokenizer.genTokens(sSentence, True))
+        self.dTokenPos = { dToken["nStart"]: dToken  for dToken in self.lToken  if dToken["sType"] != "INFO" }
+        self.dTags = {}
+        self.dError = {}
+
+    def __str__ (self):
+        s = "sentence: " + self.sSentence0 + "\n"
+        s += "now:      " + self.sSentence  + "\n"
+        for dToken in self.lToken:
+            s += f'{dToken["nStart"]}\t{dToken["nEnd"]}\t{dToken["sValue"]}'
+            if "lMorph" in dToken:
+                s += "\t" + str(dToken["lMorph"])
+            s += "\n"
+        for nPos, dToken in self.dTokenPos.items():
+            s += f"{nPos}\t{dToken}\n"
+        return s
+
+    def update (self, sSentence, bDebug=False):
+        "update <sSentence> and retokenize"
+        self.sSentence = sSentence
+        lNewToken = list(_oTokenizer.genTokens(sSentence, True))
+        for dToken in lNewToken:
+            if "lMorph" in self.dTokenPos.get(dToken["nStart"], {}):
+                dToken["lMorph"] = self.dTokenPos[dToken["nStart"]]["lMorph"]
+        self.lToken = lNewToken
+        self.dTokenPos = { dToken["nStart"]: dToken  for dToken in self.lToken  if dToken["sType"] != "INFO" }
+        if bDebug:
+            print("UPDATE:")
+            print(self)
+
+    def _getNextMatchingNodes (self, dToken, dGraph, dNode, bDebug=False):
+        "generator: return nodes where <dToken> “values” match <dNode> arcs"
+        # token value
+        if dToken["sValue"] in dNode:
+            if bDebug:
+                print("  MATCH:", dToken["sValue"])
+            yield dGraph[dNode[dToken["sValue"]]]
+        if dToken["sValue"][0:2].istitle(): # we test only 2 first chars, to make valid words such as "Laissez-les", "Passe-partout".
+            sValue = dToken["sValue"].lower()
+            if sValue in dNode:
+                if bDebug:
+                    print("  MATCH:", sValue)
+                yield dGraph[dNode[sValue]]
+        elif dToken["sValue"].isupper():
+            sValue = dToken["sValue"].lower()
+            if sValue in dNode:
+                if bDebug:
+                    print("  MATCH:", sValue)
+                yield dGraph[dNode[sValue]]
+            sValue = dToken["sValue"].capitalize()
+            if sValue in dNode:
+                if bDebug:
+                    print("  MATCH:", sValue)
+                yield dGraph[dNode[sValue]]
+        # regex value arcs
+        if "<re_value>" in dNode:
+            for sRegex in dNode["<re_value>"]:
+                if "¬" not in sRegex:
+                    # no anti-pattern
+                    if re.search(sRegex, dToken["sValue"]):
+                        if bDebug:
+                            print("  MATCH: ~" + sRegex)
+                        yield dGraph[dNode["<re_value>"][sRegex]]
+                else:
+                    # there is an anti-pattern
+                    sPattern, sNegPattern = sRegex.split("¬", 1)
+                    if sNegPattern and re.search(sNegPattern, dToken["sValue"]):
+                        continue
+                    if not sPattern or re.search(sPattern, dToken["sValue"]):
+                        if bDebug:
+                            print("  MATCH: ~" + sRegex)
+                        yield dGraph[dNode["<re_value>"][sRegex]]
+        # analysable tokens
+        if dToken["sType"][0:4] == "WORD":
+            # token lemmas
+            if "<lemmas>" in dNode:
+                for sLemma in _oSpellChecker.getLemma(dToken["sValue"]):
+                    if sLemma in dNode["<lemmas>"]:
+                        if bDebug:
+                            print("  MATCH: >" + sLemma)
+                        yield dGraph[dNode["<lemmas>"][sLemma]]
+            # regex morph arcs
+            if "<re_morph>" in dNode:
+                for sRegex in dNode["<re_morph>"]:
+                    if "¬" not in sRegex:
+                        # no anti-pattern
+                        if any(re.search(sRegex, sMorph)  for sMorph in _oSpellChecker.getMorph(dToken["sValue"])):
+                            if bDebug:
+                                print("  MATCH: @" + sRegex)
+                            yield dGraph[dNode["<re_morph>"][sRegex]]
+                    else:
+                        # there is an anti-pattern
+                        sPattern, sNegPattern = sRegex.split("¬", 1)
+                        if sNegPattern == "*":
+                            # all morphologies must match with <sPattern>
+                            if sPattern:
+                                lMorph = _oSpellChecker.getMorph(dToken["sValue"])
+                                if lMorph and all(re.search(sPattern, sMorph)  for sMorph in lMorph):
+                                    if bDebug:
+                                        print("  MATCH: @" + sRegex)
+                                    yield dGraph[dNode["<re_morph>"][sRegex]]
+                        else:
+                            if sNegPattern and any(re.search(sNegPattern, sMorph)  for sMorph in _oSpellChecker.getMorph(dToken["sValue"])):
+                                continue
+                            if not sPattern or any(re.search(sPattern, sMorph)  for sMorph in _oSpellChecker.getMorph(dToken["sValue"])):
+                                if bDebug:
+                                    print("  MATCH: @" + sRegex)
+                                yield dGraph[dNode["<re_morph>"][sRegex]]
+        # meta arc (for token type)
+        if "<meta>" in dNode:
+            for sMeta in dNode["<meta>"]:
+                # not regex here, we just search if <dNode["sType"]> exists within <sMeta>
+                if sMeta == "*":
+                    if bDebug:
+                        print("  MATCH: *" + sMeta)
+                    yield dGraph[dNode["<meta>"]["*"]]
+                elif "¬" in sMeta:
+                    if dToken["sType"] not in sMeta:
+                        if bDebug:
+                            print("  MATCH: *" + sMeta)
+                        yield dGraph[dNode["<meta>"][sMeta]]
+                elif dToken["sType"] in sMeta:
+                    if bDebug:
+                        print("  MATCH: *" + sMeta)
+                    yield dGraph[dNode["<meta>"][sMeta]]
+
+    def parse (self, dGraph, dPriority, sCountry="${country_default}", dOptions=None, bShowRuleId=False, bDebug=False, bContext=False):
+        "parse tokens from the text and execute actions encountered"
+        dOpt = _dOptions  if not dOptions  else dOptions
+        lPointer = []
+        bTagAndRewrite = False
+        for dToken in self.lToken:
+            if bDebug:
+                print("TOKEN:", dToken["sValue"])
+            # check arcs for each existing pointer
+            lNextPointer = []
+            for dPointer in lPointer:
+                for dNode in self._getNextMatchingNodes(dToken, dGraph, dPointer["dNode"], bDebug):
+                    lNextPointer.append({"iToken": dPointer["iToken"], "dNode": dNode})
+            lPointer = lNextPointer
+            # check arcs of first nodes
+            for dNode in self._getNextMatchingNodes(dToken, dGraph, dGraph[0], bDebug):
+                lPointer.append({"iToken": dToken["i"], "dNode": dNode})
+            # check if there is rules to check for each pointer
+            for dPointer in lPointer:
+                #if bDebug:
+                #    print("+", dPointer)
+                if "<rules>" in dPointer["dNode"]:
+                    bChange = self._executeActions(dGraph, dPointer["dNode"]["<rules>"], dPointer["iToken"]-1, dToken["i"], dPriority, dOpt, sCountry, bShowRuleId, bDebug, bContext)
+                    if bChange:
+                        bTagAndRewrite = True
+        if bTagAndRewrite:
+            self.rewrite(bDebug)
+        if bDebug:
+            print(self)
+        return (bTagAndRewrite, self.sSentence)
+
+    def _executeActions (self, dGraph, dNode, nTokenOffset, nLastToken, dPriority, dOptions, sCountry, bShowRuleId, bDebug, bContext):
+        "execute actions found in the DARG"
+        bChange = False
+        for sLineId, nextNodeKey in dNode.items():
+            bCondMemo = None
+            for sRuleId in dGraph[nextNodeKey]:
+                try:
+                    if bDebug:
+                        print("  TRY:", sRuleId)
+                    sOption, sFuncCond, cActionType, sWhat, *eAct = dRule[sRuleId]
+                    # Suggestion    [ option, condition, "-", replacement/suggestion/action, iTokenStart, iTokenEnd, nPriority, message, URL ]
+                    # TextProcessor [ option, condition, "~", replacement/suggestion/action, iTokenStart, iTokenEnd ]
+                    # Disambiguator [ option, condition, "=", replacement/suggestion/action ]
+                    # Sentence Tag  [ option, condition, "/", replacement/suggestion/action, iTokenStart, iTokenEnd ]
+                    # Test          [ option, condition, ">", "" ]
+                    if not sOption or dOptions.get(sOption, False):
+                        bCondMemo = not sFuncCond or globals()[sFuncCond](self.lToken, nTokenOffset, nLastToken, sCountry, bCondMemo, self.dTags, self.sSentence, self.sSentence0)
+                        if bCondMemo:
+                            if cActionType == "-":
+                                # grammar error
+                                nTokenErrorStart = nTokenOffset + eAct[0]
+                                if "bImmune" not in self.lToken[nTokenErrorStart]:
+                                    nTokenErrorEnd = (nTokenOffset + eAct[1])  if eAct[1]  else nLastToken
+                                    nErrorStart = self.nOffsetWithinParagraph + self.lToken[nTokenErrorStart]["nStart"]
+                                    nErrorEnd = self.nOffsetWithinParagraph + self.lToken[nTokenErrorEnd]["nEnd"]
+                                    if nErrorStart not in self.dError or eAct[2] > dPriority.get(nErrorStart, -1):
+                                        self.dError[nErrorStart] = self._createError(sWhat, nTokenOffset, nTokenErrorStart, nErrorStart, nErrorEnd, sLineId, sRuleId, True, eAct[3], eAct[4], bShowRuleId, "notype", bContext)
+                                        dPriority[nErrorStart] = eAct[2]
+                                        if bDebug:
+                                            print("  NEW_ERROR:", self.dError[nErrorStart], "\n  ", dRule[sRuleId])
+                            elif cActionType == "~":
+                                # text processor
+                                if bDebug:
+                                    print("  TAG_PREPARE:\n  ", dRule[sRuleId])
+                                nEndToken = (nTokenOffset + eAct[1])  if eAct[1]  else nLastToken
+                                self._tagAndPrepareTokenForRewriting(sWhat, nTokenOffset + eAct[0], nEndToken, nTokenOffset, True, bDebug)
+                                bChange = True
+                            elif cActionType == "=":
+                                # disambiguation
+                                if bDebug:
+                                    print("  DISAMBIGUATOR:\n  ", dRule[sRuleId])
+                                globals()[sWhat](self.lToken, nTokenOffset)
+                            elif cActionType == ">":
+                                # we do nothing, this test is just a condition to apply all following actions
+                                if bDebug:
+                                    print("  COND_OK")
+                                pass
+                            elif cActionType == "/":
+                                # sentence tags
+                                if bDebug:
+                                    print("  SENTENCE_TAG:\n  ", dRule[sRuleId])
+                                nTokenTag = nTokenOffset + eAct[0]
+                                if sWhat not in self.dTags:
+                                    self.dTags[sWhat] = (nTokenTag, nTokenTag)
+                                elif nTokenTag > self.dTags[sWhat][1]:
+                                    self.dTags[sWhat] = (self.dTags[sWhat][0], nTokenTag)
+                            else:
+                                print("# error: unknown action at " + sLineId)
+                        elif cActionType == ">":
+                            if bDebug:
+                                print("  COND_BREAK")
+                            break
+                except Exception as e:
+                    raise Exception(str(e), sLineId, sRuleId, self.sSentence)
+        return bChange
+
+    def _createError (self, sSugg, nTokenOffset, iFirstToken, nStart, nEnd, sLineId, sRuleId, bUppercase, sMsg, sURL, bShowRuleId, sOption, bContext):
+        # suggestions
+        if sSugg[0:1] == "=":
+            sSugg = globals()[sSugg[1:]](self.lToken, nTokenOffset)
+            lSugg = sSugg.split("|")  if sSugg  else []
+        elif sSugg == "_":
+            lSugg = []
+        else:
+            lSugg = self._expand(sSugg, nTokenOffset).split("|")
+        if bUppercase and lSugg and self.lToken[iFirstToken]["sValue"][0:1].isupper():
+            lSugg = list(map(str.capitalize, lSugg))
+        # Message
+        sMessage = globals()[sMsg[1:]](self.lToken, nTokenOffset)  if sMsg[0:1] == "="  else self._expand(sMsg, nTokenOffset)
+        if bShowRuleId:
+            sMessage += "  " + sLineId + " # " + sRuleId
+        #
+        if _bWriterError:
+            xErr = SingleProofreadingError()    # uno.createUnoStruct( "com.sun.star.linguistic2.SingleProofreadingError" )
+            xErr.nErrorStart = nStart
+            xErr.nErrorLength = nEnd - nStart
+            xErr.nErrorType = PROOFREADING
+            xErr.aRuleIdentifier = sRuleId
+            xErr.aShortComment = sMessage   # sMessage.split("|")[0]     # in context menu
+            xErr.aFullComment = sMessage   # sMessage.split("|")[-1]    # in dialog
+            if bShowRuleId:
+                xErr.aShortComment += "  " + sLineId + " # " + sRuleId
+            xErr.aSuggestions = tuple(lSugg)
+            if sURL:
+                xProperty = PropertyValue()
+                xProperty.Name = "FullCommentURL"
+                xProperty.Value = sURL
+                xErr.aProperties = (xProperty,)
+            else:
+                xErr.aProperties = ()
+            return xErr
+        else:
+            dErr = {}
+            dErr["nStart"] = nStart
+            dErr["nEnd"] = nEnd
+            dErr["sLineId"] = sLineId
+            dErr["sRuleId"] = sRuleId
+            dErr["sType"] = sOption  if sOption  else "notype"
+            dErr["sMessage"] = sMessage
+            dErr["aSuggestions"] = lSugg
+            dErr["URL"] = sURL  if sURL  else ""
+            if bContext:
+                dErr['sUnderlined'] = self.sSentence0[nStart:nEnd]
+                dErr['sBefore'] = self.sSentence0[max(0,nStart-80):nStart]
+                dErr['sAfter'] = self.sSentence0[nEnd:nEnd+80]
+            return dErr
+
+    def _expand (self, sText, nTokenOffset):
+        #print("*", sText)
+        for m in re.finditer(r"\\([0-9]+)", sText):
+            sText = sText.replace(m.group(0), self.lToken[int(m.group(1))+nTokenOffset]["sValue"])
+        #print(">", sText)
+        return sText
+
+    def _tagAndPrepareTokenForRewriting (self, sWhat, nTokenRewriteStart, nTokenRewriteEnd, nTokenOffset, bUppercase=True, bDebug=False):
+        "text processor: rewrite tokens between <nTokenRewriteStart> and <nTokenRewriteEnd> position"
+        if bDebug:
+            print("   START:", nTokenRewriteStart, "END:", nTokenRewriteEnd)
+        if sWhat == "*":
+            # purge text
+            if nTokenRewriteEnd - nTokenRewriteStart == 0:
+                self.lToken[nTokenRewriteStart]["bToRemove"] = True
+            else:
+                for i in range(nTokenRewriteStart, nTokenRewriteEnd+1):
+                    self.lToken[i]["bToRemove"] = True
+        elif sWhat == "␣":
+            # merge tokens
+            self.lToken[nTokenRewriteStart]["nMergeUntil"] = nTokenRewriteEnd
+        elif sWhat == "!":
+            # immunity
+            if nTokenRewriteEnd - nTokenRewriteStart == 0:
+                self.lToken[nTokenRewriteStart]["bImmune"] = True
+            else:
+                for i in range(nTokenRewriteStart, nTokenRewriteEnd+1):
+                    self.lToken[i]["bImmune"] = True
+        elif sWhat == "_":
+            # neutralized token
+            if nTokenRewriteEnd - nTokenRewriteStart == 0:
+                self.lToken[nTokenRewriteStart]["sNewValue"] = "_"
+            else:
+                for i in range(nTokenRewriteStart, nTokenRewriteEnd+1):
+                    self.lToken[i]["sNewValue"] = "_"
+        else:
+            if sWhat.startswith("="):
+                sWhat = globals()[sWhat[1:]](self.lToken, nTokenOffset)
+            else:
+                sWhat = self._expand(sWhat, nTokenOffset)
+            bUppercase = bUppercase and self.lToken[nTokenRewriteStart]["sValue"][0:1].isupper()
+            if nTokenRewriteEnd - nTokenRewriteStart == 0:
+                # one token
+                sWhat = sWhat + " " * (len(self.lToken[nTokenRewriteStart]["sValue"])-len(sWhat))
+                if bUppercase:
+                    sWhat = sWhat[0:1].upper() + sWhat[1:]
+                self.lToken[nTokenRewriteStart]["sNewValue"] = sWhat
+            else:
+                # several tokens
+                lTokenValue = sWhat.split("|")
+                if len(lTokenValue) != (nTokenRewriteEnd - nTokenRewriteStart + 1):
+                    print("Error. Text processor: number of replacements != number of tokens.")
+                    return
+                for i, sValue in zip(range(nTokenRewriteStart, nTokenRewriteEnd+1), lTokenValue):
+                    if not sValue or sValue == "*":
+                        self.lToken[i]["bToRemove"] = True
+                    else:
+                        if bUppercase:
+                            sValue = sValue[0:1].upper() + sValue[1:]
+                        self.lToken[i]["sNewValue"] = sValue
+
+    def rewrite (self, bDebug=False):
+        "rewrite the sentence, modify tokens, purge the token list"
+        if bDebug:
+            print("REWRITE")
+        lNewToken = []
+        nMergeUntil = 0
+        dTokenMerger = None
+        for dToken in self.lToken:
+            bKeepToken = True
+            if dToken["sType"] != "INFO":
+                if "bImmune" in dToken:
+                    nErrorStart = self.nOffsetWithinParagraph + dToken["nStart"]
+                    if nErrorStart in self.dError:
+                        if bDebug:
+                            print("immunity -> error removed:", self.dError[nErrorStart])
+                        del self.dError[nErrorStart]
+                if nMergeUntil and dToken["i"] <= nMergeUntil:
+                    dTokenMerger["sValue"] += " " * (dToken["nStart"] - dTokenMerger["nEnd"]) + dToken["sValue"]
+                    dTokenMerger["nEnd"] = dToken["nEnd"]
+                    if bDebug:
+                        print("  MERGED TOKEN:", dTokenMerger["sValue"])
+                    bKeepToken = False
+                if "nMergeUntil" in dToken:
+                    if dToken["i"] > nMergeUntil: # this token is not already merged with a previous token
+                        dTokenMerger = dToken
+                    if dToken["nMergeUntil"] > nMergeUntil:
+                        nMergeUntil = dToken["nMergeUntil"]
+                    del dToken["nMergeUntil"]
+                elif "bToRemove" in dToken:
+                    if bDebug:
+                        print("  REMOVED:", dToken["sValue"])
+                    self.sSentence = self.sSentence[:dToken["nStart"]] + " " * (dToken["nEnd"] - dToken["nStart"]) + self.sSentence[dToken["nEnd"]:]
+                    bKeepToken = False
+            #
+            if bKeepToken:
+                lNewToken.append(dToken)
+                if "sNewValue" in dToken:
+                    # rewrite token and sentence
+                    if bDebug:
+                        print(dToken["sValue"], "->", dToken["sNewValue"])
+                    dToken["sRealValue"] = dToken["sValue"]
+                    dToken["sValue"] = dToken["sNewValue"]
+                    nDiffLen = len(dToken["sRealValue"]) - len(dToken["sNewValue"])
+                    sNewRepl = (dToken["sNewValue"] + " " * nDiffLen)  if nDiffLen >= 0  else dToken["sNewValue"][:len(dToken["sRealValue"])]
+                    self.sSentence = self.sSentence[:dToken["nStart"]] + sNewRepl + self.sSentence[dToken["nEnd"]:]
+                    del dToken["sNewValue"]
+            else:
+                try:
+                    del self.dTokenPos[dToken["nStart"]]
+                except:
+                    print(self)
+                    print(dToken)
+                    exit()
+        if bDebug:
+            print("  REWRITED:", self.sSentence)
+        self.lToken.clear()
+        self.lToken = lNewToken
+
+
+
+#### Analyse tokens
+
+def g_value (dToken, sValues, nLeft=None, nRight=None):
+    "test if <dToken['sValue']> is in sValues (each value should be separated with |)"
+    sValue = "|"+dToken["sValue"]+"|"  if nLeft is None  else "|"+dToken["sValue"][slice(nLeft, nRight)]+"|"
+    if sValue in sValues:
+        return True
+    if dToken["sValue"][0:2].istitle(): # we test only 2 first chars, to make valid words such as "Laissez-les", "Passe-partout".
+        if sValue.lower() in sValues:
+            return True
+    elif dToken["sValue"].isupper():
+        #if sValue.lower() in sValues:
+        #    return True
+        sValue = "|"+sValue[1:].capitalize()
+        if sValue.capitalize() in sValues:
+            return True
+    return False
+
+
+def g_morph (dToken, sPattern, sNegPattern="", nLeft=None, nRight=None, bMemorizeMorph=True):
+    "analyse a token, return True if <sNegPattern> not in morphologies and <sPattern> in morphologies"
+    if "lMorph" in dToken:
+        lMorph = dToken["lMorph"]
+    else:
+        if nLeft is not None:
+            lMorph = _oSpellChecker.getMorph(dToken["sValue"][slice(nLeft, nRight)])
+            if bMemorizeMorph:
+                dToken["lMorph"] = lMorph
+        else:
+            lMorph = _oSpellChecker.getMorph(dToken["sValue"])
+        if not lMorph:
+            return False
+    # check negative condition
+    if sNegPattern:
+        if sNegPattern == "*":
+            # all morph must match sPattern
+            if not lMorph:
+                return False
+            zPattern = re.compile(sPattern)
+            return all(zPattern.search(sMorph)  for sMorph in lMorph)
+        else:
+            zNegPattern = re.compile(sNegPattern)
+            if any(zNegPattern.search(sMorph)  for sMorph in lMorph):
+                return False
+    # search sPattern
+    zPattern = re.compile(sPattern)
+    return any(zPattern.search(sMorph)  for sMorph in lMorph)
+
+
+def g_analyse (dToken, sPattern, sNegPattern="", nLeft=None, nRight=None, bMemorizeMorph=True):
+    "analyse a token, return True if <sNegPattern> not in morphologies and <sPattern> in morphologies (disambiguation off)"
+    if nLeft is not None:
+        lMorph = _oSpellChecker.getMorph(dToken["sValue"][slice(nLeft, nRight)])
+        if bMemorizeMorph:
+            dToken["lMorph"] = lMorph
+    else:
+        lMorph = _oSpellChecker.getMorph(dToken["sValue"])
+    if not lMorph:
+        return False
+    # check negative condition
+    if sNegPattern:
+        if sNegPattern == "*":
+            # all morph must match sPattern
+            if not lMorph:
+                return False
+            zPattern = re.compile(sPattern)
+            return all(zPattern.search(sMorph)  for sMorph in lMorph)
+        else:
+            zNegPattern = re.compile(sNegPattern)
+            if any(zNegPattern.search(sMorph)  for sMorph in lMorph):
+                return False
+    # search sPattern
+    zPattern = re.compile(sPattern)
+    return any(zPattern.search(sMorph)  for sMorph in lMorph)
+
+
+def g_tag_before (dToken, dTags, sTag):
+    if sTag not in dTags:
+        return False
+    if dToken["i"] > dTags[sTag][0]:
+        return True
+    return False
+
+
+def g_tag_after (dToken, dTags, sTag):
+    if sTag not in dTags:
+        return False
+    if dToken["i"] < dTags[sTag][1]:
+        return True
+    return False
 
 
 #### Disambiguator
 
-def select (dDA, nPos, sWord, sPattern, lDefault=None):
-    if not sWord:
-        return True
-    if nPos in dDA:
-        return True
-    if sWord not in _dAnalyses and not _storeMorphFromFSA(sWord):
-        return True
-    if len(_dAnalyses[sWord]) == 1:
-        return True
-    lSelect = [ sMorph  for sMorph in _dAnalyses[sWord]  if re.search(sPattern, sMorph) ]
-    if lSelect:
-        if len(lSelect) != len(_dAnalyses[sWord]):
-            dDA[nPos] = lSelect
-            #echo("= "+sWord+" "+str(dDA.get(nPos, "null")))
-    elif lDefault:
-        dDA[nPos] = lDefault
-        #echo("= "+sWord+" "+str(dDA.get(nPos, "null")))
-    return True
-
-
-def exclude (dDA, nPos, sWord, sPattern, lDefault=None):
-    if not sWord:
-        return True
-    if nPos in dDA:
-        return True
-    if sWord not in _dAnalyses and not _storeMorphFromFSA(sWord):
-        return True
-    if len(_dAnalyses[sWord]) == 1:
-        return True
-    lSelect = [ sMorph  for sMorph in _dAnalyses[sWord]  if not re.search(sPattern, sMorph) ]
-    if lSelect:
-        if len(lSelect) != len(_dAnalyses[sWord]):
-            dDA[nPos] = lSelect
-            #echo("= "+sWord+" "+str(dDA.get(nPos, "null")))
-    elif lDefault:
-        dDA[nPos] = lDefault
-        #echo("= "+sWord+" "+str(dDA.get(nPos, "null")))
-    return True
-
-
-def define (dDA, nPos, lMorph):
-    dDA[nPos] = lMorph
-    #echo("= "+str(nPos)+" "+str(dDA[nPos]))
-    return True
+def g_select (dToken, sPattern, lDefault=None):
+    "select morphologies for <dToken> according to <sPattern>, always return True"
+    lMorph = dToken["lMorph"]  if "lMorph" in dToken  else _oSpellChecker.getMorph(dToken["sValue"])
+    if not lMorph or len(lMorph) == 1:
+        if lDefault:
+            dToken["lMorph"] = lDefault
+            #print("DA:", dToken["sValue"], dToken["lMorph"])
+        return True
+    lSelect = [ sMorph  for sMorph in lMorph  if re.search(sPattern, sMorph) ]
+    if lSelect:
+        if len(lSelect) != len(lMorph):
+            dToken["lMorph"] = lSelect
+    elif lDefault:
+        dToken["lMorph"] = lDefault
+    #print("DA:", dToken["sValue"], dToken["lMorph"])
+    return True
+
+
+def g_exclude (dToken, sPattern, lDefault=None):
+    "select morphologies for <dToken> according to <sPattern>, always return True"
+    lMorph = dToken["lMorph"]  if "lMorph" in dToken  else _oSpellChecker.getMorph(dToken["sValue"])
+    if not lMorph or len(lMorph) == 1:
+        if lDefault:
+            dToken["lMorph"] = lDefault
+            #print("DA:", dToken["sValue"], dToken["lMorph"])
+        return True
+    lSelect = [ sMorph  for sMorph in lMorph  if not re.search(sPattern, sMorph) ]
+    if lSelect:
+        if len(lSelect) != len(lMorph):
+            dToken["lMorph"] = lSelect
+    elif lDefault:
+        dToken["lMorph"] = lDefault
+    #print("DA:", dToken["sValue"], dToken["lMorph"])
+    return True
+
+
+def g_define (dToken, lMorph):
+    "set morphologies of <dToken>, always return True"
+    dToken["lMorph"] = lMorph
+    #print("DA:", dToken["sValue"], lMorph)
+    return True
+
 
 
 #### GRAMMAR CHECKER PLUGINS
 
 ${plugins}
 
 
+#### CALLABLES FOR REGEX RULES (generated code)
+
 ${callables}
+
+
+#### CALLABLES FOR GRAPH RULES (generated code)
+
+${graph_callables}

Index: gc_core/py/lang_core/gc_options.py
==================================================================
--- gc_core/py/lang_core/gc_options.py
+++ gc_core/py/lang_core/gc_options.py
@@ -1,14 +1,20 @@
+"""
+Grammar checker default options
+"""
+
 # generated code, do not edit
 
 def getUI (sLang):
+    "returns dictionary of UI labels"
     if sLang in _dOptLabel:
         return _dOptLabel[sLang]
     return _dOptLabel["fr"]
 
 
 def getOptions (sContext="Python"):
+    "returns dictionary of options"
     if sContext in dOpt:
         return dOpt[sContext]
     return dOpt["Python"]
 
 

Index: gc_core/py/lang_core/gc_rules.py
==================================================================
--- gc_core/py/lang_core/gc_rules.py
+++ gc_core/py/lang_core/gc_rules.py
@@ -1,5 +1,9 @@
+"""
+Grammar checker regex rules
+"""
+
 # generated code, do not edit
 
 lParagraphRules = ${paragraph_rules}
 
 lSentenceRules = ${sentence_rules}

ADDED   gc_core/py/lang_core/gc_rules_graph.py
Index: gc_core/py/lang_core/gc_rules_graph.py
==================================================================
--- /dev/null
+++ gc_core/py/lang_core/gc_rules_graph.py
@@ -0,0 +1,9 @@
+"""
+Grammar checker graph rules
+"""
+
+# generated code, do not edit
+
+dAllGraph = ${rules_graphs}
+
+dRule = ${rules_actions}

Index: gc_core/py/text.py
==================================================================
--- gc_core/py/text.py
+++ gc_core/py/text.py
@@ -1,6 +1,10 @@
 #!python3
+
+"""
+Text tools
+"""
 
 import textwrap
 from itertools import chain
 
 
@@ -41,27 +45,27 @@
     lSpellErrs = sorted(aSpellErrs, key=lambda d: d['nStart'])
     sText = ""
     nOffset = 0
     for sLine in wrap(sParagraph, nWidth): # textwrap.wrap(sParagraph, nWidth, drop_whitespace=False)
         sText += sLine + "\n"
-        ln = len(sLine)
+        nLineLen = len(sLine)
         sErrLine = ""
         nLenErrLine = 0
         nGrammErr = 0
         nSpellErr = 0
         for dErr in lGrammErrs:
             nStart = dErr["nStart"] - nOffset
-            if nStart < ln:
+            if nStart < nLineLen:
                 nGrammErr += 1
                 if nStart >= nLenErrLine:
                     sErrLine += " " * (nStart - nLenErrLine) + "^" * (dErr["nEnd"] - dErr["nStart"])
                     nLenErrLine = len(sErrLine)
             else:
                 break
         for dErr in lSpellErrs:
             nStart = dErr['nStart'] - nOffset
-            if nStart < ln:
+            if nStart < nLineLen:
                 nSpellErr += 1
                 nEnd = dErr['nEnd'] - nOffset
                 if nEnd > len(sErrLine):
                     sErrLine += " " * (nEnd - len(sErrLine))
                 sErrLine = sErrLine[:nStart] + "°" * (nEnd - nStart) + sErrLine[nEnd:]
@@ -73,11 +77,11 @@
             sText += getReadableErrors(lGrammErrs[:nGrammErr], nWidth)
             del lGrammErrs[0:nGrammErr]
         if nSpellErr:
             sText += getReadableErrors(lSpellErrs[:nSpellErr], nWidth, True)
             del lSpellErrs[0:nSpellErr]
-        nOffset += ln
+        nOffset += nLineLen
     return sText
 
 
 def getReadableErrors (lErrs, nWidth, bSpell=False):
     "Returns lErrs errors as readable errors"
@@ -95,19 +99,19 @@
 
 def getReadableError (dErr, bSpell=False):
     "Returns an error dErr as a readable error"
     try:
         if bSpell:
-            s = u"* {nStart}:{nEnd}  # {sValue}:".format(**dErr)
+            sText = u"* {nStart}:{nEnd}  # {sValue}:".format(**dErr)
         else:
-            s = u"* {nStart}:{nEnd}  # {sLineId} / {sRuleId}:\n".format(**dErr)
-            s += "  " + dErr.get("sMessage", "# error : message not found")
+            sText = u"* {nStart}:{nEnd}  # {sLineId} / {sRuleId}:\n".format(**dErr)
+            sText += "  " + dErr.get("sMessage", "# error : message not found")
         if dErr.get("aSuggestions", None):
-            s += "\n  > Suggestions : " + " | ".join(dErr.get("aSuggestions", "# error : suggestions not found"))
+            sText += "\n  > Suggestions : " + " | ".join(dErr.get("aSuggestions", "# error : suggestions not found"))
         if dErr.get("URL", None):
-            s += "\n  > URL: " + dErr["URL"]
-        return s
+            sText += "\n  > URL: " + dErr["URL"]
+        return sText
     except KeyError:
         return u"* Non-compliant error: {}".format(dErr)
 
 
 def createParagraphWithLines (lLine):

ADDED   gc_lang/fr/French_language.txt
Index: gc_lang/fr/French_language.txt
==================================================================
--- /dev/null
+++ gc_lang/fr/French_language.txt
@@ -0,0 +1,276 @@
+# NOTES SUR LA LANGUE FRANÇAISE
+
+## CE QUI ENTOURE UN VERBE
+
+    PRONOMS (avant)
+        COD         COI
+        le / l’
+        la / l’
+        les
+        en
+        me / m’     me / m’
+        te / t’     te / t’
+        se / s’     lui
+        nous        nous
+        vous        nous
+        se / s’     leur
+                    y
+
+    SOMME
+        [le|la|l’|les|en|me|m’|te|t’|se|s’|nous|vous|lui|leur|y]
+
+    ADVERBE DE NÉGATION (avant)
+        ne / n’
+
+    COMBINAISONS VALIDES
+        ?[ne|n’]¿   [me|te|se]      [le|la|l’|les]
+        ?[ne|n’]¿   [m’|t’|s’]      [le|la|l’|les|en|y]
+        ?[ne|n’]¿   [le|la]         [lui|leur]
+        ?[ne|n’]¿   [l’|les]        [lui|leur|en|y]
+        ?[ne|n’]¿   [lui|leur]      en
+        ?[ne|n’]¿   [nous|vous]     [le|la|l’|les|en|y]
+        ne          [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]
+        n’          [en|y]
+
+    RÉSUMÉ & SIMPLIFICATION
+        [ne|n’|le|la|l’|les|en|me|m’|te|t’|se|s’|nous|vous|lui|leur|y]
+        ?[ne|n’]¿   [le|la|l’|les|en|me|m’|te|t’|se|s’|nous|vous|lui|leur|y]
+        ?[ne|n’]¿   [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]
+        ?[ne|n’]¿   [le|la|l’|les]                  [lui|leur|en|y]
+        ?[ne|n’]¿   [lui|leur]                      en
+
+    ADVERBE DE NÉGATION (après)
+        guère
+        jamais
+        pas
+        plus
+        point
+        que / qu’
+        rien
+
+    PRONOMS À L’IMPÉRATIF
+        APRÈS
+            -moi
+            -toi
+            -lui
+            -leur
+            -nous
+            -vous
+            -le
+            -la
+            -les
+            -en
+            -y
+
+        AVANT
+            Uniquement les combinaisons avec l’adverbe de négation [ne|n’]
+
+
+## DÉTERMINANTS
+
+    SINGULIER               PLURIEL
+    le / la / l’            les
+    ledit / ladite          lesdits / lesdites
+    un / une                des
+    du / de la              des
+    dudit / de ladite       desdits / desdites
+    de                      de
+    ce / cet / cette        ces
+    icelui / icelle         iceux / icelles
+    mon / ma                mes
+    ton / ta                tes
+    son / sa                ses
+    votre                   nos
+    notre                   vos
+    leur                    leurs
+    quel / quelle           quels / quelles
+    quelque                 quelques
+    tout / toute            tous / toutes
+    chaque
+    aucun / aucune
+    nul / nulle
+                            plusieurs
+                            certains / certaines
+                            divers / diverses
+
+    DÉTERMINANT & PRÉPOSITION
+    au / à la               aux
+    audit / à ladite        auxdits / auxdites
+
+
+## CONJONCTIONS
+
+    DE COORDINATION         DE SUBORDINATION
+    c’est-à-dire            afin que            pendant que
+    c.-à-d.                 après que           pour que
+    car                     attendu que         pourvu que
+    donc                    avant que           puisque
+    et / &                  bien que            quand
+    mais                    comme               que
+    ni                      depuis que          quoique
+    or                      dès que             sans que
+    ou                      dès lors que        sauf que
+    partant                 excepté que         selon que
+    puis                    lorsque             si
+    sinon                   lors que            tandis que
+    soit                    malgré que          tant que
+                            parce que
+
+
+## PRÉPOSITIONS
+
+    VERBALES UNIQUEMENT
+        afin de
+
+    NOMINALES ET VERBALES
+        à
+        entre
+        excepté
+        outre
+        par
+        pour
+        sans
+        sauf
+
+    PRÉPOSITIONS ET DÉTERMINANTS
+        au
+        aux
+        audit
+        auxdits
+        auxdites
+
+    NOMINALES
+        à l’instar de               devers                      par-dessus  (adv)
+        à mi-distance de            dixit                       par-devant  (adv)
+        après                       durant                      par-devers
+        attendu                     dès                         parmi
+        au-dedans   (adv)           en                          passé
+        au-dehors   (adv)           endéans                     pendant
+        au-delà     (adv)           envers                      pour
+        au-dessous  (adv)           ès                          quant à/au/à la/aux
+        au-dessus   (adv)           excepté                     revoici
+        au-devant   (adv)           face à                      revoilà
+        auprès de                   fors                        sauf
+        autour de                   grâce à                     sans
+        av                          hormis                      selon
+        avant                       hors                        sous
+        avec                        jusque                      suivant
+        chez                        jusques                     sur
+        concernant                  lez                         tandis      (adv)
+        contre                      lors de                     vers
+        courant (+mois)             lès                         versus
+        dans                        malgré                      via
+        depuis                      moins       (adv)           vis-à-vis
+        derrière                    nonobstant  (adv)           voici
+        dessous     (adv)           par-delà                    voilà
+        dessus      (adv)           par-derrière  (adv)         vs
+        devant      (adv)           par-dessous   (adv)         vu
+
+
+## PRONOMS
+
+    PRONOMS PERSONNELS SUJETS
+    je                  moi-même                                mézigue
+    tu                  toi-même                                tézigue
+    il / elle           lui / lui-même / elle-même              césigue / sézigue
+    on
+    nous                nous-même / nous-mêmes                  noszigues
+    vous                vous-même / vous-mêmes                  voszigues
+    ils / elles         eux / eux-mêmes / elles-mêmes           leurszigues
+
+    PRONOMS PERSONNELS OBJETS
+    moi                 moi-même                                mézigue
+    toi                 toi-même                                tézigue
+    lui / elle          lui-même  / elle-même                   césigue / sézigue
+    soi                 soi-même
+    nous                nous-même / nous-mêmes                  noszigues
+    vous                vous-même / vous-mêmes                  voszigues
+    eux / elles         eux / eux-mêmes / elles-mêmes           leurszigues
+
+    PRONOMS NÉGATIFS (SUJETS & OBJETS)
+    aucun
+    aucune
+    dégun
+    nul
+    personne
+    rien
+
+    PRONOMS OBJETS PRÉVERBES
+    la      COD
+    le      COD
+    les     COD
+    l’      COD
+    leur    COI
+    lui     COI
+    me      COD/COI
+    te      COD/COI
+    se      COD/COI
+    nous    COD/COI
+    vous    COD/COI
+    y       COI (proadv)
+    en      COD (proadv)
+
+    PRONOMS DÉMONSTRATIFS (SUJETS ET OBJETS)
+    çuilà           propersuj properobj 3pe mas sg
+    ça              prodem mas sg
+    ceci            prodem mas sg
+    cela            prodem mas sg
+    celle qui       prodem fem sg
+    celles qui      prodem fem pl
+    celle-ci        prodem fem sg
+    celle-là        prodem fem sg
+    celles-ci       prodem fem pl
+    celles-là       prodem fem pl
+    celui qui       prodem mas sg
+    celui-ci        prodem mas sg
+    celui-là        prodem mas sg
+    ceux qui        prodem mas pl
+    ceux-ci         prodem mas pl
+    ceux-là         prodem mas pl
+
+    icelle          detdem prodem fem sg
+    icelles         detdem prodem fem pl
+    icelui          detdem prodem mas sg
+    iceux           detdem prodem mas pl
+
+    PRONOMS DÉMONSTRATIFS (SUJETS)
+    ce
+
+    PRONOMS DÉMONSTRATIFS (OBJETS)
+    ci              (adv)
+
+    PRONOMS RELATIFS
+    auquel          proint prorel mas sg
+    auxquelles      proint prorel fem pl
+    auxquels        proint prorel mas pl
+    desquelles      proint prorel fem pl
+    desquels        proint prorel mas pl
+    dont            prorel
+    duquel          proint prorel mas sg
+    laquelle        proint prorel fem sg
+    lequel          proint prorel mas sg
+    lesquelles      proint prorel fem pl
+    lesquels        proint prorel mas pl
+    où              advint prorel
+    qué             proint prorel
+    qui             proint prorel
+    que             proint prorel
+    quid            proint
+    quoi            proint prorel
+
+    autre           proind
+    autrui          proind
+    quiconque       proind prorel
+    certaine        detind proind
+    chacun          proind mas sg
+    chacune         proind fem sg
+    d'aucuns        proind mas pl
+    grand-chose     proind
+    n'importe quoi  proind
+    n'importe qui   proind
+    plupart         proind epi pl
+    quelques-unes   proind fem pl
+    quelques-uns    proind mas pl
+    quelqu'un       proind mas sg
+    quelqu'une      proind fem sg
+    telle           proind

Index: gc_lang/fr/config.ini
==================================================================
--- gc_lang/fr/config.ini
+++ gc_lang/fr/config.ini
@@ -1,14 +1,14 @@
 [args]
 lang = fr
 lang_name = French
-locales = fr_FR fr_BE fr_CA fr_CH fr_LU fr_BF fr_BJ fr_CD fr_CI fr_CM fr_MA fr_ML fr_MU fr_NE fr_RE fr_SN fr_TG 
+locales = fr_FR fr_BE fr_CA fr_CH fr_LU fr_BF fr_BJ fr_CD fr_CI fr_CM fr_MA fr_ML fr_MU fr_NE fr_RE fr_SN fr_TG
 country_default = FR
 name = Grammalecte
 implname = grammalecte
 # always use 3 numbers for version: x.y.z
-version = 0.6.4.2
+version = 0.7
 author = Olivier R.
 provider = Dicollecte
 link = http://grammalecte.net
 description = Correcteur grammatical pour le français.
 extras = README_fr.txt

Index: gc_lang/fr/modules-js/conj.js
==================================================================
--- gc_lang/fr/modules-js/conj.js
+++ gc_lang/fr/modules-js/conj.js
@@ -85,11 +85,11 @@
 
     getSimil: function (sWord, sMorph, bSubst=false) {
         if (!sMorph.includes(":V")) {
             return new Set();
         }
-        let sInfi = sMorph.slice(1, sMorph.indexOf(" "));
+        let sInfi = sMorph.slice(1, sMorph.indexOf("/"));
         let aSugg = new Set();
         let tTags = this._getTags(sInfi);
         if (tTags) {
             if (!bSubst) {
                 // we suggest conjugated forms

Index: gc_lang/fr/modules-js/gce_analyseur.js
==================================================================
--- gc_lang/fr/modules-js/gce_analyseur.js
+++ gc_lang/fr/modules-js/gce_analyseur.js
@@ -20,12 +20,11 @@
     }
     if (s2 == "eux") {
         return "ils";
     }
     if (s2 == "elle" || s2 == "elles") {
-        // We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-        if (cregex.mbNprMasNotFem(_dAnalyses.gl_get(s1, ""))) {
+        if (cregex.mbNprMasNotFem(_oSpellChecker.getMorph(s1))) {
             return "ils";
         }
         // si épicène, indéterminable, mais OSEF, le féminin l’emporte
         return "elles";
     }
@@ -32,41 +31,40 @@
     return s1 + " et " + s2;
 }
 
 function apposition (sWord1, sWord2) {
     // returns true if nom + nom (no agreement required)
-    // We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    return cregex.mbNomNotAdj(_dAnalyses.gl_get(sWord2, "")) && cregex.mbPpasNomNotAdj(_dAnalyses.gl_get(sWord1, ""));
+    return cregex.mbNomNotAdj(_oSpellChecker.getMorph(sWord2)) && cregex.mbPpasNomNotAdj(_oSpellChecker.getMorph(sWord1));
 }
 
 function isAmbiguousNAV (sWord) {
     // words which are nom|adj and verb are ambiguous (except être and avoir)
-    if (!_dAnalyses.has(sWord) && !_storeMorphFromFSA(sWord)) {
+    let lMorph = _oSpellChecker.getMorph(sWord);
+    if (lMorph.length === 0) {
         return false;
     }
-    if (!cregex.mbNomAdj(_dAnalyses.gl_get(sWord, "")) || sWord == "est") {
+    if (!cregex.mbNomAdj(lMorph) || sWord == "est") {
         return false;
     }
-    if (cregex.mbVconj(_dAnalyses.gl_get(sWord, "")) && !cregex.mbMG(_dAnalyses.gl_get(sWord, ""))) {
+    if (cregex.mbVconj(lMorph) && !cregex.mbMG(lMorph)) {
         return true;
     }
     return false;
 }
 
 function isAmbiguousAndWrong (sWord1, sWord2, sReqMorphNA, sReqMorphConj) {
     //// use it if sWord1 won’t be a verb; word2 is assumed to be true via isAmbiguousNAV
-    // We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    let a2 = _dAnalyses.gl_get(sWord2, null);
-    if (!a2 || a2.length === 0) {
+    let a2 = _oSpellChecker.getMorph(sWord2);
+    if (a2.length === 0) {
         return false;
     }
     if (cregex.checkConjVerb(a2, sReqMorphConj)) {
         // verb word2 is ok
         return false;
     }
-    let a1 = _dAnalyses.gl_get(sWord1, null);
-    if (!a1 || a1.length === 0) {
+    let a1 = _oSpellChecker.getMorph(sWord1);
+    if (a1.length === 0) {
         return false;
     }
     if (cregex.checkAgreement(a1, a2) && (cregex.mbAdj(a2) || cregex.mbAdj(a1))) {
         return false;
     }
@@ -73,21 +71,20 @@
     return true;
 }
 
 function isVeryAmbiguousAndWrong (sWord1, sWord2, sReqMorphNA, sReqMorphConj, bLastHopeCond) {
     //// use it if sWord1 can be also a verb; word2 is assumed to be true via isAmbiguousNAV
-    // We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    let a2 = _dAnalyses.gl_get(sWord2, null);
-    if (!a2 || a2.length === 0) {
+    let a2 = _oSpellChecker.getMorph(sWord2);
+    if (a2.length === 0) {
         return false;
     }
     if (cregex.checkConjVerb(a2, sReqMorphConj)) {
         // verb word2 is ok
         return false;
     }
-    let a1 = _dAnalyses.gl_get(sWord1, null);
-    if (!a1 || a1.length === 0) {
+    let a1 = _oSpellChecker.getMorph(sWord1);
+    if (a1.length === 0) {
         return false;
     }
     if (cregex.checkAgreement(a1, a2) && (cregex.mbAdj(a2) || cregex.mbAdjNb(a1))) {
         return false;
     }
@@ -101,17 +98,16 @@
     }
     return false;
 }
 
 function checkAgreement (sWord1, sWord2) {
-    // We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    let a2 = _dAnalyses.gl_get(sWord2, null);
-    if (!a2 || a2.length === 0) {
+    let a2 = _oSpellChecker.getMorph(sWord2);
+    if (a2.length === 0) {
         return true;
     }
-    let a1 = _dAnalyses.gl_get(sWord1, null);
-    if (!a1 || a1.length === 0) {
+    let a1 = _oSpellChecker.getMorph(sWord1);
+    if (a1.length === 0) {
         return true;
     }
     return cregex.checkAgreement(a1, a2);
 }
 

Index: gc_lang/fr/modules-js/gce_suggestions.js
==================================================================
--- gc_lang/fr/modules-js/gce_suggestions.js
+++ gc_lang/fr/modules-js/gce_suggestions.js
@@ -10,20 +10,19 @@
 
 
 //// verbs
 
 function suggVerb (sFlex, sWho, funcSugg2=null) {
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     let aSugg = new Set();
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         let tTags = conj._getTags(sStem);
         if (tTags) {
             // we get the tense
             let aTense = new Set();
-            for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+            for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
                 let m;
-                let zVerb = new RegExp (">"+sStem+" .*?(:(?:Y|I[pqsf]|S[pq]|K))", "g");
+                let zVerb = new RegExp (">"+sStem+"/.*?(:(?:Y|I[pqsf]|S[pq]|K))", "g");
                 while ((m = zVerb.exec(sMorph)) !== null) {
                     // stem must be used in regex to prevent confusion between different verbs (e.g. sauras has 2 stems: savoir and saurer)
                     if (m) {
                         if (m[1] === ":Y") {
                             aTense.add(":Ip");
@@ -59,11 +58,11 @@
     return "";
 }
 
 function suggVerbPpas (sFlex, sWhat=null) {
     let aSugg = new Set();
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         let tTags = conj._getTags(sStem);
         if (tTags) {
             if (!sWhat) {
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"));
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q2"));
@@ -109,11 +108,11 @@
     return "";
 }
 
 function suggVerbTense (sFlex, sTense, sWho) {
     let aSugg = new Set();
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         if (conj.hasConj(sStem, sTense, sWho)) {
             aSugg.add(conj.getConj(sStem, sTense, sWho));
         }
     }
     if (aSugg.size > 0) {
@@ -122,11 +121,11 @@
     return "";
 }
 
 function suggVerbImpe (sFlex) {
     let aSugg = new Set();
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         let tTags = conj._getTags(sStem);
         if (tTags) {
             if (conj._hasConjWithTags(tTags, ":E", ":2s")) {
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":E", ":2s"));
             }
@@ -143,11 +142,11 @@
     }
     return "";
 }
 
 function suggVerbInfi (sFlex) {
-    return stem(sFlex).filter(sStem => conj.isVerb(sStem)).join("|");
+    return _oSpellChecker.getLemma(sFlex).filter(sStem => conj.isVerb(sStem)).join("|");
 }
 
 
 const _dQuiEst = new Map ([
     ["je", ":1s"], ["j’", ":1s"], ["j’en", ":1s"], ["j’y", ":1s"],
@@ -174,11 +173,11 @@
             return "";
         }
         sWho = ":3s";
     }
     let aSugg = new Set();
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         let tTags = conj._getTags(sStem);
         if (tTags) {
             for (let sTense of lMode) {
                 if (conj._hasConjWithTags(tTags, sTense, sWho)) {
                     aSugg.add(conj._getConjWithTags(sStem, tTags, sTense, sWho));
@@ -195,14 +194,15 @@
 //// Nouns and adjectives
 
 function suggPlur (sFlex, sWordToAgree=null) {
     // returns plural forms assuming sFlex is singular
     if (sWordToAgree) {
-        if (!_dAnalyses.has(sWordToAgree) && !_storeMorphFromFSA(sWordToAgree)) {
+        let lMorph = _oSpellChecker.getMorph(sWordToAgree);
+        if (lMorph.length === 0) {
             return "";
         }
-        let sGender = cregex.getGender(_dAnalyses.gl_get(sWordToAgree, []));
+        let sGender = cregex.getGender(lMorph);
         if (sGender == ":m") {
             return suggMasPlur(sFlex);
         } else if (sGender == ":f") {
             return suggFemPlur(sFlex);
         }
@@ -256,13 +256,12 @@
     return "";
 }
 
 function suggMasSing (sFlex, bSuggSimil=false) {
     // returns masculine singular forms
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     let aSugg = new Set();
-    for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+    for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
         if (!sMorph.includes(":V")) {
             // not a verb
             if (sMorph.includes(":m") || sMorph.includes(":e")) {
                 aSugg.add(suggSing(sFlex));
             } else {
@@ -292,13 +291,12 @@
     return "";
 }
 
 function suggMasPlur (sFlex, bSuggSimil=false) {
     // returns masculine plural forms
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     let aSugg = new Set();
-    for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+    for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
         if (!sMorph.includes(":V")) {
             // not a verb
             if (sMorph.includes(":m") || sMorph.includes(":e")) {
                 aSugg.add(suggPlur(sFlex));
             } else {
@@ -333,13 +331,12 @@
 }
 
 
 function suggFemSing (sFlex, bSuggSimil=false) {
     // returns feminine singular forms
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     let aSugg = new Set();
-    for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+    for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
         if (!sMorph.includes(":V")) {
             // not a verb
             if (sMorph.includes(":f") || sMorph.includes(":e")) {
                 aSugg.add(suggSing(sFlex));
             } else {
@@ -367,13 +364,12 @@
     return "";
 }
 
 function suggFemPlur (sFlex, bSuggSimil=false) {
     // returns feminine plural forms
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     let aSugg = new Set();
-    for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+    for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
         if (!sMorph.includes(":V")) {
             // not a verb
             if (sMorph.includes(":f") || sMorph.includes(":e")) {
                 aSugg.add(suggPlur(sFlex));
             } else {
@@ -400,11 +396,11 @@
     }
     return "";
 }
 
 function hasFemForm (sFlex) {
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         if (mfsp.isFemForm(sStem) || conj.hasConj(sStem, ":PQ", ":Q3")) {
             return true;
         }
     }
     if (phonet.hasSimil(sFlex, ":f")) {
@@ -412,11 +408,11 @@
     }
     return false;
 }
 
 function hasMasForm (sFlex) {
-    for (let sStem of stem(sFlex)) {
+    for (let sStem of _oSpellChecker.getLemma(sFlex)) {
         if (mfsp.isFemForm(sStem) || conj.hasConj(sStem, ":PQ", ":Q1")) {
             // what has a feminine form also has a masculine form
             return true;
         }
     }
@@ -425,14 +421,13 @@
     }
     return false;
 }
 
 function switchGender (sFlex, bPlur=null) {
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     let aSugg = new Set();
     if (bPlur === null) {
-        for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+        for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
             if (sMorph.includes(":f")) {
                 if (sMorph.includes(":s")) {
                     aSugg.add(suggMasSing(sFlex));
                 } else if (sMorph.includes(":p")) {
                     aSugg.add(suggMasPlur(sFlex));
@@ -447,19 +442,19 @@
                     aSugg.add(suggFemPlur(sFlex));
                 }
             }
         }
     } else if (bPlur) {
-        for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+        for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
             if (sMorph.includes(":f")) {
                 aSugg.add(suggMasPlur(sFlex));
             } else if (sMorph.includes(":m")) {
                 aSugg.add(suggFemPlur(sFlex));
             }
         }
     } else {
-        for (let sMorph of _dAnalyses.gl_get(sFlex, [])) {
+        for (let sMorph of _oSpellChecker.getMorph(sFlex)) {
             if (sMorph.includes(":f")) {
                 aSugg.add(suggMasSing(sFlex));
             } else if (sMorph.includes(":m")) {
                 aSugg.add(suggFemSing(sFlex));
             }
@@ -471,11 +466,11 @@
     return "";
 }
 
 function switchPlural (sFlex) {
     let aSugg = new Set();
-    for (let sMorph of _dAnalyses.gl_get(sFlex, [])) { // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
+    for (let sMorph of _oSpellChecker.getMorph(sFlex)) { 
         if (sMorph.includes(":s")) {
             aSugg.add(suggPlur(sFlex));
         } else if (sMorph.includes(":p")) {
             aSugg.add(suggSing(sFlex));
         }
@@ -491,11 +486,11 @@
 }
 
 function suggSimil (sWord, sPattern=null, bSubst=false) {
     // return list of words phonetically similar to sWord and whom POS is matching sPattern
     let aSugg = phonet.selectSimil(sWord, sPattern);
-    for (let sMorph of _dAnalyses.gl_get(sWord, [])) {
+    for (let sMorph of _oSpellChecker.getMorph(sWord)) {
         for (let e of conj.getSimil(sWord, sMorph, bSubst)) {
             aSugg.add(e);
         }
     }
     if (aSugg.size > 0) {
@@ -513,12 +508,11 @@
     }
     return "ce";
 }
 
 function suggLesLa (sWord) {
-    // we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    if (_dAnalyses.gl_get(sWord, []).some(s  =>  s.includes(":p"))) {
+    if (_oSpellChecker.getMorph(sWord).some(s  =>  s.includes(":p"))) {
         return "les|la";
     }
     return "la";
 }
 

Index: gc_lang/fr/modules-js/lexicographe.js
==================================================================
--- gc_lang/fr/modules-js/lexicographe.js
+++ gc_lang/fr/modules-js/lexicographe.js
@@ -85,11 +85,11 @@
     [':C', [" conjonction,", "Conjonction"]],
     [':Ĉ', [" conjonction (él.),", "Conjonction (élément)"]],
     [':Cc', [" conjonction de coordination,", "Conjonction de coordination"]],
     [':Cs', [" conjonction de subordination,", "Conjonction de subordination"]],
     [':Ĉs', [" conjonction de subordination (él.),", "Conjonction de subordination (élément)"]],
-    
+
     [':Ñ', [" locution nominale (él.),", "Locution nominale (élément)"]],
     [':Â', [" locution adjectivale (él.),", "Locution adjectivale (élément)"]],
     [':Ṽ', [" locution verbale (él.),", "Locution verbale (élément)"]],
     [':Ŵ', [" locution adverbiale (él.),", "Locution adverbiale (élément)"]],
     [':Ŕ', [" locution prépositive (él.),", "Locution prépositive (élément)"]],
@@ -189,11 +189,11 @@
     ["m'en", " (me) pronom personnel objet + (en) pronom adverbial"],
     ["t'en", " (te) pronom personnel objet + (en) pronom adverbial"],
     ["s'en", " (se) pronom personnel objet + (en) pronom adverbial"]
 ]);
 
-const _dSeparator = new Map([
+const _dChar = new Map([
     ['.', "point"],
     ['·', "point médian"],
     ['…', "points de suspension"],
     [':', "deux-points"],
     [';', "point-virgule"],
@@ -213,16 +213,21 @@
     ['»', "guillemet fermant (chevrons)"],
     ['“', "guillemet ouvrant double"],
     ['”', "guillemet fermant double"],
     ['‘', "guillemet ouvrant"],
     ['’', "guillemet fermant"],
+    ['"', "guillemets droits (déconseillé en typographie)"],
     ['/', "signe de la division"],
     ['+', "signe de l’addition"],
     ['*', "signe de la multiplication"],
     ['=', "signe de l’égalité"],
     ['<', "inférieur à"],
     ['>', "supérieur à"],
+    ['⩽', "inférieur ou égal à"],
+    ['⩾', "supérieur ou égal à"],
+    ['%', "signe de pourcentage"],
+    ['‰', "signe pour mille"],
 ]);
 
 
 class Lexicographe {
 
@@ -243,14 +248,15 @@
         // return a object {sType, sValue, aLabel}
         let m = null;
         try {
             switch (oToken.sType) {
                 case 'SEPARATOR':
+                case 'SIGN':
                     return {
                         sType: oToken.sType,
                         sValue: oToken.sValue,
-                        aLabel: [_dSeparator.gl_get(oToken.sValue, "caractère indéterminé")]
+                        aLabel: [_dChar.gl_get(oToken.sValue, "caractère indéterminé")]
                     };
                     break;
                 case 'NUM':
                     return {
                         sType: oToken.sType,
@@ -263,17 +269,24 @@
                         sType: oToken.sType,
                         sValue: oToken.sValue.slice(0, 40) + "…",
                         aLabel: ["hyperlien"]
                     };
                     break;
-                case 'ELPFX':
+                case 'WORD_ELIDED':
                     let sTemp = oToken.sValue.replace("’", "").replace("'", "").replace("`", "").toLowerCase();
                     return {
                         sType: oToken.sType,
                         sValue: oToken.sValue,
                         aLabel: [_dElidedPrefix.gl_get(sTemp, "préfixe élidé inconnu")]
                     };
+                    break;
+                case 'WORD_ORDINAL':
+                    return {
+                        sType: oToken.sType,
+                        sValue: oToken.sValue,
+                        aLabel: ["nombre ordinal"]
+                    };
                     break;
                 case 'FOLDERUNIX':
                     return {
                         sType: oToken.sType,
                         sValue: oToken.sValue.slice(0, 40) + "…",
@@ -285,11 +298,11 @@
                         sType: oToken.sType,
                         sValue: oToken.sValue.slice(0, 40) + "…",
                         aLabel: ["dossier Windows"]
                     };
                     break;
-                case 'ACRONYM':
+                case 'WORD_ACRONYM':
                     return {
                         sType: oToken.sType,
                         sValue: oToken.sValue,
                         aLabel: ["Sigle ou acronyme"]
                     };
@@ -454,11 +467,11 @@
         let aElem = [];
         do {
             let oToken = aTokenList[iKey];
             let sMorphLoc = '';
             let aTokenTempList = [oToken];
-            if (oToken.sType == "WORD" || oToken.sType == "ELPFX"){
+            if (oToken.sType == "WORD" || oToken.sType == "WORD_ELIDED"){
                 let iKeyTree = iKey + 1;
                 let oLocNode = this.oLocGraph[oToken.sValue.toLowerCase()];
                 while (oLocNode) {
                     let oTokenNext = aTokenList[iKeyTree];
                     iKeyTree++;

Index: gc_lang/fr/modules-js/tests_data.json
==================================================================
--- gc_lang/fr/modules-js/tests_data.json
+++ gc_lang/fr/modules-js/tests_data.json
@@ -1,1 +1,1 @@
-${gctestsJS}
+${regex_gctestsJS}

Index: gc_lang/fr/modules/conj.py
==================================================================
--- gc_lang/fr/modules/conj.py
+++ gc_lang/fr/modules/conj.py
@@ -1,6 +1,9 @@
-# Grammalecte - Conjugueur
+"""
+Grammalecte - Conjugueur
+"""
+
 # License: GPL 3
 
 import re
 import traceback
 
@@ -27,10 +30,11 @@
 _dTenseIdx = { ":PQ": 0, ":Ip": 1, ":Iq": 2, ":Is": 3, ":If": 4, ":K": 5, ":Sp": 6, ":Sq": 7, ":E": 8 }
 
 
 
 def isVerb (sVerb):
+    "return True if it’s a existing verb"
     return sVerb in _dVerb
 
 
 def getConj (sVerb, sTense, sWho):
     "returns conjugation (can be an empty string)"
@@ -54,13 +58,14 @@
         return None
     return _lVtyp[_dVerb[sVerb][0]]
 
 
 def getSimil (sWord, sMorph, bSubst=False):
+    "returns a set of verbal forms similar to <sWord>, according to <sMorph>"
     if ":V" not in sMorph:
         return set()
-    sInfi = sMorph[1:sMorph.find(" ")]
+    sInfi = sMorph[1:sMorph.find("/")]
     aSugg = set()
     tTags = _getTags(sInfi)
     if tTags:
         if not bSubst:
             # we suggest conjugated forms
@@ -98,10 +103,11 @@
                 aSugg.clear()
     return aSugg
 
 
 def getConjSimilInfiV1 (sInfi):
+    "returns verbal forms phonetically similar to infinitive form (for verb in group 1)"
     if sInfi not in _dVerb:
         return set()
     aSugg = set()
     tTags = _getTags(sInfi)
     if tTags:
@@ -140,16 +146,18 @@
         return ""
     if sSfx == "0":
         return sWord
     try:
         return sWord[:-(ord(sSfx[0])-48)] + sSfx[1:]  if sSfx[0] != '0'  else  sWord + sSfx[1:]  # 48 is the ASCII code for "0"
-    except:
+    except (IndexError, TypeError):
         return "## erreur, code : " + str(sSfx) + " ##"
-        
+
 
 
 class Verb ():
+    "Verb and its conjugation"
+
     def __init__ (self, sVerb, sVerbPattern=""):
         # conjugate a unknown verb with rules from sVerbPattern
         if not isinstance(sVerb, str):
             raise TypeError("sVerb should be a string")
         if not sVerb:
@@ -165,11 +173,11 @@
         self.bProWithEn = (self._sRawInfo[5] == "e")
         self._tTags = _getTags(sVerbPattern)
         if not self._tTags:
             raise ValueError("Unknown verb.")
         self._tTagsAux = _getTags(self.sVerbAux)
-        self.cGroup = self._sRawInfo[0];
+        self.cGroup = self._sRawInfo[0]
         self.dConj = {
             ":Y": {
                 "label": "Infinitif",
                 ":": sVerb,
             },
@@ -289,10 +297,11 @@
         except:
             traceback.print_exc()
             return "# erreur"
 
     def infinitif (self, bPro, bNeg, bTpsCo, bInt, bFem):
+        "returns string (conjugaison à l’infinitif)"
         try:
             if bTpsCo:
                 sInfi = self.sVerbAux  if not bPro  else  "être"
             else:
                 sInfi = self.sVerb
@@ -311,17 +320,19 @@
         except:
             traceback.print_exc()
             return "# erreur"
 
     def participePasse (self, sWho):
+        "returns past participle according to <sWho>"
         try:
             return self.dConj[":Q"][sWho]
         except:
             traceback.print_exc()
             return "# erreur"
 
     def participePresent (self, bPro, bNeg, bTpsCo, bInt, bFem):
+        "returns string (conjugaison du participe présent)"
         try:
             if not self.dConj[":P"][":"]:
                 return ""
             if bTpsCo:
                 sPartPre = _getConjWithTags(self.sVerbAux, self._tTagsAux, ":PQ", ":P")  if not bPro  else  getConj("être", ":PQ", ":P")
@@ -348,10 +359,11 @@
         except:
             traceback.print_exc()
             return "# erreur"
 
     def conjugue (self, sTemps, sWho, bPro, bNeg, bTpsCo, bInt, bFem):
+        "returns string (conjugue le verbe au temps <sTemps> pour <sWho>) "
         try:
             if not self.dConj[sTemps][sWho]:
                 return ""
             if not bTpsCo and bInt and sWho == ":1s" and self.dConj[sTemps].get(":1ś", False):
                 sWho = ":1ś"
@@ -370,16 +382,16 @@
             if bNeg:
                 sConj = "n’" + sConj  if bEli and not bPro  else  "ne " + sConj
             if bInt:
                 if sWho == ":3s" and not _zNeedTeuph.search(sConj):
                     sConj += "-t"
-                sConj += "-" + self._getPronom(sWho, bFem)
+                sConj += "-" + self._getPronomSujet(sWho, bFem)
             else:
                 if sWho == ":1s" and bEli and not bNeg and not bPro:
                     sConj = "j’" + sConj
                 else:
-                    sConj = self._getPronom(sWho, bFem) + " " + sConj
+                    sConj = self._getPronomSujet(sWho, bFem) + " " + sConj
             if bNeg:
                 sConj += " pas"
             if bTpsCo:
                 sConj += " " + self._seekPpas(bPro, bFem, sWho.endswith("p") or self._sRawInfo[5] == "r")
             if bInt:
@@ -387,11 +399,11 @@
             return sConj
         except:
             traceback.print_exc()
             return "# erreur"
 
-    def _getPronom (self, sWho, bFem):
+    def _getPronomSujet (self, sWho, bFem):
         try:
             if sWho == ":3s":
                 if self._sRawInfo[5] == "r":
                     return "on"
                 elif bFem:
@@ -402,10 +414,11 @@
         except:
             traceback.print_exc()
             return "# erreur"
 
     def imperatif (self, sWho, bPro, bNeg, bTpsCo, bFem):
+        "returns string (conjugaison à l’impératif)"
         try:
             if not self.dConj[":E"][sWho]:
                 return ""
             if bTpsCo:
                 sImpe = _getConjWithTags(self.sVerbAux, self._tTagsAux, ":E", sWho)  if not bPro  else  getConj(u"être", ":E", sWho)

Index: gc_lang/fr/modules/conj_generator.py
==================================================================
--- gc_lang/fr/modules/conj_generator.py
+++ gc_lang/fr/modules/conj_generator.py
@@ -1,22 +1,26 @@
-# Conjugation generator
-# beta stage, unfinished, the root for a new way to generate flexions…
+"""
+Conjugation generator
+beta stage, unfinished, the root for a new way to generate flexions…
+"""
 
 import re
 
 
 def conjugate (sVerb, sVerbTag="i_____a", bVarPpas=True):
+    "conjugate <sVerb> and returns a list of tuples (conjugation form, tags)"
     lConj = []
     cGroup = getVerbGroupChar(sVerb)
     for nCut, sAdd, sFlexTags, sPattern in getConjRules(sVerb, bVarPpas):
         if not sPattern or re.search(sPattern, sVerb):
             sFlexion = sVerb[0:-nCut] + sAdd  if nCut  else sVerb + sAdd
             lConj.append((sFlexion, ":V" + cGroup + "_" + sVerbTag + sFlexTags))
     return lConj
 
 
-def getVerbGroupChar (sVerb, ):
+def getVerbGroupChar (sVerb):
+    "returns the group number of <sVerb> guessing on its ending"
     sVerb = sVerb.lower()
     if sVerb.endswith("er"):
         return "1"
     if sVerb.endswith("ir"):
         return "2"
@@ -26,10 +30,11 @@
         return "3"
     return "4"
 
 
 def getConjRules (sVerb, bVarPpas=True, nGroup=2):
+    "returns a list of lists to conjugate a verb, guessing on its ending"
     if sVerb.endswith("er"):
         # premier groupe, conjugaison en fonction de la terminaison du lemme
         # 5 lettres
         if sVerb[-5:] in oConj["V1"]:
             lConj = list(oConj["V1"][sVerb[-5:]])
@@ -115,11 +120,11 @@
         [2,     "ît",           ":Sq:3s/*",         False],
         [2,     "is",           ":E:2s/*",          False],
         [2,     "issons",       ":E:1p/*",          False],
         [2,     "issez",        ":E:2p/*",          False]
     ],
-    
+
     # premier groupe (bien plus irrégulier que prétendu)
     "V1": {
         # a
         # verbes en -er, -ger, -yer, -cer
         "er": [

Index: gc_lang/fr/modules/cregex.py
==================================================================
--- gc_lang/fr/modules/cregex.py
+++ gc_lang/fr/modules/cregex.py
@@ -1,11 +1,13 @@
-# Grammalecte - Compiled regular expressions
+"""
+Grammalecte - Compiled regular expressions
+"""
 
 import re
 
 #### Lemme
-Lemma = re.compile("^>(\w[\w-]*)")
+Lemma = re.compile(r"^>(\w[\w-]*)")
 
 #### Analyses
 Gender = re.compile(":[mfe]")
 Number = re.compile(":[spi]")
 
@@ -78,13 +80,15 @@
 
 
 #### FONCTIONS
 
 def getLemmaOfMorph (s):
+    "return lemma in morphology <s>"
     return Lemma.search(s).group(1)
 
 def checkAgreement (l1, l2):
+    "returns True if agreement in gender and number is possible between morphologies <l1> and <l2>"
     # check number agreement
     if not mbInv(l1) and not mbInv(l2):
         if mbSg(l1) and not mbSg(l2):
             return False
         if mbPl(l1) and not mbPl(l2):
@@ -97,10 +101,11 @@
     if mbFem(l1) and not mbFem(l2):
         return False
     return True
 
 def checkConjVerb (lMorph, sReqConj):
+    "returns True if <sReqConj> in <lMorph>"
     return any(sReqConj in s  for s in lMorph)
 
 def getGender (lMorph):
     "returns gender of word (':m', ':f', ':e' or empty string)."
     sGender = ""
@@ -115,11 +120,11 @@
 
 def getNumber (lMorph):
     "returns number of word (':s', ':p', ':i' or empty string)."
     sNumber = ""
     for sMorph in lMorph:
-        m = Number.search(sWord)
+        m = Number.search(sMorph)
         if m:
             if not sNumber:
                 sNumber = m.group(0)
             elif sNumber != m.group(0):
                 return ":i"
@@ -129,98 +134,126 @@
 #         mbWhat (lMorph)    returns True   if lMorph contains What at least once
 
 ## isXXX = it’s certain
 
 def isNom (lMorph):
+    "returns True if all morphologies are “nom”"
     return all(":N" in s  for s in lMorph)
 
 def isNomNotAdj (lMorph):
+    "returns True if all morphologies are “nom”, but not “adjectif”"
     return all(NnotA.search(s)  for s in lMorph)
 
 def isAdj (lMorph):
+    "returns True if all morphologies are “adjectif”"
     return all(":A" in s  for s in lMorph)
 
 def isNomAdj (lMorph):
+    "returns True if all morphologies are “nom” or “adjectif”"
     return all(NA.search(s)  for s in lMorph)
 
 def isNomVconj (lMorph):
+    "returns True if all morphologies are “nom” or “verbe conjugué”"
     return all(NVconj.search(s)  for s in lMorph)
 
 def isInv (lMorph):
+    "returns True if all morphologies are “invariable”"
     return all(":i" in s  for s in lMorph)
 
 def isSg (lMorph):
+    "returns True if all morphologies are “singulier”"
     return all(":s" in s  for s in lMorph)
 
 def isPl (lMorph):
+    "returns True if all morphologies are “pluriel”"
     return all(":p" in s  for s in lMorph)
 
 def isEpi (lMorph):
+    "returns True if all morphologies are “épicène”"
     return all(":e" in s  for s in lMorph)
 
 def isMas (lMorph):
+    "returns True if all morphologies are “masculin”"
     return all(":m" in s  for s in lMorph)
 
 def isFem (lMorph):
+    "returns True if all morphologies are “féminin”"
     return all(":f" in s  for s in lMorph)
 
 
 ## mbXXX = MAYBE XXX
 
 def mbNom (lMorph):
+    "returns True if one morphology is “nom”"
     return any(":N" in s  for s in lMorph)
 
 def mbAdj (lMorph):
+    "returns True if one morphology is “adjectif”"
     return any(":A" in s  for s in lMorph)
 
 def mbAdjNb (lMorph):
+    "returns True if one morphology is “adjectif” or “nombre”"
     return any(AD.search(s)  for s in lMorph)
 
 def mbNomAdj (lMorph):
+    "returns True if one morphology is “nom” or “adjectif”"
     return any(NA.search(s)  for s in lMorph)
 
 def mbNomNotAdj (lMorph):
-    b = False
+    "returns True if one morphology is “nom”, but not “adjectif”"
+    bResult = False
     for s in lMorph:
         if ":A" in s:
             return False
         if ":N" in s:
-            b = True
-    return b
+            bResult = True
+    return bResult
 
 def mbPpasNomNotAdj (lMorph):
+    "returns True if one morphology is “nom” or “participe passé”, but not “adjectif”"
     return any(PNnotA.search(s)  for s in lMorph)
 
 def mbVconj (lMorph):
+    "returns True if one morphology is “nom” or “verbe conjugué”"
     return any(Vconj.search(s)  for s in lMorph)
 
 def mbVconj123 (lMorph):
+    "returns True if one morphology is “nom” or “verbe conjugué” (but not “avoir” or “être”)"
     return any(Vconj123.search(s)  for s in lMorph)
 
 def mbMG (lMorph):
+    "returns True if one morphology is “mot grammatical”"
     return any(":G" in s  for s in lMorph)
 
 def mbInv (lMorph):
+    "returns True if one morphology is “invariable”"
     return any(":i" in s  for s in lMorph)
 
 def mbSg (lMorph):
+    "returns True if one morphology is “singulier”"
     return any(":s" in s  for s in lMorph)
 
 def mbPl (lMorph):
+    "returns True if one morphology is “pluriel”"
     return any(":p" in s  for s in lMorph)
 
 def mbEpi (lMorph):
+    "returns True if one morphology is “épicène”"
     return any(":e" in s  for s in lMorph)
 
 def mbMas (lMorph):
+    "returns True if one morphology is “masculin”"
     return any(":m" in s  for s in lMorph)
 
 def mbFem (lMorph):
+    "returns True if one morphology is “féminin”"
     return any(":f" in s  for s in lMorph)
 
 def mbNpr (lMorph):
+    "returns True if one morphology is “nom propre” or “titre de civilité”"
     return any(NP.search(s)  for s in lMorph)
 
 def mbNprMasNotFem (lMorph):
+    "returns True if one morphology is “nom propre masculin” but not “féminin”"
     if any(NPf.search(s)  for s in lMorph):
         return False
     return any(NPm.search(s)  for s in lMorph)

Index: gc_lang/fr/modules/gce_analyseur.py
==================================================================
--- gc_lang/fr/modules/gce_analyseur.py
+++ gc_lang/fr/modules/gce_analyseur.py
@@ -2,11 +2,11 @@
 
 from . import cregex as cr
 
 
 def rewriteSubject (s1, s2):
-    # s1 is supposed to be prn/patr/npr (M[12P])
+    "rewrite complex subject: <s1> a prn/patr/npr (M[12P]) followed by “et” and <s2>"
     if s2 == "lui":
         return "ils"
     if s2 == "moi":
         return "nous"
     if s2 == "toi":
@@ -16,62 +16,57 @@
     if s2 == "vous":
         return "vous"
     if s2 == "eux":
         return "ils"
     if s2 == "elle" or s2 == "elles":
-        # We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-        if cr.mbNprMasNotFem(_dAnalyses.get(s1, False)):
+        if cr.mbNprMasNotFem(_oSpellChecker.getMorph(s1)):
             return "ils"
         # si épicène, indéterminable, mais OSEF, le féminin l’emporte
         return "elles"
     return s1 + " et " + s2
 
 
 def apposition (sWord1, sWord2):
     "returns True if nom + nom (no agreement required)"
-    # We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    return cr.mbNomNotAdj(_dAnalyses.get(sWord2, False)) and cr.mbPpasNomNotAdj(_dAnalyses.get(sWord1, False))
+    return cr.mbNomNotAdj(_oSpellChecker.getMorph(sWord2)) and cr.mbPpasNomNotAdj(_oSpellChecker.getMorph(sWord1))
 
 
 def isAmbiguousNAV (sWord):
     "words which are nom|adj and verb are ambiguous (except être and avoir)"
-    if sWord not in _dAnalyses and not _storeMorphFromFSA(sWord):
+    lMorph = _oSpellChecker.getMorph(sWord)
+    if not cr.mbNomAdj(lMorph) or sWord == "est":
         return False
-    if not cr.mbNomAdj(_dAnalyses[sWord]) or sWord == "est":
-        return False
-    if cr.mbVconj(_dAnalyses[sWord]) and not cr.mbMG(_dAnalyses[sWord]):
+    if cr.mbVconj(lMorph) and not cr.mbMG(lMorph):
         return True
     return False
 
 
 def isAmbiguousAndWrong (sWord1, sWord2, sReqMorphNA, sReqMorphConj):
-    "use it if sWord1 won’t be a verb; word2 is assumed to be True via isAmbiguousNAV"
-    # We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    a2 = _dAnalyses.get(sWord2, None)
+    "use it if <sWord1> won’t be a verb; <sWord2> is assumed to be True via isAmbiguousNAV"
+    a2 = _oSpellChecker.getMorph(sWord2)
     if not a2:
         return False
     if cr.checkConjVerb(a2, sReqMorphConj):
         # verb word2 is ok
         return False
-    a1 = _dAnalyses.get(sWord1, None)
+    a1 = _oSpellChecker.getMorph(sWord1)
     if not a1:
         return False
     if cr.checkAgreement(a1, a2) and (cr.mbAdj(a2) or cr.mbAdj(a1)):
         return False
     return True
 
 
 def isVeryAmbiguousAndWrong (sWord1, sWord2, sReqMorphNA, sReqMorphConj, bLastHopeCond):
-    "use it if sWord1 can be also a verb; word2 is assumed to be True via isAmbiguousNAV"
-    # We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    a2 = _dAnalyses.get(sWord2, None)
+    "use it if <sWord1> can be also a verb; <sWord2> is assumed to be True via isAmbiguousNAV"
+    a2 = _oSpellChecker.getMorph(sWord2)
     if not a2:
         return False
     if cr.checkConjVerb(a2, sReqMorphConj):
         # verb word2 is ok
         return False
-    a1 = _dAnalyses.get(sWord1, None)
+    a1 = _oSpellChecker.getMorph(sWord1)
     if not a1:
         return False
     if cr.checkAgreement(a1, a2) and (cr.mbAdj(a2) or cr.mbAdjNb(a1)):
         return False
     # now, we know there no agreement, and conjugation is also wrong
@@ -82,24 +77,25 @@
         return True
     return False
 
 
 def checkAgreement (sWord1, sWord2):
-    # We don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    a2 = _dAnalyses.get(sWord2, None)
+    "check agreement between <sWord1> and <sWord1>"
+    a2 = _oSpellChecker.getMorph(sWord2)
     if not a2:
         return True
-    a1 = _dAnalyses.get(sWord1, None)
+    a1 = _oSpellChecker.getMorph(sWord1)
     if not a1:
         return True
     return cr.checkAgreement(a1, a2)
 
 
 _zUnitSpecial = re.compile("[µ/⁰¹²³⁴⁵⁶⁷⁸⁹Ωℓ·]")
 _zUnitNumbers = re.compile("[0-9]")
 
 def mbUnit (s):
+    "returns True it can be a measurement unit"
     if _zUnitSpecial.search(s):
         return True
     if 1 < len(s) < 16 and s[0:1].islower() and (not s[1:].islower() or _zUnitNumbers.search(s)):
         return True
     return False
@@ -110,10 +106,11 @@
 _zEndOfNG1 = re.compile(" *$| +(?:, +|)(?:n(?:’|e |o(?:u?s|tre) )|l(?:’|e(?:urs?|s|) |a )|j(?:’|e )|m(?:’|es? |a |on )|t(?:’|es? |a |u )|s(?:’|es? |a )|c(?:’|e(?:t|tte|s|) )|ç(?:a |’)|ils? |vo(?:u?s|tre) )")
 _zEndOfNG2 = re.compile(r" +(\w[\w-]+)")
 _zEndOfNG3 = re.compile(r" *, +(\w[\w-]+)")
 
 def isEndOfNG (dDA, s, iOffset):
+    "returns True if next word doesn’t belong to a noun group"
     if _zEndOfNG1.match(s):
         return True
     m = _zEndOfNG2.match(s)
     if m and morphex(dDA, (iOffset+m.start(1), m.group(1)), ":[VR]", ":[NAQP]"):
         return True
@@ -126,10 +123,11 @@
 _zNextIsNotCOD1 = re.compile(" *,")
 _zNextIsNotCOD2 = re.compile(" +(?:[mtsnj](e +|’)|[nv]ous |tu |ils? |elles? )")
 _zNextIsNotCOD3 = re.compile(r" +([a-zéèî][\w-]+)")
 
 def isNextNotCOD (dDA, s, iOffset):
+    "returns True if next word is not a COD"
     if _zNextIsNotCOD1.match(s) or _zNextIsNotCOD2.match(s):
         return True
     m = _zNextIsNotCOD3.match(s)
     if m and morphex(dDA, (iOffset+m.start(1), m.group(1)), ":[123][sp]", ":[DM]"):
         return True
@@ -138,10 +136,11 @@
 
 _zNextIsVerb1 = re.compile(" +[nmts](?:e |’)")
 _zNextIsVerb2 = re.compile(r" +(\w[\w-]+)")
 
 def isNextVerb (dDA, s, iOffset):
+    "returns True if next word is a verb"
     if _zNextIsVerb1.match(s):
         return True
     m = _zNextIsVerb2.match(s)
     if m and morph(dDA, (iOffset+m.start(1), m.group(1)), ":[123][sp]", False):
         return True
@@ -151,6 +150,6 @@
 #### Exceptions
 
 aREGULARPLURAL = frozenset(["abricot", "amarante", "aubergine", "acajou", "anthracite", "brique", "caca", "café", \
                             "carotte", "cerise", "chataigne", "corail", "citron", "crème", "grave", "groseille", \
                             "jonquille", "marron", "olive", "pervenche", "prune", "sable"])
-aSHOULDBEVERB = frozenset(["aller", "manger"]) 
+aSHOULDBEVERB = frozenset(["aller", "manger"])

Index: gc_lang/fr/modules/gce_suggestions.py
==================================================================
--- gc_lang/fr/modules/gce_suggestions.py
+++ gc_lang/fr/modules/gce_suggestions.py
@@ -6,18 +6,19 @@
 
 
 ## Verbs
 
 def suggVerb (sFlex, sWho, funcSugg2=None):
+    "change <sFlex> conjugation according to <sWho>"
     aSugg = set()
-    for sStem in stem(sFlex):
+    for sStem in _oSpellChecker.getLemma(sFlex):
         tTags = conj._getTags(sStem)
         if tTags:
             # we get the tense
             aTense = set()
-            for sMorph in _dAnalyses.get(sFlex, []): # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-                for m in re.finditer(">"+sStem+" .*?(:(?:Y|I[pqsf]|S[pq]|K|P))", sMorph):
+            for sMorph in _oSpellChecker.getMorph(sFlex):
+                for m in re.finditer(">"+sStem+"/.*?(:(?:Y|I[pqsf]|S[pq]|K|P))", sMorph):
                     # stem must be used in regex to prevent confusion between different verbs (e.g. sauras has 2 stems: savoir and saurer)
                     if m:
                         if m.group(1) == ":Y":
                             aTense.add(":Ip")
                             aTense.add(":Iq")
@@ -38,43 +39,44 @@
     if aSugg:
         return "|".join(aSugg)
     return ""
 
 
-def suggVerbPpas (sFlex, sWhat=None):
+def suggVerbPpas (sFlex, sPattern=None):
+    "suggest past participles for <sFlex>"
     aSugg = set()
-    for sStem in stem(sFlex):
+    for sStem in _oSpellChecker.getLemma(sFlex):
         tTags = conj._getTags(sStem)
         if tTags:
-            if not sWhat:
+            if not sPattern:
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q2"))
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q3"))
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q4"))
                 aSugg.discard("")
-            elif sWhat == ":m:s":
+            elif sPattern == ":m:s":
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
-            elif sWhat == ":m:p":
+            elif sPattern == ":m:p":
                 if conj._hasConjWithTags(tTags, ":PQ", ":Q2"):
                     aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q2"))
                 else:
                     aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
-            elif sWhat == ":f:s":
+            elif sPattern == ":f:s":
                 if conj._hasConjWithTags(tTags, ":PQ", ":Q3"):
                     aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q3"))
                 else:
                     aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
-            elif sWhat == ":f:p":
+            elif sPattern == ":f:p":
                 if conj._hasConjWithTags(tTags, ":PQ", ":Q4"):
                     aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q4"))
                 else:
                     aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
-            elif sWhat == ":s":
+            elif sPattern == ":s":
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q3"))
                 aSugg.discard("")
-            elif sWhat == ":p":
+            elif sPattern == ":p":
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q2"))
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q4"))
                 aSugg.discard("")
             else:
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":PQ", ":Q1"))
@@ -82,22 +84,24 @@
         return "|".join(aSugg)
     return ""
 
 
 def suggVerbTense (sFlex, sTense, sWho):
+    "change <sFlex> to a verb according to <sTense> and <sWho>"
     aSugg = set()
-    for sStem in stem(sFlex):
+    for sStem in _oSpellChecker.getLemma(sFlex):
         if conj.hasConj(sStem, sTense, sWho):
             aSugg.add(conj.getConj(sStem, sTense, sWho))
     if aSugg:
         return "|".join(aSugg)
     return ""
 
 
 def suggVerbImpe (sFlex):
+    "change <sFlex> to a verb at imperative form"
     aSugg = set()
-    for sStem in stem(sFlex):
+    for sStem in _oSpellChecker.getLemma(sFlex):
         tTags = conj._getTags(sStem)
         if tTags:
             if conj._hasConjWithTags(tTags, ":E", ":2s"):
                 aSugg.add(conj._getConjWithTags(sStem, tTags, ":E", ":2s"))
             if conj._hasConjWithTags(tTags, ":E", ":1p"):
@@ -108,19 +112,21 @@
         return "|".join(aSugg)
     return ""
 
 
 def suggVerbInfi (sFlex):
-    return "|".join([ sStem  for sStem in stem(sFlex)  if conj.isVerb(sStem) ])
+    "returns infinitive forms of <sFlex>"
+    return "|".join([ sStem  for sStem in _oSpellChecker.getLemma(sFlex)  if conj.isVerb(sStem) ])
 
 
 _dQuiEst = { "je": ":1s", "j’": ":1s", "j’en": ":1s", "j’y": ":1s", \
              "tu": ":2s", "il": ":3s", "on": ":3s", "elle": ":3s", "nous": ":1p", "vous": ":2p", "ils": ":3p", "elles": ":3p" }
 _lIndicatif = [":Ip", ":Iq", ":Is", ":If"]
 _lSubjonctif = [":Sp", ":Sq"]
 
 def suggVerbMode (sFlex, cMode, sSuj):
+    "returns other conjugations of <sFlex> acconding to <cMode> and <sSuj>"
     if cMode == ":I":
         lMode = _lIndicatif
     elif cMode == ":S":
         lMode = _lSubjonctif
     elif cMode.startswith((":I", ":S")):
@@ -131,11 +137,11 @@
     if not sWho:
         if sSuj[0:1].islower(): # pas un pronom, ni un nom propre
             return ""
         sWho = ":3s"
     aSugg = set()
-    for sStem in stem(sFlex):
+    for sStem in _oSpellChecker.getLemma(sFlex):
         tTags = conj._getTags(sStem)
         if tTags:
             for sTense in lMode:
                 if conj._hasConjWithTags(tTags, sTense, sWho):
                     aSugg.add(conj._getConjWithTags(sStem, tTags, sTense, sWho))
@@ -147,13 +153,14 @@
 ## Nouns and adjectives
 
 def suggPlur (sFlex, sWordToAgree=None):
     "returns plural forms assuming sFlex is singular"
     if sWordToAgree:
-        if sWordToAgree not in _dAnalyses and not _storeMorphFromFSA(sWordToAgree):
+        lMorph = _oSpellChecker.getMorph(sFlex)
+        if not lMorph:
             return ""
-        sGender = cr.getGender(_dAnalyses.get(sWordToAgree, []))
+        sGender = cr.getGender(lMorph)
         if sGender == ":m":
             return suggMasPlur(sFlex)
         elif sGender == ":f":
             return suggFemPlur(sFlex)
     aSugg = set()
@@ -191,13 +198,12 @@
     return ""
 
 
 def suggMasSing (sFlex, bSuggSimil=False):
     "returns masculine singular forms"
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     aSugg = set()
-    for sMorph in _dAnalyses.get(sFlex, []):
+    for sMorph in _oSpellChecker.getMorph(sFlex):
         if not ":V" in sMorph:
             # not a verb
             if ":m" in sMorph or ":e" in sMorph:
                 aSugg.add(suggSing(sFlex))
             else:
@@ -219,13 +225,12 @@
     return ""
 
 
 def suggMasPlur (sFlex, bSuggSimil=False):
     "returns masculine plural forms"
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     aSugg = set()
-    for sMorph in _dAnalyses.get(sFlex, []):
+    for sMorph in _oSpellChecker.getMorph(sFlex):
         if not ":V" in sMorph:
             # not a verb
             if ":m" in sMorph or ":e" in sMorph:
                 aSugg.add(suggPlur(sFlex))
             else:
@@ -250,13 +255,12 @@
     return ""
 
 
 def suggFemSing (sFlex, bSuggSimil=False):
     "returns feminine singular forms"
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     aSugg = set()
-    for sMorph in _dAnalyses.get(sFlex, []):
+    for sMorph in _oSpellChecker.getMorph(sFlex):
         if not ":V" in sMorph:
             # not a verb
             if ":f" in sMorph or ":e" in sMorph:
                 aSugg.add(suggSing(sFlex))
             else:
@@ -276,13 +280,12 @@
     return ""
 
 
 def suggFemPlur (sFlex, bSuggSimil=False):
     "returns feminine plural forms"
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     aSugg = set()
-    for sMorph in _dAnalyses.get(sFlex, []):
+    for sMorph in _oSpellChecker.getMorph(sFlex):
         if not ":V" in sMorph:
             # not a verb
             if ":f" in sMorph or ":e" in sMorph:
                 aSugg.add(suggPlur(sFlex))
             else:
@@ -301,33 +304,35 @@
         return "|".join(aSugg)
     return ""
 
 
 def hasFemForm (sFlex):
-    for sStem in stem(sFlex):
+    "return True if there is a feminine form of <sFlex>"
+    for sStem in _oSpellChecker.getLemma(sFlex):
         if mfsp.isFemForm(sStem) or conj.hasConj(sStem, ":PQ", ":Q3"):
             return True
     if phonet.hasSimil(sFlex, ":f"):
         return True
     return False
 
 
 def hasMasForm (sFlex):
-    for sStem in stem(sFlex):
+    "return True if there is a masculine form of <sFlex>"
+    for sStem in _oSpellChecker.getLemma(sFlex):
         if mfsp.isFemForm(sStem) or conj.hasConj(sStem, ":PQ", ":Q1"):
             # what has a feminine form also has a masculine form
             return True
     if phonet.hasSimil(sFlex, ":m"):
         return True
     return False
 
 
 def switchGender (sFlex, bPlur=None):
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
+    "return feminine or masculine form(s) of <sFlex>"
     aSugg = set()
     if bPlur == None:
-        for sMorph in _dAnalyses.get(sFlex, []):
+        for sMorph in _oSpellChecker.getMorph(sFlex):
             if ":f" in sMorph:
                 if ":s" in sMorph:
                     aSugg.add(suggMasSing(sFlex))
                 elif ":p" in sMorph:
                     aSugg.add(suggMasPlur(sFlex))
@@ -338,17 +343,17 @@
                     aSugg.add(suggFemPlur(sFlex))
                 else:
                     aSugg.add(suggFemSing(sFlex))
                     aSugg.add(suggFemPlur(sFlex))
     elif bPlur:
-        for sMorph in _dAnalyses.get(sFlex, []):
+        for sMorph in _oSpellChecker.getMorph(sFlex):
             if ":f" in sMorph:
                 aSugg.add(suggMasPlur(sFlex))
             elif ":m" in sMorph:
                 aSugg.add(suggFemPlur(sFlex))
     else:
-        for sMorph in _dAnalyses.get(sFlex, []):
+        for sMorph in _oSpellChecker.getMorph(sFlex):
             if ":f" in sMorph:
                 aSugg.add(suggMasSing(sFlex))
             elif ":m" in sMorph:
                 aSugg.add(suggFemSing(sFlex))
     if aSugg:
@@ -355,13 +360,13 @@
         return "|".join(aSugg)
     return ""
 
 
 def switchPlural (sFlex):
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
+    "return plural or singular form(s) of <sFlex>"
     aSugg = set()
-    for sMorph in _dAnalyses.get(sFlex, []):
+    for sMorph in _oSpellChecker.getMorph(sFlex):
         if ":s" in sMorph:
             aSugg.add(suggPlur(sFlex))
         elif ":p" in sMorph:
             aSugg.add(suggSing(sFlex))
     if aSugg:
@@ -368,43 +373,45 @@
         return "|".join(aSugg)
     return ""
 
 
 def hasSimil (sWord, sPattern=None):
+    "return True if there is words phonetically similar to <sWord> (according to <sPattern> if required)"
     return phonet.hasSimil(sWord, sPattern)
 
 
 def suggSimil (sWord, sPattern=None, bSubst=False):
     "return list of words phonetically similar to sWord and whom POS is matching sPattern"
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
     aSugg = phonet.selectSimil(sWord, sPattern)
-    for sMorph in _dAnalyses.get(sWord, []):
+    for sMorph in _oSpellChecker.getMorph(sWord):
         aSugg.update(conj.getSimil(sWord, sMorph, bSubst))
         break
     if aSugg:
         return "|".join(aSugg)
     return ""
 
 
 def suggCeOrCet (sWord):
+    "suggest “ce” or “cet” or both according to the first letter of <sWord>"
     if re.match("(?i)[aeéèêiouyâîï]", sWord):
         return "cet"
     if sWord[0:1] == "h" or sWord[0:1] == "H":
         return "ce|cet"
     return "ce"
 
 
 def suggLesLa (sWord):
-    # we don’t check if word exists in _dAnalyses, for it is assumed it has been done before
-    if any( ":p" in sMorph  for sMorph in _dAnalyses.get(sWord, []) ):
+    "suggest “les” or “la” according to <sWord>"
+    if any( ":p" in sMorph  for sMorph in _oSpellChecker.getMorph(sWord) ):
         return "les|la"
     return "la"
 
 
 _zBinary = re.compile("^[01]+$")
 
 def formatNumber (s):
+    "add spaces or hyphens to big numbers"
     nLen = len(s)
     if nLen < 4:
         return s
     sRes = ""
     # nombre ordinaire
@@ -435,10 +442,11 @@
         sRes += "|" + s[0:2] + " " + s[2:5] + " " + s[5:7] + " " + s[7:9]                   # fixe belge 2
     return sRes
 
 
 def formatNF (s):
+    "typography: format NF reference (norme française)"
     try:
         m = re.match("NF[  -]?(C|E|P|Q|S|X|Z|EN(?:[  -]ISO|))[  -]?([0-9]+(?:[/‑-][0-9]+|))", s)
         if not m:
             return ""
         return "NF " + m.group(1).upper().replace(" ", " ").replace("-", " ") + " " + m.group(2).replace("/", "‑").replace("-", "‑")
@@ -446,10 +454,11 @@
         traceback.print_exc()
         return "# erreur #"
 
 
 def undoLigature (c):
+    "typography: split ligature character <c> in several chars"
     if c == "fi":
         return "fi"
     elif c == "fl":
         return "fl"
     elif c == "ff":
@@ -470,10 +479,11 @@
 _xNormalizedCharsForInclusiveWriting = str.maketrans({
     '(': '_',  ')': '_',
     '.': '_',  '·': '_',
     '–': '_',  '—': '_',
     '/': '_'
- })
+})
 
 
 def normalizeInclusiveWriting (sToken):
+    "typography: replace word separators used in inclusive writing by underscore (_)"
     return sToken.translate(_xNormalizedCharsForInclusiveWriting)

Index: gc_lang/fr/modules/lexicographe.py
==================================================================
--- gc_lang/fr/modules/lexicographe.py
+++ gc_lang/fr/modules/lexicographe.py
@@ -1,14 +1,17 @@
-# Grammalecte - Lexicographe
+"""
+Grammalecte - Lexicographe
+"""
+
 # License: MPL 2
 
 
 import re
 import traceback
 
 
-_dTAGS = {  
+_dTAGS = {
     ':N': (" nom,", "Nom"),
     ':A': (" adjectif,", "Adjectif"),
     ':M1': (" prénom,", "Prénom"),
     ':M2': (" patronyme,", "Patronyme, matronyme, nom de famille…"),
     ':MP': (" nom propre,", "Nom propre"),
@@ -78,11 +81,11 @@
     ':C': (" conjonction,", "Conjonction"),
     ':Ĉ': (" conjonction (él.),", "Conjonction (élément)"),
     ':Cc': (" conjonction de coordination,", "Conjonction de coordination"),
     ':Cs': (" conjonction de subordination,", "Conjonction de subordination"),
     ':Ĉs': (" conjonction de subordination (él.),", "Conjonction de subordination (élément)"),
-    
+
     ':Ñ': (" locution nominale (él.),", "Locution nominale (élément)"),
     ':Â': (" locution adjectivale (él.),", "Locution adjectivale (élément)"),
     ':Ṽ': (" locution verbale (él.),", "Locution verbale (élément)"),
     ':Ŵ': (" locution adverbiale (él.),", "Locution adverbiale (élément)"),
     ':Ŕ': (" locution prépositive (él.),", "Locution prépositive (élément)"),
@@ -125,18 +128,18 @@
     'elle': " pronom personnel sujet, 3ᵉ pers. fém. sing.",
     'nous': " pronom personnel sujet/objet, 1ʳᵉ pers. plur.",
     'vous': " pronom personnel sujet/objet, 2ᵉ pers. plur.",
     'ils': " pronom personnel sujet, 3ᵉ pers. masc. plur.",
     'elles': " pronom personnel sujet, 3ᵉ pers. masc. plur.",
-    
+
     "là": " particule démonstrative",
     "ci": " particule démonstrative",
-    
+
     'le': " COD, masc. sing.",
     'la': " COD, fém. sing.",
     'les': " COD, plur.",
-        
+
     'moi': " COI (à moi), sing.",
     'toi': " COI (à toi), sing.",
     'lui': " COI (à lui ou à elle), sing.",
     'nous2': " COI (à nous), plur.",
     'vous2': " COI (à vous), plur.",
@@ -153,18 +156,20 @@
     "s'en": " (se) pronom personnel objet + (en) pronom adverbial",
 }
 
 
 class Lexicographe:
+    "Lexicographer - word analyzer"
 
     def __init__ (self, oSpellChecker):
         self.oSpellChecker = oSpellChecker
         self._zElidedPrefix = re.compile("(?i)^([dljmtsncç]|quoiqu|lorsqu|jusqu|puisqu|qu)['’](.+)")
         self._zCompoundWord = re.compile("(?i)(\\w+)-((?:les?|la)-(?:moi|toi|lui|[nv]ous|leur)|t-(?:il|elle|on)|y|en|[mts][’'](?:y|en)|les?|l[aà]|[mt]oi|leur|lui|je|tu|ils?|elles?|on|[nv]ous)$")
         self._zTag = re.compile("[:;/][\\w*][^:;/]*")
 
     def analyzeWord (self, sWord):
+        "returns a tuple (a list of morphologies, a set of verb at infinitive form)"
         try:
             if not sWord:
                 return (None, None)
             if sWord.count("-") > 4:
                 return (["élément complexe indéterminé"], None)
@@ -192,17 +197,18 @@
                 aMorph.append( "{} :  inconnu du dictionnaire".format(sWord) )
             # suffixe d’un mot composé
             if m2:
                 aMorph.append( "-{} : {}".format(m2.group(2), self._formatSuffix(m2.group(2).lower())) )
             # Verbes
-            aVerb = set([ s[1:s.find(" ")]  for s in lMorph  if ":V" in s ])
+            aVerb = set([ s[1:s.find("/")]  for s in lMorph  if ":V" in s ])
             return (aMorph, aVerb)
         except:
             traceback.print_exc()
             return (["#erreur"], None)
 
     def formatTags (self, sTags):
+        "returns string: readable tags"
         sRes = ""
         sTags = re.sub("(?<=V[1-3])[itpqnmr_eaxz]+", "", sTags)
         sTags = re.sub("(?<=V0[ea])[itpqnmr_eaxz]+", "", sTags)
         for m in self._zTag.finditer(sTags):
             sRes += _dTAGS.get(m.group(0), " [{}]".format(m.group(0)))[0]

Index: gc_lang/fr/modules/mfsp.py
==================================================================
--- gc_lang/fr/modules/mfsp.py
+++ gc_lang/fr/modules/mfsp.py
@@ -1,6 +1,8 @@
-# Masculins, féminins, singuliers et pluriels
+"""
+Masculins, féminins, singuliers et pluriels
+"""
 
 from .mfsp_data import lTagMiscPlur as _lTagMiscPlur
 from .mfsp_data import lTagMasForm as _lTagMasForm
 from .mfsp_data import dMiscPlur as _dMiscPlur
 from .mfsp_data import dMasForm as _dMasForm

Index: gc_lang/fr/modules/phonet.py
==================================================================
--- gc_lang/fr/modules/phonet.py
+++ gc_lang/fr/modules/phonet.py
@@ -1,6 +1,9 @@
-# Grammalecte - Suggestion phonétique
+"""
+Grammalecte - Suggestion phonétique
+"""
+
 # License: GPL 3
 
 import re
 
 from .phonet_data import dWord as _dWord

Index: gc_lang/fr/modules/tests.py
==================================================================
--- gc_lang/fr/modules/tests.py
+++ gc_lang/fr/modules/tests.py
@@ -1,7 +1,10 @@
 #! python3
-# coding: UTF-8
+
+"""
+Grammar checker tests for French language
+"""
 
 import unittest
 import os
 import re
 import time
@@ -145,18 +148,24 @@
                     sErrorText = sLine.strip()
                     sExceptedSuggs = ""
                 sExpectedErrors = self._getExpectedErrors(sErrorText)
                 sTextToCheck = sErrorText.replace("}}", "").replace("{{", "")
                 sFoundErrors, sListErr, sFoundSuggs = self._getFoundErrors(sTextToCheck, sOption)
-                self.assertEqual(sExpectedErrors, sFoundErrors, \
-                                 "\n# Line num: " + sLineNum + \
-                                 "\n> to check: " + _fuckBackslashUTF8(sTextToCheck) + \
-                                 "\n  expected: " + sExpectedErrors + \
-                                 "\n  found:    " + sFoundErrors + \
-                                 "\n  errors:   \n" + sListErr)
+                # tests
+                if sExpectedErrors != sFoundErrors:
+                    print("\n# Line num: " + sLineNum + \
+                          "\n> to check: " + _fuckBackslashUTF8(sTextToCheck) + \
+                          "\n  expected: " + sExpectedErrors + \
+                          "\n  found:    " + sFoundErrors + \
+                          "\n  errors:   \n" + sListErr)
                 if sExceptedSuggs:
-                    self.assertEqual(sExceptedSuggs, sFoundSuggs, "\n# Line num: " + sLineNum + "\n> to check: " + _fuckBackslashUTF8(sTextToCheck) + "\n  errors:   \n" + sListErr)
+                    if sExceptedSuggs != sFoundSuggs:
+                        print("\n# Line num: " + sLineNum + \
+                              "\n> to check: " + _fuckBackslashUTF8(sTextToCheck) + \
+                              "\n  expected: " + sExceptedSuggs + \
+                              "\n  found:    " + sFoundSuggs + \
+                              "\n  errors:   \n" + sListErr)
         # untested rules
         i = 0
         for sOpt, sLineId, sRuleId in gce.listRules():
             if sLineId not in self._aRuleTested and not re.search("^[0-9]+[sp]$|^[pd]_", sRuleId):
                 echo(sRuleId, end= ", ")

Index: gc_lang/fr/modules/textformatter.py
==================================================================
--- gc_lang/fr/modules/textformatter.py
+++ gc_lang/fr/modules/textformatter.py
@@ -1,6 +1,10 @@
 #!python3
+
+"""
+Text formatter
+"""
 
 import re
 
 
 dReplTable = {
@@ -65,11 +69,11 @@
     "ts_apostrophe":          [ ("(?i)\\b([ldnjmtscç])['´‘′`](?=\\w)", "\\1’"),
                                 ("(?i)(qu|jusqu|lorsqu|puisqu|quoiqu|quelqu|presqu|entr|aujourd|prud)['´‘′`]", "\\1’") ],
     "ts_ellipsis":            [ ("\\.\\.\\.", "…"),
                                 ("(?<=…)[.][.]", "…"),
                                 ("…[.](?![.])", "…") ],
-    "ts_n_dash_middle":       [ (" [-—] ", " – "), 
+    "ts_n_dash_middle":       [ (" [-—] ", " – "),
                                 (" [-—],", " –,") ],
     "ts_m_dash_middle":       [ (" [-–] ", " — "),
                                 (" [-–],", " —,") ],
     "ts_n_dash_start":        [ ("^[-—][  ]", "– "),
                                 ("^– ", "– "),

Index: gc_lang/fr/rules.grx
==================================================================
--- gc_lang/fr/rules.grx
+++ gc_lang/fr/rules.grx
@@ -47,11 +47,11 @@
 # http://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Fautes_d%27orthographe/Courantes
 
 
 !!
 !!
-!! Options                                                                                          
+!! Options                                                                                        !!
 !!
 !!
 
 OPTGROUP/basic: typo apos, esp tab, nbsp unit, tu maj, num virg, nf chim, ocr mapos, liga
 OPTGROUP/gramm: conf sgpl gn
@@ -96,11 +96,11 @@
 OPT/idrule:         False       False       False       False       False       False
 OPT/html:           False       False       False       True        True        True
 OPT/latex:          False       False       False       False       False       False
 
 # Priority: from 0 to 9. Default priority is 4.
-OPTPRIORITY/tu:     6
+OPTPRIORITY/tu:     7
 OPTPRIORITY/conf:   5
 OPTPRIORITY/ocr:    3
 
 OPTDEFAULTUILANG: fr_FR
 
@@ -198,14 +198,15 @@
 
 
 
 !!
 !!
-!! Définitions pour les regex                                                                       
+!! Définitions pour les regex                                                                     !!
 !!
 !!
 
+# REGEX
 DEF: avoir          [aeo]\w*
 DEF: etre           [êeésf]\w+
 DEF: avoir_etre     [aeêésfo]\w*
 DEF: aller          (?:ai?ll|v[ao]|ir[aio])\w*
 DEF: ppas           \w[\w-]+[éiust]e?s?
@@ -217,60 +218,63 @@
 DEF: w1             \w+
 DEF: w2             \w\w+
 DEF: w3             \w\w\w+
 DEF: w4             \w\w\w\w+
 
-
-
-
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!! PASSE 0: PARAGRAPHE PAR PARAGRAPHE                                                               
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-
-
-
-!!
-!!
-!!! Espaces & tabulations                                                                           
+# GRAPH
+DEF: mois           [>janvier|>février|>mars|>avril|>mai|>juin|>juillet|>août|>aout|>septembre|>octobre|>novembre|>décembre|>vendémiaire|>brumaire|>frimaire|>nivôse|>pluviôse|>ventôse|>germinal|>floréal|>prairial|>messidor|>thermidor|>fructidor]
+DEF: mi_mois        [>mi-janvier|>mi-février|>mi-mars|>mi-avril|>mi-mai|>mi-juin|>mi-juillet|>mi-août|>mi-aout|>mi-septembre|>mi-octobre|>mi-novembre|>mi-décembre|mi-vendémiaire|mi-brumaire|mi-frimaire|mi-nivôse|mi-pluviôse|mi-ventôse|mi-germinal|mi-floréal|mi-prairial|mi-messidor|mi-thermidor|mi-fructidor]
+DEF: pronom_obj     [moi|toi|soi|lui|elle|nous|vous|eux|elles|moi-même|toi-même|soi-même|lui-même|elle-même|nous-mêmes|vous-même|vous-mêmes|eux-mêmes|elles-mêmes]
+
+
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!! PASSE 0: PARAGRAPHE PAR PARAGRAPHE                                                             !!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+
+
+
+!!
+!!
+!!! Espaces & tabulations                                                                         !!
 !!
 !!
 
 # Espaces surnuméraires
 # Note : les tabulations ne sont pas soulignées dans LibreOffice. Mais l’erreur est bien présente.
@@ -375,11 +379,11 @@
 #
 
 
 !!!
 !!!
-!!! Processeur: efface les ponctuations gênantes (URL, sigles, abréviations, IP, heures, etc.)      
+!!! Processeur: efface les ponctuations gênantes (URL, sigles, abréviations, IP, heures, etc.)    !!
 !!!
 !!!
 
 # e-mail
 __<i>(p_email)__
@@ -390,11 +394,10 @@
     https?://[\w./?&!%=+*"'@$#-]+ <<- ~>> *
 __<i](p_URL2)__
     ((?:{w_1}[.])*)({w_2})([.](?:com|net|org|info|fr|ca|be|ch|i[ot]|co[.]uk|tk|es|jp|zh|ru|us|nl|xyz)) @@0,**,$
     <<- ~1>> *
     <<- ~2>> =\2.capitalize()
-    <<- =>> define(\2, [":MP:e:i"])
     <<- ~3>> *
 
 # Numéro de chapitre
 __<i>(p_chapitre)__
     ^\d+[.][\d.-]* <<- ~>> *
@@ -482,11 +485,11 @@
     \[…\] <<- ~>> *
 __[s](p_mot_entre_crochets)__
     \[({w_1})\] @@1
     <<- \1.isdigit() ~>> *
     <<- __else__ and morph(\1, ":G", False) ~>> =" " + \1 + " "
-    <<- __else__ and \1.isalpha() ~>> _
+    <<- __else__ and \1.isalpha() ~>> " _"
 __[s](points_suspension_entre_parenthèses)__
     \(…\)
     <<- ->> […]                 # Pour indiquer une troncature de texte, on utilise usuellement des crochets.
     <<- ~>> *
 
@@ -524,11 +527,11 @@
 
 
 
 !!!
 !!!
-!!! Processeur: balises HTML et LaTeX                                                               
+!!! Processeur: balises HTML et LaTeX                                                             !!
 !!!
 !!!
 
 # HTML
 __<i>/html(p_html_amp_xxx)__            &amp;[a-zA-Z]+; <<- ~>> _
@@ -552,11 +555,11 @@
 
 
 
 !!
 !!
-!!!! Écritures épicènes dystypographiques                                                           
+!!!! Écritures épicènes dystypographiques                                                         !!
 !!
 !!
 
 # (attention aux modifs: brainfuck d’intensité non négligeable)
 # La désambiguïsation est faite lors de la deuxième passe
@@ -651,11 +654,11 @@
 TEST: il faut en parler à l’{{auteur(e)}} et à son agent.
 
 
 !!
 !!
-!!!! Majuscules manquantes                                                                          
+!!!! Majuscules manquantes                                                                        !!
 !!
 !!
 
 # Majuscules après un point
 __[s]/maj(majuscule_après_point)__
@@ -674,11 +677,11 @@
 TEST: {{je}} suis disponible quand tu veux. Mais pas aujourd’hui.
 
 
 !!
 !!
-!!!! Virgules                                                                                       
+!!!! Virgules                                                                                     !!
 !!
 !!
 
 # virgules manquantes
 __[i>/virg(virgule_manquante_avant_etc)__   {w_1}( etc[.])  @@$ <<- -1>> , etc.                     # Avant « etc. », il faut mettre une virgule.
@@ -686,16 +689,16 @@
     ({w_1})( car)(?= (?:j[e’]|tu|ils?|nous|vous|elles?|on|les?|l[a’]|ces?|des?|cette|[mts](?:on|a|es))\b)  @@0,$
     <<- not morph(\1, ":[DR]", False) -2>> , car
     # Si « car » est la conjonction de coordination, une virgule est peut-être souhaitable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=3447
 __[i>/virg(virgule_manquante_avant_mais)__
     ({w_1})( mais)(?= (?:j[e’]|tu|ils?|nous|vous|elles?|on)\b)  @@0,$
-    <<- not morph(\1, ">(?:[mtscl]es|[nv]os|quels) ", False) -2>> , mais
+    <<- not morph(\1, ">(?:[mtscl]es|[nv]os|quels)/", False) -2>> , mais
     # Si « mais » est la conjonction de coordination, une virgule est souhaitable si elle introduit une nouvelle proposition.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=3445
 __[i>/virg(virgule_manquante_avant_donc)__
     ({w_1})( donc)(?= (?:j[e’]|tu|ils?|elles?|on)\b)  @@0,$
     <<- not morph(\1, ":V", False) -2>> , donc
-    # Si « mais » est la conjonction de coordination, une virgule est souhaitable si elle introduit une nouvelle proposition.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=3448
+    # Si « donc » est la conjonction de coordination, une virgule est souhaitable si elle introduit une nouvelle proposition.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=3448
 
 TEST: Un chien, un chat{{ etc.}}                                            ->> , etc.
 TEST: Je suis fatigué{{ car}} ils ont joué toute la nuit.                   ->> , car
 TEST: Je suis fatigué{{ mais}} il a joué toute la nuit.                     ->> , mais
 TEST: il l’a vu de ses propres yeux{{ donc}} il faut y croire.              ->> , donc
@@ -732,11 +735,11 @@
 #    -1>> \1.|\1…|\1 !|\1 ?|\1 :|\1 ;|\1,                                               # Il manque une ponctuation finale.
 
 
 !!
 !!
-!!!! Espaces manquants                                                                              
+!!!! Espaces manquants                                                                            !!
 !!
 !!
 
 __<s>/typo(typo_espace_manquant_après1)__
     ({w1})[,:]({w_1})  @@0,$  <<- not \1.isdigit() -2>> " \2"                                       # Il manque un espace.
@@ -761,11 +764,11 @@
 TEST: pic.twitter.com/PICNAME
 
 
 !!
 !!
-!!!! Points                                                                                         
+!!!! Points                                                                                       !!
 !!
 !!
 
 # Points superflus
 __[i>/typo(typo_et_cetera)__             etc(?:[.]{3,5}|…) <<- ->> etc.                             # Un seul point après « etc. »
@@ -800,11 +803,11 @@
 
 
 
 !!
 !!
-!!!! Tirets                                                                                         
+!!!! Tirets                                                                                       !!
 !!
 !!
 
 # Tirets, énumérations et dialogues
 __<s>/typo(typo_tiret_début_ligne)__    ^[-_][  ] <<- ->> "— |– "           # Dialogues et énumérations : un tiret cadratin ou demi-cadratin, suivi d’un espace insécable, est requis.
@@ -823,16 +826,16 @@
 TEST: « {{- }}Viens ! On va en finir avec cette affaire, sale fils de pute. ->> "— |– "
 
 
 !!
 !!
-!!!! Ponctuations redondantes                                                                       
+!!!! Ponctuations redondantes                                                                     !!
 !!
 !!
 
 # virgules et points
-__<s>/typo(typo_virgules_points)__ 
+__<s>/typo(typo_virgules_points)__
     ,[.,]{2,}
     <<- ->> =\0.replace(",", ".").replace("...", "…")                                               # Erreur de numérisation ? Virgules au lieu de points ?
 
 TEST: Ah !{{,.,}} et en quoi consistait le festin ?
 
@@ -871,11 +874,11 @@
 TEST: {{» }}C’est ce qu’on croit savoir.                                    ->> "» |« "
 
 
 !!
 !!
-!!!! Signes typographiques                                                                          
+!!!! Signes typographiques                                                                        !!
 !!
 !!
 
 __<s>/typo(typo_signe_multiplication)__
     (\d+) ?[x*] ?(\d+)  @@0,$ <<- not \0.startswith("0x") ->> \1 × \2                               # Signe de multiplication typographique.
@@ -900,28 +903,28 @@
 TEST: __liga__ une belle {{fi}}gure                                        ->> fi
 
 
 !!
 !!
-!!!! Apostrophes                                                                                    
+!!!! Apostrophes                                                                                  !!
 !!
 !!
 ## Apostrophe typographique
 __[i>/apos(apostrophe_typographique)__
-    ([ldsncjmç]|jusqu|lorsqu|aujourd|presqu|quelqu|puisqu|qu|prud|entr)['´‘′`](?=[\w"«]) @@0 <<- ->> \1’    # Apostrophe typographique.
+    ([ldsncjmç]|jusqu|lorsqu|aujourd|presqu|quelqu|puisqu|qu|prud|entr)['´‘′`ʼ](?=[\w"«]) @@0 <<- ->> \1’    # Apostrophe typographique.
 __[i>/apos(apostrophe_typographique_après_t)__
-    t['´‘′`](?!ils?|elles?|on)(?=[\w"«]) <<- ->> t’                                                         # Apostrophe typographique.
+    t['´‘′`ʼ](?!ils?|elles?|on)(?=[\w"«]) <<- ->> t’                                                         # Apostrophe typographique.
 
 TEST: {{C'}}est l’apostrophe typographique qui manque.                    ->> C’
 TEST: C’est {{l'}}apostrophe typographique qui manque.                    ->> l’
 TEST: {{Aujourd'}}hui, je suis fatigué
 TEST: Je pense {{qu`}}elle se trompe
 TEST: Que {{t'}}arrive-t-il ?
 
 
 __[i>/typo(typo_apostrophe_incorrecte)__
-    (([ldsncjmtç]|lorsqu|puisqu|presqu|quoiqu|quelqu|jusqu|qu|aujourd|entr)(?:[’'´‘′`][’'´‘′` ]|”|“|"| [’'´‘′`] ?))[aeéiouhœæyîèêôû]  @@0,0
+    (([ldsncjmtç]|lorsqu|puisqu|presqu|quoiqu|quelqu|jusqu|qu|aujourd|entr)(?:[’'´‘′`ʼ][’'´‘′`ʼ ]|”|“|"| [’'´‘′`ʼ] ?))[aeéiouhœæyîèêôû]  @@0,0
     <<- not (\2.__len__() == 1  and  \1.endswith("′ ")) -1>> \2’                                    # Apostrophe incorrecte.
 
 TEST: {{C’ }}est rageant.                                                 ->> C’
 TEST: {{Lorsqu’ }}il vient, on s’ennuie.
 TEST: {{l’'}}électricien est parti
@@ -954,11 +957,11 @@
 TEST: Je {{n }}ai pas retrouvé l’ambiance de mes années de lycée.               ->> n’
 
 
 !!
 !!
-!!!! Guillemets typographiques                                                                      
+!!!! Guillemets typographiques                                                                    !!
 !!
 !!
 
 __<s>/typo(typo_guillemets_typographiques_doubles_ouvrants)__
     "(?=\w)
@@ -996,11 +999,11 @@
 TEST: J’en ai '''marre''' (syntaxe wiki).
 
 
 !!
 !!
-!!!! Élisions                                                                                       
+!!!! Élisions                                                                                     !!
 !!
 !!
 
 __[i]/typo(typo_élision_déterminants)__
     (l[ea] |de )([aâeéêiîoôu]\w+)  @@0,$
@@ -1048,11 +1051,11 @@
 TEST: {{ce}} animal est dangereux
 
 
 !!
 !!
-!!!! Divers                                                                                         
+!!!! Divers                                                                                       !!
 !!
 !!
 
 ## NF (memo: don’t use flag i)
 __[s]/nf(nf_norme_française)__
@@ -1071,11 +1074,11 @@
 TEST: __chim__ les molécules {{CaCO3}} et {{H2O}}…
 
 
 !!
 !!
-!!!! Cohérence des guillemets                                                                       
+!!!! Cohérence des guillemets                                                                     !!
 !!
 !!
 
 __<s>/typo(typo_cohérence_guillemets_chevrons_ouvrants)__
     («)[^»“]+?(”)  @@0,$
@@ -1129,11 +1132,11 @@
 TEST: « J’en suis “malade”. »
 
 
 !!
 !!
-!!!! Espaces insécables avant unités de mesure                                                      
+!!!! Espaces insécables avant unités de mesure                                                    !!
 !!
 !!
 
 __[s]/unit(unit_nbsp_avant_unités1)__
     ((\d+(?:,\d+[⁰¹²³⁴⁵⁶⁷⁸⁹]?|[⁰¹²³⁴⁵⁶⁷⁸⁹]|)) ?)(?:[kcmµn]?(?:[slgJKΩ]|m[²³]?|Wh?|Hz|dB)|[%‰€$£¥Åℓhj]|min|°C|℃)(?![’'])  @@0,0
@@ -1167,11 +1170,11 @@
 TEST: je veux 200 euros.
 
 
 !!
 !!
-!!!! Grands nombres                                                                                 
+!!!! Grands nombres                                                                               !!
 !!
 !!
 
 __[s]/num(num_grand_nombre_soudé)__
     \d\d\d\d+
@@ -1216,11 +1219,11 @@
 TEST: Il a perdu {{20 000}} euros à la Bourse en un seul mois.
 
 
 !!
 !!
-!!!! Dates                                                                                          
+!!!! Dates                                                                                        !!
 !!
 !!
 __[i]/date(date_nombres)__
     (?<!\d[ /.-])(\d\d?)[ /.-](\d\d?)[ /.-](\d\d\d+)(?![ /.-]\d)  @@0,w,$
     <<- not checkDate(\1, \2, \3) and not before(r"(?i)\bversions? +$") ->> _                       # Cette date est invalide.
@@ -1233,877 +1236,27 @@
 TEST: 12-12-2012
 
 
 !!
 !!
-!!!! Redondances                                                                                    
+!!!! Redondances                                                                                  !!
 !!
 !!
 __[i]/redon1(redondances_paragraphe)__
     ({w_4})[  ,.;!?:].*[  ](\1)  @@0,$
-    <<- not morph(\1, ":(?:G|V0)|>(?:t(?:antôt|emps|rès)|loin|souvent|parfois|quelquefois|côte|petit|même) ", False) and not \1[0].isupper()
+    <<- not morph(\1, ":(?:G|V0)|>(?:t(?:antôt|emps|rès)|loin|souvent|parfois|quelquefois|côte|petit|même)/", False) and not \1[0].isupper()
     -2>> _                                                      # Dans ce paragraphe, répétition de « \1 » (à gauche).
     <<- __also__ -1>> _                                         # Dans ce paragraphe, répétition de « \1 » (à droite).
 
 TEST: __redon1__ Tu es son {{avenir}}. Et lui aussi est ton {{avenir}}.
 TEST: __redon1__ Car parfois il y en a. Mais parfois il n’y en a pas.
 
 
 
-
-!!!
-!!!
-!!! Processeur: Dernier nettoyage avant coupure du paragraphe en phrases                            
-!!!
-!!!
-
-# Trait d’union conditionnel (u00AD)
-__<i>(p_trait_union_conditionnel1)__    \w+‑\w+‑\w+ <<- ~>> =\0.replace("‑", "")
-__<i>(p_trait_union_conditionnel2)__    \w+‑\w+ <<- ~>> =\0.replace("‑", "")
-
-# empêcher la scission en fin de dialogue
-__<s>(p_fin_dialogue1)__    ([?!…][?!…  ]*)[ "'”» ]*,  @@0 <<- ~1>> *
-__<s>(p_fin_dialogue2)__    ([?!…][?!…  ]*)[ "'”» ]*[a-zéèêîô]  @@0 <<- ~1>> ,
-
-TEST: « Je suis donc perdu ? », dit Paul.
-TEST: “C’est bon !”, croit savoir Marie.
-TEST: “Parce que… ?” finit par demander Paul.
-TEST: « Dans quel pays sommes-nous ? » demanda un manifestant. 
-
-
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!! PASSE 1: PHRASE PAR PHRASE                                                                       
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-!!
-
-[++]
-
-
-
-!!!! Doublons (casse identique)                                                                     
-
-__[s](doublon)__
-    ({w1}) {1,3}\1  @@0
-    <<- not re.search("(?i)^([nv]ous|faire|en|la|lui|donnant|œuvre|h[éoa]|hou|olé|joli|Bora|couvent|dément|sapiens|très|vroum|[0-9]+)$", \1)
-        and not (re.search("^(?:est|une?)$", \1) and before("[’']$"))
-        and not (\1 == "mieux" and before("(?i)qui +$"))
-    ->> \1   # Doublon.
-
-TEST: Il y a un {{doublon doublon}}.
-
-
-!!!! Nombres: typographie                                                                           
-
-#(\d\d\d\d)-(\d\d\d\d)   <<- ->> \1–\2                              # Ne pas séparer deux dates par un trait d’union, mais par un tiret demi-cadratin.
-
-__[s]/num(num_lettre_O_zéro1)__  [\dO]+[O][\dO]+ <<- not option("ocr") ->> =\0.replace("O", "0")    # S’il s’agit d’un nombre, utilisez le chiffre « 0 » plutôt que la lettre « O ».
-__[s]/num(num_lettre_O_zéro2)__  [1-9]O <<- not option("ocr") ->> =\0.replace("O", "0")             # S’il s’agit d’un nombre, utilisez le chiffre « 0 » plutôt que la lettre « O ».
-
-TEST: année {{2O11}}                                                      ->> 2011
-TEST: {{3O}} (chiffre avec un O).                                         ->> 30
-
-
-# Nombres ordinaux
-__[s]/typo(typo_ordinaux_premier)__
-    1 ?(?:ier|i?ère)s?
-    <<- ->> =\0.replace(" ", "").replace("è", "").replace("i", "").replace("e", "ᵉ").replace("r", "ʳ").replace("s", "ˢ")
-    # Nombre ordinal. Premier : 1ᵉʳ. Première : 1ʳᵉ. Premier : 1ᵉʳˢ. Première : 1ʳᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-__[s]/typo(typo_ordinaux_deuxième)__
-    2 ?nde?s?
-    <<- ->> =\0.replace(" ", "").replace("n", "").replace("d", "ᵈ").replace("e", "ᵉ").replace("s", "ˢ")
-    # Nombre ordinal. Second : 2ᵈ. Seconde : 2ᵈᵉ. Seconds : 2ᵈˢ. Secondes : 2ᵈᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-__[s]/typo(typo_ordinaux_nième)__
-    ([0-9]+) ?(?:è|i?[èe]me)s?  @@0
-    <<- \0.endswith("s") ->> \1ᵉˢ                                                                   # Nombre ordinal pluriel. Exemples : 2ᵉˢ, 3ᵉˢ, 4ᵉˢ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-    <<- __else__ ->> \1ᵉ                                                                            # Nombre ordinal singulier. Exemples : 2ᵉ, 3ᵉ, 4ᵉ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-__[s]/typo(typo_ordinaux_romain_premier)__
-    I ?(?:ier|i?ère)s?
-    <<- ->> =\0.replace(" ", "").replace("è", "").replace("i", "").replace("e", "ᵉ").replace("r", "ʳ").replace("s", "ˢ")
-    # Nombre ordinal romain. Premier : 1ᵉʳ. Première : Iʳᵉ. Premier : Iᵉʳˢ. Première : Iʳᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-__[s]/typo(typo_ordinaux_romain_deuxième)__
-    II ?nde?s?
-    <<- ->> =\0.replace(" ", "").replace("n", "").replace("d", "ᵈ").replace("e", "ᵉ").replace("s", "ˢ")
-    # Nombre ordinal romain. Second : IIᵈ. Seconde : IIᵈᵉ. Seconds : IIᵈˢ. Secondes : IIᵈᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-__[s]/typo(typo_ordinaux_romains_nième)__
-    ([IVXLCM]{1,3}) ?(?:è|i?[èe]me)s?  @@0
-    <<- not morph(\0, ":G", False) >>>
-    <<- \0.endswith("s") ->> \1ᵉˢ                                                                   # Nombre ordinal romain singulier. Exemples : IIᵉ, IIIᵉ, IVᵉ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-    <<- __else__ ->> \1ᵉ                                                                            # Nombre ordinal romain pluriel. Exemples : IIᵉˢ, IIIᵉˢ, IVᵉˢ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
-
-TEST: la {{1ière}} fois, c’est la plus dure     ->> 1ʳᵉ
-TEST: le {{1ier}} de chaque semaine             ->> 1ᵉʳ
-TEST: le {{2nd}} du mois                        ->> 2ᵈ
-TEST: les {{3ièmes}} années                     ->> 3ᵉˢ
-TEST: C’est la {{3ème}} fois…                   ->> 3ᵉ
-TEST: Non, la {{2è}} fois.                      ->> 2ᵉ
-TEST: François {{Iier}}                         ->> Iᵉʳ
-TEST: le {{IInd}} siècle                        ->> IIᵈ
-TEST: le {{VIième}} siècle                      ->> VIᵉ
-TEST: Le {{XXIème}} siècle.                     ->> XXIᵉ
-TEST: le {{XXè}} siècle.                        ->> XXᵉ
-
-
-
-!!!! Écritures épicènes invariables                                                                 
-
-__[i](d_typo_écriture_épicène_pluriel)__
-    ({w_1}[éuitsrn])_(?:[nt]|)e_s  @@0
-    <<- morphex(\1, ":[NAQ]", ":G") =>> define(\1, [":N:A:Q:e:p"])
-
-__[i](d_typo_écriture_épicène_singulier)__
-    ({w_2}[éuitsrn])_e  @@0
-    <<- morph(\1, ":[NAQ]", False) =>> define(\1, [":N:A:Q:e:s"])
-
-
-!!!! Dates                                                                                          
-
-__[i]/date(date_jour_mois_année)__
-    (\d\d?) (janvier|février|ma(?:rs|i)|a(?:vril|o[ûu]t)|jui(?:n|llet)|septembre|octobre|novembre|décembre) (\d\d\d+)  @@0,w,$ 
-    <<- not checkDateWithString(\1, \2, \3) ->> _                                                   # Cette date est invalide.
-
-TEST: {{29 février 2011}}
-
-
-__[i]/date(date_journée_jour_mois_année1)__
-    (lundi|m(?:ardi|ercredi)|jeudi|vendredi|samedi|dimanche),? (?:le |)(\d\d?)-(\d\d?)-(\d\d+)  @@0,w,w,$ 
-    <<- not after(r"^ +av(?:ant|) +J(?:C|ésus-Christ)") and not checkDay(\1, \2, \3, \4)
-    -1>> =getDay(\2, \3, \4)                                                                        # Le jour de la date suivante est incorrect.
-
-TEST: {{mercredi}}, le 10-06-2014                                         ->> mardi
-
-
-__[i]/date(date_journée_jour_mois_année2)__
-    (lundi|m(?:ardi|ercredi)|jeudi|vendredi|samedi|dimanche),? (?:le |)(\d\d?) (janvier|février|ma(?:rs|i)|a(?:vril|o[ûu]t)|jui(?:n|llet)|septembre|octobre|novembre|décembre) (\d\d+)  @@0,w,w,$ 
-    <<- not after(r"^ +av(?:ant|) +J(?:C|ésus-Christ)") and not checkDayWithString(\1, \2, \3, \4)
-    -1>> =getDayWithString(\2, \3, \4)                                                              # Le jour de la date suivante est incorrect.
-
-TEST: {{mercredi}}, le 10 juin 2014                                       ->> mardi
-TEST: {{lundi}}, 18 août 1912                                             ->> dimanche
-TEST: lundi, 18 août 1912 avant Jésus-Christ (date imaginaire)
-
-
-__[i]/date(date_mois_31)__ 31 (avril|juin|septembre|novembre)  @@3
-    <<- ->> 30 \1                                                                                   # Cette date est invalide. Il n’y a que 30 jours en \1. 
-
-TEST: le {{31 avril}}
-
-
-__[i]/date(date_février)__ 3[01] février
-    <<- ->> 28 février|29 février                                                                   # Cette date est invalide. Il n’y a que 28 ou 29 jours en février. 
-
-TEST: le {{30 février}}
-
-
-
-!!!
-!!!
-!!! Processeur: épuration des signes inutiles et quelques simplifications                           
-!!!
-!!!
-
-# fin de phrase
-__<s>(p_fin_de_phrase)__        [.?!:;…][ .?!… »”")]*$  <<- ~>> *
-
-# début de phrase
-__<s>(p_début_de_phrase)__      ^ *[-–—] <<- ~>> *
-
-# Guillemets et exposants
-__<s>(p_guillemets_exposants)__ [«»“”"„`¹²³⁴⁵⁶⁷⁸⁹⁰]+ <<- ~>> *
-
-# Chapitres et références
-__<s>(p_chapitre_référence)__   [[({][\dIVXLCDM]+, \d+[])}]   <js>[\[\(\{][\dIVXLCDM]+, \d+[\]\)\}]</js>   <<- ~>> *
-
-# simplification des mots grammaticaux élidés
-__[i>(p_qu_apostrophe)__        (lorsqu|puisqu|quoiqu|jusqu|qu)’ @@0 <<- ~>> \1
-
-# le, la ou les chose(s)
-__[i>(p_le_ou_les)__            l[ea] ou les {w_2}([(]s[)]) @@$ <<- ~1>> s
-__[i](p_le_ou_la)__             l(e ou la|a ou le) {w_2} @@1 <<- ~1>> ’
-
-# les références aux notes
-__[i](p_références_aux_notes)__ [a-zéèâàôîù][a-zéèâàôîù-]+(\d+) @@$ <<- not morph(\0, ":", False) ~1>> *
-
-# faux positifs avec adverbes de négation
-__[i](p_pas_mal)__              pas mal <<- not morph(word(-1), ":D", False) ~>> *
-__[i](p_pas_assez)__            pas assez ({w_2}) @@$ <<- morph(\1, ":A", False) and not morph(word(-1), ":D", False) ~>> *
-
-# faux positifs avec «à chez»
-__[i](p_de_chez_à_chez_pronom)__    de chez \w+ (?:à|jusqu à) chez (?:moi|toi|lui|elles?|eux|nous|vous) <<- ~>> * 
-__[i](p_de_chez)__                  (jusqu à|de) chez @@0 <<- ~1>> *
-
-# faux positifs
-__[i](p_en_tout_et_pour_tout)__ en tout et pour tout <<- ~>> *
-__[i](p_au_sortir_de)__         au (sortir) de?s?  @@3 <<- ~1>> *
-__[i](p_au_revoir)__            au revoir <<- ~>> au_revoir
-
-# singletons entre parenthèses / crochets / accolades
-__<s>(p_singleton_parenthèses)__    [(]\w+[)] <js>\([a-zA-Z]+\)</js> <<- ~>> *
-__<s>(p_singleton_accolades)__      [{]\w+[}] <js>\{[a-zA-Z]+\}</js> <<- ~>> *
-__<s>(p_singleton_crochets)__       [[]\w+[]] <js>\[[a-zA-Z]+\]</js> <<- ~>> *
-
-# Avocats
-__[s](p_Me_nom_propre)__        (Me) [A-ZÉÂÔÈ][\w-]+ @@0 <<- ~1>> *
-
-# Évènements
-__[s](p_Mai_68)__               Mai 68 <<- ~>> Mai-68
-
-# Rois, reines, papes et vaniteux du même acabit
-__[s](p_titres_et_ordinaux)__   [A-ZÉÂÔÈ]\w+ ([XVI]+|I(?:er|ᵉʳ)) @@$ <<- \1 != "I" ~1>> *
-
-# Marques
-__[i](p_Peugeot)__              Peugeot (\d0\d\d?) @@$ <<- ~1>> *
-
-# alors que / dès lors que (éviter d’accorder un participe passé avec un pseudo-COD antérieur)
-__[i](p_alors_dès_lors_que)__   (alors|dès lors) que?  @@0 <<- ~1>> _
-
-# Fusion des mots “multiples” (expérimental)
-__[s](p_fusion_mots_multiples)__
-    [A-Z][a-z]+ [A-Z][a-z]+
-    <<- spell(\0.replace(" ", "_")) ~>> =\0.replace(" ", "_")
-
-
-TEST: New York {{étaient}} {{devenue}} la plaque tournante de tous les trafics.
-
-
-!!
-!!
-!!!! Traits d’union                                                                                 
-!!
-!!
-
-__<i]/tu(tu_t_euphonique_incorrect)__
-    ([-–—− ]t(?:[’' ][-–—−]?|[-–—−][’' ]?))(ils?|elles?|on|tu)  @@0,$
-    <<- re.search("(?i)^(?:ils|elles|tu)$", \2) -1>> -      # Le “t” euphonique n’est pas nécessaire avec “\2”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=t+euphonique&id=2513
-    <<- __else__ and \1 != "-t-" and \1 != "-T-" -1>> -t-   # Pour le “t” euphonique, il faut deux traits d’union. Pas d’apostrophe. Pas d’espace.
-    <<- ~1>> -t-
-__<i]/tu(tu_t_euphonique_superflu)__
-    [td]([- ]t[-’' ])(?:il|elle|on)  @@1
-    <<- -1>> -                                              # Le “t” euphonique est superflu quand le verbe se termine par “t” ou “d”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=t+euphonique&id=2513
-    <<- ~1>> -t-
-__<i]/tu(tu_t_euphonique_manquant)__
-    [aec](-(il|elle|on))  @@1,2  <<- -1>> -t-\2             # Il faut un “t” euphonique.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=t+euphonique&id=2513
-
-TEST: va{{ t’}}il y parvenir ?                          ->> -t-
-TEST: A{{ t’}}elle soif ?                               ->> -t-
-TEST: A{{ t-}}elle faim ?                               ->> -t-
-TEST: a{{ t'}}elle                                      ->> -t-
-TEST: a{{-t'}}il                                        ->> -t-
-TEST: a{{-t }}il.                                       ->> -t-
-TEST: a{{ t’}}il.                                       ->> -t-
-TEST: a{{ t-}}on.                                       ->> -t-
-TEST: donne{{ t-}}ils                                   ->> -
-TEST: donne{{-t }}il                                    ->> -t-
-TEST: vient{{-t-}}il                                    ->> -
-TEST: viendras{{-t-}}tu                                 ->> -
-TEST: Viendront{{ t-}}ils                               ->> -
-TEST: viennent{{ t-}}ils                                ->> -
-TEST: mangent{{-t-}}elles                               ->> -
-TEST: Ont{{ t’}}ils                                     ->> -
-TEST: Ont{{-t’}}ils                                     ->> -
-TEST: l’ont{{ t’}}ils vu ?                              ->> -
-TEST: exploite{{−t−}}il les ressources numériques       ->> -t-
-TEST: vainc{{-il}} ses ennemis aisément                 ->> -t-il
-TEST: Assis, gronde{{-t -}}elle                         ->> -t-
-TEST: vient-il demain ?
-TEST: prend-elle l’avantage ?
-TEST: saura-t-on jamais la vérité ?
-TEST: arrive-t-elle ce matin ?
-TEST: y aura-t-il du poulet au dîner ?
-
-
-__[i]/tu(tu_va_t_en)__              va[ -]t[ -]en(?! guerre) <<- ->> va-t’en                        # Une apostrophe est nécessaire (s’en aller).
-__[i]/tu(tu_va_t_en_guerre)__       va[ -]t[’' -]en guerres? <<- ->> va-t-en-guerre                 # Va-t-en-guerre (invariable) : des traits d’union sont nécessaires.
-
-TEST: {{Va-t-en}}, c’en est assez.
-TEST: Un {{va-t’en guerre}}, on ne peut pas lui faire confiance.
-TEST: Les {{va-t-en guerre}} sont de sortie.
-
-
-### Traits d’union douteux
-__[i]/tu(tu_trait_union_douteux)__
-    ({w1})(?:--|—|–)({w1})  @@0,$
-    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":", False) ->> \1-\2                               # Trait d’union : un tiret simple suffit.
-
-TEST: Nous préparons une {{contre–attaque}}.
-
-
-### ce / cet / cette / ces + nom + là
-__[i]/tu(tu_ce_cette_ces_nom_là1)__
-    c(?:e[st]?|ette) (({w_2}) là)(?! où)  @@$,w <<- morph(\2, ":[NB]", False) -1>> \2-là            # Il manque probablement un trait d’union.
-__[i]/tu(tu_ce_cette_ces_nom_là2)__
-    c(?:e[st]?|ette) (({w_2}) la)  @@$,w <<- morph(\2, ":[NB]", False) and isEnd() -1>> \2-là       # Il manque probablement un trait d’union.
-
-TEST: Ces {{trois là}} sont incollables.
-TEST: Je connais bien cette {{sensation là}}.
-TEST: Laisse ce chiot là où il est !
-
-
-### Préfixes
-__[i]/tu(tu_préfixe_ex)__
-    ex ({w2}) @@$  <<- morph(\1, ":N") and not re.search("(?i)^(?:aequo|nihilo|cathedra|absurdo|abrupto)", \1)
-    ->> ex-\1                                                                                       # S’il s’agit d’un seul mot, il manque un trait d’union.
-
-TEST: Son {{ex ami}} est un vrai cauchemar.
-TEST: Ton ex donne du fil à retordre.
-
-
-__[i]/tu(tu_préfixe_in)__
-    (in) ({w_2})  @@0,$
-    <<- not before(r"(?i)\b(?:drive|plug|sit) +$") >>>
-    <<- re.search("^(?:dix-huit|douze|seize|folio|octavo|quarto|plano)$", \2)
-    ->> =\0.replace(" ", "-")                                                                       # Il manque un trait d’union.
-    <<- __else__ and morph(\2, ":N:m") -1>> un                                                      # Confusion possible : pour le déterminant désignant quelque chose, écrivez “un”.
-
-TEST: Cet {{in folio}} est incroyable.
-TEST: c’est {{in}} stage de réinsertion.
-TEST: Dans ce drive in douze hommes mangent.
-
-
-__[i]/tu(tu_préfixe_mi)__
-    mi ({w2}) @@$  <<- morph(\1, ":[NAQ]", False) ->> mi-\1                                         # S’il s’agit d’un seul mot, il manque un trait d’union.    
-
-TEST: J’ai été engagé pour un {{mi temps}}.
-
-
-__[i]/tu(tu_préfixe_quasi)__
-    (?:l(?:es?|a|eurs?)|ce(?:tte|t|s|)|des?|m(?:a|on|es)|[ts](?:es|a)) (quasi ({w1}))  @@$,$ 
-    <<- morphex(\2, ":N", ":[AGW]") -1>> quasi-\2                                                   # Il manque un trait d’union : « quasi » s’accroche au mot qui le suit s’il s’agit d’un nom.
-    <<- ~1>> \2
-
-TEST: leurs {{quasi indifférences}}
-
-
-__[i]/tu(tu_préfixe_semi)__
-    semi ({w2})  @@$ <<- morphex(\1, ":[NAQ]", ":G") ->> semi-\1                                   # S’il s’agit d’un seul mot, il manque un trait d’union.
-
-TEST: en {{semi liberté}}
-
-
-__[i]/tu(tu_préfixe_xxxo)__
-    (franco|américano|anglo|belgo|électro|ferro|hydro|labio|macro|magnéto|médico|micro|nano|néo|neuro|paléo|physico|politico|rétro|rhino|sino|socio|stéréo) ({w1})  @@0,$
-    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":", False)
-    ->> \1-\2                                                                                       # S’il s’agit d’un seul mot, il manque un trait d’union.
-
-TEST: des {{franco américains}}
-TEST: {{franco américaine}}                             ->> franco-américaine
-TEST: {{ferro électrique}}                              ->> ferro-électrique
-TEST: {{rétro ingénierie}}.                             ->> rétro-ingénierie
-
-
-__[i]/tu(tu_préfixe_pseudo)__
-    pseudo ({w_2}) @@$
-    <<- morph(\1, ":N") ->> pseudo-\1                                                               # Si vous voulez évoquer le simulacre de “\1”, mettez un trait d’union.
-    <<- __also__ ~>> \1
-__[i](p_pseudo_xxx)__
-    (pseudo-){w_2} @@0 <<- ~1>> *
-
-TEST: il n’avait contracté qu’un {{pseudo mariage}}.
-
-
-__[i]/tu(tu_préfixe_divers)__
-    (anti|auto|arrière|avant|demi|extra|intra|multi|non|post|sans|sous) ({w1})  @@0,$
-    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":", False) and morph(word(-1), ":D", False, not bool(re.search("(?i)^(?:s(?:ans|ous)|non)$", \1)))
-    ->> \1-\2                                                                                       # Il manque probablement un trait d’union.
-
-TEST: il a pris une balle dans l’{{arrière train}}.
-TEST: Ce {{sans gêne}} mérite une bonne leçon
-
-
-__[i]/tu(tu_mots_composés)__
-    (attrape|garde|porte|brise|cache|casse|chauffe|contre|coupe|cure|croque|entre|essuie|lance|lave|lève|marque|pare|passe|perce|pèse|porte|poste|pousse|presse|protège|ramasse|serre|taille|tire|tourne|traîne|vice|vide) ({w1})  @@0,$
-    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":N", False) and morph(word(-1), ":(?:D|V0e)", False, True)
-        and not (morph(\1, ":G", False) and morph(\2, ":[GYB]", False))
-    ->> \1-\2                                                                                       # Il manque probablement un trait d’union.
-
-TEST: ce sont des {{lève tard}}.
-
-
-### Tri 1
-__[i]/tu(tu_à_tout_va)__                    [àa] tout vas? <<- ->> à tout-va                        # Il manque un trait d’union.
-__[i]/tu(à_la_va_vite)__                    [àa] la vas? vite <<- ->> à la va-vite                  # Il manque un trait d’union.
-__[i]/tu(tu_aller_retour)__                 allers? retours? <<- ->> =\0.replace(" ", "-")          # Il manque un trait d’union.
-__[i]/tu(tu_arc_en_ciel)__                  arcs? en ciel <<- ->> =\0.replace(" ", "-")             # Il manque les traits d’union.
-__[i]/tu(tu_après_demain)__                 après demain <<- ->> après-demain                       # Il manque un trait d’union.
-__[i]/tu(tu_au_préposition)__               au (delà|dehors|desso?us|devant) @@$ <<- ->> au-\1      # Il manque un trait d’union.
-__[i]/tu(tu_avant_hier)__                   avant hier <<- ->> avant-hier                           # Il manque un trait d’union.
-__[i]/tu(tu_bouche_à_oreille_bouche)__      bouche à (?:bouche|oreilles?) <<- morph(word(-1), ":D", False) ->> =\0.replace(" ", "-") # Il manque les traits d’union.
-__[i]/tu(tu_c_est_à_dire)__                 c’est [àa] dire <<- ->> c’est-à-dire                    # Il manque les traits d’union.
-__[i]/tu(tu_chef_d_œuvre_lieu)__            chef (lieu|d’œuvre) @@$ <<- ->> chef-\1                 # Il manque un trait d’union.
-__[i]/tu(tu_celui_celle_là_ci)__
-    ce(?:lles?|lui|ux) (?:là|[cs]i)
-    <<- not (\0.endswith("si") and morph(word(1), ":[AW]", False))
-    ->> =\0.replace(" ", "-").replace("si", "ci")                                                   # Il manque un trait d’union.
-__[i]/tu(tu_centre_ville)__                 centres? villes? <<- ->> centre-ville|centres-villes    # Il manque un trait d’union.
-__[i]/tu(tu_ci_dessous_devant_contre)__     ci (desso?us|devant|contre) @@$ <<- ->> ci-\1           # Il manque un trait d’union.
-__[i]/tu(tu_de_ci_de_là)__                  de ci,? de là <<- ->> de-ci de-là|de-ci, de-là          # Il manque les traits d’union.
-__[i]/tu(tu_en_contre_bas_partie)__     en contre (bas|partie) @@$ <<- ->> en contre\1|en contre-\1 # Mettez un trait d’union ou soudez.
-__[i]/tu(tu_en_contrepoint)__           en (contre[- ]point) @@$ <<- -1>> contrepoint               # Soudez.
-__[i]/tu(tu_état_major)__               état major <<- ->> état-major                               # Il manque un trait d’union.
-__[i]/tu(tu_grand_chose)__              grand chose <<- ->> grand-chose                             # Il manque un trait d’union.
-__[i]/tu(tu_grand_père_mère)__          grands? (?:père|mère)s? <<- ->> =\0.replace(" ", "-")       # Il manque un trait d’union.
-__[i]/tu(tu_ici_bas)__                  ici bas <<- ->> ici-bas                                     # Il manque un trait d’union.
-__[i]/tu(tu_jusque_là)__                jusque là <<- ->> jusque-là                                 # Il manque un trait d’union.
-__[i]/tu(tu_là_adverbe)__       là (bas|haut|desso?us|dedans|devant|derrière) @@3 <<- ->> là-\1     # Il manque un trait d’union.
-__[i]/tu(tu_n_est_ce_pas)__             n’est(?: ce[ -]pas|-ce-pas) <<- ->> n’est-ce pas            # Un trait d’union.
-__[i]/tu(tu_nord_sud_ouest)__           (nord|sud) ouest @@0 <<- ->> \1-ouest                       # Il manque un trait d’union.
-__[i]/tu(tu_nord_sud_est)__             (nord|sud) est @@0 <<- isEnd() ->> \1-est                   # Il manque un trait d’union.
-__[i]/tu(tu_outre_mer)__                outre mer <<- ->> outre-mer                                 # Il manque un trait d’union.
-__[i]/tu(tu_ouï_dire)__                 ou[iï] dire <<- morph(word(-1), ":G") ->> ouï-dire          # Il manque un trait d’union.
-__[i]/tu(tu_par_préposition)__
-    par (desso?us|devant|delà|derrière|dehors|dedans|devers)  @@$ 
-    <<- ->> par-\1                                                                                  # Il manque un trait d’union.
-__[i]/tu(tu_par_ci_par_là)__            par ci,? par là <<- ->> par-ci par-là|par-ci, par-là        # Trait(s) d’union manquant(s).
-__[i]/tu(tu_prêt_à_porter)__
-    (prêts?) à porter  @@0 
-    <<- before(r"(?i)\b(?:les?|du|des|un|ces?|[mts]on) +") ->> \1-à-porter                          # Il manque les traits d’union.
-__[i]/tu(tu_plate_forme)__  plates? formes? <<- ->> plate-forme|plates-formes|plateforme|plateformes    # Il manque un trait d’union. Vous pouvez aussi souder les deux mots.
-__[i]/tu(tu_quelques_uns_unes)__       quelques (une?s) @@$ <<- ->> quelques-\1                     # Il manque un trait d’union.
-__[i]/tu(tu_plus_moins_values)__       (plus|moins) (values?)  @@0,$  <<- ->> \1-\2                 # Il manque un trait d’union.
-__[i]/tu(tu_rez_de_chaussée)__         rez de chaussées? <<- ->> rez-de-chaussée                    # Il manque un trait d’union.
-__[i]/tu(tu_science_fiction)__         science fiction <<- ->> science-fiction                      # Il manque un trait d’union.
-__[i]/tu(tu_stock_option)__            stock options? <<- ->> =\0.replace(" ", "-")                 # Il manque un trait d’union.
-__[i]/tu(tu_soi_disant)__              soi disant
-    <<- not ( morph(word(-1), ":R", False) and after("^ +qu[e’]") ) ->> soi-disant                  # Il manque un trait d’union.
-__[i]/tu(tu_sous_jacent)__             sous (jacente?s?) @@$ <<- ->> sous-\1                        # Il manque un trait d’union.
-# sur-mesures
-__[i]/tu(tu_vice_président_roi)__      vice (présidente?s?|rois?) @@$ <<- ->> vice-\1               # Il manque un trait d’union.
-__[i]/tu(tu_vis_à_vis)__               vis [àa] vis <<- ->> vis-à-vis                               # Il manque les traits d’union.
-__[i]/tu(tu_week_end)__                week (ends?) @@$ <<- ->> week-\1                             # Il manque un trait d’union.
-
-TEST: Ils font des tests {{à tout va}}
-TEST: on a fait {{à la va vite}}…
-TEST: marre de faire des {{allers retours}}
-TEST: {{le}} {{bouche à oreille}}
-TEST: à ce {{moment là}}                                                        ->> moment-là
-TEST: une {{plus value}}                                                        ->> plus-value
-TEST: Il est {{en-dessous}} de tout.                                            ->> en dessous
-TEST: Ils sont {{en-deçà}} de tout                                              ->> en deçà
-TEST: {{Là bas}}.                                                               ->> Là-bas 
-TEST: {{Au dessus}}                                                             ->> Au-dessus
-TEST: {{ci dessus}}                                                             ->> ci-dessus
-TEST: {{par dessus}}                                                            ->> par-dessus
-TEST: {{au delà}}                                                               ->> au-delà
-TEST: {{ci devant}}.                                                            ->> ci-devant
-TEST: Il faisait froid cet {{hiver la}}.                                        ->> hiver-là
-TEST: {{Ceux la}} vont à la pêche.                                              ->> Ceux-là
-TEST: {{en contre bas}}
-TEST: mes deux {{grands pères}} sont décédés
-TEST: elles vont viennent {{de ci, de là}}.
-TEST: mais {{celles là}} sont différentes.
-TEST: seulement par {{ouï dire}}.
-TEST: ne vois-tu pas que c’est un {{chef d’œuvre}} ?
-TEST: Mieux qu’{{avant hier}}.
-TEST: nous irons là-bas {{après demain}}.
-TEST: L’{{état major}} n’a pas encore tranché la question.
-TEST: {{ici bas}}, n’attends rien de bon, à moins que…
-TEST: un bel enfoiré, {{c’est à dire}} un hypocrite
-TEST: {{jusque là}}, tout va bien
-TEST: regarde l’{{arc en ciel}}
-TEST: ils sont allés au {{centre ville}}.
-TEST: Il ne connaît pas {{grand chose}} à tout ça.
-TEST: en {{contre point}},
-TEST: {{Quelques unes}} sont très habiles.
-TEST: Tout ce que nous faisons {{par ci, par là}}.
-TEST: La papesse du {{prêt à porter}} viendra demain.
-TEST: sur cette {{plate forme}}, rien ne fonctionne
-TEST: Un énorme {{plus value}}.
-TEST: Habiter au {{rez de chaussée}}, quelle horreur.
-TEST: {{Apporte moi}} ce dictionnaire.                  ->> Apporte-moi
-TEST: C’est de la {{science fiction}}.
-TEST: Tout ce {{soi disant}} esprit religieux
-TEST: {{sous jacent}}                                   ->> sous-jacent
-TEST: Il a été nommé {{vice président}}
-TEST: Que vas-tu faire {{vis à vis}} d’eux              ->> vis-à-vis
-TEST: un super {{week end}}                             ->> week-end
-TEST: ils sont partis {{outre mer}}
-TEST: elles sont allées au {{sud ouest}}
-TEST: {{nord est}}
-TEST: des {{stock options}}
-TEST: Un autre chantier important, celui si sensible de la préservation des données personnelles des élèves
-
-
-# est-ce … ?
-__[i]/tu(tu_est_ce)__
-    (?<![cCdDlL][’'])(est ce) ({w_2})  @@0,$
-    <<- morphex(\2, ":", ":N.*:[me]:[si]|>qui ") and morph(word(-1), ":Cs", False, True)
-    -1>> est-ce                                                                                     # S’il s’agit d’une interrogation, il manque un trait d’union.
-
-TEST: {{est ce}} que c’est grave ?                                              ->> est-ce
-TEST: qu’{{est ce}} que c’est ?                                                 ->> est-ce
-TEST: elles reviendront, {{n’est ce pas}} ?
-TEST: nous en sommes à l’étape où nous voulons définir ce qu’est ce projet
-
-
-### Tri 2
-__[i]/tu(tu_beaux_arts)__       (?:[ld]es|aux) (beaux arts) @@$ <<- -1>> beaux-arts                 # Il manque un trait d’union.
-__[i]/tu(tu_basket_volley)__    (basket|volley) ball @@0 <<- ->> \1-ball                            # Il manque un trait d’union.
-__[i]/tu(tu_pronom_même)__      (lui|elle|[mts]oi|vous) même @@0 <<- not after("^ +s(?:i |’)") ->> \1-même  # Il manque un trait d’union si “même” se rapporte à “\1”.|https://fr.wiktionary.org/wiki/moi-m%C3%AAme
-__[i]/tu(tu_pronom_mêmes)__     (nous|vous|eux|elles) mêmes @@0 <<- ->> \1-mêmes                                        # Il manque un trait d’union.
-__[i]/tu(tu_va_et_vient)__      (?:[lcd]es?|un|[mts]on|leurs?|[nv]os|quels?) (vas? et vien[ts]) @@$ <<- -1>> va-et-vient  # Il manque les traits d’union.
-
-TEST: les {{beaux arts}}
-TEST: je déteste le {{basket ball}}
-TEST: {{Lui même}}                                    ->> Lui-même
-TEST: {{eux mêmes}}.                                  ->> eux-mêmes
-TEST: un {{va et vient}} incessant me casse la tête
-
-
-### Noms propres
-__[u]/tu(tu_Royaume_Uni)__      Royaume Uni <<- ->> Royaume-Uni             # Il manque un trait d’union (s’il s’agit de l’État englobant la Grande-Bretagne et l’Irlande du Nord).
-__[u]/tu(tu_Grande_Bretagne)__  Grande Bretagne <<- ->> Grande-Bretagne     # Il manque un trait d’union (s’il s’agit de l’État englobant l’Angleterre, l’Écosse et le pays de Galles).
-__[u]/tu(tu_Pays_Bas)__                 (?:[ld]es|aux) (Pays Bas) @@$ <<- -1>> Pays-Bas                         # Il manque un trait d’union.
-__[u]/tu(tu_Aix_en_Provence)__          Aix en Provence <<- ->> Aix-en-Provence                                 # Il manque un trait d’union.
-__[u]/tu(tu_Bosnie_Herzégovine)__       Bosnie Herzégovine <<- ->> Bosnie-Herzégovine                           # Il manque un trait d’union.
-__[u]/tu(tu_Charente_Maritime)__        Charente Maritime <<- ->> Charente-Maritime                             # Il manque un trait d’union.
-__[u]/tu(tu_Clermont_Ferrand)__         Clermont Ferr?an[dt] <<- ->> Clermont-Ferrand                           # Il manque un trait d’union.
-__[u]/tu(tu_Colombie_Britannique)__     Colombie Britannique <<- ->> Colombie-Britannique                       # Il manque un trait d’union.
-__[u]/tu(tu_États_Unis)__               États Unis <<- ->> États-Unis                                           # S’il s’agit des USA, il manque un trait d’union.
-__[u]/tu(tu_Franche_Comté)__            Franche Comté <<- ->> Franche-Comté                                     # Il manque un trait d’union.
-__[u]/tu(tu_Haute_Département)__        Haute (Garonne|Loire|Marne|Normandie|Corse|Vienne) @@$ <<- ->> Haute-\1 # Il manque un trait d’union.
-__[u]/tu(tu_Île_de_France)__            [ÎI]le [dD]e France <<- ->> Île-de-France                               # Il manque les traits d’union.
-__[u]/tu(tu_Maison_Blanche)__           Maison Blanche <<- ->> Maison-Blanche                           # Il manque un trait d’union.
-__[u]/tu(tu_Moyen_Orient)__             Moyen Orient <<- ->> Moyen-Orient                               # Il manque un trait d’union.
-__[u]/tu(tu_Nouveau_Brunswick)__        Nouveau Brunswick <<- ->> Nouveau-Brunswick                     # Il manque un trait d’union.
-__[u]/tu(tu_Nouvelle_Qqch)__            Nouvelle (Zélande|Calédonie|Orléans) @@$ <<- ->> Nouvelle-\1    # Il manque un trait d’union.
-__[u]/tu(tu_Pas_de_Calais)__            Pas de Calais <<- ->> Pas-de-Calais                             # Il manque les traits d’union.
-__[u]/tu(tu_Rhône_Alpes)__              Rhône Alpes <<- ->> Rhône-Alpes                                 # Il manque les traits d’union.
-__[u]/tu(tu_Saône_et_Loire)__           Saône et Loire <<- ->> Saône-et-Loire                           # Il manque un trait d’union.
-__[u]/tu(tu_Jésus_Christ)__             Jésus Christ <<- ->> Jésus-Christ                               # Il manque un trait d’union.
-__[u]/tu(tu_Jean_prénom)__
-    Jean (Baptiste|Claude|François|Jacques|Louis|Luc|Marc|Marie|Michel|Paul|Philippe|Pierre)  @@$ 
-    <<- ->> Jean-\1                                                                                 # Il manque un trait d’union.
-__[u]/tu(tu_Marie_Prénom)__
-    Marie (Ange|Agnès|Anne|Antoinette|Cécile|Chantal|Charlotte|Christine|Claire|Claude|Dominique|France|Françoise|Hélène|Jeanne|José|Josèphe|Line|Louise|Madeleine|Noëlle|Odile|Paule|Pierre|Rose|Thérèse)  @@$ 
-    <<- ->> Marie-\1                                                                                # Il manque un trait d’union.
-__[s]/tu(tu_St_Ste_Bidule)__
-    ((Ste?) )[A-ZÉÈÎ]\w+ @@0,0
-    <<- -1>> \2-
-    # Il manque un trait d’union s’il s’agit d’une église, d’une cité, d’une communauté… S’il s’agit d’une personne, écrivez « saint(e) » sans majuscule, sans trait d’union.
-
-TEST: Émigrer au {{Royaume Uni}}
-TEST: Étudier en {{Grande Bretagne}}
-TEST: Vivre aux {{Pays Bas}}
-TEST: Il passe par {{Aix en Provence}}
-TEST: Qui se souvient de la {{Bosnie Herzégovine}} ?
-TEST: en {{Charente Maritime}}
-TEST: À {{Clermont Ferrand}}
-TEST: habiter la {{Colombie Britannique}}
-TEST: Il fait son stage étudiant aux {{États Unis}}
-TEST: Des fromages délicieux de {{Franche Comté}}
-TEST: La {{Haute Garonne}}
-TEST: L’{{Île de France}} est surpeuplée.
-TEST: Un nouveau président à la {{Maison Blanche}}
-TEST: La guerre au {{Moyen Orient}}
-TEST: Il ne connaît au {{Nouveau Brunswick}}
-TEST: Elle a visité la {{Nouvelle Orléans}}
-TEST: Vivre dans le {{Pas de Calais}}
-TEST: Des vacances en {{Rhône Alpes}}
-TEST: Elle déménage en {{Saône et Loire}}
-TEST: {{Jésus Christ}}, dernier héros de l’Antiquité
-TEST: Elle a quitté {{Jean Paul}}.
-TEST: {{Marie Hélène}} s’est perdue dans le dédale
-TEST: Elle va prier à {{Ste }}Catherine.
-
-
-### nombres
-__[i]/tu(tu_nombres)__
-    (?:dix|trente|quarante|cinquante|soixante|septante|octante|huitante|nonante) (?:deux|trois|six|sept|huit|quatre?|cinqu?|neu[fv])(?:ièmes?|)
-    <<- ->> =\0.replace(" ", "-")                                                                   # Il manque un trait d’union.
-__[i]/tu(tu_nombres_vingt)__
-    vingts? (?:deux|trois|six|sept|huit|quatre?|cinqu?|neu[fv])(?:ièmes?|)
-    <<- not before("(?i)quatre $") ->> =\0.replace(" ", "-").replace("vingts", "vingt")             # Il manque un trait d’union.
-__[i]/tu(tu_nombres_soixante)__
-    soixante (?:douze?|treize?|quatorze?|quinze?|seize?|dix(?:[- ]sept|[- ]huit|[- ]neu[fv]|))(?:ièmes?|)
-    <<- ->> =\0.replace(" ", "-")                                                                   # Trait(s) d’union manquant(s).
-__[i]/tu(tu_nombres_octante)__
-    quatre[- ]vingts? (?:une?|deux|trois|six|sept|huit|quatre?|onze?|douze?|treize?|quatorze?|quinze?|seize?|cinqu?|neu[fv]|dix(?:[- ]sept|[- ]huit|[- ]neu[fv]|))(?:ièmes?|)
-    <<- ->> =\0.replace(" ", "-").replace("vingts", "vingt")                                        # Trait(s) d’union manquant(s).
-#__[i]tu(tu_nombre et un)__
-#    (vingt|trente|quarante|cinquante|soixante|septante|octante|huitante|nonante)[- ](une?|unièmes?)
-#   ->> \1 et \2|\1-et-\2                                      # Il manque « et ». (Si vous suivez la réforme orthographique, utilisez des traits d’union.)
-
-TEST: Il en veut {{vingts}} !                 ->> vingt
-TEST: Y a-t-il {{quarante deux}} pages ?      ->> quarante-deux
-TEST: J’en veux {{quatre-vingt}} !            ->> quatre-vingts
-TEST: Non, {{quatre-vingts deux}} !           ->> quatre-vingt-deux
-TEST: {{Quatre vingts deux}}.                 ->> Quatre-vingt-deux
-TEST: cent {{mot}}                            ->> mots
-TEST: cinquante {{mot}}                       ->> mots
-TEST: mille cinquante {{mot}}                 ->> mots
-TEST: deux {{cents}} trois mots               ->> cent
-TEST: il y a {{cents}} mots                   ->> cent
-TEST: {{cents}} mots                          ->> cent
-TEST: ils mangent {{cents}} têtes             ->> cent
-TEST: deux {{tête}}                           ->> têtes
-TEST: {{soixante quatorze}}, c’est trop
-TEST: Mais {{vingt trois}}, c’est assez
-TEST: La poïesis, en grec, est ce qui permet de faire passer n’importe quoi du non-être à l’être
-
-
-### Pas de trait d’union
-__[i]/tu(tu_deux_tiers)__           deux-tiers <<- ->> deux tiers                                               # Pas de trait d’union.
-__[i]/tu(tu_en_bas_haut)__          en-(bas|haut|de(?:ssous|hors|çà)) @@$ <<- ->> en \1                         # Pas de trait d’union.
-__[i]/tu(tu_peu_à_peu)__            peu-[aà]-peu <<- ->> peu à peu                                              # Pas de trait d’union.
-__[i]/tu(tu_s_il_te_plaît)__        s’il-(?:[tm]e|[vn]ous)-pla[îi]t <<- ->> =\0.replace("-", " ")               # Pas de traits d’union.
-__[i]/tu(tu_tout_à_fait)__          tout-à-fait <<- ->> tout à fait                                             # Pas de trait d’union.
-__[i]/tu(tu_trois_quarts)__         trois-quarts? <<- not morph(word(-1), ":D", False, False) ->> trois quarts  # Pas de trait d’union.
-__[i]/tu(tu_parce_que)__            parce-que? <<- ->> =\0.replace("-", " ")                                    # Pas de trait d’union.
-__<i]/tu(tu_qqch_ça_aussi_donc)__   \b-(?:ç[aà]|aussi|donc) <<- ->> =\0.replace("-", " ")                       # Pas de trait d’union.
-__[i]/tu(tu_d_entre_pronom)__       d’entre-(?:nous|vous|eux|elles) <<- ->> =\0.replace("-", " ")               # Pas de trait d’union.
-
-TEST: J’en ai déjà fait les {{deux-tiers}}.
-TEST: {{en-haut}} de la montagne.
-TEST: On va finir par s’y faire, {{peu-à-peu}}.
-TEST: Venez vite, {{s’il-vous-plait}}.
-TEST: Elles sont {{tout-à-fait}} ravies.
-TEST: {{Trois-quarts}} des participantes y sont parvenues.
-TEST: {{Parce-qu}}’ils y croient plus que tout.
-TEST: Oui, ça{{-aussi}}.
-TEST: Peu {{d’entre-nous}} savent ce dont il s’agit.
-
-
-__[i]/tu(tu_y_attaché)__
-    (y[’-])({avoir_etre})(?:-(?:t-|)(?:ils?|elles?|je|tu|on|nous|vous)|) @@0,2
-    <<- morph(\2, ":V0|>en ", False) -1>> "y "                                                      # Ici, ni apostrophe, ni trait d’union.
-
-TEST: {{Y’}}a trop de malheureux sur Terre.
-TEST: {{Y’}}en a marre, de ces conneries.
-TEST: {{y-}}a-t-il des beignets ?                     ->> "y "
-
-
-__[i]/tu(tu_lorsque)__
-    lors que?
-    <<- not before(r"(?i)\bd[eè]s +$") ->> =\0.replace(" ", "")                                     # Attachez les deux mots.|https://fr.wiktionary.org/wiki/lorsque
-
-TEST: Elle y arriva {{lors qu}}’elle trouva l’astuce permettant l’ouverture de la porte.
-TEST: Dès lors qu’on sait comment s’y prendre, aucune raison de faillir.
-
-
-!!!! Virgules                                                                                       
-
-# Dialogues
-__[u]/virg(virgule_dialogue_après_nom_propre)__
-    ([A-ZÉÈ][\w-]+) (\w+-(?:moi|toi|l(?:ui|a|e(?:ur|s|))|nous|vous|je|tu|ils|elles))  @@0,$
-    <<- morphex(\1, ":M", ":G") and not morph(\2, ":N", False) and isStart()
-    -1>> \1,                                                                        # Dialogue ? Ajoutez une virgule pour mettre en incise la personne à qui s’adresse la réplique.
-
-TEST: {{Maria}} donnez-vous du temps ?
-TEST: {{Marion}} passe-moi le sel.
-TEST: {{Paul}} prends-lui la main.
-TEST: Alexandre tient-il ses généraux ?
-TEST: Alexandra vient-elle ?
-
-
-__[u]/virg(virgule_dialogue_avant_nom_propre)__
-    ({w1})(-l(?:es?|a)(?:-(?:[mt]oi|[nv]ous|lui|leur)|)) ([A-ZÉÈ][\w-]+)   @@0,*,$
-    <<- morph(\1, ":E", False) and morph(\3, ":M", False)
-    -2>> \2,                                                                        # Dialogue. Ajoutez une virgule pour mettre en incise la personne à qui s’adresse la réplique.
-
-TEST: viens et donne{{-le}} Paul.
-TEST: donne{{-le-moi}} Camille.
-TEST: donne-moi Alice.
-TEST: Tape-toi Patrick.
-
-
-__[u]/virg(virgule_après_verbe_COD)__
-    l(?:es?|a) ({w_2}(?:[ei]r|re)) ([A-ZÉÂÔÈ][\w-]+)  @@w,$
-    <<- morph(\1, ":Y", False) and morph(\2, ":M", False) and not morph(word(-1), ">à ", False, False)
-    -1>> \1,                                                                                        # Une virgule est probablement souhaitable.
-
-TEST: Tu vas les {{donner}} Rachel.
-TEST: Il va la {{tuer}} Paul.
-TEST: Cependant les promesses n’engagent que ceux qui les croient, comme aimait à le dire Jacques Chirac.
-
-
-
-!!!! Apostrophe manquante (2)                                                                       
-
-__<s>/typo(typo_apostrophe_manquante_audace2)__
-    ^ *([LDSNCJMTÇ] )[aeéiouhAEÉIOUHyîèêôûYÎÈÊÔÛ]  @@*
-    <<- option("mapos") -1>> =\1[:-1]+"’"                                                           # Il manque peut-être une apostrophe.
-
-TEST: __mapos__ {{L }}opinion des gens, elle s’en moquait.
-
-
-
-!!!! A / À: accentuation la préposition en début de phrase                                          
-
-__<s]/typo(typo_À_début_phrase1)__
-    ^ *(A) (?!t[’-](?:ils?|elles?|on))({w_2})  @@*,$
-    <<- morphex(\2, ":[GNAY]", ":(?:Q|3s)|>(?:priori|post[eé]riori|contrario|capella|fortiori) ")
-        or (\2 == "bientôt" and isEnd())
-    -1>> À                                                                                          # S’il s’agit de la préposition « à », il faut accentuer la majuscule.
-__<s>/typo(typo_À_début_phrase2)__
-    ^ *(A) [ldnms]’  @@*  <<- -1>> À                                                                # S’il s’agit de la préposition « à », il faut accentuer la majuscule.
-__<s>/typo(typo_À_début_phrase3)__
-    ^ *(A) t’(?!il |elle |ont? )  @@*  <<- -1>> À                                                   # S’il s’agit de la préposition « à », il faut accentuer la majuscule.
-
-TEST: {{A}} vaincre sans péril, on triomphe sans gloire.
-TEST: « {{A}} partir de maintenant, ce ne sera plus comme avant.
-TEST: — {{A}} n’en plus pouvoir
-TEST: — {{A}} t’emmener loin de tout ceci.
-TEST: {{A}} bientôt, mon ami.
-TEST: A bientôt fini son devoir.
-TEST: A priori, nul ne peut y parvenir sans une aide extérieure.
-TEST: A devient notre meilleure chance d’y parvenir.
-
-
-!!!! Accentuation des majuscules                                                                    
-
-__[u]/maj(maj_accents)__
-    E(?:tat|glise|co(?:le|nomie)|quipe|lectri(?:cité|que)|gal(?:ité|ement)|té)s? @@1
-    <<- ->> ="É"+\0[1:]                                                                            # Accentuez les majuscules.
-    <<- ~>> ="É"+\0[1:]
-
-TEST: Le budget de l’{{Etat}}.
-
-
-
-!!!
-!!!
-!!! Désambiguïsation                                                                                
-!!!
-!!!
-
-# mots grammaticaux
-__[i](d_dans)__
-    dans
-    <<- not morph(word(-1), ":D.*:p|>[a-z]+ièmes ", False, False) =>> select(\0, ":R")
-
-__[i](d_ton_son)__
-    (\w+) ([ts]on)  @@0,$
-    <<- morph(\1, ">(?:le|ce[st]?|ton|mon|son|quel(?:que|)s?|[nv]otre|un|leur|ledit|dudit) ") =>> exclude(\2, ":D")
-
-# Pronoms le/la/les
-__[i](d_je_le_la_les)__
-    je (l(?:e(?:ur|s|)|a)) @@$                  <<- not morph(word(-1), ":1s", False, False) =>> select(\1, ":Oo")
-__[i](d_tu_le_la_les)__
-    tu (l(?:e(?:ur|s|)|a)) @@$                  <<- not morph(word(-1), ":2s", False, False) =>> select(\1, ":Oo")
-__[i](d_il_elle_on_le_la_les)__
-    (?:il|elle|on) (l(?:e(?:ur|s|)|a)) @@$      <<- not morph(word(-1), ":3s", False, False) =>> select(\1, ":Oo")
-__[i](d_nous_le_la_les)__
-    nous (l(?:e(?:ur|s|)|a)) @@$                <<- not morph(word(-1), ":1p", False, False) =>> select(\1, ":Oo")
-__[i](d_vous_le_la_les)__
-    vous (l(?:e(?:ur|s|)|a)) @@$                <<- not morph(word(-1), ":2p", False, False) =>> select(\1, ":Oo")
-__[i](d_nous)__
-    (nous) ({avoir_etre}) @@0,$                 <<- not morph(\2, ":1p", False) =>> exclude(\1, ":Os")
-__[i](d_vous)__
-    (vous) ({avoir_etre}) @@0,$                 <<- not morph(\2, ":2p", False) =>> exclude(\1, ":Os")
-__[i](d_ils_elles_le_la_les)__
-    (?:ils|elles) (l(?:e(?:ur|s|)|a)) @@$       <<- not morph(word(-1), ":3p", False, False) =>> select(\1, ":Oo")
-__[i](d_ne_me_te_te_le_la_leur)__
-    [nmts]e (l(?:e(?:ur|s|)|a)) @@$             <<- =>> =select(\1, ":Oo")
-
-
-# verbe
-__[i](d_ne_verbe)__
-    ne +(?:l(?:es? |eurs? |ui |a |’)|[nv]ous |)({w_1}) @@$
-    <<- not morph(\1, ":(?:O[sp]|X)", False) =>> select(\1, ":V")
-__[i](d_n_m_t_s_verbe)__
-    [nmts]’(?:en +|y +|)({w_1}) @@$
-    <<- not morph(\1, ":X", False) =>> select(\1, ":V")
-__[i](d_me_te_se_verbe)__
-    [mts]e +(?:l(?:es? +|a +|’)|)({w_2})  @@$
-    <<- =>> select(\1, ":V")
-__[i](d_je_verbe)__
-    j’(?:en +|y +|)({w_1}) @@$
-    <<- =>> select(\1, ":[123][sp]")
-__[i](d_je_il_ils_on_verbe)__
-    (?:je|ils?|on) +(?:l(?:es? +|la +|’)|[nv]ous +|)({w_1}) @@$
-    <<- not morph(\1, ":(?:Oo|X)", False) =>> select(\1, ":[123][sp]")
-__[i](d_tu_verbe)__
-    tu +(?:l(?:es? +|la +|’)|[nv]ous +|)({w_1}) @@$
-    <<- morph(word(-1), ":Cs", False, True) and not morph(\1, ":(?:Oo|X)", False) =>> select(\1, ":[123][sp]")
-__[s](d_nom_propre_verbe)__
-    ([A-ZÉÈ]{w_1}) +({w_1})  @@0,$
-    <<- morph(\1, ":M") and \2.islower() and morphex(\2, ":[123][sg]", ":Q") and morph(\2, ":N", False) and morph(word(-1), ":Cs", False, True)
-    =>> select(\2, ":[123][sp]")
-    <<- morph(\1, ":M", False) and morphex(\2, ":[123]s|>(?:[nmts]e|nous|vous) ", ":A") and isStart() =>> =select(\1, ":M")
-__[i](d_que_combien_pourquoi_en_y_verbe)__
-    (?:que?|combien|pourquoi) +(?:en +|y +|)({w_3}) @@$
-    <<- =>> exclude(\1, ":E")
-
-# groupe nominal
-__[i](d_aucun_non_verbe)__
-    aucun +({w_4}) @@$
-    <<- morph(\1, ":[NA].*:[me]", False) =>> exclude(\1, ":V")
-__[i](d_de_non_verbe)__
-    d(?:e +|’)({w_1}) @@$
-    <<- not morph(\1, ":[YD]", False) =>> exclude(\1, ":V")
-__[i](d_d_un_une_non_verbe)__
-    d’une? ({w_1}) @@$
-    <<- =>> exclude(\1, ":V")
-__[i](d_déterminant_non_verbe)__
-    (?:des|chaque|quelques?|cet(?:te|)|m(?:on|a)|[ts]a|aux?) +({w_1}) @@$
-    <<- =>> exclude(\1, ":V")
-__[i](d_de_la_non_verbe)__
-    de l(?:a |’)({w_2}) @@6
-    <<- not morph(\1, ":Y", False) =>> exclude(\1, ":V")
-__[i](d_de_pronom_non_verbe)__
-    de (?:tel(?:le|)s?|ce(?:tte|t|s)|[ts](?:a|es)|m(?:on|a|es)|[nv]o(?:tre|s)|plein) +({w_2})  @@$
-    <<- =>> exclude(\1, ":V")
-__[i](d_par_non_verbe)__
-    par +({w_3}) @@$
-    <<- =>> exclude(\1, ":V[123]")
-__[i](d_très_non_verbe)__
-    très +({w_2}) @@$
-    <<- =>> exclude(\1, ":[123][sp]")
-
-# divers
-__[i](p_bac_plus_nombre)__
-    bac ?([+] ?\d\d?) @@$
-    <<- ~1>> *
-    <<- =>> define(\0, [":N:e:i"])
-
-
-TEST: il s’agit d’{{un}} {{anagramme}}
-TEST: nul ne sait qui arriva à ce pauvre Paul surpris par la pluie.
-TEST: elle finit par être très fière de son fils.
-
-
-
-
-!!
-!!
-!!!! OCR                                                                                            
+!!
+!!
+!!!! OCR                                                                                          !!
 !!
 !!
 
 # ?
 __<s]/ocr(ocr_point_interrogation)__
@@ -2204,11 +1357,11 @@
 
 TEST: __ocr__ on poirautait, {{cotte}} mariée n’arrivait pas à se décider.
 
 
 # Comme / Gomme
-__[s]/ocr(ocr_comme)__      Gomme <<- not morph(word(1), ">(?:et|o[uù]) ") ->> Comme                # Erreur de numérisation ?
+__[s]/ocr(ocr_comme)__      Gomme <<- not morph(word(1), ">(?:et|o[uù])/") ->> Comme                # Erreur de numérisation ?
 
 TEST: __ocr__ {{Gomme}} il était sage à cette époque-là !
 
 
 # Comment / Gomment
@@ -2467,11 +1620,11 @@
 # Mais / Hais / Mats / niais
 __[u]/ocr(ocr_mais1)__      Hais <<- ->> Mais                                                       # Erreur de numérisation ?
 __[i]/ocr(ocr_mais2)__      mats <<- not morph(word(-1), ":D:[me]:p", False, False) ->> mais        # Erreur de numérisation ?
 __[i]/ocr(ocr_mais3)__      maïs <<- not morph(word(-1), ":D:(?:m:s|e:p)", False, False) ->> mais   # Erreur de numérisation ?
 __[s]/ocr(ocr_mais4)__
-    niais <<- not morph(word(-1), ">(?:homme|ce|quel|être) ", False, False) ->> mais                # Erreur de numérisation ?
+    niais <<- not morph(word(-1), ">(?:homme|ce|quel|être)/", False, False) ->> mais                # Erreur de numérisation ?
 
 TEST: __ocr__ {{Hais}} il en sait trop.
 TEST: __ocr__ c’était bien, {{mats}} quelle journée
 TEST: __ocr__ c’est bien, {{niais}} trop subtil.
 TEST: __ocr__ c’est parfait, {{maïs}} trop subtil.
@@ -2589,11 +1742,11 @@
 TEST: __ocr__ pour elle, c’est une condition sine qua non.
 
 
 # qu’importe
 __[i]/ocr(ocr_qu_importe)__
-    qu (importé)  @@3
+    qu’(importé)  @@3
     <<- -1>> importe                                                                                # Erreur de numérisation ?
 
 TEST: __ocr__ Qu’{{importé}} le flacon, pourvu qu’on ait l’ivresse.
 
 
@@ -2695,11 +1848,11 @@
 ## Casse
 __[s]/ocr(ocr_casse1)__
     [A-ZÉÈÂÊÎÔ]{w_1}
     <<- \0.istitle() and before(r"(?i)\w") >>>
     <<- morphex(\0, ":G", ":M") ->> =\0.lower()                                                     # Erreur de numérisation ? Casse improbable.
-    <<- __else__ and morphex(\0, ":[123][sp]", ":[MNA]|>Est ") ->> =\0.lower()                      # Erreur de numérisation ? Casse improbable.
+    <<- __else__ and morphex(\0, ":[123][sp]", ":[MNA]|>Est/") ->> =\0.lower()                      # Erreur de numérisation ? Casse improbable.
 
 TEST: __ocr__ votre ami la regarde, {{Vous}} ne l’avez pas achetée
 TEST: __ocr__ pour accommoder son regard, {{La}} lourde forme demeure
 TEST: __ocr__ parler de Nicole, {{Le}} sommeil ne vient pas.
 TEST: __ocr__ a fait de toi, Charles, {{Tu}} étais beau quand
@@ -2730,11 +1883,11 @@
 
 ## Lettres isolées
 # Note: l’option “mapos” cherche les apostrophes manquantes après les lettres l, d, n, m, t, s, j, c, ç
 __[s]/ocr(ocr_lettres_isolées)!2__
     \w(?!’)
-    <<- not re.search("[0-9aàAÀyYdlnmtsjcçDLNMTSJCÇ_]", \0) and not before(r"\d +$") and not (\0.isupper() and after0(r"^\."))
+    <<- not re.search("[0-9aàAÀyYdlnmtsjcçDLNMTSJCÇ_]", \0) and not before(r"\d[   ]+$") and not (\0.isupper() and after0(r"^\."))
     ->> _           # Lettre isolée : erreur de numérisation ?
 
 TEST: __ocr__ des verres luisent sur {{i}} le bureau blanc.
 TEST: __ocr__ la voix, {{e}} est celle de…
 TEST: __ocr__ ressemble {{h}} une fenêtre de serre.
@@ -2750,251 +1903,1277 @@
 TEST: __ocr__ trouve {{l£}} temps
 TEST: __ocr__ elle s’{{avance*}} sur le seuil
 TEST: __ocr__ par beaucoup d’argent ? {{{Il}} débouche le Jack Daniels
 
 
-!!
-!!
-!!!! Incohérences de base                                                                           
+
+!!!
+!!!
+!!! Processeur: Dernier nettoyage avant coupure du paragraphe en phrases                          !!
+!!!
+!!!
+
+# Trait d’union conditionnel (u00AD)
+__<i>(p_trait_union_conditionnel1)__    \w+‑\w+‑\w+ <<- ~>> =\0.replace("‑", "")
+__<i>(p_trait_union_conditionnel2)__    \w+‑\w+ <<- ~>> =\0.replace("‑", "")
+
+# empêcher la scission en fin de dialogue
+__<s>(p_fin_dialogue1)__    ([?!…][?!…  ]*)[ "'”» ]*,  @@0 <<- ~1>> *
+__<s>(p_fin_dialogue2)__    ([?!…][?!…  ]*)[ "'”» ]*[a-zéèêîô]  @@0 <<- ~1>> ,
+
+TEST: « Je suis donc perdu ? », dit Paul.
+TEST: “C’est bon !”, croit savoir Marie.
+TEST: “Parce que… ?” finit par demander Paul.
+TEST: « Dans quel pays sommes-nous ? » demanda un manifestant.
+
+
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!! PASSE 1: PHRASE PAR PHRASE                                                                     !!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+!!
+
+[++]
+
+
+
+!!!! Doublons (casse identique)                                                                   !!
+
+__[s](doublon)__
+    ({w1}) {1,3}\1  @@0
+    <<- not re.search("(?i)^([nv]ous|faire|en|la|lui|donnant|œuvre|h[éoa]|hou|olé|joli|Bora|couvent|dément|sapiens|très|vroum|[0-9]+)$", \1)
+        and not (re.search("^(?:est|une?)$", \1) and before("[’']$"))
+        and not (\1 == "mieux" and before("(?i)qui +$"))
+    ->> \1   # Doublon.
+
+TEST: Il y a un {{doublon doublon}}.
+
+
+!!!! Nombres: typographie                                                                         !!
+
+#(\d\d\d\d)-(\d\d\d\d)   <<- ->> \1–\2                              # Ne pas séparer deux dates par un trait d’union, mais par un tiret demi-cadratin.
+
+__[s]/num(num_lettre_O_zéro1)__  [\dO]+[O][\dO]+ <<- not option("ocr") ->> =\0.replace("O", "0")    # S’il s’agit d’un nombre, utilisez le chiffre « 0 » plutôt que la lettre « O ».
+__[s]/num(num_lettre_O_zéro2)__  [1-9]O <<- not option("ocr") ->> =\0.replace("O", "0")             # S’il s’agit d’un nombre, utilisez le chiffre « 0 » plutôt que la lettre « O ».
+
+TEST: année {{2O11}}                                                      ->> 2011
+TEST: {{3O}} (chiffre avec un O).                                         ->> 30
+
+
+# Nombres ordinaux
+__[s]/typo(typo_ordinaux_premier)__
+    1 ?(?:ier|i?ère)s?
+    <<- ->> =\0.replace(" ", "").replace("è", "").replace("i", "").replace("e", "ᵉ").replace("r", "ʳ").replace("s", "ˢ")
+    # Nombre ordinal. Premier : 1ᵉʳ. Première : 1ʳᵉ. Premiers : 1ᵉʳˢ. Premières : 1ʳᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+__[s]/typo(typo_ordinaux_deuxième)__
+    2 ?nde?s?
+    <<- ->> =\0.replace(" ", "").replace("n", "").replace("d", "ᵈ").replace("e", "ᵉ").replace("s", "ˢ")
+    # Nombre ordinal. Second : 2ᵈ. Seconde : 2ᵈᵉ. Seconds : 2ᵈˢ. Secondes : 2ᵈᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+__[s]/typo(typo_ordinaux_nième)__
+    ([0-9]+) ?(?:è|i?[èe]me)s?  @@0
+    <<- \0.endswith("s") ->> \1ᵉˢ                                                                   # Nombre ordinal pluriel. Exemples : 2ᵉˢ, 3ᵉˢ, 4ᵉˢ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+    <<- __else__ ->> \1ᵉ                                                                            # Nombre ordinal singulier. Exemples : 2ᵉ, 3ᵉ, 4ᵉ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+__[s]/typo(typo_ordinaux_romain_premier)__
+    I ?(?:ier|i?ère)s?
+    <<- ->> =\0.replace(" ", "").replace("è", "").replace("i", "").replace("e", "ᵉ").replace("r", "ʳ").replace("s", "ˢ")
+    # Nombre ordinal romain. Premier : 1ᵉʳ. Première : Iʳᵉ. Premiers : Iᵉʳˢ. Premières : Iʳᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+__[s]/typo(typo_ordinaux_romain_deuxième)__
+    II ?nde?s?
+    <<- ->> =\0.replace(" ", "").replace("n", "").replace("d", "ᵈ").replace("e", "ᵉ").replace("s", "ˢ")
+    # Nombre ordinal romain. Second : IIᵈ. Seconde : IIᵈᵉ. Seconds : IIᵈˢ. Secondes : IIᵈᵉˢ.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+__[s]/typo(typo_ordinaux_romains_nième)__
+    ([IVXLCM]{1,3}) ?(?:è|i?[èe]me)s?  @@0
+    <<- not morph(\0, ":G", False) >>>
+    <<- \0.endswith("s") ->> \1ᵉˢ                                                                   # Nombre ordinal romain singulier. Exemples : IIᵉ, IIIᵉ, IVᵉ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+    <<- __else__ ->> \1ᵉ                                                                            # Nombre ordinal romain pluriel. Exemples : IIᵉˢ, IIIᵉˢ, IVᵉˢ…|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4271
+
+TEST: la {{1ière}} fois, c’est la plus dure     ->> 1ʳᵉ
+TEST: le {{1ier}} de chaque semaine             ->> 1ᵉʳ
+TEST: le {{2nd}} du mois                        ->> 2ᵈ
+TEST: les {{3ièmes}} années                     ->> 3ᵉˢ
+TEST: C’est la {{3ème}} fois…                   ->> 3ᵉ
+TEST: Non, la {{2è}} fois.                      ->> 2ᵉ
+TEST: François {{Iier}}                         ->> Iᵉʳ
+TEST: le {{IInd}} siècle                        ->> IIᵈ
+TEST: le {{VIième}} siècle                      ->> VIᵉ
+TEST: Le {{XXIème}} siècle.                     ->> XXIᵉ
+TEST: le {{XXè}} siècle.                        ->> XXᵉ
+
+
+
+!!!! Écritures épicènes invariables                                                               !!
+
+__[i](d_typo_écriture_épicène_pluriel)__
+    ({w_1}[éuitsrn])_(?:[nt]|)e_s  @@0
+    <<- morphex(\1, ":[NAQ]", ":G") =>> define(\1, [":N:A:Q:e:p"])
+
+__[i](d_typo_écriture_épicène_singulier)__
+    ({w_2}[éuitsrn])_e  @@0
+    <<- morph(\1, ":[NAQ]", False) =>> define(\1, [":N:A:Q:e:s"])
+
+
+!!!! Dates                                                                                        !!
+
+__[i]/date(date_jour_mois_année)__
+    (\d\d?) (janvier|février|ma(?:rs|i)|a(?:vril|o[ûu]t)|jui(?:n|llet)|septembre|octobre|novembre|décembre) (\d\d\d+)  @@0,w,$
+    <<- not checkDateWithString(\1, \2, \3) ->> _                                                   # Cette date est invalide.
+
+TEST: {{29 février 2011}}
+
+
+__[i]/date(date_journée_jour_mois_année1)__
+    (lundi|m(?:ardi|ercredi)|jeudi|vendredi|samedi|dimanche),? (?:le |)(\d\d?)-(\d\d?)-(\d\d+)  @@0,w,w,$
+    <<- not after(r"^ +av(?:ant|) +J(?:C|ésus-Christ)") and not checkDay(\1, \2, \3, \4)
+    -1>> =getDay(\2, \3, \4)                                                                        # Le jour de la date suivante est incorrect.
+
+TEST: {{mercredi}}, le 10-06-2014                                         ->> mardi
+
+
+__[i]/date(date_journée_jour_mois_année2)__
+    (lundi|m(?:ardi|ercredi)|jeudi|vendredi|samedi|dimanche),? (?:le |)(\d\d?) (janvier|février|ma(?:rs|i)|a(?:vril|o[ûu]t)|jui(?:n|llet)|septembre|octobre|novembre|décembre) (\d\d+)  @@0,w,w,$
+    <<- not after(r"^ +av(?:ant|) +J(?:C|ésus-Christ)") and not checkDayWithString(\1, \2, \3, \4)
+    -1>> =getDayWithString(\2, \3, \4)                                                              # Le jour de la date suivante est incorrect.
+
+TEST: {{mercredi}}, le 10 juin 2014                                       ->> mardi
+TEST: {{lundi}}, 18 août 1912                                             ->> dimanche
+TEST: lundi, 18 août 1912 avant Jésus-Christ (date imaginaire)
+
+
+__[i]/date(date_mois_31)__ 31 (avril|juin|septembre|novembre)  @@3
+    <<- ->> 30 \1                                                                                   # Cette date est invalide. Il n’y a que 30 jours en \1.
+
+TEST: le {{31 avril}}
+
+
+__[i]/date(date_février)__ 3[01] février
+    <<- ->> 28 février|29 février                                                                   # Cette date est invalide. Il n’y a que 28 ou 29 jours en février.
+
+TEST: le {{30 février}}
+
+
+
+!!!
+!!!
+!!! Processeur: épuration des signes inutiles et quelques simplifications                         !!
+!!!
+!!!
+
+# fin de phrase
+__<s>(p_fin_de_phrase)__        [.?!:;…][ .?!… »”")]*$  <<- ~>> *
+
+# début de phrase
+__<s>(p_début_de_phrase)__      ^ *[-–—] <<- ~>> *
+
+# Guillemets et exposants
+__<s>(p_guillemets_exposants)__ [«»“”"„`¹²³⁴⁵⁶⁷⁸⁹⁰]+ <<- ~>> *
+
+# Chapitres et références
+__<s>(p_chapitre_référence)__   [[({][\dIVXLCDM]+, \d+[])}]   <js>[\[\(\{][\dIVXLCDM]+, \d+[\]\)\}]</js>   <<- ~>> *
+
+# simplification des mots grammaticaux élidés
+__[i>(p_qu_apostrophe)__        (lorsqu|puisqu|quoiqu|jusqu|qu)’ @@0 <<- ~>> \1
+
+# le, la ou les chose(s)
+__[i>(p_le_ou_les)__            l[ea] ou les {w_2}([(]s[)]) @@$ <<- ~1>> s
+__[i](p_le_ou_la)__             l(e ou la|a ou le) {w_2} @@1 <<- ~1>> ’
+
+# les références aux notes
+__[i](p_références_aux_notes)__ [a-zéèâàôîù][a-zéèâàôîù-]+(\d+) @@$ <<- not morph(\0, ":", False) ~1>> *
+
+# faux positifs avec adverbes de négation
+__[i](p_pas_mal)__              pas mal <<- not morph(word(-1), ":D", False) ~>> *
+__[i](p_pas_assez)__            pas assez ({w_2}) @@$ <<- morph(\1, ":A", False) and not morph(word(-1), ":D", False) ~>> *
+
+# faux positifs avec «à chez»
+__[i](p_de_chez_à_chez_pronom)__    de chez \w+ (?:à|jusqu à) chez (?:moi|toi|lui|elles?|eux|nous|vous) <<- ~>> *
+__[i](p_de_chez)__                  (jusqu à|de) chez @@0 <<- ~1>> *
+
+# faux positifs
+__[i](p_en_tout_et_pour_tout)__ en tout et pour tout <<- ~>> *
+__[i](p_au_sortir_de)__         au (sortir) de?s?  @@3 <<- ~1>> *
+__[i](p_au_revoir)__            au revoir <<- ~>> au_revoir
+
+# singletons entre parenthèses / crochets / accolades
+__<s>(p_singleton_parenthèses)__    [(]\w+[)] <js>\([a-zA-Z]+\)</js> <<- ~>> *
+__<s>(p_singleton_accolades)__      [{]\w+[}] <js>\{[a-zA-Z]+\}</js> <<- ~>> *
+__<s>(p_singleton_crochets)__       [[]\w+[]] <js>\[[a-zA-Z]+\]</js> <<- ~>> *
+
+# Avocats
+__[s](p_Me_nom_propre)__        (Me) [A-ZÉÂÔÈ][\w-]+ @@0 <<- ~1>> *
+
+# Évènements
+__[s](p_Mai_68)__               Mai 68 <<- ~>> Mai-68
+
+# Rois, reines, papes et vaniteux du même acabit
+__[s](p_titres_et_ordinaux)__   [A-ZÉÂÔÈ]\w+ ([XVI]+|I(?:er|ᵉʳ)) @@$ <<- \1 != "I" ~1>> *
+
+# Marques
+__[i](p_Peugeot)__              Peugeot (\d0\d\d?) @@$ <<- ~1>> *
+
+# alors que / dès lors que (éviter d’accorder un participe passé avec un pseudo-COD antérieur)
+__[i](p_alors_dès_lors_que)__   (alors|dès lors) que?  @@0 <<- ~1>> _
+
+# Fusion des mots “multiples” (expérimental)
+__[s](p_fusion_mots_multiples)__
+    [A-Z][a-z]+ [A-Z][a-z]+
+    <<- spell(\0.replace(" ", "_")) ~>> =\0.replace(" ", "_")
+
+
+TEST: New York {{étaient}} {{devenue}} la plaque tournante de tous les trafics.
+
+
+!!
+!!
+!!!! Traits d’union                                                                               !!
+!!
+!!
+
+__<i]/tu(tu_t_euphonique_incorrect)__
+    ([-–—− ]t(?:[’' ][-–—−]?|[-–—−][’' ]?))(ils?|elles?|on|tu)  @@0,$
+    <<- re.search("(?i)^(?:ils|elles|tu)$", \2) -1>> -      # Le “t” euphonique n’est pas nécessaire avec “\2”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=t+euphonique&id=2513
+    <<- __else__ and \1 != "-t-" and \1 != "-T-" -1>> -t-   # Pour le “t” euphonique, il faut deux traits d’union. Pas d’apostrophe. Pas d’espace.
+    <<- \1 != "-t-" ~1>> -t-
+__<i]/tu(tu_t_euphonique_superflu)__
+    [td]([- ]t[-’' ])(?:il|elle|on)  @@1
+    <<- -1>> -                                              # Le “t” euphonique est superflu quand le verbe se termine par “t” ou “d”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=t+euphonique&id=2513
+    <<- \1 != "-t-" ~1>> -t-
+__<i]/tu(tu_t_euphonique_manquant)__
+    [aec](-(il|elle|on))  @@1,2  <<- -1>> -t-\2             # Il faut un “t” euphonique.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=t+euphonique&id=2513
+
+TEST: va{{ t’}}il y parvenir ?                          ->> -t-
+TEST: A{{ t’}}elle soif ?                               ->> -t-
+TEST: A{{ t-}}elle faim ?                               ->> -t-
+TEST: a{{ t'}}elle                                      ->> -t-
+TEST: a{{-t'}}il                                        ->> -t-
+TEST: a{{-t }}il.                                       ->> -t-
+TEST: a{{ t’}}il.                                       ->> -t-
+TEST: a{{ t-}}on.                                       ->> -t-
+TEST: donne{{ t-}}ils                                   ->> -
+TEST: donne{{-t }}il                                    ->> -t-
+TEST: vient{{-t-}}il                                    ->> -
+TEST: viendras{{-t-}}tu                                 ->> -
+TEST: Viendront{{ t-}}ils                               ->> -
+TEST: viennent{{ t-}}ils                                ->> -
+TEST: mangent{{-t-}}elles                               ->> -
+TEST: Ont{{ t’}}ils                                     ->> -
+TEST: Ont{{-t’}}ils                                     ->> -
+TEST: l’ont{{ t’}}ils vu ?                              ->> -
+TEST: exploite{{−t−}}il les ressources numériques       ->> -t-
+TEST: vainc{{-il}} ses ennemis aisément                 ->> -t-il
+TEST: Assis, gronde{{-t -}}elle                         ->> -t-
+TEST: vient-il demain ?
+TEST: prend-elle l’avantage ?
+TEST: saura-t-on jamais la vérité ?
+TEST: arrive-t-elle ce matin ?
+TEST: y aura-t-il du poulet au dîner ?
+
+
+__[i]/tu(tu_va_t_en)__              va[ -]t[ -]en(?! guerre) <<- ->> va-t’en                        # Une apostrophe est nécessaire (s’en aller).
+__[i]/tu(tu_va_t_en_guerre)__       va[ -]t[’' -]en guerres? <<- ->> va-t-en-guerre                 # Va-t-en-guerre (invariable) : des traits d’union sont nécessaires.
+
+TEST: {{Va-t-en}}, c’en est assez.
+TEST: Un {{va-t’en guerre}}, on ne peut pas lui faire confiance.
+TEST: Les {{va-t-en guerre}} sont de sortie.
+
+
+### Traits d’union douteux
+__[i]/tu(tu_trait_union_douteux)__
+    ({w1})(?:--|—|–)({w1})  @@0,$
+    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":", False) ->> \1-\2                               # Trait d’union : un tiret simple suffit.
+
+TEST: Nous préparons une {{contre–attaque}}.
+
+
+### ce / cet / cette / ces + nom + là
+__[i]/tu(tu_ce_cette_ces_nom_là1)__
+    c(?:e[st]?|ette) (({w_2}) là)(?! où)  @@$,w <<- morph(\2, ":[NB]", False) -1>> \2-là            # Il manque probablement un trait d’union.
+__[i]/tu(tu_ce_cette_ces_nom_là2)__
+    c(?:e[st]?|ette) (({w_2}) la)  @@$,w <<- morph(\2, ":[NB]", False) and isEnd() -1>> \2-là       # Il manque probablement un trait d’union.
+
+TEST: Ces {{trois là}} sont incollables.
+TEST: Je connais bien cette {{sensation là}}.
+TEST: Laisse ce chiot là où il est !
+
+
+### Préfixes
+__[i]/tu(tu_préfixe_ex)__
+    ex ({w2}) @@$  <<- morph(\1, ":N") and not re.search("(?i)^(?:aequo|nihilo|cathedra|absurdo|abrupto)", \1)
+    ->> ex-\1                                                                                       # S’il s’agit d’un seul mot, il manque un trait d’union.
+
+TEST: Son {{ex ami}} est un vrai cauchemar.
+TEST: Ton ex donne du fil à retordre.
+
+
+__[i]/tu(tu_préfixe_in)__
+    (in) ({w_2})  @@0,$
+    <<- not before(r"(?i)\b(?:drive|plug|sit) +$") >>>
+    <<- re.search("^(?:dix-huit|douze|seize|folio|octavo|quarto|plano)$", \2)
+    ->> =\0.replace(" ", "-")                                                                       # Il manque un trait d’union.
+    <<- __else__ and morph(\2, ":N:m") -1>> un                                                      # Confusion possible : pour le déterminant désignant quelque chose, écrivez “un”.
+
+TEST: Cet {{in folio}} est incroyable.
+TEST: c’est {{in}} stage de réinsertion.
+TEST: Dans ce drive in douze hommes mangent.
+
+
+__[i]/tu(tu_préfixe_mi)__
+    mi ({w2}) @@$  <<- morph(\1, ":[NAQ]", False) ->> mi-\1                                         # S’il s’agit d’un seul mot, il manque un trait d’union.
+
+TEST: J’ai été engagé pour un {{mi temps}}.
+
+
+__[i]/tu(tu_préfixe_quasi)__
+    (?:l(?:es?|a|eurs?)|ce(?:tte|t|s|)|des?|m(?:a|on|es)|[ts](?:es|a)) (quasi ({w1}))  @@$,$
+    <<- morphex(\2, ":N", ":[AGW]") -1>> quasi-\2                                                   # Il manque un trait d’union : « quasi » s’accroche au mot qui le suit s’il s’agit d’un nom.
+    <<- ~1>> \2
+
+TEST: leurs {{quasi indifférences}}
+
+
+__[i]/tu(tu_préfixe_semi)__
+    semi ({w2})  @@$ <<- morphex(\1, ":[NAQ]", ":G") ->> semi-\1                                   # S’il s’agit d’un seul mot, il manque un trait d’union.
+
+TEST: en {{semi liberté}}
+
+
+__[i]/tu(tu_préfixe_xxxo)__
+    (franco|américano|anglo|belgo|électro|ferro|hydro|labio|macro|magnéto|médico|micro|nano|néo|neuro|paléo|physico|politico|rétro|rhino|sino|socio|stéréo) ({w1})  @@0,$
+    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":", False)
+    ->> \1-\2                                                                                       # S’il s’agit d’un seul mot, il manque un trait d’union.
+
+TEST: des {{franco américains}}
+TEST: {{franco américaine}}                             ->> franco-américaine
+TEST: {{ferro électrique}}                              ->> ferro-électrique
+TEST: {{rétro ingénierie}}.                             ->> rétro-ingénierie
+
+
+__[i]/tu(tu_préfixe_pseudo)__
+    pseudo ({w_2}) @@$
+    <<- morph(\1, ":N") ->> pseudo-\1                                                               # Si vous voulez évoquer le simulacre de “\1”, mettez un trait d’union.
+    <<- __also__ ~>> \1
+__[i](p_pseudo_xxx)__
+    (pseudo-){w_2} @@0 <<- ~1>> *
+
+TEST: il n’avait contracté qu’un {{pseudo mariage}}.
+
+
+__[i]/tu(tu_préfixe_divers)__
+    (anti|auto|arrière|avant|demi|extra|intra|multi|non|post|sans|sous) ({w1})  @@0,$
+    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":", False) and morph(word(-1), ":D", False, not bool(re.search("(?i)^(?:s(?:ans|ous)|non)$", \1)))
+    ->> \1-\2                                                                                       # Il manque probablement un trait d’union.
+
+TEST: il a pris une balle dans l’{{arrière train}}.
+TEST: Ce {{sans gêne}} mérite une bonne leçon
+
+
+__[i]/tu(tu_mots_composés)__
+    (attrape|garde|porte|brise|cache|casse|chauffe|contre|coupe|cure|croque|entre|essuie|lance|lave|lève|marque|pare|passe|perce|pèse|porte|poste|pousse|presse|protège|ramasse|serre|taille|tire|tourne|traîne|vice|vide) ({w1})  @@0,$
+    <<- spell(\1+"-"+\2) and analyse(\1+"-"+\2, ":N", False) and morph(word(-1), ":(?:D|V0e)", False, True)
+        and not (morph(\1, ":G", False) and morph(\2, ":[GYB]", False))
+    ->> \1-\2                                                                                       # Il manque probablement un trait d’union.
+
+TEST: ce sont des {{lève tard}}.
+
+
+### Tri 1
+__[i]/tu(tu_à_tout_va)__                    [àa] tout vas? <<- ->> à tout-va                        # Il manque un trait d’union.
+__[i]/tu(à_la_va_vite)__                    [àa] la vas? vite <<- ->> à la va-vite                  # Il manque un trait d’union.
+__[i]/tu(tu_aller_retour)__                 allers? retours? <<- ->> =\0.replace(" ", "-")          # Il manque un trait d’union.
+__[i]/tu(tu_arc_en_ciel)__                  arcs? en ciel <<- ->> =\0.replace(" ", "-")             # Il manque les traits d’union.
+__[i]/tu(tu_après_demain)__                 après demain <<- ->> après-demain                       # Il manque un trait d’union.
+__[i]/tu(tu_au_préposition)__               au (delà|dehors|desso?us|devant) @@$ <<- ->> au-\1      # Il manque un trait d’union.
+__[i]/tu(tu_avant_hier)__                   avant hier <<- ->> avant-hier                           # Il manque un trait d’union.
+__[i]/tu(tu_bouche_à_oreille_bouche)__      bouche à (?:bouche|oreilles?) <<- morph(word(-1), ":D", False) ->> =\0.replace(" ", "-") # Il manque les traits d’union.
+__[i]/tu(tu_c_est_à_dire)__                 c’est [àa] dire <<- ->> c’est-à-dire                    # Il manque les traits d’union.
+__[i]/tu(tu_chef_d_œuvre_lieu)__            chef (lieu|d’œuvre) @@$ <<- ->> chef-\1                 # Il manque un trait d’union.
+__[i]/tu(tu_celui_celle_là_ci)__
+    ce(?:lles?|lui|ux) (?:là|[cs]i)
+    <<- not (\0.endswith("si") and morph(word(1), ":[AW]", False))
+    ->> =\0.replace(" ", "-").replace("si", "ci")                                                   # Il manque un trait d’union.
+__[i]/tu(tu_centre_ville)__                 centres? villes? <<- ->> centre-ville|centres-villes    # Il manque un trait d’union.
+__[i]/tu(tu_ci_dessous_devant_contre)__     ci (desso?us|devant|contre) @@$ <<- ->> ci-\1           # Il manque un trait d’union.
+__[i]/tu(tu_de_ci_de_là)__                  de ci,? de là <<- ->> de-ci de-là|de-ci, de-là          # Il manque les traits d’union.
+__[i]/tu(tu_en_contre_bas_partie)__     en contre (bas|partie) @@$ <<- ->> en contre\1|en contre-\1 # Mettez un trait d’union ou soudez.
+__[i]/tu(tu_en_contrepoint)__           en (contre[- ]point) @@$ <<- -1>> contrepoint               # Soudez.
+__[i]/tu(tu_état_major)__               état major <<- ->> état-major                               # Il manque un trait d’union.
+__[i]/tu(tu_grand_chose)__              grand chose <<- ->> grand-chose                             # Il manque un trait d’union.
+__[i]/tu(tu_grand_père_mère)__          grands? (?:père|mère)s? <<- ->> =\0.replace(" ", "-")       # Il manque un trait d’union.
+__[i]/tu(tu_ici_bas)__                  ici bas <<- ->> ici-bas                                     # Il manque un trait d’union.
+__[i]/tu(tu_jusque_là)__                jusque là <<- ->> jusque-là                                 # Il manque un trait d’union.
+__[i]/tu(tu_là_adverbe)__       là (bas|haut|desso?us|dedans|devant|derrière) @@3 <<- ->> là-\1     # Il manque un trait d’union.
+__[i]/tu(tu_n_est_ce_pas)__             n’est(?: ce[ -]pas|-ce-pas) <<- ->> n’est-ce pas            # Un trait d’union.
+__[i]/tu(tu_nord_sud_ouest)__           (nord|sud) ouest @@0 <<- ->> \1-ouest                       # Il manque un trait d’union.
+__[i]/tu(tu_nord_sud_est)__             (nord|sud) est @@0 <<- isEnd() ->> \1-est                   # Il manque un trait d’union.
+__[i]/tu(tu_outre_mer)__                outre mer <<- ->> outre-mer                                 # Il manque un trait d’union.
+__[i]/tu(tu_ouï_dire)__                 ou[iï] dire <<- morph(word(-1), ":G") ->> ouï-dire          # Il manque un trait d’union.
+__[i]/tu(tu_par_préposition)__
+    par (desso?us|devant|delà|derrière|dehors|dedans|devers)  @@$
+    <<- ->> par-\1                                                                                  # Il manque un trait d’union.
+__[i]/tu(tu_par_ci_par_là)__            par ci,? par là <<- ->> par-ci par-là|par-ci, par-là        # Trait(s) d’union manquant(s).
+__[i]/tu(tu_prêt_à_porter)__
+    (prêts?) à porter  @@0
+    <<- before(r"(?i)\b(?:les?|du|des|un|ces?|[mts]on) +") ->> \1-à-porter                          # Il manque les traits d’union.
+__[i]/tu(tu_plate_forme)__  plates? formes? <<- ->> plate-forme|plates-formes|plateforme|plateformes    # Il manque un trait d’union. Vous pouvez aussi souder les deux mots.
+__[i]/tu(tu_quelques_uns_unes)__       quelques (une?s) @@$ <<- ->> quelques-\1                     # Il manque un trait d’union.
+__[i]/tu(tu_plus_moins_values)__       (plus|moins) (values?)  @@0,$  <<- ->> \1-\2                 # Il manque un trait d’union.
+__[i]/tu(tu_rez_de_chaussée)__         rez de chaussées? <<- ->> rez-de-chaussée                    # Il manque un trait d’union.
+__[i]/tu(tu_science_fiction)__         science fiction <<- ->> science-fiction                      # Il manque un trait d’union.
+__[i]/tu(tu_stock_option)__            stock options? <<- ->> =\0.replace(" ", "-")                 # Il manque un trait d’union.
+__[i]/tu(tu_soi_disant)__              soi disant
+    <<- not ( morph(word(-1), ":R", False) and after("^ +qu[e’]") ) ->> soi-disant                  # Il manque un trait d’union.
+__[i]/tu(tu_sous_jacent)__             sous (jacente?s?) @@$ <<- ->> sous-\1                        # Il manque un trait d’union.
+# sur-mesures
+__[i]/tu(tu_vice_président_roi)__      vice (présidente?s?|rois?) @@$ <<- ->> vice-\1               # Il manque un trait d’union.
+__[i]/tu(tu_vis_à_vis)__               vis [àa] vis <<- ->> vis-à-vis                               # Il manque les traits d’union.
+__[i]/tu(tu_week_end)__                week (ends?) @@$ <<- ->> week-\1                             # Il manque un trait d’union.
+
+TEST: Ils font des tests {{à tout va}}
+TEST: on a fait {{à la va vite}}…
+TEST: marre de faire des {{allers retours}}
+TEST: {{le}} {{bouche à oreille}}
+TEST: à ce {{moment là}}                                                        ->> moment-là
+TEST: une {{plus value}}                                                        ->> plus-value
+TEST: Il est {{en-dessous}} de tout.                                            ->> en dessous
+TEST: Ils sont {{en-deçà}} de tout                                              ->> en deçà
+TEST: {{Là bas}}.                                                               ->> Là-bas
+TEST: {{Au dessus}}                                                             ->> Au-dessus
+TEST: {{ci dessus}}                                                             ->> ci-dessus
+TEST: {{par dessus}}                                                            ->> par-dessus
+TEST: {{au delà}}                                                               ->> au-delà
+TEST: {{ci devant}}.                                                            ->> ci-devant
+TEST: Il faisait froid cet {{hiver la}}.                                        ->> hiver-là
+TEST: {{Ceux la}} vont à la pêche.                                              ->> Ceux-là
+TEST: {{en contre bas}}
+TEST: mes deux {{grands pères}} sont décédés
+TEST: elles vont viennent {{de ci, de là}}.
+TEST: mais {{celles là}} sont différentes.
+TEST: seulement par {{ouï dire}}.
+TEST: ne vois-tu pas que c’est un {{chef d’œuvre}} ?
+TEST: Mieux qu’{{avant hier}}.
+TEST: nous irons là-bas {{après demain}}.
+TEST: L’{{état major}} n’a pas encore tranché la question.
+TEST: {{ici bas}}, n’attends rien de bon, à moins que…
+TEST: un bel enfoiré, {{c’est à dire}} un hypocrite
+TEST: {{jusque là}}, tout va bien
+TEST: regarde l’{{arc en ciel}}
+TEST: ils sont allés au {{centre ville}}.
+TEST: Il ne connaît pas {{grand chose}} à tout ça.
+TEST: en {{contre point}},
+TEST: {{Quelques unes}} sont très habiles.
+TEST: Tout ce que nous faisons {{par ci, par là}}.
+TEST: La papesse du {{prêt à porter}} viendra demain.
+TEST: sur cette {{plate forme}}, rien ne fonctionne
+TEST: Un énorme {{plus value}}.
+TEST: Habiter au {{rez de chaussée}}, quelle horreur.
+TEST: {{Apporte moi}} ce dictionnaire.                  ->> Apporte-moi
+TEST: C’est de la {{science fiction}}.
+TEST: Tout ce {{soi disant}} esprit religieux
+TEST: {{sous jacent}}                                   ->> sous-jacent
+TEST: Il a été nommé {{vice président}}
+TEST: Que vas-tu faire {{vis à vis}} d’eux              ->> vis-à-vis
+TEST: un super {{week end}}                             ->> week-end
+TEST: ils sont partis {{outre mer}}
+TEST: elles sont allées au {{sud ouest}}
+TEST: {{nord est}}
+TEST: des {{stock options}}
+TEST: Un autre chantier important, celui si sensible de la préservation des données personnelles des élèves
+
+# l’ à
+__[i]/tu(tu_l_à)__
+    l’(à (?:côté|coup|peu[ -]près|à[ -]pic|plat[ -]ventrisme|propos|valoir))  @@2
+    <<- -1>> =\1.replace(" ", "-")                                                                  # Mettez des traits d’union pour ces noms communs.
+
+TEST: l’{{à propos}} n’est pat si facile à acquérir.
+
+
+# est-ce … ?
+__[i]/tu(tu_est_ce)__
+    (?<![cCdDlL][’'])(est ce) ({w_2})  @@0,$
+    <<- morphex(\2, ":", ":N.*:[me]:[si]|>qui/") and morph(word(-1), ":Cs", False, True)
+    -1>> est-ce                                                                                     # S’il s’agit d’une interrogation, il manque un trait d’union.
+
+TEST: {{est ce}} que c’est grave ?                                              ->> est-ce
+TEST: qu’{{est ce}} que c’est ?                                                 ->> est-ce
+TEST: elles reviendront, {{n’est ce pas}} ?
+TEST: nous en sommes à l’étape où nous voulons définir ce qu’est ce projet
+
+
+### Tri 2
+__[i]/tu(tu_beaux_arts)__       (?:[ld]es|aux) (beaux arts) @@$ <<- -1>> beaux-arts                 # Il manque un trait d’union.
+__[i]/tu(tu_basket_volley)__    (basket|volley) ball @@0 <<- ->> \1-ball                            # Il manque un trait d’union.
+__[i]/tu(tu_pronom_même)__      (lui|elle|[mts]oi|vous) même @@0 <<- not after("^ +s(?:i |’)") ->> \1-même  # Il manque un trait d’union si “même” se rapporte à “\1”.|https://fr.wiktionary.org/wiki/moi-m%C3%AAme
+__[i]/tu(tu_pronom_mêmes)__     (nous|vous|eux|elles) mêmes @@0 <<- ->> \1-mêmes                                        # Il manque un trait d’union.
+__[i]/tu(tu_va_et_vient)__      (?:[lcd]es?|un|[mts]on|leurs?|[nv]os|quels?) (vas? et vien[ts]) @@$ <<- -1>> va-et-vient  # Il manque les traits d’union.
+
+TEST: les {{beaux arts}}
+TEST: je déteste le {{basket ball}}
+TEST: {{Lui même}}                                    ->> Lui-même
+TEST: {{eux mêmes}}.                                  ->> eux-mêmes
+TEST: un {{va et vient}} incessant me casse la tête
+
+
+### Noms propres
+__[u]/tu(tu_Royaume_Uni)__      Royaume Uni <<- ->> Royaume-Uni             # Il manque un trait d’union (s’il s’agit de l’État englobant la Grande-Bretagne et l’Irlande du Nord).
+__[u]/tu(tu_Grande_Bretagne)__  Grande Bretagne <<- ->> Grande-Bretagne     # Il manque un trait d’union (s’il s’agit de l’État englobant l’Angleterre, l’Écosse et le pays de Galles).
+__[u]/tu(tu_Pays_Bas)__                 (?:[ld]es|aux) (Pays Bas) @@$ <<- -1>> Pays-Bas                         # Il manque un trait d’union.
+__[u]/tu(tu_Aix_en_Provence)__          Aix en Provence <<- ->> Aix-en-Provence                                 # Il manque un trait d’union.
+__[u]/tu(tu_Bosnie_Herzégovine)__       Bosnie Herzégovine <<- ->> Bosnie-Herzégovine                           # Il manque un trait d’union.
+__[u]/tu(tu_Charente_Maritime)__        Charente Maritime <<- ->> Charente-Maritime                             # Il manque un trait d’union.
+__[u]/tu(tu_Clermont_Ferrand)__         Clermont Ferr?an[dt] <<- ->> Clermont-Ferrand                           # Il manque un trait d’union.
+__[u]/tu(tu_Colombie_Britannique)__     Colombie Britannique <<- ->> Colombie-Britannique                       # Il manque un trait d’union.
+__[u]/tu(tu_États_Unis)__               États Unis <<- ->> États-Unis                                           # S’il s’agit des USA, il manque un trait d’union.
+__[u]/tu(tu_Franche_Comté)__            Franche Comté <<- ->> Franche-Comté                                     # Il manque un trait d’union.
+__[u]/tu(tu_Haute_Département)__        Haute (Garonne|Loire|Marne|Normandie|Corse|Vienne) @@$ <<- ->> Haute-\1 # Il manque un trait d’union.
+__[u]/tu(tu_Île_de_France)__            [ÎI]le [dD]e France <<- ->> Île-de-France                               # Il manque les traits d’union.
+__[u]/tu(tu_Maison_Blanche)__           Maison Blanche <<- ->> Maison-Blanche                           # Il manque un trait d’union.
+__[u]/tu(tu_Moyen_Orient)__             Moyen Orient <<- ->> Moyen-Orient                               # Il manque un trait d’union.
+__[u]/tu(tu_Nouveau_Brunswick)__        Nouveau Brunswick <<- ->> Nouveau-Brunswick                     # Il manque un trait d’union.
+__[u]/tu(tu_Nouvelle_Qqch)__            Nouvelle (Zélande|Calédonie|Orléans) @@$ <<- ->> Nouvelle-\1    # Il manque un trait d’union.
+__[u]/tu(tu_Pas_de_Calais)__            Pas de Calais <<- ->> Pas-de-Calais                             # Il manque les traits d’union.
+__[u]/tu(tu_Rhône_Alpes)__              Rhône Alpes <<- ->> Rhône-Alpes                                 # Il manque les traits d’union.
+__[u]/tu(tu_Saône_et_Loire)__           Saône et Loire <<- ->> Saône-et-Loire                           # Il manque un trait d’union.
+__[u]/tu(tu_Jésus_Christ)__             Jésus Christ <<- ->> Jésus-Christ                               # Il manque un trait d’union.
+__[u]/tu(tu_Jean_prénom)__
+    Jean (Baptiste|Claude|François|Jacques|Louis|Luc|Marc|Marie|Michel|Paul|Philippe|Pierre)  @@$
+    <<- ->> Jean-\1                                                                                 # Il manque un trait d’union.
+__[u]/tu(tu_Marie_Prénom)__
+    Marie (Ange|Agnès|Anne|Antoinette|Cécile|Chantal|Charlotte|Christine|Claire|Claude|Dominique|France|Françoise|Hélène|Jeanne|José|Josèphe|Line|Louise|Madeleine|Noëlle|Odile|Paule|Pierre|Rose|Thérèse)  @@$
+    <<- ->> Marie-\1                                                                                # Il manque un trait d’union.
+__[s]/tu(tu_St_Ste_Bidule)__
+    ((Ste?) )[A-ZÉÈÎ]\w+ @@0,0
+    <<- -1>> \2-
+    # Il manque un trait d’union s’il s’agit d’une église, d’une cité, d’une communauté… S’il s’agit d’une personne, écrivez « saint(e) » sans majuscule, sans trait d’union.
+
+TEST: Émigrer au {{Royaume Uni}}
+TEST: Étudier en {{Grande Bretagne}}
+TEST: Vivre aux {{Pays Bas}}
+TEST: Il passe par {{Aix en Provence}}
+TEST: Qui se souvient de la {{Bosnie Herzégovine}} ?
+TEST: en {{Charente Maritime}}
+TEST: À {{Clermont Ferrand}}
+TEST: habiter la {{Colombie Britannique}}
+TEST: Il fait son stage étudiant aux {{États Unis}}
+TEST: Des fromages délicieux de {{Franche Comté}}
+TEST: La {{Haute Garonne}}
+TEST: L’{{Île de France}} est surpeuplée.
+TEST: Un nouveau président à la {{Maison Blanche}}
+TEST: La guerre au {{Moyen Orient}}
+TEST: Il ne connaît au {{Nouveau Brunswick}}
+TEST: Elle a visité la {{Nouvelle Orléans}}
+TEST: Vivre dans le {{Pas de Calais}}
+TEST: Des vacances en {{Rhône Alpes}}
+TEST: Elle déménage en {{Saône et Loire}}
+TEST: {{Jésus Christ}}, dernier héros de l’Antiquité
+TEST: Elle a quitté {{Jean Paul}}.
+TEST: {{Marie Hélène}} s’est perdue dans le dédale
+TEST: Elle va prier à {{Ste }}Catherine.
+
+
+### nombres
+__[i]/tu(tu_nombres)__
+    (?:dix|trente|quarante|cinquante|soixante|septante|octante|huitante|nonante) (?:deux|trois|six|sept|huit|quatre?|cinqu?|neu[fv])(?:ièmes?|)
+    <<- ->> =\0.replace(" ", "-")                                                                   # Il manque un trait d’union.
+__[i]/tu(tu_nombres_vingt)__
+    vingts? (?:deux|trois|six|sept|huit|quatre?|cinqu?|neu[fv])(?:ièmes?|)
+    <<- not before("(?i)quatre $") ->> =\0.replace(" ", "-").replace("vingts", "vingt")             # Il manque un trait d’union.
+__[i]/tu(tu_nombres_soixante)__
+    soixante (?:douze?|treize?|quatorze?|quinze?|seize?|dix(?:[- ]sept|[- ]huit|[- ]neu[fv]|))(?:ièmes?|)
+    <<- ->> =\0.replace(" ", "-")                                                                   # Trait(s) d’union manquant(s).
+__[i]/tu(tu_nombres_octante)__
+    quatre[- ]vingts? (?:une?|deux|trois|six|sept|huit|quatre?|onze?|douze?|treize?|quatorze?|quinze?|seize?|cinqu?|neu[fv]|dix(?:[- ]sept|[- ]huit|[- ]neu[fv]|))(?:ièmes?|)
+    <<- ->> =\0.replace(" ", "-").replace("vingts", "vingt")                                        # Trait(s) d’union manquant(s).
+#__[i]tu(tu_nombre et un)__
+#    (vingt|trente|quarante|cinquante|soixante|septante|octante|huitante|nonante)[- ](une?|unièmes?)
+#   ->> \1 et \2|\1-et-\2                                      # Il manque « et ». (Si vous suivez la réforme orthographique, utilisez des traits d’union.)
+
+TEST: Il en veut {{vingts}} !                 ->> vingt
+TEST: Y a-t-il {{quarante deux}} pages ?      ->> quarante-deux
+TEST: J’en veux {{quatre-vingt}} !            ->> quatre-vingts
+TEST: Non, {{quatre-vingts deux}} !           ->> quatre-vingt-deux
+TEST: {{Quatre vingts deux}}.                 ->> Quatre-vingt-deux
+TEST: cent {{mot}}                            ->> mots
+TEST: cinquante {{mot}}                       ->> mots
+TEST: mille cinquante {{mot}}                 ->> mots
+TEST: deux {{cents}} trois mots               ->> cent
+TEST: il y a {{cents}} mots                   ->> cent
+TEST: {{cents}} mots                          ->> cent
+TEST: ils mangent {{cents}} têtes             ->> cent
+TEST: deux {{tête}}                           ->> têtes
+TEST: {{soixante quatorze}}, c’est trop
+TEST: Mais {{vingt trois}}, c’est assez
+TEST: La poïesis, en grec, est ce qui permet de faire passer n’importe quoi du non-être à l’être
+
+
+### Pas de trait d’union
+__[i]/tu(tu_deux_tiers)__           deux-tiers <<- ->> deux tiers                                               # Pas de trait d’union.
+__[i]/tu(tu_en_bas_haut)__          en-(bas|haut|de(?:ssous|hors|çà)) @@$ <<- ->> en \1                         # Pas de trait d’union.
+__[i]/tu(tu_peu_à_peu)__            peu-[aà]-peu <<- ->> peu à peu                                              # Pas de trait d’union.
+__[i]/tu(tu_s_il_te_plaît)__        s’il-(?:[tm]e|[vn]ous)-pla[îi]t <<- ->> =\0.replace("-", " ")               # Pas de traits d’union.
+__[i]/tu(tu_tout_à_fait)__          tout-à-fait <<- ->> tout à fait                                             # Pas de trait d’union.
+__[i]/tu(tu_trois_quarts)__         trois-quarts? <<- not morph(word(-1), ":D", False, False) ->> trois quarts  # Pas de trait d’union.
+__[i]/tu(tu_parce_que)__            parce-que? <<- ->> =\0.replace("-", " ")                                    # Pas de trait d’union.
+__<i]/tu(tu_qqch_ça_aussi_donc)__   \b-(?:ç[aà]|aussi|donc) <<- ->> =\0.replace("-", " ")                       # Pas de trait d’union.
+__[i]/tu(tu_d_entre_pronom)__       d’entre-(?:nous|vous|eux|elles) <<- ->> =\0.replace("-", " ")               # Pas de trait d’union.
+
+TEST: J’en ai déjà fait les {{deux-tiers}}.
+TEST: {{en-haut}} de la montagne.
+TEST: On va finir par s’y faire, {{peu-à-peu}}.
+TEST: Venez vite, {{s’il-vous-plait}}.
+TEST: Elles sont {{tout-à-fait}} ravies.
+TEST: {{Trois-quarts}} des participantes y sont parvenues.
+TEST: {{Parce-qu}}’ils y croient plus que tout.
+TEST: Oui, ça{{-aussi}}.
+TEST: Peu {{d’entre-nous}} savent ce dont il s’agit.
+
+
+__[i]/tu(tu_y_attaché)__
+    (y[’-])({avoir_etre})(?:-(?:t-|)(?:ils?|elles?|je|tu|on|nous|vous)|) @@0,2
+    <<- morph(\2, ":V0|>en/", False) -1>> "y "                                                      # Ici, ni apostrophe, ni trait d’union.
+
+TEST: {{Y’}}a trop de malheureux sur Terre.
+TEST: {{Y’}}en a marre, de ces conneries.
+TEST: {{y-}}a-t-il des beignets ?                     ->> "y "
+
+
+__[i]/tu(tu_lorsque)__
+    lors que?
+    <<- not before(r"(?i)\bd[eè]s +$") ->> =\0.replace(" ", "")                                     # Attachez les deux mots.|https://fr.wiktionary.org/wiki/lorsque
+
+TEST: Elle y arriva {{lors qu}}’elle trouva l’astuce permettant l’ouverture de la porte.
+TEST: Dès lors qu’on sait comment s’y prendre, aucune raison de faillir.
+
+
+!!!! Virgules                                                                                     !!
+
+# Dialogues
+__[u]/virg(virgule_dialogue_après_nom_propre)__
+    ([A-ZÉÈ][\w-]+) (\w+-(?:moi|toi|l(?:ui|a|e(?:ur|s|))|nous|vous|je|tu|ils|elles))  @@0,$
+    <<- morphex(\1, ":M", ":G") and not morph(\2, ":N", False) and isStart()
+    -1>> \1,                                                                        # Dialogue ? Ajoutez une virgule pour mettre en incise la personne à qui s’adresse la réplique.
+
+TEST: {{Maria}} donnez-vous du temps ?
+TEST: {{Marion}} passe-moi le sel.
+TEST: {{Paul}} prends-lui la main.
+TEST: Alexandre tient-il ses généraux ?
+TEST: Alexandra vient-elle ?
+
+
+__[u]/virg(virgule_dialogue_avant_nom_propre)__
+    ({w1})(-l(?:es?|a)(?:-(?:[mt]oi|[nv]ous|lui|leur)|)) ([A-ZÉÈ][\w-]+)   @@0,*,$
+    <<- morph(\1, ":E", False) and morph(\3, ":M", False)
+    -2>> \2,                                                                        # Dialogue. Ajoutez une virgule pour mettre en incise la personne à qui s’adresse la réplique.
+
+TEST: viens et donne{{-le}} Paul.
+TEST: donne{{-le-moi}} Camille.
+TEST: donne-moi Alice.
+TEST: Tape-toi Patrick.
+
+
+__[u]/virg(virgule_après_verbe_COD)__
+    l(?:es?|a) ({w_2}(?:[ei]r|re)) ([A-ZÉÂÔÈ][\w-]+)  @@w,$
+    <<- morph(\1, ":Y", False) and morph(\2, ":M", False) and not morph(word(-1), ">à/", False, False)
+    -1>> \1,                                                                                        # Une virgule est probablement souhaitable.
+
+TEST: Tu vas les {{donner}} Rachel.
+TEST: Il va la {{tuer}} Paul.
+TEST: Cependant les promesses n’engagent que ceux qui les croient, comme aimait à le dire Jacques Chirac.
+
+
+
+!!!! Apostrophe manquante (2)                                                                     !!
+
+__<s>/typo(typo_apostrophe_manquante_audace2)__
+    ^ *([LDSNCJMTÇ] )[aeéiouhAEÉIOUHyîèêôûYÎÈÊÔÛ]  @@*
+    <<- option("mapos") -1>> =\1[:-1]+"’"                                                           # Il manque peut-être une apostrophe.
+
+TEST: __mapos__ {{L }}opinion des gens, elle s’en moquait.
+
+
+
+!!!! A / À: accentuation la préposition en début de phrase                                        !!
+
+__<s]/typo(typo_À_début_phrase1)__
+    ^ *(A) (?!t[’-](?:ils?|elles?|on))({w_2})  @@*,$
+    <<- morphex(\2, ":[GNAY]", ":(?:Q|3s)|>(?:priori|post[eé]riori|contrario|capella|fortiori)/")
+        or (\2 == "bientôt" and isEnd())
+    -1>> À                                                                                          # S’il s’agit de la préposition « à », il faut accentuer la majuscule.
+__<s>/typo(typo_À_début_phrase2)__
+    ^ *(A) [ldnms]’  @@*  <<- -1>> À                                                                # S’il s’agit de la préposition « à », il faut accentuer la majuscule.
+__<s>/typo(typo_À_début_phrase3)__
+    ^ *(A) t’(?!il |elle |ont? )  @@*  <<- -1>> À                                                   # S’il s’agit de la préposition « à », il faut accentuer la majuscule.
+
+TEST: {{A}} vaincre sans péril, on triomphe sans gloire.
+TEST: « {{A}} partir de maintenant, ce ne sera plus comme avant.
+TEST: — {{A}} n’en plus pouvoir
+TEST: — {{A}} t’emmener loin de tout ceci.
+TEST: {{A}} bientôt, mon ami.
+TEST: A bientôt fini son devoir.
+TEST: A priori, nul ne peut y parvenir sans une aide extérieure.
+TEST: A devient notre meilleure chance d’y parvenir.
+
+
+!!!! Accentuation des majuscules                                                                  !!
+
+__[u]/maj(maj_accents)__
+    E(?:tat|glise|co(?:le|nomie)|quipe|lectri(?:cité|que)|gal(?:ité|ement)|té)s? @@1
+    <<- ->> ="É"+\0[1:]                                                                            # Accentuez les majuscules.
+    <<- ~>> ="É"+\0[1:]
+
+TEST: Le budget de l’{{Etat}}.
+
+
+
+!!!
+!!!
+!!! Désambiguïsation                                                                              !!
+!!!
+!!!
+
+# mots grammaticaux
+__[i](d_dans)__
+    dans
+    <<- not morph(word(-1), ":D.*:p|>[a-z]+ièmes/", False, False) =>> select(\0, ":R")
+
+__[i](d_ton_son)__
+    (\w+) ([ts]on)  @@0,$
+    <<- morph(\1, ">(?:le|ce[st]?|ton|mon|son|quel(?:que|)s?|[nv]otre|un|leur|ledit|dudit)/") =>> exclude(\2, ":D")
+
+# Pronoms le/la/les
+__[i](d_je_le_la_les)__
+    je (l(?:e(?:ur|s|)|a)) @@$                  <<- not morph(word(-1), ":1s", False, False) =>> select(\1, ":Oo")
+__[i](d_tu_le_la_les)__
+    tu (l(?:e(?:ur|s|)|a)) @@$                  <<- not morph(word(-1), ":2s", False, False) =>> select(\1, ":Oo")
+__[i](d_il_elle_on_le_la_les)__
+    (?:il|elle|on) (l(?:e(?:ur|s|)|a)) @@$      <<- not morph(word(-1), ":3s", False, False) =>> select(\1, ":Oo")
+__[i](d_nous_le_la_les)__
+    nous (l(?:e(?:ur|s|)|a)) @@$                <<- not morph(word(-1), ":1p", False, False) =>> select(\1, ":Oo")
+__[i](d_vous_le_la_les)__
+    vous (l(?:e(?:ur|s|)|a)) @@$                <<- not morph(word(-1), ":2p", False, False) =>> select(\1, ":Oo")
+__[i](d_nous)__
+    (nous) ({avoir_etre}) @@0,$                 <<- not morph(\2, ":1p", False) =>> exclude(\1, ":Os")
+__[i](d_vous)__
+    (vous) ({avoir_etre}) @@0,$                 <<- not morph(\2, ":2p", False) =>> exclude(\1, ":Os")
+__[i](d_ils_elles_le_la_les)__
+    (?:ils|elles) (l(?:e(?:ur|s|)|a)) @@$       <<- not morph(word(-1), ":3p", False, False) =>> select(\1, ":Oo")
+__[i](d_ne_me_te_te_le_la_leur)__
+    [nmts]e (l(?:e(?:ur|s|)|a)) @@$             <<- =>> =select(\1, ":Oo")
+
+
+
+
+@@@@
+@@@@
+@@@@
+@@@@
+@@@@GRAPH: graphe1                                                                                 _
+@@@@
+@@@@
+@@@@
+@@@@
+
+
+# verbe
+__da_préverbes_verbes__
+    ne ?[le|la|l’|les|lui|leur|nous|vous]¿  (@:¬:[OX])
+        <<- =>> select(\1, ":V")
+
+    [n’|m’|t’|s’]  ?[en|y]¿  (@:¬:[OX])
+        <<- =>> select(\1, ":V")
+
+    [me|te|se]  ?[le|la|l’|les]¿  (*WORD)
+        <<- =>> select(\1, ":V")
+
+    j’ ?[en|y]¿  (*WORD)
+        <<- =>> select(\1, ":[123][sp]")
+
+    [je|il|ils|on]  ?[le|la|l’|les|lui|leur|nous|vous]¿  (@:¬:[OX])
+        <<- =>> select(\1, ":[123][sp]")
+
+    tu  ?[le|la|l’|les|lui|leur|nous|vous]¿  (@:¬:[OX])
+        <<- morph(<1, ":Cs|<start>") =>> select(\1, ":[123][sp]")
+
+    @:M  @:[123]s¬:Q
+        <<- \2.islower() and morph(<1, ":Cs|<start>") =>> select(\2, ":[123][sp]")
+
+    <start> @:M  @:(?:[123]s|Oo)|>ne/¬:A
+        <<- =>> =select(\2, ":M")
+
+    [que|qu’|qu|combien|pourquoi]  ¿[en|y]¿  (*WORD)
+        <<- =>> exclude(\1, ":E")
+
+
+__da_groupe_nominal__
+    aucun  @:[NA].*:[me]
+        <<- =>> exclude(\2, ":V")
+
+    [de|d’]  @:¬:[YD]
+        <<- =>> exclude(\2, ":V")
+
+    d’ [un|une]  *WORD
+        <<- =>> exclude(\3, ":V")
+
+    [des|chaque|quelque|quelques|cet|cette|mon|ma|ta|sa|mes|au|aux|nos|vos]  *WORD
+        <<- =>> exclude(\2, ":V")
+
+    de  [la|l’]  @:¬:Y
+        <<- =>> exclude(\3, ":V")
+
+    de [>telle|ce|cet|cette|ces|mon|ma|ta|sa|mes|tes|ses|notre|votre|plein|pleine]  *WORD
+        <<- =>> exclude(\3, ":V")
+
+    par  *WORD
+        <<- =>> exclude(\2, ":V[123]")
+
+    très  *WORD
+        <<- =>> exclude(\2, ":[123][sp]")
+
+    en tant que  *WORD
+        <<- =>> exclude(\4, ":[123][sp]")
+
+    bac + ~^\d\d?$
+        <<- ~>> ␣
+        <<- =>> define(\1, [":N:e:i"])
+
+
+TEST: il s’agit d’{{un}} {{anagramme}}
+TEST: nul ne sait qui arriva à ce pauvre Paul surpris par la pluie.
+TEST: elle finit par être très fière de son fils.
+TEST: en tant que président du conseil
+TEST: les bac +2 sont trop nombreux.
+TEST: c’est à n’y plus rien comprendre.
+
+
+!!
+!!
+!!!! Incohérences de base                                                                         !!
 !!
 !!
 
 ### double négation
-__[i](double_négation)__
-    pas (personne|aucune?|jamais)  @@4
-    <<- not morph(word(-1), ":D:[me]" ,False, False) ->> \1|pas, \1
-    # Double négation : les mots « pas \1 » ne devraient pas se succéder. Si ces mots appartiennent à des propositions distinctes, une virgule est peut-être préférable.
+__double_négation__
+    pas [personne|aucun|aucune|jamais]
+        <<- not morph(<1, ":D.*:[me]") ->> \1|pas, \1
+        # Double négation : les mots « pas \1 » ne devraient pas se succéder. Si ces mots appartiennent à des propositions distinctes, une virgule est peut-être préférable.
 
 TEST: Ce que tu ne fais {{pas jamais}}.
 
 
 ### incohérences globales (attention à la casse du 2e mot, car beaucoup de sigles peuvent tromper)
-__[s](incohérences_globales1)__
-    ([clmtsCLMTS]es|[nvNV]os) ([cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on)  @@0,$
-    <<- -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
-__[s](incohérences_globales2)__
-    ([cC]e(?:tte|t|)|[mtsMTS]a|[mM]on) ([cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on)  @@0,$
-    <<- -2>> =suggSimil(\2, ":[NA].*:[si]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+__incohérences_globales__
+    [ce|cet|cette|ma|ta|sa|mon] [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on]
+        <<- /conf/ not \1.isupper() and not \2.isupper()
+        -2>> =suggSimil(\2, ":[NA].*:[si]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+
+    [quel|quelle] [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on]
+        <<- /conf/ not \1.isupper() and not \2.isupper() and not value(<1, "|tel|telle|")
+        -2>> =suggSimil(\2, ":[NA].*:[si]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+
+    [ces|les|mes|tes|ces|nos|vos] [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on]
+        <<- /conf/ not \1.isupper() and not \2.isupper()
+        -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+
+    [quels|quelles] [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on]
+        <<- /conf/ not \1.isupper() and not \2.isupper() and not value(<1, "|tels|telles|")
+        -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+
+    des [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on]
+        <<- /conf/ not \1.isupper() -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                       # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+        <<- /conf/ __also__ -1>> de                                                                 # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
 
 TEST: {{Ces}} {{cette}} canaille qui nous a donné tant de fil à retordre.
 TEST: Mon {{il}} est une merveille.
+TEST: je ne sais {{des}} {{ses}} choses.
 
 
-__[s](incohérence_globale_au_qqch)__
-    ([aA]u) ({w2})  @@0,$
-    <<- not \2.isupper() >>>
-    <<- morph(\2, ">(?:[cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on|parce) ", False)
-    -2>> =suggSimil(\2, ":[NA].*:[si]", True)                                                       # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
-    <<- __else__ and morph(\2, ">quelle ", False) ->> auquel|auxquels|auxquelles                    # Incohérence. Soudez les deux mots.|https://fr.wiktionary.org/wiki/auquel
-    <<- __else__ and \2 == "combien" and morph(word(1), ":[AY]", False) -1>> ô                      # Incohérence probable.|https://fr.wiktionary.org/wiki/%C3%B4_combien
+__incohérence_au_qqch__
+    au  [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on|parce]
+        <<- /conf/ not \1.isupper() and not \2.isupper()
+        -2>> =suggSimil(\2, ":[NA].*:[si]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+
+    aux [ces|des|les|mes|ses|tes|nos|vos|ce|cet|cette|ma|ta|sa|mon|je|tu|il|ils|elle|elles|nous|vous|on|parce]
+        <<- /conf/ not \1.isupper() and not \2.isupper()
+        -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
+
+    [au|aux] [quel|quels|quelle|quelles]
+        <<- /conf/ ->> auquel|auxquels|auxquelles                                                   # Incohérence. Soudez les deux mots.|https://fr.wiktionary.org/wiki/auquel
+
+    [au|aux] combien  @:[AY]
+        <<- /conf/ -1:2>> ô combien                                                                 # Confusion probable.|https://fr.wiktionary.org/wiki/%C3%B4_combien
 
 TEST: au {{nos}} enfants.
 TEST: {{Au quel}} faut-il s’adresser ?
+TEST: ils jouent aux {{des}}.
+TEST: {{Aux quels}} a-t-il adressé sa requête. ?
+TEST: Des individus {{aux combien}} sensibles aux usages.
 TEST: Au MES, rien de nouveau.
 
 
-__[s](incohérence_globale_aux_qqch)__
-    ([aA]ux) ({w2})  @@0,$
-    <<- not \2.isupper() >>>
-    <<- morph(\2, ">(?:[cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on|parce) ", False)
-    -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                                                       # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
-    <<- __else__ and morph(\2, ">quelle ", False) ->> auxquels|auxquelles                           # Incohérence. Soudez les deux mots.|https://fr.wiktionary.org/wiki/auquel
-    <<- __else__ and \2 == "combien" and morph(word(1), ":[AY]", False) -1>> ô                      # Incohérence probable.|https://fr.wiktionary.org/wiki/%C3%B4_combien
-
-TEST: ils jouent aux {{des}}.
-TEST: {{Aux quels}} a-t-il adressé sa requête. ?
-TEST: Des individus {{aux}} combien sensibles aux usages.
-
-
-__[s](incohérences_globales3)__
-    ([dD]es) ([cdlmst]es|[nv]os|cettes?|[mts]a|mon|je|tu|ils?|elle?|[vn]ous|on)  @@0,$
-    <<- -2>> =suggSimil(\2, ":[NA].*:[pi]", True)                                                   # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
-    <<- -1>> de                                                                                     # Incohérence : les mots “\1” et “\2” ne devraient pas se succéder.
-
-TEST: je ne sais {{des}} {{ses}} choses.
-
-
-
-!!
-!!
-!!!! Style                                                                                          
-!!
-!!
-
-#__bs__  Mr <<- ->> M.                          # M. est l’usage courant pour “Monsieur”. « Mr » est l’abréviation ancienne, française.
+
+!!
+!!
+!!!! Style                                                                                        !!
+!!
+!!
 
 # à / en
-__[i]/bs(bs_en_à_ville)__
-    (en) A(?:gen|miens|ngers|jjacio|rles|vignon)  @@0
-    <<- -1>> à       # On utilise la préposition “à” avant les villes (à Avignon, à Arles…), la préposition “en” avant les régions (en Amérique, en Afrique…).
+__bs_en_à_ville__
+    en [Agen|Amiens|Angers|Ajjacio|Arles|Avignon]
+        <<- /bs/ -1>> à                             # On utilise la préposition “à” avant les villes (à Avignon, à Arles…), la préposition “en” avant les régions (en Amérique, en Afrique…).
 
 TEST: {{En}} Avignon
 TEST: {{En}} Agen
 
 
 # avoir été
-__[i]/bs(bs_avoir_été_chez)__
-    (?<!l’)({avoir}) été chez  @@0
-    <<- not re.search("(?i)^avoir$", \1) and morph(\1, ">avoir ", False)
-    ->> _                                                                                           # Tournure familière. Utilisez « être allé ».
+__bs_avoir_été_chez__
+    >avoir été chez
+        <<- /bs/ not value(<1, "|l’|") ->> _                                                        # Tournure familière. Utilisez « être allé ».
 
 TEST: J’{{ai été chez}} le coiffeur.
 TEST: Chez les intellectuels, le mot utopie n’a jamais été synonyme de folie, mais il l’a été pour l’homme de la rue.
+TEST: Saoul, je l’ai été chez mon ami, mais après ça allait mieux.
 
 
 # abyme / abîme
-__[i]/bs(bs_mise_en_abyme)__
-    mis\w+ en (ab[îi]mes?) @@$ <<- -1>> abyme
-    # Classiquement, on écrit plutôt « abyme » dans cette expression.|https://fr.wiktionary.org/wiki/mise_en_abyme
+__bs_mettre_en_abyme__
+    >mettre en [>abîme|>abime]
+        <<- /bs/ -3>> abyme
+        # Classiquement, on écrit plutôt “abyme” dans cette expression.|https://fr.wiktionary.org/wiki/mise_en_abyme
 
 TEST: La mise en {{abîme}}.
 
 
 # à date / jusqu’à date
-__[i]/bs(bs_à_date)__
-    ({etre}|m\w+) ([aà] date)  @@0,$  <<- morph(\1, ">(?:être|mettre) ", False) -2>> à jour         # Anglicisme incompris hors du Québec.
-__[i]/bs(bs_jusquà_date)__
-    jusqu [àa] date <<- ->> jusqu’ici|jusqu’à maintenant|jusqu’à ce jour|à ce jour                  # Anglicisme incompris hors du Québec.
+__bs_à_date__
+    [>être|>mettre] [a|à] >date
+        <<- /bs/ -2:3>> à jour                                                                      # Anglicisme incompris hors du Québec.
+
+    [jusqu’|jusqu] [à|a] >date
+        <<- /bs/ ->> jusqu’ici|jusqu’à maintenant|jusqu’à ce jour|à ce jour                         # Anglicisme incompris hors du Québec.
 
 TEST: être {{à date}}
 TEST: mettre {{a date}}
 TEST: {{jusqu’à date}}
 
 
 # incessamment sous peu
-__[i]/bs(bs_incessamment_sous_peu)__
-    incessamment +sous (peu[tx]?)  @@$
-    <<- not \1.endswith("u") -1>> peu                                                               # Confusion.|https://fr.wiktionary.org/wiki/sous_peu
-    <<- __else__ ->> sous peu|bientôt|dans peu de temps|d’un moment à l’autre                       # Expression impropre.|https://fr.wiktionary.org/wiki/incessamment_sous_peu
+__bs_incessamment_sous_peu__
+    incessamment >sou [peu|peux|peut]
+        <<- /bs/ not \3.endswith("u") -3>> peu                                                      # Confusion.|https://fr.wiktionary.org/wiki/sous_peu
+        <<- /bs/ not \2.endswith("s") -2>> sous                                                     # Confusion.|https://fr.wiktionary.org/wiki/sous_peu
+        <<- /bs/ __else__ ->> sous peu|bientôt|dans peu de temps|d’un moment à l’autre              # Expression impropre.|https://fr.wiktionary.org/wiki/incessamment_sous_peu
 
 TEST: ils arrivent {{incessamment sous peu}}.
 
 
 # pire
-__[i]/bs(bs_pire)__          (?:moins|aussi|plus) (pires?) @@$ <<- -1>> mauvais|mauvaise|mauvaises  # Tournure erronée. Utilisez « mauvais ».|http://www.academie-francaise.fr/plus-pire-moins-pire
-__[i]/bs(bs_de_mal_en_pis)__ de mal en pires? <<- ->> de mal en pis                                 # Tournure erronée. Utilisez « de mal en pis ».
-__[i]/bs(bs_au_pis_aller)__  au pire aller <<- ->> au pis aller                                     # Tournure erronée. Utilisez « au pis aller ».
+__bs_pire__
+    [moins|aussi|plus] [>pire]
+        <<- /bs/ -2>> mauvais|mauvaise|mauvaises                    # Tournure erronée. Utilisez « mauvais ».|http://www.academie-francaise.fr/plus-pire-moins-pire
+
+    de mal en >pire
+        <<- /bs/ ->> de mal en pis                                  # Tournure erronée. Utilisez « de mal en pis ».
+
+    au pire aller
+        <<- /bs/ ->> au pis aller                                   # Tournure erronée. Utilisez « au pis aller ».
 
 TEST: c’est plus {{pire}} que tout.
 TEST: il est moins {{pire}} que l’autre.
 TEST: elles sont aussi {{pires}} que les autres.
 TEST: ils vont {{de mal en pire}}
 TEST: {{Au pire aller}}, on s’en passera.
 
 
 # pour ne pas que
-__[i]/bs(bs_pour_ne_pas_que)__
-    pour ne pas que?  <<- ->> _
-    # Tournure familière. Écrivez “pour qu’il ne vienne pas” plutôt que “pour ne pas qu’il vienne.”|http://www.academie-francaise.fr/pour-pas-que-au-lieu-de-pour-que-ne-pas
+__bs_pour_ne_pas_que__
+    pour ne pas [que|qu’|qu]
+        <<- /bs/ ->> _
+        # Tournure familière. Écrivez “pour qu’il ne vienne pas” plutôt que “pour ne pas qu’il vienne.”|http://www.academie-francaise.fr/pour-pas-que-au-lieu-de-pour-que-ne-pas
 
 TEST: Nous y sommes allés {{pour ne pas qu}}’elle se sente seule.
 
 
 # très / trop
-__[i]/bs(bs_très_trop_superflu)__
-    tr(ès|op) (beaucoup|assez|mieux|pire|meilleur|délicieux|plus|moins) @@2,$ <<- ->> \2            # « tr\1 » est superflu.
+__bs_très_trop_superflu__
+    [très|trop] [beaucoup|assez|mieux|pire|meilleur|délicieux|plus|moins]
+        <<- /bs/ ->> \2                                                                             # Avec “\2”, “\1” est superflu.
 
 TEST: Je l’aime {{très beaucoup}}.
 
 
 # novlangue
-__[i]/bs(bs_vidéoprotection)__
-    vidéo-?protection(s|)  @@$
-    <<- ->> vidéosurveillance\1|télésurveillance\1|surveillance\1 des populations
-    # Novlangue. Double pensée. Utilisez un terme plus approprié.|http://fr.wikipedia.org/wiki/Doublepens%C3%A9e
+__bs_vidéoprotection__
+    >vidéoprotection
+    >vidéo-protection
+        <<- /bs/ ->> vidéosurveillance|télésurveillance|surveillance des populations
+        # Novlangue. Double pensée. Utilisez un terme plus approprié.|http://fr.wikipedia.org/wiki/Doublepens%C3%A9e
 
-TEST: {{vidéo-protection}}
+TEST: les méfaits de la {{vidéoprotection}}
 
 
 #__[i]/bs__  (tomb\w+) dans les pommes <<- ->> \1 dans les pâmes                                    # « Tomber dans les pâmes » est l’ancienne tournure.
 
-# malgré que
-__[i]/bs(bs_malgré_que)__
-    malgré (que?)  @@7
-    <<- not after_chk1(r" \w[\w-]+ en ([aeo][a-zû]*)", ":V0a")
-    ->> bien \1                                                                                     # Tournure populaire. Utilisez « bien que ».
+__bs_malgré_que__
+    malgré que
+        <<- /bs/ not after(r" en (?:a|aie|aies|ait|eut|eût|aura|aurait|avait)\b")
+        ->> bien que|quoique                                                                        # “Malgré que” est une tournure populaire. Utilisez “bien que” ou “quoique”.
+
+    malgré [qu’|qu]
+        <<- /bs/ not after(r" en (?:a|aie|aies|ait|eut|eût|aura|aurait|avait)\b")
+        ->> bien qu’|quoiqu’                                                                        # “Malgré que” est une tournure populaire. Utilisez “bien que” ou “quoique”.
 
 TEST: {{Malgré que}} je sois fou.
 
 
-######### Expressions impropres
-
 #([mts]e|[nv]ous) (rappel\w+) (de) <<- word(1) != "ne" and not morph(word(1), ":V")
 #   -3>> _                                                     # Expression impropre. « Se rappeler quelque chose » ou « Se souvenir de quelque chose ».
 #Se rappelle de l’amour
 
 #enjoindre à qqn de faire qqch
 
 
-!!
-!!
-!!!! Pléonasmes                                                                                     
-!!
-!!
-
-__[i]/pleo(pleo_abolir)__               (abol\w+) (?:absolument|entièrement|compl[èé]tement|totalement) @@0 <<- morph(\1, ">abolir ", False) ->> \1         # Pléonasme.
-__[i]/pleo(pleo_acculer)__              (accul\w+) aux? pieds? du mur @@0 <<- morph(\1, ">acculer ", False) ->> \1                                          # Pléonasme.
-__[i]/pleo(pleo_achever)__              (ach[eè]v\w+) (?:absolument|entièrement|compl[èé]tement|totalement) @@0 <<- morph(\1, ">achever ", False) ->> \1    # Pléonasme.
-__[i]/pleo(pleo_en_cours)__             actuellement en cours <<- not after(r" +de?\b") ->> en cours                                            # Pléonasme.
-__[i]/pleo(pleo_en_train_de)__          (actuellement en train) d(?:e(?! nuit)|’{w_2}) @@0 <<- -1>> en train                                    # Pléonasme.
-__[i]/pleo(pleo_ajouter)__              (ajout\w+) en plus @@0 <<- ->> \1                                                                       # Pléonasme.
-__[i]/pleo(pleo_apanage)__              (apanages?) exclusifs? @@0 <<- ->> \1                                                                   # Pléonasme.
-__[i]/pleo(pleo_applaudir)__            (applaudi\w+) des deux mains @@0 <<- ->> \1                                                             # Pléonasme.
-__[i]/pleo(pleo_aujourd_hui)__          au jour d’aujourd’hui <<- ->> aujourd’hui                                                               # Pléonasme.
-__[i]/pleo(pleo_avancer)__              (avan[cç]\w+) en avant @@0 <<- morph(\1, ">avancer ", False) ->> \1                                     # Pléonasme.
-__[i]/pleo(pleo_s_avérer)__             s’av([éè]r\w+) vrai(e?s?) @@4,$ <<- ->> s’av\1 exact\2                                                  # Pléonasme.
-__[i]/pleo(pleo_avéré)__                (avérée?s?) vraie?s? @@0 <<- ->> \1                                                                     # Pléonasme.
-__[i]/pleo(pleo_avenir)__               avenir devant (?:lui|[mts]oi|eux|[nv]ous) <<- morph(word(-1), ":A|>un", False) ->> avenir               # Pléonasme.
-__[i]/pleo(pleo_bourrasque)__           (bourrasques?) de vent @@0 <<- ->> \1                                                                   # Pléonasme.
-__[i]/pleo(pleo_car_en_effet)__         car en effet <<- ->> car|en effet                                                                       # Pléonasme.
-__[i]/pleo(pleo_cirrhose)__             (cirrhoses?) du foie @@0 <<- ->> \1                                                                     # Pléonasme.
-__[i]/pleo(pleo_collaborer)__           (collabor\w+) ensemble @@0 <<- morph(\1, ">collaborer ", False) ->> \1                                  # Pléonasme.
-__[i]/pleo(pleo_comme_par_exemple)__    comme par exemple <<- ->> comme|par exemple                                                             # Pléonasme.
-__[i]/pleo(pleo_comparer)__             (compar\w+) entre (?:eux|elles) @@0 <<- morph(\1, ">comparer ", False) ->> \1                           # Pléonasme.
-__[i]/pleo(pleo_contraindre)__          (contrai\w+) malgré (?:soi|eux|lui|moi|elle|toi) @@0 <<- morph(\1, ">contraindre ", False) ->> \1       # Pléonasme.
-__[i]/pleo(pleo_descendre)__            (descend\w+) en bas(?! de) @@0 <<- ->> \1                                                               # Pléonasme.
-__[i]/pleo(pleo_dessiner)__             (dessin\w+) un dessin @@0 <<- ->> \1                                                                    # Pléonasme.
-__[i]/pleo(pleo_dorénavant)__           à (?:partir|compter) de dorénavant <<- ->> dorénavant|à partir de maintenant                            # Pléonasme.
-__[i]/pleo(pleo_donc_par_conséquent)__  donc par conséquent <<- ->> donc|par conséquent|c’est pourquoi                                          # Pléonasme.
-__[i]/pleo(pleo_enchevêtrer)__          (enchevêtr\w+) les uns dans les autres @@0 <<- morph(\1, ">enchevêtrer ", False) ->> \1                 # Pléonasme.
-__[i]/pleo(pleo_entraider)__            (entraid\w+) (?:mutuellement|les uns les autres) @@0 <<- morph(\1, ">entraider ", False) ->> \1         # Pléonasme.
-__[i]/pleo(pleo_entraide)__             (entraides?) mutuelles? @@0 <<- ->> \1                                                                  # Pléonasme.
-__[i]/pleo(pleo_erreur)__               (erreurs?) involontaires? @@0 <<- ->> \1                                                                # Pléonasme.
-__[i]/pleo(pleo_étape)__                (étapes?) intermédiaires? @@0 <<- ->> \1                                                                # Pléonasme.
-__[i]/pleo(pleo_hasard)__               (hasards?) imprévus? @@0 <<- ->> \1                                                                     # Pléonasme.
-__[i]/pleo(pleo_hémorragie)__           (hémorragies?) de sang @@0 <<- ->> \1                                                                   # Pléonasme.
-__[i]/pleo(pleo_joindre)__              (join\w+) ensemble @@0 <<- morph(\1, ">joindre ") ->> \1|mettre ensemble                                # Pléonasme.
-__[i]/pleo(pleo_lever)__                lever debout <<- ->> lever                                                                              # Pléonasme.
-__[i]/pleo(pleo_mais_qqch)__            mais (cependant|pourtant|toutefois) @@5 <<- ->> mais|cependant|pourtant|toutefois                       # Pléonasme.
-__[i]/pleo(pleo_marche)__               (marches?) à pieds? @@0 <<- ->> \1                                                                      # Pléonasme.
-__[i]/pleo(pleo_méandre)__              (méandres?) sinueux @@0 <<- ->> \1                                                                      # Pléonasme.
-__[i]/pleo(pleo_media)__                (m[eé]dias?) d’informations? @@0 <<- ->> \1                                                             # Pléonasme.
-__[i]/pleo(pleo_monopole)__             (monopoles?) exclusifs? @@0 <<- ->> \1                                                                  # Pléonasme.
-__[i]/pleo(pleo_monter)__               (mont\w+) en haut(?! d[eu’]) @@0 <<- morph(\1, ">monter ", False) ->> \1                                # Pléonasme.
-__[i]/pleo(pleo_opportunité)__          (opportunités?) à saisir @@0 <<- ->> \1                                                                 # Pléonasme.
-__[i]/pleo(pleo_orage)__                (orages?) électriques? @@0 <<- ->> \1                                                                   # Pléonasme.
-__[i]/pleo(pleo_jumelles)__             paires? de jumelles? <<- ->> jumelles                                                                   # Pléonasme.
-__[i]/pleo(pleo_panacée)__              (panacées?) universelles? @@0 <<- ->> \1|remède universel                                               # Pléonasme.
-__[i]/pleo(pleo_perspective)__          (perspectives?) d’avenir @@0 <<- ->> \1                                                                 # Pléonasme.
-__[i]/pleo(pleo_balbutiement)__         premiers? (balbutiements?) @@$ <<- ->> \1                                                               # Pléonasme.
-__[i]/pleo(pleo_priorité)__             premières? (priorités?) @@$ <<- ->> \1                                                                  # Pléonasme.
-__[i]/pleo(pleo_projet1)__              (projets?) futurs? @@0 <<- ->> \1                                                                       # Pléonasme.
-__[i]/pleo(pleo_projet2)__              futurs? (projets?) @@$ <<- ->> \1                                                                       # Pléonasme.
-__[i]/pleo(pleo_prototype)__            (prototypes?) expérimenta(?:l|ux) @@0 <<- ->> \1                                                        # Pléonasme.
-__[i]/pleo(pleo_rénover)__              (rénov\w+) à neuf @@0 <<- morph(\1, ">rénov(?:er|ation) ", False) ->> \1                                # Pléonasme.
-__[i]/pleo(pleo_puis_qqch)__            puis (?:après|ensuite|alors) <<- ->> puis|après|ensuite|alors                                           # Pléonasme.
-__[i]/pleo(pleo_réunir)__               (réuni\w*) ensemble @@0 <<- morph(\1, ">réunir ", False) ->> \1                                         # Pléonasme.
-__[i]/pleo(pleo_reculer)__              (recul\w*) en arrière @@0 <<- morph(\1, ">recul(?:er|) ", False) ->> \1                                 # Pléonasme.
-__[i]/pleo(pleo_risque)__               (risques?) (?:potentiels?|de menaces?) @@0 <<- ->> \1                                                   # Pléonasme.
-__[i]/pleo(pleo_secousse)__             (secousses?) sé?ismiques? @@0 <<- ->> secousse tellurique|secousses telluriques|tremblement de terre    # Pléonasme.
-__[i]/pleo(pleo_solidaire)__            (solidaires?) les uns des autres @@0 <<- ->> \1                                                         # Pléonasme.
-__[i]/pleo(pleo_suffire)__              (suffi\w+) simplement @@0 <<- morph(\1, ">suffire ", False) ->> \1                                      # Pléonasme.
-__[i]/pleo(pleo_talonner)__             (talonn\w+) de près @@0 <<- morph(\1, ">talonner ", False) ->> \1                                       # Pléonasme.
-__[i]/pleo(pleo_taux_alcoolémie)__      taux d’alcoolémies? @@7 <<- ->> taux d’alcool|alcoolémie                                                # Pléonasme. L’alcoolémie est le taux d’alcool dans le sang.
-__[i]/pleo(pleo_tunnel)__               (tunnels?) souterrains? @@0 <<- ->> \1                                                                  # Pléonasme.
-__[i]/pleo(pleo_hardes)__               vieilles hardes <<- ->> hardes                                                                          # Pléonasme.
-__[i]/pleo(pleo_voire_même)__           voire même <<- ->> voire|même                                                                           # Pléonasme.|https://fr.wiktionary.org/wiki/voire_m%C3%AAme
+__code_legacy__
+    legacy code
+    code legacy
+        <<- ->> code hérité|code reliquat                                                           # \1 \2. Anglicisme superflu.
+
+TEST: c’est du {{legacy code}}.
+TEST: ce {{code legacy}} est un cauchemar
+
+
+
+!!
+!!
+!!!! Pléonasmes                                                                                   !!
+!!
+!!
+
+__pleo_pléonasmes_divers__
+    >abolir [absolument|entièrement|complétement|complètement|totalement]
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >acculer [au|aux] >pied du mur
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >achever [absolument|entièrement|complétement|complètement|totalement]
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    actuellement en cours
+        <<- /conf/ not value(>1, "|de|d’|") ->> en cours                                    # Pléonasme.
+
+    actuellement en train [de|d’]
+        <<- /conf/ not value(>1, "|nuit|") -1:3>> en train                                  # Pléonasme.
+
+    >ajouter en plus
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >apanage >exclusive
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    [>applaudir|>applaudissement] des deux mains
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    au jour d’ aujourd’hui
+        <<- /conf/ ->> aujourd’hui                                                          # Pléonasme.
+
+    >avancer en avant
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >avérer >vraie
+        <<- /conf/ -2>> =\2.replace("vrai", "exact")                                        # Pléonasme.
+
+    [avéré|avérée|avérés|avérées] >vraie
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    avenir devant [moi|toi|soi|lui|elle|nous|vous|eux|elles]
+        <<- /conf/ morph(<1, ":A|>un") ->> avenir                                           # Pléonasme.
+
+    >bourrasque de vent
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    car en effet
+        <<- /conf/ ->> car|en effet                                                         # Pléonasme.
+
+    >cirrhose du foie
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >collaborer ensemble
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    comme par exemple
+        <<- /conf/ ->> comme|par exemple                                                    # Pléonasme.
+
+    >comparer entre [eux|elles]
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >contraindre malgré [moi|toi|soi|lui|elle|nous|vous|eux|elles]
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >descendre en bas
+        <<- /conf/ not value(>1, "|de|des|du|d’|") ->> \1                                   # Pléonasme.
+
+    >dessiner un dessin
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    à [partir|compter] de dorénavant
+        <<- /conf/ ->> dorénavant|à partir de maintenant                                    # Pléonasme.
+
+    donc par conséquent
+        <<- /conf/ ->> donc|par conséquent|c’est pourquoi                                   # Pléonasme.
+
+    >enchevêtrer les uns dans les autres
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >entraider mutuellement
+    >entraider les uns les autres
+        <<- /conf/  ->> \1                                                                  # Pléonasme.
+
+    >entraide >mutuelle
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >erreur >involontaire
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >étape >intermédiaire
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >hasard >imprévue
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >hémorragie de sang
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >joindre ensemble
+        <<- /conf/ ->> \1|mettre ensemble                                                   # Pléonasme.
+
+    >lever debout
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    mais [cependant|pourtant|toutefois]
+        <<- /conf/ ->> mais|cependant|pourtant|toutefois                                    # Pléonasme.
+
+    >marche à >pied
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >méandre sinueux
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    [>média|media] d’ >information
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >monopole >exclusive
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >monter en haut
+        <<- /conf/ not value(>1, "|de|des|du|d’|") ->> \1                                   # Pléonasme.
+
+    >opportunité à saisir
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >orage >électrique
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >paire de >jumelle
+        <<- /conf/ ->> jumelles                                                             # Pléonasme.
+
+    >panacée >universelle
+        <<- /conf/ ->> \1|remède universel                                                  # Pléonasme.
+
+    >perspective d’ avenir
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    [premier|premiers] >balbutiement
+        <<- /conf/ ->> \2                                                                   # Pléonasme.
+
+    [première|premières] >priorité
+        <<- /conf/ ->> \2                                                                   # Pléonasme.
+
+    >projet >future
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >future >projet
+        <<- /conf/ ->> \2                                                                   # Pléonasme.
+
+    >prototype >expérimentale
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    [>rénover|>rénovation] à neuf
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    puis [après|ensuite|alors]
+        <<- /conf/ ->> puis|après|ensuite|alors                                             # Pléonasme.
+
+    >réunir ensemble
+        <<- /conf/  ->> \1                                                                  # Pléonasme.
+
+    [>reculer|>recul] en arrière
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >risque >potentielle
+    >risque de >menace
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >secousse [>séismique|>sismique]
+        <<- /conf/ ->> secousse tellurique|secousses telluriques|tremblement de terre       # Pléonasme.
+
+    >solidaire les uns des autres
+    >solidaire les uns avec les autres
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >suffire simplement
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    >talonner de près
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    taux d’ >alcoolémie
+        <<- /conf/ ->> taux d’alcool|alcoolémie                                             # Pléonasme. L’alcoolémie est le taux d’alcool dans le sang.
+
+    >tunnel >souterraine
+        <<- /conf/ ->> \1                                                                   # Pléonasme.
+
+    vieilles hardes
+        <<- /conf/ ->> hardes                                                               # Pléonasme.
+
+    voire même
+        <<- /conf/ ->> voire|même                                                           # Pléonasme.|https://fr.wiktionary.org/wiki/voire_m%C3%AAme
 
 TEST: il faut {{abolir totalement}} ces pratiques   ->> abolir
 TEST: il faut {{achever complètement}} ce projet    ->> achever
 TEST: {{au jour d’aujourd’hui}}                     ->> aujourd’hui
 TEST: {{actuellement en cours}}                     ->> en cours
@@ -3014,12 +3193,12 @@
 TEST: s’{{entraident les uns les autres}}           ->> entraident
 TEST: {{comme par exemple}}                         ->> comme|par exemple
 TEST: {{médias d’informations}}                     ->> médias
 TEST: {{lever debout}}                              ->> lever
 TEST: {{cirrhose du foie}}                          ->> cirrhose
-TEST: {{s’avérer vrai}}                             ->> s’avérer exact
-TEST: {{avérées vraies}}                            ->> avérées
+TEST: s’avérer {{vrai}}                             ->> exact
+TEST: {{avérées vraies}}                            ->> avérées|||exactes
 TEST: {{bourrasques de vent}}                       ->> bourrasques
 TEST: {{contraint malgré lui}}                      ->> contraint
 TEST: {{contraindre malgré eux}}                    ->> contraindre
 TEST: {{applaudir des deux mains}}                  ->> applaudir
 TEST: Car {{à partir de dorénavant}}, ce sera…      ->> dorénavant|à partir de maintenant
@@ -3059,2327 +3238,790 @@
 TEST: {{vieilles hardes}}                           ->> hardes
 TEST: {{voire même}}                                ->> voire|même
 
 
 # d’avance / à l’avance
-__[i]/pleo(pleo_verbe_à_l_avance)__
-    ((?:pré[pvds]|pressen|pronostiqu|réserv|dev(?:an[cç]|in)|avert)\w+) (?:d’avance|à l’avance)  @@0
-    <<- morph(\1, ">(?:prévenir|prévoir|prédire|présager|préparer|pressentir|pronostiquer|avertir|devancer|deviner|réserver) ", False)
-    ->> \1                                                                                                              # Pléonasme.
-
-TEST: {{prédire à l’avance}}                  ->> prédire
-TEST: {{pronostiquer d’avance}}               ->> pronostiquer
-TEST: {{réserver d’avance}}                         ->> réserver
+__pleo_verbe_à_l_avance__
+    [>prévenir|>prévoir|>prédire|>présager|>préparer|>pressentir|>pronostiquer|>avertir|>devancer|>deviner|>réserver] à l’ avance
+    [>prévenir|>prévoir|>prédire|>présager|>préparer|>pressentir|>pronostiquer|>avertir|>devancer|>deviner|>réserver] d’ avance
+        <<- /conf/ ->> \1                                                                           # Pléonasme.
+
+TEST: {{prédire à l’avance}}                    ->> prédire
+TEST: {{pronostiquer d’avance}}                 ->> pronostiquer
+TEST: {{réserver d’avance}}                     ->> réserver
 
 
 # plus tard / à une date ultérieure
-__[i]/pleo(pleo_différer_ajourner_reporter)__
-    ((?:diff|ajourn|report)\w+) à (?:plus tard|date ultérieure|une date ultérieure)  @@0
-    <<- morph(\1, ">(?:ajourner|différer|reporter) ", False)
-    ->> \1                                                                                                              # Pléonasme.
-
-TEST: {{Ajourner à une date ultérieure}}      ->> Ajourner
-TEST: {{différer à une date ultérieure}}      ->> différer
-TEST: {{reporter à plus tard}}                ->> reporter
-
+__pleo_différer_ajourner_reporter__
+    [>ajourner|>différer|>reporter] à plus tard
+    [>ajourner|>différer|>reporter] à date ultérieure
+    [>ajourner|>différer|>reporter] à une date ultérieure
+        <<- /conf/ ->> \1                                                                           # Pléonasme.
+
+TEST: {{Ajourner à une date ultérieure}}        ->> Ajourner
+TEST: {{différer à une date ultérieure}}        ->> différer
+TEST: {{reporter à plus tard}}                  ->> reporter
+
+
+
+
+!!
+!!
+!!!! Tournures de langage                                                                         !!
+!!
+!!
+
+__faire_plaisir__
+    >faire plaisirs
+        <<- /sgpl/ -2>> plaisir                                                                     # Faire plaisir : dans cette locution, “plaisir” doit être au singulier.
+        <<- ~2>> *
+
+TEST: Ça me fait {{plaisirs}}.
 
 
 # ayants droit
-__[i]/sgpl(sgpl_ayants_droit)__
-    [ldcs]es (ayant[- ]droits?) @@4 <<- -1>> ayants droit                 # Au singulier : « un ayant droit ». Au pluriel : « des ayants droit ».
+__sgpl_ayants_droit__
+    [les|des|ces|ses|nos|vos|leurs] ayant [droit|droits]
+        <<- /gn/ -2:3>> ayants droit                                        # Au singulier : « un ayant droit ». Au pluriel : « des ayants droit ».
 
 TEST: Comment lutter contre la cupidité des {{ayant droits}}
 # Note: À supprimer? Graphie qui tend vers la soudure et le pluriel régulier (ayant-droit(s))
 
 
 # Mon, ton, son : euphonie
-__[i]/gn(gn_mon_ton_son_euphonie)__
-    ([mts]a) +({w_2})  @@0,$
-    <<- morphex(\2, ">[aâeéèêiîoôuûyœæ].+:[NAQ].*:f", ":[eGW]") -1>> =\1.replace("a", "on")         # Même si « \2 » est féminin, on utilise « mon/ton/son » pour faire la liaison.|http://fr.wikipedia.org/wiki/Euphonie
+__gn_mon_ton_son_euphonie__
+    [ma|ta|sa]  @>[aâeéèêiîoôuûyœæ].+:[NAQ].*:f¬:[eGW]
+        <<- /gn/ -1>> =\1.replace("a", "on")                                # Même si « \2 » est féminin, on utilise « mon/ton/son » pour faire la liaison.|http://fr.wikipedia.org/wiki/Euphonie
 
 TEST: {{ta}} aimée                                            ->> ton
 TEST: {{ma}} obligée                                          ->> mon
 TEST: Ce couple va donner à la France sa très importante collection qui rejoindra le musée d’Orsay
 
 
-!!
-!!
-!!!! Confusions                                                                                     
-!!
-!!
-
-__[s>/conf(conf_ne_n)__     [nN]e n’                        <<- ->> ne m’|n’                        # Incohérence. Double négation.
-__[s>/conf(conf_pronoms1)__ [mtMT]e ([nmst](?:’|e )) @@$    <<- ->> \1                              # Incohérence.
-__[s>/conf(conf_pronoms2)__ [sS]e ([mst](?:’|e )) @@$       <<- ->> \1                              # Incohérence.
-__[s>/conf(conf_de_d)__     [dD][eu] d’(?![A-ZÉÂÔÈ])        <<- ->> d’                              # Incohérence. 
-
-TEST: Il {{ne n’}}arrive jamais à l’heure.
-TEST: Ça {{me te }}prend la tête, toutes ces complications vaines.
-TEST: il {{se m’}}est difficile d’y parvenir.
-TEST: Ça t’arrive {{de d’}}arriver à l’heure ?
-TEST: Les écrits de d’Alembert.
-
-
-#### Articles et prépositions + verbes
-
-__[i]/conf(conf_à_le_la_les_leur)__
-    à l(?:es? +|eurs? +|a +|’)({w_3})  @@$
-    <<- morphex(\1, ":", ":[GNAWMBYŴ]") -1>> =suggSimil(\1, ":[NA]", True)                           # Incohérence : après “à”, on devrait trouver un groupe nominal.
-
-TEST: à leur {{profile}}
-TEST: une référence à l’astuce de base qui permet d’outrepasser ses droits.
-TEST: Le mari répète à l’envi qu’il a découvert la France à travers les mots de sa femme.
-
-
-__[s]/conf(conf_en_mts_verbe)__
-    ([eE]n ([mtsn])(?:e |’))({w_1}) @@0,*,$
-    <<- morphex(\3, ":[123][sp]", ":[PY]") and not \0.endswith("n’importe") >>>
-    <<- morph(\3, ":3p", False) -3>> =suggVerb(\2, ":P")                                            # Incohérence : « en \1 \2 »… Vouliez-vous écrire le verbe au participe présent ?
-    <<- not (\1.endswith("se ") and morph(\3, ":[NA]", False)) -1>> "\2’en "                        # Incohérence : vouliez-vous écrire « \2’en » ?
-
-TEST: {{en t’}}ait donné tant.                          ->> "t’en "
-TEST: {{en n’}}{{envoient}} que peu.
-TEST: toute chose pourrait finalement advenir indifféremment en n’importe quel point du globe
-
-
-__[i]/conf(conf_malgré_le_la_les_leur)__
-    malgré l(?:es? +|eurs? +|a +|’)({w_3})  @@$
-    <<- morphex(\1, ":", ":[GNAWMB]") -1>> =suggSimil(\1, ":[NA]", True)                             # Incohérence : après “malgré”, on devrait trouver un groupe nominal.
-
-TEST: malgré l’{{arrête}} qui interdisait le port 
-TEST: malgré les deux précédentes erreurs
-
-
-__[i]/conf(conf_ma_ta_cette_verbe)__
-    ([mt]a|cette) +({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
-    -2>> =suggSimil(\2, ":[NA]:[fe]:[si]", True)                                                    # Incohérence avec « \1 » : « \2 » est un verbe.
-
-TEST: Cette {{pèle}} est trop fragile.
-
-
-__[i]/conf(conf_sa_verbe)__
-    (sa) ({w_2})  @@0,3
-    <<- \2[0].islower() and morphex(\2, ":V.*:(?:Y|[123][sp])", ":(?:N.*:[fe]|A|W)") >>>
-    <<- morph(\2, "V.....[pqx]", False) -1>> ça|se                                                   # Confusion : « \2 » est un verbe. Exemples : sa jambe, ça vient. (Une faute de frappe peut-être ?)
-    <<- __else__ -1>> ça                                                                            # Confusion : « \2 » est un verbe. Exemples : sa jambe, ça vient.
-    <<- hasSimil(\2) -2>> =suggSimil(\2, ":[NA]:[fe]:[si]", True)                                   # Incohérence avec « \1 » : « \2 » est un verbe.
-
+
+!!
+!!
+!!!! Confusions générales                                                                         !!
+!!
+!!
+
+__conf_déterminant_fem_sing_verbe__
+    [ma|ta|cette|ladite]  @:(?:Y|[123][sp])¬:[NA]
+        <<- /conf/ \2.islower() -2>> =suggSimil(\2, ":[NA]:[fe]:[si]", True)                        # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    sa  @:(?:Y|[123][sp])¬:(?:N.*:[fe]|A|W)
+        <<- /conf/ \2.islower() >>>
+        <<- morph(\2, "V.....[pqx]") -1>> ça|se                                                     # Confusion : « \2 » est un verbe. Exemples : sa jambe, ça vient. (Une faute de frappe peut-être ?)
+        <<- __else__ -1>> ça                                                                        # Confusion : « \2 » est un verbe. Exemples : sa jambe, ça vient.
+        <<- hasSimil(\2) -2>> =suggSimil(\2, ":[NA]:[fe]:[si]", True)                               # Incohérence avec « \1 » : « \2 » est un verbe.
+
+TEST: Cette {{pèle}} est trop fragile.
 TEST: {{sa}} devient difficile.
 TEST: il me tendit {{sa}} {{pèche}}.
 TEST: {{sa}} prend du temps.                                                  ->> ça|se
 TEST: {{çà}} va                                                               ->> ça
 TEST: {{sa}} va                                                               ->> ça
 
 
-__[i]/conf(conf_du_cet_au_verbe)__
-    (du|cet|au) +({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower() and not (\2 == "sortir" and re.search(r"(?i)au", \1))
-    -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True)                                                    # Incohérence avec « \1 » : « \2 » est un verbe.
-
-TEST: cet {{plaît}} est infectée.
-
-
-__[i]/conf(conf_ce_verbe)__
-    (ce) +(?!faire|peut)({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]:.:[si]|:V0e.*:3[sp]|>devoir") and \2[0].islower() and hasSimil(\2)
-    -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True)                                                    # Incohérence avec « \1 » : « \2 » est un verbe.
-
+__conf_déterminant_mas_sing_verbe__
+    [du|cet|ledit|dudit]  @:(?:Y|[123][sp])¬:[NAQ]
+        <<- /conf/ \2.islower()
+        -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True)                                                # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    au  @:(?:Y|[123][sp])¬:[NAQ]
+        <<- /conf/ \2.islower() and not value(\2, "|sortir|")
+        -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True)                                                # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    ce  @:V.*:(?:Y|[123][sp])¬:[NAQ]:.:[si]
+        <<- /conf/ \2.islower() and not value(\2, "|faire|sont|soit|fut|fût|serait|sera|peut|pouvait|put|pût|pourrait|pourra|doit|dut|dût|devait|devrait|devra|") and hasSimil(\2)
+        -2>> =suggSimil(\2, ":[NA]:[me]:[si]", True)                                                # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    mon  @:(?:Y|[123][sp])¬:[NAQ]
+        <<- /conf/ \2.islower()
+        -2>> =suggSimil(\2, ":[NA]:.:[si]", True)                                                   # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    [<start>|,]  [ton|son|audit]  @:(?:Y|[123][sp])¬:[NAQ]
+        <<- /conf/ \3.islower()
+        -3>> =suggSimil(\3, ":[NA]:[me]:[si]", True)                                                # Incohérence avec « \2 » : « \3 » est un verbe.
+
+    un  @:(?:Y|[123][sp])¬:[GNA]
+        <<- /conf/ not value(<1, "|dont|l’|d’|sauf|") and not before(r"(?i)\bun à +$")
+        -2>> =suggSimil(\2, ":[NAQ]:[me]:[si]", True)                                               # Incohérence avec “\1” : “\2” est une forme verbale conjuguée.
+
+TEST: un {{maintient}} difficile.
+TEST: quelqu’un arrive.
+TEST: cet {{plaît}} est infectée.
 TEST: {{ce}} {{rappelle}} n’en finit pas.
-
-
-__[i]/conf(conf_mon_verbe)__
-    (mon) +({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
-    -2>> =suggSimil(\2, ":[NA]:.:[si]", True)                                                       # Incohérence avec « \1 » : « \2 » est un verbe.
-
 TEST: mon {{rackette}} n’a pas porté les fruits espérés.
+TEST: ton {{recèle}} avait été dévoilé
 TEST: Belle qui tient mon vit captif entre tes doigts.
 
 
-__[i]/conf(conf_ton_son_verbe)__
-    [st]on ({w_2})  @@4
-    <<- morph(\1, ":V.*:(?:Y|[123][sp])") and \1[0].islower() and isStart()
-    -1>> =suggSimil(\1, ":[NA]:[me]:[si]", True)                                                    # Incohérence : « \1 » est un verbe.
-
-TEST: ton {{recèle}} a été dévoilé
-
-
-__[i]/conf(conf_det_plur_verbe)__
-    ([dcmts]es|quelques|aux|[nv]os) +({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower() and not re.search(r"(?i)^quelques? soi(?:ent|t|s)\b", \0)
-    -2>> =suggSimil(\2, ":[NA]:.:[pi]", True)                                                       # Incohérence avec « \1 » : « \2 » est un verbe.
+__conf_déterminant_plur_verbe__
+    [des|ces|mes|tes|ses|aux|nos|vos]  @:V.*:(?:Y|[123][sp])¬:[NA]
+        <<- /conf/ \2.islower()
+        -2>> =suggSimil(\2, ":[NA]:.:[pi]", True)                                                   # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    quelques  @:V.*:(?:Y|[123][sp])¬:[NA]
+        <<- /conf/ \2.islower() and not value(\2, "|soient|soit|sois|")
+        -2>> =suggSimil(\2, ":[NA]:.:[pi]", True)                                                   # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    [auxdits|lesdits|desdits]  @:V.*:(?:Y|[123][sp])¬:[NA]
+        <<- /conf/ \2.islower()
+        -2>> =suggSimil(\2, ":[NA]:[me]:[pi]", True)                                                # Incohérence avec « \1 » : « \2 » est un verbe.
+
+    [auxdites|lesdites|desdites]  @:V.*:(?:Y|[123][sp])¬:[NA]
+        <<- /conf/ \2.islower()
+        -2>> =suggSimil(\2, ":[NA]:[fe]:[pi]", True)                                                # Incohérence avec « \1 » : « \2 » est un verbe.
 
 TEST: la crainte des {{attentas}} fait feu de tout bois.
-
-
-__[i]/conf(conf_auxdits_verbe)__
-    (auxdits) +({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
-    -2>> =suggSimil(\2, ":[NA]:[me]:[pi]", True)                                                    # Incohérence avec « \1 » : « \2 » est un verbe.
-
 TEST: elle se rendit auxdits {{jardinais}}
-
-
-__[i]/conf(conf_auxdites_verbe)__
-    (auxdites) +({w_2})  @@0,$
-    <<- morphex(\2, ":V.*:(?:Y|[123][sp])", ":[NAQ]") and \2[0].islower()
-    -2>> =suggSimil(\2, ":[NA]:[fe]:[pi]", True)                                                    # Incohérence avec « \1 » : « \2 » est un verbe.
-
 TEST: auxdites {{scelles}}, il ne prêta pas attention.
 
 
-__[i]/conf(conf_de_la_vconj)__  de la +({w_2})  @@6
-    <<- morphex(\1, ":[123][sp]", ":[NAQ]") >>>
-    <<- morphex(\1, ":V1.*:(?:Iq|Ip:2p)", ":1p") -1>> =suggVerbInfi(@)                              # Incohérence : mettez le verbe à l’infinitif (à moins qu’il y ait confusion avec un nom féminin).
-    <<- __else__ -1>> =suggSimil(\1, ":(?:[NA]:[fe]:[si])", False)                                  # Incohérence : « \1 » est un verbe.
+__conf_de_dès_par_vconj__
+    [de|d’|dès|par]  @:V.*:[123][sp]¬:[GNA]
+        <<- /conf/ not \2.istitle() -2>> =suggSimil(\2, ":[NA]", True)                              # Incohérence avec “\1” : “\2” est une forme verbale conjuguée.
+
+    [d’|par]  [un|une]  @:V.*:[123][sp]¬:[GNA]
+        <<- /conf/ not \3.istitle() and not value(<1, "|plus|moins|")
+        -3>> =suggSimil(\3, ":[NA]", True)                                                          # Incohérence avec “\1\2” : “\3” est une forme verbale conjuguée.
+
+    de l’ @:[123][sp]¬:[NAQ]
+        <<- /conf/ not \3.istitle() -3>> =suggSimil(\3, ":[NA]:.:[si]", True)                       # Incohérence avec “\1 \2” : “\3” est une forme verbale conjuguée.
+
+    de  le  *WORD
+        <<- /conf/ morph(\3, ":[NAQ].*:[me]", ":[YG]") and not \3.istitle() -1:2>> du               # Incohérence avec “\1 \2” : “\3” est un nom ou un adjectif.
+        <<- /conf/ morph(\3, ":[123][sp]") -3>> =suggVerbInfi(\3)                                   # Incohérence avec “\1 \2” : “\3” est une forme verbale conjuguée.
+
+    de  la  *WORD
+        <<- /conf/ morph(\3, ":[123][sp]", ":[NAQ]") and not \3.istitle() >>>
+        <<- morph(\3, ":V1.*:(?:Iq|Ip:2p)", ":1p") -3>> =suggVerbInfi(\3)               # Incohérence avec “\1 \2” : mettez le verbe à l’infinitif (à moins qu’il y ait confusion avec un nom féminin).
+        <<- __else__ -3>> =suggSimil(\3, ":(?:[NA]:[fe]:[si])", False)                  # Incohérence avec “\1 \2” : “\3” est un verbe.
 
 TEST: les petits esprits de la {{pensait}} religieuse
-
-
+TEST: {{de le}} vin                                           ->> du
+TEST: il n’est pas interdit de le {{pensait}}
+TEST: de l’{{entra}}
+TEST: par {{bloque}} de données
+TEST: il s’agit de {{mette}} en évidence.
+TEST: d’une {{habille}} femme
+TEST: plus d’un ont été traumatisés
+TEST: Plus d’une sont parties aussi vite qu’elles étaient venues
 TEST: pour les insulter au sortir du seul troquet dispensateur d’oubli liquide du coin
 TEST: ce peut être un matériau à part entière pour alimenter discussions et délibérations.
 
 
-__[i]/conf(conf_de_le_nom_ou_vconj)__
-    (de le) ({w_2})  @@0,6
-    <<- morphex(\2, ":[NAQ].*:[me]", ":[YG]") and \2[0].islower() -1>> du                           # Incohérence : « \2 » est un nom ou un adjectif.
-    <<- morph(\2, ":[123][sp]", False) -2>> =suggVerbInfi(\2)                                       # Incohérence : « \2 » est une forme verbale conjuguée.
-
-TEST: {{de le}} vin                                           ->> du
-TEST: il n’est pas interdit de le {{pensait}}
-
-
-__[i]/conf(conf_de_l_vconj)__
-    de l’({w_2})  @@5
-    <<- morphex(\1, ":[123][sp]", ":[NAQ]") -1>> =suggSimil(\1, ":[NA]:.:[si]", True)               # Incohérence : « \1 » est une forme verbale conjuguée.
-
-TEST: de l’{{entra}}
-
-
-__[i]/conf(conf_un_verbe)__
-    (?<!’)un ({w_2})  @@3
-    <<- morph(\1, ":(?:Y|[123][sp])") and not before("(?i)(?:dont|sauf|un à) +$")
-    -1>> =suggSimil(\1, ":[NAQ]:[me]:[si]", True)                                                   # Incohérence : « \1 » est une forme verbale conjuguée.
-
-TEST: un {{maintient}} difficile.
-
-
-__[i]/conf(conf_de_dès_par_vconj)__
-    (?:d(?:e|ès)|par) ({w_2})  @@$
-    <<- \1[0].islower() and morph(\1, ":V.*:[123][sp]") -1>> =suggSimil(\1, ":[NA]", True)          # Incohérence : « \1 » est une forme verbale conjuguée.
-
-TEST: par {{bloque}} de données
-TEST: il s’agit de {{mette}} en évidence.
-
-
-__[i]/conf(conf_d_une_vconj)__
-    d’(?:une? +|)({w_2})  @@$
-    <<- \1[0].islower() and morphex(\1, ":V.*:[123][sp]", ":[GNA]") and not before(r"(?i)\b(?:plus|moins) +$")
-    -1>> =suggSimil(\1, ":[NA]", True)                                                              # Incohérence : « \1 » est une forme verbale conjuguée.
-
-TEST: d’une {{habille}} femme
-TEST: plus d’un ont été traumatisés
-TEST: plus d’une sont parties aussi vite qu’elles étaient venues
-
-
-__[i]/conf(conf_il_on_pas_verbe)__
-    (?<!t’)(?:il|on) (?:l’|l(?:es?|a|eur|ui) +|[nv]ous +|)({w_2}) @@$
-    <<- morphex(\1, ":", ":(?:[123][sp]|O[onw]|X)|ou ") and morphex(word(-1), ":", ":3s", True)
-    -1>> =suggSimil(\1, ":(?:3s|Oo)", False)                                                        # Incohérence : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+__conf_préposition_le_la_les_leur__
+    à  [le|la|l’|les|leur|leurs]  @:¬:[GNAWMBYŴ]
+        <<- /conf/ -3>> =suggSimil(\3, ":[NA]", True)                           # Incohérence : après “à”, on devrait trouver un groupe nominal (ou un verbe à l’infinitif).
+
+TEST: à leur {{profile}}
+TEST: une référence à l’astuce de base qui permet d’outrepasser ses droits.
+TEST: Le mari répète à l’envi qu’il a découvert la France à travers les mots de sa femme.
+
+
+    [malgré|dès] [le|la|l’|les|leur|leurs]  @:¬:[GNAWMB]
+        <<- /conf/ -3>> =suggSimil(\3, ":[NA]", True)                           # Incohérence : après “\1”, on devrait trouver un groupe nominal.
+
+TEST: malgré l’{{arrête}} qui interdisait le port
+TEST: malgré les deux précédentes erreurs
+
+
+__conf_je_non_verbe__
+    je  @:¬:(?:[123][sp]|O[onw]|X)
+        <<- /conf/ not value(\2, "|soussigné|soussignée|") and not morph(<1, ":1s")
+        -2>> =suggSimil(\2, ":(?:1s|Oo)", False)                                                    # Incohérence avec “je” : “\2” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+
+    je  [le|la|l’|les|leur|lui|nous|vous]  @:¬:(?:[123][sp]|O[onw]|X)
+        <<- /conf/ not morph(<1, ":1s") -3>> =suggSimil(\3, ":(?:1s|Oo)", False)                    # Incohérence avec “je” : “\3” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+
+TEST: Je {{travail}}.
+TEST: Je soussigné, M. X., déclare que…
+
+
+__conf_tu_non_verbe__
+    tu  ?[le|la|l’|les|leur|lui|nous|vous]¿  (@:¬:(?:[123][sp]|O[onw]|X))
+        <<- /conf/ not morph(<1, ":(?:2s|V0|R)") -1>> =suggSimil(\1, ":(?:2s|Oo)", False)           # Incohérence avec “tu” : “\1” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+
+TEST: tu {{croix}} que tu sais quelque chose, mais tu ne sais rien.
+TEST: tu la {{croix}} idiote ?
+TEST: Elles sont à tu et à toi.
+
+
+__conf_il_on_non_verbe__
+    [il|on]  @:¬:(?:[123][sp]|O[onw]|X)|>ou/
+        <<- /conf/ not morph(<1, ":3s") and not value(<1, "|t’|")
+        -2>> =suggSimil(\2, ":(?:3s|Oo)", False)                                                    # Incohérence avec “\1” : “\2” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+
+    [il|on]  [le|la|l’|les|leur|lui|nous|vous]  @:¬:(?:[123][sp]|O[onw]|X)
+        <<- /conf/ not morph(<1, ":3s") and not value(<1, "|t’|")
+        -3>> =suggSimil(\3, ":(?:3s|Oo)", False)                                                    # Incohérence avec “\1” : “\3” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
 
 TEST: il {{et}} parti.
+TEST: il nous {{et}} indispensable.
 
 
-__[i]/conf(conf_ils_pas_verbe)__
-    (?<!t’)ils (?:l’|l(?:es?|a|eur|ui) +|[nv]ous +|)({w_2}) @@$
-    <<- morphex(\1, ":", ":(?:[123][sp]|O[onw]|X)|ou ") and morphex(word(-1), ":", ":3p", True)
-    -1>> =suggSimil(\1, ":(?:3p|Oo)", False)                                                        # Incohérence avec « ils » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+__conf_ils_non_verbe__
+    ils  @:¬:(?:[123][sp]|O[onw]|X)|>ou/
+        <<- /conf/ not morph(<1, ":3p") and not value(<1, "|t’|")
+        -2>> =suggSimil(\2, ":(?:3p|Oo)", False)                                                    # Incohérence avec “ils” : “\2” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
+
+    ils  [le|la|l’|les|leur|lui|nous|vous]  @:¬:(?:[123][sp]|O[onw]|X)
+        <<- /conf/ not morph(<1, ":3p") and not value(<1, "|t’|")
+        -3>> =suggSimil(\3, ":(?:3p|Oo)", False)                                                    # Incohérence avec “ils” : “\3” devrait être un verbe, un pronom objet, un adverbe de négation, etc.
 
 TEST: ils {{son}} du même bois.
 TEST: Ils {{étai}} partie au {{restaurent}}
-
-
-__[i]/conf(conf_je_pas_verbe)__
-    je (?!soussigné)(?:l’|l(?:es?|a|eur|ui) +|[nv]ous +|)({w_2}) @@$
-    <<- morphex(\1, ":", ":(?:[123][sp]|O[onw]|X)") and morphex(word(-1), ":", ":1s", True)
-    -1>> =suggSimil(\1, ":(?:1s|Oo)", False)                                                        # Incohérence avec « je » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
-
-TEST: Je {{travail}}.
-
-
-__[i]/conf(conf_tu_pas_verbe)__
-    tu (?:l’|l(?:es?|a|eur|ui) +|[nv]ous +|)({w_2}) @@$
-    <<- morphex(\1, ":", ":(?:[123][sp]|O[onw]|X)") and morphex(word(-1), ":", ":(?:2s|V0e|R)", True)
-    -1>> =suggSimil(\1, ":(?:2s|Oo)", False)                                                        # Incohérence avec « tu » : « \1 » devrait être un verbe, un pronom objet, un adverbe de négation, etc.
-
-TEST: tu {{croix}} que tu sais quelque chose, mais tu ne sais rien.
-TEST: Elles sont à tu et à toi.
-
-TEST: elles seules peuvent s’en sortir.
-TEST: elle seule peut y arriver
-TEST: elle seules les femmes la font craquer
-
-
-#### Participes présents
-
-__[i]/conf(conf_adj_part_présent1)__    [nmts]e (\w+ant) @@3 <<- morphex(\1, ":", ":P") -1>> _      # Incohérence : « \1 » n’est pas un participe présent.
-__[i]/conf(conf_adj_part_présent2)__    (?:[nv]ous|lui) (\w+ant) @@$ <<- morph(\1, ":[NAQ]") -1>> _ # Incohérence : « \1 » n’est pas un participe présent.
-
-TEST: ne {{convaincant}} que les convaincus.
-TEST: une tension lui {{provocant}} un ulcère
-TEST: comme des nuages ou des coteaux se reflétant dans l’eau (ligature fl)
-
-
-# incohérences
-
-# Trop de faux positifs
-#__[i]/conf__
-#    très +(bien|\w+ent) +({w2})  @@w,$
-#    <<- morph(\1, ":W", False) and morphex(\2, ":[123][sp]", ":[GAQW]") -2>> _
-#    # Incohérence avec « très » : « \2 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
-
- 
-__[i]/conf(conf_très_verbe)__
-    très +(?!envie)({w_2})  @@$
-    <<- morphex(\1, ":(?:Y|[123][sp])", ":[AQW]") -1>> =suggSimil(\1, ":[AW]", True)                # Incohérence avec « très » : « \1 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
-    <<- morph(\1, ">jeûne ", False) -1>> =\1.replace("û", "u")                                      # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
-
-TEST: Il est très {{cite}}.
-TEST: très {{suivit}} par ce détective
-TEST: il était très {{habille}}
-TEST: Très {{jeûne}}, elle a su qu’elle ne voulait pas d’une vie ordinaire.
-
-
-__[i]/conf(conf_trop_vconj)__
-    trop +({w_2})  @@$
-    <<- morphex(\1, ":[123][sp]", ":(?:[GNAQWM]|3p)") and not before(r"(?i)\bce que? ") -1>> _      # Incohérence probable avec « trop » : « \1 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
-
-TEST: J’ai trop {{mangeais}}.
-TEST: Ce que nous réussissons presque sera considéré comme un échec.
-
-
-__[i]/conf(conf_presque_trop_vconj)__
-    presque +({w2})  @@$
-    <<- morphex(\1, ":[123][sp]", ":[GNAQWM]") and not before(r"(?i)\bce que? |ou $") -1>> _        # Incohérence probable avec « presque » : « \1 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
-
-TEST: presque {{délaissait}} par tout le monde.
-TEST: Tout le monde ou presque déteste ces gens-là.
-
-
-# élimination de presque
-__[i](p_presque)__
-    presque <<- ~>> *
-
-__[i]/conf(conf_chez_vconj)__
-    chez +({w2})  @@$
-    <<- not \1[0].isupper() and morphex(\1, ":[123][sp]", ":[GNAQM]") -1>> _                        # Incohérence avec « chez ».
+TEST: ils leur {{étai}} indifférent
+
+
+__conf_préverbes__
+    ne n’
+        <<- /conf/ not \1.isupper() ->> ne m’|n’                        # Incohérence. Double négation.
+
+    [me|te] [ne|n’|me|m’|te|t’|se|s’]
+        <<- /conf/ not \1.isupper() ->> \1                              # Incohérence.
+
+    se [me|m’|te|t’|se|s’]
+        <<- /conf/ not \1.isupper() ->> \1                              # Incohérence.
+
+    [de|du] d’ *WORD
+        <<- /conf/ not \1.isupper() and \3.islower() -1:2>> d’          # Incohérence.
+
+TEST: Il {{ne n’}}arrive jamais à l’heure.
+TEST: Ça {{me te}} prend la tête, toutes ces complications vaines.
+TEST: il {{se m’}}est difficile d’y parvenir.
+TEST: Ça t’arrive {{de d’}}arriver à l’heure ?
+TEST: Les écrits de d’Alembert.
+
+
+__conf_chez_vconj__
+    chez  @:(?:[123][sp]|P)¬:[GNAQM]
+        <<- /conf/ not \2.istitle() -2>> _                                                          # Incohérence avec “chez” : “\2” est une forme verbale conjuguée.
 
 TEST: Tout ce qu’on fera chez {{sera}} enregistré.
 
 
-__[i]/conf(conf_sur_vconj)__
-    sur +({w2})  @@$
-    <<- not \1[0].isupper() and morphex(\1, ":[123][sp]", ":[GNAQM]") and not morph(word(-1), ":[NA]:[me]:si", False)
-    -1>> _                                                                                          # Incohérence avec « sur ».
-
-TEST: Toutes les blagues qu’on fera sur {{entreront}} dans l’histoire !
-
-
-__[i]/conf(conf_si_vconj)__
-    si +({w2})  @@$
-    <<- morphex(\1, ":[123][sp]", ":[GNAQWMT]") and morphex(word(1), ":", ":D", True)
-    -1>> =suggSimil(\1, ":[AWGT]", True)                                                            # Incohérence avec « si » : « \1 » ne devrait pas être une forme verbale conjuguée.
-
-TEST: Ces gens sont si {{prit}} par leur travail qu’ils en oublient de vivre.
-TEST: Ça ira mieux demain, surtout si émerge une demande forte de la part des consommateurs.
-
-
-__[i]/conf(conf_de_plus_en_plus_verbe)__
-    de plus en plus +({w_2})  @@$
-    <<- morphex(\1, ":(?:[123][sp]|Y)", ":(?:[GAQW]|3p)") and not morph(word(-1), ":V[123].*:[123][sp]|>(?:pouvoir|vouloir|falloir) ", False, False)
-    -1>> =suggVerbPpas(@)
-    # Incohérence avec « de plus en plus » : « \1 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
+__conf_de_plus_en_plus_verbe__
+    de plus en plus  @:(?:[123][sp]|Y)¬:(?:[GAQW]|3p)
+        <<- /conf/ not morph(<1, ":V[123].*:[123][sp]|>(?:pouvoir|vouloir|falloir)/")
+        -5>> =suggVerbPpas(\5)
+        # Incohérence probable avec « de plus en plus » : « \5 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
 
 TEST: de plus en plus {{gagnait}} par la folie.
 TEST: de plus en plus {{concerner}} par ce problème
 TEST: avec quel zèle ils remplissent leurs devoirs de citoyens (de plus en plus deviennent enseignant·e·s, infirmier·e·s ou s’engagent dans l’armée, etc.).
 TEST: il faut de plus en plus aider ces gens.
 
+
+#### Participes présents
+__conf_participes_présents__
+    [ne|n’|me|m’|te|t’|se|s’]  ~\want$
+        <<- /conf/ morph(\2, ":", ":P") -2>> _                                                      # Incohérence : « \2 » n’est pas un participe présent.
+
+    [nous|vous|lui]  ~\want$
+        <<- /conf/ morph(\2, ":[NAQ]", ":[PG]") -2>> _                                              # Incohérence : « \2 » n’est pas un participe présent.
+
+TEST: ne {{convaincant}} que les convaincus.
+TEST: une tension lui {{provocant}} un ulcère
+TEST: comme des nuages ou des coteaux se reflétant dans l’eau (ligature fl)
+
+
+__conf_en_participes_présents__
+    en   [ne|me|m’|te|t’|t’]  @:[123][sp]¬:[PY]
+        <<- /conf/ morph(\3, ":3p") -3>> =suggVerb(\3, ":P")                                        # Incohérence : « en \1 \2 »… Vouliez-vous écrire le verbe au participe présent ?
+        <<- /conf/ value(\2, "|m’|t’|s’|") -1:2>> "\2en "                                           # Incohérence : vouliez-vous écrire « \2’en » ?
+        <<- /conf/ __else__ -1:2>> =\2[0:1] + "’en"                                                 # Incohérence : vouliez-vous écrire « \2’en » ?
+
+    en   se  @:[123][sp]¬:[PY]
+        <<- /conf/ morph(\3, ":3p") -3>> =suggVerb(\3, ":P")                                        # Incohérence : « en \1 \2 »… Vouliez-vous écrire le verbe au participe présent ?
+        <<- /conf/ not morph(\3, ":[NA]") -1:2>> "s’en "                                            # Incohérence : vouliez-vous écrire « \2’en » ?
+
+    en   n’  @:[123][sp]¬:[PY]
+        <<- /conf/ not value(\3, "|importe|") >>>
+        <<- morph(\3, ":3p") -3>> =suggVerb(\3, ":P")                                               # Incohérence : « en \1 \2 »… Vouliez-vous écrire le verbe au participe présent ?
+        <<- -1:2>> "n’en "                                                                          # Incohérence : vouliez-vous écrire « \2’en » ?
+
+TEST: {{en t’}}ait donné tant.                          ->> "t’en "
+TEST: {{en n’}}{{envoient}} que peu.
+TEST: il {{en me}} donne beaucoup.                      ->> m’en
+TEST: {{en n’}}{{abordent}} la côte, nous vîmes le désastre.
+TEST: toute chose pourrait finalement advenir indifféremment en n’importe quel point du globe
+
+
+
+__conf_presque_vconj__
+    presque  @:[123][sp]¬:[GNAQWM]
+        <<- /conf/ not tag_before(\1, "ce_que") and not value(<1, "|ou|") -2>> _                    # Incohérence probable avec “presque” : « \2 » n’est ni un adjectif, ni un participe passé, ni un adverbe.
+
+TEST: presque {{délaissait}} par tout le monde.
+TEST: Tout le monde ou presque déteste ces gens-là.
+
+
+__conf_sur_vconj__
+    sur  @:(?:[123][sp]|P)¬:[GNAQM]
+        <<- /conf/ not \2.istitle() and not morph(<1, ":[NA]:[me]:si") -2>> _                       # Incohérence avec “sur” : “\2” est une forme verbale conjuguée.
+
+TEST: Toutes les blagues qu’on fera sur {{entreront}} dans l’histoire !
+TEST: Elles se querellent sans cesse sur presque tout.
+
+
+__conf_si_vconj__
+    si  @:[123][sp]¬:[GNAQWMT]  <end>
+    si  @:[123][sp]¬:[GNAQWMT]  @:¬:D
+        <<- /conf/ -2>> =suggSimil(\2, ":[AWGT]", True)                                             # Incohérence probable avec “si” : “\2” ne devrait pas être une forme verbale conjuguée.
+
+TEST: Ces gens sont si {{prit}} par leur travail qu’ils en oublient de vivre.
+TEST: Ça ira mieux demain, surtout si émerge une demande forte de la part des consommateurs.
+
+
+__conf_trop_vconj__
+    trop  @:[123][sp]¬:(?:[GNAQWM]|3p)
+        <<- /conf/ not tag_before(\1, "ce_que") -2>> _                                              # Incohérence probable avec “trop” : “\2” n’est ni un adjectif, ni un participe passé, ni un adverbe.
+
+TEST: J’ai trop {{mangeais}}.
+TEST: Ce que nous réussissons presque sera considéré comme un échec.
+
+
+__conf_très_verbe__
+    très  @:(?:Y|[123][sp])¬:[AQW]
+        <<- /conf/ not value(\2, "|envie|") -2>> =suggSimil(\2, ":[AW]", True)                      # Incohérence avec “très” : “\2” n’est ni un adjectif, ni un participe passé, ni un adverbe.
+
+TEST: Il est très {{cite}}.
+TEST: très {{suivit}} par ce détective
+TEST: il était très {{habille}}
+
+
+
+
+
+!!
+!!
+!!!! Confusions spécifiques                                                                       !!
+!!
+!!
 
 # a / à
-__[i]/conf(conf_a_à_tout_à_fait)__  tout (a) fait @@5                                               <<- -1>> à          # Confusion.
-__[i]/conf(conf_a_à_jusqu_à)__      jusqu (a) @@6                                                   <<- -1>> à          # Confusion.
-__[i]/conf(conf_a_à_grâce_à)__      grâce (a) @@6             <<- morph(word(-1), ":[VN]", False, True) -1>> à          # Confusion probable.
-__[i]/conf(conf_a_à_moins_que)__    (a) moins que? @@0                                    <<- isStart() -1>> à          # Confusion probable : « à moins que » pour dire « sauf si ».
-__[i]/conf(conf_a_à_tout_à_coup)__  tout h?ah? co[uû][pt]?                                          <<- ->> tout à coup # Confusion.
-__[i]/conf(conf_a_à_coup_sûr)__     a coup s[uû]r                                                   <<- ->> à coup sûr  # Confusion.
-__[i]/conf(conf_a_à_face_à)__       face (a) @@5    <<- not before(r"(?i)\b(?:[lmts]a|leur|une|en) +$") -1>> à          # Confusion.
-__[i]/conf(conf_a_à_pas_à_pas)__    pas (a) pas @@4                                                 <<- -1>> à          # Confusion.
-__[i]/conf(conf_a_à_par_rapport)__  par rapport (a) ({w_2}) @@12,$  <<- morph(\2, ":(?:D|Oo|M)", False) -1>> à          # Confusion.
-__[i]/conf(conf_a_à_être_à)__
-    ({etre}) (a)(?! priori| posteriori| fortiori)  @@0,$
-    <<- morph(\1, ">être :V") and not before(r"(?i)\bce que? ") -2>> à                                # Confusion. Utilisez la préposition « à ».
-__[i]/conf(conf_a_à_peu_près)__
-    (?:a peu[tx]? (?:près|prés?|prêts?)|à peu[tx] (?:près|prés?|prêts?)|à peu (?:prés?|prêts?))
-    <<- ->> à peu près                                                                              # Confusion.
-    <<- ~>> *
-__[i]/conf(conf_a_à_pronoms1)__     ne +l(?:es?|a) +(?:l(?:eur|ui) +|)(à)  @@$  <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_pronoms2)__     ne +[nv]ous +(?:les +|l’|)(à)  @@$          <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_pronoms3)!6__   [mtsn]e l(?:es +|’)(à)  @@$                 <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_pronoms4)__     [mtsnl]’(?:en|y) +(à)  @@$                  <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_pronoms5)__     les (?:en|y) +(à)  @@$                      <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_pronoms6)__     [nv]ous +(?:en +|y +|les +|l’)(à)  @@$      <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_pronoms7)!6__   [mt]’(à) @@2                                <<- -1>> a          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_été)__
-    (à) +été  @@0
-    <<- -1>> a                                                                                      # Confusion probable : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_l_à)__
-    l’(à) ({w_2})  @@2,4
-    <<- not re.search("(?i)^(?:côtés?|coups?|peu(?:-près|)|pics?|propos|valoir|plat-ventrismes?)", \2)
-    -1>> a                                                                                          # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-    <<- re.search("(?i)^(?:côtés?|coups?|peu-près|pics?|propos|valoir|plat-ventrismes?)", \2)
-    ->> l’à-\2                                                                                      # Il faut un trait d’union.
-__[i]/conf(conf_a_à_il_on_à)__
-    (?:il|on) +(?:l(?:es +|’)|en +|y +(?:en +|)|[vn]ous +|)(à)  @@$
-    <<- not morph(word(-1), ":3s", False, False) -1>> a                                             # Confusion probable : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_elle_à)__
-    elle +(?:l(?:es +|’)|en +|y +(?:en |)|[vn]ous +|)(à)  @@$
-    <<- not morph(word(-1), ":(?:3s|R)", False, False) and not morph(word(1), ":Oo|>qui ", False, False)
-    -1>> a                                                                                          # Confusion probable : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_qui_pronom_à)__
-    qui (?:l(?:ui|eur)(?: en|)|nous|vous|en|y) +(à)  @@$ <<- -1>> a                                 # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_qui_a)__
-    qui (à) +({w_2})  @@4,$  <<- morphex(\2, ":Q", ":M[12P]") -1>> a                                # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_le)__
-    (à le) ({w_2})  @@0,5
-    <<- morphex(\2, ":[NAQ].*:[me]", ":(?:Y|Oo)") -1>> a le|au
-    # Confusion. Ou vous confondez “a” (préposition) avec “a” (avoir), ou vous devez employer “au”. Exemple : _à_ midi, il _a_ pris son déjeuner _au_ restaurant.
-    <<- morphex(\2, ":[NAQ].*:f", ":(?:Y|Oo)") -1>> à la
-    # Confusion. Ou vous confondez “a” (préposition) avec “a” (avoir), ou vous devez employer “au”. Exemple : _à_ midi, il _a_ pris son déjeuner _au_ restaurant.
-__[i]/conf(conf_a_à_les)__
-    (à les) ({w_2})  @@0,6  <<- morphex(\2, ":[NAQ]", ":(?:Y|Oo)") -1>> a les|aux
-    # Confusion. Ou vous confondez “a” (préposition) avec “a” (avoir), ou vous devez employer “aux”. Exemple : Elle _a_ donné du travail _aux_ employés _à_ profusion.
-__[i]/conf(conf_a_à_au_aux)__
-    (à) aux?(?! (?:moins|plus)) @@0 <<- -1>> a                                                      # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
-__[i]/conf(conf_a_à_base_cause)__
-    (a) (?:base|cause) d(?:es?|u|) @@0 <<- not before(r"(?i)\bce que?\b") -1>> à                    # Confusion. Utilisez la préposition « à ».
-__[i]/conf(conf_a_à_faim_peur_honte_soif)__
-    (à) +(?:faim|peur|honte|soif) @@0 <<- -1>> a                                                    # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez : 
-__[i]/conf(conf_a_à_part)__
-    (a) part ({w1}) @@0,7 <<- morph(\2, ":(?:M[12]|D|Oo)") -1>> à                                   # Confusion probable.
-__[i]/conf(conf_a_à_les_à)__
-    les (à)(?! côtés| peu près| prioris?| post[eé]rioris?| valoirs?| pics?| propos) @@4 <<- -1>> a
-    # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez : 
-__[i]/conf(conf_a_à_avant_conj_prep)__
-    (à) +(?:a(?:fin|lors|près|uprès|ux?(?! moins| plus| mieux)|vant|vec)|au-de(?:dans|hors|là|sso?us|vant)|chez|d(?:ans|evant|ès|déjà|onc|urant)|lorsque?|malgré|par(?:ce|mi|)|p(?:endant|our|uisque)|que?|sur|tandis)  @@0
-    <<- -1>> a                                                                                      # Confusion probable : “à” est une préposition. Écrivez “a” pour la conjugaison de “avoir”.
-__[i]/conf(conf_a_participe_passé_ou_vconj)__
-    (à) +({w_2})  @@0,$
-    <<- \2.islower() and \2 != "coté" >>>
-    <<- morphex(\2, ":(?:V.......[_z][az].*:Q|V1.*:Ip:2p)", ":[MGWNY]") -1>> a                      # Confusion probable : “à” est une préposition. Pour le verbe “avoir”, écrivez :
-    <<- __also__ and morph(\2, "V1.*:(?:Ip:2p|Q)", False) and not before(r"(?i)\b(?:il +|elle +|on +|l(?:es|ui|leur) +|[nv]ous +|y +|en +|[nmtsld]’)$")
-    -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
-    <<- __else__ and morph(\2, ":[123][sp]") and not \2.startswith("tord") >>>
-    <<- morph(\2, ":V2.*:Ip:3s") -2>> =suggVerbPpas(@, ":m:s")                                      # Incohérence : “\1” est une préposition. “\2” est un verbe conjugué.
-    <<- __also__ -1>> a                                                                             # Confusion probable : “à” est une préposition. Pour le verbe “avoir”, écrivez :
-    <<- __else__ -2>> _                                                                             # Incohérence : “\1” est une préposition. “\2” est un verbe conjugué.
-__[i]/conf(conf_a_à_locutions1)__
-    (a) (?:nouveau|présent|(?:bonne distance|bord|cause|contre-courant|côté|court|défaut|droite|gauche|l’(?:arrière|autre bout|écart|égard|extérieur|aune|avant|encontre|ins(?:u|tar)|intérieur|opposé)|la (?:portée|suite)|partir|portée|propos|rebours) d(?:es?|u))  @@0
-    <<- -1>> à                                                                                      # Confusion. Utilisez la préposition “à”.
-__[s]/conf(conf_a_à_locutions2)__
-    (a) (?:califourchon|contre(?:cœur|temps)|côté d(?:e|’\w[\w-]+)|demi-mot|nouveau|présent|rebrousse-poil|regret|travers|tout-va|l’(?:heure (?:actuelle|qu il est)|accoutumée|amiable|avance|aven(?:ir|ant)|air libre|aveuglette|emporte-pièce|évidence|exclusion de toute autre chose|improviste|inverse|ordre du jour|œil nu|en croire|un(?:animité| (?:d’entre eux|des leurs)|e (?:d’entre elles|des leurs)))|la (?:bonne franquette|con|dér(?:ive|obée)|diable|fois|limite du supportable|lumière de tout ce(?:ci|la)|mords-moi-le-nœud|papa|petite semaine|pointe du progrès|queue leu leu|rescousse|sauvette|surprise générale|va[ -]vite|virgule près|volée)|partir (?:de (?:demain|là|maintenant|rien)|d’(?:aujourd’hui|hier|ici))|au(?:cun prix|trui|tre chose)|bas co[ûu]t|bâ(?:bord|tons rompus)|beaucoup près|belles dents|bien (?:des égards|y (?:penser|réfléchir|songer))|bon (?:compte|escient|droit)|bout (?:de (?:bras|souffle|forces?)|portant|touchant)|bras (?:ouverts|le corps)|brève échéance|but non lucratif|cause d(?:e (?:ça|[mt]oi|lui|[nv]ous)|’e(?:lles?|ux))|ce (?:compte-là|moment-là|titre)|cet (?:égard|instant(?: précis|))|cette (?:époque(?: de l’année|)|heure de la (?:journée|nuit))|chaque (?:fois|instant)|chaudes larmes|cœur (?:joie|ouvert|perdu)|ciel ouvert|contre-cœur|corps perdu|cou(?:p sûr|per le souffle|rt terme|rte (?:échéance|portée))|couilles rabattues|de nombreuses reprises|des kilomètres à la ronde|dose homéopathique|double (?:titre|tranchant)|durée limitée|en (?:juger par (?:[mts]on|[nv]otre|leur) expérience|perdre (?:haleine|la tête))|faible (?:allure|revenu)|feu et à sang|flanc de (?:colline|montagne)|fleur de peau|géométrie variable|grand(?:-peine|e échelle)|haut risque|hue et à dia|huis clos|intervalles (?:ir|)réguliers|juste (?:raison|titre)|long terme|longue(?: échéance| portée|ur (?:de (?:temps|journée))|d’année)|loyer modéré|main (?:armée|droite|gauche|levée)|maint(?:s égards|es reprises)|marche forcée|merveille|mi-(?:course|distance|temps)|mi(?:di|nuit)(?: pile|)|moindres frais|moyen(?: terme|ne échéance)|mots couverts|ne (?:jamais|pas|rien|guère)|n’en (?:pas douter|point douter|plus finir)|outrance|parler franc|part (?:entière|ça|ce(?:la|ci))|partir de là|part(?:ir de rien|s égales)|pas de (?:géant|loup|tortue|velours)|personne en danger|perte de vue|petit(?: feu|e (?:dose|échelle))|peu (?:de choses? |)près|pieds joints|pile ou face|plat(?: ventre|e couture)|plein(?: (?:régime|temps|nez)|s poumons)|plus (?:forte raison|d’un titre)|point nommé|portée de main|première vue|prix (?:cassé|modique)s?|proprement parler|qui (?:mieux mieux|que ce soit|de droit)|quelque distance|quelques exceptions près|ras bords?|rude épreuve|tel point|temps (?:plein|partiel|complet)|tête reposée|tire[ -]d’aile|titre (?:conservatoire|d’exemple|indicatif|informatif|grâcieux|personnel|posthume)|tombeau ouvert|tort (?:ou à raison|et à travers)|tour de (?:bras|rôle)|tous (?:crins|points de vue)|tout(?: (?:âge|bout de champ|crin|instant|jamais|le (?:moins|monde)|moment|point de vue|prix|un chacun)|e (?:allure|bride|épreuve|force|heure|vitesse|volée))|toutes (?:fins utiles|jambes)|tribord|tu et à toi|un moment donné|usage interne|visage découvert|vive allure|voix (?:haute|basse)|vol d’oiseau|vrai dire|vue d’œil|y (?:regarder de plus près|réfléchir))  @@0
-    <<- not before(r"(?i)[ln]’$|(?<!-)\b(?:il|elle|on|y|n’en) +$")
-    -1>> à                  # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
-__[s]/conf(conf_a_à_locutions3)__
-    (a) (?:confesse|mi(?:di|nuit)|r(?:allonge|eculons|enverse|isque)|tâtons|vélo|la (?:manque|ramasse|re(?:dresse|nverse)))  @@0
-    <<- not before(r"(?i)(?:\bque? |[ln]’$|(?<!-)\b(?:il|elle|on|y|n’en) +$)")
-    -1>> à                  # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
-__[s]/conf(conf_a_à_locutions4)__
-    (a) (?:[mts](?:es|on|a)|[nv]o(?:s|tre)|leurs?) (?:avis|c(?:onnaissance|ôtés)|c(?:œur|orps) défendant|dé(?:pens|triment)|disposition|encontre|égard|grand(?: désarroi|e (?:surprise|tristesse))|guise|insu|portée|risques et périls|sujet|tour)  @@0
-    <<- not before(r"(?i)(?:\bque? |[ln]’$|(?<!-)\b(?:il|elle|on|y|n’en) +$)")
-    -1>> à                  # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
-__[s]/conf(conf_a_à_infi)__
-    (?<![mtn]’)(a) (?:[mts](?:’(?:en +|y +|)|e +)|[nv]ous|)({w_2}(?:er|re|ir))  @@0,2
-    <<- morph(\2, ":Y", False) and not before(r"(?i)\bque? |(?:il|elle|on|n’(?:en|y)) +$") 
-    -1>> à                  # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
-__[s]/conf(conf_a_à_après_interrogative)__
-    \w+-(?:je|ils?|elles?|je|tu|on|vous|nous) (a)(?! priori| posteriori| fortiori)  @@$
-    <<- -1>> à              # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
-
-
-TEST: Cette femme {{à}} été confondue avec une autre.
-TEST: L’homme {{à}} ouvert la boîte.
-TEST: Il ne nous reste plus qu’{{à}} {{vérifié}} si votre maquette.
-TEST: Je veux {{à}} {{mangé}}.
-TEST: Ne pas hésiter {{à}} {{demandé}} des conseils.
-TEST: cette femme, dans son délire, {{à}} {{jetez}} son argent à la poubelle.
+
+__conf_a_à_incohérences__
+    à [afin|alors|après|auprès|avant|avec|au-dedans|au-dehors|au-delà|au-dessous|au-dessus|au-devant|chez|dans|devant|dès|déjà|donc|durant|lorsque|lorsqu’|lorsqu|malgré|parce|parmi|pendant|pour|puisque|puisqu’|puisqu|quoique|quoiqu’|que|qu’|que|sur|tandis]
+        <<- /conf/ -1>> a                                           # Incohérence avec “\2”. Confusion probable : “à” est une préposition. Écrivez “a” pour la conjugaison de “avoir”.
+
+    à [au|aux]
+        <<- /conf/ not value(>1, "|moins|plus|mieux|") -1>> a       # Incohérence avec “\2”. Confusion probable : “à” est une préposition. Écrivez “a” pour la conjugaison de “avoir”.
+
+TEST: ce que cet homme, dans son garage, {{à}} alors une importance.
+TEST: ce que cette personne, dans son esprit trouble et vindicatif, {{à}} aux hommes à dire, nul ne le sait.
+
+
+__conf_a_à_verbe!6__
+    [n’|m’|t’|s’]   ?[en|y]¿        (à)
+    [l’|les]        [en|y]          (à)
+    [ne|me|te|se]   [les|l’]        (à)
+    [nous|vous]     [en|y|les|l’]   (à)
+    ne [le|la|les]  [leur|lui]      (à)
+    ne [le|la|les]  [leur|lui]      (à)
+    y en                            (à)
+        <<- /conf/ -1>> a                                           # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    y à
+        <<- /conf/ -2>> a                                           # Confusion probable : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    [l’|les|en] à
+        <<- /conf/ not \1.isupper() and not value(>1, "|côté|coup|pic|peu|plat|propos|valoir|")
+        -2>> a                                                      # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    [il|on]  [nous|vous]  à
+        <<- /conf/ -3>> a                                           # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    elle  [nous|vous]  à
+        <<- /conf/ not morph(<1, ":(?:3s|R)") and not morph(>1, ":Oo|>quo?i/")
+        -1>> 3                                                      # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    à été
+        <<- /conf/ -1>> à                                           # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    qui  à  @:Q¬:M
+        <<- /conf/ \3.islower() -2>> a                              # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+    qui  [lui|leur|nous|vous|y]  à
+        <<- /conf/ -3>> a                                           # Confusion : “à” est une préposition. Pour le verbe avoir, écrivez “a”.
+
+
+    à  le  @:[NAQ].*:[me]¬:(?:Y|Oo)
+        <<- /conf/ -1:2>> a le|au
+        # Confusion. Ou vous confondez “a” (préposition) avec “a” (avoir), ou vous devez employer “au”. Exemple : _à_ midi, il _a_ pris son déjeuner _au_ restaurant.
+
+    à  le  @:[NAQ].*:f¬:(?:Y|Oo)
+        <<- /conf/ -1:2>> à la|a la
+        # Confusion. Ou vous confondez “a” (préposition) avec “a” (avoir), ou vous devez employer “a la”. Exemple : _à_ midi, elle _a_ pris son déjeuner _a_ la cantine.
+
+    à  les  @:[NAQ]¬:(?:Y|Oo)
+        <<- /conf/ -1:2>> a les|aux
+        # Confusion. Ou vous confondez “a” (préposition) avec “a” (avoir), ou vous devez employer “aux”. Exemple : Elle _a_ donné du travail _aux_ employés _à_ profusion.
+
+    à  *WORD
+        <<- /conf/ \2.islower() and not value(\2, "|coté|") >>>
+        <<- morph(\2, ":(?:V.......[_z][az].*:Q|V1.*:Ip:2p)", ":[MGWNY]") -1>> a                    # Confusion probable : “à” est une préposition. Pour le verbe “avoir”, écrivez :
+        <<- __also__ and morph(\2, "V1.*:(?:Ip:2p|Q)", "*") and not value(<1, "|il|elle|on|n’|les|l’|m’|t’|s’|d’|en|y|lui|nous|vous|leur|")
+        -2>> =suggVerbInfi(\2)                                                                       # Le verbe devrait être à l’infinitif.
+        <<- __else__ and morph(\2, ":[123][sp]", "*") and not value(\2, "|tord|tords|") >>>
+        <<- morph(\2, ":V2.*:Ip:3s", "*") -2>> =suggVerbPpas(\2, ":m:s")                            # Incohérence : “\1” est une préposition. “\2” est un verbe conjugué.
+        <<- __also__ -1>> a                                                                         # Confusion probable : “à” est une préposition. Pour le verbe “avoir”, écrivez :
+        <<- __else__ -2>> _                                                                         # Incohérence : “\1” est une préposition. “\2” est un verbe conjugué.
+
 TEST: Ce fâcheux, comme à son habitude, les {{à}} ennuyés à mourir.
 TEST: Lui l’{{à}} pris par surprise.
-TEST: Les parties {{a}} nouveau divisées ne se réuniront pas avant longtemps.
-TEST: elles sont tout {{a}} fait compétentes
-TEST: c’est grâce {{a}} nous que vous y êtes parvenus
-TEST: elles se défendront jusqu’{{a}} la mort.
-TEST: ce qu’elles feront alors {{a coup sûr}}, difficile de le devenir.
-TEST: elles progressent pas {{a}} pas
 TEST: elle n’y {{à}} pas droit.
-TEST: elle risque de tout perdre, {{a}} moins qu’un miracle survienne.
-TEST: {{tout a coup}}, il n’y eut plus aucune lumière
 TEST: il y {{à}} des pertes.
 TEST: ce qui {{à}} pris tant de valeur, c’est…
-TEST: Ce chien, croyons-nous savoir, {{à le}} maître le plus violent qui soit.
+TEST: Cette femme {{à}} été confondue avec une autre.
 TEST: Il ne les leur {{à}} pas imposés.
 TEST: l’homme, jamais, ne la lui {{à}} imposés.
 TEST: l’homme, jamais, ne nous l’{{à}} prise.
 TEST: il me les {{à}} donnés
 TEST: il me l’{{à}} donné
 TEST: qui en {{à}} ?
-TEST: Il l’a fait {{a}} cause de toi.
+TEST: un élève qui leur {{à}} fait bien des misères.
 TEST: Il ne m’{{à}} jamais vu.
 TEST: Que fait-il {{a}} cette conférence ?
 TEST: Il m’en {{à}} donné.
 TEST: Il y en {{à}}.
-TEST: un machin ennuyeux {{a}} s’en tirer une balle dans la tête.
-TEST: ce que cet homme, dans son garage, {{à}} alors une importance.
 TEST: Il les y {{à}}.
-TEST: On {{à}} faim.
 TEST: Elle en {{à}} pris.
-TEST: Elle {{à}} froid.
 TEST: Elle l’en {{à}} averti.
+TEST: elle n’{{à}} rien raté.
 TEST: lui, avec ceux-là, nous en {{à}} donnés trois.
-TEST: un élève qui leur {{à}} fait bien des misères.
-TEST: cet homme {{à}} faim
-TEST: Je sais qu’ils sont {{a}} toi.
 TEST: Celui qui y croit {{à les}} moyens d’y parvenir.
-TEST: Face {{a}} ces gens, il ne pensait pas pouvoir réussir
-TEST: On s’y fait, d’une manière ou d’une autre, {{a}} notre corps défendant.
-TEST: Puisqu’on nous méprise, autant y aller {{a}} reculons.
+TEST: Ce chien, croyons-nous savoir, {{à le}} maître le plus violent qui soit.
+TEST: L’homme {{à}} ouvert la boîte.
+TEST: Il ne nous reste plus qu’{{à}} {{vérifié}} si votre maquette.
+TEST: Je veux {{à}} {{mangé}}.
+TEST: Ne pas hésiter {{à}} {{demandé}} des conseils.
+TEST: cette femme, dans son délire, {{à}} {{jetez}} son argent à la poubelle.
+TEST: Ce que cet homme à {{devient}} aujourd’hui notre problème
+TEST: il en a.
+TEST: elle en a.
+TEST: celle qui à contrario nous a foutu dans la merde.
+TEST: ceux qui à Somewhere se sont si mal illustrés.
+
+
+__conf_à_a_infinitif__
+    a  @:Y¬:G
+    a  [ne|n’|me|m’|te|t’|se|s’|en|y|lui|nous|vous]  @:Y
+    a  [n’|m’|t’|s’|l’|les|lui|nous|vous|leur] [en|y] @:Y
+    a  [le|la|l’|les|leur]  @:Y¬:N
+        <<- /conf/ not value(<1, "|il|elle|on|n’|m’|t’|") and not before(r"(?i)\bque? |n’(?:en|y) +$")
+        -1>> à                                                      # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
+
+TEST: scrupuleux {{a}} n’en toucher qu’une part infime.
 TEST: Ne pas hésiter {{a}} {{demander}} des conseils.
 TEST: Sébastien {{a}} {{demander}} des conseils.
-TEST: Personne {{a}} part Tom ne connaît son adresse
-TEST: Attention {{a}} ne pas la réveiller.
+
+
+__conf_à_peu_près__
+    a [peu|peux|peut] [près|>pré|>prête]
+    à [peux|peut] [près|>pré|>prête]
+    à peu [>pré|>prête]
+        <<- /conf/ ->> à peu près                                   # Confusion.|https://fr.wiktionary.org/wiki/%C3%A0_peu_pr%C3%A8s
+        <<- ~>> *
+
 TEST: C’est {{à peu prêt}} la même chose.
-TEST: ils viennent nous attaquer {{a}} tout bout de champ
+TEST: elle est {{a peut près}} au point.
+TEST: C’est à peu près ça.
+
+
+__conf_à_a__
+    [<start>|,] a moins [que|qu’|qu]
+        <<- /conf/ -2>> à                                           # Confusion probable : « à moins que » pour dire « sauf si ».
+
+    a [>coup|>cout|>coût|>cou] [sur|sûr]
+        <<- /conf/ ->> à coup sûr                                   # Confusion.|https://fr.wiktionary.org/wiki/%C3%A0_coup_s%C3%BBr
+
+    a part @:(?:M[12]|D|Oo)
+        <<- /conf/ -1>> à                                           # Confusion probable : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.
+
+    face a
+        <<- /conf/ not morph(<1, ":(D.*:f:s|A.*:[fe]:[si])|>en/")
+        -2>> à                                                      # Confusion probable : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.
+
+    par rapport  a  @:(?:D|Oo|M)
+        <<- /conf/ -3>> à                                           # Confusion : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.
+
+    grâce a
+        <<- /conf/ morph(<1, ":[VN]|<start>", "*") -2>> à           # Confusion probable.|https://fr.wiktionary.org/wiki/gr%C3%A2ce_%C3%A0
+
+    tout a fait
+    [jusqu’|jusqu] a
+    pas a pas
+        <<- /conf/ -2>> à                                           # Confusion : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.
+
+TEST: Personne {{a}} part Tom ne connaît son adresse
+TEST: ce qu’elles feront alors {{a coup sûr}}, difficile de le devenir.
+TEST: Face {{a}} ces gens, il ne pensait pas pouvoir réussir
+TEST: c’est grâce {{a}} nous que vous y êtes parvenus
 TEST: par rapport {{a}} eux, je me sens parfois dépassé
 TEST: par rapport {{a}} ces hommes-là, nous manquons d’expérience
-TEST: Ce que cet homme à {{devient}} aujourd’hui notre problème
-TEST: ce que cette personne, dans son esprit trouble et vindicatif, {{à}} aux hommes à dire, nul ne le sait.
+TEST: elles sont tout {{a}} fait compétentes
+TEST: elles se défendront jusqu’{{a}} la mort.
+TEST: elles progressent pas {{a}} pas
+
+
+__conf_à_a_locutions_de_des_du__
+    a bonne distance                                                                            [de|des|du]
+    a [bord|cause|contre-courant|côté|court|défaut|droite|gauche|partir|portée|propos|rebours]  [de|des|du]
+    a l’ [arrière|écart|égard|extérieur|aune|avant|encontre|insu|instar|intérieur|opposé]       [de|des|du]
+    a l’ autre bout                                                                             [de|des|du]
+    a la [portée|suite]                                                                         [de|des|du]
+        <<- /conf/ -1>> à                                           # Confusion probable : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.
+
+    a [base|cause] [de|des|du]
+        <<- /conf/ not tag_before(\1, "ce_que") -1>> à              # Confusion probable : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.
+
+TEST: travailler {{a}} bonne distance des fourneaux.
+TEST: Il l’a fait {{a}} cause de toi.
+
+
+__conf_à_a_locutions__
+    a [califourchon|contrecœur|contre-cœur|contretemps|contre-temps|demi-mot|nouveau|présent|rebrousse-poil|regret|travers|tout-va|confesse|midi|minuit|rallonge|reculons|risque|tâtons|vélo]
+    a côté [de|d’]
+    a l’ heure actuelle
+    a l’ heure [qu’|qu] il est
+    a l’ [accoutumée|amiable|avance|avenir|avenant|aveuglette|emporte-pièce|évidence|improviste|inverse]
+    a l’ air libre
+    a l’ exclusion de toute autre chose
+    a l’ ordre du jour
+    a l’ œil nu
+    a l’ en croire
+    a l’ unanimité
+    a l’ un d’ entre eux
+    a l’ un des leurs
+    a l’ une d’ entre elles
+    a l’ une des leurs
+    a la [con|dérive|dérobée|diable|fois|mords-moi-le-nœud|papa|rescousse|sauvette|va-vite|volée]
+    a la bonne franquette
+    a la limite du supportable
+    a la lumière de tout [ceci|cela|ça]
+    a la petite semaine
+    a la pointe du progrès
+    a la queue leu leu
+    a la surprise générale
+    a la va vite
+    a la virgule près
+    a partir [de|d’] [demain|là|maintenant|rien|aujourd’hui|hier|ici]
+    a aucun prix
+    a autrui
+    a autre chose
+    a bas [>coût|>cout]
+    a bâbord
+    a bâtons rompus
+    a beaucoup près
+    a belles dents
+    a bien des égards
+    a bien y [penser|réfléchir|songer]
+    a bon [compte|escient|droit]
+    a bout de [bras|souffle|>force]
+    a bout [portant|touchant]
+    a bras le corps
+    a bras ouverts
+    a brève échéance
+    a but non lucratif
+    a cause [de|d’] {pronom_obj}
+    a ce [compte-là|moment-là|titre]
+    a cet égard
+    a cet instant précis
+    a cette époque
+    a cette époque de l’année
+    a cette heure de la [journée|nuit]
+    a chaque [fois|instant]
+    a chaudes larmes
+    a cœur [joie|ouvert|perdu]
+    a ciel ouvert
+    a corps perdu
+    a couper le souffle
+    a court terme
+    a courte [échéance|portée]
+    a couilles rabattues
+    a de nombreuses reprises
+    a des kilomètres à la ronde
+    a dose homéopathique
+    a double [titre|tranchant]
+    a durée limitée
+    a en juger par [mon|ton|son|notre|votre|leur] expérience
+    a en juger par [mon|ton|son|notre|votre|leur] expérience
+    a en perdre haleine
+    a en perdre la tête
+    a faible [allure|revenu]
+    a feu et à sang
+    a flanc de [colline|montagne]
+    a fleur de peau
+    a géométrie variable
+    a grand-peine
+    a grande échelle
+    a haut risque
+    a hue et à dia
+    a huis clos
+    a intervalles [réguliers|irréguliers]
+    a juste [raison|titre]
+    a la [manque|ramasse|redresse|renverse]
+    a long terme
+    a longue [échéance|portée]
+    a longueur [de|d’] [temps|journée|année]
+    a loyer modéré
+    a main [armée|droite|gauche|levée]
+    a maints égards
+    a maintes reprises
+    a marche forcée
+    a merveille
+    a [mi-course|mi-distance|mi-temps]
+    a [midi|minuit] ?pile¿
+    a moindres frais
+    a moyen terme
+    a moyenne échéance
+    a mots couverts
+    a ne [jamais|pas|rien|guère|point]
+    a n’ en pas douter
+    a n’ en plus finir
+    a n’ en point douter
+    a outrance
+    a parler franc
+    a part [entière|ça|cela|ceci]
+    a partir de là
+    a partir de rien
+    a parts égales
+    a pas de [géant|loup|tortue|velours]
+    a personne en danger
+    a perte de vue
+    a petit feu
+    a petite [dose|échelle]
+    a peu de >chose près
+    a peu près
+    a pieds joints
+    a pile ou face
+    a plat ventre
+    a plate couture
+    a plein [régime|temps|nez]
+    a pleins poumons
+    a plus forte raison
+    a plus d’un titre
+    a point nommé
+    a portée de main
+    a première vue
+    a prix [cassé|cassés|>modique]
+    a proprement parler
+    a qui de droit
+    a qui mieux mieux
+    a qui que ce soit
+    a quelque distance
+    a quelques exceptions près
+    a ras >bord
+    a rude épreuve
+    a tel point
+    a temps [plein|partiel|complet]
+    a tête reposée
+    a [tire-d’aile|tire-d’ailes]
+    a tire d’ >aile
+    a titre [conservatoire|d’exemple|indicatif|informatif|grâcieux|personnel|posthume]
+    a titre d’ exemple
+    a tombeau ouvert
+    a tort et à travers
+    a tort ou à raison
+    a tour de [bras|rôle]
+    a tous crins
+    a tous points de vue
+    a tout [âge|crin|instant|jamais|moment|prix]
+    a tout bout de champ
+    a tout le [moins|monde]
+    a tout point de vue
+    a tout un chacun
+    a toute [allure|bride|épreuve|force|heure|vitesse|volée]
+    a toutes jambes
+    a toutes fins utiles
+    a tribord
+    a tu et à toi
+    a un moment donné
+    a usage interne
+    a visage découvert
+    a vive allure
+    a voix [haute|basse]
+    a vol d’ oiseau
+    a vrai dire
+    a vue d’ œil
+    a y [réfléchir|songer|penser]
+    a y regarder de plus près
+        <<- /conf/ not before(r"(?i)[ln]’$|(?<!-)\b(?:il|elle|on|y|n’en) +$")
+        -1>> à              # Confusion probable : “a” est une forme conjugée de “avoir”. Pour la préposition, écrivez “à”.|http://fr.wiktionary.org/wiki/%C3%A0
+
+    a [mon|ton|son|notre|votre|leur] [cœur|corps] défendant
+    a [mon|ton|son|notre|votre|leur] grand désarroi
+    a [mon|ton|son|notre|votre|leur] [avis|côté|détriment|encontre|égard|insu|sujet|tour]
+    a [ma|ta|sa|notre|votre|leur] grande [surprise|tristesse]
+    a [ma|ta|sa|notre|votre|leur] [connaissance|disposition|guise|portée]
+    a [mes|tes|ses|nos|vos|leurs] [dépens|côtés]
+    a [mes|tes|ses|nos|vos|leurs] risques et périls
+        <<- /conf/ not before(r"(?i)(?:\bque? |[ln]’$|(?<!-)\b(?:il|elle|on|y|n’en) +$)")
+        -1>> à              # Confusion probable : “a” est la conjugaison du verbe “avoir”. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
+
+TEST: Puisqu’on nous méprise, autant y aller {{a}} reculons.
+TEST: Les parties {{a}} nouveau divisées ne se réuniront pas avant longtemps.
+TEST: ils viennent nous attaquer {{a}} tout bout de champ
+TEST: On s’y fait, d’une manière ou d’une autre, {{a}} notre corps défendant.
 TEST: on fait ça {{a}} la va-vite.
+
+
+
+
+TEST: elle risque de tout perdre, {{a}} moins qu’un miracle survienne.
+TEST: {{tout a coup}}, il n’y eut plus aucune lumière
+TEST: un machin ennuyeux {{a}} s’en tirer une balle dans la tête.
+TEST: On {{à}} faim.
+TEST: Elle {{à}} froid.
+TEST: cet homme {{à}} faim
+TEST: Je sais qu’ils sont {{a}} toi.
+TEST: Attention {{a}} ne pas la réveiller.
+
+
 TEST: Je tenais à le lui faire savoir.
 TEST: il va falloir songer à les leur donner
 TEST: le coût est estimé à au moins 1000 milliards de dollars
 TEST: elle à qui nous avons donné notre cœur et pour laquelle nous avons tout tenté pour la faire aimer de nos concitoyens.
 TEST: jusqu’à parfois se mettre en danger
-TEST: les méthodes de l’à peu près ne suffisent pas.
-
-
-__[i]/conf(conf_celui_celle_à_qui)__
-    ce(?:lui|lles?|ux) (a) qui  @@w
-    <<- -1>> à                                  # Confusion. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
-
-TEST: Ceux {{a}} qui nous avons notifié le problème sont partis.
-TEST: Il y a qui au dîner ce soir ?
-
-
-__[i]/conf(conf_mener_à_bien)__
-    (m[eèé]n\w+) (a) bien  @@0,w
-    <<- morph(\1, ">mener ", False) and ( not before(r"\bque? ") or morph(word(-1), ">(?:falloir|aller|pouvoir) ", False, True) )
-    -2>> à                  # Confusion probable. Dans cette locution, utilisez la préposition « à ».|https://fr.wiktionary.org/wiki/mener_%C3%A0_bien
-    <<- __also__ ~>> \1
-
-TEST: Mener {{a}} bien cette guerre sera plus difficile qu’on le pense.
-TEST: Je peux mener {{a}} bien cette opération.
-TEST: Cette coalition que tu penses mener a bien l’intention de te trahir.
-
-
-__[i]/conf(conf_mettre_à_profit)__
-    (m(?:i[st]|ett)\w*).* (a) profit  @@0,w
-    <<- morph(\1, ">mettre ", False) -2>> à     # Confusion probable. Dans « mettre à profit », utilisez la préposition « à ».|https://fr.wiktionary.org/wiki/mettre_%C3%A0_profit
-
-TEST: Mettre {{a}} profit ses compétences
-TEST: Il a mis son talent {{a}} profit.
-
-
-__[s]/conf(conf_m_a_tuer)__
-    m’a +(tuer) @@$
-    <<- -1>> tué|tuée
-    # Cliché. Évitez cette erreur de grammaire délibérée, faite d’innombrables fois, pour mimer l’affaire Omar Raddad.|https://fr.wikipedia.org/wiki/Omar_m'a_tuer
-
-TEST: la réalité m’a {{tuer}}
-
-
-# après avoir
-__[i]/conf(conf_après_avoir)__
-    [àa] pr(?:êt|é|è)s? [aà] ?voire?
-    <<- ->> après avoir                                                     # Confusion générale.
-
-TEST: après avoir réussi son examen
-TEST: {{a pré a voire}} monté les marches
-
-
-# aux dépens
-__[i]/conf(conf_aux_dépens)__
-    (aux?) (dépend?s?)  @@0,$
-    <<- not \1.endswith("x") and not \1.endswith("X") -1>> aux              # Locution prépositive : « aux dépens de ».|https://fr.wiktionary.org/wiki/aux_d%C3%A9pens_de
-    <<- not \2.endswith("ens") and not \2.endswith("ENS") -2>> dépens       # Locution prépositive : « aux dépens de ».|https://fr.wiktionary.org/wiki/aux_d%C3%A9pens_de
-
-TEST: Ce sont des clichés {{au}} {{dépend}} d’un grand chef. Tout ça pour faire du buzz et exister médiatiquement.
-
-
-# au temps / autant
-__[i]/conf(conf_au_temps_pour_moi)__
-    (au ?tant?) pour moi @@0
-    <<- isStart() -1>> au temps                                             # Pour reconnaître son erreur, « au temps pour moi » est l’expression recommandée par l’Académie française.
-__[i]/conf(conf_autant_que_faire_se_peut)__
-    au t(?:emps|ant?) que f(?:aire|erre|ers?) [sc]e peu[xt]?
-    <<- ->> autant que faire se peut                                        # Locution adverbiale : « autant que faire se peut ».|https://fr.wiktionary.org/wiki/autant_que_faire_se_peut
-
-TEST: Je me suis trompé. {{Autant}} pour moi.
-TEST: on va y arriver, {{au temps que faire se peut}}…
-
-
-# ça / çà / sa
-__[i]/conf(conf_ça_sa)__
-    (ça) ({w_2}) @@0,3 <<- morph(\2, ":[NAQ].*:f") and not re.search("^seule?s?", \2) -1>> sa       # Confusion : “sa” (sa maison, sa passion) ≠ “ça” (ça vient, ça heurte).
-__[i]/conf(conf_sa_ça1)__
-    (sa) +({w_2}) @@0,$
-    <<- morphex(\2, ":G", ">(?:tr(?:ès|op)|peu|bien|plus|moins|toute) |:[NAQ].*:f") -1>> ça         # Confusion : “sa” (sa maison, sa passion) ≠ “ça” (ça vient, ça heurte).
-__[i>/conf(conf_sa_ça2)__       (sa) +(?:[dnmtsjl]’|lorsqu |qu |puisqu )  @@0 <<- -1>> ça           # Confusion : “sa” (sa maison, sa passion) ≠ “ça” (ça vient, ça heurte).
-__[i]/conf(conf_çà_ça)__        çà(?! et là) <<- not before(r"\b(?:[oO]h|[aA]h) +$") ->> ça         # Confusion : « çà » ne s’emploie plus guère que dans l’expression « çà et là ».
-__[i]/conf(conf_çà_et_là)__     ça et là <<- not morph(word(-1), ":R") ->> çà et là                 # Confusion : « ça » équivaut à « cela ». Dans l’expression « çà et là », « çà » équivaut à « ici ».
-__[s]/conf(conf_sa_fin)__       (sa) *$  @@0  <<- -1>> ça                           # Confusion probable : “sa” est un déterminant féminin singulier. Pour l’équivalent de “cela” ou “ceci”, écrivez :
-
-TEST: Je prends {{sa}}…
-TEST: {{ça}} patrie, il la détestait
-TEST: et {{sa}} par deux fois
-TEST: Il trouva de la nourriture {{ça et là}}.                                ->> çà et là
-TEST: Elle parle comme {{ça}} mère.                                           ->> sa
-TEST: C’est comme {{sa}}.
-TEST: {{sa}} l’ennuierait, ce fils de pute, de dire bonjour ?
-TEST: il faut s’y prendre comme {{sa}}
-TEST: on fait {{sa}} lorsqu’on a tout perdu
-TEST: avec sa presque belle-mère
-TEST: sa toute nouvelle application de synchronisation de fichiers
-
-
-# ce / se / ceux
-__[s]/conf(conf_se_verbe)__
-    ([cC]e) ({w_2})  @@0,3
-    <<- \2[0].islower() and \2 != "faire"
-        and ( morphex(\2, ":V[123].*:(?:Y|[123][sp])", ":[NAGM]|>(?:devoir|pouvoir|sembler) ") or re.search("-(?:ils?|elles?|on)$", \2) )
-    -1>> se                                                                 # Confusion : « \2 » est un verbe. Exemples : ce bâtiment, se perdre.
-__[i]/conf(conf_pour_ce_faire)__
-    pour (se) faire,? ({w_2})  @@5,$
-    <<- (\0.find(",") >= 0 or morphex(\2, ":G", ":[AYD]"))
-    -1>> ce                                                                 # Confusion probable. Dans cette locution, il faut employer “ce”.|http://fr.wiktionary.org/wiki/pour_ce_faire
-__[i]/conf(conf_ne_se1)!6__
-    ne (ce) @@3 <<- -1>> se                                                 # Confusion. Ce chien, ce chat… Se demander, se croire…
-__[i>/conf(conf_ne_se2)__
-    ne ([cç]’) @@3 <<- -1>> s’                                              # Confusion. Ce chien, ce chat… Se demander, se croire…
-__[i]/conf(conf_ce_conj_prep)__
-    (se) (?:qu[ei]?|dont|malgré|pourquoi|avec|pour|par) @@0 <<- -1>> ce     # Confusion. Exemples : ce bâtiment, se perdre.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440
-__[i]/conf(conf_qui_se_verbe)__
-    qui (ce) ({w_2})  @@4,$
-    <<- morphex(\2, ":V", ":[NAQ].*:[me]") or before(r"(?i)\b[cs]e +$")
-    -1>> se                                                                 # Confusion probable. Exemples : ce bâtiment, se perdre.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440
-__[i]/conf(conf_ceux_ce_être)__
-    (ceux) (?:ne |)(?:sont|serai(?:en|)[ts]?|f[uû](?:ren|)t|n’(?!ayant|étant)\w+) @@0
-    <<- -1>> ce                                                             # Confusion.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829
-__[s]/conf(conf_ce_ne_être_doit)__
-    ([sS]e) n(?:e |’)({être}|d[eouû]\w+|p[oeuû]\w+)  @@0,$
-    <<- morph(\2, ">(?:être|pouvoir|devoir) .*:3s", False)
-    -1>> ce                                                                 # Confusion probable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440
-__[i]/conf(conf_ce_ne)__
-    (ceux) ne ({w_2}) @@0,$
-    <<- morphex(\2, ":[123]s", ":P") -1>> ce                                # Confusion.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829
-__[i]/conf(conf_ce_nom1)__
-    (se) ({w1}) @@0,3
-    <<- morphex(\2, ":[NAQ]", ":([123][sp]|Y|P|Q)|>l[ea]? ") -1>> ce        # Confusion. Ce chien, ce chat… Se demander, se croire…
-__[i]/conf(conf_ce_nom2)__
-    (ceux) (?!l[aà] |qu[ie]? )({w_2}) @@0,$
-    <<- morphex(\2, ":N.*:s", ":(?:A.*:[pi]|P|R)|>autour ") -1>> ce         # Confusion probable.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829
-
-TEST: il ne {{ce}} compte pas parmi eux
-TEST: il ne {{ç’}}avançait jamais sans avoir pesé toutes les conséquences
-TEST: {{Se}} seraient des histoires.
-TEST: {{se}} seraient des jours heureux.
-TEST: {{Se}} sont de grands enfants.
-TEST: {{Se}} sera une fille.
-TEST: {{ceux}} seraient des jours heureux
-TEST: Pour {{se}} faire, ils sont prêts à tout.
-TEST: {{se}} {{ne}} peut être ainsi.
-TEST: C’est tout {{se}} qu’il y a
-TEST: Tout {{se}} que je fais
-TEST: tout {{se}} qu’il entend
-TEST: {{Ce}} {{promener}} est relaxant.
-TEST: Il {{ce}} {{sent}} seul
-TEST: {{se}} {{train}} est en retard
-TEST: {{ceux}} train arrive trop vite.
-TEST: {{ceux}} ne doit pas nous faire oublier ce désastre
-TEST: qui {{ce}} donne en spectacle.
-TEST: {{ce}} prennent-ils pour des experts ?
-TEST: les expatriés éloignés ou ceux habitant ici
-TEST: les photographies de ceux n’ayant pas dépassé sept sur vingt.
-TEST: Pensez-vous que ceux ne sachant même pas ce qu’est une VHS peuvent y trouver leur compte ?
-TEST: la réduction de ma liberté intellectuelle et celle de ceux autour de moi
-TEST: […] qui ne peut être si ardente qu’elle ne se doive, ce semble, éteindre par la moindre goutte de sang qui sorte de leurs plaies.
-TEST: à qui ce texte doit tant, à qui ce texte est dédié
-
-
-# ce à quoi
-__[i]/conf(conf_ce_à_quoi)__
-    (?:se [àa] quoi|ce a quoi)
-    <<- ->> ce à quoi                                   # Confusion.|https://fr.wiktionary.org/wiki/ce_%C3%A0_quoi
-
-TEST: c’est {{se a quoi}} il pensait qui le minait.
-
-
-# ces / ses / c’est
-__[s]/conf(conf_c_est1)__
-    ([scSC]es) (?:à|au-dessus|avec|aux?|contre|derrière|devant|par|pour|sans) (?:l(?:es?|a|)|une?|[cs]es?|cette|de?s?|du|lui|elles?|eux|nous|vous)  @@0
-    <<- -1>> c’est                                                                          # Confusion. Écrivez « c’est » pour dire « ceci est… ».
-__[s>/conf(conf_c_est2)__
-    ([scSC]es) [ld]’(?![A-Z])  @@0
-    <<- -1>> c’est                                                                          # Confusion. Écrivez « c’est » pour dire « ceci est… ».
-__[s]/conf(conf_c_est3)__
-    ([scSC]es) (?:qu(?:lle|el?|)|comme|ce(?:t|tte|)|[nv]os|les?|eux|elles)  @@0
-    <<- -1>> c’est                                                                          # Confusion probable. Écrivez « c’est » pour dire « ceci est… ».
-__[s]/conf(conf_c_est4)__
-    ([scSC]es) ({w_1}) ({w_1}) @@0,w,$
-    <<- morph(\2, ":[WX]", ":N:.*:[pi]") and morph(\3, ":[RD]|>pire ", False) -1>> c’est           # Confusion probable. Écrivez « c’est » pour dire « ceci est… ».
-__[i]/conf(conf_ces_ses)__
-    (c’est) ({w_2})  @@0,6 <<- morphex(\2, ":N.*:p", ":(?:G|W|M|A.*:[si])") -1>> ces|ses    # Confusion. Exemples : c’est facile ; ces chats (désignation) ; ses chats (possession)…
-
-TEST: {{ses}} au-dessus de ses forces.
-TEST: {{ces}} comme la peste
-TEST: car {{ses}} d’avance perdu
-TEST: {{ces}} qu’il y a tant de pertes
-TEST: {{ces}} jamais une bonne idée.
-TEST: {{c’est}} {{délires}} nous ennuient
-TEST: En 2015, c’est Paris et son agglomération qui…
-TEST: Ses pas de danse.
-
-
-# compte / comte / conte
-__[i]/conf(conf_à_bon_compte)__
-    à bon (co[nm]te)  @@$
-    <<- -1>> compte                                                             # Confusion. Locution “à bon compte”.|https://fr.wiktionary.org/wiki/%C3%A0_bon_compte
-__[i]/conf(conf_à_ce_compte_là)__
-    à ce (co[nm]te)-là  @@*
-    <<- -1>> compte                                                             # Confusion probable. Locution “à ce compte-là”.|https://fr.wiktionary.org/wiki/%C3%A0_ce_compte-l%C3%A0
-__[i]/conf(conf_compte)__
-    (co[mn]tes?)[ -](à (?:rebours|découvert|terme)|bancaires?|des opérations|tenus?|rendus?|joints?|courants?|chèques?) @@0,$
-    <<- not \1.startswith("tenu") or isStart() -1>> compte|comptes              # Confusion probable. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez :
-__[i]/conf(conf_en_fin_de_compte)__
-    en (f(?:aim|in)s?|lignes?) de co[nm]tes?  @@w
-    <<- \1.startswith("f") ->> en fin de compte                                 # Confusion. Locution “en fin de compte”.|https://fr.wiktionary.org/wiki/en_fin_de_compte
-    <<- \1.startswith("l") ->> en ligne de compte                               # Confusion. Locution “en ligne de compte”.|https://fr.wiktionary.org/wiki/en_ligne_de_compte
-__[i]/conf(conf_la_cour_des_comptes)__
-    la cour des (co[nm]tes)  @@$
-    <<- -1>> comptes                                                            # Confusion. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez :
-__[i]/conf(conf_loin_du_compte)__
-    loin du (co[mn]te)  @@$
-    <<- -1>> compte                                                             # Confusion. Locution “loin du compte”.|https://fr.wiktionary.org/wiki/loin_du_compte
-__[i]/conf(règlement_de_comptes)__
-    r[éè]glements? de (co[mn]tes?)  @@$
-    <<- -1>> comptes                                                            # Confusion.|https://fr.wiktionary.org/wiki/r%C3%A8glement_de_comptes
-__[i]/conf(régler_son_compte)__
-    (r[éè]gl\w+) +(?:[mts]on|leurs?|[vn]otre) (co[mn]tes?)  @@0,$
-    <<- morph(\1, ">régler ", False) -2>> compte                                # Confusion. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez :|https://fr.wiktionary.org/wiki/r%C3%A9gler_son_compte
-__[i]/conf(conf_tout_compte_fait)__
-    tout (co[mn]te) fait  @@w
-    <<- -1>> compte                                                             # Confusion. Locution “tout compte fait”.|https://fr.wiktionary.org/wiki/tout_compte_fait
-
-TEST: il s’en est tiré à bon {{conte}}.
-TEST: à ce {{conte}}-là, il ne va pas faire long feu.
-TEST: mon {{comte}} bancaire est encore à sec.
-TEST: {{comte}} tenu du dysfonctionnement du moteur
-TEST: mais {{en fin de comte}}, ce n’était qu’une arnaque de plus.
-TEST: Rien de tout ceci n’entre {{en ligne de conte}}.
-TEST: la cour des {{contes}} publie un nouveau rapport.
-TEST: Ils sont encore tous deux loin du {{conte}}.
-TEST: Elle a l’impression d’être laissée pour {{comte}}.
-TEST: C’est un règlement de {{comte}} entre voyous.
-TEST: on va lui régler son {{conte}}, à cet enculé.
-TEST: tout {{conte}} fait, ça reste un salopard.
-
-
-__[i]/conf(conf_conte_de_fée)__
-    (comp?tes?) (?:de (?:bonnes? femmes?|fées?)|allégoriques?|fantastiques?|littéraires?|merveilleux|mora(?:l|ux)|ora(?:l|ux)|populaires?|satiriques?|traditionnels?|véhiculés?|et légendes?)  @@0
-    <<- -1>> conte|contes                                                       # Confusion probable. Si vous parlez d’un récit, écrivez :|https://fr.wiktionary.org/wiki/conte
-
-TEST: Encore un {{comte}} de fée, assez de ces fadaises !
-TEST: c’est un {{compte}} allégorique.
-TEST: {{Comptes}} et légendes des Terres du Milieu.
-TEST: ce sont des {{comptes}} de bonnes femmes
-TEST: Elle parla au comte d’amour, mais il fit mine de n’y rien entendre.
-
-
-# date / datte
-__[i]/conf(conf_date1)__
-    dates
-    <<- after("(?i)^ +(?:fra[iî]ches|dénoyautées|fourrées|sèches|séchées|cultivées|produites|muscade|medjool|Hamraya|deglet[ -]nour|kenta|allig|khouat)")
-        or before(r"(?i)\b(?:confiture|crème|gâteau|mélasse|noyau|pâte|recette|sirop)[sx]? de +$|\b(?:moelleux|gateau|fondant|cake)[sx]? aux +$")
-    ->> dattes                                                                              # Confusion probable : le fruit s’écrit avec deux “t”.
-
-TEST: il va faire un cake aux {{dates}}.
-TEST: elle a fait de la confiture de {{dates}}
-TEST: Elles étaient à cette date cultivées à l’air libre.
-TEST: De fraîche date…
-
-
-# d’en / dans
-__[i]/conf(conf_dans1)__
-    (d’en|dan) (?:l(?:es?|a)|une?|d(?:es?|u)|[mts](?:on|a|es)|[nv]o(?:tre|s)|ce(?:tte|t|s|))  @@0
-    <<- \1.endswith("en") or isRealStart() -1>> dans                                # Confusion. Utilisez “dans” pour dire “à l’intérieur de quelque chose”.
-__[i]/conf(conf_dans2)__
-    ^ *(dents?) (?:l(?:es?|a)|une?|[mts](?:on|a|es)|[nv]o(?:tre|s)|ce(?:tte|t|s|))  @@*
-    <<- -1>> dans                                                                   # Confusion. Utilisez “dans” pour dire “à l’intérieur de quelque chose”.
-
-TEST: {{dan}} la voiture
-TEST: ils sont partis {{d’en}} une direction différente
-TEST: {{dents}} les montagnes au loin.
-
-
-# davantage / d’avantage
-__[i]/conf(conf_d_avantages)__
-    (?:peu|plein|beaucoup|trop|plus|moins|assez|suffisamment|tellement|obtentions?|régimes?) (davantage)  @@$
-    <<- -1>> d’avantages                                                            # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
-__[i]/conf(conf_être_davantage_ppas)__
-    ({etre}) (d’avantages?) ({w_2}) @@0,w,$
-    <<- morph(\1, ":V0e", False) and morphex(\3, ":[NAQ]", ":G") -2>> davantage     # Confusion possible : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
-__[i]/conf(conf_davantage1)__
-    ({w1}) (d’avantages?) @@0,$
-    <<- morphex(\1, ":V", ":Q|>(?:profiter|bénéficier|nombre) ") and not morph(word(1), ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s? ", False, False)
-    -2>> davantage                                                                  # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
-__[i]/conf(conf_davantage2)__
-    ({w_1})-(?:je|tu|ils?|elles?|[nv]ous|on) +(d’avantages?) @@0,$
-    <<- not morph(\1, ">(?:profiter|bénéficier) ", False) and not morph(word(1), ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s? ", False, False)
-    -2>> davantage                                                                  # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
-__[i>/conf(conf_davantage3)__
-    (d’avantages?) d(?:e +|’) @@0
-    <<- -1>> davantage                                                              # Confusion possible : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
-
-TEST: ils ont peu {{davantage}} à vivre ici.
-TEST: Ils s’exerceront {{d’avantages}}.
-TEST: {{d’avantage}} de monde de jour en jour
-TEST: Viens-tu {{d’avantage}} à la maison
-TEST: {{d’avantage}} de monde viendra
-TEST: ils sont {{d’avantages}} perdus que les autres.
-TEST: tout ce qu’il apporte d’avantages pécuniaires.
-TEST: un certain nombre d’avantages sociaux.
-
-
-# différend / différent
-__[i]/conf(conf_différent)__
-    différends?
-    <<- morph(word(-1), ":W", False, False) ->> =\0.replace("end", "ent")           # Confusion probable : “un différend” est un désaccord. Pour l’adjectif qualifiant une différence, écrivez :
-__[i]/conf(conf_différend1)__
-    (?:mon|[vn]otre|leur) +(différent) @@$
-    <<- morphex(word(1), ":[GVX]", ":[NAQ]", True)
-    -1>> différend                                          # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
-__[i]/conf(conf_différend2)__
-    [ts]on +(différent) @@$
-    <<- morphex(word(1), ":[GVX]", ":[NAQ]", True) and not morph(word(-1), ":D", False, False)
-    -1>> différend                                          # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
-__[i]/conf(conf_un_différend)__
-    un (différent)  @@3
-    <<- morphex(word(1), ":[GV]", ":[NAQ]", False)
-    -1>> différend                                          # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
-__[i]/conf(conf_différends)__
-    (?:leurs|[mts]es|[nv]os) (différents) @@$
-    <<- morphex(word(1), ":[GV]", ":[NAQ]", True)
-    -1>> différends                                         # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
-__[i]/conf(conf_les_différends)__
-    (?:[ld]es) (différents) @@$
-    <<- morphex(word(1), ":G", ":[NAQ]", False)
-    -1>> différends                                         # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
-__[i]/conf(conf_être_différent)__
-    ({etre}) +(?:pas +|)(?:si +|)(différends?)  @@0,$
-    <<- morph(\1, ":V0e", False)
-    -2>> =\2.replace("nd", "nt")                            # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
-
-TEST: Très {{différends}} de nous, ces gens-là !
-TEST: Régler votre {{différent}}.
-TEST: Notre {{différent}} avec eux perdure.
-TEST: Un {{différent}} peut toujours se résoudre.
-TEST: J’en ai marre de leurs {{différents}}.
-TEST: Il y a des {{différents}} que nul ne saurait résoudre.
-TEST: ce qui l’occupe, c’est son {{différent}} avec eux.
-TEST: Ils sont pas {{différends}} de nous.
-TEST: Cette fois, il parla avec un ton différent.
-TEST: J’en veux un différent.
-TEST: dans ses différents ouvrages
-TEST: dans ses différents postes gouvernementaux
-
-
-# eh bien, hé bien / et bien
-__[i]/conf(conf_eh_bien)__
-    et bien(?! que?| sûr| d’autres| entendu| avant| souvent| longtemps| des| moins| plus| au-delà)
-    <<- isStart() and not morph(word(1), ":[WAY]", False, False)
-    ->> eh bien|hé bien                                     # Confusion probable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=h%C3%A9&T3.x=0&T3.y=0
-__[i]/conf(conf_eh_ben)__
-    et (ben)  @@3
-    <<- not \1.startswith("B")
-    ->> eh ben|hé ben                                       # Confusion probable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=h%C3%A9&T3.x=0&T3.y=0
-
-TEST: {{et bien}} il y aura des pertes
-TEST: {{et ben}} on n’en sait rien.
-TEST: nous y songions, et bien au-delà des considérations habituelles.
-TEST: une image bien plus colorée, et bien plus intense, de la vie.
-TEST: Toutes ces questions, et bien d’autres, sont vues aujourd’hui dans le paradigme quantitatif de la monnaie, des taux de change flottants et de la monnaie administrée.
-TEST: et bien manger, c’est important.
-TEST: il a été vaincu, et bien vaincu.
-
-
-# faut / faux
-__[i]/conf(conf_faux)__
-    faut
-    <<- not morph(word(-1), ">(?:ils?|ne|en|y|leur|lui|nous|vous|[mtsl]e|la|les) ", False, True) and morphex(word(1), ":",  ":(?:Y|Oo|X|M)", True)
-    ->> faux                                                # Confusion probable : “faut” est une conjugaison de “falloir”. Pour indiquer la fausseté d’une chose, écrivez :
-
-TEST: un homme {{faut}}
-TEST: c’est {{faut}}
-TEST: il m’en faut plus.
-TEST: il faut réussir.
-TEST: bien sûr, faut y arriver.
-TEST: il ne faut pas se leurrer.
-TEST: y faut pas qu’elle l’entende.
-TEST: faut l’emmener chez le docteur.
-TEST: Faut Linux, sinon ça marchera jamais.
-
-
-# flan / flanc
-__[i]/conf(conf_flan)__
-    (flancs?) (?:aux? (?:caramel|café|citron|chocolat|four|lait|lard|noix|pomme|pruneaux?|œuf|raisin)s?|d’(?:or|argent)|de cuivre|pâtissier|à la (?:crème|coco|noix))  @@0
-    <<- -1>> =\1.replace("c", "").replace("C", "")                                                  # Confusion. S’il s’agit d’une pâtisserie (ou d’une pièce de métal), écrivez :|https://fr.wiktionary.org/wiki/flan
-__[i]/conf(conf_c_est_du_flan)__
-    c’(?:est|était) (?:que +|rien que +|tout +|)du (flanc) @@$
-    <<- -1>> flan                                                                                   # Confusion. Locution « c’est du flan ».|https://fr.wiktionary.org/wiki/flan
-__[i]/conf(conf_comme_deux_ronds_de_flan)__
-    comme deux ronds de (flancs?)  @@$
-    <<- -1>> flan                                                                                   # Confusion. Locution « comme deux ronds de flan ».|https://fr.wiktionary.org/wiki/comme_deux_ronds_de_flan
-
-TEST: encore un {{flanc}} au chocolat.
-TEST: ce type, c’est que du {{flanc}}.
-TEST: j’en étais comme deux ronds de {{flancs}}
-
-
-__[i]/conf(conf_flanc)__
-    (flans?) (?:des? (?:la |)(?:colline|montagne)s?|gauches?|droites?|nord|sud|ouest)  @@0
-    <<- -1>> =\0.replace("an", "anc").replace("AN", "ANC")                                          # Confusion probable. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
-__[i]/conf(conf_sur_le_flanc)__
-    ((?:attaqu|allong|bless|couch|étend|touch)\w+) +sur (?:les?|[mts](?:on|es)|[nv]o(?:tre|s)) (flans?)  @@0,$
-    <<- morph(\1, ">(?:attaquer|allonger|blesser|coucher|étendre|toucher) ", False)
-    -2>> =\0.replace("an", "anc").replace("AN", "ANC")                                              # Confusion probable. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
-__[i]/conf(conf_tirer_au_flanc)__
-    (tir\w*)[ -]+aux?[ -](flans?)  @@0,$
-    <<- morph(\1, ">tir(?:er|) ", False) -2>> =\0.replace("an", "anc").replace("AN", "ANC")         # Confusion. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
-
-TEST: attaqué sur son {{flan}} droit
-TEST: elle possède une maison à {{flan}} de colline.
-TEST: étendu sur son {{flan}}.
-TEST: Ce sale tir-au-{{flan}} le paiera cher.
-TEST: le flan est une pâtisserie.
-TEST: versez du caramel sur le flan.
-
-
-# golf / golfe
-__[i]/conf(conf_golf)__
-    (champion(?:ne|nat|)s?|clubs?|joueu(?:r|se)s?|parcours|sacs?|balles?|terrains?|tournois?|compétitions?|passionnée?s?|écoles?|professeurs?|parties?|professionnel(?:le|)s?|amateure?s?|stages?|journées?|après-midi|matinées?|heures?|fédérations?|fans?) de (golfe)  @@0,$
-    <<- -2>> golf                                                           # Confusion. Le golfe est une zone de mer ou d’un lac avancée dans les terres. Ex : Le golfe Persique.
-__[i]/conf(conf_golfe)__
-    (golf) (persique|d[ue] (?:Bengale|Botnie|Gascogne|Gabès|Guinée|Lion|Morbihan|Mexique|Porto|Saint-Laurent|Thaïlande|Tonkin|Tunis|Winam)|d’(?:Aden|Ajaccio|Alaska|Hammamet))  @@0,$
-    <<- -1>> golfe                                                          # Confusion. Le golf est un sport.
-__[i]/conf(conf_Golfe)__
-    (?:guerre|émir|monarchie)s? du (golf) @@$ <<- -1>> Golfe                # Confusion. Le golf est un sport.             
-
-TEST: Il a réalisé un documentaire sur la guerre du {{Golf}}.
-TEST: C’est un bon joueur de {{golfe}}.
-TEST: Le {{golf}} Persique est presque une mer fermée.
-TEST: J’ai fait de la voile dans le {{golf}} du Morbihan.
-TEST: Le {{golf}} d’Aden.
-
-
-# haut delà / au-delà
-__[i]/conf(conf_au_delà)__      haut[- ]del[àa] <<- ->> au-delà             # Confusion. 
-
-TEST: il va dans l’{{haut delà}}
-
-
-# héro / héros
-__[i]/conf(conf_héros)__
-    (?:le|quel|cet?|un|du|au) (héro) @@$
-    <<- -1>> héros                                          # Confusion. L’héro est l’abréviation de “héroïne” (la drogue). L’homme héroïque s’écrit “héros”.
-
-TEST: Mon frère, {{ce}} {{héro}} !
-
-
-# hors / or
-__[i>/conf(conf_hors_or1)__
-    ^ *(hors),  @@* <<- -1>> or
-    # Confusion. Écrivez “or” pour dire “néanmoins”. La préposition “hors” sert à dire “en dehors de” ou “excepté”.|https://fr.wiktionary.org/wiki/hors
-__[i]/conf(conf_hors_or2)__
-    (hors) (?:j(?:e|’[\w-]+)|tu|ils?|on|parce|quel(?:le|)s?|pourquoi|qu[ie])  @@0 <<- -1>> or,
-    # Confusion probable. Écrivez “or” pour dire “néanmoins”. La préposition “hors” sert à dire “en dehors de” ou “excepté”.|https://fr.wiktionary.org/wiki/hors
-
-TEST: {{hors}}, nous y coryons malgré tout ce qu’on peut en dire.
-TEST: {{Hors}} il y a tant à faire depuis que nous sommes arrivés en ces lieux.
-TEST: Hors nous, personne ne sait ce qui s’est passé là-bas.
-TEST: Le peuple se sent hors jeu.
-
-
-# la / là
-__[s]/conf(conf_la_là)__
-    ([lL]a) (?:a(?:fin|lors|près|uprès|ux?|vant|vec)|au(?:-de(?:dans|hors|là|sso?us|vant)|x|)|c(?:e(?:t|te|s|)|ar|hez|omme)|ça|d(?:ans|evant|es?|ès|onc|urant|’{w_1})|e(?:lles?|n|t)|ils?|je?|l(?:es?|a|orsque?|’{w_1})|m(?:algré|es|on|a|e)|n(?:e|ous)|o[uùn]|par(?:ce|fois|mi|)|p(?:arce|endant|our|uisque)|qu(?:e?|and)|s(?:on|a|es?|ouvent|ur)|t(?:andis|on|a|es?|u)|un|vous)
-    @@0
-    <<- not morph(word(-1), ":E|>le ", False, False)
-    -1>> là                                                                                         # Confusion probable. Écrivez “là” si vous voulez dire “ici”.
-
-TEST: nous serions encore {{la}} l’année prochaine
-TEST: en reprenant le chandail de John {{la}} où elle l’avait abandonné.
-TEST: Qui serait la ou le plus à même à occuper ce poste selon vous ?
-
-
-__[i]/conf(conf_tiret_la_là)__
-    ce(?:te|s|) +{w_2}-(la) @@$
-    <<- -1>> là                                                                                     # Confusion. Écrivez “là” soudé au nom pour désigner un objet précis.
-
-TEST: Ce {{fait}}-{{la}} ne peut être ignoré.
-
-
-# les / lés / lès
-__[i]/conf(conf_les1)__
-    (lés) +({w_2})  @@0,$
-    <<- morph(\2, ":N.*:m:[pi]") -1>> les                                                           # Confusion probable. Un lé est une bande de tissu ou de papier peint.|https://fr.wiktionary.org/wiki/l%C3%A9
-
-TEST: Entre les saules et {{lés}} ifs.
-TEST: Les asphaltes purs d’étanchéité sont des mastics bitumineux, de même que les masses d’enrobage des lés d’étanchéité.
-TEST: Pour avoir fait de neuf une grande cage de bois de grosses solives, membrures et sablières, contenant neuf pieds de long sur huit de lé. (Victor Hugo)
-TEST: Un lé de velours, de taffetas, de toile.
-TEST: Draps de lit de deux lés.
-
-
-__[i]/conf(conf_les2)__
-    lès
-    <<- isEnd() or morph(word(-1), ":D.*:p") ->> lés                                                # Confusion probable : “lès” signifie “à côté de” et ne s’emploie plus guère que dans des noms de ville, comme Garges-lès-Gonesse. Si vous parlez des bandes de tissu ou de papier peint, écrivez :|https://fr.wiktionary.org/wiki/l%C3%A8s
-    <<- __else__ ->> les                                                                            # Confusion probable : “lès” signifie “à côté de” et ne s’emploie plus guère que dans des noms de ville, comme Garges-lès-Gonesse ou Vandœuvre-lès-Nancy.|https://fr.wiktionary.org/wiki/l%C3%A8s
-
-TEST: Montrez-moi ces {{lès}} venus d’Italie.                           ->> lés
-TEST: avec {{lès}} hommes d’à côté, difficile de se concentrer.         ->> les
-TEST: Entre les saules et {{lès}} ifs                                   ->> les
-TEST: Elle habite Vandœuvre-lès-Nancy.
-
-
-# leurs / leur
-__[i]/conf(conf_leurs_verbe)__
-    (leurs) ({w_2})  @@0,6
-    <<- morphex(\2, ":(?:[123][sp]|Y)", ":(?:G|N|A|M[12P])") and not before(r"(?i)\b[ld]es +$")
-    -1>> leur                                                                                       # Incohérence : “leurs” est un déterminant pluriel censé précéder un substantif pluriel. Pour le pronom personnel devant un verbe, écrivez :
-
-TEST: je vais {{leurs}} reprendre
-TEST: je {{leurs}} apprends la programmation
-TEST: après qu’un des leurs ait été gravement blessé par un tir de grenade
-
-
-# loin s’en faut
-__[i]/conf(conf_loin_s_en_faut)__
-    loins? +(?:[sc]ens|san[gs]?s?|s[’ ]en) +fau[xt]
-    <<- not re.search("(?i)loin s’en faut", \0) and morph(word(-1), ":N", ">(?:aller|venir|partir) ", True)
-    ->> loin s’en faut                                                                              # Confusion probable. Cette locution s’écrit :|https://fr.wiktionary.org/wiki/loin_s%E2%80%99en_faut
-
-TEST: Ils n’étaient guère prêts à ça, {{loins sans faux}}.
-TEST: Et les intellectuels ? En France comme ailleurs, tous n’ont pas, loin s’en faut, une pleine lucidité sur cette précarité galopante.
-
-
-# mai / mais
-__[i]/conf(mais)__
-    (mai) +({w_1}) @@0,$
-    <<- morphex(\2, ":O", ":3s") and isStart() -1>> mais            # Confusion probable : “mai” est le 5ᵉ mois de l’année. Pour la conjonction de coordination, écrivez “mais”.|https://fr.wiktionary.org/wiki/mais
-
-TEST: {{mai}} il y a encore tant à faire.
-TEST: Je viendrai, {{mai}} il faudra avoir tout prévu.
-TEST: Mai pluvieux.
-
-
-# min / mins
-__[u]/conf(conf_symbole_min)__  \d+ (mins) @@$ <<- -1>> min                                         # Les unités de mesure abrégées ne prennent pas la marque du pluriel.
-
-TEST: 120 {{Mins}} de bonheur
-
-
-# on / ont
-__[i]/conf(conf_on_ont_adverbe)__
-    (?<!’)(on) ({w_2})  @@0,3
-    <<- morphex(\2, ":W", ":3s") and not morph(word(-1), ":V.*:3s", False, False) -1>> ont          # Confusion probable : “avoir” à la 3ᵉ personne du pluriel du présent s’écrit “ont”.
-
-TEST: ces gens {{on}} {{souvent}} tort.
-TEST: Je voulais qu’on soit ensemble.
-
-
-# ou / où
-__[i]/conf(conf_où_verbe)__
-    ^(Ou) ({w_2}) @@0,3 <<- morphex(\2, ":3[sp]", ":Y") -1>> Où                             # Confusion probable. La conjonction “ou” signale une alternative. Utilisez “où” pour “en quel lieu”.
-__[i]/conf(conf_au_moment_par_d_où)__
-    (?:au moment |jusqu |par |d’)(ou) @@$ <<- -1>> où                                       # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
-__[i]/conf(conf_vers_où)__
-    vers (ou) @@5 <<- not morph(word(-1), ":D", False, False) -1>> où                       # Confusion probable. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
-__[i]/conf(conf_jusqu_où_au_cas_où)__
-    (?:au|le|des) cas (ou) @@$ <<- -1>> où                                                  # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
-__[i]/conf(conf_à_partir_du_temps_où)__
-    à partir d(?:u (?:lieu|moment|jour|mois)|e l’(?:instant|année|heure)|e la (?:minute|semaine|seconde)) +(ou) @@$
-    <<- -1>> où                                                                             # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
-__[i]/conf(conf_depuis_xxxx_où)__
-    depuis (?:le (?:jour|millénaire|moment|mois|siècle)|la (?:minute|semaine|seconde)|l’(?:année|heure|instant)) (ou)  @@$
-    <<- -1>> où                                                                             # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
-
-TEST: {{Ou}} sont tes affaires ?
-TEST: au moment {{ou}} elle allait enfin réussir
-TEST: vers {{ou}} se tourner quand tout va mal ?
-TEST: pour le cas {{ou}} on serait arrêté dans notre élan.
-TEST: à partir du moment {{ou}} il est entré.
-TEST: à partir de l’instant {{ou}} elle est venue.
-TEST: depuis l’année {{ou}} nous sommes allés en Bretagne
-TEST: depuis la seconde {{ou}} tu as parlé
-TEST: depuis le jour {{ou}} il a été blessé.
-
-
-# pale / pâle
-__[i]/conf(conf_pale_pâle1)__
-    (?:bien|tr(?:ès|op)|si|vraiment|tellement) +(pales?)  @@$
-    <<- -1>> =\1.replace("pal", "pâl")
-    # Utilisez “pâle” pour évoquer la pâleur… Une pale est, entre autres choses, un élément d’une hélice.|http://fr.wiktionary.org/wiki/pale
-__[i]/conf(conf_pale_pâle2)__
-    (pales?) +(?:imitat(?:ion|eur|rice)|rayon)s?  @@0
-    <<- -1>> =\1.replace("pal", "pâl")
-    # Utilisez “pâle” pour évoquer la pâleur… Une pale est, entre autres choses, un élément d’une hélice.|http://fr.wiktionary.org/wiki/pale
-
-TEST: elles sont si {{pales}}.
-TEST: cette {{pale}} imitation d’un chef-d’œuvre
-
-
-# peu / peux / peut / peut-être
-__[i]/conf(conf_peut_adv)__
-    (?<![dDuUnN][eEnN] )(peu) (?:pas|donc|jamais|rien|parfois|alors|enfin|rarement|éventuellement) @@0
-    <<- not before("très +$") -1>> peut                                     # Confusion probable : « peu » signifie « pas beaucoup », pour le verbe pouvoir, écrivez :
-__[i]/conf(conf_il_ce_peut_être)!6__
-    ^ *(?:il|ce) (peut-être) @@$
-    <<- -1>> peut être                                                      # Confusion probable : « peut-être » signifie « possiblement ».
-__[i]/conf(conf_cela_peut_être_adj)__
-    ^ *(?:cela|ceci) (peut-être) ({w_2})  @@w,$
-    <<- morph(\2, ":[AQ]", False) -1>> peut être                            # Confusion probable : « peut-être » signifie « possiblement ».
-__[i]/conf(conf_peu_à_peu)__
-    peu[xt]? a peu[xt]?
-    <<- ->> peu à peu                                                       # Confusion : « peu à peu » ou « petit à petit ». 
-__[i]/conf(conf_peu_importe)__
-    (peu[tx]) importe(?:nt|) @@w
-    <<- morph(word(-1), ":C", False, True) -1>> peu                         # Confusion : « \1 » est une conjugaison de “pouvoir”, utilisez “peu” pour dire “pas beaucoup”.
-__[i]/conf(conf_adv_de_peu)!6__
-    (?:très|trop|de|quelque|pour|à) (peu[tx]) @@$
-    <<- -1>> peu                                                            # Confusion : « \1 » est une conjugaison de “pouvoir”, utilisez “peu” pour dire “pas beaucoup”.
-__[i]/conf(conf_un_peu)!6__
-    un (peu[xt]) @@3
-    <<- not before("(?i)(?:quelqu|l|d)’") -1>> peu                          # Confusion : « \1 » est une conjugaison de “pouvoir”, utilisez “peu” pour dire “pas beaucoup”.
-__[i]/conf(conf_il_on_ne_peut)!6__
-    (?:il|on) (?:ne |)(peu) @@$
-    <<- -1>> peut                                                           # Confusion : « peu » signifie « pas beaucoup ».
-__[i]/conf(conf_je_tu_peux)!6__
-    (?:je|tu) (?:ne |)(peu)
-    @@$ <<- -1>> peux                                                       # Confusion : « peu » signifie « pas beaucoup ».
-__[i]/conf(conf_ne_se_peut)!6__
-    [ns]e (peu) @@3
-    <<- -1>> peut                                                           # Confusion. Exemples : Il est peu habile, mais il peut y arriver.
-__[i]/conf(conf_peu_adj)__
-    (peu[tx]) ({w_2})  @@0,$
-    <<- morph(\2, ":A") and not re.search("(?i)^seule?s?$", \2) and not before(r"(?i)\b(?:il|on|ne|je|tu) +$")
-    -1>> peu                                                                # Confusion probable : « \1 » est une conjugaison de « pouvoir », utilisez « peu ».
-
-TEST: {{peu}} rarement y arriver.
-TEST: Il est un {{peut}} comme une forêt
-TEST: Il {{peut-être}} mortel.
-TEST: Cela {{peut-être}} mortel.
-TEST: cela ne se {{peu}}.
-TEST: des bâtisses {{peu a peu}} abandonnées.
-TEST: aucun pays – ou très peu alors – n’a réussi à faire ça de façon durable
-TEST: Mais {{peut}} importe le rang.
-TEST: homme de {{peut}} de foi, écoute le vent.
-TEST: Il en vient un {{peut}} tous les jours.
-TEST: {{peut}} sympathique, cet individu.
-TEST: il {{peu}} y parvenir
-TEST: tu ne {{peu}} en savoir plus
-TEST: {{peut}} {{embarrassés}} par leurs déboires, ils poursuivirent comme si de rien n’était.
-
-
-# la plupart
-__[i]/conf(conf_la_plupart)__   la (plu[st][ -]part) @@3 <<- -1>> plupart                           # Confusion. Écrivez « la plupart » pour évoquer la majeure partie de quelque chose.
-
-TEST: la {{plus part}}
-
-
-# par-dessus / pardessus
-__[i]/conf(conf_par_dessus)__
-    (pardessus) +({w1})  @@0,$
-    <<- morph(\2, ":D|>bord ", False) and not morph(word(-1), ":D.*:[me]|>(?:grande|petite) ", False, False)
-    -1>> par-dessus                                                                                 # Confusion probable. Un pardessus est un vêtement. Pour la préposition, écrivez :
-
-TEST: {{Pardessus}} les montagnes.
-TEST: Il passa {{pardessus}} les collines.
-TEST: Mets ton pardessus ce matin.
-
-
-# pot aux roses / poteau rose
-__[i]/conf(conf_pot_aux_roses)__
-    poteau rose <<- ->> pot aux roses
-    # Confusion probable. On dit : « découvrir le pot aux roses ».|http://fr.wiktionary.org/wiki/d%C3%A9couvrir_le_pot_aux_roses
-
-TEST: Ils ont découvert le {{poteau rose}}.
-
-
-# prêt / près / pré
-__[i]/conf(conf_prêt_à)__
-    (près) à ({w_2})  @@0,$
-    <<- not before("(?i)(?:peu|de|au plus) $") and morph(\2, ":Y|>(?:tout|les?|la) ") -1>> prêt|prêts       # Confusion. Être près de (faire) quelque chose. Prêt à faire quelque chose.
-__[i]/conf(conf_près_de)__
-    (prêts?) d(?:e +|’)({w_1}) @@0,$
-    <<- morph(\2, ":(?:Y|M[12P])|>(?:en|y|les?) ", False) -1>> près                                 # Confusion. Être près de (faire) quelque chose. Prêt à faire quelque chose.
-__[i]/conf(conf_près)__         de(?: plus|puis) (prêts?)  @@$ <<- -1>> près                        # Confusion. Être prêt(e) à faire quelque chose. Être près de quelque chose.
-__[i]/conf(conf_très_près)__    très (pr(?:êt|é)s?) @@$ <<- -1>> près                               # Confusion probable. Pour évoquer la proximité, utilisez :
-
-TEST: ils se sont approchés très {{prêts}}.
-TEST: Je suis si {{prêt}} d’y arriver.
-TEST: Il est {{près}} à les aider
-TEST: Elle va regarder ça de plus {{prêt}}.
-
-
-# quand / quant / qu’en
-__[i]/conf(conf_quant_à)__
-    (?<![dD]e )(quand) (?:à|aux?)  @@0
-    <<- not morph(word(-1), ">(?:arriver|venir|à|revenir|partir|aller) ")
-        and not(\0.endswith("à") and after("^ +[mts]on tour[, ]")) -1>> quant                           # Confusion probable. Quand = à quel moment. Quant à = à propos de.
-__[i]/conf(conf_quand1)__   quant(?! à| aux?| est[ -]il d(?:es?|u) ) <<- ->> quand                  # Confusion. Quand = à quel moment. Quant à = à propos de.
-__[i]/conf(conf_qu_en1)__   (quan[dt]) est[ -]il d(?:es?|u) @@0 <<- -1>> qu’en                      # Confusion. Ce qu’il en est de… → Qu’en est-il de… ?
-__[i]/conf(conf_qu_en2)__   (quan[dt]) ({w_2}ant) @@0,$ <<- morph(\2, ":P", False) -1>> qu’en       # Confusion probable.
-__[i]/conf(conf_quand2)__
-    (qu en) (?:je|tu|ils?) @@0
-    <<- not after("^ +ne s(?:ai[st]|u[st]|urent|avai(?:[ts]|ent)) ") -1>> quand                     # Confusion probable. Pour évoquer un moment, écrivez :
-
-TEST: {{Quant}} est-il du chien ?
-TEST: {{Quand}} à ma santé, elle est défaillante.
-TEST: {{Quant}} ils…
-TEST: {{quant}} je…
-TEST: {{quant}} nous…
-TEST: il comprit {{quand}} prenant son parti, il se protégeait aussi.
-TEST: {{qu’en}} il vient, c’est l’enfer.
-TEST: il est exact qu’en je ne sais combien de temps il parvint à un résultat inattendu.
-TEST: être rassuré quant à l’avenir du continent européen
-TEST: il comprit trop tard qu’en elle naquit alors le doute qui l’éloigna de lui à jamais.
-TEST: Quand à mon tour je réalise l’imposture, c’est trop tard.
-
-
-# quand bien même
-__[i]/conf(conf_quand_bien_même)__
-    combien même <<- not after("^ si ") ->> quand bien même                                         # Locution conjonctive.|https://fr.wiktionary.org/wiki/quand_bien_m%C3%AAme                             
-
-TEST: J’irai, {{combien même}} vous seriez tous contre moi.
-TEST: Il partirait en guerre quand bien même devrait-il être tout seul.
-TEST: Elle veut savoir combien même si ça ne lui est d’aucune utilité immédiate.
-
-
-# qu’elle / quelle
-__[i]/conf(conf_quelle_nom_adj)__
-    (qu elles?) +(?!seule?s?)({w_2})  @@0,$
-    <<- morphex(\2, ":[NAQ]", ":(?:G|[123][sp]|W)") -1>> =\1.replace(" ", "")                       # Confusion probable. Ex : Quelle femme ! Je crois qu’elle réussira.
-
-TEST: {{qu’elle}} emmerdeuse.
-
-
-__[i]/conf(conf_qu_elle_verbe)__
-    (quelles?) +({w_1})  @@0,$
-    <<- \2.islower() and (morphex(\2, ":V|>(?:ne?|me?|te?|se?|[nv]ous|l(?:e|a|es|ui|leur|)|en|y) ", ":[NA].*:[fe]|>(?:plus|moins)") or \2 == "t" or \2 == "s")
-        and not (morph(\2, ">(?:pouvoir|devoir|en)", False) and morph(word(1), ":V0e", False)) >>>
-    <<- \1.endswith("e") and not morph(\2, ":V0e", False) and not (morph(\2, ":V0a", False) and after("^ +été "))
-    -1>> qu’elle                                                                                    # Confusion. Le sujet “elle” doit être séparée de la conjonction “que”. 1
-    <<- __else__ and \1.endswith("s") and not morph(\2, ":V0e", False)  and not (morph(\2, ":V0a", False) and after("^ +été "))
-    -1>> qu’elles                                                                                   # Confusion. Le sujet “elles” doit être séparée de la conjonction “que”. 2
-    <<- __else__ and morph(\2, ":V0e", False) and morphex(word(1), ":[QA]", ":G", False) >>>
-    <<- \1.endswith("e") -1>> qu’elle                                                               # Confusion. Le sujet “elle” doit être séparée de la conjonction “que”. 3
-    <<- __else__ and \1.endswith("s") -1>> qu’elles                                                 # Confusion. Le sujet “elles” doit être séparée de la conjonction “que”. 4
-
-TEST: Je sais {{quelle}} est partie.
-TEST: {{Quelle}} partit prendre son repas à la cantine, je n’en avais cure.
-TEST: Il se plaint {{quelle}} ne nous dit rien.
-TEST: {{Quelles}} sont intelligentes, ces filles-là.
-TEST: {{Quelle}} a du répondant, cette gamine !
-TEST: {{Quelle}} y vienne, on verra ce qu’elle vaut.
-TEST: Je veux {{quelles}} s’efforcent à y parvenir.
-TEST: {{Quelle}} l’apprenne un jour, on n’y peut rien.
-TEST: Je crois {{quelle}} n’en sait pas assez pour nous nuire.
-TEST: {{Quelles}} t’arrivent seulement à la cheville, voilà qui serait étonnant.
-TEST: {{Quelles}} m’engueulent encore une seule fois et elles vont le regretter.
-TEST: Je crois {{quelle}} est partie.
-TEST: il pense {{quelles}} sont devenues dangereuses.
-TEST: Quelle est sa passion ?
-TEST: Quelles sont leurs principales études ?
-TEST: Quelles en sont les conséquences ?
-TEST: Quelle plus belle complicité que…
-TEST: Quelle peut être la date de clôture d’un exercice ?
-TEST: Quelle doit être la date du mariage ?
-TEST: Quelles ont été les annonces faites ?
-
-
-# savoir / ignorer
-__[i]/conf(être_pas_sans_savoir)__
-    ({etre}) pas sans (ignor(?:e[rz]|ée?s?|ai[st]))  @@0,$
-    <<- morph(\1, ":V0e", False)
-    -2>> savoir     # Confusion : vous écrivez l’inverse de ce que vous voulez dire.|http://fr.wiktionary.org/wiki/vous_n%E2%80%99%C3%AAtes_pas_sans_savoir
-
-TEST: Vous n’êtes pas sans {{ignorer}} que…
-
-
-## s’en / sens / sans / cent / cens
-__[i]/conf(conf_il_on_s_en)__  (?:ils?|on) (san[sg]|cen[st]|c’en) ({w_2})  @@w,$
-    <<- isStart() and morph(\2, ":V", False)
-    -1>> s’en                                                                                       # Confusion probable.
-__[i]/conf(conf_elle_s_en)__  elles? (san[sg]|cen[st]|c’en) ({w_2})  @@w,$
-    <<- isStart() and morph(\2, ":V", False) and not ( \1 == "sans" and morph(\2, ":[NY]", False) )
-    -1>> s’en                                                                                       # Confusion probable.
-
-TEST: il {{c’en}} est vite lassé.
-TEST: {{S’en}} était vraiment trop !
-TEST: Car {{s’en}} était vraiment fini !
-TEST: elle {{sang}} était voulu
-
-
-## son / sont
-__[i]/conf(conf_ne_sont)__
-    ne (?:l(?:e|eur|ui) |[nv]ous |)(son)  @@$
-    <<- -1>> sont                   # Confusion : “son” est un déterminant ou un nom masculin. Le verbe “être” à la 3ᵉ personne du pluriel s’écrit “sont”.
-__[i]/conf(conf_me_te_se_son)!6__
-    [mts]e (son)  @@3
-    <<- -1>> sont                   # Confusion : “son” est un déterminant ou un nom masculin. Le verbe “être” à la 3ᵉ personne du pluriel s’écrit “sont”.
-__[i]/conf(conf_son_qqch)__
-    (sont) ({w_2})  @@0,$
-    <<- morphex(\2, ":[NA].*:[me]:s|>[aeéiîou].* :[NA].*:f:s", ":[GW]")
-        and morphex(word(-1), ":V|>(?:à|avec|chez|dès|contre|devant|derrière|en|par|pour|sans|sur) ", ":[NA].*:[pi]|>(?:ils|elles|vous|nous|leur|lui|[nmts]e) ", True)
-        and not before(r"(?i)\bce que? |[mts]’en +$")
-    -1>> son                        # Confusion : “sont” est le verbe “être” à la 3ᵉ personne du pluriel. Pour le déterminant, écrivez “son”.
-__[i]/conf(conf_qui_sont_les)__
-    (?:qu[ie]|comment|pourquoi) +(son) @@$
-    <<- morph(word(1), ":[DR]", False, True) -1>> sont      # Confusion probable : “son” est un déterminant ou un nom masculin. Le verbe “être” à la 3ᵉ personne du pluriel s’écrit “sont”.
-
-TEST: ne leur {{son}} pas odieux.
-TEST: Ces chiens me {{son}} odieux.
-TEST: {{sont}} {{pain}}
-TEST: en {{sont}} {{absence}}
-TEST: qui {{son}} ces gens ?
-TEST: ces gens qui {{son}}, dans le meilleur des cas, des imbéciles ne peuvent nous aider.
-TEST: elles s’en sont mal portées
-TEST: ils en sont reconnaissants
-TEST: Il ne sait pas vraiment ce que sont la peur et la souffrance.
-
-
-# statu / statut
-__[i]/conf(conf_statu_quo)__
-    statu[tse] quo <<- ->> statu quo                                                      # Confusion.|https://fr.wiktionary.org/wiki/statu_quo
-__[i]/conf(conf_statue_statut)__
-    statu(?! quo) <<- ->> statut|statue                                                   # Confusion : “statu” ne s’emploie que dans l’expression “statu quo”.
-
-TEST: Ça n’en finit pas, c’est le {{statut quo}}.
-TEST: Quelle splendide {{statu}}.
-
-
-# sur / sûr
-__[i]/conf(conf_sûr_de_nom_propre)__
-    (sur) d(?:e |’)([A-ZÉÈ][\w-]+)  @@0,$
-    <<- morph(\2, ":M[12]", False) -1>> sûr
-    # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
-
-TEST: Je suis {{sur}} de Patrick.
-
-
-# tant / temps (1re partie)
-__[i]/conf(conf_en_temps_de)__
-    en (tant?) de?  @@3
-    <<- not after("^[ ’](?:lieux|endroits|places|mondes|villes|pays|régions|cités)") -1>> temps     # Confusion. Écrivez « en temps de » si vous évoquez une période de temps.
-__[i]/conf(conf_de_temps_en_temps)__    de tant? en tant?                   <<- ->> de temps en temps   # Confusion. Écrivez « de temps en temps ».
-__[i]/conf(conf_un_temps_soit_peu)__    un (temps|tan) soi[tes]? peu  @@3   <<- -1>> tant           # Confusion. Écrivez « un tant soit peu ».
-__[i]/conf(conf_tant_de)__              a(?:près|vec) (temps|tan) de?  @@w  <<- -1>> tant           # Confusion.|http://fr.wiktionary.org/wiki/tant 
-__[i]/conf(conf_à_temps_partiel)__      [àa] (tant?) (?:partiel|plein)s? @@2 <<- -1>> temps         # Confusion.
-__[i]/conf(conf_en_même_temps)__        en mêmes? (tant?)  @@$              <<- -1>> temps          # Confusion.
-
-TEST: en {{tant}} de guerre, il faut savoir faire face et ne pas faiblir face à l’adversité.
-TEST: ils vont {{de tan en tan}} au restaurant
-TEST: un {{temps}} soit peu perdu dans cette affaire.
-TEST: après {{temps}} de souffrance, il faut savoir lâcher prise.
-TEST: il travaille à {{tant}} partiel
-TEST: en même {{tant}}, on s’en moque, de toutes ces histoires ennuyeuses.
-TEST: ce qui a commencé en 2011 en tant d’endroits du pourtour méditerranéen
-TEST: elle est allée en tant de lieux qu’il est difficile de suivre son trajet.
-
-
-# tant bien même
-__[i]/conf(conf_tant_bien_même)__
-    tant bien même <<- ->> quand bien même                                  # Confusion. Écrivez « quand bien même ».|http://www.academie-francaise.fr/tant-bien-meme
-
-TEST: il sera condamné {{tant bien même}} il prouverait que c’était un accident.
-
-
-# voie / vois / voix
-# ->> voix
-__[i]/conf(conf_à_haute_voix)__     à haute (voi[tes])   @@8            <<- -1>> voix               # Confusion.|http://fr.wiktionary.org/wiki/voix
-__[i]/conf(conf_à_voix)__           à (voi[tes]) (?:basse|haute) @@2    <<- -1>> voix               # Confusion.|http://fr.wiktionary.org/wiki/voix
-__[i]/conf(conf_de_vive_voix)__     de vives? (voi[est])  @@$           <<- -1>> voix               # Confusion.|http://fr.wiktionary.org/wiki/voix
-
-TEST: à haute {{voie}}
-TEST: à {{voie}} haute
-TEST: de vive {{voie}}
-
-# ->> voie
-__[i]/conf(conf_sur_la_bonne_voie)__        sur la bonne (voix) @@$     <<- -1>> voie               # Confusion.|http://fr.wiktionary.org/wiki/voix
-__[i]/conf(conf_en_voie_de)__
-    en (voix) d(?:e (?:développement|disparition|guérison|résorption)|’(?:acquisition|achèvement|extinction|obtention))  @@3
-    <<- -1>> voie                                                                                   # Confusion.|http://fr.wiktionary.org/wiki/voie
-__[i]/conf(conf_ouvrir_la_voix)__
-    (ouv\w+) +la (voix) (?:à|aux?)  @@0,w <<- morph(\1, ">ouvrir ", False) -2>> voie                # Confusion.|http://fr.wiktionary.org/wiki/voie
-__[i]/conf(conf_par_voie_de_conséquence)__  par (voix) de conséquence   @@4 <<- -1>> voie           # Confusion.|http://fr.wiktionary.org/wiki/voie
-__[i]/conf(conf_voie_adj)__
-    (voix) (?:abdominale|anale|biliaire|carrossable|communale|express|interdite|intramusculaire|intraveineuse|piétonne|principale|prioritaire|privée|publique|déserte|romaine|appienne|flaminienne|ferrée|ferroviaire|lactée|lacrymale|aérienne|maritime|fluviale|terrestre|navigable|détournée|déviée|buccale|digestive|urinaire|respiratoire|parallèle|administrative|diplomatique|gouvernementale|législative|hiérarchique|rectiligne|sinueuse|souterraine|urbaine)s? @@0
-    <<- -1>> voie                                                                                   # Confusion.|http://fr.wiktionary.org/wiki/voie
-
-TEST: sur la bonne {{voix}}
-TEST: ces patients sont en {{voix}} de guérison.
-TEST: il faut ouvrir la {{voix}} aux nouveaux venus.
-TEST: Je propse que, par {{voix}} de conséquence, nous partions immédiatement.
-TEST: C’est une {{voix}} interdite.
-
-
-# voire / voir
-__[i]/conf(conf_voir_voire)__
-    (voir) ({w_2}) @@0,$
-    <<- not re.search("^(?:grand|petit|rouge)$", \2) and morphex(\2, ":A", ":[NGM]") and not \2.istitle()
-        and not before(r"(?i)\b[ndmts](?:e |’(?:en |y ))(?:pas |jamais |) *$") and not morph(word(-1), ":O[os]|>(?:[ndmts]e|falloir|pouvoir|savoir|de) ", False)
-    -1>> voire 
-    # Confusion probable : “voir” est un verbe concernant la perception visuelle. Pour signifier “et même possiblement”, écrivez :|https://fr.wiktionary.org/wiki/voire
-
-__[i]/conf(conf_voire_voir)__
-    voire
-    <<- morph(word(-1), ":Cs|>(?:ni|et|sans|pour|falloir|[pv]ouvoir|aller) ", True, False) ->> voir
-    # Confusion probable : “voire” signifie “et même possiblement”. Pour le verbe, écrivez “voir”.|https://fr.wiktionary.org/wiki/voire
-
-TEST: Elles sont fatiguées, {{voir}} épuisées.
-TEST: Ce serait pour aider, ainsi que {{voire}} l’avancement du projet.
-TEST: Elles vont voir rouge en apprenant cet échec.
-TEST: Voir les enfants jouer ne me rend pas nostalgique.
-TEST: Il faut voir grand.
-TEST: Il sait voir grand.
-TEST: Il sait voir telle ou telle chose avec acuité.
-TEST: ça reste à voir
-TEST: Je veux le voir étonné par toutes ces merveilles.
-TEST: Les start-ups doivent aller vite, voir grand.
-TEST: de fortes chances de se voir ruiné
-TEST: Quelle chance tu as eue de voir ruiné ce connard.
-TEST: l’immobilier a été ces dernières années l’investissement le plus rentable (voir graphique ci-dessous)
-TEST: elles sont pas mal ainsi, voire élégantes pourrait-on dire.
-TEST: il y en a peu, voire très peu.
-TEST: car elles pénètrent dans les poumons voire le système sanguin.
-TEST: des enfants malades, qui préfèrent souvent voir Dark Vador que des vieux clowns un peu flippants.
-
-
-
-!!
-!!
-!!!! Pronoms + incohérences                                                                         
-!!
-!!
-__[i](p_m_enfin)__      m’enfin <<- ~>> *
-
-__[i]/conf(conf_j_y_en_qqch)__
-    (j’(?:en +|y +|))({w_1})  @@0,$
-    <<- morphex(\2, ":", ":(?:[123][sp]|O[onw])")
-    -2>> =suggSimil(\2, ":1s", False)                                                               # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-__[i]/conf(conf_ne_qqch)__
-    (n(?:e +|’))({w_1})  @@0,$
-    <<- morphex(\2, ":", ":(?:[123][sp]|Y|P|O[onw]|X)|>(?:[lmtsn]|surtout|guère|presque|même|tout|parfois|vraiment|réellement|justement) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Oo|Y)", False)                                               # Incohérence avec « \1 » : « \2 » devrait être un verbe ou un pronom personnel objet.
-__[i]/conf(conf_n_y_en_qqch)__
-    (n’(?:en|y)) ({w_1})  @@0,$
-    <<- morphex(\2, ":", ":(?:[123][sp]|Y|P|O[onw]|X)") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False)                                                  # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-__[i]/conf(conf_ne_pronom_qqch)__
-    (ne (?:l(?:es? +|eur +|a +|’)|[nv]ous))({w_1})  @@0,$
-    <<- morphex(\2, ":", ":(?:[123][sp]|Y|P|O[onw]|X)") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False)                                                  # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-__[i]/conf(conf_me_te_se_qqch)__
-    ([mts]e +(?:les? |la |l’|))(?!voi(?:là|ci))({w_1})  @@0,$
-    <<- not re.search("(?i)^se que?", \0)
-        and morphex(\2, ":", ":(?:[123][sp]|Y|P|Oo)|>[lmts] ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Oo|Y)", False)                                               # Incohérence avec « \1 » : « \2 » devrait être un verbe ou un pronom personnel objet.
-__[i]/conf(conf_m_t_s_y_en_qqch)__
-    ([mts]’(?:en|y)) (?!voilà)({w_1})  @@0,$
-    <<- morphex(\2, ":", ":(?:[123][sp]|Y|P|X|Oo)|rien ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False)                                                  # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-__[i]/conf(conf_m_s_qqch)__
-    ([ms]’)({w_1})  @@0,2
-    <<- morphex(\2, ":", ":(?:[123][sp]|Y|P)|>(?:en|y|ils?) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False)                                                  # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-__[i]/conf(conf_t_qqch)__
-    (t’)({w_1})  @@0,2
-    <<- morphex(\2, ":", ":(?:[123][sp]|Y|P)|>(?:en|y|ils?|elles?) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|ce)$", \2)
-    -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False)                                                  # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-__[i]/conf(conf_c_ç_qqch)__
-    ([cç]’)({w_1})  @@0,2
-    <<- morphex(\2, ":", ":[123][sp]|>(?:en|y|que?) ") and not re.search("(?i)-(?:ils?|elles?|[nv]ous|je|tu|on|dire)$", \2)
-    -2>> =suggSimil(\2, ":3s", False)                                                               # Incohérence avec « \1 » : « \2 » devrait être un verbe.
-
-TEST: ne l’{{oubli}} pas
-TEST: elle ne la {{croix}} pas
-TEST: ils me les {{laissés}}.
-TEST: ne {{pensée}} rien, jamais
-TEST: n’en {{laissée}} que des miettes
-TEST: s’y {{intéressé}}
-TEST: Il ne {{travail}} pas le week-end.
-TEST: Je m’en {{fou}}.
-TEST: il m’{{arête}} encore une fois avec une impudence insupportable.
-TEST: J’y {{travail}}.
-TEST: ç’{{avé}} été dur.
-TEST: me {{pronostic}} un cancer dans les trois mois.
-TEST: t’{{appel}} l’autre gras, puis on y va.
-TEST: te {{mangé}}
-TEST: s’y {{accordez}}
-TEST: s’en {{approché}}
-TEST: m’y {{attaché}}
-TEST: je t’en {{parlé}}
-TEST: j’ai peur qu’il ne leur {{face}} quelque chose de mal
-TEST: M’enfin, c’est absurde
-TEST: il est normal de ne presque pas payer des gens qui effectuent un travail
-TEST: j’ai l’impression de ne même pas savoir ce qu’est un « juif français ».
-TEST: C’que j’comprends, c’est qu’il y a des limites à ce qu’on peut supporter.
-TEST: la tentation pour certains médias de ne tout simplement pas rémunérer notre travail si celui-ci n’est finalement pas publié.
-TEST: Ne parfois pas être celui qui sabote l’ambiance.
-
-
-!!
-!!
-!!!! Formes verbales sans sujet                                                                     
-!!
-!!
-
-## Incohérences avec formes verbales 1sg et 2sg sans sujet
-__[i](p_notre_père_qui_es_au_cieux)__   notre père (qui est? aux cieux) @@11 <<- ~1>> *
-
-__[i]/conj(conj_xxxai_sans_sujet)!3__
-    \w*ai(?! je)
-    <<- ( morph(\0, ":1s") or ( before("> +$") and morph(\0, ":1s", False) ) ) and not (\0[0:1].isupper() and before0(r"\w"))
-        and not before(r"(?i)\b(?:j(?:e |[’'])|moi(?:,? qui| seul) )")
-    ->> =suggVerb(@, ":3s")                                     # Incohérence. Ceci est un verbe à la 1ʳᵉ personne du singulier. Sujet (“je” ou “moi qui”) introuvable.
-__[i]/conj(conj_xxxes_sans_sujet)!3__
-    \w*es(?! tu)
-    <<- morphex(\0, ":2s", ":(?:E|G|W|M|J|[13][sp]|2p)") and not \0[0:1].isupper() and not isRealStart()
-        and ( not morph(\0, ":[NAQ]", False) or before("> +$") )
-        and not before(r"(?i)\bt(?:u |[’']|oi,? qui |oi seul )")
-    ->> =suggVerb(@, ":3s")                                     # Incohérence. Ceci est un verbe à la 2ᵉ personne du singulier. Sujet (“tu” ou “toi qui”) introuvable.
-__[i]/conj(conj_xxxas_sans_sujet)!3__
-    \w+as(?! tu)
-    <<- morphex(\0, ":2s", ":(?:G|W|M|J|[13][sp]|2p)") and not (\0[0:1].isupper() and before0(r"\w"))
-        and ( not morph(\0, ":[NAQ]", False) or before("> +$") )
-        and not before(r"(?i)\bt(?:u |[’']|oi,? qui |oi seul )")
-    ->> =suggVerb(@, ":3s")                                     # Incohérence. Ceci est un verbe à la 2ᵉ personne du singulier. Sujet (“tu” ou “toi qui”) introuvable.
-__[i]/conj(conj_xxxxs_sans_sujet)!3__
-    \w+[iudnrtpcï]s(?! (?:tu|je))
-    <<- morphex(\0, ":[12]s", ":(?:E|G|W|M|J|3[sp]|2p|1p)") and not (\0[0:1].isupper() and before0(r"\w"))
-        and ( not morph(\0, ":[NAQ]", False) or before("> +$") or ( re.search("(?i)^étais$", \0) and not morph(word(-1), ":[DA].*:p", False, True) ) )
-        and not before(r"(?i)\b(?:j(?:e |[’'])|moi(?:,? qui| seul) |t(?:u |[’']|oi,? qui |oi seul ))")
-    ->> =suggVerb(@, ":3s")                                                  # Incohérence. Le sujet de cette forme verbale est introuvable.
-__[i]/conj(conj_peux_veux_sans_sujet)!3__
-    [pv]eux(?! (?:tu|je))
-    <<- not (\0[0:1].isupper() and before0(r"\w")) and not before(r"(?i)\b(?:j(?:e |[’'])|moi(?:,? qui| seul) |t(?:u |[’']|oi,? qui |oi seul ))")
-    ->> =suggVerb(@, ":3s")                                                  # Incohérence. Le sujet de cette forme verbale est introuvable.
-__[i]/conj(conj_équivaux_prévaux_sans_sujet)!3__
-    (?:équi|pré|)vaux(?! (?:tu|je))
-    <<- not (\0[0:1].isupper() and before0(r"\w"))
-        and not (\0 == "vaux" and morph(word(-1), ":(?:R|D.*:p)", False, False))
-        and not before(r"(?i)\b(?:j(?:e |[’'])|moi(?:,? qui| seul) |t(?:u |[’']|oi,? qui |oi seul ))")
-    ->> =suggVerb(@, ":3s")                                                  # Incohérence. Le sujet de cette forme verbale est introuvable.
-
-TEST: Caroline, quand l’heure viendra, {{décideras}} de la conduite à tenir.
-TEST: ceux-là, dans tous les cas de figure et dans tous les coups ratés, {{comprenais}} mal pourquoi on leur en voulait.
-TEST: Lui, quand il y pensait, en {{arrivai}} à chaque fois à la même conclusion.
-TEST: Elle, ici et dans tous les cas de figure, {{veux}} toujours en faire plus.
-TEST: Le total de cette opération, contrairement à ce qu’on pense, {{équivaux}} à au moins trois d’entre eux.
-TEST: {{j'}}ai signalé que {{j'}}essayais de regrouper les paragraphes. (Tests avec apostrophe droite.)
-TEST: je me questionne, {{exiges}} des réponses mais n’en obtiens pas…
-TEST: dans tous les cas de figure imaginés par cette bande de nuls, il n’y en a pas un qui les sauvera.
-TEST: ces gens qui vont par monts et par vaux.
-TEST: pour ne justement pas donner l’impression de s’être trompé.
-
-
-## Incohérences avec formes verbales 1pl et 2pl sans sujet
-__[i]/conj(conj_xxxons_sans_sujet)!3__
-    \w+(?:ons|[âîûn]mes)(?! nous)
-    <<- morphex(\0, ":V.*:1p", ":[EGMNAJ]") and not (\0[0:1].isupper() and before(r"\w"))
-        and not before0(r"\b(?:[nN]ous(?:-mêmes?|)|(?:[eE]t|[oO]u) moi(?:-même|)|[nN]i (?:moi|nous)),? ")
-    ->> =suggVerb(@, ":3p")                                 # Incohérence. Ceci est un verbe à la 1ʳᵉ personne du pluriel. Sujet (“nous” ou équivalent) introuvable.
-__[i]/conj(conj_xxxez_sans_sujet)!3__
-    \w+(?:ez|[âîûn]tes)(?! vous)
-    <<- morphex(\0, ":V.*:2p", ":[EGMNAJ]") and not (\0[0:1].isupper() and before(r"\w"))
-        and not before0(r"\b(?:[vV]ous(?:-mêmes?|)|(?:[eE]t|[oO]u) toi(?:-même|)|[tT]oi(?:-même|) et|[nN]i (?:vous|toi)),? ")
-    ->> _                                                   # Incohérence. Ceci est un verbe à la 2ᵉ personne du pluriel. Sujet (“vous” ou équivalent) introuvable.
-
-TEST: les hommes et les femmes, qui sans un bruit, sans une parole amère, {{continuerons}} leur tâche n’en seront pas plus récompensés.
-TEST: il était dit que cette femme et son frère {{promènerez}} leur chien à cette heure de la journée.
-TEST: cet homme et cette femme {{pouvez}} y parvenir avec de la persévérance
-TEST: Comme on lui disait que vous-même aviez déjà consulté le notaire
-TEST: ce sont des terroristes et ça ne nous arrivera pas à nous, qui n’avons rien à nous reprocher
-TEST: mes supérieurs et moi-même avons pris la décision de ne pas vendre
-TEST: Ni lui ni moi n’avions mangé
-TEST: Mon épouse et moi-même avons toujours dit
-TEST: que vous ou moi ignorions à peu près tout du boson de Higgs n’a pas du tout le même sens
-
-
-
-!!
-!!
-!!!! Locutions invariables                                                                          
-!!
-!!
-
-## plus que prévu / mois que prévu
-__[i]/sgpl(sgpl_que_prévu1)__   (plus|moins|autant) +que (prévu(?:es?|s)) @@0,$ <<- -2>> prévu                          # Invariable. Implicitement, \1 que ce qui était prévu.
-__[i]/sgpl(sgpl_que_prévu2)__   (plus|moins|aussi) +({w_2}) +que (prévu(?:es?|s)) @@0,w,$ <<- -3>> prévu                # Invariable. Implicitement, \1 \2 que ce qui était prévu.
-__[i]/sgpl(sgpl_que_prévu3)__   (plus|moins|autant) +d(?:e |’)({w_2}) +que (prévu(?:es?|s)) @@0,w,$ <<- -3>> prévu      # Invariable. Implicitement, \1 \2 que ce qui était prévu.
-__[i]/sgpl(sgpl_comme_adj)__    comme ((annoncé|convenu|prévu)(?:es?|s)) @@6,6 <<- -1>> \2                              # Invariable. Implicitement, comme ce qui était \2.
-
-TEST: il y en a autant que {{prévus}}.
-TEST: elles sont plus nombreuses plus que {{prévues}}
-TEST: il y a moins de bouffe que {{prévue}}
-TEST: comme {{annoncés}}, ils sont arrivés
-TEST: moins loin que {{prévus}}                               ->> prévu
-TEST: plus rapide que {{prévues}}                             ->> prévu
-TEST: autant d’hommes que {{prévus}}                          ->> prévu
-TEST: il y en a moins que {{prévues}}                         ->> prévu
-TEST: comme {{convenus}}                                      ->> convenu
-
-
-
-!!
-!!
-!!!! Tout, tous, toute, toutes                                                                      
-!!
-!!
-
-__[i](p_fais_les_tous)__
-    fai(?:tes|sons|s)-(?:les|[nv]ous) (tou(?:te|)s) @@$ <<- ~1>> *
-__[i](p_tout_débuts_petits)__
-    (tout) (?:débuts|petits) @@0 <<- before(r"\b(aux|[ldmtsc]es|[nv]os|leurs) +$") ~1>> *
-__[i](p_les_tout_xxx)__
-    (?:[ldmtsc]es|[nv]os|leurs|aux) (tout) ({w_2})  @@w,$
-    <<- morph(\2, ":[AQ].*:[pi]", False) ~1>> *
-
-
-__[i]/gn(gn_tous_deux)__
-    (tout) deux  @@0 <<- isStart() -1>> tous                                                        # Locution pronominale : « tous deux ».|https://fr.wiktionary.org/wiki/tous_deux
-
-TEST: {{Tout}} deux sont partis les premiers.
-
-
-__[i]/gn(gn_tous_déterminant_pluriel)__
-    tout(?= [cmts]es\b)
-    <<- not before(r"(?i)\b(?:d[eu]|avant|après|sur|malgré) +$") ->> tous                           # Erreur d’accord probable.
-
-TEST: {{Tout}} mes hommes sont venus.
-TEST: Malgré tout ces hommes sont quand même revenus.
-
-
-__[i]/gn(gn_tous_les)__
-    (tout) les ({w_2})  @@0,$
-    <<- not before(r"(?i)\b(?:d[eu]|avant|après|sur|malgré) +$") and not morph(\2, ":(?:3s|Oo)", False)
-    -1>> tous                                                                                       # Erreur d’accord probable avec « les \2 ».
-
-TEST: {{Tout}} les hommes sont dingues.
-
-
-__[i]/gn(gn_tous_ceux)__
-    tout(?= ceux\b)
-    <<- not before(r"(?i)\b(?:d[eu]|avant|après|sur|malgré) +$") ->> tous                           # Erreur d’accord probable avec « ceux ».
-
-TEST: Donne à manger à {{tout}} ceux qui sont là.
-TEST: Revenus de tout ceux qui sont partis ont perdu la foi.
-
-
-__[i]/gn(gn_toutes_déterminant_fem_plur)__  toute(?= (?:celles|[clmtsd]es)\b)   <<- ->> toutes      # Erreur d’accord probable.
-__[i]/gn(gn_tout_ce)__                      toute(?= cet?\b)                    <<- ->> tout        # Erreur d’accord probable.
-__[i]/gn(gn_tout_mon)__                     toute(?= mon [bcdfgjklmnpqrstvwxz]) <<- ->> tout        # Erreur d’accord probable.
-
-TEST: {{Toute}} celles qui viendront…
-TEST: et {{toute}} ce barouf ne nous a apporté que des ennuis.
-TEST: car {{toute}} mon savoir vient d’elle
-
-
-__[i]/gn(gn_toutes_déterminant_nom_fem_plur)__
-    (tous) +(?:[lcmtsd]es) +({w_2})  @@0,$
-    <<- morphex(\2, ":f", ":(?:[123][sp]|[me])") and morphex(word(-1), ":", ":(?:R|[123][sp]|Q)|>(?:[nv]ous|eux) ", True)
-    -1>> toutes                                                                                     # Erreur d’accord probable. « \2 » est féminin.
-    <<- __also__ and hasFemForm(\2) -2>> =suggMasPlur(@, True)                                      # Erreur d’accord probable. « \1 » est masculin.
-__[i]/gn(gn_tous_déterminant_nom_mas_plur)__
-    (toutes) +(?:[lcmtsd]es) +({w_2})  @@0,$
-    <<- morphex(\2, ":m", ":(?:[123][sp]|[fe])") and morphex(word(-1), ":", ":(?:R|[123][sp]|Q)|>(?:[nv]ous|eux) ", True)
-    -1>> tous                                                                                       # Erreur d’accord probable. « \2 » est masculin.
-    <<- __also__ and hasFemForm(\2) -2>> =suggFemPlur(@, True)                                      # Erreur d’accord probable. « \1 » est féminin.
-
-TEST: {{tous}} ces {{idiotes}}
-TEST: {{toutes}} mes {{bars}}
-
-
-__[i]/gn(gn_tout_nom_mas_sing)__
-    tout ({w3})  @@5
-    <<- morphex(\1, ":N.*:[fp]", ":(?:A|W|G|M[12P]|Y|[me]:i|3s)") and morph(word(-1), ":R|>de ", False, True)
-    -1>> =suggMasSing(@, True)                                                                      # “\1” devrait être au masculin singulier.
-
-__[i]/gn(gn_toute_nom_fem_sing)__
-    toute ({w3})  @@6
-    <<- morph(\1, ":[NAQ].*:[mp]") and morph(word(-1), ":R|>de ", False, True)
-    -1>> =suggFemSing(@, True)                                                                      # “\1” devrait être au féminin singulier.
-
-__[i]/gn(gn_tous_nom_mas_plur)__
-    tous ({w3})  @@5
-    <<- morph(\1, ":[NAQ].*:[fs]") and morph(word(-1), ":R|>de ", False, True)
-    -1>> =suggMasPlur(@, True)                                                                      # “\1” devrait être au masculin pluriel.
-
-__[i]/gn(gn_toutes_nom_fem_plur)__
-    toutes ({w3})  @@7
-    <<- morph(\1, ":[NAQ].*:[ms]") and morph(word(-1), ":R|>de ", False, True)
-    -1>> =suggFemPlur(@, True)                                                                      # “\1” devrait être au féminin pluriel.
-
-TEST: Tout {{hommes}}
-TEST: De tous {{âge}} !
-TEST: avec toutes {{femme}}                                   ->> femmes
-TEST: sur toutes {{armure}}                                   ->> armures
-TEST: Toute {{époux}} doit faire preuve de bienveillance
-TEST: Il se souvient de toute mon histoire.
-TEST: Tout les sépare.
-TEST: les tout débuts du mouvement ouvrier
-TEST: vos tout débuts furent difficiles
-TEST: aux tout débuts, il y eut bien des erreurs
-TEST: comment les inégalités sociales impactent la santé des tout petits
-
-
-
-!!
-!!
-!!!! Adverbes de négation                                                                           
-!!
-!!
-
-__[i]/neg(ne_manquant1)__
-    (?:je|tu|ils?|on|elles?) ([bcdfgjklmnpqrstvwxz][\w-]*) (pas|rien|jamais|guère)  @@w,$
-    <<- morph(\1, ":[123][sp]", False) and not (re.search("(?i)^(?:jamais|rien)$", \2) and before(r"\b(?:que?|plus|moins) "))
-    -1>> ne \1                                                                                      # Ne … \2 : il manque l’adverbe de négation.
-
-__[i]/neg(ne_manquant2)__
-    (?:je|tu|ils?|on|elles?) ([aeéiouœ][\w-]*) (pas|rien|jamais|guère)    @@w,$
-    <<- morph(\1, ":[123][sp]", False) and not (re.search("(?i)^(?:jamais|rien)$", \2) and before(r"\b(?:que?|plus|moins) "))
-    -1>> n’\1                                                                                       # Ne … \2 : il manque l’adverbe de négation.
-
-__[i]/neg(ne_manquant3)__
-    (?:je|tu|ils?|on|elles?) ([mts](?:e +|’(?:en|y) +|’)|[vn]ous +|l(?:e +|a +|eur +|ui +|l’))({w_1}) (pas|rien|jamais|guère)  @@*,w,$
-    <<- morph(\2, ":[123][sp]", False) and not (re.search("(?i)^(?:jamais|rien)$", \3) and before(r"\b(?:que?|plus|moins) "))
-    -1>> ne \1                                                                                      # Ne … \3 : il manque l’adverbe de négation.
-
-__[i]/neg(ne_manquant4)__
-    (?:je|tu|ils?|on|elles?) (y|en) ({w_1}) (pas|rien|jamais|guère)  @@w,w,$
-    <<- morph(\2, ":[123][sp]", False) and not (re.search("(?i)^(?:jamais|rien)$", \3) and before(r"\b(?:que?|plus|moins) "))
-    -1>> n’\1                                                                                       # Ne … \3 : il manque l’adverbe de négation.
-
-TEST: __neg__ On {{a}} pas compris.
-TEST: __neg__ Il {{part}} pas encore.
-TEST: __neg__ On {{vous }}a pas compris.
-TEST: __neg__ On {{en}} a pas.
-TEST: __neg__ Il {{y}} a jamais d’eau.
-
-
-
-!!
-!!
-!!!! Infinitif                                                                                      
-!!
-!!
-
-__[i](p_ne_plus_pas_jamais_beaucoup_trop_rien)__
-    ne (?:pas|plus|jamais) +(beaucoup|trop|rien)  @@$ <<- ~1>> *
-
-__[i]/infi(infi_ne)__
-    ne (?:pas|rien|jamais(?: rien| plus|)|plus(?: jamais| rien| guère|)|guère|point) (?:non plus |)(?:l(?:e(?:ur|s|)|a|ui) |nous |vous |[mtsl]’(?:en |y |)|[mts]e |en |y |)({w_1})
-    @@$
-    <<- not morph(\1, ":(?:Y|W|O[ow])|>que? ", False) and spell(\1)
-    -1>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
-
-TEST: ne jamais {{cédé}}
-TEST: ne rien {{finit}}
-TEST: ne jamais plus s’y {{frottait}}
-TEST: ne plus guère y {{pensée}}
-TEST: ne pas les {{contrariés}}
-TEST: Ne rien m’en {{dit}}
-TEST: Ne jamais lui {{donnait}} sa chance.
-TEST: Il a décidé de ne plus {{mangés}} avec nous.
-TEST: ne plus {{mangez}} fait maigrir
-TEST: ne plus {{mangées}} fait maigrir
-TEST: ne pas {{allé}}
-TEST: Ne jamais {{mangez}} de viande !
-TEST: J’espère ne pas te déranger
-TEST: Ne pas te le donner, ce serait une insulte.
-TEST: ne jamais vraiment évoquer le sujet
-TEST: déterminés à ne pas se laisser récupérer
-TEST: de ne pas en élire du tout
-TEST: Mais gare à ne pas non plus trop surestimer la menace
-TEST: ne jamais beaucoup bosser, c’est sa devise.
-
-
-__[i]/imp(imp_infinitif_erroné)__
-    n(?:e +|’)({w_2}er) +(?:pas|jamais) @@w
-    <<- morph(\1, ":V1.*:Y", False) and isStart() -1>> =suggVerbTense(\1, ":E", ":2p")              # Confusion probable : “\1” est un verbe à l’infinitif. Si vous vouliez utiliser l’impératif, écrivez :
-
-TEST: Non, ne {{manger}} pas ça.
-TEST: Ne {{donner}} jamais à manger ces saloperies au chat.         ->> donnez
-
-
-
-!!!
-!!!
-!!! Processeur: épuration des adverbes, locutions adverbiales, interjections et expressions usuelles
-!!!
-!!!
-
-# Dates
-__[s](p_date)__
-    (?:[dD]epuis le|[lL]e|[dD]u|[aA]u|[jJ]usqu au|[àÀ] compter du) (?:1(?:er|ᵉʳ)|\d\d?) (?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor)(?: \d+| dernier| prochain|) <<- ~>> *
-__[i](p_en_l_an_de_grâce_année)__
-    en l’an (?:de grâce |)\d+ <<- ~>> *
-__[s](p_en_de_mois_année)__
-    (?:[eE]n +|[dD](?:e +|’))(?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor) +\d{2,4} <<- ~>> *
-__[i](p_en_année)__
-    en \d\d+ <<- not morph(word(1), ":[AN].*:[pi]", False, False) ~>> *
-__[i](p_de_année)__
-    (de \d\d+) ({w_2}) @@0,$ <<- morph(\2, ":A.*:s", False) ~1>> *
-__[s](p_à_la_mi_mois)__
-    [àÀ] la mi-(?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor)(?:\d{2,4}|) <<- ~>> *
-__[i](p_à_l_été_automne_hiver)__
-    à l’(?:été|automne|hiver) \d{2,4}  <<- ~>> *
-__[i](p_au_printemps)__
-    au printemps \d{2,4}  <<- ~>> *
-
-TEST: Une étude de 2005 publiée dans le Journal
-TEST: Les cinq variantes de la couverture du magazine Wired d’avril 2016 consacrée à Silicon Valley.
-TEST: c’est donc la cinquième en 50 ans
-
-
-# nombres
-__[i](p_un_nombre)__
-    un (\d+) ({w_2}) @@w,$ <<- morph(\2, ":A.*:s")  ~1>> *
-
-TEST: l’équipe veut aussi voir dans la lettre le nombre d’or, un symbole d’harmonie, ainsi qu’un 6 retourné.
-
-
-## moi/toi/lui/elle/nous/vous/eux/elles seul·e·s
-__[i](p_moi_toi_seul)__     [mt]oi (seule?) @@4 <<- ~1>> *
-__[i](p_lui_seul)__         lui (seul) @@4 <<- ~1>> *
-__[i](p_elle_seule)__       elle (seule) @@5 <<- ~1>> *
-__[i](p_nous_seuls)__       [nv]ous (seule?s) @@5 <<- ~1>> *
-__[i](p_eux_seuls)__        eux (seuls) @@4 <<- ~1>> *
-__[i](p_elles_seules)__     elles (seules) @@6 <<- ~1>> *
-
-## personne d’autre que…
-__[i](p_personne_d_autre_que)__
-    personne (d’autre qu(?:e |’)(?:lui|elles?|[nv]ous|eux)) @@$ <<- ~1>> *
-
-## Avant
-__[i](p_dès_qqch)__         dès (?:à présent|aujourd’hui|maintenant|lors|que possible|(?:demain|hier)(?: (?:soir|matin|après-midi)|)) <<- ~>> *
-__[i](p_et_qqch)__          et (?:ainsi de suite|tutti quanti) <<- ~>> *
-__[i](p_et_ou)__            et(/ou) @@2 <<- ~1>> *
-__[i](p_quant_à_présent)__  quant à présent <<- ~>> *
-__[i](p_ni_qqch_ni_qqch)__
-    ni (?:à|avec|contre|pour|chez|sur|sous|devant|derrière) *(?:[tm]oi|lui|elles?|eux|[nv]ous|),? ni (?:à|avec|contre|pour|chez|sur|sous|devant|derrière) (?:[mt]oi|lui|elles?|eux|[nv]ous) <<- ~>> *
-
-
-## Inconditionnel
-__[i](p_24h_sur_24)__           24 ?h(?:eures|) ?(?:sur |/ ?)24 <<- ~>> *
-__[i](p_7j_sur_7)__             7 ?j(?:ours|) ?(?:sur |/ ?)7 <<- ~>> *
-__[i](p_sept_j_sur_sept)__      sept jours sur sept <<- ~>> *
-__[i](p_vq_h_sur_vq_)__         vingt-quatre heures sur vingt-quatre <<- ~>> *
-__<i](p_loc_de_début_phrase)__  ^ *(?:et(?: puis|)|puis|car|mais|or donc|m’est avis que) <<- ~>> *
-__[i](p_à_nn_pour_cent)__       à \d+(?:,\d+|) % <<- ~>> *
-__[i](p_à_côté_de)__            à côté (?:de (?:ça|lui|[mt]oi|[nv]ous)|d’(?:elles|eux))(?! et) <<- ~>> *
-__[i](p_à_la_qqch)__            à la (?:bo(?:nne franquette|urre)|con|dér(?:ive|obée)|diable|fois|leur|limite du supportable|longue|lumière de tout ce(?:ci|la)|manque|mords-moi-le-nœud|papa|petite semaine|pointe du progrès|première occasion|queue leu leu|ramasse|re(?:nverse|dresse|scousse)|sauvette|surprise générale|virgule près|volée) <<- ~>> *
-__[i](p_à_heure)__              à \d\d? ?h(?: ?\d\d|)(?: (?:du (?:matin|soir)|de l’après-midi|ce (?:matin|soir)|cet après-midi|demain (?:matin|soir|après-midi)|)|) <<- ~>> *
-__[i](p_à_loc_qqch1)__          à (?:califourchon|chacun|confesse|contre(?:cœur|temps)|demi-mot|foison|grand-peine|loisir|merveille|moitié|nouveau|outrance|peine|perpétuité|présent|raison|rallonge|rebrousse-poil|reculons|regret|renverse|risque|tâtons|tort|tout-va) <<- ~>> *
-__[i](p_à_loc_qqch2)__          à (?:au(?:cun prix|trui|tre chose)|bas (?:co[ûu]t|prix)|bâ(?:bord|tons rompus)|beaucoup près|belles dents|bien (?:des égards|pire|y (?:penser|réfléchir|songer|repenser))|bon (?:compte|escient|droit)|bout (?:de (?:bras|souffle|forces?)|nerfs|portant|touchant)|bras (?:ouverts|le corps)|brève échéance|but (?:non |)lucratif|cause d(?:e (?:ça|[mt]oi|lui|[nv]ous)|’e(?:lles?|ux))|ce (?:compte-là|moment-là|titre)|cet (?:égard|instant(?: précis|))|cette (?:date|époque(?: de l’année|)|heure de la (?:journée|nuit)|occasion)|chaque (?:fois|instant)|chaudes larmes|cœur (?:joie|ouvert|perdu)|ciel ouvert|contre-cœur|corps perdu|cou(?:p sûr|per le souffle|rt terme|rte (?:échéance|portée))|couilles rabattues|de (?:nombreuses|multiples) reprises|des kilomètres à la ronde|défaut d’autre chose|dose homéopathique|double (?:titre|tranchant)|durée limitée|en (?:juger par (?:[mts]on|[nv]otre|leur) expérience|perdre (?:haleine|la tête))|faible (?:allure|revenu)|feu et à sang|flanc de (?:colline|montagne)|fleur de peau|franchement parler|géométrie variable|grand(?:-peine|e échelle)|haut risque|hue et à dia|huis clos|intervalles (?:ir|)réguliers|juste (?:raison|titre)|long terme|longue(?: échéance| portée|ur (?:de (?:temps|journée))|d’année)|loyer modéré|main(?: (?:armée|droite|gauche|levée)|s nues)|maint(?:s égards|es reprises)|marche forcée|merveille|mi-(?:course|distance|temps)|mi(?:di|nuit)(?: pile|)|moindres frais|mots couverts|moyen(?: terme|ne échéance)|n’en (?:pas douter|point douter|plus finir)|outrance|parler franc|part (?:entière|ça|ce(?:la|ci))|partir de là|part(?:ir de rien|s égales)|pas de (?:géant|loup|tortue|velours)|personne en danger|perte de vue|petit(?: feu|e (?:dose|échelle))|peu (?:de (?:distance|choses près|frais)|près)|pieds joints|pile ou face|plat(?: ventre|e couture)|plein(?: (?:régime|temps|nez)|s poumons)|plus (?:forte raison|d’un titre)|point nommé|portée de (?:main|tir)|première vue|prix (?:cassé|modique)s?|proprement parler|qui (?:mieux mieux|que ce soit|de droit)|quelque(?: distance|s (?:exceptions|nuances) près)|ras bords?|rude épreuve|s’y méprendre|somme nulle|tel point|temps (?:plein|partiel|complet)|tête reposée|tire[ -]d’aile|titre (?:conservatoire|d’exemple|expérimental|indicatif|informatif|grâcieux|personnel|posthume)|tombeau ouvert|tort (?:ou à raison|et à travers)|tour de (?:bras|rôle)|tous (?:crins|points de vue)|toutes (?:fins utiles|jambes)|tribord|tu et à toi|un moment donné|usage interne|visage (?:découvert|humain)|vive allure|voix (?:haute|basse)|vol d’oiseau|vrai dire|vue d’œil|y (?:regarder de plus près|réfléchir)) <<- ~>> *
-__[i](p_à_partir_de)__          à partir (?:de (?:demain(?: matin| midi| soir|)|là|maintenant|rien)|d’(?:aujourd’hui|hier(?: matin| midi| soir|)|ici)) <<- ~>> *
-__[i](p_à_quelques_uns)__       à quelques-un(?:s d’entre (?:eux|nous|vous)|es d’entre (?:nous|vous|elles)) <<- ~>> *
-__[i](p_à_tout_qqch)__          à tout(?: (?:âge|bout de champ|crin|instant|jamais|le (?:moins|monde)|moment|point de vue|prix|un chacun)|e (?:allure|bride|épreuve|force|heure(?: d(?:u jour|e la nuit)|)|vitesse|volée)) <<- ~>> *
-__[i](p_à_l_qqch)__             à l’(?:heure (?:actuelle|qu il est)|accoutumée|amiable|avance|aven(?:ir(?: incertain)|ant)|air libre|aveuglette|emporte-pièce|échelle (?:nationale|mondiale|régionale|départementale|cantonale|locale|galactique|universelle)|évidence|exclusion de toute autre chose|improviste|inverse|occasion|ordre du jour|œil nu|en croire|un(?:animité| (?:d’entre eux|des leurs)|e (?:d’entre elles|des leurs))) <<- ~>> *
-__[i](p_à_det_plur_qqch)__      à (?:[mts]es|[nv]os|leurs) (?:côtés|dépens|risques et périls|trousses) <<- ~>> *
-__[i](p_à_det_sing_fem_qqch)__  à (?:[mts]a|[nv]otre|leur) (?:connaissance|disposition|grande (?:surprise|tristesse)|guise|juste mesure|portée) <<- ~>> *
-__[i](p_à_det_sing_mas_qqch)__  à (?:[mts]on|[nv]otre|leur) (?:avis|c(?:œur|orps) défendant|détriment|encontre|égard|grand (?:désarroi|soulagement)|insu|sujet|tour) <<- ~>> *
-__[i](p_à_midi_minuit)__        à mi(?:di|nuit)(?: pile|) <<- ~>> *
-__[i](p_à_cette_heure)__        à cette heure(?: (?:du jour|de la nuit|tardive|matinale)|) <<- ~>> *
-__[i](p_a_loc_latine)__         [aà] (?:priori|post[eé]riori|contrario|cappella|minima) <<- ~>> *
-__[i](p_ab_loc_latine)__        ab (?:absurdo|initio) <<- ~>> *
-__[i](p_ad_loc_latine)__        ad (?:hoc|vitam æternam|hominem|infinitum|nauseam|valorem|patres) <<- ~>> *
-__[i](p_advienne_que_pourra)__  advienne que pourra <<- ~>> *
-__[i](p_après_qqch)__           après (?:[mts]oi|lui|eux|mûre réflexion|tout,|un certain temps|cette date(?: fatidique|)|un bon bout de temps) <<- ~>> *
-__[i](p_qqch_après_identique)__ (heure|minute|seconde|jour|nuit|semaine|trimestre|semestre|mois|décennie|année|siècle|génération) après \1 @@0 <<- ~>> *
-__[i](p_au_dessus_delà_qqch)__  au-de(?:ssus (?:de (?:[mts]oi|lui|[nv]ous)|d’(?:eux|elles?))|là du descriptible) <<- ~>> *
-__[i](p_au_qqch)__              au (?:[xXvViI]+[eᵉ] siècle|bas mot|beau fixe|bon moment|bout (?:du (?:compte|rouleau)|d’un moment)|cas par cas|commencement|contraire|coude à coude|coup par coup|déb(?:otté|but)|demeurant|doigt mouillé|fil (?:des ans|du temps)|grand (?:complet|jamais)|hasard|jour (?:et à l’heure dits|le jour)|jugé|leur|lieu de (?:ce(?:la|ci)|ça|quoi)|loin|même titre que n’importe l(?:aquelle|equel) d’entre (?:nous|vous|eux|elles)|milieu de nulle part|moment opportun|pas de (?:charge|course)|plus (?:haut point|près|pressé|vite|tôt|tard)|premier abord|préalable|propre comme au figuré|quotidien|ras des pâquerettes|saut du lit|sens (?:figuré|large|propre)|surplus) <<- ~>> *
-__[i](p_au_adj_moment)__        au (?:dernier|même|bon|mauvais) (?:moment|instant) <<- ~>> *
-__[i](p_au_cours_des)__         au cours des (?:deux|trois|quatre|cinq|six|sept|huit|neux|dix|onze|douze|treize|quatorze|quinze|seize|dix-(?:sept|huit|neuf)|vingt|trente|quarante|cinquante|soixante|soixante-dix|quatre-vingt|quatre-vingt-dix|cent) (?:derni(?:ère|er)s|prochaine?s) (?:années|mois|siècles) <<- ~>> *
-__[i](p_au_fond_de_qqch)__      (?:tout |)au fond (?:de (?:[mts]oi|lui|[nv]ous)|d’(?:elles?|eux))(?:-mêmes?|) <<- ~>> *
-__[i](p_aux_qqch)__             aux (?:abois|leurs|mien(?:ne|)s|tien(?:ne|)s|sien(?:ne|)s) <<- ~>> *
-__[i](p_autant_que_qqch)__      autant que (?:nécessaire|possible|prévu|faire se peut) <<- ~>> *
-__[i](p_autour_de_qqch)__       autour (?:d’(?:eux|elles?)|de (?:lui|[nv]ous|[mt]oi)) <<- ~>> *
-__[i](p_autrement_dit)__        autrement dit <<- ~>> *
-__[i](p_av_JC)__                av. J.-C. <<- ~>> *
-__[i](p_avant_qqch)__           avant (?:longtemps|terme|tout le monde|toute(?: chose|s choses)|d’aller plus loin|J.-C.|Jésus-Christ|d’en arriver là|de faire quoi que ce soit(?: de stupide|)|qu il ne soit trop tard|un bon bout de temps) <<- ~>> *
-__[i](p_avec_qqch1)__           avec (?:brio|joie|légèreté|insistance|peine|autre chose|pertes et fracas|un peu de chance|tout le respect que (?:je (?:vous|te|l(?:eur|ui)) dois|nous (?:vous|te|l(?:eur|ui)) devons)|tout un chacun|un peu de chance) <<- ~>> *
-__[i](p_avec_qqch2)__           avec (?:autrui|[mts]oi|lui|e(?:ux|lles?)|[nv]ous(?: autres)|le plus grand soin|tout le monde|tout ça|on ne sait quo?i)(?! qui) <<- ~>> *
-__[i](p_beaucoup_plus_moins)__  beaucoup (?:plus|moins) <<- ~>> *
-__[i](p_bel_et_bien)__          bel et bien <<- ~>> *
-__[i](p_bien_adv_temps)__       bien (?:assez tôt|des fois|souvent) <<- ~>> *
-__[i](p_bon_gré_mal_gré)__      bon gré,? mal gré <<- ~>> *
-__[i](p_bras_dessus_dessous)__  bras dessus,? bras dessous <<- ~>> *
-__[i](p_çà_et_là)__             çà et là <<- ~>> *
-__[i](p_ce_faisant)__           ce faisant <<- ~>> *
-__[i](p_ceci_qqch)__            ceci (?:mis à part|va sans dire) <<- ~>> *
-__[i](p_cela_qqch)__            cela (?:mis à part|va sans dire) <<- ~>> *
-__[i](p_ces_derniers_temps)__   ces derniers temps <<- ~>> *
-__[i](p_ceux_d_entre_pronom)__  ce(?:lui|lles?|ux) (d’entre (?:[nv]ous|eux|elles)) @@$ <<- ~1>> *
-__[i](p_cette_fois_là)__        cette fois-(?:là|ci) <<- ~>> *
-__[i](p_chacun_d_entre_nous)__  chacune? (d’entre (?:[nv]ous|eux|elles)) @@$ <<- ~1>> *
-__[i](p_chaque_fois)__          chaque fois <<- ~>> *
-__[i](p_chemin_de_fer)__        chemins? (de fer) @@$ <<- ~1>> *
-__[i](p_chez)__                 chez (?:[mt]oi|lui|e(?:ux|lles?)|[nv]ous|autrui|quelqu’une?|on ne sait qui) <<- ~>> *
-__[i](p_comme_qqch)__           comme (?:avant|autrefois|d’habitude|toujours|de juste|bon (?:me|te|l(?:ui|eur)|[nv]ous) semble|au bon vieux temps|cul et chemise|frappée?s? par la foudre|n’importe où(?: ailleurs|)|par (?:enchantement|magie|un fait exprès)|promis|qui dirait|si de rien n’était|tout un chacun) <<- ~>> *
-__[i](p_comme_tant_d_autres)__  comme tant d’autres (?:avant|après) (?:[mts]oi|lui|[nv]ous|eux|elles?)(?! qui) <<- ~>> *
-__[i](p_contrairement_aux_apparences)__     contrairement aux apparences <<- ~>> *
-__[i](p_contre_qqch)__          contre (?:mauvaise fortune,? bon cœur|nature|toute (?:attente|vraisemblance)|vents et marées|[mts]oi|lui|elles?|[nv]ous|eux|(?:[mts]on|[nv]otre|leur) gré) <<- ~>> *
-__[i](loc_côte_à_côte)__
-    c[ôo]tt?es? [àaá] c[ôo]tt?es?
-    <<- not re.search("(?i)^côte à côte$", \0) ->> côte à côte      # Locution adverbiale invariable. Écrivez “côte à côte”.|https://fr.wiktionary.org/wiki/c%C3%B4te_%C3%A0_c%C3%B4te
-    <<- ~>> *
-__[i](p_coute_que_coute)__      co[ûu]te que co[ûu]te <<- ~>> *
-__[i](p_crois_le_ou_non)__      cro(?:yez|ois)-le ou (?:non|pas) <<- ~>> *
-__[i](p_cul_par_dessur_tête)__  cul par-dessus tête <<- ~>> *
-__[i](p_dans_qqch)__            dans (?:ces? cas(?: précis|-là|-ci| particuliers?|)|l’i(?:déal|mmédiat)|la mesure du possible|les années \d\d+|peu de temps|tout (?:ce(?:la|ci)|ça)|très peu de temps|un(?: cas comme dans l’autre|e (?:certaine|large|moindre) mesure)) <<- ~>> *
-__[i](p_début_mois)__           début (?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre)(?: \d\d\d\d|) <<- ~>> *
-__[i](p_d_qqch)__               d’(?:abord|affilée|ailleurs|année en année|aujourd’hui|antan|autant (?:plus|moins)|autre(?:fois|s fois| part)|arr(?:arrache-?pied|ière en avant)|avant en arrière|à côté|âge mûr|emblée|empoigne|en face|entr(?:e (?:[nv]ous|eux|elles)|ée de jeu)|est en ouest|extrême[ -](?:droite|gauche)|égale? à égale?|habitude|heure en heure|hier(?: (?:matin|soir|après-midi)|)|ici(?: là| peu(?: de temps|)| très peu(?: de temps|)|)|ordinaire|origine (?:inconnue|douteuse)|ordre général|ouest en est|ore?s et déjà|un (?:autre côté|(?:bout à|côté comme de) l’autre|commun accord)) <<- ~>> *
-__[i](p_d_une_qqch)__           d’une (?:autre trempe|(?:façon|manière) ou d’une autre|certaine (?:façon|manière)|tout autre ampleur|(?:minute|seconde) à l’autre) <<- ~>> *
-__[i](p_d_où_que)__             d’où qu (?:(?:il|elle|on) vienne|(?:ils|elles) viennent) <<- ~>> *
-__[i](p_de_ci_de_là)__          de-ci,? de-là <<- ~>> *
-__[i](p_de_heure)__             de \d\d? ?h(?: ?\d\d|)(?: (?:du (?:matin|soir)|de l’après-midi|ce (?:matin|soir)|cet après-midi|demain (?:matin|soir|après-midi))|) <<- ~>> *
-__[i](p_de_qqch)__              de (?:\d+(?:,\d+|) ?%|cesse|conserve|facto|fait|guingois|luxe|nouveau|permanence|partout|préférence|profundis|rechange|routine|surcro[îi]t|visu|A à Z|bas(?: (?:en haut|étage)|se (?:condition|extraction|))|bon (?:aloi|cœur|gré|matin|sens|ton)|bonne (?:facture|famille|foi|heure|humeur|grâce|qualité|compagnie)|bric et de broc|but en blanc|ce(?: (?:fait(?: même|)|seul fait|point de vue)|tte sorte|t acabit)|courte (?:durée|vue)|dernière minute|demain(?: (?:matin|soir|après-midi)|)|droite (?:à|comme de) gauche|fâcheuse mémoise|fil en aiguille|fond en comble|fort (?:loin|près)|fra[iî]che date|ga[îi]e?té de cœur|gauche (?:à|comme de) droite|grande (?:taille|envergure)|gré ou de force|guerre lasse|haut(?: (?:en bas|rang|vol)|e (?:lutte|stature|volée))|jour comme de nuit|là-bas|la (?:meilleure (?:manière|façon) possible|même (?:façon|manière)|sorte|tête aux pieds|veille)|loin(?: en loin|)|longue (?:date|durée|haleine)|main de ma[îi]tre|mauvais(?: (?:aloi|go[ûu]t|gré)|e (?:foi|grâce|humeur))|mieux en mieux|nature (?:inconnue|indéterminée|insolite)|nombreuses (?:fois|années plus (?:tôt|tard))|nos jours|notoriété publique|nulle part|pire en pire|près(?: ou de loin|)|par(?: le monde(?: entier|)|t et d’autre)|petite taille|pied ferme|premi(?:er (?:ordre|plan)|ère main)|plein (?:droit|fouet)|plus (?:belle|près)|première (?:catégorie|nécessité)|prime abord|proche en proche|pure forme|sang-froid|seconde (?:zone|importance|main)|si bon(?: matin|ne heure)|source sûre|taille moyenne|telle sorte|temps (?:en temps|à autre)|tr(?:ès|op) (?:loin|près)|vive voix) <<- ~>> *
-__[i](p_de_nous_vous_tous)__    de [nv]ous tous <<- ~>> *
-__[i](p_de_tout_qqch)__         de tou(?:t (?:poil|temps|à l’heure|premier (?:ordre|plan))|tes (?:parts|pièces|sortes|(?:[mts]es|leurs|[nv]os) forces)|te (?:éternité|évidence|façon|urgence)|s (?:côtés|bords)) <<- ~>> *
-__[i](p_de_ceux_celles)__       de ce(?:ux|lles)-(?:ci|là)(?! qui) <<- ~>> *
-__[i](p_de_det_mas_qqch)__      de (?:[mts]on|[nv]otre|leur) (?:mieux|plein gré|point de vue|propre (?:cru|chef)|vivant) <<- ~>> *
-__[i](p_de_det_fem_qqch)__      de (?:[mts]a|[nv]otre|leur) part <<- ~>> *
-__[i](p_de_qqch_en_identique)__ de (moins|plus|mieux|pire|jour|minute|semaine|mois|trimestre|semestre|siècle|millénaire|décennie) en \1 @@3 <<- ~>> *
-__<i](p_de_plus)__              ^ *de plus <<- ~>> *
-__[i](p_des_qqch)__             des (?:fois|pieds à la tête|uns et des autres|(?:années|mois|siècles|millénaires|décennies|semaines) plus t(?:ôt|ard)) <<- ~>> *
-__[i](p_depuis_qqch)__          depuis (?:assez longtemps|belle lurette|bien longtemps|de (?:très |)longues années|des lustres|longtemps|lors|peu de temps|quelque temps|quelques (?:secondes|minutes|heures|jours|semaines|mois|trimestres|semestres|années|décennies|siècles|millénaires)|si longtemps|toujours|tout ce temps|très longtemps) <<- ~>> *
-__[i](p_depuis_tps)__           depuis (\d+ (?:ans|années|mois|semaines|jours|heures|minutes|secondes|)|les années \d\d+) @@$ <<- ~>> *
-__[i](p_Dieu_en_garde_témoin)__ Dieu (?:[mt]’en (?:garde|soit témoin)|[nv]ous en (?:garde|soit témoin)|l(?:es |’)en garde|l(?:eur|ui) en soit témoin) <<- ~>> *
-__[i](p_du_moins)__             du moins <<- ~>> _
-__[i](p_du_qqch)__              du (?:[xXvViI]+[eᵉ] siècle|bout des lèvres|début à la fin|fond du cœur|jour au lendemain|haut en bas|même (?:acabit|tonneau)|moins,? pas|(?:nord|sud) au (?:nord|sud)|tout au tout) <<- ~>> *
-__[i](p_demain)__               (?:après-|avant |)demain(?: matin| soir| après-midi|) <<- ~>> *
-__[i](p_don_Juan)__             (don) Juan @@0 <<- ~1>> *
-__[i](p_du_même_ordre_coup)__   du même (?:ordre|coup) <<- ~>> *
-__[i](p_en_nombre_années)__     en \d\d+(?: ans| années| mois| semaines| jours| heures| minutes| secondes|) <<- ~>> *
-__[i](p_en_cours)__             en cours(?! d[e’]) <<- ~>> *
-__[i](p_en_pronom)__            en (?:[mt]oi|eux|elles?) <<- ~>> *
-__[i](p_en_qqch1)__             en (?:aparté|apparence|arrière|avance|avant|cachette|ceci|cela|clair|commun|conséquence|continu|contrepartie|définitive|détail|direct|douce|effet|émoi|filigrane|général|goguette|hâte|majorité|outre|pâmoison|parallèle|partie|particulier|permanence|personne|pratique|prime|privé|principe|priorité|public|réalité|retour|revanche|rien|rogne|route|secret|silence|somme|suspens|théorie|trompe-l’œil|vain|vérité|ville|vitesse) <<- ~>> *
-__[i](p_en_qqch2)__             en (?:aucun(?: cas|e (?:circonstance|façon|manière))|bon(?: état|ne (?:compagnie|et due forme|posture|santé(?: physique| mentale|)|voie))|bout de course|cas d(?:e (?:besoin|doute)|’urgence)|chacune? d(?:e [nv]ous|’(?:eux|elles))|chair et en os|chute libre|comparution immédiate|connaissance de cause|coupe réglée|cours de route|d’autres (?:circonstances|termes|temps)|de telles circonstances|début d(?:e (?:journée|matinée|soirée)|’après-midi)|définitive|dehors de (?:tout|)(?:ça|cela|ceci)|dents de scie|dernier (?:lieu|recours|ressort)|désespoir de cause|détention provisoire|direction d(?:u (?:nord|sud)(?:-est|-ouest|)|e l’(?:est|ouest))|état (?:de (?:choc(?: circulatoire|)|marche)|d’ébriété(?: avancée|))|excellent état|file indienne|fin d(?:e (?:compte|journée|matinée|soirée)|’après-midi)|forte (?:baisse|hausse)|gage de bonne foi|garde à vue(?: prolongée|)|grand(?: nombre|e (?:difficulté|majorité|partie|pompe))|haut lieu|l’occurrence|lieu sûr|ligne de (?:compte|mire)|mains propres|mauvais(?: état|e (?:posture|santé))|même temps|milieu d(?:e (?:journée|matinée|soirée)|’après-midi)|nombre (?:plus que |)suffisant|partant de zéro|plein(?: air| cœur| jour|e (?:gueule|figure|forme|poire|nuit|tronche))|perte de vitesse|peu de temps|piteux état|point d(?:e mire|’orgue)|position de (?:force|faiblesse)|premi(?:er lieu|ère (?:instance|ligne))|pure perte|quantité (?:plus que |)suffisante|quelque sorte|queue de peloton|rangs serrés|rase campagne|règle générale|roue libre|sens inverse|si peu de temps|sous-main|tête à tête|temps (?:et en heure|normal|opportun|ordinaire|utile|voulu)|termes choisis|toile de fond|tous (?:les cas|sens)|tout (?:bien tout honneur|cas|genre|lieu|et pour tout|état de cause|premier lieu|sens|temps)|toute(?: (?:bonne foi|circonstance|connaissance de cause|confiance|discrétion|franchise|hâte|impartialité|impunité|innocence|légalité|liberté|logique|sécurité|simplicité)|s circonstances)|un (?:clin d’œil|rien de temps)|une autre occasion|vase clos|voie de développement|y réfléchissant bien) <<- ~>> *
-__[i](p_en_mois_dernier)__      en (?:janvier|février|mars|avril|mai|jui(?:n|llet)|ao[ûu]t|septembre|octobre|novembre|décembre) dernier <<- ~>> *
-__[i](p_en_dat_mas_qqch)__      en (?:[mts]on|leur|[nv]otre) (?:âme et conscience|for intérieur|nom propre) <<- ~>> *
-__[i](p_en_ce_qqch)__           en ce(?: (?:moment|temps-là|qui (?:[mt]e|l(?:es?|a)|[nv]ous) concern(?:e|ait))|t instant) <<- ~>> *
-__[i](p_encore_qqch)__          encore (?:une fois|et (?:encore|toujours)) <<- ~>> *
-__[i](p_envers_qqch)__          envers (?:autrui|et contre tout|les uns et les autres|tout le monde) <<- ~>> *
-__[i](p_entre_qqch)__           entre (?:(?:[mt]oi|lui|elles?|[nv]ous|eux) et (?:[mt]oi|lui|elles?|[nv]ous|eux)|chien et loup|de (?:bonnes|mauvaises) mains|l’une? et l’autre|les uns et les autres|quat(?:re[- ]z-?yeux|’ z-?yeux)) <<- ~>> *
-__[i](p_entre_date)__           entre (?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre) (?:\d\d{1,3} |)et (?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre)(?: \d\d{1,3}|) <<- ~>> *
-__[i](p_épaule_contre_épaule)__ épaule contre épaule <<- ~>> *
-__[i](p_été_comme_hiver)__      été comme hiver <<- ~>> *
-__[i](p_oh_ah_euh_eh_bien)__    (?:oh|ah|euh|eh bien) <<- ~>> *
-__[i](p_ex_loc_latine)__        ex (?:nihilo|cathedra|absurdo|abrupto) <<- ~>> *
-__[i](p_face_à_face)__          face à face <<- ~>> *
-__[i](p_nombre_fois_de_suite)__ (?:deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze|treize|quatorze|quinze|seize|vingt|trente|quarante|cinquante|soixante|cent) fois de suite <<- ~>> *
-__[i](p_grosso_modo)__          grosso modo <<- ~>> *
-__[i](p_grand_bien_lui_fasse)__ grand bien lui fasse <<- isStart() ~>> *
-__[i](p_hier)__                 (?:avant-|)hier(?: matin| soir| après-midi|) <<- ~>> *
-__[i](p_hors_de_qqch)__         hors (?:de (?:contrôle|portée)|d’(?:atteinte|état de nuire)|du commun) <<- ~>> *
-__[i](p_ici_qqch)__             ici(?: comme ailleurs| ou ailleurs| et (?:là|maintenant)| même|-bas) <<- ~>> *
-__[i](p_id_est)__               id est <<- ~>> *
-__[i](p_il_y_a_qqch)__          il y a (?:longtemps|peu de temps|très (?:longtemps|peu de temps)|(?:quelques|moins de \d+|\d+) (?:secondes|minutes|heures|jours|semaines|mois|an(?:née|)s|siècles|millénaires)|quelque temps) <<- ~>> *
-__[i](p_il_n_y_a_pas_qqch)__    il n’y a pas (?:si |)longtemps <<- ~>> *
-__[i](p_illico_presto)__        illico presto <<- ~>> *
-__[i](p_in_loc_latine)__        in (?:abstracto|extenso|extremis|fine|petto|situ|utero|vitro|vivo) <<- ~>> *
-__[i](p_ipso_facto)__           ipso facto <<- ~>> *
-__[i](p_j_en_passe)__           j’en passe et des meilleure?s <<- ~>> *
-__[i](p_jour_pour_jour)__       jour pour jour <<- ~>> *
-__[i](p_jusque_là)__            jusque-là <<- ~>> *
-__[i](p_jusque_qqch)__          jusqu (?:alors|ici|aujourd’hui|au bout des ongles) <<- ~>> *
-__[i](p_jusque_à_qqch)__        jusqu à (?:aujourd’hui|bac|présent|maintenant|récemment|(?:demain|hier)(?: matin| soir| après-midi|)|nouvel ordre|plus (?:ample informé|soif)|preuve du contraire|la (?:fin de(?: (?:[mts]es|[nv]os|leurs) jours|s temps)|tombée de la nuit)|(?:[mts]on|leur|[nv]otre) dernier souffle(?: de vie|)|ce que (?:mort s’ensuive|(?:j’en sache|tu en saches|(?:il|elle|on) en sache|nous en sachions|vous en sachiez|(?:ils|elles) en sachent) plus)|Noël|Pâques) <<- ~>> *
-__[i](p_la_qqch)__              la (?:plupart du temps|main dans la main|mort dans l’âme) <<- ~>> *
-__[i](p_le_qqch)__              le (?:cas échéant|moins (?:du monde|souvent)|plus (?:tôt|tard|souvent|de (?:temps|monde)) possible|moment venu|plus souvent) <<- ~>> *
-__[i](p_là_qqch)__              là(?:-bas|-haut|-de(?:dans|hors|rrière|sso?us|vant)| non plus) <<- ~>> *
-__[i](p_l_un_qqch)__            l’une? (?:après|pour|de(?:rrière|)|avec|contre|sur|près de) l’autre <<- ~>> *
-__[i](p_le_pour_et_le_contre)__ le pour et le contre <<- ~>> =\0.replace(" ", "_")
-__[i](p_les_uns_les_autres)__   les une?s (?:des |(?:après |pour |avec |contre |sur |derrière |devant |)les) autres <<- ~>> *
-__[i](p_non_loin)__             non loin (?:d’ici|de là) <<- ~>> *
-__[i](p_loin_qqch)__            loin (?:de (?:là|tout ça)|d’(?:être|ici)|s’en fa(?:ut|llait)) <<- ~>> *
-__[i](p_maintes_fois)__         (?:[lcd]es |)maintes fois <<- ~>> *
-__[i](p_malgré_pronom)__        malgré (?:[mt]oi|lui|elles?|[nv]ous|eux)(?! qui) <<- ~>> *
-__[i](p_malgré_ça)__            malgré (?:ça|cela|tout) <<- ~>> *
-__[i](p_manu_militari)__        manu militari <<- ~>> *
-__[i](p_mieux_vaut_tard_que_jamais)__       mieux va(?:u|lai)t tard que jamais <<- ~>> *
-__[i](p_moins_que_nécessaire)__             moins que (?:nécessaire|prévu) <<- ~>> *
-__[i](p_moitié_qqch_moitié_qqch)__          moitié ({w2}),? moitié ({w2}) @@7,$ <<- ~>> *
-__[i](p_mot_pour_mot)__         mot pour mot <<- ~>> *
-__[i](p_mutatis_mutandis)__     mutatis mutandis <<- ~>> *
-__[i](p_ne_vous_en_déplaise)__  ne (?:vous |l(?:ui|eur) |t’)en déplaise <<- ~>> *
-__[i](p_nez_à_nez)__            nez à nez <<- ~>> *
-__[i](p_ni_qqch)__              ni (?:de près,? ni de loin|plus ni moins|vu,? ni connu) <<- ~>> *
-__[i](p_non_qqch)__             non (?:plus|sans raison|seulement) <<- ~>> *
-__[i](p_nulle_part)__           nulle part <<- ~>> *
-__[i](p_ô_combien)__            ô combien <<- ~>> *
-__[i](p_ou_bien)__              ou (bien) @@3 <<- ~1>> *
-__[i](p_ou_qqch_d_approchant)__ ou quelque chose d’approchant <<- ~>> *
-__[i](p_où_bon_nous_semble)__   où bon (?:me|te|lui|nous|vous|leur) semble <<- ~>> *
-__[i](p_oui_et_ou_non)__        oui (?:ou|et) non <<- ~>> *
-__[i](p_outre_mesure)__         outre mesure <<- ~>> *
-__[i](p_qqch_par_qqch)__        (une?|deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze|treize|quatorze|quinze|seize|vingt|trente|quarante|cinquante|soixante|cent|mille|éta[pg]e|morceau|pièce) par \1 @@0 <<- ~>> *
-__[i](p_par_qqch1)__            par (?:à-coups|ailleurs|avance|chance|conséquent|curiosité|contre|défaut|définition|endroits|essence|ex(?:cellence|emple)|hasard|ici|inadvertance|là|moments|monts et par vaux|nature|principe|terre) <<- ~>> *
-__[i](p_par_qqch2)__            par (?:la (?:même occasion|suite)|(?:bien des|certains) (?:aspects|côtés)|acquit de conscience|beau temps|bonté de cœur|ce biais|égard pour (?:moi|toi|lui|elles?|eux|nous|vous)(?! qui)|lui-même|elle(?:-même|)|eux(?:-mêmes|)|elles(?:-mêmes|)|le passé|les temps qui courent|[nv]ous-mêmes?|[mt]oi(?:-même|)|temps de pluie|tout le monde|voie (?:de (?:conséquence|mer|terre)|d’exception)) <<- ~>> *
-__[i](p_par_ci_par_là)__        par-ci,? par-là <<- ~>> *
-__[i](p_par_position)__         par-de(?:vant|rrière|ssus (?:le marché|tout)) <<- ~>> *
-__[i](p_par_devers_pronom)__    par-devers (?:moi|toi|lui|elles?|lui|eux|nous|vous) <<- ~>> *
-__[i](p_par_nombre_fois)__      par (?:deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze|treize|quatorze|quinze|seize|vingt|trente|quarante|cinquante|soixante|cent) fois <<- ~>> *
-__[i](p_parmi_qqch)__           parmi (?:[nv]ous(?: autres|)|eux|elles) <<- ~>> *
-__[i](p_partant_de_là)__        partant de là <<- ~>> *
-__[i](p_pas_qqch)__             pas (?:du tout|à pas|le moins du monde) <<- ~>> *
-__[i](p_pendant_qqch)__         pendant (?:ce temps-là|(?:bien |si |assez |très |)longtemps|plusieurs (?:heures|minutes|secondes|mois|semaines|jours|années|siècles|millénaires|décennies)|quelque temps) <<- ~>> *
-__[i](p_petit_à_petit)__        petit à petit <<- ~>> *
-__[i](p_peu_qqch)__             peu (?:à peu|de temps auparavant|ou prou) <<- ~>> *
-__[i](p_pile_poil)__            pile poil <<- ~>> *
-__[i](p_plein_qqch)__           plein (?:nord|sud|ouest|de fois) <<- ~>> *
-__[i](p_plus_avant)__           plus avant(?! de | que?) <<- ~>> *
-__[i](p_plus_qqch)__            plus (?:du tout|que (?:nécessaire|prévu|jamais|tout(?: au monde|e autre chose))|jamais|bas que terre|d’une fois) <<- ~>> *
-__[i](p_plusieurs_fois)__       plusieurs fois(?: de suite)? <<- ~>> *
-__[i](p_pour_qqch)__            pour (?:autrui|le (?:moment|moins|meilleur et pour le pire)|une fois|l’(?:essentiel|instant)|l’heure|de bon|la suite|un oui ou pour un non|ainsi dire|ce faire|quelque (?:part|temps)|tout (?:le monde|un chacun|dire)|faire (?:bonne mesure|simple)|y parvenir|couronner le tout|rien au monde|ce que (?:(?:j’|tu )en sais)|ça va(?:ut|lait)) <<- ~>> *
-__[i](p_pour_pronom)__          pour (?:[mt]oi|elles?|eux|ça|cela|ceci|ceux-(?:là|ci)|celles?-(?:là|ci))(?! qui) <<- ~>> *
-__[i](p_pour_xxx_fois)__        pour la (?:première|seconde|{w_2}ième|dernière) fois(?: de suite| de ma vie|) <<- ~>> *
-__[i](p_pour_det_fem_qqch)__    pour (?:[mts]a|[nv]otre|leur) (?:gouverne|part) <<- ~>> *
-__[i](p_pour_det_mas_qqch)__    pour (?:[mts]on|[nv]otre|leur) propre (?:compte|bien) <<- ~>> *
-__[i](p_pour_xxx_que_ça_intéresse)__        pour ce(?:lles?|ux|lui) (?:et ce(?:lles?|ux|lui) |)que (?:ça|ce(?:la|ci)) intéresse <<- ~>> *
-__[i](p_pour_s_en_rendre_compte)__          pour (?:[mts]’|[vn]ous )en rendre compte <<- ~>> *
-__[i](p_quand_qqch)__           quand b(?:ien même|on (?:[mt]e|l(?:ui|eur)|[nv]ous) semble) <<- ~>> *
-__[i](p_quant_à_pronom1)__      quant à (?:[mt]oi|lui|elles?|[nv]ous|eux)(?! qui) <<- ~>> *
-__[i](p_quant_à_pronom2)__      quant à (?:ça|cela|ceci) <<- ~>> *
-__[i](p_que_ça_plaise_ou_non)__ que (?:ça|ceci|cela) (?:me|te|l(?:ui|eur)|[nv]ous) plaise ou non <<- ~>> *
-__[i](p_que_voulu_ou_non)__     que (?:je le veuille|tu le veuilles|vous le vouliez|nous le voulions) ou non <<- ~>> *
-__[i](p_que_xxx_ou_non)__       qu (?:à cela ne tienne|(?:(?:il|elle|on) le veuille|(?:ils|elles) le veuillent) ou non) <<- ~>> *
-__[i](p_quel_qu_en_soit_le_qqch)__          quel qu en soit le (?:moyen|prix|risque(?: financier|)|danger) <<- ~>> *
-__[i](p_quelle_qu_en_soit_la_qqch)__        quelle qu en soit la (?:cause|raison) <<- ~>> *
-__[i](p_quelque_qqch)__         quelque(?: (?:part|temps)|s fois) <<- ~>> *
-__[i](p_quelques_tps_adv)__     quelques (?:instants|secondes|minutes|heures|jours|semaines|mois|années|décennies|siècles|millénaires|trimestres|semestres) (?:auparavant|plus (?:tard|tôt)) <<- ~>> *
-__[i](p_qui_plus_est)__         qui plus est <<- ~>> *
-__[i](p_qui_loc_tps)__          qui (ce (?:jour|matin|après-midi|soir)-là|cette (?:nuit|matinée|soirée)-là) @@4 <<- ~1>> *
-__[i](p_quoi_qu_il_qqch)__      quoi qu il (?:(?:arriv|en co[ûu]t)(?:e|ât)|adv(?:ienne|înt)) <<- ~>> *
-__[i](p_sans_difficulté)__      sans (?:grande|grosse) difficulté(?: apparente| aucune| financière| majeure| particulière|) <<- ~>> *
-__[i](p_sans_qqch)__            sans (?:ambages|arrêt|au(?:cun doute|tre forme de procès)|cesse|commune mesure|conteste|coup férir|crier gare|difficulté(?: apparente| aucune| financière| majeure| particulière|)|dire mot|doute|encombres?|états d’âme|fin|foi,? ni loi|l’ombre d’un doute|le (?:faire exprès|vouloir)|mot dire|nul doute|queue ni tête|raison apparente|relâche|répit|(?:grand |)succès|trêve|vergogne|(?:pour autant |)y (?:prendre g(?:arde|o[ûu]t)|faire attention|parvenir|réussir|réfléchir|songer|penser)|faire de vagues|s’en (?:rendre compte|apercevoir)|l’aide de personne) <<- ~>> *
-__[i](p_séance_tenante)__       séance tenante <<- ~>> *
-__[i](p_selon_qqch)__           selon (?:toute vraisemblance|(?:[mt]oi|lui|elles?|eux|nous|vous)(?! qui)) <<- ~>> *
-__[i](p_semble_t_il)__          sembl(?:e-t-il|ait-il) <<- ~>> *
-__[i](p_sens_dessus_dessous)__  sens dessus dessous <<- ~>> *
-__[i](p_seul_à_seul)__          seule?s? à seule?s? <<- ~>> *
-__[i](p_stp_svp)__              s’il (?:te|vous) pla[îi]t <<- ~>> *
-__[i](p_si_qqch)__              si (?:bas|besoin est|haut|longtemps|nécessaire|possible|soudain|(?:cela|ça) ne tenait qu à (?:moi|toi|lui|eux|elles?|nous|vous)) <<- ~>> *
-__[i](p_six_pieds_sous_terre)__ six pieds sous terre <<- ~>> *
-__[i](p_sine_loc_latine)__      sine (?:die|qua non) <<- ~>> *
-__[i](p_soi_qqch)__             soi(?:t dit en passant|-disant) <<- ~>> *
-__[i](p_sous_qqch)__            sous (?:aucun prétexte|bonne (?:escorte|garde)|coupe réglée|haute surveillance) <<- ~>> *
-__[i](p_stricto_sensu)__        stricto sensu <<- ~>> *
-__[i>(p_sur_ce)__               sur ce, <<- ~>> *
-__[i](p_sur_qqch)__             sur (?:ce plan-là|le (?:(?:long|moyen|court) terme|qui-vive)|la (?:forme comme sur le fond|même longueur d’onde)|(?:leur|[mts]on|[nv]otre) (?:trente[ -]et[ -]un|31)) <<- ~>> *
-__[i](p_tant_qqch)__            tant (?:bien que mal|s’en faut) <<- ~>> *
-__[i](p_tôt_ou_tard)__          tôt ou tard <<- ~>> *
-__[i](loc_tour_à_tour)__
-    tours? [àa] tours?
-    <<- not re.search("(?i)^tour à tour$", \0) ->> tour à tour      # Locution adverbiale invariable. Écrivez “tour à tour”.|https://fr.wiktionary.org/wiki/tour_%C3%A0_tour
-    <<- ~>> *
-__[i](p_tous_qqch)__            tous (?:comptes faits|frais payés) <<- ~>> *
-__[i](p_tout_qqch)__            tout (?:à (?:fait|coup|l’heure)|le temps|de (?:même|suite|go)|au plus|aussi bien|simplement|bonnement|compte fait|feu,? tout flammes?|bien (?:considéré|réfléchi)|du long) <<- ~>> *
-__[i](p_toutes_qqch)__          toutes (?:affaires cessantes|choses égales par ailleurs|griffes dehors|proportions gardées) <<- ~>> *
-__[i](p_trait_pour_trait)__     trait pour trait <<- ~>> *
-__[i](p_très_adverbe)__         très (?:bas|haut|bien|mal) <<- ~>> *
-__[i](p_un_à_un)__              (une?) à \1 @@0 <<- ~>> *
-__[i](p_un_qqch)__              un (?:à un|jour ou l’autre|instant plus (?:tôt|tard)|milli(?:er|on|ard) de fois|moment plus (?:tôt|tard)|peu (?:mieux|moins bien|partout|plus t(?:ôt|ard) que prévu)|tant soit peu) <<- ~>> *
-__[i](p_plus_tôt_tard_que)__    plus t(?:ôt|ard) que (?:prévu|nécessaire) <<- ~>> *
-__[i](p_une_qqch)__             une (?:à une|autre fois|bonne fois pour toutes|dernière fois|fois(?: pour toutes| de plus| n’est pas coutume)) <<- ~>> *
-__[i](p_une_fois)__             une fois <<- ~>> _
-__[i](p_urbi_et_orbi)__         urbi et orbi <<- ~>> *
-__[i](p_v_divers)__             v(?:aille que vaille|entre à terre|ers nulle part) <<- ~>> *
-
-TEST: ils vont et viennent, toujours {{cotes a cotes}}…
-TEST: Nous irons {{tours à tours}} chercher du bois.
-TEST: Ma thèse en 180 secondes.
-
-
-# je / tu / il / elles / nous / vous / ils / elles 
-__[i](p_je_vous_en_prie)__      je (?:t’en|vous en) (?:prie|supplie) <<- ~>> *
-__[i](p_nous_vous_en_prions)__  nous (?:t’en|vous en) (?:prions|supplions) <<- ~>> *
-
-# mot-là
-__[i](p_qqch_tiret_là)__        ({w1})(-là) @@0,$ <<- morphex(\1, ":[NAQ]", ":G") ~2>> *
-
-# Après
-__[i](p_adv_longtemps)__        (?:bien|si|assez) longtemps <<- ~>> *
-__[i](p_plus_loc_adv)__         plus (?:près|loin|tôt|tard|ou moins|que (?:nécessaire|jamais)|d’une fois) <<- ~>> *
-
-## Simplification partielle
-__[i](p_tout_au_long_de)__      (tout au long) d(?:es?|u) @@0 <<- not morph(word(-1), ":R", False, False) ~1>> au
-__[i](p_à_loc_de1)__            à (bonne distance|bord|cause|contre-courant|côté|court|défaut|droite|gauche|hauteur|l’(?:aff[ûu]t|arrière|autre bout|aune|avant|écart|égard|extérieur|encontre|ins(?:u|tar)|intérieur|opposé|orée|approche)|la (?:hauteur|portée|suite)|partir|portée|pro(?:ximité|pos)|quelques (?:mètres|kilomètres|lieues|pas|centaines de mètres|minutes|heures)|rebours) d(?:es?|u) @@2 <<- ~1>> *
-__[i](p_à_loc_de2)__            à (base|force|grand(?: renfort|s coups)|raison) de? @@2 <<- ~1>> *
-__[i](p_au_loc_de)__            au (bout|beau milieu|courant|cours|détriment|fin fond|grand dam|fur et à mesure|gré|l(?:ieu|ong|arge)|milieu|nez et à la barbe|plus profond|profit|s(?:ein|ortir|ujet)|vu(?: et au su|)) d(?:es?|u) @@3 <<- ~1>> *
-__[i](p_aux_loc_de)__           aux (abords|dépens) d(?:es?|u) @@4 <<- ~1>> *
-__[i](p_ceux_et_celles_qui)__   ceux (et celles?) +qui @@5 <<- ~1>> *
-__[i](p_compte_tenu_de)__       (compte tenu) d(?:es?|u) @@0 <<- ~1>> avec
-__[i](p_de_mes_yeux_vu)__       (de (?:[mts]es|[nv]os|leurs) yeux) vue?s? @@0 <<-  ~1>> *
-__[i](p_en_loc_de1)__           en (arrière|attente|amont|aval|cas|cours|dehors|dépit|direction|faveur|guise|l’(?:absence|honneur)|lieu et place|plein milieu|présence|raison|sus|termes|vertu) d(?:es?|u) @@3 <<- ~1>> *
-__[i](p_en_loc_de2)__           en (flagrant délit|matière) de? @@3 <<- ~1>> *
-__[i](p_en_proie_à)__           (en proie) à @@0 <<- ~1>> *
-__[i](p_eu_égard_à)__           (eu égard) (?:à|aux?) @@0 <<- ~1>> *
-__[i](p_la_une_de)__            la (une) d(?:es?|u) @@3 <<- ~1>> _
-__[i](p_le_long_de)__           le (long) d(?:es?|u) @@3 <<- ~1>> _
-__[i](p_par_le_biais_de)__      par (le biais|l’entremise) d(?:es?|u) @@4 <<- ~1>> * 
-__[i](p_pour_ou_contre)__       pour (ou contre) @@5 <<- ~1>> *
-__[i](p_rien_comparé_à)__       rien +(comparé) +à @@w <<- ~1>> *
-__[i](p_suite_à)__              (suite) (?:à|aux?) @@0 <<- not before(r"(?i)\b(?:une|la|cette|[mts]a|[nv]otre|de) +") ~1>> *
-__[i](p_vent_debout_contre)__   (vent debout) contre @@0 <<- ~1>> *
-
-# Déterminant + nombre
-__[i](p_dét_plur_nombre_nom)__
-    (?:[dmts]es|nos|vos|le(?:ur|)s) (\d+(?: ou \d+|)) ({w_2})  @@w,$
-    <<- morphex(\2, ":[NA].*:[pi]", ":(?:V0|3p)|>(?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor)")
-    ~1>> *
-
-## Simplifications des substantifs
-__[i](loc_arc_à_poulies)__
-    arcs? (([àa]) poulies) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_armée_de)__                     armées? (de (?:l’air|terre)) @@$ <<- ~1>> *
-__[i](p_armé_jusqu_aux_dents_)__        armée?s? (jusqu aux dents) @@$ <<- ~1>> *
-__[i](loc_armes_à_feu)__
-    armes? (([àa]) feu) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_armes_de_qqch)__                armes? (de (?:poing|guerre|destruction massive)) @@$ <<- ~1>> *
-__[i](p_attestation_sur_l_honneur)__    (?:attestation|déclaration)s? (sur l’honneur) @@$ <<- ~1>> *
-__[i](p_attendre_de_pied_ferme)__       attend\w* (de pied ferme) @@$ <<- ~1>> *
-__[i](p_ayants_droit)__                 ayants (droit) @@$ <<- ~1>> *
-__[i](p_boite_aux_lettres)__            bo[îi]tes? (aux lettres|à gants) @@$ <<- ~1>> *
-__[u](p_bisphenol_A)__                  bisph[ée]nols? (A) @@$ <<- ~1>> *
-__[i](p_blanc_comme)__                  blanc(?:he|)s? (comme neige|comme de la craie) @@$ <<- ~1>> *
-__[i](loc_bombe)__
-    bombes? (([àa]) (?:eau|fragmentation|retardement)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_canne_à)__
-    (cann?es?) (([àa]) (?:pêche|sucre)s?) @@0,$,w
-    <<- \1.find("ane") != -1 -1>> =\1.replace("ane", "anne")    # Confusion : la cane est la femelle du canard.|https://fr.wiktionary.org/wiki/canne
-    <<- \3 == "a" -3>> à                                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~2>> *
-__[i](loc_caisse_à_outils)__
-    caisses? (([àa]) outils?) @@$,w
-    <<- \2 == "a" -2>> à                                # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_chair_à)__
-    chairs? (([àa]) (?:pâté|canons?)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_chambre_de)__                   chambres? (d’(?:agriculture|hôtes?)|de (?:commerce|compensation|décompression|dégrisement)) @@$ <<- ~1>> *
-__[i](p_chemin_de_traverse)__           chemins? (de traverse) @@$ <<- ~1>> *
-__[i](p_chili_con_carne)__              chilis? (con carne) @@$ <<- ~1>> *
-__[i](p_chef_d_œuvre)__                 chefs?(-d’œuvre) @@$ <<- ~1>> *
-__[i](p_clair_comme)__                  claire?s? (comme (?:de l’eau de (?:boudin|roche|source)|du (?:cristal|jus de (?:boudin|chaussettes?|chique)))) @@$ <<- ~1>> *
-__[i](p_commis_d_office)__              commise?s? (d’office) @@$ <<- ~1>> *
-__[i](p_convention)__                   conventions? (récepteur|générateur) @@$ <<- ~1>> *
-__[i](p_con_comme)__                    con(?:ne|)s? (comme (?:un balai|une valise sans poignées?|la lune)) @@$ <<- ~1>> *
-__[i](p_coup_de)__
-    coups? (de (?:balai|bol|cœur|foudre|fil|grâce|jarnac|théâtre|coude|genou|main|p(?:atte|ied|oing|oker|ouce)|tête)|d’(?:avance|éclat|État|œil|épaule)|du sort) @@$
-    <<- ~1>> *
-__[i](p_course_contre_la_montre)__      courses? (contre la montre) @@$ <<- ~1>> *
-__[i](p_cousu_main)__                   cousue?s? +(main) @@$ <<- ~1>> *
-__[i](p_cout_de_revient)__              (?:co[uû]t|prix) (de revient) @@$ <<- ~1>> *
-__[i](loc_crayon_à_qqch)__
-    crayons? (([àa]) (?:lèvres|sourcils)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_cuillère)__
-    cuillères? +(([àa]) (?:café|soupe)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_délai_de)__                     délais? (d’attente|de (?:carence|connexion|prescription|préavis|rétraction|rigueur)) @@$ <<- ~1>> *
-__[i](p_demande_d_asile)__              demandes? (d’asile) @@$ <<- ~1>> *
-__[i](p_descente_aux)__                 descentes? (aux (?:enfers|flambeaux)) @@$ <<- ~1>> *
-__[i](p_diner_aux_chandelles)__         d[îi]ners? (aux chandelles) @@$ <<- ~1>> *
-__[i](p_digne_de)__                     dignes? (de (?:confiance|foi|ce nom)) @@$ <<- ~1>> *
-__[i](p_droit)__                        (droit) (?:au but|dans les yeux) @@0 <<- ~1>> *
-__[i](p_droit_comme_un_i)__             droite?s? (comme un i) @@$ <<- ~1>> *
-__[i](p_eau_de)__                       eaux? (de (?:bouleau|bleuet|chaux|coco|javel|jouvence|mer|noix de coco|parfum|pluie|seltz|source|vie)) @@$ <<- ~1>> *
-__[i](p_espérance_de_vie)__             espérances? (de vie) @@$ <<- ~1>> *
-__[i](p_état_de)__                      états? (d’(?:âme|e(?:sprit|xtrême urgence)|urgence)|de (?:conservation|fait|l’art)) @@$ <<- ~1>> *
-__[i](p_expérience_utilisateur)__       expériences? +(utilisateurs?) @@$ <<- ~1>> *
-__[i](loc_fard_à_paupières)__
-    fards? (([àa]) paupières) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_fille_au_pair)__                filles? (au pair|à soldats?) @@$ <<- ~1>> *
-__[i](loc_fils_fille_à)__
-    fil(?:les?|s) (([àa]) (?:papa|maman)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[s](p_femme_de)__                     [fF]emmes? (de (?:chambre|lettres|loi|ménage)|d’(?:âge mûr|affaires|exception|É(?:tat|glise)|honneur)) @@$ <<- ~1>> *
-__[s](p_homme_de)__                     [hH]ommes? (de (?:lettres|loi|main|paille)|d’(?:âge mûr|affaires|armes|exception|É(?:tat|glise)|honneur)) @@$ <<- ~1>> *
-__[i](p_haut_comme_3_pommes)__          haute?s? (comme (?:trois|3) pommes) @@$  <<- ~1>> *
-__[i](p_hôtel_de_ville)__               hôtels? (de ville) @@$ <<- ~1>> *
-__[i](loc_gaz_à_effet_de_serre)__
-    gaz (([àa]) effet de serre)  @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_garde)__                        gardes? (à vue|du corps) @@$ <<- ~1>> *
-__[i](p_infirmier_de_garde)__           (?:infirmières?|médecins?) (de garde) @@$ <<- ~1>> *
-__[i](p_impression_que)__               (l(?:a (?:nette|bizarre) +|’étrange +|’)impression) +que? @@0 <<- ~1>> *
-__[i](p_pressentiment_que)__            (le (?:pres|)sentiment) +que? @@0 <<- ~1>> *
-__[i](p_invité)__                       invitée?s? (d’honneur|surprise) @@$ <<- ~1>> *
-__[i](p_journal_de_bord)__              journa(?:l|ux) (de bord) @@$ <<- ~1>> *
-__[i](loc_lime_à_ongles)__
-    limes? (([àa]) ongles?) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_liste_d_attente)__              listes? (d’attente) @@$ <<- ~1>> *
-__[i](loc_machine_à_qqch)__
-    machines? (([àa]) (?:café|coudre|laver|remonter le temps)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_main_d_œuvre)__                 mains? (d’œuvre) @@$ <<- ~1>> *
-__[i](p_maison_de)__                    maisons? (de (?:passe|retraite)) @@$ <<- ~1>> *
-__[i](p_mal_de)__                       ma(?:l|ux) (de (?:tête|ventre|mer)) @@$ <<- ~1>> *
-__[i](p_marché_aux_puces)__             marchés? (aux puces) @@$ <<- ~1>> *
-__[i](p_maréchal_des_logis)__           maréchale?s? (des logis(?:[ -]chef|)) @@$ <<- ~1>> *
-__[i](p_marge_de_manœuvre)__            marges? (de manœuvres?) @@$ <<- ~1>> *
-__[i](p_mère_au_foyer)__                mères? (au foyer) @@$ <<- ~1>> *
-__[i](p_metteur_en_scène)__             metteu(?:r|se)s? (en scène) @@$ <<- ~1>> *
-__[i](p_mineur_de_moins_de_x_ans)__     mineure?s? (de moins de ({w1}) ans) @@$,>1:w <<- \2.isdigit() or morph(\2, ":B", False) ~1>> *
-__[i](p_miroir_aux_alouettes)__         miroirs? (aux alouettes) @@$ <<- ~1>> *
-__[i](p_monnaie)__                      monnaies? (d’échange|de réserve) @@$  <<- ~1>> *
-__[i](p_mode_de)__                      modes? (de (?:paiement|scrutin|vie)) @@$ <<- ~1>> *
-__[i](loc_moule_à_qqch)__
-    moules? (([àa]) (?:gaufres?|gâteaux?|brioche|manqué|savarin|charlotte)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_mot_de_passe)__                 mots? (de passe) @@$ <<- ~1>> *
-__[i](p_moteur_essence_diesel)__        moteurs? (essence|di[eé]sel)s? @@$ <<- ~1>> *
-__[i](p_motion_de)__                    motions? (de (?:blâme|censure|défiance)) @@$ <<- ~1>> *
-__[i](p_noix_de)__                      noix (de (?:cajou|p[ée]can|coco|lavage|muscade|veau|macadamia)) @@$ <<- ~1>> *
-__[i](p_nu_comme_un_ver)__              nue?s? (comme (?:un ver|des vers)) @@$ <<- ~1>> *
-__[i](p_numéro)__
-    numéro (un|deux|trois|quatre|cinq|six|sept|huit|neuf|dix(?:-sept|-huit|-neuf|)|onze|douze|treize|quatorze|quinze|seize|vingt|trente|quarante|cinquante|soixante(?:-dix|)|quatre-vingt(?:-dix|)|cent|mille|\d+) @@$
-    <<- before(r"\b[lL]a +$") =>> define(\0, [">numéro :N:f:s"])
-    <<- ~1>> *
-__[i](p_oiseau_de)__                    oiseaux? (de (?:malheur|nuit|proie|mauvais augure)) @@$ <<- ~1>> * 
-__[i](p_onde_de_choc)__                 ondes? (de choc) @@$ <<- ~1>> *
-__[i](p_orge)__                         orge (perlé|mondé|carré) @@$ <<- ~1>> *
-__[i](p_noire_comme)__                  noire?s? (comme (?:la nuit|une nuit sans lune)) @@$ <<- ~1>> *
-__[i](p_partie_de_jambe_en_l_air)__     parties? (de jambes en l’air) @@$ <<- ~1>> *
-
-__[i](p_pièce_de)__                     pièces? (de (?:théâtre|monnaie|\d+ (?:euros?|centimes?|cents?|livres? sterling|shillings?))) @@$ <<- ~1>> *
-__[i](p_pomme_de)__                     pommes? (de (?:discorde|terre|reinette|pin)|d’(?:Adam|api|amour|ambre|eau|or))  @@$  <<- ~1>> *
-__[i](p_porte_de)__                     portes? (de (?:service|garage)) @@$ <<- ~1>> *
-__[i](p_poudre_aux_yeux)__              poudres? (aux yeux) @@$ <<- ~1>> *
-__[i](p_preuve_du_contraire)__          preuves? +(?:suffisantes? +|)(du contraire) @@$ <<- ~1>> *
-__[i](p_quelqu_un_d_autre)__            quelqu un (d’autre) @@$ <<- ~1>> *
-__[i](p_réglé_comme)__                  réglée?s? (comme du papier à musique) @@$  <<- ~1>> *
-__[i](p_papier_à)__
-    papiers? (([àa]) (?:lettres?|musique)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_remire_à_plat)__
-    remise?s? (([àa]) plat) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_requête)__                      requêtes? (en (?:nullité|non (?:conciliation|inscription|lieu|révocation de sursis))) @@$ <<- ~1>> *
-__[i](p_roues_avant_arrière)__          roues? (avant|arrière) @@$ <<- ~1>> *
-__[i](p_roulement_à_billes)__           roulements? (à billes) @@$ <<- ~1>> *
-__[i](loc_rouge_à_lèvres)__
-    rouges? (([àa]) lèvres) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_sac_à_qqch)__
-    sacs? (([àa]) (?:dos|main|langer|merde|foutre)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_sac_de_qqch)__                  sacs? (de (?:couchage|sport|voyage)) @@$ <<- ~1>> *
-__[i](p_salle)__                        salles? (à manger|d’attente|de (?:bains?|conférence)) @@$ <<- ~1>> *
-__[i](p_sain_de_corps)__                saine?s? (d(?:e corps et d|)’esprit) @@$ <<- ~1>> *
-__[i](p_sclérose_en_plaques)__          scléroses? (en plaques) @@$  <<- ~1>> *
-__[i](p_secret_défense)__ 				secrets? (défense) @@$ <<- ~1>> *
-__[i](loc_silo)__
-    silos? (([àa]) (?:grains?|blé)) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_soue_à_cochons)__
-    soues? (([àa]) cochons?) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[u](p_système)__                      systèmes? (d’exploitation|D) @@$ <<- ~1>> *
-__[i](p_taille)__                       taille (\d+) @@$ <<- ~1>> *
-__[i](p_talons_aiguilles)__             talons? (aiguilles?) @@$ <<- ~1>> *
-__[i](p_taux_de_qqch)__                 taux (d’(?:abstention|absorption|alcool|alphabétisation|endettement|inflation|intérêt|imposition|occupation|ouverture|œstrogène|urée|usure)|de (?:change|cholest[ée]rol|glycémie|fécondité|participation|testostérone|TVA)) @@$ <<- ~1>> *
-__[i](p_tête_de_déterré)__              têtes? (de déterrée?s?) @@$ <<- ~1>> *
-__[i](p_tout_un_chacun)__               (tout un) chacun @@0 <<- ~1>> *
-__[i](p_tour_de_passe_passe)__          tours? (de passe-passe) @@$ <<- ~1>> *
-__[i](p_trou_à_rat)__
-    trous? (([àa]) rats?) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_tueur_à_gages)__
-    tueu(?:r|se)s? (([àa]) gages) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_vache_à_lait)__
-    vaches? (([àa]) lait) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](p_vecteur)__                      vecteurs? (accélérations?|positions?|rotations?|vitesses?) @@$ <<- ~1>> *
-__[i](loc_vente_à_domicile)__
-    ventes? (([àa]) domicile) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_vernis_à_ongles)__
-    vernis (([àa]) ongles) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_vol_à)__
-    vols? (([àa]) l(?:’étalage|a (?:sauvette|tire))) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
-__[i](loc_voie_de_recours)__
-    (voi[ex]s?) (de (?:recours|perdition)) @@0,$
-    <<- \1.endswith("x") -1>> voie|voies        # Confusion probable.|https://fr.wiktionary.org/wiki/voie
-    <<- ~2>> *
-__[i](loc_usine_à_gaz)__
-    usines? (([àa]) gaz) @@$,w
-    <<- \2 == "a" -2>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
-    <<- ~1>> *
+TEST: les méthodes de l’à-peu-près ne suffisent pas.
+
+
+## substantifs
+__conf_à_substantifs__
+    >arc a >poulie
+    >arme a >feu
+    >bombe a [eau|fragmentation|retardement]
+    [>canne|>cane] a [>pêche|>sucre]
+    >caisse a >outil
+    >chair a [pâté|>canon]
+    >crayon a [lèvres|sourcils]
+    >cuillère a [café|soupe]
+    >fard a paupières
+    [>fille|fils] a [papa|maman]
+    >gaz a effet de serre
+    >lime a >ongle
+    >machine a [café|coudre|laver]
+    >machine a >remonter le temps
+    >moule a [>gaufre|>gâteau|brioche|manqué|savarin|charlotte]
+    >papier a [>lettre|musique]
+    >punk a >chienne
+    >rouge a >lèvre
+    >sac a [dos|main|langer|merde|foutre]
+    >silo a [>grain|blé]
+    >soue a >cochonne
+    >trou a >rat
+    >tueuse a gages
+    >vache a lait
+    >vente a domicile
+    >vernis a ongles
+    >vol a [la|l’] [étalage|sauvette|tire]
+    >usine a gaz
+        <<- /conf/ -2>> à                   # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
 
 TEST: C’est un arc {{a}} poulies
 TEST: Ceci est une arme {{a}} feu.
 TEST: Combien de bombes {{a}} fragmentation
 TEST: C’est une nouvelle caisse {{a}} outils
@@ -5406,169 +4048,3831 @@
 TEST: Ce n’est que du vernis {{a}} ongles.
 TEST: le vol {{a}} l’étalage est un fléau.
 TEST: Il nous faut une {{voix}} de recours.
 TEST: c’est une putain d’usine {{a}} gaz.
 TEST: ce produit est notre vache {{a}} lait
-TEST: un champ de canne à sucre
-TEST: La batterie se recharge automatiquement grâce au moteur essence.
-TEST: c’est un moteur diésel.
-TEST: cette descente aux enfers interminable.
-TEST: c’est une vache à lait
-TEST: Ses talons aiguille étaient à la denière mode.
-
-
-# simplification des nombres
-__<i](p_10_qqch)__
-    dix-(?:sept|huit|neuf) <<- ~>> dix
-__[i](p_20_30_40_50_qqch)__
-    (?:vingt|trente|quarante|cinquante)(-(?:deux|trois|quatre|cinq|six|sept|huit|neuf|et-un)| et un) @@$ <<- ~1>> *
-__[i](p_60_qqch)__
-    soixante-(?:d(?:eux|ix|ouze)|tr(?:ois|eize)|quat(?:re|orze)|cinq|six|sept|huit|neuf|quinze|seize| et (?:un|onze)|-et-(?:un|onze))
-    <<- ~>> soixante
-__[i](p_80_qqch)__
-    quatre-vingt-(?:un|d(?:eux|ix|ouze)|tr(?:ois|eize)|quat(?:re|orze)|cinq|six|sept|huit|neuf|onze|quinze|seize)
-    <<- ~>> quatre-vingts
-__[i](p_qqch_100)__
-    ((?:d(?:eux|ouze)|tr(?:ois|eize)|quat(?:re|orze)|cinq|s(?:ix|seize)|sept|huit|neuf|onze|quinze) cents) +({w_2})  @@0,$ 
-    <<- morphex(\2, ":[NAQ].*:[pi]", ":(?:G|3p)") ~1>> cent
-__[i](p_qqch_1000)__
-    (?:deux|trois|quatre|cinq|six|sept|huit|neuf|cent) (?:cent |)mille
-    <<- ~>> mille
-
-__[i](p_det_plur_nombre_nom)__
-    (?:le(?:ur|)s|des|ses|ces|mes|tes|nos|vos) +((?:quelque +|)(?:d(?:eux|ix|ouze)|tr(?:ois|eize|ente)|qua(?:t(?:re(?:-vingts|)|orze)|rante)|cinq(?:uante|)|s(?:ix|eize|oixante)|sept|huit|neuf|onze|quinze|vingt|cent|mille|\d+)) +({w_2})  @@w,$ 
-    <<- morphex(\2, ":[NAQ].*:[pi]", ":(?:G|3p)") ~1>> *
-
-__[i](p_une_heure)__
-    (?:à |d(?:e +|’))une +heure(?: (?:d(?:eu|i)x|tr(?:ois|eize|ente)|qu(?:a(?:t(?:re|orze)|rante)|inze)|cinq(?:uante|)|s(?:ix|ept|eize)|huit|neuf|onze|douze|vingt|décente|(?:très |)tardive)|) <<- ~>> *
-__[i](p_nombre_heure)__
-    (?:à|de) (?:d(?:eu|i)x|tr(?:ois|eize)|qu(?:at(?:re|orze)|inze)|cinq|s(?:ix|ept|eize)|huit|neuf|onze|douze|vingt) +heures(?: (?:d(?:eu|i)x|tr(?:ois|eize|ente)|qu(?:a(?:t(?:re|orze)|rante)|inze)|cinq(?:uante|)|s(?:ix|ept|eize)|huit|neuf|onze|douze|vingt)|) <<- ~>> *
-
-## Conditionnel
-__[i](p_à_xxx_pour_cent)__          à ({w_2}) pour cent @@2 <<- morph(\1, ":B", False) ~>> *
-__[i](p_au_moins)__                 (au moins) +({w_1}) @@0,$ <<- not morph(\2, ":[AQ].*:[me]:[si]", False) ~1>> *
-__[i](p_au_hasard)__                au hasard <<- isEndOfNG() ~>> *
-__[i](p_aussi_adv_que_possible)__   aussi ({w_2}) que (?:nécessaire|possible) @@6 <<- morph(\1, ":W", False) ~>> *
-__[i](p_au_sens_adj_du_terme)__     au sens (?:le (?:plus|moins) |)({w_2}) du terme @@w <<- morph(\1, ":A .*:m:s", False) ~>> *
-#__[i](p_aussi_xxx_que_ce_soit)__   aussi ({w_2}) que ce soit
-__[i](p_nombre_de)__                (nombre) des? @@0 <<- morph(word(-1), ":(?:R|C[sc])", False, True) ~1>> *
-__[i](p_à_xxx_reprises)__           à ({w_2}) reprises @@2 <<- morph(\1, ":B", False) or re.search("(?i)^(?:plusieurs|maintes)", \1) ~>> *
-__[i](p_bien_entendu)__             bien entendu <<- morph(word(1), ":[NAQR]|>que? ", False, True) ~>> *
-__[i](p_comme_pronom)__
-    ({w_2}) (comme (?:eux|elles?|lui|ça|celui-(?:ci|là)|celles?-(?:ci|là)|ceux(?:ci|là)|l[ea] [nv]ôtre|le [mts]ien|la [mts]ienne|les (?:[nv]ôtres|sien(?:ne|)s))) @@0,$
-    <<- morphex(\1, ":[NAQ]", ":V0") ~2>> *
-__[i](p_pêle_mêle)__                ({w_2}) (pêle-mêle) @@0,$ <<- not morph(\1, ":D", False) ~2>> *
-__[i](p_droit_devant)__             ({w_2}) (droit) devant @@0,w <<- not morph(\1, ":D.*:[me]:[si]", False) ~2>> *
-__[i](p_dans_xxx_cas)__
-    dans (?:la (?:(?:grande |)majorité|plupart) des|de (?:tr[èo][sp] |)nombreux|maints) cas
-    <<- not morph(word(1), ":([AQ].*:[me]:[pi])", False, False) ~>> *
-__[i](p_du_coup)__
-    (du coup) ({w_1}) @@0,$
-    <<- not morph(\2, ":A", False) ~1>> *
-__[i](p_verbe_pronom_être)__
-    (d[eouû]\w+|cr[ouû]\w+|pens\w+|imagin\w+|estim\w+) (l(?:eur|ui)|nous|vous) être @@0,w
-    <<- morph(\1, ">(?:croire|devoir|estimer|imaginer|penser) ") ~2>> *
-__[i](p_en_partie)__
-    (en partie) ({w_2}) @@0,$
-    <<- morph(\1, ":(?:R|D|[123]s|X)", False) ~1>> *
-__[i](p_en_plus)__
+TEST: ils vont et viennent, toujours {{cotes a cotes}}…
+TEST: Nous irons {{tours à tours}} chercher du bois.
+
+
+__conf_mettre_a_profit_plat__
+    [>mettre|>remettre] ?[ceci|cela|ça|tout]¿ (a) [plat|profit]
+    [>mettre|>remettre] tout [ceci|cela|ça] (a) [plat|profit]
+    [>mettre|>remettre] [mon|ton|son|notre|votre|leur] talent (a) [plat|profit]
+    [>mettre|>remettre] [ma|ta|sa|notre|votre|leur] compétence (a) [plat|profit]
+    [>mettre|>remettre] [mes|tes|ses|nos|vos|leurs] [talents|compétences] (a) [plat|profit]
+        <<- /conf/ -1>> à                   # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
+
+TEST: Mettre {{a}} profit ses compétences
+TEST: remettre ceci {{a}} profit
+TEST: mettre tout {{a}} plat
+TEST: Il a mis son talent {{a}} profit.
+TEST: Remettre ses compétences {{a}} profit.
+
+
+__conf_mener_a_bien__
+    >mener a bien
+        <<- /conf/ morph(<1, ">(?:falloir|aller|pouvoir)/", ">que?/")
+        -2>> à                              # Confusion probable. Dans cette locution, utilisez la préposition « à ».|https://fr.wiktionary.org/wiki/mener_%C3%A0_bien
+
+    >mener a bien cette [tâche|entreprise|action|étude|construction|recherche|guerre|conquête]
+    >mener a bien ce [projet|travail]
+    >mener a bien ces [travaux|projets|tâches|entreprises|actions|études|constructions|recherches|guerres|conquêtes]
+        <<- /conf/ -2>> à                   # Confusion probable. Dans cette locution, utilisez la préposition « à ».|https://fr.wiktionary.org/wiki/mener_%C3%A0_bien
+
+TEST: Mener {{a}} bien cette guerre sera plus difficile qu’on le pense.
+TEST: Je peux mener {{a}} bien cette opération.
+TEST: Cette coalition que tu penses mener a bien l’intention de te trahir.
+
+
+__conf_à_a_après_verbes__
+    @:V¬:[YGNAWM]  a
+        <<- not tag_before(\1, "ce_que")
+        -2>> à                                  # Confusion probable : “a” est la conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.|http://fr.wiktionary.org/wiki/%C3%A0
+
+    ~\w-(?:je|tu|ils?|elles?|on|vous|nous)$  a
+        <<- -2>> à                              # Confusion : “a” est la conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.|http://fr.wiktionary.org/wiki/%C3%A0
+
+TEST: Vient-on {{a}} la maison demain ?
+TEST: Arrivait-elle {{a}} le manger ?
+
+
+__conf_celui_celle_à_qui__
+    [celui|celle|ceux|celles]  a  qui
+        <<- /conf/ -2>> à                   # Confusion. Utilisez la préposition “à”.|http://fr.wiktionary.org/wiki/%C3%A0
+
+TEST: Ceux {{a}} qui nous avons notifié le problème sont partis.
+TEST: Il y a qui au dîner ce soir ?
+
+
+# m’a tuer
+__conf_m_a_tuer__
+    m’ a tuer
+        <<- /conf/ -3>> tué|tuée
+        # Cliché. Évitez cette erreur de grammaire délibérée, faite d’innombrables fois, pour mimer l’affaire Omar Raddad.|https://fr.wikipedia.org/wiki/Omar_m'a_tuer
+
+TEST: la réalité m’a {{tuer}}
+
+
+# après avoir
+__conf_après_avoir__
+    [à|a] [>prêt|>pré|près] [a|à] [voire|voir]
+    [à|a] [>prêt|>pré|près] [a|à] [voire|voir]
+    [à|a] [>prêt|>pré|près] avoir
+    après [a|à] [voire|voir]
+        <<- /conf/ ->> après avoir          # Confusion générale.
+
+TEST: {{a pré a voire}} monté les marches
+TEST: après avoir réussi son examen
+
+
+# aux dépens
+__conf_aux_dépens__
+    au [dépend|dépends|dépens]
+    aux [dépend|dépends]
+        <<- /conf/ ->> aux dépens           # Locution prépositive : « aux dépens de ».|https://fr.wiktionary.org/wiki/aux_d%C3%A9pens_de
+
+TEST: Ce sont des clichés {{au dépend}} d’un grand chef. Tout ça pour faire du buzz et exister médiatiquement.
+
+
+# au temps / autant
+__conf_au_temps_pour_moi__
+    [<start>|,]  au  [tant|tan]  pour moi
+    [<start>|,]  aux [tant|tans]  pour moi
+        <<- /conf/ -2:3>> au temps                      # Pour reconnaître son erreur, « au temps pour moi » est l’expression recommandée par l’Académie française.
+
+    [<start>|,]  [autant|autan|autans]  pour moi
+        <<- /conf/ -2>> au temps                        # Pour reconnaître son erreur, « au temps pour moi » est l’expression recommandée par l’Académie française.
+
+TEST: Je me suis trompé. {{Autant}} pour moi.
+TEST: Je me suis trompé. {{Au tan}} pour moi.
+
+
+__conf_autant_que_faire_se_peut!7__
+    [au|aux] [temps|tant|>tan] que [faire|ferre|>fer] [se|ce] [peu|peut|peux]
+    >autan que [faire|ferre|>fer] [se|ce] [peu|peut|peux]
+    autant que [ferre|>fer] [se|ce] [peu|peut|peux]
+    autant que [faire|ferre|>fer] ce [peu|peut|peux]
+    autant que [faire|ferre|>fer] [se|ce] [peu|peux]
+        <<- /conf/ ->> autant que faire se peut         # Locution adverbiale : « autant que faire se peut ».|https://fr.wiktionary.org/wiki/autant_que_faire_se_peut
+
+TEST: on va y arriver, {{au temps que faire se peut}}…
+
+
+# ça / çà / sa
+__conf_ça_çà_sa__
+    ça  @:[NAQ].*:f¬:(?:G|P|[123][sp])|>seule?s?/
+        <<- /conf/ -1>> sa                              # Confusion : “sa” (sa maison, sa passion) ≠ “ça” (ça vient, ça heurte).
+
+    sa  @:G¬>(?:tr(?:ès|op)|peu|bien|plus|moins|toute|presque)/|:[NAQ].*:f
+        <<- /conf/ -1>> ça                              # Confusion : “sa” (sa maison, sa passion) ≠ “ça” (ça vient, ça heurte).
+
+    sa [n’|m’|t’|s’|j’|l’|d’|qu’|lorsqu’|puisqu’|quoiqu’]
+        <<- /conf/ -1>> ça                              # Confusion : “sa” (sa maison, sa passion) ≠ “ça” (ça vient, ça heurte).
+
+    çà
+        <<- /conf/ not before(r"\b(?:[oO]h|[aA]h) +$") and not after("^ +et là")
+        ->> ça                                          # Confusion : « çà » ne s’emploie plus guère que dans l’expression « çà et là ».
+
+    ça et là
+        <<- /conf/ not morph(<1, ":R") ->> çà et là     # Confusion : « ça » équivaut à « cela ». Dans l’expression « çà et là », « çà » équivaut à « ici ».
+
+    sa  <end>
+        <<- /conf/ -1>> ça                              # Confusion probable : “sa” est un déterminant féminin singulier. Pour l’équivalent de “cela” ou “ceci”, écrivez :
+
+TEST: Je prends {{sa}}…
+TEST: {{ça}} patrie, il la détestait
+TEST: et {{sa}} par deux fois
+TEST: Il trouva de la nourriture {{ça et là}}.                                ->> çà et là
+TEST: Elle parle comme {{ça}} mère.                                           ->> sa
+TEST: C’est comme {{sa}}.
+TEST: {{sa}} l’ennuierait, ce fils de pute, de dire bonjour ?
+TEST: il faut s’y prendre comme {{sa}}
+TEST: on fait {{sa}} lorsqu’on a tout perdu
+TEST: avec sa presque belle-mère
+TEST: sa toute nouvelle application de synchronisation de fichiers
+
+
+__conf_canne_cane__
+    >cane [a|à] [>pêche|>sucre]
+        <<- /conf/ -1>> =\1.replace("ane", "anne")      # Confusion : la cane est la femelle du canard.|https://fr.wiktionary.org/wiki/canne
+
+TEST: Voici ma {{cane}} à pêche.
+
+
+# ce / se / ceux
+__conf_ce_ceux_se!6__
+    ce  @:V[123].*:(?:Y|[123][sp])¬:[NAGM]|>(?:devoir|pouvoir|sembler)/
+        <<- /conf/ not \1.isupper() and \2.islower() and not value(\2, "|faire|")
+        -1>> se                                         # Confusion : « \2 » est un verbe. Exemples : ce bâtiment, se perdre.
+
+    ce  ~\w-(?:ils?|elles?|on)$
+        <<- /conf/ not \1.isupper() and \2.islower()
+        -1>> se                                         # Confusion : « \2 » est un verbe. Exemples : ce bâtiment, se perdre.
+
+    pour se faire ,
+    pour se faire @:G¬:[AYD]
+        <<- /conf/ -2>> ce                              # Confusion probable. Dans cette locution, il faut employer “ce”.|http://fr.wiktionary.org/wiki/pour_ce_faire
+
+    ne ce
+        <<- /conf/ -2>> se                              # Confusion. Ce chien, ce chat… Se demander, se croire…
+
+    ne [c’|ç’]
+        <<- /conf/ -2>> s’                              # Confusion. Ce chien, ce chat… Se demander, se croire…
+
+    se [que|qu’|qu|qui|dont|malgré|pourquoi|avec|pour|par]
+        <<- /conf/ -1>> ce                              # Confusion. Exemples : ce bâtiment, se perdre.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440
+
+    qui  ce  @:V¬:[NAQ].*:[me]
+        <<- /conf/ -2>> se                              # Confusion probable. Exemples : ce bâtiment, se perdre.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440
+
+    ceux  ?[ne|n’]¿  @:V0.*:[123][sp]¬:P|>a/
+        <<- /conf/ -1>> ce                              # Confusion.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829
+
+    se [ne|n’] [>être|>pouvoir|>devoir]
+        <<- /conf/ not \1.isupper() -1>> ce             # Confusion probable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=2440
+
+    se  @:[NAQ]¬:([123][sp]|Y|P|Q)|>l[ea]?/
+        <<- /conf/ not \1.isupper() -1>> ce             # Confusion. Ce chien, ce chat… Se demander, se croire…
+
+    ceux  ne  @:[123]s¬:P
+        <<- /conf/ -1>> ce                              # Confusion.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829
+
+    ceux  @:N.*:s¬:(?:A.*:[pi]|P|R|G)|>(?:autour|a)/
+        <<- /conf/ -1>> ce                              # Confusion probable.|http://www.intellego.fr/soutien-scolaire-6eme/aide-scolaire-francais/ce-ceux-ou-se/3829
+
+TEST: il ne {{ce}} compte pas parmi eux
+TEST: il ne {{ç’}}avançait jamais sans avoir pesé toutes les conséquences
+TEST: {{Se}} seraient des histoires.
+TEST: {{se}} seraient des jours heureux.
+TEST: {{Se}} sont de grands enfants.
+TEST: {{Se}} sera une fille.
+TEST: {{ceux}} seraient des jours heureux
+TEST: Pour {{se}} faire, ils sont prêts à tout.
+TEST: {{se}} ne peut être ainsi.
+TEST: C’est tout {{se}} qu’il y a
+TEST: Tout {{se}} que je fais
+TEST: tout {{se}} qu’il entend
+TEST: {{Ce}} {{promener}} est relaxant.
+TEST: Il {{ce}} {{sent}} seul
+TEST: {{se}} {{train}} est en retard
+TEST: {{ceux}} train arrive trop vite.
+TEST: {{ceux}} ne doit pas nous faire oublier ce désastre
+TEST: qui {{ce}} donne en spectacle.
+TEST: {{ce}} prennent-ils pour des experts ?
+TEST: les expatriés éloignés ou ceux habitant ici
+TEST: les photographies de ceux n’ayant pas dépassé sept sur vingt.
+TEST: Pensez-vous que ceux ne sachant même pas ce qu’est une VHS peuvent y trouver leur compte ?
+TEST: la réduction de ma liberté intellectuelle et celle de ceux autour de moi
+TEST: […] qui ne peut être si ardente qu’elle ne se doive, ce semble, éteindre par la moindre goutte de sang qui sorte de leurs plaies.
+TEST: à qui ce texte doit tant, à qui ce texte est dédié
+
+
+# ce à quoi
+__conf_ce_à_quoi_qui__
+    se [à|a] [quoi|koi]
+    ce a [quoi|koi]
+        <<- /conf/ ->> ce à quoi                                # Confusion.|https://fr.wiktionary.org/wiki/ce_%C3%A0_quoi
+
+TEST: c’est {{se a quoi}} il pensait qui le minait.
+
+
+# ces / ses / c’est
+__conf_ces_ses_c_est__
+    [ses|ces] [à|au-dessus|avec|au|aux|comme|envers|contre|derrière|devant|par|pour|sans|sur]  @:D
+    [ses|ces] [à|au-dessus|avec|au|aux|comme|envers|contre|derrière|devant|par|pour|sans|sur]  [que|qu’|qu]
+    [ses|ces] [à|au-dessus|avec|au|aux|comme|envers|contre|derrière|devant|par|pour|sans|sur]  [l’|d’]
+    [ses|ces] [à|au-dessus|avec|au|aux|comme|envers|contre|derrière|devant|par|pour|sans|sur]  {pronom_obj}
+    [ses|ces] @:D
+    [ses|ces] [que|qu’|qu]
+    [ses|ces] [l’|d’]
+    [ses|ces] {pronom_obj}
+    [ses|ces] @:[WX]¬:N:.*:[pi]  @:[RD]|>pire/
+        <<- /conf/ not \1.isupper() -1>> c’est                  # Confusion probable. Écrivez « c’est » pour dire « ceci est… ».
+
+    c’ est  @:N.*:p¬:(?:G|W|M|A.*:[si])
+        <<- /conf/ -1:2>> ces|ses                               # Confusion. Exemples : c’est facile ; ces chats (désignation) ; ses chats (possession)…
+
+TEST: {{ses}} au-dessus de ses forces.
+TEST: {{ces}} comme la peste
+TEST: car {{ses}} d’avance perdu
+TEST: {{ces}} qu’il y a tant de pertes
+TEST: {{ces}} jamais une bonne idée.
+TEST: {{c’est}} {{délires}} nous ennuient
+TEST: En 2015, c’est Paris et son agglomération qui…
+TEST: Ses pas de danse.
+
+
+# compte / comte / conte
+__conf_compte__
+    à bon [>conte|comte|comtes]
+        <<- /conf/ -3>> compte                                  # Confusion. Locution “à bon compte”.|https://fr.wiktionary.org/wiki/%C3%A0_bon_compte
+
+    à ce [conte-là|comte-là]
+        <<- /conf/ -3>> compte-là                               # Confusion probable. Locution “à ce compte-là”.|https://fr.wiktionary.org/wiki/%C3%A0_ce_compte-l%C3%A0
+
+    [comte|comtes|>conte] à [rebours|découvert|terme]
+    [comte|comtes|>conte] [>bancaire|rendu|rendus|joint|joints|courant|courants|>chèques]
+    [comte|comtes|>conte] des opérations
+        <<- /conf/ -1>> compte|comptes                          # Confusion probable. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez “compte”.
+
+    [<start>|,] comte tenu
+        <<- /conf/ -2>> compte                                  # Confusion probable. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez “compte”.
+
+    en [>fin|>faim] de [comte|comtes|>conte]
+        <<- /conf/ ->> en fin de compte                         # Confusion. Locution “en fin de compte”.|https://fr.wiktionary.org/wiki/en_fin_de_compte
+
+    en >ligne de [comte|comtes|>conte]
+        <<- /conf/ ->> en ligne de compte                       # Confusion. Locution “en ligne de compte”.|https://fr.wiktionary.org/wiki/en_ligne_de_compte
+
+    la cour des [contes|comtes]
+        <<- /conf/ -4>> comptes                                 # Confusion. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez “compte”.
+
+    loin du comte ~¬[A-ZÉÈ]
+    loin du conte
+        <<- /conf/ -3>> compte                                  # Confusion. Locution “loin du compte”.|https://fr.wiktionary.org/wiki/loin_du_compte
+
+    [>réglement|>règlement] de [>conte|comte|comtes]
+        <<- /conf/ -3>> comptes                                 # Confusion.|https://fr.wiktionary.org/wiki/r%C3%A8glement_de_comptes
+
+    >régler  [mon|ton|son|notre|votre|leur|leurs]  [comte|comtes|>conte]
+        <<- /conf/ -3>> compte      # Confusion. Un conte est un récit fictif, “comte” est un titre de noblesse. Pour un état chiffré, un calcul… écrivez “compte”.|https://fr.wiktionary.org/wiki/r%C3%A9gler_son_compte
+
+    tout [comte|conte] fait
+        <<- /conf/ -2>> compte                                  # Confusion. Locution “tout compte fait”.|https://fr.wiktionary.org/wiki/tout_compte_fait
+
+TEST: il s’en est tiré à bon {{conte}}.
+TEST: à ce {{conte-là}}, il ne va pas faire long feu.
+TEST: mon {{comte}} bancaire est encore à sec.
+TEST: {{comte}} tenu du dysfonctionnement du moteur
+TEST: mais {{en fin de comte}}, ce n’était qu’une arnaque de plus.
+TEST: Rien de tout ceci n’entre {{en ligne de conte}}.
+TEST: la cour des {{contes}} publie un nouveau rapport.
+TEST: Ils sont encore tous deux loin du {{conte}}.
+TEST: Elle a l’impression d’être laissée pour {{comte}}.
+TEST: C’est un règlement de {{comte}} entre voyous.
+TEST: on va lui régler son {{conte}}, à cet enculé.
+TEST: tout {{conte}} fait, ça reste un salopard.
+
+
+__conf_conte_de_fée__
+    [comte|comtes|>compte] de bonnes femmes
+    [comte|comtes|>compte] de >fée
+    [comte|comtes|>compte] [>allégorique|>fantastique|>littéraire|merveilleux|moral|moraux|oral|oraux|>populaire|>satirique|>traditionnelle]
+    [comte|comtes|>compte] et >légende
+        <<- /conf/ -1>> conte|contes                                                # Confusion probable. Si vous parlez d’un récit, écrivez :|https://fr.wiktionary.org/wiki/conte
+
+TEST: Encore un {{comte}} de fée, assez de ces fadaises !
+TEST: c’est un {{compte}} allégorique.
+TEST: {{Comptes}} et légendes des Terres du Milieu.
+TEST: ce sont des {{comptes}} de bonnes femmes
+TEST: Elle parla au comte d’amour, mais il fit mine de n’y rien entendre.
+
+
+# dans / d’en
+__conf_dans_dan_d_en__
+    d’ en [le|la|l’|les|de|d’|des|du|un|une|mon|ton|son|ma|ta|sa|mes|tes|ses|notre|votre|nos|vos|leurs|ce|cet|cette|ces]
+        <<- /conf/ -1:2>> dans                                                      # Confusion. Utilisez “dans” pour dire “à l’intérieur de quelque chose”.
+
+    <start>  [>dent|dan]  [le|la|l’|les|un|une|mon|ton|son|ma|ta|sa|mes|tes|ses|notre|votre|nos|vos|leurs|ce|cet|cette|ces]
+        <<- /conf/ -2>> dans                                                        # Confusion. Utilisez “dans” pour dire “à l’intérieur de quelque chose”.
+
+TEST: {{dan}} la voiture
+TEST: ils sont partis {{d’en}} une direction différente
+TEST: {{dents}} les montagnes au loin.
+TEST: Dents de la mer.
+
+
+# date / datte
+__conf_date_datte__
+    [>confiture|>crème|>gâteau|>mélasse|>noyau|>pâte|>recette|>sirop]  de >date
+    [moelleux|>gâteau|>fondant|>cake] [au|aux]  >date
+        <<- /conf/ -3>> dattes                                                      # Confusion probable : le fruit s’écrit avec deux “t”.
+
+    >date [>fraîche|>fraiche|>dénoyautée|>fourrée|>sèche|>séchée|>cultivée|produite|produites|>muscade|medjool|hamraya|deglet-nour|kenta|allig|khouat]
+        <<- /conf/ -1>> =\1.replace("ate", "atte").replace("ATE", "ATTE")           # Confusion probable : le fruit s’écrit avec deux “t”.
+
+TEST: il va faire un cake aux {{dates}}.
+TEST: elle a fait de la confiture de {{dates}}
+TEST: Elles étaient à cette date cultivées à l’air libre.
+TEST: De fraîche date…
+
+
+# davantage / d’avantage
+__conf_davantage_d_avantages__
+    [peu|plein|beaucoup|trop|plus|moins|assez|suffisamment|tellement|>obtention|>régime]  davantage
+        <<- /conf/ -2>> d’avantages                                                 # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    >être  d’  >avantage  @:[NAQ]¬:G
+        <<- /conf/ -2:3>> davantage                                                 # Confusion possible : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    @:V  d’ >avantage
+        <<- /conf/ not morph(\1, ":Q|>(?:profiter|bénéficier|nombre|tant)/") and not morph(>1, ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s?/")
+        -2:3>> davantage                                                            # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    ~-(?:je|tu|il|on)  d’  >avantage
+        <<- /conf/ not morph(\1, ">(?:profiter|bénéficier)/", 0, -3) and not morph(>1, ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s?/")
+        -2:3>> davantage                                                            # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    ~-ils  d’ >avantage
+        <<- /conf/ not morph(\1, ">(?:profiter|bénéficier)/", 0, -4) and not morph(>1, ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s?/")
+        -2:3>> davantage                                                            # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    ~-(?:elle|nous|nous)  d’  >avantage
+        <<- /conf/ not morph(\1, ">(?:profiter|bénéficier)/", 0, -5) and not morph(>1, ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s?/")
+        -2:3>> davantage                                                            # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    ~-elles  d’  >avantage
+        <<- /conf/ not morph(\1, ">(?:profiter|bénéficier)/", 0, -6) and not morph(>1, ">(?:financi[eè]re?|pécuni(?:er|aire)|sociaux)s?/")
+        -2:3>> davantage                                                            # Confusion probable : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+    d’ >avantage [de|d’]
+        <<- /conf/ -1:2>> davantage                                                 # Confusion possible : “davantage” signifie “plus” ; un “avantage” signifie “faveur”, “bénéfice”, “profit”…
+
+TEST: ils ont peu {{davantage}} à vivre ici.
+TEST: Ils s’exerceront {{d’avantages}}.
+TEST: {{d’avantage}} de monde de jour en jour
+TEST: Viendras-tu {{d’avantage}} à la maison
+TEST: {{d’avantage}} de monde viendra
+TEST: ils sont {{d’avantages}} perdus que les autres.
+TEST: il en faut {{d’avantages}}.
+TEST: tout ce qu’il apporte d’avantages pécuniaires.
+TEST: un certain nombre d’avantages sociaux.
+TEST: ils ont tant d’avantages.
+
+
+# différend / différent
+__conf_différent_différend__
+    >différend
+        <<- /conf/ morph(<1, ":W") ->> =\1.replace("end", "ent")        # Confusion probable : “un différend” est un désaccord. Pour l’adjectif qualifiant une différence, écrivez “différent”.
+
+    [mon|notre|votre|leur]  différent  @:[GVX]¬:[NAQ]
+    [mon|notre|votre|leur]  différent  <end>
+        <<- /conf/ -2>> différend                                       # Confusion probable : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
+
+    [ton|son]  différent  @:[GVX]¬:[NAQ]
+    [ton|son]  différent  <end>
+        <<- /conf/ not morph(<1, ":D") -2>> différend                   # Confusion probable : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
+
+    un  différent  @:[GV]¬:[NAQ]
+        <<- /conf/ -2>> différend                                       # Confusion probable : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
+
+    [mes|tes|ses|nos|vos|leurs]  différents  @:[GV]¬:[NAQ]
+    [mes|tes|ses|nos|vos|leurs]  différents  <end>
+        <<- /conf/ -2>> différends                                      # Confusion probable : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
+
+    [les|des]  différents  @:G¬:[NAQ]
+    les  différents  <end>
+        <<- /conf/ -2>> différends                                      # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
+
+    >être  ?[pas|si]¿   (>différends)
+    >être  pas  si      (>différends)
+        <<- /conf/ -1>> =\1.replace("nd", "nt")                         # Confusion : « différent » est un adjectif, « différend » est le nom qui signifie désaccord.
+
+TEST: Très {{différends}} de nous, ces gens-là !
+TEST: Régler votre {{différent}}.
+TEST: Notre {{différent}} avec eux perdure.
+TEST: Un {{différent}} peut toujours se résoudre.
+TEST: J’en ai marre de leurs {{différents}}.
+TEST: Il y a des {{différents}} que nul ne saurait résoudre.
+TEST: ce qui l’occupe, c’est son {{différent}} avec eux.
+TEST: Ils sont pas si {{différends}} de nous.
+TEST: Cette fois, il parla avec un ton différent.
+TEST: J’en veux un différent.
+TEST: Il en veut des différents.
+TEST: dans ses différents ouvrages
+TEST: dans ses différents postes gouvernementaux
+
+
+# eh bien, hé bien / et bien
+__conf_eh_bien__
+    [<start>|,]  et  bien
+        <<- /conf/ not value(>1, "|que|qu’|qu|sûr|davantage|entendu|d’|avant|souvent|longtemps|des|moins|plus|trop|loin|au-delà|") and not morph(>1, ":[YA]")
+        -2:3>> eh bien|hé bien                                              # Confusion probable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=h%C3%A9&T3.x=0&T3.y=0
+
+    et ben
+        <<- /conf/ \2.islower() ->> eh ben|hé ben                           # Confusion probable.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?T1=h%C3%A9&T3.x=0&T3.y=0
+
+TEST: {{et bien}} il y aura des pertes
+TEST: {{et ben}} on n’en sait rien.
+TEST: nous y songions, et bien au-delà des considérations habituelles.
+TEST: une image bien plus colorée, et bien plus intense, de la vie.
+TEST: Toutes ces questions, et bien d’autres, sont vues aujourd’hui dans le paradigme quantitatif de la monnaie, des taux de change flottants et de la monnaie administrée.
+TEST: et bien manger, c’est important.
+TEST: il a été vaincu, et bien vaincu.
+TEST: et Ben est parti.
+
+
+# en / an
+__être_en_xxxx__
+    [>être|>rester|>demeurer] an [contradiction|désaccord|accord]
+        <<- /conf/ -2>> en                                                                          # Confusion. Un an = une année. Pour la préposition, écrivez “en”.
+
+TEST: Je suis {{an}} désaccord avec lui.
+
+
+# faut / faux
+__conf_faux_faut__
+    faut  @:¬(?:Y|Oo|X|M)
+    faut  <end>
+        <<- /conf/ not value(<1, "|il|ils|ne|en|y|leur|lui|nous|vous|me|te|se|la|le|les|<start>|")
+        -1>> faux                                                           # Confusion probable : “faut” est une conjugaison de “falloir”. Pour indiquer la fausseté d’une chose, écrivez :
+
+TEST: un homme {{faut}}
+TEST: c’est {{faut}}
+TEST: il m’en faut plus.
+TEST: il faut réussir.
+TEST: bien sûr, faut y arriver.
+TEST: il ne faut pas se leurrer.
+TEST: y faut pas qu’elle l’entende.
+TEST: faut l’emmener chez le docteur.
+TEST: Faut Linux, sinon ça marchera jamais.
+
+
+# flan / flanc
+__conf_flanc_flan__
+    >flanc [pâtissier|pâtissiers]
+    >flanc [au|aux] [>caramel|>café|>citron|>chocolat|>four|>lait|>lard|noix|>pomme|>pruneau|>œuf|>raisin]
+    >flanc [de|d’] [or|argent|cuivre]
+    >flanc à la [crème|coco|noix]
+        <<- /conf/ -1>> =\1.replace("c", "").replace("C", "")               # Confusion. S’il s’agit d’une pâtisserie (ou d’une pièce de métal), écrivez :|https://fr.wiktionary.org/wiki/flan
+
+    c’ [est|était] ?[que|tout]¿ du (flanc)
+    c’ [est|était] rien que du (flanc)
+        <<- /conf/ -1>> flan                                                # Confusion. Locution « c’est du flan ».|https://fr.wiktionary.org/wiki/flan
+
+    comme deux ronds de >flanc
+        <<- /conf/ -5>> flan                                                # Confusion. Locution « comme deux ronds de flan ».|https://fr.wiktionary.org/wiki/comme_deux_ronds_de_flan
+
+    >flan de la [>colline|>montagne]
+    >flan [de|des] [>colline|>montagne]
+    >flan [>gauche|droit|droits|nord|sud|ouest]
+        <<- /conf/ -1>> =\1.replace("an", "anc").replace("AN", "ANC")       # Confusion probable. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+    [>attaquer|>allonger|>blesser|>coucher|>étendre|>toucher]  sur  [le|mon|ton|son|notre|votre|leur]   flan
+        <<- /conf/ -4>> flanc                                               # Confusion probable. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+    [>attaquer|>allonger|>blesser|>coucher|>étendre|>toucher]  sur  [les|mes|tes|ses|nos|vos|leurs]     flans
+        <<- /conf/ -4>> flancs                                              # Confusion probable. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+
+    [>tirer|>tir]  au  flan
+        <<- /conf/ -3>> flanc                                               # Confusion. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+    [>tirer|>tir]  aux flans
+        <<- /conf/ -3>> flancs                                              # Confusion. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+    tir-aux-flan
+    tir-aux-flans
+    tir-au-flans
+    tir-au-flan
+        <<- /conf/ ->> tir-au-flanc                                         # Confusion. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+    tirs-aux-flan
+    tirs-aux-flans
+    tirs-au-flans
+    tirs-au-flan
+        <<- /conf/ ->> tirs-au-flanc                                        # Confusion. Le flan est une pâtisserie.|https://fr.wiktionary.org/wiki/flanc
+
+TEST: encore un {{flanc}} au chocolat.
+TEST: ce type, c’est que du {{flanc}}.
+TEST: ce type, c’est rien que du {{flanc}}.
+TEST: j’en étais comme deux ronds de {{flancs}}
+TEST: attaqué sur son {{flan}} droit
+TEST: elle possède une maison à {{flan}} de colline.
+TEST: étendu sur son {{flan}}.
+TEST: Ce sale {{tir-au-flan}} le paiera cher.
+TEST: le flan est une pâtisserie.
+TEST: versez du caramel sur le flan.
+
+
+# golf / golfe
+__conf_golf_golfe__
+    [>championne|>championnat|>club|>joueuse|parcours|>sac|>balle|>terrain|>tournoi|>compétition|>passionnée|>école|>professeure|>partie|>professionnelle|>amateure|>stage|>journée|après-midi|>matinée|>heure|>fédération|>fan] de golfe
+        <<- /conf/ -3>> golf                                                # Confusion. Le golfe est une zone de mer ou d’un lac avancée dans les terres. Ex : Le golfe Persique.
+
+    golf persique
+    golf [de|du|d’] [Bengale|Botnie|Gascogne|Gabès|Guinée|Lion|Morbihan|Mexique|Porto|Saint-Laurent|Thaïlande|Tonkin|Tunis|Winam|Aden|Ajaccio|Alaska|Hammamet]
+        <<- /conf/ -1>> golfe                                               # Confusion. Le golf est un sport.
+
+    [>guerre|>émir|>monarchie] du golf
+        <<- /conf/ -3>> Golfe                                               # Confusion. Le golf est un sport.
+
+TEST: Il a réalisé un documentaire sur la guerre du {{Golf}}.
+TEST: C’est un bon joueur de {{golfe}}.
+TEST: Le {{golf}} Persique est presque une mer fermée.
+TEST: J’ai fait de la voile dans le {{golf}} du Morbihan.
+TEST: Le {{golf}} d’Aden.
+
+
+# haut delà / au-delà
+__conf_au_delà__
+    haut [dela|delà]
+    [haut-dela|haut-delà]
+        <<- /conf/ ->> au-delà                              # Confusion.
+
+TEST: il va dans l’{{haut delà}}
+
+
+# héro / héros
+__conf_héros__
+    [le|quel|ce|cet|un|du|au]  héro
+        <<- /conf/ -1>> héros                               # Confusion. L’héro est l’abréviation de “héroïne” (la drogue). L’homme héroïque s’écrit “héros”.
+
+TEST: Mon frère, {{ce}} {{héro}} !
+
+
+# hors / or
+__conf_hors_or__
+    <start>  hors  ,
+        <<- /conf/ -2>> or
+        # Confusion. Écrivez “or” pour dire “néanmoins”. La préposition “hors” sert à dire “en dehors de” ou “excepté”.|https://fr.wiktionary.org/wiki/hors
+
+    hors [je|j’|tu|il|ils|on|parce|quel|quels|quelle|quelles|pourquoi|qui|que]
+        <<- /conf/ -1>> or,
+        # Confusion probable. Écrivez “or” pour dire “néanmoins”. La préposition “hors” sert à dire “en dehors de” ou “excepté”.|https://fr.wiktionary.org/wiki/hors
+
+TEST: {{hors}}, nous y coryons malgré tout ce qu’on peut en dire.
+TEST: {{Hors}} il y a tant à faire depuis que nous sommes arrivés en ces lieux.
+TEST: Hors nous, personne ne sait ce qui s’est passé là-bas.
+TEST: Le peuple se sent hors jeu.
+
+
+# jeune / jeûne
+__conf_jeune__
+    très  >jeûne
+        <<- /conf/ -2>> =\1.replace("û", "u")                                                       # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
+
+TEST: Très {{jeûne}}, elle a su qu’elle ne voulait pas d’une vie ordinaire.
+
+
+# la / là
+__conf_la_là!7__
+    la  [l’|d’|n’|m’|t’|s’|c’|ç’|j’|qu’|lorsqu’|puisqu’|quoiqu’]
+    la  @:G¬:(?:[NA]:[ef]|W)|>(?:lui|leur|votre|notre|voilà|voici|plupart)
+        <<- /conf/ \1 != "LA" and not \2.isupper() and not morph(<1, ":E|>le/") -1>> là             # Confusion probable. Écrivez “là” si vous voulez dire “ici”.
+
+    [ce|cet|cette|ces]  ~-(la)
+        <<- /conf/ -2>> =\2.replace("-la", "-là")                                                   # Confusion. Écrivez “là” soudé au nom pour désigner un objet précis.
+
+TEST: nous serions encore {{la}} l’année prochaine
+TEST: en reprenant le chandail de John {{la}} où elle l’avait abandonné.
+TEST: Ce {{fait}}-{{la}} ne peut être ignoré.
+TEST: la peu efficace sensibilité
+TEST: c’est toujours la même histoire
+TEST: c’est la moins habile de toutes
+TEST: Qui serait la ou le plus à même à occuper ce poste selon vous ?
+
+
+# la plupart
+__conf_la_plupart__
+    la [plus|plue|plues|plut|plût|plu] [part|parts|par|pare|pares]
+        <<- /conf/ -2:3>> plupart                                               # Confusion. Écrivez « la plupart » pour évoquer la majeure partie de quelque chose.
+
+    la [plus-part|plus-parts|plus-par|plus-pare|plus-pares]
+    la [plues-part|plues-parts|plues-par|plues-pare|plues-pares]
+    la [plut-part|plut-parts|plut-par|plut-pare|plut-pares]
+    la [plût-part|plût-parts|plût-par|plût-pare|plût-pares]
+    la [plu-part|plu-parts|plu-par|plu-pare|plu-pares]
+        <<- /conf/ -2>> plupart                                                 # Confusion. Écrivez « la plupart » pour évoquer la majeure partie de quelque chose.
+
+TEST: la {{plus part}}
+TEST: la {{plu-part}}
+
+
+__conf_les_lés_lès__
+    [les|des|ces|mes|tes|ses|nos|vos|leurs|quelques]  lès
+        <<- /conf/ -2>> lés                                     # Confusion probable : “lès” signifie “à côté de” et ne s’emploie plus guère que dans des noms de ville, comme Garges-lès-Gonesse. Si vous parlez des bandes de tissu ou de papier peint, écrivez “lés”.|https://fr.wiktionary.org/wiki/l%C3%A8s
+
+    lès  [<end>|,]
+        <<- /conf/ -1>> lés                                     # Confusion probable : “lès” signifie “à côté de” et ne s’emploie plus guère que dans des noms de ville, comme Garges-lès-Gonesse. Si vous parlez des bandes de tissu ou de papier peint, écrivez “lés”.|https://fr.wiktionary.org/wiki/l%C3%A8s
+
+    lès  *WORD
+        <<- /conf/ not morph(<1, ":D.*:p") -1>> les             # Confusion probable : “lès” signifie “à côté de” et ne s’emploie plus guère que dans des noms de ville, comme Garges-lès-Gonesse ou Vandœuvre-lès-Nancy.|https://fr.wiktionary.org/wiki/l%C3%A8s
+
+    lés  @:N.*:[pi]¬:(?:[MGAW]|3p)
+        <<- /conf/ -1>> les                                     # Confusion probable. Un lé est une bande de tissu ou de papier peint.|https://fr.wiktionary.org/wiki/l%C3%A9
+
+TEST: Entre les saules et {{lés}} ifs.
+TEST: Montrez-moi ces {{lès}} venus d’Italie.                           ->> lés
+TEST: avec {{lès}} hommes d’à côté, difficile de se concentrer.         ->> les
+TEST: Entre les saules et {{lès}} ifs                                   ->> les
+TEST: Les asphaltes purs d’étanchéité sont des mastics bitumineux, de même que les masses d’enrobage des lés d’étanchéité.
+TEST: Pour avoir fait de neuf une grande cage de bois de grosses solives, membrures et sablières, contenant neuf pieds de long sur huit de lé. (Victor Hugo)
+TEST: Un lé de velours, de taffetas, de toile.
+TEST: Draps de lit de deux lés.
+TEST: Elle habite Vandœuvre-lès-Nancy.
+
+
+# leurs / leur
+__conf_leurs_verbe__
+    leurs  @:(?:[123][sp]|Y)¬:[GNAM]
+    <<- /conf/ not morph(<1, ">[ld]es/")
+    -1>> leur                                       # Incohérence : “leurs” est un déterminant pluriel censé précéder un substantif pluriel. Pour le pronom personnel devant un verbe, écrivez “leur”.
+
+TEST: je vais {{leurs}} reprendre
+TEST: je {{leurs}} apprends la programmation
+TEST: après qu’un des leurs ait été gravement blessé par un tir de grenade
+
+
+# loin s’en faut
+__conf_loin_s_en_faut__
+    [loin|loins] [sens|cens|sans|>sang] [faux|faut]
+    [loin|loins] c’ en [faux|faut]
+    [loin|loins] s’ en [faux]
+    loins s’ en faut
+        <<- /conf/ ->> loin s’en faut               # Confusion probable. Cette locution s’écrit “loin s’en faut”.|https://fr.wiktionary.org/wiki/loin_s%E2%80%99en_faut
+
+TEST: Ils n’étaient guère prêts à ça, {{loins sans faux}}.
+TEST: Et les intellectuels ? En France comme ailleurs, tous n’ont pas, loin s’en faut, une pleine lucidité sur cette précarité galopante.
+
+
+# mai / mais
+__conf_mai_mais__
+    [<start>|,]  mai  @:Os¬:3s
+    <<- /conf/ -2>> mais                            # Confusion probable : “mai” est le 5ᵉ mois de l’année. Pour la conjonction de coordination, écrivez “mais”.|https://fr.wiktionary.org/wiki/mais
+
+TEST: {{mai}} il y a encore tant à faire.
+TEST: Je viendrai, {{mai}} il faudra avoir tout prévu.
+TEST: Mai pluvieux.
+
+
+# min / mins
+__conf_symbole_min__
+    ~\d+  mins
+        <<- /conf/ -2>> min                         # Les unités de mesure abrégées ne prennent pas la marque du pluriel.
+
+TEST: 120 {{Mins}} de bonheur
+
+
+# on / ont
+__conf_on_ont__
+    on  @:W¬:3s
+        <<- /conf/ not morph(<1, ":V.*:3s") and not before0("’$")
+        -1>> ont                                            # Confusion probable : “avoir” à la 3ᵉ personne du pluriel du présent s’écrit “ont”.
+
+TEST: ces gens {{on}} {{souvent}} tort.
+TEST: Je voulais qu’on soit ensemble.
+
+
+# ou / où
+__conf_où_ou__
+    <start>  Ou  @:3[sp]¬:Y
+        <<- /conf/ -2>> Où                                  # Confusion probable. La conjonction “ou” signale une alternative. Utilisez “où” pour “en quel lieu”.
+
+    au moment (ou)
+    [jusqu’|jusqu] (ou)
+    par (ou)
+    d’ (ou)
+        <<- /conf/ -1>> où                                  # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
+
+    vers ou
+        <<- /conf/ not morph(<1, ":D") -2>> où              # Confusion probable. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
+
+    [au|le|des] cas ou
+        <<- /conf/ -3>> où                                  # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
+
+    à partir du [lieu|moment|jour|mois]     (ou)
+    à partir de l’ [instant|année|heure]    (ou)
+    à partir de la [minute|semaine|seconde] (ou)
+        <<- /conf/ -1>> où                                  # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
+
+    depuis le [jour|millénaire|moment|mois|siècle] ou
+    depuis la [minute|semaine|seconde] ou
+    depuis l’ [année|heure|instant] ou
+        <<- /conf/ -4>> où                                  # Confusion. La conjonction “ou” signale une alternative. Pour identifier un lieu ou un temps, écrivez “où”.
+
+TEST: {{Ou}} sont tes affaires ?
+TEST: au moment {{ou}} elle allait enfin réussir
+TEST: vers {{ou}} se tourner quand tout va mal ?
+TEST: pour le cas {{ou}} on serait arrêté dans notre élan.
+TEST: à partir du moment {{ou}} il est entré.
+TEST: à partir de l’instant {{ou}} elle est venue.
+TEST: depuis l’année {{ou}} nous sommes allés en Bretagne
+TEST: depuis la seconde {{ou}} tu as parlé
+TEST: depuis le jour {{ou}} il a été blessé.
+
+
+# pale / pâle
+__conf_pâle_pale__
+    [bien|très|trop|si|vraiment|tellement] >pale
+        <<- /conf/ -2>> =\2.replace("pal", "pâl")
+        # Utilisez “pâle” pour évoquer la pâleur… Une pale est, entre autres choses, un élément d’une hélice.|http://fr.wiktionary.org/wiki/pale
+
+    >pale [>imitation|>imitatrice|>rayon]
+        <<- /conf/ -1>> =\1.replace("pal", "pâl")
+        # Utilisez “pâle” pour évoquer la pâleur… Une pale est, entre autres choses, un élément d’une hélice.|http://fr.wiktionary.org/wiki/pale
+
+TEST: elles sont si {{pales}}.
+TEST: cette {{pale}} imitation d’un chef-d’œuvre
+
+
+# par-dessus / pardessus
+__conf_par_dessus__
+    pardessus  [bord|@:D]
+        <<- /conf/ not morph(<1, ":D.*:[me]|>(?:grande|petite)/")
+        -1>> par-dessus                                                     # Confusion probable. Un pardessus est un vêtement. Pour la préposition, écrivez “par-dessus”.
+
+TEST: {{Pardessus}} les montagnes.
+TEST: Il passa {{pardessus}} les collines.
+TEST: Mets ton pardessus ce matin.
+
+
+# peu / peux / peut / peut-être
+__conf_peu_peut_peux_peut_être!6__
+    peu [pas|donc|jamais|rien|parfois|alors|enfin|rarement|éventuellement]
+        <<- /conf/ not morph(<1, ">(?:très|en|un|de|du)") -1>> peut         # Confusion probable : « peu » signifie « pas beaucoup », pour le verbe pouvoir, écrivez :
+
+    [peu-être|peux-être]
+        <<- /conf/ ->> peut-être                                            # Confusion. Écrivez « peut-être », qui signifie « possiblement ».
+
+    <start>  [il|ce|ne]  peut-être
+        <<- /conf/ -3>> peut être                                           # Confusion probable : « peut-être » signifie « possiblement ».
+
+    <start>  [cela|ceci|ça]  peut-être  @:[AQ]
+        <<- /conf/ -3>> peut être                                           # Confusion probable : « peut-être » signifie « possiblement ».
+
+    [peux|peut|peu] a [peux|peut|peu]
+    [peux|peut|peu] à [peux|peut]
+        <<- /conf/ ->> peu à peu                                            # Confusion : « peu à peu » ou « petit à petit ».
+
+    [peux|peut] [importent|importe]
+        <<- /conf/ morph(<1, ":C|<start>") -1>> peu                         # Confusion : « \1 » est une conjugaison de “pouvoir”, utilisez “peu” pour dire “pas beaucoup”.
+
+    [très|trop|de|quelque|pour|à] [peux|peut]
+        <<- /conf/ -2>> peu                                                 # Confusion : « \2 » est une conjugaison de “pouvoir”, utilisez “peu” pour dire “pas beaucoup”.
+
+    un  [peux|peut]
+        <<- /conf/ not before("(?i)(?:(?:quelqu|l|d)’|sauf +)") -2>> peu    # Confusion : « \2 » est une conjugaison de “pouvoir”, utilisez “peu” pour dire “pas beaucoup”.
+
+    [il|on] ?[ne|n’]¿ (peu)
+        <<- /conf/ -1>> peut                                                # Confusion : « peu » signifie « pas beaucoup ».
+
+    [je|tu] ?[ne|n’]¿ (peu)
+        <<- /conf/ -1>> peux                                                # Confusion : « peu » signifie « pas beaucoup ».
+
+    [ne|se|n’|s’] peu
+        <<- /conf/ -2>> peut                                                # Confusion. Exemples : Il est peu habile, mais il peut y arriver.
+
+    [peut|peux]  @:A¬:(?:[MGWYX]|3[sp])
+        <<- /conf/ not morph(\2, ">seule") and not morph(<1, ">(?:je|tu|il|on|ne)")
+        -1>> peu                                                            # Confusion probable : « \1 » est une conjugaison de « pouvoir », utilisez « peu ».
+
+TEST: {{peu}} rarement y arriver.
+TEST: Il est un {{peut}} comme une forêt
+TEST: Il {{peut-être}} mortel.
+TEST: Cela {{peut-être}} mortel.
+TEST: cela ne se {{peu}}.
+TEST: des bâtisses {{peu a peu}} abandonnées.
+TEST: aucun pays – ou très peu alors – n’a réussi à faire ça de façon durable
+TEST: Mais {{peut}} importe le rang.
+TEST: homme de {{peut}} de foi, écoute le vent.
+TEST: Il en vient un {{peut}} tous les jours.
+TEST: {{peut}} sympathique, cet individu.
+TEST: il {{peu}} y parvenir
+TEST: tu ne {{peu}} en savoir plus
+TEST: {{peut}} {{embarrassés}} par leurs déboires, ils poursuivirent comme si de rien n’était.
+
+
+# pot aux roses / poteau rose
+__conf_pot_aux_roses__
+    poteau rose
+        <<- /conf/ ->> pot aux roses                                        # Confusion probable. On dit : « découvrir le pot aux roses ».|http://fr.wiktionary.org/wiki/d%C3%A9couvrir_le_pot_aux_roses
+
+TEST: Ils ont découvert le {{poteau rose}}.
+
+
+# prêt / près / pré
+__conf_pré_près_prêt__
+    de plus ([>prêt|>pré])
+    depuis ([>prêt|>pré])
+        <<- /conf/ -1>> près                                                # Confusion probable. Être prêt(e) à faire quelque chose. Être près de quelque chose. Le pré est un champ d’herbes.
+
+    très [>prêt|>pré]
+        <<- /conf/ -2>> près                                                # Confusion probable. Être prêt(e) à faire quelque chose. Être près de quelque chose. Le pré est un champ d’herbes.
+
+    près à @:Y|>(?:tout|les?|la)/
+        <<- /conf/ not before(r"(?i)\b(?:peu|de|au plus) $") -1>> prêt|p    # Confusion probable. Être près de (faire) quelque chose. Prêt à faire quelque chose.
+
+    >prêt [de|d’] [toi|vous|lui|elle|eux|elles|@:M]
+        <<- /conf/ not before(r"(?i)\b(obten|obt[iî])") -1>> près           # Confusion probable. Être près de (faire) quelque chose. Prêt à faire quelque chose.
+
+    >prêt [de|d’] la [lui|leur|@:Y]
+        <<- /conf/ \3.islower() -1>> près                                   # Confusion probable. Être près de (faire) quelque chose. Prêt à faire quelque chose.
+
+    >prêt [de|d’] [le|l’|les|me|m’|te|t’|se|s’|ne|n’|en|y|@:Y]
+        <<- /conf/ \3.islower() -1>> près                                   # Confusion probable. Être près de (faire) quelque chose. Prêt à faire quelque chose.
+
+    si [>prêt|>pré] du but
+        <<- /conf/ ~2>> près                                                # Confusion probable. Être près de (faire) quelque chose. Prêt à faire quelque chose.
+
+TEST: depuis {{prêt}} de 15 ans
+TEST: ils se sont approchés très {{prêts}}.
+TEST: Je suis si {{prêt}} d’y arriver.
+TEST: Elle est si {{prêt}} de la trouver.
+TEST: Il est {{près}} à les aider
+TEST: Elle va regarder ça de plus {{prêt}}.
+TEST: Il a obtenu un prêt de Patrick
+TEST: Il a obtenu un prêt de Le Drian
+
+
+# quand / quant / qu’en
+__conf_quand_quant_qu_en__
+    quand à
+        <<- /conf/ not morph(<1, ">(?:arriver|venir|à|revenir|partir|repartir|aller|de)/") and not after("^ +[mts]on tour[, ]")
+        -1>> quant                                                          # Confusion probable. Quand = à quel moment. Quant à = à propos de.|https://fr.wiktionary.org/wiki/quant_%C3%A0
+
+    quand [au|aux]
+        <<- /conf/ not morph(<1, ">(?:arriver|venir|à|revenir|partir|repartir|aller|de)/")
+        -1>> quant                                                          # Confusion probable. Quand = à quel moment. Quant à = à propos de.|https://fr.wiktionary.org/wiki/quant_%C3%A0
+
+    [quand|quant]   @:P
+        <<- /conf/ -1>> qu’en                                               # Confusion probable.
+
+    [quand|quant] [est|était] il [de|des|du]
+    [quand|quant] [est-il|était-il] [de|des|du]
+        <<- /conf/ -1>> qu’en                                               # Confusion probable. Ce qu’il en est de… → Qu’en est-il de… ?
+
+    quant  ~ˆ|aux?
+        <<- /conf/ -1>> quand                                               # Confusion. Quand = à quel moment. Quant à = à propos de.
+
+    [qu’|qu] en [je|tu|il|ils]
+        <<- /conf/ not after("^ ne s(?:ai[st]|u[ts]|avai(?:s|t|ent)|urent) ")
+        -1:2>> quand                                                        # Confusion probable. Pour évoquer un moment, écrivez “quand”.|https://fr.wiktionary.org/wiki/quand
+
+TEST: {{Quant}} est-il du chien ?
+TEST: {{Quand}} à ma santé, elle est défaillante.
+TEST: {{Quant}} ils…
+TEST: {{quant}} je…
+TEST: {{quant}} nous…
+TEST: il comprit {{quand}} prenant son parti, il se protégeait aussi.
+TEST: {{qu’en}} il vient, c’est l’enfer.
+TEST: il est exact qu’en je ne sais combien de temps il parvint à un résultat inattendu.
+TEST: être rassuré quant à l’avenir du continent européen
+TEST: il comprit trop tard qu’en elle naquit alors le doute qui l’éloigna de lui à jamais.
+TEST: Quand à mon tour je réalise l’imposture, c’est trop tard.
+TEST: Quant au chat, on verra plus tard.
+
+
+# quand bien même
+__conf_quand_bien_même__
+    tant bien même
+        <<- /conf/ ->> quand bien même      # Confusion. Écrivez « quand bien même ».|http://www.academie-francaise.fr/tant-bien-meme
+
+    combien même ~¬si
+        <<- /conf/ -1:2>> quand bien même   # Locution conjonctive.|https://fr.wiktionary.org/wiki/quand_bien_m%C3%AAme
+
+TEST: il sera condamné {{tant bien même}} il prouverait que c’était un accident.
+TEST: J’irai, {{combien même}} vous seriez tous contre moi.
+TEST: Il partirait en guerre quand bien même devrait-il être tout seul.
+TEST: Elle veut savoir combien même si ça ne lui est d’aucune utilité immédiate.
+
+
+# quelle / qu’elle
+__conf_qu_elle_quelle__
+    [que|qu’|qu]  elle   @:[NAQ]¬:(?:G|[123][sp]|W|Oo|X)|>seule?/
+        <<- /conf/ -1:2>> quelle                                                                    # Confusion probable. Ex : Quelle femme ! Je crois qu’elle réussira.
+
+    [que|qu’|qu]  elles  @:[NAQ]¬:(?:G|[123][sp]|W|Oo|X)|>seule?/
+        <<- /conf/ -1:2>> quelles                                                                   # Confusion probable. Ex : Quelle femme ! Je crois qu’elle réussira.
+
+    quelle  [ne|n’|me|m’|te|t’|se|s’|nous|vous|le|la|l’|les|lui|leur|en|y]
+        <<- /conf/ not (morph(\2, ">en/") and morph(>1, ":V0e")) -1>> qu’elle                       # Confusion. Le sujet “elle” doit être séparée de la conjonction “que”.
+
+    quelle  @:V¬:[NA].*:[fe]|>(?:être|plus)
+        <<- /conf/ \2.islower() and not (morph(\2, ">(?:pouvoir|devoir)/") and morph(>1, ":V0e")) and not (morph(\2, ":V0a") and after("^ +été "))
+        -1>> qu’elle                                                                                # Confusion. Le sujet “elle” doit être séparée de la conjonction “que”.
+
+    quelles [ne|n’|me|m’|te|t’|se|s’|nous|vous|le|la|l’|les|lui|leur|en|y]
+        <<- /conf/ not (morph(\2, ">en/") and morph(>1, ":V0e")) -1>> qu’elles                      # Confusion. Le sujet “elles” doit être séparée de la conjonction “que”.
+
+    quelles @:V¬:[NA].*:[fe]|>(?:être|plus)
+        <<- /conf/ \2.islower() and not (morph(\2, ">(?:pouvoir|devoir)/") and morph(>1, ":V0e")) and not (morph(\2, ":V0a") and after("^ +été "))
+        -1>> qu’elles                                                                               # Confusion. Le sujet “elles” doit être séparée de la conjonction “que”.
+
+    quelle  >être   @:[QA]¬:G
+        <<- /conf/ morph(\2, ":[123][sp]") -1>> qu’elle                                             # Confusion. Le sujet “elle” doit être séparée de la conjonction “que”.
+
+    quelles >être   @:[QA]¬:G
+        <<- /conf/ morph(\2, ":[123][sp]") -1>> qu’elles                                            # Confusion. Le sujet “elles” doit être séparée de la conjonction “que”.
+
+TEST: {{qu’elle}} emmerdeuse.
+TEST: Je sais {{quelle}} est partie.
+TEST: {{Quelle}} partit prendre son repas à la cantine, je n’en avais cure.
+TEST: Il se plaint {{quelle}} ne nous dit rien.
+TEST: {{Quelles}} sont intelligentes, ces filles-là.
+TEST: {{Quelle}} a du répondant, cette gamine !
+TEST: {{Quelle}} y vienne, on verra ce qu’elle vaut.
+TEST: Je veux {{quelles}} s’efforcent à y parvenir.
+TEST: {{Quelle}} l’apprenne un jour, on n’y peut rien.
+TEST: Je crois {{quelle}} n’en sait pas assez pour nous nuire.
+TEST: {{Quelles}} t’arrivent seulement à la cheville, voilà qui serait étonnant.
+TEST: {{Quelles}} m’engueulent encore une seule fois et elles vont le regretter.
+TEST: Je crois {{quelle}} est partie.
+TEST: il pense {{quelles}} sont devenues dangereuses.
+TEST: je crois qu’elle seule peut y parvenir
+TEST: Quelle est sa passion ?
+TEST: Quelles sont leurs principales études ?
+TEST: Quelles en sont les conséquences ?
+TEST: Quelle plus belle complicité que…
+TEST: Quelle peut être la date de clôture d’un exercice ?
+TEST: Quelle doit être la date du mariage ?
+TEST: Quelles ont été les annonces faites ?
+TEST: Elle cache qu’elle a été en prison.
+TEST: Elle avait été accueillie avec joie.
+
+
+# quoi que / quoique
+__conf_quoique_quoi_que__
+    [quoiqu’|quoiqu] il se soit ?@:W¿ passé
+    [quoique|quoiqu’|quoiqu] [je|j’|tu|il|elle|on|nous|vous|ils|elles] en >penser
+    [quoique|quoiqu’|quoiqu] [je|j’|tu|il|elle|on|nous|vous|ils|elles] >avoir pu faire
+        <<- -1>> quoi que|quoi qu’      # Confusion probable.|https://fr.wiktionary.org/wiki/quoi_que
+
+TEST: mais {{quoique}} tu en penses, c’est comme ça que ça fonctionne.
+TEST: {{Quoiqu}}’il se soit passé réellement passé, je vais lui faire la peau.
+TEST: {{quoique}} vous ayez pu faire, ça a donné les résultats escomptés.
+
+
+# ne pas être sans savoir
+__ne_pas_être_sans_savoir__
+    >être [pas|plus|jamais|guère] sans >ignorer
+        <<- /conf/ -4>> savoir          # Confusion : vous écrivez l’inverse de ce que vous voulez dire.|http://fr.wiktionary.org/wiki/vous_n%E2%80%99%C3%AAtes_pas_sans_savoir
+
+    ne [pas|plus|jamais|guère] être sans >ignorer
+        <<- /conf/ -5>> savoir          # Confusion probable : vous écrivez l’inverse de ce que vous voulez dire.|http://fr.wiktionary.org/wiki/vous_n%E2%80%99%C3%AAtes_pas_sans_savoir
+
+TEST: Vous n’êtes pas sans {{ignorer}} que…
+TEST: ne pas être sans {{ignorer}} la cause de ces phénomènes.
+
+
+# s’en / sens / cens / cent / sans / sang
+__conf_s_en_sens_sans_cent_cens__
+    [<start>|,]  [il|ils|on]    [c’|ç’]  en                     @:V
+    [<start>|,]  [elle|elles]   [c’|ç’]  en                     @:V¬:V0e
+        <<- /conf/ -3:4>> s’en                                                                      # Confusion probable.
+
+    [<start>|,]  [il|ils|on]    [sans|sang|sangs|cens|cent]     @:V
+    [<start>|,]  [elle|elles]   [sang|sangs|cens|cent]          @:V
+    [<start>|,]  [elle|elles]   sans                            @:V¬:(?:[NYDA]|Oo)|>(?:y|en)
+        <<- /conf/ -3>> s’en                                                                        # Confusion probable.
+
+TEST: il {{c’en}} est vite lassé.
+TEST: {{S’en}} était vraiment trop !
+TEST: Car {{s’en}} était vraiment fini !
+TEST: elle {{sang}} était voulu
+TEST: elle sans y penser
+TEST: elle sans vergogne
+TEST: elle sans la condamner
+TEST: elles sans un sou en poche
+TEST: elles sans grandes convictions
+TEST: elle c’en était trop (TODO : proposer une virgule)
+
+
+# son / sont
+__conf_son_sont__
+    [ne|me|te|se] son
+        <<- /conf/ -2>> sont    # Confusion : “son” est un déterminant ou un nom masculin. Le verbe “être” à la 3ᵉ personne du pluriel s’écrit “sont”.
+
+    ne [le|leur|leurs|lui|nous|vous] son
+        <<- /conf/ -3>> sont    # Confusion : “son” est un déterminant ou un nom masculin. Le verbe “être” à la 3ᵉ personne du pluriel s’écrit “sont”.
+
+    [qui|que|comment|pourquoi|lorsque|quand] son [,|@:[DR]]
+        <<- /conf/ -2>> sont    # Confusion probable : “son” est un déterminant ou un nom masculin. Le verbe “être” à la 3ᵉ personne du pluriel s’écrit “sont”.
+
+    [<start>|,] sont @:[NA].*:[me]:s|>[aeéiîou].*/:[NA].*:f:s¬:[GW]
+        <<- /conf/ -2>> son     # Confusion probable : “sont” est le verbe “être” à la 3ᵉ personne du pluriel. Pour le déterminant, écrivez “son”.
+
+    sont @:[NA].*:[me]:s|>[aeéiîou].*/:[NA].*:f:s¬:[GW]
+        <<- /conf/ morph(<1, ":V", ":[NA].*:[pi]|>(?:ils|elles|vous|nous|leur|lui|[nmts]e)/") and not before(r"(?i)\bce que? |[mts]’en +$")
+        -1>> son                # Confusion probable : “sont” est le verbe “être” à la 3ᵉ personne du pluriel. Pour le déterminant, écrivez “son”.
+
+    [à|chez|dès|par] sont
+    [avec|contre|devant|derrière|pour|sans|sur] sont @:[NA].*:[me]:s|>[aeéiîou].*/:[NA].*:f:s¬:[GW]
+        <<- /conf/ -2>> son     # Confusion probable : “sont” est le verbe “être” à la 3ᵉ personne du pluriel. Pour le déterminant, écrivez “son”.
+
+    en sont @:[NA].*:[me]:s|>[aeéiîou].*/:[NA].*:f:s¬:[GW]
+        <<- /conf/ not before(r"(?i)\b(?:ce que? |ils|elles|leur|lui|nous|vous|[mtsl]’)$")
+        -2>> son                # Confusion probable : “sont” est le verbe “être” à la 3ᵉ personne du pluriel. Pour le déterminant, écrivez “son”.
+
+TEST: ne leur {{son}} pas odieux.
+TEST: Ces chiens me {{son}} odieux.
+TEST: {{sont}} {{pain}}
+TEST: en {{sont}} {{absence}}
+TEST: qui {{son}} ces gens ?
+TEST: ces gens qui {{son}}, dans le meilleur des cas, des imbéciles ne peuvent nous aider.
+TEST: elles s’en sont mal portées
+TEST: ils en sont reconnaissants
+TEST: sont loin, ces gens…
+TEST: Il ne sait pas vraiment ce que sont la peur et la souffrance.
+
+
+# statue / statut / statu
+__conf_statu_statue_statut__
+    [statut|statue|status] quo
+        <<- /conf/ ->> statu quo                # Confusion. Écrivez “statu quo”.|https://fr.wiktionary.org/wiki/statu_quo
+
+    statu ~¬[qQ][uU][oO]
+        <<- /conf/ -1>> statut|statue           # Confusion : “statu” ne s’emploie que dans l’expression “statu quo”.
+
+TEST: Ça n’en finit pas, c’est le {{statut quo}}.
+TEST: Quelle splendide {{statu}}.
+
+
+# sur / sûr
+__conf_sûr_sur__
+    sur [que|qu’|qu]
+    sur [de|d’] {pronom_obj}
+    sur [de|d’] @:M
+    sur [de|d’] [ne|n’|me|m’|te|t’|se|s’]
+    sur [de|d’] [le|les|mon|ton|son|ma|ta|sa|mes|tes|ses|ce|cet|cette|ces|cela|ceci|ça]
+    sur [de|d’] la @:Y
+        <<- /conf/ -1>> sûr
+        # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
+
+    sur [de|d’] @:Y
+        <<- /conf/ -1>> sûr
+        # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
+
+    en lieu sur
+        <<- /conf/ -3>> sûr
+        # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
+
+    [sure|surs|sures] [de|d’|que|qu’|qu]
+        <<- /conf/ -1>> =\1.replace("sur", "sûr")
+        # Confusion probable : “sur” un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
+
+TEST: Je suis {{sur}} de Patrick.
+TEST: Je suis {{sure}} qu’il ne va pas tarder à venir
+TEST: {{sures}} d’elles-mêmes, elles ne s’en laissent pas conter.
+TEST: {{sur}} de toi et de moi, que peut-il nous arriver, sinon le meilleur.
+TEST: Il est tellement {{sur}} de la trouver.
+TEST: ils sont en lieu {{sur}} et introuvables.
+TEST: il s’étendit sur de la mousse à mémoire de forme
+
+
+# temps / tant / tan
+__conf_tant_temps_tan_1__
+    en [tant] [de|d’] [guerre|paix|crise|doute|pluie]
+        <<- /conf/ -2>> temps                               # Confusion. Écrivez « en temps de » si vous évoquez une période de temps.
+
+    de [tant|tan|tans] en [tant|tan|tans]
+        <<- /conf/ ->> de temps en temps                    # Confusion. Écrivez « de temps en temps ».
+
+    un [temps|tan|tans] [soi|sois|soie|soies|soit] peu
+        <<- /conf/ -2>> tant                                # Confusion. Écrivez « un tant soit peu ».
+
+    un [temps|tan|tans|tant] [soi|sois|soie|soies] peu
+        <<- /conf/ -3>> soit                                # Confusion. Écrivez « un tant soit peu ».
+
+    [après|avec] [temps|tan|tans] [de|d’]
+        <<- /conf/ -2>> tant                                # Confusion. Écrivez “tant” pour évoquer une quantité de quelque chose.|http://fr.wiktionary.org/wiki/tant
+
+    [à|a] [tan|tans|tant] [partiel|partiels|plein|pleins]
+        <<- /conf/ -2>> temps                               # Confusion. Pour ce qui est temporel, écrivez “temps”.
+
+    en [même|mêmes] [tant|tan|tans]
+        <<- /conf/ ->> en même temps                        # Confusion. Pour ce qui est temporel, écrivez “temps”.
+
+TEST: en {{tant}} de guerre, il faut savoir faire face et ne pas faiblir face à l’adversité.
+TEST: ils vont {{de tan en tan}} au restaurant
+TEST: un {{temps}} soit peu perdu dans cette affaire.
+TEST: après {{temps}} de souffrance, il faut savoir lâcher prise.
+TEST: il travaille à {{tant}} partiel
+TEST: {{en même tant}}, on s’en moque, de toutes ces histoires ennuyeuses.
+TEST: ce qui a commencé en 2011 en tant d’endroits du pourtour méditerranéen
+TEST: elle est allée en tant de lieux qu’il est difficile de suivre son trajet.
+
+
+# tout à coup
+__conf_tout_à_coup__
+    tout [a|ah|ha] [>cou|>coût|>cout|>coup]
+    [tout|toute|toutes] à [>cou|>coût|>cout]
+    [tout|toute|toutes] [a|ah|ha] [>cou|>coût|>cout|>coup]
+    [tout|toute|toutes] [a|ah|ha] coup
+        <<- ->> tout à coup                                         # Confusion.|https://fr.wiktionary.org/wiki/tout_%C3%A0_coup
+
+TEST: ils sont {{tout à cous}} figés
+TEST: Mais {{toute a cou}}, plus rien ne fonctionnait.
+TEST: Tout à coup, rien n’alla plus comme avant.
+
+
+# voix / voie / vois / voit
+__conf_voie_voix_vois_voit__
+    à haute [voie|vois|voit]
+    de vive [voie|vois|voit]
+        <<- /conf/ -3>> voix        # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    à [voie|vois|voit] [basse|haute]
+        <<- /conf/ -2>> voix        # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    sur la bonne voix
+        <<- /conf/ -4>> voie        # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    >ouvrir la voix [à|au|aux]
+        <<- /conf/ -3>> voie        # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    en voix [de|d’] [développement|disparition|guérison|résorption|acquisition|achèvement|extinction|obtention]
+    par voix de >conséquence
+        <<- /conf/ -2>> voie        # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    voix [abdominale|anale|biliaire|carrossable|communale|express|interdite|intramusculaire|intraveineuse|piétonne|principale|prioritaire|privée|publique|déserte|romaine|appienne|flaminienne|ferrée|ferroviaire|lactée|lacrymale|aérienne|maritime|fluviale|terrestre|navigable|détournée|déviée|buccale|digestive|urinaire|respiratoire|parallèle|administrative|diplomatique|gouvernementale|législative|hiérarchique|rectiligne|sinueuse|souterraine|urbaine]
+        <<- /conf/ -1>> voie        # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    voix [abdominales|anales|biliaires|carrossables|communales|expresss|interdites|intramusculaires|intraveineuses|piétonnes|principales|prioritaires|privées|publiques|désertes|romaines|appiennes|flaminiennes|ferrées|ferroviaires|lactées|lacrymales|aériennes|maritimes|fluviales|terrestres|navigables|détournées|déviées|buccales|digestives|urinaires|respiratoires|parallèles|administratives|diplomatiques|gouvernementales|législatives|hiérarchiques|rectilignes|sinueuses|souterraines|urbaines]
+        <<- /conf/ -1>> voies       # Confusion. La voix est un son humain, animal ou instrumental. Pour évoquer un chemin, écrivez “voie”.|http://fr.wiktionary.org/wiki/voie
+
+    >voix de [recours|perdition]
+        <<- -1>> voie|voies         # Confusion probable.|https://fr.wiktionary.org/wiki/voie
+
+TEST: sur la bonne {{voix}}
+TEST: ces patients sont en {{voix}} de guérison.
+TEST: il faut ouvrir la {{voix}} aux nouveaux venus.
+TEST: Je propse que, par {{voix}} de conséquence, nous partions immédiatement.
+TEST: C’est une {{voix}} interdite.
+
+
+# voir / voire
+__conf_voir_voire__
+    voir [grand|petit|rouge]
+        <<- ~2>> !
+
+    voir  @:A¬:[NGM]
+        <<- /conf/ not \2.istitle() and not morph(<1, ":O[os]|>(?:[ndmts]e|falloir|pouvoir|savoir|de)/")
+            and not before(r"(?i)\b[ndmts](?:e |’(?:en |y ))(?:pas |jamais |) *$")
+        -1>> voir                       # Confusion probable : “voir” est un verbe concernant la perception visuelle. Pour signifier “et même possiblement”, écrivez :|https://fr.wiktionary.org/wiki/voire
+
+    [comme|lorque|puisque|quand|que|quoique|si]     (voire)
+    [ni|et|par|pour|sans]                           (voire)
+    [>aller|>falloir|>pouvoir|>vouloir]  ?[guère|jamais|pas|plus|point|rien]¿  (voire)
+        <<- /conf/ -1>> voir            # Confusion probable : “voire” signifie “et même possiblement”. Pour le verbe, écrivez “voir”.|https://fr.wiktionary.org/wiki/voire
+
+TEST: Elles sont fatiguées, {{voir}} épuisées.
+TEST: Ce serait pour aider, ainsi que {{voire}} l’avancement du projet.
+TEST: il faut penser juste et {{voire}} vrai.
+TEST: Je ne vais jamais {{voire}} ces gens-là.
+TEST: Elles vont voir rouge en apprenant cet échec.
+TEST: Voir les enfants jouer ne me rend pas nostalgique.
+TEST: Il faut voir grand.
+TEST: Il sait voir grand.
+TEST: Il sait voir telle ou telle chose avec acuité.
+TEST: ça reste à voir
+TEST: Je veux le voir étonné par toutes ces merveilles.
+TEST: Les start-ups doivent aller vite, voir grand.
+TEST: de fortes chances de se voir ruiné
+TEST: Quelle chance tu as eue de voir ruiné ce connard.
+TEST: l’immobilier a été ces dernières années l’investissement le plus rentable (voir graphique ci-dessous)
+TEST: elles sont pas mal ainsi, voire élégantes pourrait-on dire.
+TEST: il y en a peu, voire très peu.
+TEST: car elles pénètrent dans les poumons voire le système sanguin.
+TEST: des enfants malades, qui préfèrent souvent voir Dark Vador que des vieux clowns un peu flippants.
+
+
+
+!!
+!!
+!!!! Verbes composés                                                                              !!
+!!
+!!
+
+#__verbes_composés_interrogatifs__
+#    ~-(?:je|tu|ils?|elles?)$
+#        <<- =>> define(\1, [":VCi"])
+#
+#__verbes_composés_impératifs__
+#    ~-(?:moi|toi|leur|en|y)$
+#        <<- =>> define(\1, [":VCe"])
+#
+#__verbes_composés_interrogatifs_et_impératifs__
+#    ~-[nv]ous$
+#        <<- =>> define(\1, [":VCi", ":VCe"])
+
+
+__rendez_vous__
+    ne [le|la|les] [lui|leur]   (rendez-vous)
+    ne me [le|la|les]           (rendez-vous)
+    ne [lui|leur] en            (rendez-vous)
+    ne [le|la|les|lui|leur]     (rendez-vous)
+    [me|ne|nous|vous|lui]       (rendez-vous)
+        <<- =>> define(\1, [":VCi1:2p"])
+        <<- ~1>> !
+
+#   [un|mon|ton|son|ce|mes|tes|ses|leurs] rendez-vous
+#   rendez-vous seulement défini comme :N:m:i
+
+
+
+
+!!
+!!
+!!!! Pronoms + incohérences                                                                       !!
+!!
+!!
+
+__m_enfin__
+    m’ enfin
+        <<- ~2>> !
+        <<- ~>> *
+
+
+__non_verbe_après_préverbes__
+    [ne|n’]     [le|la|l’|les]      [lui|leur|en|y]         @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)
+    [ne|n’]     [lui|leur]          en                      @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)
+        <<- /conf/ -4>> =suggSimil(\4, ":(?:[123][sp]|Y)", False)                                   # Incohérence avec « \1 \2 \3 » : « \4 » devrait être un verbe.
+
+    [ne|n’]     [le|la|l’|les|nous|vous|lui|leur]           @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)|>(?:pas|presque|jamais|rien|guère|point|plus)/
+    n’          [en|y]                                      @:[NAQ]¬:(?:[123][sp]|Y|W|P|Oo|X)|>(?:pas|presque|jamais|rien|guère|point|plus)/
+    [me|m’|te|t’|se|s’]   [le|la|l’|les|en|y]               @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)|>(?:pas|presque|jamais|rien|guère|point|plus)/
+        <<- /conf/ -3>> =suggSimil(\3, ":(?:[123][sp]|Y)", False)                                   # Incohérence avec « \1 \2 » : « \3 » devrait être un verbe.
+
+    [nous|vous]           [le|la|l’|les|en|y]               @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)|>(?:pas|presque|jamais|rien|guère|point|plus)/
+        <<- /conf/ not morph(<1, ":R|>de/") -3>> =suggSimil(\3, ":(?:[123][sp]|Y)", False)          # Incohérence avec « \1 \2 » : « \3 » devrait être un verbe.
+
+    [ne|n’]                                                 @:[NAQ]¬:(?:[123][sp]|Y|W|P|Oo|X)|>(?:[mtsl]|même|pas|presque|jamais|rien|guère|point|plus)/
+    [me|m’|te|t’|se]                                        @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)|>(?:l|pas|presque|jamais|rien|guère|point|plus)/
+    [s’]                                                    @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)|>ils?/
+        <<- /conf/ -2>> =suggSimil(\2, ":(?:[123][sp]|Y)", False)                                   # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+
+    [c’|ç’]                                                 @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)|>que?/
+        <<- /conf/ -2>> =suggSimil(\2, ":3s", False)                                                # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+
+    j’          [en|y]                                      @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)
+        <<- /conf/ -3>> =suggSimil(\3, ":1s", False)                                                # Incohérence avec « \1 \2 » : « \3 » devrait être un verbe.
+
+    j’                                                      @:[NAQ]¬:(?:[123][sp]|Y|P|Oo|X)
+        <<- /conf/ -2>> =suggSimil(\2, ":1s", False)                                                # Incohérence avec « \1 » : « \2 » devrait être un verbe.
+
+TEST: ne l’{{oubli}} pas
+TEST: elle ne la {{croix}} pas
+TEST: ils me les {{laissés}}.
+TEST: ne {{pensée}} rien, jamais
+TEST: n’en {{laissée}} que des miettes
+TEST: s’y {{intéressé}}
+TEST: Il ne {{travail}} pas le week-end.
+TEST: Je m’en {{fou}}.
+TEST: il m’{{arête}} encore une fois avec une impudence insupportable.
+TEST: J’y {{travail}}.
+TEST: ç’{{avé}} été dur.
+TEST: me {{pronostic}} un cancer dans les trois mois.
+TEST: t’{{appel}} l’autre gras, puis on y va.
+TEST: te {{mangé}}
+TEST: s’y {{accordez}}
+TEST: s’en {{approché}}
+TEST: m’y {{attaché}}
+TEST: je t’en {{parlé}}
+TEST: j’ai peur qu’il ne leur {{face}} quelque chose de mal
+TEST: M’enfin, c’est absurde
+TEST: il est normal de ne presque pas payer des gens qui effectuent un travail
+TEST: j’ai l’impression de ne même pas savoir ce qu’est un « juif français ».
+TEST: C’que j’comprends, c’est qu’il y a des limites à ce qu’on peut supporter.
+TEST: la tentation pour certains médias de ne tout simplement pas rémunérer notre travail si celui-ci n’est finalement pas publié.
+TEST: Ne parfois pas être celui qui sabote l’ambiance.
+TEST: il s’en va.
+TEST: C’en est trop !
+TEST: T’y viendras, comme tout le monde.
+TEST: Nous y voilà enfin.
+TEST: T’y voilà propulsé.
+TEST: t’en voilà débarrassée.
+TEST: N’oublient-ils pas ce qu’ils étaient autrefois…
+TEST: Ne presque jamais réussir un plat aussi simple, c’est de l’incompétence pure et simple.
+
+
+__loc_notre_père_qui_es_au_cieux__
+    notre père qui [es|est] aux cieux
+        <<- ~4>> !
+        <<- ~3:0>> *
+
+
+!!
+!!
+!!!! Formes verbales sans sujet                                                                   !!
+!!
+!!
+
+__tag_sujets__
+    [je|j’]
+    [moi|moi-même] qui
+    [moi|moi-même] [seul|seule]
+        <<- />> 1s
+
+    tu
+    t’  @:2s
+    t’  [en|y]  @:2s
+    [toi|toi-même] ?,¿ qui
+    [toi|toi-même] [seul|seule]
+        <<- />> 2s
+
+    nous
+    nous ?,¿ qui
+    nous-même
+    nous-mêmes
+    nous [seul|seuls|seules]
+    [et|ou] [moi|moi-même]
+    ni [moi|moi-même]
+    [moi|moi-même] et
+        <<- />> 1p
+
+    vous
+    vous ?,¿ qui
+    vous-même
+    vous-mêmes
+    vous [seul|seule|seuls|seules]
+    [et|ou] [toi|toi-même]
+    ni [toi|toi-même]
+    [toi|toi-même] et
+        <<- />> 2p
+
+
+__tag_prop_sub__
+    ce [que|qu’|qu]
+        <<- />> ce_que
+
+
+## Incohérences avec formes verbales 1sg et 2sg sans sujet
+
+__conj_xxxai__sans_sujet!3__
+    [se|s’]  ?[en|y|le|la|l’|les]¿  (~ai$)
+        <<- /conj/ morph(\1, ":1s", ":(?:G|W|M|J|3[sp])")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 1ʳᵉ personne du singulier. Sujet (“je” ou “moi qui”) introuvable.
+
+    [ne|n’]  ?[le|la|l’|les|en|me|m’|te|t’|nous|vous|lui|leur|y]¿  (~ai$)  ~¬[jJ]e
+        <<- /conj/ morph(\1, ":1s", ":(?:E|G|W|M|J|3[sp])") and not tag_before(\1, "1s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 1ʳᵉ personne du singulier. Sujet (“je” ou “moi qui”) introuvable.
+
+    [me|m’|te|t’|nous|vous]     ?[le|la|l’|les|en|y]¿   (~ai$)  ~¬[jJ]e
+    [le|la|l’|les]              [lui|leur|en|y]         (~ai$)  ~¬[jJ]e
+    [lui|leur]                  en                      (~ai$)  ~¬[jJ]e
+        <<- /conj/ morph(\1, ":1s", ":(?:E|G|W|M|J|3[sp])") and not tag_before(\1, "1s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 1ʳᵉ personne du singulier. Sujet (“je” ou “moi qui”) introuvable.
+
+    ~ai$  ~¬[jJ]e
+        <<- morph(\1, ":1s", ":(?:E|G|W|M|J|3[sp]|N|A|Q)") and not (\1.istitle() and before0(r"\w")) and not tag_before(\1, "1s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 1ʳᵉ personne du singulier. Sujet (“je” ou “moi qui”) introuvable.
+
+
+__conj_xxxas_xxxes__sans_sujet!3__
+    [se|s’]  ?[en|y|le|la|l’|les]¿  (~[ae]s$)
+        <<- /conj/ morph(\1, ":2s", ":(?:G|W|M|J|3[sp])")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 2ᵉ personne du singulier. Sujet (“tu” ou “toi qui”) introuvable.
+
+    [ne|n’]  ?[le|la|l’|les|en|me|m’|te|t’|nous|vous|lui|leur|y]¿  (~[ae]s$)  ~¬[tT]u
+        <<- /conj/ morph(\1, ":2s", ":(?:E|G|W|M|J|3[sp])") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 2ᵉ personne du singulier. Sujet (“tu” ou “toi qui”) introuvable.
+
+    [me|m’|te|t’|nous|vous]     ?[le|la|l’|les|en|y]¿   (~[ae]s$)  ~¬[tT]u
+    [le|la|l’|les]              [lui|leur|en|y]         (~[ae]s$)  ~¬[tT]u
+    [lui|leur]                  en                      (~[ae]s$)  ~¬[tT]u
+        <<- /conj/ morph(\1, ":2s", ":(?:E|G|W|M|J|3[sp])") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 2ᵉ personne du singulier. Sujet (“tu” ou “toi qui”) introuvable.
+
+    ~[ae]s$  ~¬[tT]u
+        <<- /conj/ morph(\1, ":2s", ":(?:E|G|W|M|J|3[sp]|N|A|Q|1p)") and not (\1.istitle() and before0(r"\w")) and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Ceci est un verbe à la 2ᵉ personne du singulier. Sujet (“tu” ou “toi qui”) introuvable.
+
+
+__conj_xxxxxs_sans_sujet!3__
+    [se|s’]  ?[en|y|le|la|l’|les]¿  (~[iudnrtpcï]s$)
+        <<- /conj/ morph(\1, ":[12]s", ":(?:G|W|M|J|3[sp]|2p|1p)")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    [ne|n’]  ?[le|la|l’|les|en|me|m’|te|t’|nous|vous|lui|leur|y]¿  (~[iudnrtpcï]s$)  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ morph(\1, ":[12]s", ":(?:E|G|W|M|J|3[sp]|2p|1p)")
+            and not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    [me|m’|te|t’|nous|vous]     ?[le|la|l’|les|en|y]¿   (~[iudnrtpcï]s$)  ~¬(?:[tT]u|[jJ]e)
+    [le|la|l’|les]              [lui|leur|en|y]         (~[iudnrtpcï]s$)  ~¬(?:[tT]u|[jJ]e)
+    [lui|leur]                  en                      (~[iudnrtpcï]s$)  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ morph(\1, ":[12]s", ":(?:E|G|W|M|J|3[sp]|2p|1p)")
+            and not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    étais  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ not (\1.istitle() and before0(r"\w")) and not morph(<1, ":[DA].*:p")
+            and not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    ~[iudnrtpcï]s$  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ morph(\1, ":[12]s", ":(?:E|G|W|M|J|3[sp]|2p|1p|V0e|N|A|Q)") and not (\1.istitle() and before0(r"\w"))
+            and not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+
+__conj_peux_veux_vaux_équivaux_prévaux_sans_sujet!3__
+    [se|s’]  ?[en|y|le|la|l’|les]¿  ([peux|veux|vaux|équivaux|prévaux])
+        <<- /conj/ -1>> =suggVerb(\1, ":3s")                                                        # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    [ne|n’]  ?[le|la|l’|les|en|me|m’|te|t’|nous|vous|lui|leur|y]¿  ([peux|veux|vaux|équivaux|prévaux])  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    [me|m’|te|t’|nous|vous]     ?[le|la|l’|les|en|y]¿   ([peux|veux|vaux|équivaux|prévaux])  ~¬(?:[tT]u|[jJ]e)
+    [le|la|l’|les]              [lui|leur|en|y]         ([peux|veux|vaux|équivaux|prévaux])  ~¬(?:[tT]u|[jJ]e)
+    [lui|leur]                  en                      ([peux|veux|vaux|équivaux|prévaux])  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    vaux  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ not (\1.istitle() and before0(r"\w")) and not tag_before(\1, "1s") and not tag_before(\1, "2s")
+            and not morph(<1, ":(?:R|D.*:p)")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+    [peux|veux|équivaux|prévaux]  ~¬(?:[tT]u|[jJ]e)
+        <<- /conj/ not (\1.istitle() and before0(r"\w")) and not tag_before(\1, "1s") and not tag_before(\1, "2s")
+        -1>> =suggVerb(\1, ":3s")                                                                   # Incohérence. Le sujet de cette forme verbale est introuvable.
+
+
+TEST: Caroline, quand l’heure viendra, {{décideras}} de la conduite à tenir.
+TEST: ceux-là, dans tous les cas de figure et dans tous les coups ratés, {{comprenais}} mal pourquoi on leur en voulait.
+TEST: Lui, quand il y pensait, en {{arrivai}} à chaque fois à la même conclusion.
+TEST: Elle, ici et dans tous les cas de figure, {{veux}} toujours en faire plus.
+TEST: Le total de cette opération, contrairement à ce qu’on pense, {{équivaux}} à au moins trois d’entre eux.
+TEST: {{j'}}ai signalé que {{j'}}essayais de regrouper les paragraphes. (Tests avec apostrophe droite.)
+TEST: je me questionne, {{exiges}} des réponses mais n’en obtiens pas…
+TEST: dans tous les cas de figure imaginés par cette bande de nuls, il n’y en a pas un qui les sauvera.
+TEST: ces gens qui vont par monts et par vaux.
+TEST: pour ne justement pas donner l’impression de s’être trompé.
+
+
+## Incohérences avec formes verbales 1pl et 2pl sans sujet
+__conj_xxxons_sans_sujet!3__
+    @:1p¬:[EGMNAJ]  ~¬[nN]ous
+        <<- /conj/ not (\1.istitle() and before0(r"\w")) and not tag_before(\1, "1p") -1>> =suggVerb(\1, ":3p")     # Ceci est un verbe à la 1ʳᵉ personne du pluriel. Sujet (“nous” ou équivalent) introuvable.
+
+__conj_xxxez_sans_sujet!3__
+    @:2p¬:[EGMNAJ]  ~¬[vV]ous
+        <<- /conj/ not (\1.istitle() and before0(r"\w")) and not tag_before(\2, "2p") -1>> =suggVerb(\1, ":3p")     # Ceci est un verbe à la 2ᵉ personne du pluriel. Sujet (“vous” ou équivalent) introuvable.
+
+TEST: les hommes et les femmes, qui sans un bruit, sans une parole amère, {{continuerons}} leur tâche n’en seront pas plus récompensés.
+TEST: il était dit que cette femme et son frère {{promènerez}} leur chien à cette heure de la journée.
+TEST: cet homme et cette femme {{pouvez}} y parvenir avec de la persévérance
+TEST: Comme on lui disait que vous-même aviez déjà consulté le notaire
+TEST: ce sont des terroristes et ça ne nous arrivera pas à nous, qui n’avons rien à nous reprocher
+TEST: mes supérieurs et moi-même avons pris la décision de ne pas vendre
+TEST: Ni lui ni moi n’avions mangé
+TEST: Mon épouse et moi-même avons toujours dit
+TEST: que vous ou moi ignorions à peu près tout du boson de Higgs n’a pas du tout le même sens
+
+
+
+!!
+!!
+!!!! Locutions invariables                                                                        !!
+!!
+!!
+
+__locutions_invariables__
+    [plus|moins|autant]  que  [prévue|prévus|prévues]
+        <<- /sgpl/ -3>> prévu                                                                       # Invariable. Implicitement, \1 que ce qui était prévu.
+
+    [plus|moins|aussi]  **  que  [prévue|prévus|prévues]
+        <<- /sgpl/ -4>> prévu                                                                       # Invariable. Implicitement, \1 \2 que ce qui était prévu.
+
+    [plus|moins|autant]  [de|d’]  **  que  [prévue|prévus|prévues]
+        <<- /sgpl/ -5>> prévu                                                                       # Invariable. Implicitement, \1 \2 \3 que ce qui était prévu.
+
+    comme [annoncés|annoncée|annoncées]
+        <<- /sgpl/ -2>> annoncé                                                                     # Invariable. Implicitement, comme ce qui était annoncé.
+
+    comme [convenus|convenue|convenues]
+        <<- /sgpl/ -2>> convenu                                                                     # Invariable. Implicitement, comme ce qui était convenu.
+
+    comme [prévue|prévus|prévues]
+        <<- /sgpl/ -2>> prévu                                                                       # Invariable. Implicitement, comme ce qui était prévu.
+
+
+TEST: il y en a autant que {{prévus}}.
+TEST: elles sont plus nombreuses plus que {{prévues}}
+TEST: il y a moins de bouffe que {{prévue}}
+TEST: comme {{annoncés}}, ils sont arrivés
+TEST: moins loin que {{prévus}}                               ->> prévu
+TEST: plus rapide que {{prévues}}                             ->> prévu
+TEST: autant d’hommes que {{prévus}}                          ->> prévu
+TEST: il y en a moins que {{prévues}}                         ->> prévu
+TEST: comme {{convenus}}                                      ->> convenu
+
+
+
+!!
+!!
+!!!! Tout, tous, toute, toutes                                                                    !!
+!!
+!!
+
+__purge_tout_tous_toutes__
+    [fais-les|fais-nous]                        [tous|toutes]
+    [faisons-les|faisons-nous|faisons-vous]     [tous|toutes]
+    [faites-les|faites-nous|faites-vous]        [tous|toutes]
+        <<- ~2>> *
+
+    [laisse-les|laisse-nous]                    [tous|toutes]
+    [laissons-les|laissons-nous|laissons-vous]  [tous|toutes]
+    [laissez-les|laissez-nous|laissez-vous]     [tous|toutes]
+        <<- ~2>> *
+
+    [les|des|mes|tes|ses|ces|nos|vos|leurs|aux]  tout  [débuts|petits]
+    [les|des|mes|tes|ses|ces|nos|vos|leurs|aux]  tout  @:A.*:[pi]
+        <<- ~2>> *
+
+
+__tout_det__
+    [<start>|,]  tout [deux|trois]
+        <<- /gn/ -2>> tous                                                                          # Locution pronominale : « tous deux ».|https://fr.wiktionary.org/wiki/tous_deux
+
+    tout [mes|tes|ses|ces|nos|vos|leurs|ceux|celles]
+        <<- /gn/ not morph(<1, ">(?:d[eu]|avant|après|malgré)/") -1>> tous                          # Erreur d’accord probable avec « \2 ».
+
+    tout les @:¬:(?:3s|Oo)
+        <<- /gn/ not morph(<1, ">(?:d[eu]|avant|après|malgré)/") -1>> tous                          # Erreur d’accord probable avec « les \3 ».
+
+TEST: {{Tout}} deux sont partis les premiers.
+TEST: {{Tout}} mes hommes sont venus.
+TEST: {{Tout}} les hommes sont dingues.
+TEST: Donne à manger à {{tout}} ceux qui sont là.
+TEST: Revenus de tout ceux qui sont partis ont perdu la foi.
+TEST: car malgré tout ceux qui persistent obtiennent parfois justice.
+TEST: je ne connais pas du tout ceux dont tu parles.
+TEST: Malgré tout ces hommes sont quand même revenus.
+TEST: Les tout premiers hommes.
+TEST: Les tout petits ne sont pas des légumes.
+
+
+__toute_det__
+    toute [celles|les|des|mes|tes|ses|ces]
+        <<- /gn/ -1>> toutes                                                                        # Erreur d’accord probable avec “\2”.
+
+    toute [ce|cet]
+        <<- /gn/ -1>> tout                                                                          # Erreur d’accord probable avec “\2”.
+
+    toute mon ~^[bcdfgjklmnpqrstvwxz]
+        <<- /gn/ -1>> tout                                                                          # Erreur d’accord probable avec “\2”.
+
+TEST: {{Toute}} celles qui viendront…
+TEST: et {{toute}} ce barouf ne nous a apporté que des ennuis.
+TEST: car {{toute}} mon savoir vient d’elle
+
+
+__tous_det_nom__
+    [<start>|,]     tous    [des|mes|tes|ses|ces]   @:[NA].*:f¬:[me]
+    [<start>|,]     tous    [les]                   @:[NA].*:f¬:(?:3p|[me])
+        <<- /gn/ -2>> toutes                                                                        # Erreur d’accord probable : « \4 » est féminin.
+        <<- /gn/ __also__ and hasFemForm(\4) -4>> =suggMasPlur(\4, True)                            # Erreur d’accord probable : « \2 » est masculin.
+
+    tous    [des|mes|tes|ses|ces]   @:[NA].*:f¬:[me]
+    tous    [les]                   @:[NA].*:f¬:(?:3p|[me])
+        <<- /gn/ morph(<1, ":", ":(?:R|[123][sp]|Q)|>(?:[nv]ous|eux)/") -1>> toutes                 # Erreur d’accord probable : « \3 » est féminin.
+        <<- /gn/ __also__ and hasFemForm(\3) -3>> =suggMasPlur(\3, True)                            # Erreur d’accord probable : « \1 » est masculin.
+
+TEST: {{tous}} ces {{idiotes}}
+TEST: indubitablement {{tous}} des {{privilégiées}}
+
+
+__toutes_det_nom__
+    [<start>|,]     toutes  [des|mes|tes|ses|ces]   @:[NA].*:m¬:[fe]
+    [<start>|,]     toutes  [les]                   @:[NA].*:m¬:(?:3p|[fe])
+        <<- /gn/ -2>> tous                                                                          # Erreur d’accord probable : « \4 » est masculin.
+        <<- /gn/ __also__ and hasFemForm(\4) -4>> =suggFemPlur(\4, True)                            # Erreur d’accord probable : « \2 » est féminin.
+
+    toutes  [des|mes|tes|ses|ces]   @:[NA].*:m¬:[fe]
+    toutes  [les]                   @:[NA].*:m¬:(?:3p|[fe])
+        <<- /gn/ morph(<1, ":", ":(?:R|[123][sp]|Q)|>(?:[nv]ous|eux)/") -1>> tous                   # Erreur d’accord probable : « \3 » est masculin.
+        <<- /gn/ __also__ and hasFemForm(\3) -3>> =suggFemPlur(\3, True)                            # Erreur d’accord probable : « \1 » est féminin.
+
+TEST: {{toutes}} mes {{bars}}
+TEST: vraiment {{toutes}} des {{costauds}}
+
+
+__tout_nom__
+    [<start>|,] tout  @:N.*:[fp]¬:(?:A|W|G|M|Y|[me]:[is]|3s)
+    de          tout  @:N.*:[fp]¬:(?:A|W|G|M|Y|[me]:[is]|3s)
+        <<- /gn/ -3>> =suggMasSing(\3, True)                                                        # Accord avec “tout” : “\3” devrait être au masculin singulier.
+
+    tout  @:N.*:[fp]¬:(?:A|W|G|M|Y|[me]:[is]|3s)
+        <<- /gn/ morph(<1, ":R", ":D.*:p") -2>> =suggMasSing(\2, True)                              # Accord avec “tout” : “\2” devrait être au masculin singulier.
+
+__toute_nom__
+    [<start>|,] toute  @:[NA].*:[mp]¬:(?:W|G|M|[fe]:[is])
+    de          toute  @:[NA].*:[mp]¬:(?:W|G|M|Y|[fe]:[is])
+        <<- /gn/ -3>> =suggFemSing(\3, True)                                                        # Accord avec “toute” : “\3” devrait être au féminin singulie
+
+    toute  @:[NA].*:[mp]¬:(?:W|G|M|Y|[fe]:[is])
+        <<- /gn/ morph(<1, ":R") -2>> =suggFemSing(\2, True)                                        # Accord avec “toute” : “\2” devrait être au féminin singulier.
+
+__tous_nom__
+    [<start>|,] tous  @:[NA].*:[fs]¬:(?:W|G|M|[me]:[ip])
+    de          tous  @:[NA].*:[fs]¬:(?:W|G|M|Y|[me]:[ip])
+        <<- /gn/ -3>> =suggMasPlur(\3, True)                                                        # Accord avec “tous” : “\3” devrait être au masculin pluriel.
+
+    tous  @:[NA].*:[fs]¬:(?:W|G|M|Y|[me]:[ip])
+        <<- /gn/ morph(<1, ":R") -2>> =suggMasPlur(\2, True)                                        # Accord avec “tous” : “\2” devrait être au masculin pluriel.
+
+__toutes_nom__
+    [<start>|,] toutes  @:[NA].*:[ms]¬:(?:W|G|M|[fe]:[ip])
+    de          toutes  @:[NA].*:[ms]¬:(?:W|G|M|Y|[fe]:[ip])
+        <<- /gn/ -3>> =suggFemPlur(\3, True)                                                        # Accord avec “toutes” : “\3” devrait être au féminin pluriel.
+
+    toutes  @:[NA].*:[ms]¬:(?:W|G|M|Y|[fe]:[ip])
+        <<- /gn/ morph(<1, ":R") -2>> =suggFemPlur(\2, True)                                        # Accord avec “toutes” : “\2” devrait être au féminin pluriel.
+
+TEST: Tout {{hommes}}
+TEST: De tous {{âge}} !
+TEST: avec toutes {{femme}}                                     ->> femmes
+TEST: sur toutes {{armure}}                                     ->> armures
+TEST: Toute {{époux}} doit faire preuve de bienveillance
+TEST: Il se souvient de toute mon histoire.
+TEST: Tout les sépare.
+TEST: les tout débuts du mouvement ouvrier
+TEST: vos tout débuts furent difficiles
+TEST: aux tout débuts, il y eut bien des erreurs
+TEST: comment les inégalités sociales impactent la santé des tout petits
+
+
+
+!!
+!!
+!!!! Adverbes de négation                                                                         !!
+!!
+!!
+
+__ne_manquant__
+    [<start>|,]  je             [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]     @:1s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]     @:2s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]     @:3s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]     @:1p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]     @:2p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    [le|la|l’|les|me|m’|te|t’|se|s’|nous|vous|lui|leur]     @:3p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+        <<- /neg/ -3>> ne \3                                                                        # Ne … \5 : il manque l’adverbe de négation.
+
+    [<start>|,]  [je|j’]        [en|y]                                                  @:1s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             [en|y]                                                  @:2s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   [en|y]                                                  @:3s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           [en|y]                                                  @:1p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           [en|y]                                                  @:2p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    [en|y]                                                  @:3p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+        <<- /neg/ -3>> n’\3                                                                         # Ne … \5 : il manque l’adverbe de négation.
+
+    [<start>|,]  je             [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]     @:1s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]     @:2s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]     @:3s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]     @:1p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]     @:2p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    [me|m’|te|t’|se|s’|nous|vous]   [le|la|l’|les|en|y]     @:3p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  je             [le|la|l’|les]                  [lui|leur|en|y]         @:1s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             [le|la|l’|les]                  [lui|leur|en|y]         @:2s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   [le|la|l’|les]                  [lui|leur|en|y]         @:3s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           [le|la|l’|les]                  [lui|leur|en|y]         @:1p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           [le|la|l’|les]                  [lui|leur|en|y]         @:2p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    [le|la|l’|les]                  [lui|leur|en|y]         @:3p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  je             [lui|leur]                      en                      @:1s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             [lui|leur]                      en                      @:2s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   [lui|leur]                      en                      @:3s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           [lui|leur]                      en                      @:1p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           [lui|leur]                      en                      @:2p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    [lui|leur]                      en                      @:3p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+        <<- /neg/ -3>> ne \3                                                                        # Ne … \6 : il manque l’adverbe de négation.
+
+    [<start>|,]  [je|j’]        @>[aeéiouœ].*:1s¬:(?:Oo|X)              [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             @>[aeéiouœ].*:2s¬:(?:Oo|X)              [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   @>[aeéiouœ].*:3s¬:(?:Oo|X)              [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           @>[aeéiouœ].*:1p¬:(?:Oo|X)              [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           @>[aeéiouœ].*:2p¬:(?:Oo|X)              [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    @>[aeéiouœ].*:3p¬:(?:Oo|X)              [pas|rien|jamais|guère|point]
+        <<- /neg/ -3>> n’\3                                                                         # Ne … \4 : il manque l’adverbe de négation.
+
+    [<start>|,]  je             @>[bcdfgjklmnpqrstvwxz].*:1s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  tu             @>[bcdfgjklmnpqrstvwxz].*:2s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [il|elle|on]   @>[bcdfgjklmnpqrstvwxz].*:3s¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  nous           @>[bcdfgjklmnpqrstvwxz].*:1p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  vous           @>[bcdfgjklmnpqrstvwxz].*:2p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+    [<start>|,]  [ils|elles]    @>[bcdfgjklmnpqrstvwxz].*:3p¬:(?:Oo|X)  [pas|rien|jamais|guère|point]
+        <<- /neg/ -3>> ne \3                                                                        # Ne … \4 : il manque l’adverbe de négation.
+
+TEST: __neg__ On {{a}} pas compris.
+TEST: __neg__ Il {{part}} pas encore.
+TEST: __neg__ On {{vous}} a pas compris.
+TEST: __neg__ On {{en}} a pas.
+TEST: __neg__ Il {{y}} a jamais d’eau.
+TEST: __neg__ je {{deviendrai}} pas hargneux.
+TEST: __neg__ il {{le}} lui donne pas souvent.
+
+
+!!
+!!
+!!!! Infinitif                                                                                    !!
+!!
+!!
+
+__infi_ne_pas_jamais_etc__
+    ne ?presque¿ [pas|rien|guère|point]                   ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] [trop|beaucoup]   ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] non plus          ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿       ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus]¿ non plus            ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿ ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère]¿ non plus      ?[le|la|l’|les|leur|lui|nous|vous|me|m’|te|t’|se|s’|en|y]¿  (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point]                   [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] [trop|beaucoup]   [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] non plus          [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿       [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus]¿ non plus            [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿ [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère]¿ non plus      [m’|t’|s’|nous|vous|les|lui|leur|l’]  [en|y]                (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point]                   [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] [trop|beaucoup]   [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] non plus          [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿       [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus]¿ non plus            [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿ [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère]¿ non plus      [me|te|nous|vous] [le|la|les]                               (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point]                   [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] [trop|beaucoup]   [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ [pas|rien|guère|point] non plus          [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿       [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ jamais ?[rien|plus]¿ non plus            [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿ [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+    ne ?presque¿ plus ?[jamais|rien|guère]¿ non plus      [le|la|les] [lui|leur]                                      (@:[VNA]¬:(?:Y|W|X|O[ow])|>que?/)
+        <<- /infi/ -1>> =suggVerbInfi(\1)                                                           # Après “ne pas”, “ne jamais”, “ne plus”, “ne rien”… le verbe devrait être à l’infinitif.
+
+    n’ [en|y] ?presque¿ [pas|rien|guère|point]                        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] [trop|beaucoup]        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] non plus               (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿            (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus]¿ non plus                 (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿      (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère]¿ non plus           (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point]                        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] [trop|beaucoup]        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] non plus               (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿            (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus]¿ non plus                 (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿      (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère]¿ non plus           (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point]                        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] [trop|beaucoup]        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] non plus               (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿            (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus]¿ non plus                 (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿      (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère]¿ non plus           (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point]                        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] [trop|beaucoup]        (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ [pas|rien|guère|point] non plus               (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus|trop|beaucoup]¿            (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ jamais ?[rien|plus]¿ non plus                 (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère|trop|beaucoup]¿      (@:[VNA]¬:(?:Y|W|X))
+    n’ [en|y] ?presque¿ plus ?[jamais|rien|guère]¿ non plus           (@:[VNA]¬:(?:Y|W|X))
+        <<- /infi/ -1>> =suggVerbInfi(\1)                                                           # Après “ne pas”, “ne jamais”, “ne plus”, “ne rien”… le verbe devrait être à l’infinitif.
+
+    ne [pas|jamais|plus|rien|guère|point] [beaucoup|trop]
+        <<- ~3>> *
+
+TEST: ne jamais les {{cédé}}
+TEST: ne point nous {{donné}}
+TEST: ne rien {{finit}}
+TEST: ne jamais plus s’y {{frottait}}
+TEST: ne presque jamais plus s’y {{frottaient}}
+TEST: ne plus guère y {{pensée}}
+TEST: ne pas les {{contrariés}}
+TEST: Ne rien m’en {{dit}}
+TEST: Ne jamais lui {{donnait}} sa chance.
+TEST: Ne jamais les leur {{montré}}
+TEST: Il a décidé de ne plus {{mangés}} avec nous.
+TEST: ne plus {{mangez}} fait maigrir
+TEST: ne plus {{mangées}} fait maigrir
+TEST: ne pas {{allé}}
+TEST: ne jamais plus me les {{montrés}}
+TEST: Ne jamais {{mangez}} de viande !
+TEST: J’espère ne pas te déranger
+TEST: Ne pas te le donner, ce serait une insulte.
+TEST: ne jamais vraiment évoquer le sujet
+TEST: déterminés à ne pas se laisser récupérer
+TEST: de ne pas en élire du tout
+TEST: Mais gare à ne pas non plus trop surestimer la menace
+TEST: ne jamais beaucoup bosser, c’est sa devise.
+
+
+__imp_ne_infinitif_negadv__
+    [<start>|,]  [ne|n’]  @:V1.*:Y  [pas|plus|jamais]
+        <<- /imp/ -3>> =suggVerbTense(\3, ":E", ":2p")                                              # Confusion probable : “\1” est un verbe à l’infinitif. Si vous vouliez utiliser l’impératif, écrivez :
+
+TEST: Non, ne {{manger}} pas ça.                                    ->> mangez
+TEST: Ne {{donner}} jamais à manger ces saloperies au chat.         ->> donnez
+
+
+
+!!!
+!!!
+!!! Processeur: épuration des adverbes, locutions adverbiales, interjections et expressions usuelles  !!
+!!!
+!!!
+
+__purge_dates__
+    depuis le           [1er|1ᵉʳ|~\d\d?]  {mois}    ?[dernier|prochain|~\d{2,5}]¿
+    [le|du|au]          [1er|1ᵉʳ|~\d\d?]  {mois}    ?[dernier|prochain|~\d{2,5}]¿
+    [jusqu’|jusqu]  au  [1er|1ᵉʳ|~\d\d?]  {mois}    ?[dernier|prochain|~\d{2,5}]¿
+    à  compter  du      [1er|1ᵉʳ|~\d\d?]  {mois}    ?[dernier|prochain|~\d{2,5}]¿
+    en  l’  an  ~\d{2,5}
+    en  l’  an  de  grâce  ~\d{2,5}
+    en  {mois}  ~\d{2,5}
+    [de|d’|D’]  {mois}  ~\d{2,5}
+    à  la  {mi_mois}    ?~\d{2,5}¿
+        <<- ~>> *
+
+    en  ~\d{2,5}  [,|<end>]
+    en  ~\d{2,5}  @:¬:[AN].*:[pi]
+    de  ~\d{2,5}  @:A.*:s
+        <<- ~1:2>> *
+
+TEST: ils sont depuis le 2 janvier {{parti}} à l’étranger.
+TEST: ils sont depuis le 2 janvier 2012 {{parti}} à l’étranger.
+
+
+__purge_saisons__
+    à  l’  [été|automne|hiver]  ~\d{2,4}
+    au  printemps  ~\d{2,4}
+        <<- ~>> *
+
+TEST: Une étude de 2005 publiée dans le Journal
+TEST: Les cinq variantes de la couverture du magazine Wired d’avril 2016 consacrée à Silicon Valley.
+TEST: c’est donc la cinquième en 50 ans
+
+
+__purge_un_nombre__
+    un  ~\d+  @:A.*:s¬:G
+        <<-  ~2>> *
+
+TEST: l’équipe veut aussi voir dans la lettre le nombre d’or, un symbole d’harmonie, ainsi qu’un 6 retourné.
+
+
+## moi/toi/lui/elle/nous/vous/eux/elles seul·e·s
+__purge_pronom_seul__
+    [moi|toi]       [seul|seule]
+    lui             seul
+    elle            seule
+    [nous|vous]     [seuls|seules]
+    eux             seuls
+    elles           seules
+        <<- ~1>> *
+
+
+__purge_début_phrase__
+    <start>  car
+    <start>  de plus
+    <start>  et  ?puis¿
+    <start>  mais
+    <start>  m’  est   avis  [que|qu’|qu]
+    <start>  or  donc
+    <start>  puis
+    [<start>|,] grand bien lui fasse
+        <<- ~2:0>> *
+
+
+__purge_horaires_et_durée__
+    24  [heures|h]  [sur|/]  24
+    7   [jours|j]   [sur|/]  7
+    sept [jours|j]  [sur|/]  sept
+    vingt-quatre  heures  [sur|/] vingt-quatre
+        <<- ~>> *
+
+    heure       après   heure
+    minute      après   minute
+    seconde     après   seconde
+    jour        après   jour
+    nuit        après   nuit
+    semaine     après   semaine
+    trimestre   après   trimestre
+    semestre    après   semestre
+    mois        après   mois
+    décennie    après   décennie
+    année       après   année
+    siècle      après   siècle
+    génération  après   génération
+        <<- ~>> *
+
+    [à|de]  ~\d\d?  h  ?~\d\d?¿
+    [à|de]  ~\d\d?  h  ?~\d\d?¿   [du|ce]  [matin|soir]
+    [à|de]  ~\d\d?  h  ?~\d\d?¿   de  l’ après-midi
+    [à|de]  ~\d\d?  h  ?~\d\d?¿   cet  après-midi
+    [à|de]  ~\d\d?  h  ?~\d\d?¿   demain  [matin|soir|après-midi]
+        <<- ~>> *
+
+TEST: Le train de 2 h 47 {{arriveraient}} en retard.
+TEST: Le train de 2 h 47 du matin {{arriveraient}} en retard.
+
+
+__purge_prépositions_qqn__
+    [après|avant|avec|pour|contre|sans|envers|chez|en|malgré|selon] les uns et les autres           [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:6>> *
+
+    [après|avant|avec|pour|contre|sans|envers|chez|d’|D’|malgré|selon] on ne sait [qui|quoi]        [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:5>> *
+
+    [après|avant|avec|pour|contre|sans|envers|chez|de|en|malgré|selon] tout un chacun               [<end>|,|@:[VXG]¬>qui]
+    [après|avant|avec|pour|contre|sans|envers|chez|de|en|malgré|selon] tout le monde                [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:4>> *
+
+    [après|avant|avec|pour|contre|sans|envers|chez|de|en|malgré] tout ça                            [<end>|,|@:[VXG]¬>qui]
+    [après|avant|avec|pour|contre|sans|envers|chez|de|en|malgré|selon] [vous|nous] autres           [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:3>> *
+
+    [après|avant|avec|pour|contre|sans|envers|chez|de|d’|D’|en|malgré|selon]  [autrui|quelqu’un|quelqu’une]     [<end>|,|@:[VXG]¬>qui]
+    [après|avant|avec|envers|chez|malgré|selon]                               {pronom_obj}                      [<end>|,|@:[VXG]¬>qui]
+    [contre|pour|sans|de|en]   [moi|toi|soi|elle|eux|elles|moi-même|toi-même|soi-même|lui-même|elle-même|nous-mêmes|vous-même|vous-mêmes|eux-mêmes|elles-mêmes]    [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:2>> *
+
+    par égard pour   [moi|toi|soi|elle|eux|elles|moi-même|toi-même|soi-même|lui-même|elle-même|nous-mêmes|vous-même|vous-mêmes|eux-mêmes|elles-mêmes]    [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:4>> *
+
+    en   [moi|toi|soi|elle|eux|elles|moi-même|toi-même|soi-même|lui-même|elle-même|nous-mêmes|vous-même|vous-mêmes|eux-mêmes|elles-mêmes]
+        <<- ~>> *
+
+    [après|avant|avec|pour|contre|sans|envers|chez|de|en|malgré|selon] [celui-ci|celui-là|celle-ci|celle-là|ceux-ci|ceux-là|celles-ci|celles-là]
+        <<- ~>> *
+
+    entre [moi|toi|lui|elle|elles|nous|vous|eux] et [moi|toi|lui|elle|elles|nous|vous|eux]
+    entre [nous|vous|eux|elles] [deux|trois|quatre|cinq|six|sept|huit|neuf|dix]
+        <<- ~>> *
+
+    ni   [après|avec|chez|contre|de|derrière|devant|envers|malgré|pour|sans|sous|sur] [moi|toi|lui|elle|elles|eux|nous|vous] ?,¿ ni [après|avec|chez|contre|de|derrière|devant|envers|malgré|pour|sans|sous|sur] [moi|toi|lui|elle|elles|eux|nous|vous]
+        <<- ~>> *
+
+    parmi [nous|vous] ?autres¿
+    parmi [eux|elles]
+        <<- ~>> *
+
+    par-devers [moi|toi|lui|elle|elles|lui|eux|nous|vous]
+        <<- ~>> *
+
+    quant à [moi|toi|lui|elle|elles|lui|eux|nous|vous]  [<end>|,|@:[VXG]¬>qui]
+        <<- ~1:3>> *
+
+TODO: comme
+
+
+__purge_locutions_latines__
+    [a|à]       [priori|postériori|posteriori|contrario|cappella|minima]
+        <<- ~>> *
+        <<- ~1>> !
+
+    ab          [absurdo|initio]
+    ad          [hoc|hominem|infinitum|nauseam|valorem|patres]
+    ad          vitam æternam
+    ex          [nihilo|cathedra|absurdo|abrupto]
+    id          est
+    in          [abstracto|extenso|extremis|fine|petto|situ|utero|vitro|vivo]
+    ipso        facto
+    mutatis     mutandis
+        <<- ~>> *
+
+
+__purge_locutions__
+    , [oui|non] ,
+    , entre autres ?choses¿ ,
+    à ~\d+(?:,\d+|)  %
+    à [autrui|bâbord|califourchon|chacun|confesse|contrecœur|contre-cœur|contretemps|demi-mot|foison|grand-peine|loisir|merveille|moitié|nouveau|outrance|peine|perpétuité|présent|raison|rallonge|rebrousse-poil|reculons|regret|renverse|risque|tâtons|tort|tribord|tout-va]
+    à aucun prix
+    à autre chose
+    à bas [cout|coût|prix]
+    à bâtons rompus
+    à beaucoup près
+    à belles dents
+    à bien des égards
+    à bien pire
+    à bon [compte|escient|droit]
+    à bout  de [bras|souffle|force|forces|nerf|nerfs]
+    à bout  [portant|touchant]
+    à bras ouverts
+    à bras le corps
+    à brève échéance
+    à but ?non¿ lucratif
+    à cause [de|d’]  [ça|moi|toi|lui|nous|vous|elle|elles|eux]
+    à ce [compte-là|moment-là|titre]
+    à cet égard
+    à cet instant ?[exact|précis]¿
+    à cette [date|occasion]
+    à cette époque
+    à cette époque de l’ année
+    à cette heure
+    à cette heure du jour
+    à cette heure de la [journée|nuit]
+    à cette heure [tardive|matinale]
+    à ciel ouvert
+    à chaque [fois|instant]
+    à chaudes larmes
+    à cœur [joie|ouvert|perdu]
+    à corps perdu
+    à côté  [de|d’]  [ça|moi|toi|lui|nous|vous|elle|elles|eux]
+    à couilles rabattues
+    à coup sûr
+    à couper le souffle
+    à court terme
+    à courte [échéance|portée]
+    à des kilomètres à la ronde
+    à défaut d’autre chose
+    à dose homéopathique
+    à durée limitée
+    à ~\d+ reprises
+    à @:B reprises
+    à [plusieurs|quelques|maintes] reprises
+    à de  [nombreuses|multiples]  reprises
+    à double [titre|tranchant]
+    à en juger par [mon|ton|son|notre|votre|leur] expérience
+    à en perdre haleine
+    à en perdre la tête
+    à faible  [allure|revenu]
+    à feu et à sang
+    à flanc de [colline|montagne]
+    à fleur de peau
+    à franchement parler
+    à géométrie variable
+    à grande échelle
+    à haut risque
+    à hue et à dia
+    à huis clos
+    à intervalles [irréguliers|réguliers]
+    à juste [raison|titre]
+    à l’ heure actuelle
+    à l’ heure [qu’|qu] il est
+    à l’ accoutumée
+    à l’ amiable
+    à l’ avance
+    à l’ avenir
+    à l’ avenir incertain
+    à l’ avenant
+    à l’ air libre
+    à l’ aveuglette
+    à l’ emporte-pièce
+    à l’ échelle [nationale|mondiale|régionale|départementale|cantonale|locale|galactique|universelle]
+    à l’ évidence
+    à l’ exclusion de toute autre chose
+    à l’ improviste
+    à l’ inverse
+    à l’ occasion
+    à l’ ordre du jour
+    à l’ œil nu
+    à l’ en croire
+    à l’ unanimité
+    à l’ un d’ entre eux
+    à l’ une d’ entre elles
+    à l’ [un|une] des leurs
+    à la  [bourre|con|dérive|dérobée|diable|fois|leur|longue|manque|mords-moi-le-nœud|papa|ramasse|renverse|redresse|rescousse|sauvette|volée]
+    à la  bonne franquette
+    à la  limite du supportable
+    à la  lumière de tout [ceci|cela|ça]
+    à la  petite semaine
+    à la  pointe du progrès
+    à la  première occasion
+    à la  queue leu leu
+    à la  surprise générale
+    à la  virgule près
+    à long terme
+    à longue [échéance|portée]
+    à longueur [de|d’] [temps|journée|année]
+    à loyer modéré
+    à main [armée|droite|gauche|levée]
+    à mains nues
+    à maints égards
+    à marche forcée
+    à merveille
+    à [midi|minuit]  ?pile¿
+    à [mi-course|mi-distance|mi-temps]
+    à moindres frais
+    à mots couverts
+    à moyen terme
+    à moyenne échéance
+    à [mes|tes|ses|nos|vos|leurs] [côtés|dépens|trousses]
+    à [mes|tes|ses|nos|vos|leurs] risques et périls
+    à [ma|ta|sa|notre|votre|leur] [connaissance|disposition|guise|portée]
+    à [ma|ta|sa|notre|votre|leur] grande [surprise|tristesse]
+    à [ma|ta|sa|notre|votre|leur] juste mesure
+    à [mon|ton|son|notre|votre|leur] [avis|détriment|encontre|égard|insu|sujet|tour]
+    à [mon|ton|son|notre|votre|leur] [cœur|corps] défendant
+    à [mon|ton|son|notre|votre|leur] grand [désarroi|soulagement]
+    à n’ en pas douter
+    à n’ en plus finir
+    à n’ en point douter
+    à parler franc
+    à part [entière|ça|cela|ceci]
+    à parts égales
+    à partir [de|d’]  [aujourd’hui|ici|là|maintenant|rien]
+    à partir [de|d’]  [demain|hier]  ?[matin|midi|soir]¿
+    à pas de [géant|loup|tortue|velours]
+    à personne en danger
+    à perte de vue
+    à petit feu
+    à petite [dose|échelle]
+    à peu de choses près
+    à peu de [distance|frais]
+    à peu près
+    à pieds joints
+    à pile ou face
+    à plat ventre
+    à plate couture
+    à plein [régime|temps|nez]
+    à pleins poumons
+    à plus forte raison
+    à plus d’un titre
+    à point nommé
+    à portée de [main|tir]
+    à première vue
+    à prix [cassé|modique|cassés|modiques]
+    à proprement parler
+    à qui de droit
+    à qui mieux mieux
+    à qui que ce soit
+    à quelque distance
+    à quelques [exceptions|nuances] près
+    à quelques-uns d’ entre [nous|vous|eux]
+    à quelques-unes d’ entre [nous|vous|elles]
+    à ras [bord|bords]
+    à rude épreuve
+    à s’ y méprendre
+    à somme nulle
+    à tel point
+    à temps  [plein|partiel|complet]
+    à tête reposée
+    à tire d’ [aile|ailes]
+    à [tire-d’aile|tire-d’ailes]
+    à titre  [conservatoire|expérimental|indicatif|informatif|grâcieux|personnel|posthume]
+    à titre  d’ exemple
+    à tombeau ouvert
+    à tort ou à raison
+    à tort et à travers
+    à tour de  [bras|rôle]
+    à tout [âge|crin|instant|jamais|moment|prix]
+    à tout bout de champ
+    à tout le [moins|monde]
+    à tout point de vue
+    à tout un chacun
+    à toute [allure|bride|épreuve|force|vitesse|volée]
+    à toute heure
+    à toute heure du jour
+    à toute heure du jour et de la nuit
+    à toute heure de la nuit
+    à toute heure de la nuit et du jour
+    à tous crins
+    à tous points de vue
+    à toutes fins utiles
+    à toutes jambes
+    à tu et à toi
+    à un moment donné
+    à une   heure  [décente|tardive]
+    à cette heure matinale
+    à usage interne
+    à visage découvert
+    à visage humain
+    à vive allure
+    à voix [haute|basse]
+    à vol d’ oiseau
+    à vrai dire
+    à vue d’ œil
+    à ?bien¿ y regarder de plus près
+    à ?bien¿ y [penser|réfléchir|songer|repenser]
+    advienne que pourra
+    ah
+    ailleurs
+    ainsi
+    alentour
+    alors
+    après [moi|toi|soi|lui|eux]
+    après cette date ?fatidique¿
+    après mûre réflexion
+    après tout ,
+    après un bon bout de temps
+    après un certain temps
+    au [dernier|même|bon|mauvais] [moment|instant]
+    au bas mot
+    au beau fixe
+    au bon moment
+    au bout du [compte|rouleau]
+    au bout d’ un moment
+    au cas par cas
+    au commencement
+    au contraire
+    au coude à coude
+    au coup par coup
+    au cours des @:B [dernières|derniers|prochaines|prochains] [années|mois|siècles] <<- ~>> *
+    au demeurant
+    au doigt mouillé
+    au débotté
+    au début
+    au fil des ans
+    au fil du temps
+    au fur et à mesure
+    au grand [complet|jamais]
+    au hasard
+    au jour et à l’ heure dits
+    au jugé
+    au le jour
+    au leur
+    au lieu de [cela|ceci|ça|quoi]
+    au loin
+    au milieu de nulle part
+    au moment opportun
+    au même titre que n’ importe [laquelle|lequel] d’ entre [nous|vous|eux|elles]
+    au pas de [charge|course]
+    au plus [près|pressé|vite|tôt|tard]
+    au plus haut point
+    au premier abord
+    au propre comme au figuré
+    au préalable
+    au quotidien
+    au ras des pâquerettes
+    au saut du lit
+    au sens [figuré|large|propre]
+    au surplus
+    au ~[xXvViI]+[eᵉ] siècle
+    au-delà du descriptible
+    au-dessus [de|d’] {pronom_obj}
+    aujourd’hui
+    auparavant
+    ?tout¿ au fond [de|d’] {pronom_obj}
+    aux [abois|leurs|mien|miens|mienne|miennes|tien|tiens|tienne|tiennes|sien|siens|sienne|siennes|nôtres|vôtres]
+    autant que [nécessaire|possible|prévu]
+    autant que faire se peut
+    autour [de|d’] {pronom_obj}
+    autrement dit
+    av. J.-C.
+    avant longtemps
+    avant terme
+    avant tout le monde
+    avant toute chose
+    avant toutes choses
+    avant d’ aller plus loin
+    avant J.-C.
+    avant Jésus-Christ
+    avant d’ en arriver là
+    avant de faire quoi que ce soit
+    avant de faire quoi que ce soit [de|d’] ?@:W¿ [stupide|crétin|con|idiot]
+    avant [qu’|qu] il ne soit trop tard
+    avant un bon bout de temps
+    avec [brio|joie|légèreté|insistance|peine]
+    avec autre chose
+    avec le plus grand soin
+    avec pertes et fracas
+    avec un peu de chance
+    avec tout le respect que je [vous|te|leur|lui] dois
+    avec tout le respect que nous [vous|te|leur|lui] devons
+    avec tout un chacun
+    avec un peu de chance
+    beaucoup [plus|moins]
+    bel et bien
+    bien assez tôt
+    bien des fois
+    bien souvent
+    bientôt
+    bon gré ?,¿ mal gré
+    bras dessus ?,¿ bras dessous
+    çà et là
+    ce faisant
+    cependant
+    [cela|ça|ceci] mis à part
+    [cela|ça|ceci] va sans dire
+    certes
+    ces derniers temps
+    cette [fois-là|fois-ci]
+    chaque fois
+    ci-dessous
+    ci-dessus
+    comme avant
+    comme autrefois
+    comme d’ habitude
+    comme toujours
+    comme de juste
+    comme bon [me|te|lui|leur|nous|vous] semble
+    comme au bon vieux temps
+    comme cul et chemise
+    comme [frappé|frappée|frappés|frappées] par la foudre
+    comme n’ importe où ?ailleurs¿
+    comme par [enchantement|magie]
+    comme par un fait exprès
+    comme promis
+    comme qui dirait
+    comme si de rien n’ était
+    contrairement aux apparences
+    contre mauvaise fortune ?,¿ bon cœur
+    contre nature
+    contre toute [attente|vraisemblance]
+    contre vents et marées
+    contre [mon|ton|son|notre|votre|leur] gré
+    côte à côte
+    [coute|coûte] que [coute|coûte]
+    [croyez-le|crois-le] ou [non|pas]
+    cul par-dessus tête
+    dans [ce|ces] [cas-là|cas-ci]
+    dans ce cas [précis|particulier]
+    dans ces cas [précis|particuliers]
+    dans l’ [idéal|immédiat]
+    dans la mesure du possible
+    dans les années ~\d\d+
+    dans peu de temps
+    dans tout [cela|ça|ceci]
+    dans très peu de temps
+    dans un cas comme dans l’autre
+    dans une [certaine|large|moindre] mesure
+    début {mois} ~\d\d{2,5}
+    au début {mois} ~\d\d{2,5}
+    en ce début {mois} ~\d\d{2,5}
+    d’ abord
+    d’ affilée
+    d’ ailleurs
+    d’ année en année
+    d’ aujourd’hui
+    d’ antan
+    d’ autant [plus|moins]
+    d’ [autrefois|part]
+    d’ autres fois
+    d’ [arrache-pied|arrachepied]
+    d’ arrière en avant
+    d’ avant en arrière
+    d’ à côté
+    d’ âge mûr
+    d’ emblée
+    d’ empoigne
+    d’ en face
+    d’ entre [nous|vous|eux|elles]
+    d’ entrée de jeu
+    d’ est en ouest
+    d’ extrême [droite|gauche]
+    d’ [extrême-droite|extrême-gauche]
+    d’ [égal|égale] à [égal|égale]
+    d’ habitude
+    d’ heure en heure
+    d’ hier ?[matin|soir|après-midi]¿
+    d’ ici ?[là|peu]¿
+    d’ ici peu de temps
+    d’ ordinaire
+    d’ origine [inconnue|douteuse|plébéienne|aristocratique]
+    d’ ordre général
+    d’ où [qu’|qu] [il|elle|on] vienne
+    d’ où [qu’|qu] [ils|elles] viennent
+    d’ ouest en est
+    d’ [ors|ores] et déjà
+    d’ un autre côté
+    d’ un [bout|jour] à l’ autre
+    d’ un côté comme de l’ autre
+    d’ un commun accord
+    d’ une autre trempe
+    d’ une [façon|manière] ou d’une autre
+    d’ une certaine [façon|manière]
+    d’ une tout autre ampleur
+    d’ une [minute|seconde] à l’ autre
+    de-ci ?,¿ de-là
+    de ~\d+(?:,\d+|) %
+    de [cesse|conserve|facto|fait|guingois|luxe|nouveau|permanence|partout|préférence|profundis|rechange|routine|surcroît|surcroit|visu]
+    de A à Z
+    de bas (?:en haut|étage)
+    de basse [condition|extraction]
+    de bon [aloi|cœur|gré|matin|sens|ton]
+    de bonne [facture|famille|foi|heure|humeur|grâce|qualité|compagnie]
+    de bric et de broc
+    de but en blanc
+    de ce fait ?[incontestable|irréfutable|même]¿
+    de ce seul fait
+    de ce point de vue
+    de cette sorte
+    de cet acabit
+    de courte [durée|vue]
+    de dernière minute
+    de demain [matin|soir|après-midi]
+    de droite à gauche
+    de droite comme de gauche
+    de fâcheuse mémoise
+    de fil en aiguille
+    de fond en comble
+    de fort [loin|près]
+    de [fraîche|fraiche] date
+    de [gaieté|gaîté|gaité] de cœur
+    de gauche à droite
+    de gauche comme de droite
+    de grande [taille|envergure]
+    de gré ou de force
+    de guerre lasse
+    de haut en bas
+    de haut [rang|vol]
+    de haute [lutte|stature|volée]
+    de jour comme de nuit
+    de là-bas
+    de la meilleure [manière|façon] possible
+    de la même [façon|manière]
+    de la sorte
+    de la tête aux pieds
+    de la veille
+    de loin
+    de loin en loin
+    de longue [date|durée|haleine]
+    de main de [maître|maitre]
+    de mauvais [aloi|goût|gout|gré]
+    de mauvaise [foi|grâce|humeur]
+    de mieux en mieux
+    de nature [étrangère|inconnue|indéterminée|insolite]
+    de nombreuses années plus [tôt|tard]
+    de nombreuses fois
+    de nos jours
+    de notoriété publique
+    de nulle part
+    de pire en pire
+    de près
+    de près ou de loin
+    de par le monde ?entier¿
+    de part et d’autre
+    de petite taille
+    de pied ferme
+    de plein [droit|fouet]
+    de plus [belle|près]
+    de premier [ordre|plan]
+    de première [catégorie|main|nécessité]
+    de prime abord
+    de proche en proche
+    de pure forme
+    de sang-froid
+    de seconde [catégorie|zone|importance|main]
+    de si bon matin
+    de si bonne heure
+    de source sûre
+    de taille moyenne
+    de telle sorte
+    de temps à autre
+    de temps en temps
+    de [très|trop] [loin|près]
+    de vive voix
+    de [nous|vous] tous
+    de tous [côtés|bords]
+    de tout [poil|temps]
+    de tout à l’ heure
+    de tout premier [ordre|plan]
+    de toute [éternité|évidence|façon|urgence]
+    de toutes [parts|pièces|sortes]
+    de toutes [mes|tes|ses|nos|vos|leurs] forces
+    de [mon|ton|son|notre|votre|leur] mieux
+    de [mon|ton|son|notre|votre|leur] plein gré
+    de [mon|ton|son|notre|votre|leur] point de vue
+    de [mon|ton|son|notre|votre|leur] propre [cru|chef]
+    de [mon|ton|son|notre|votre|leur] vivant
+    de [ma|ta|sa|notre|votre|leur] part
+    de moins en moins
+    de plus en plus
+    de mieux en mieux
+    de pire en pire
+    de jour en jour
+    de minute en minute
+    de semaine en semaine
+    de mois en mois
+    de trimestre en trimestre
+    de semestre en semestre
+    de siècle en siècle
+    de millénaire en millénaire
+    de décennie en décennie
+    [demain|après-demain] ?[matin|soir|après-midi]¿
+    avant demain ?[matin|soir|après-midi]¿
+    debout
+    derechef
+    donc
+    dorénavant
+    déjà
+    désormais
+    depuis @:B [ans|années|mois|semaines|jours|heures|minutes|secondes]
+    depuis ~\d+ [ans|années|mois|semaines|jours|heures|minutes|secondes]
+    depuis assez longtemps
+    depuis belle lurette
+    depuis bien longtemps
+    depuis de ?très¿ longues années
+    depuis des lustres
+    depuis les années ~\d\d+
+    depuis longtemps
+    depuis lors
+    depuis peu de temps
+    depuis quelque temps
+    depuis quelques [secondes|minutes|heures|jours|semaines|mois|trimestres|semestres|années|décennies|siècles|millénaires]
+    depuis si longtemps
+    depuis toujours
+    depuis tout ce temps
+    depuis très longtemps
+    des fois
+    des pieds à la tête
+    des uns et des autres
+    des [années|mois|siècles|millénaires|décennies|semaines] plus [tôt|tard]
+    dès [maintenant|lors|aujourd’hui]
+    dès à présent
+    dès que possible
+    dès [demain|hier] ?[soir|matin|après-midi]¿
+    Dieu [m’|t’|l’|nous|vous|les] en [garde|préserve]
+    Dieu [m’|t’|lui|nous|vous|leur] en soit témoin
+    du ~[xXvViI]+[eᵉ] siècle
+    du [Ier|Iᵉʳ|1er|1ᵉʳ] siècle
+    du bout des lèvres
+    du début à la fin
+    du fond du cœur
+    du jour au lendemain
+    du haut en bas
+    du même [acabit|coup|ordre|tonneau]
+    du moins ?,¿ pas
+    du [nord|sud] au [nord|sud]
+    du tout au tout
+    eh bien
+    en \d\d+ [ans|années|mois|semaines|jours|heures|minutes|secondes]
+    en [aparté|apparence|arrière|avance|avant|cachette|ceci|cela|clair|commun|conséquence|continu|contrepartie|définitive|détail|direct|douce|effet|émoi|filigrane|général|goguette|hâte|majorité|outre|pâmoison|parallèle|partie|particulier|permanence|personne|pratique|prime|privé|principe|priorité|public|réalité|retour|revanche|rien|rogne|route|secret|silence|somme|suspens|théorie|trompe-l’œil|vain|vérité|ville|vitesse]
+    en aucun cas
+    en aucune [circonstance|façon|manière]
+    en bon état
+    en bonne [compagnie|posture|voie]
+    en bonne et due forme|
+    en bonne santé ?[physique|mentale|psychique]¿
+    en bout de course
+    en cas [de|d’] [besoin|doute|urgence]
+    en [chacun|chacune] [de|d’] [nous|vous|eux|elles]
+    en chair et en os
+    en chute libre
+    en comparution immédiate
+    en connaissance de cause
+    en coupe réglée
+    en cours de route
+    en d’autres [circonstances|termes|temps]
+    en de telles circonstances
+    en début [de|d’] [journée|matinée|soirée|après-midi]
+    en définitive
+    en dehors de ?tout¿ [ça|cela|ceci]
+    en dents de scie
+    en dernier [lieu|recours|ressort]
+    en désespoir de cause
+    en détention provisoire
+    en direction de l’ [est|ouest]
+    en direction du [nord|nord-est|nord-ouest|sud|sud-est|sud-ouest]
+    en état de choc ?circulatoire¿
+    en état de marche
+    en état d’ ébriété ?avancée¿
+    en excellent état
+    en file indienne
+    en fin [de|d’] [compte|journée|matinée|soirée|après-midi]
+    en forte [baisse|hausse]
+    en gage de bonne foi
+    en garde à vue ?prolongée¿
+    en grand nombre
+    en grende [difficulté|majorité|partie|pompe]
+    en haut lieu
+    en l’occurrence
+    en lieu sûr
+    en ligne de [compte|mire]
+    en mains propres
+    en mauvais état
+    en mauvaise [posture|santé]
+    en même temps
+    en milieu [de|d’] [journée|matinée|soirée|après-midi]
+    en nombre suffisant
+    en nombre plus que suffisant
+    en partant de zéro
+    en plein [air|cœur|jour]
+    en pleine [gueule|figure|forme|poire|nuit|tronche]
+    en perte de vitesse
+    en peu de temps
+    en piteux état
+    en point [de|d’] [mire|orgue]
+    en position de [force|faiblesse]
+    en premier lieu
+    en première [instance|ligne]
+    en pure perte
+    en quantité suffisante
+    en quantité plus que suffisante
+    en quelque sorte
+    en queue de peloton
+    en rangs serrés
+    en rase campagne
+    en règle générale
+    en roue libre
+    en sens inverse
+    en si peu de temps
+    en sous-main
+    en tête à tête
+    en temps et en heure
+    en temps [normal|opportun|ordinaire|utile|voulu]
+    en termes choisis
+    en toile de fond
+    en tous les cas
+    en tous les sens
+    en tout bien tout honneur
+    en tout [cas|genre|lieu|sens|temps]
+    en tout et pour tout
+    en tout état de cause
+    en tout premier lieu
+    en toute bonne foi
+    en toute connaissance de cause
+    en toute [circonstance|confiance|discrétion|franchise|hâte|impartialité|impunité|innocence|légalité|liberté|logique|sécurité|simplicité]
+    en toutes circonstances
+    en un clin d’œil
+    en un rien de temps
+    en une autre occasion
+    en vase clos
+    en voie de développement
+    en y réfléchissant bien
+    en [janvier|février|mars|avril|mai|juin|juillet|août|aout|septembre|octobre|novembre|décembre] dernier
+    en [mon|ton|son|leur|notre|votre] âme et conscience
+    en [mon|ton|son|leur|notre|votre] for intérieur
+    en [mon|ton|son|leur|notre|votre] nom propre
+    en ce [moment|temps-là]
+    en ce qui [me|te|le|la|les|nous|vous] [concerne|concernait]
+    en cet instant
+    encore
+    encore une fois
+    encore et [encore|toujours]
+    enfin
+    entre {mois} ?~\d{2,5}¿ et {mois} ?~\d{2,5}¿
+    entre chien et loup
+    entre de [bonnes|mauvaises] mains
+    entre l’ [un|une] et l’ autre
+    entre les uns et les autres
+    entre [quatre|quatr’|quat’] [zyeux|yeux]
+    entre [quatre-zyeux|quatr’zyeux|quat’zyeux|quatre-yeux|quatr’yeux|quat’yeux]
+    ensuite
+    envers et contre tout
+    épaule contre épaule
+    et   ainsi de suite
+    et   tutti quanti
+    été comme hiver
+    euh
+    face à face
+    @:B fois de suite
+    grosso modo
+    guère
+    [hier|avant-hier] ?[matin|soir|après-midi]¿
+    hors [de|d’] [contrôle|portée|atteinte]
+    hors d’ état de nuire
+    hors du commun
+    ici
+    ici [comme|ou] ailleurs
+    ici et [là|maintenant]
+    ici même
+    ici-bas
+    il y a ?très¿ longtemps
+    il y a ?très¿ peu de temps
+    il y a quelques [secondes|minutes|heures|jours|semaines|mois|année|ans|siècles|millénaires]
+    il y a moins de ~\d+ [secondes|minutes|heures|jours|semaines|mois|année|ans|siècles|millénaires]
+    il y a ~\d+ [secondes|minutes|heures|jours|semaines|mois|année|ans|siècles|millénaires]
+    il y a quelque temps
+    il n’y a pas ?si¿ longtemps
+    illico ?presto¿
+    jadis
+    j’ en passe et des [meilleurs|meilleures]
+    jour pour jour
+    [jusqu’|jusqu] [alors|ici|aujourd’hui|Noël|Pâques]
+    [jusqu’|jusqu] au bout des ongles
+    [jusqu’|jusqu] au nouvel an
+    [jusqu’|jusqu] à aujourd’hui
+    [jusqu’|jusqu] à bac
+    [jusqu’|jusqu] à présent
+    [jusqu’|jusqu] à maintenant
+    [jusqu’|jusqu] à récemment
+    [jusqu’|jusqu] à [demain|hier] ?[matin|soir|après-midi]¿
+    [jusqu’|jusqu] à nouvel ordre
+    [jusqu’|jusqu] à plus ample informé
+    [jusqu’|jusqu] à plus soif
+    [jusqu’|jusqu] à preuve du contraire
+    [jusqu’|jusqu] à la fin de [mes|tes|ses|nos|vos|leurs] jours
+    [jusqu’|jusqu] à la fin des temps
+    [jusqu’|jusqu] à la tombée de la nuit
+    [jusqu’|jusqu] à [mon|ton|son|notre|votre|leur] dernier souffle
+    [jusqu’|jusqu] à [mon|ton|son|notre|votre|leur] dernier souffle de vie
+    [jusqu’|jusqu] à ce que mort s’ensuive
+    [jusqu’|jusqu] à ce que [j’|il|elle|on] en sache plus
+    [jusqu’|jusqu] à ce que tu en saches plus
+    [jusqu’|jusqu] à ce que nous en sachions plus
+    [jusqu’|jusqu] à ce que vous en sachiez plus
+    [jusqu’|jusqu] à ce que [ils|elles] en sachent plus
+    jusque-là
+    la plupart du temps
+    la main dans la main
+    là-bas
+    là-haut
+    là-dedans
+    là-dehors
+    là-derrière
+    là-dessous
+    là-dessus
+    là-devant
+    là non plus
+    la mort dans l’ âme
+    le cas échéant
+    le moins du monde
+    le [moins|plus] [tôt|tard|souvent]
+    le [moins|plus] de [temps|monde] possible
+    le moment venu
+    les [uns|unes] des autres
+    les [uns|unes] [après|avec|chez|contre|de|derrière|devant|envers|malgré|pour|sans|sous|sur] les autres
+    l’ [un|une] [après|avec|chez|contre|de|derrière|devant|envers|malgré|pour|sans|sous|sur] l’ autre
+    l’ [un|une] près de l’autre
+    loin
+    loin [de|d’] là
+    loin [de|d’] tout [ça|cela|ceci]
+    loin d’ [être|ici]
+    loin s’ en [faut|fallait]
+    longtemps
+    [bien|si|assez] longtemps
+    maintes fois
+    malgré [ça|cela|ceci|tout]
+    manu militari
+    mieux [vaut|valait] tard que jamais
+    moins que [nécessaire|prévu]
+    moitié ** ?,¿ moitié **
+    mot pour mot
+    mouais
+    naguère
+    ne [lui|leur|m’|t’|nous|vous] en déplaise
+    néanmoins
+    nez à nez
+    non loin [de|d’] [ici|là]
+    nulle part
+    ô combien
+    oh
+    ou quelque chose d’ approchant
+    où bon [me|te|lui|nous|vous|leur] semble
+    oui [ou|et] non
+    outre mesure
+    ni de près ?,¿ ni de loin
+    ni plus ?,¿ ni moins
+    ni vu ?,¿ ni connu
+    non [plus|seulement]
+    non sans raison
+    quant à présent
+    par [à-coups|ailleurs|avance|chance|conséquent|curiosité|contre|défaut|définition|endroits|essence|excellence|exemple|hasard|ici|inadvertance|là|moments|nature|principe|terre]
+    par acquit de conscience
+    par beau temps
+    par bien des [aspects|côtés]
+    par bonté de cœur
+    par ce biais
+    par certains [aspects|côtés]
+    par la même occasion
+    par la suite
+    par le passé
+    par les temps qui courent
+    par monts et par vaux
+    par temps de pluie
+    par tout le monde
+    par voie de [conséquence|mer|terre]
+    par voie d’exception
+    par @:B fois
+    un par un
+    une par une
+    deux par deux
+    trois par trois
+    quatre par quatre
+    cinq par cinq
+    six par six
+    sept par sept
+    huit par huit
+    neuf par neuf
+    dix par dix
+    onze par onze
+    douze par douze
+    treize par treize
+    quatorze par quatorze
+    quinze par quinze
+    seize par seize
+    vingt par vingt
+    trente par trente
+    quarante par quarante
+    cinquante par cinquante
+    soixante par soixante
+    cent par cent
+    mille par mille
+    bout par bout
+    étage par étage
+    étape par étape
+    fragment par fragment
+    morceau par morceau
+    niveau par niveau
+    pièce par pièce
+    par-ci ?,¿ par-là
+    par-derrière
+    par-dessus le marché
+    par-dessus tout
+    par-devant
+    parfois
+    partant de là
+    partout
+    pas du tout
+    pas le moins du monde
+    pas à pas
+    pendant ?[bien|si|assez|très]¿ longtemps
+    pendant ce temps-là
+    pendant plusieurs [heures|minutes|secondes|mois|semaines|jours|années|siècles|millénaires|décennies]
+    pendant quelque temps
+    petit à petit
+    peu de temps auparavant
+    peu ou prou
+    peu à peu
+    peut-être
+    pile poil
+    plein [nord|sud|ouest]
+    plein de fois
+    plus [près|loin|tôt|tard]
+    plus [près|loin|tôt|tard] que [prévu|nécessaire]
+    plus bas que terre
+    plus du tout
+    plus d’ une fois
+    plus jamais
+    plus ou moins
+    plus que [nécessaire|prévu|jamais]
+    plus que tout au monde
+    plus que toute autre chose
+    plusieurs fois
+    plusieurs fois de suite
+    plutôt
+    pour [celui|celle|ceux|celles] et [celui|celle|ceux|celles] que [ça|cela|ceci] intéresse
+    pour [celui|celle|ceux|celles] que [ça|cela|ceci] intéresse
+    pour [ma|ta|sa|notre|votre|leur] [gouverne|part]
+    pour [mon|ton|son|notre|votre|leur] propre [compte|bien]
+    pour [m’|t’|s’|nous|vous] en rendre compte
+    pour ainsi dire
+    pour ce faire
+    pour ce que [j’|tu] en [sais|savais]
+    pour couronner le tout
+    pour de bon
+    pour faire bonne mesure
+    pour faire simple
+    pour la [première|seconde|dernière|~ième$] fois
+    pour la [première|seconde|dernière|~ième$] fois de ma vie
+    pour la [première|seconde|dernière|~ième$] fois de suite
+    pour la suite
+    pour le [moment|moins]
+    pour le meilleur et pour le pire
+    pour l’ [essentiel|instant|heure]
+    pour quelque [part|temps]
+    pour rien au monde
+    pour tout dire
+    pour un oui ou pour un non
+    pour une fois
+    pour y parvenir
+    pour ça [vaut|valait]
+    pourtant
+    presque
+    primo
+    quand bien même
+    quand bon [me|te|lui|nous|vous|leur] [semble|semblera|semblait]
+    quant à [ça|cela|ceci]
+    que [ça|ceci|cela] [me|te|lui|leur|nous|vous] plaise ou non
+    que je le veuille ou non
+    que tu le veuilles ou non
+    [qu’|qu] [il|elle|on] le veuille ou non
+    que vous le vouliez ou non
+    que nous le voulions ou non
+    [qu’|qu] [ils|elles] le veuillent ou non
+    [qu’|qu] à cela ne tienne
+    quel [qu’|qu] en soit le [moyen|prix|danger]
+    quel [qu’|qu] en soit le risque ?financier¿
+    quelle [qu’|qu] en soit la [cause|raison]
+    quelque [part|temps]
+    quelquefois
+    quelques fois
+    quelques [instants|secondes|minutes|heures|jours|semaines|mois|années|décennies|siècles|millénaires|trimestres|semestres] auparavant
+    quelques [instants|secondes|minutes|heures|jours|semaines|mois|années|décennies|siècles|millénaires|trimestres|semestres] plus [tard|tôt]
+    qui plus est
+    quoi [qu’|qu] il [arrive|arrivât|advienne|advînt]
+    quoi [qu’|qu] il en [coûte|coûtât|coute|coutât]
+    sans ?grand¿ succès
+    sans [ambages|arrêt|cesse|conteste|doute|encombre|encombres|fin|relâche|répit|trêve|vergogne]
+    sans [grande|grosse] difficulté ?[apparente|aucune|financière|majeure|particulière]¿
+    sans aucun doute
+    sans autre forme de procès
+    sans commune mesure
+    sans coup férir
+    sans crier gare
+    sans difficulté ?[apparente|aucune|financière|majeure|particulière]¿
+    sans dire mot
+    sans faire de vagues
+    sans foi ?,¿ ni loi
+    sans le faire exprès
+    sans le vouloir
+    sans l’ aide de personne
+    sans l’ ombre d’ un doute
+    sans mot dire
+    sans nul doute
+    sans pour autant y [parvenir|réussir|réfléchir|songer|penser]
+    sans pour autant y faire attention
+    sans pour autant y prendre [garde|goût|gout]
+    sans queue ni tête
+    sans raison apparente
+    sans s’ en apercevoir
+    sans s’ en rendre compte
+    sans y [parvenir|réussir|réfléchir|songer|penser]
+    sans y faire attention
+    sans y prendre [garde|goût|gout]
+    sans états d’ âme
+    secondo
+    selon toute vraisemblance
+    semblait-il
+    semble-t-il
+    sens dessus dessous
+    [seule|seul] à [seule|seul]
+    si [bas|haut|longtemps|nécessaire|possible|soudain]
+    si [cela|ça|ceci] ne tenait [qu’|qu] à [moi|toi|lui|eux|elle|elles|nous|vous]
+    si besoin est
+    sine die
+    sine qua non
+    six pieds sous terre
+    soi-disant
+    soit dit en passant
+    soudain
+    sous aucun prétexte
+    sous bonne [escorte|garde]
+    sous coupe réglée
+    sous haute surveillance
+    souvent
+    stricto sensu
+    sur [mon|ton|son|notre|votre|leur] [trente-et-un|31]
+    sur [mon|ton|son|notre|votre|leur] trente et un
+    sur ce ,
+    sur ce plan-là
+    sur la forme comme sur le fond
+    sur la même longueur d’ onde
+    sur le [long|moyen|court] terme
+    sur le qui-vive
+    sur-le-champ
+    surtout
+    séance tenante
+    s’ il [te|vous] [plaît|plait]
+    tant bien que mal
+    tant s’ en faut
+    tantôt
+    tard
+    tertio
+    toujours
+    tous comptes faits
+    tous frais payés
+    tout [bonnement|simplement]
+    tout au plus
+    tout aussi bien
+    tout bien [considéré|réfléchi]
+    tout compte fait
+    tout de [même|suite|go]
+    tout du long
+    tout feu ?,¿ tout [flamme|flammes]
+    tout le temps
+    tout à [fait|coup]
+    tout à l’ heure
+    toutefois
+    toutes affaires cessantes
+    toutes choses égales par ailleurs
+    toutes griffes dehors
+    toutes proportions gardées
+    trait pour trait
+    très ?[bas|haut|bien|mal]¿
+    tôt
+    tôt ou tard
+    un à un
+    une à une
+    un jour ou l’autre
+    un instant plus [tôt|tard]
+    un [millier|million|milliard] de fois
+    un moment plus [tôt|tard]
+    un peu mieux
+    un peu moins bien
+    un peu partout
+    un peu plus [tôt|tard] que prévu
+    un tant soit peu
+    une à une
+    une autre fois
+    une bonne fois pour toutes
+    une dernière fois
+    une fois de plus
+    une fois n’ est pas coutume
+    une fois pour toutes
+    urbi et orbi
+    vaille que vaille
+    ventre à terre
+    vers nulle part
+    vite
+    volontiers
+        <<- ~>> *
+
+
+__gestion_mots_grammaticaux__
+    à [bord|cause|contre-courant|côté|court|défaut|droite|gauche|hauteur|partir|portée|proximité|propos|rebours] [de|des|du]
+        <<- ~2>> *
+
+    à bonne distance [de|des|du]
+    à l’ [affût|affut|arrière|autre bout|aune|avant|écart|égard|extérieur|encontre|insu|instar|intérieur|opposé|orée|approche] [de|des|du]
+    à la [hauteur|portée|suite] [de|des|du]
+        <<- ~2:3>> *
+
+    à l’ autre bout [de|des|du]
+        <<- ~2:4>> *
+
+    à [quelques|plusieurs] [mètres|kilomètres|lieues|pas|minutes|heures] [de|des|du]
+        <<- ~2:3>> *
+
+    à [quelques|plusieurs] [dizaines|centaines|milliers] de [mètres|kilomètres] [de|des|du]
+        <<- ~2:5>> *
+
+    à [base|force|raison] [de|d’]
+        <<- ~2>> *
+
+    à grand renfort     [de|d’]
+    à grands coups      [de|d’]
+        <<- ~2:3>> *
+
+    au [bout|courant|cours|détriment|gré|lieu|long|large|milieu|profit|sein|sortir|sujet|vu] [de|des|du]
+        <<- ~2>> *
+
+    au beau milieu      [de|des|du]
+    au fin fond         [de|des|du]
+    au grand dam        [de|des|du]
+    au plus profond     [de|des|du]
+        <<- ~2:3>> *
+
+    au fur et à mesure  [de|des|du]
+    au vu et au su      [de|des|du]
+        <<- ~2:5>> *
+
+    au nez et à la barbe [de|des|du]
+        <<- ~2:6>> *
+
+    aux [abords|dépens] [de|des|du]
+        <<- ~2>> _
+
+    [celui|celle|celles|ceux]   d’ entre [nous|vous|eux|elles]
+    [chacun|chacune]            d’ entre [nous|vous|eux|elles]
+        <<- ~2:0>> *
+
+    ceux et [celle|celles] qui
+        <<- ~2:3>> *
+
+    comme tant d’ autres  @:R
+        <<- ~1:4>> *
+
+    compte tenu [de|des|du]
+        <<- ~1:2>> avec
+
+    depuis ,
+        <<- ~1>> *
+
+    du moins
+        <<- ~>> _
+
+    en cours ~¬^(?:de|d’)$
+        <<- ~1:2>> *
+
+    de [mes|tes|ses|nos|vos|leurs] yeux [vu|vue|vus|vues]
+        <<- ~1:3>> *
+
+    elle aussi  @:A:[fe]:s
+        <<- ~1:2>> *
+
+    elle aussi  @:W¬:(?:3s|X)  [<end>|@:A:[fe]:s]
+        <<- ~1:2>> *
+
+    elles aussi  @:A:[fe]:p
+        <<- ~1:2>> *
+
+    elle aussi  @:W¬:(?:3p|X)  [<end>|@:A:[fe]:p]
+        <<- ~1:2>> *
+
+    en lieu et place [de|des|du]
+        <<- ~2:4>> *
+
+    en l’ [absence|honneur] [de|des|du]
+    en plein milieu [de|des|du]
+        <<- ~2:3>> *
+
+    en [arrière|attente|amont|aval|cas|cours|dehors|dépit|direction|faveur|guise|présence|raison|sus|termes|vertu] [de|des|du]
+        <<- ~2>> *
+
+    en flagrant délit [de|d’]
+        <<- ~2:3>> *
+
+    en matière [de|d’]
+        <<- ~2>> *
+
+    en proie à
+        <<- ~1:2>> *
+
+    eu égard [à|au|aux]
+        <<- ~1:2>> *
+
+    et  /  ou
+        <<- ~2:3>> *
+
+    [>aller|>croire|>devoir|>estimer|>imaginer|>penser] [lui|leur|nous|vous] être
+        <<- ~2>> *
+
+    jamais
+        <<- not morph(<1, ">ne") ~>> *
+
+    la une [de|des|du]
+        <<- ~2>> _
+
+    l’ impression que
+        <<- ~1>> _
+
+    l’ étrange impression que
+    la [nette|bizarre] impression que
+        <<- ~2:3>> _
+
+    le long [de|des|du]
+        <<- ~2>> _
+
+    le pour et le contre
+        <<- ~>> ␣
+        <<- =>> define(\1, [":LN:m:p"])
+
+    le [pressentiment|sentiment] [que|qu’|qu]
+        <<- ~1>> _
+
+    ou bien
+        <<- ~2>> *
+
+    pas très
+        <<- morph(<1, ":[NV]", ":A:[em]:[is]") ~>> *
+
+    par le biais [de|des|du]
+    par l’ entremise [de|des|du]
+        <<- ~2:3>> *
+
+    personne  d’ autre [que|qu’|qu]  [moi|toi|lui|elle|elles|nous|vous|eux]
+        <<- ~2:0>> *
+
+    pour ou contre
+        <<- ~2:0>> *
+
+    qui ce      [jour-là|matin-là|après-midi-là|soir-là]
+    qui cette   [nuit-là|matinée-là|soirée-là]
+        <<- ~2:0>> *
+
+    plus avant ~¬(?:de|d’|que|qu’|qu)
+        <<- ~1:2>> *
+
+    rien comparé à
+        <<- ~2>> *
+
+    suite [à|au|aux]
+        <<- not morph(<1, ">(?:une|la|cette|[mts]a|[nv]otre|de|quelque)/") ~1>> *
+
+    tout au long [de|des|du]
+        <<- not morph(<1, ":R") ~1>> *
+        <<- ~3>> *
+
+    tout un chacun
+        <<- ~1:2>> *
+
+    une fois
+        <<- ~>> _
+
+    [vent debout] contre
+        <<- ~1:2>> *
+
+    je      [t’|vous]   en  [prie|supplie]
+    nous    [t’|vous]   en  [prions|supplions]
+        <<- ~>> *
+
+
+# Déterminant + nombre
+__p_dét_plur_nombre_nom__
+    [les|des|mes|tes|ses|nos|vos|leurs]  ~\d+  @:[NA].*:[pi]¬:(?:V0|3p|Oo|X)|>(?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor)
+        <<- ~2>> *
+
+    [les|des|mes|tes|ses|nos|vos|leurs]  ~\d+  ou  ~\d+  @:[NA].*:[pi]¬:(?:V0|3p|Oo|X)|>(?:janvier|février|mars|avril|mai|juin|juillet|ao[ûu]t|septembre|octobre|novembre|décembre|vendémiaire|brumaire|frimaire|nivôse|pluviôse|ventôse|germinal|floréal|prairial|messidor|thermidor|fructidor)
+        <<- ~2:4>> *
+
+    [les|des]   >numéro  [un|~\d+|@:B]  et  [~\d+|@:B]
+        <<- ~3:0>> *
+
+    la  >numéro  un
+    la  >numéro  @:B
+    la  >numéro  ~\d+
+        <<- =>> define(\2, [">numéro/:N:f:s"])
+        <<- ~3>> *
+
+    le  numéro  un  @:¬:N:[em]:[is]
+        <<- ~3>> *
+
+    >numéro  @:B
+    >numéro  ~\d+
+        <<- ~2>> *
+
+
+__mot_composé_avec_là__
+    ~-[lL][àÀ]$
+        <<- morph(\1, ":[NAQ]", ":G", 0, -3) ~>> =\1[:-3]
+
+TEST: cette femme-là {{étaient}} partout.
+
+
+__simplification_des_nombres__
+    [vingt|trente|quarante|cinquante|soixante|soixante-dix|septante|quatre-vingt|octante|huitante|quatre-vingt-dix|nonante] et [un|une|onze]
+        <<- ~>> \1-et-\3||
+        <<- ~2:3>> *
+
+    [deux|trois|quatre|cinq|six|sept|huit|neuf|onze|douze|treize|quatorze|quinze|seize|dix-sept|dix-huit|dix-neuf]  cents  @:[NAQ].*:[pi]¬:(?:G|3p)
+        <<- ~1:2>> ␣
+
+    [deux|trois|quatre|cinq|six|sept|huit|neuf] ?cent¿ mille
+    cent mille
+        <<- ~>> ␣
+
+
+__purge_des_nombres__
+    [les|des|ces|mes|tes|ses|nos|vos|leurs]  quelque  @:B   @:[NA].*:[pi]¬:(?:G|3p)
+    [les|des|ces|mes|tes|ses|nos|vos|leurs]  quelque  ~\d+  @:[NA].*:[pi]¬:(?:G|3p)
+        <<- ~2:3>> *
+
+    [à|de|d’]  @:B  pour  cent
+        <<- ~>> *
+
+
+    [à|de|d’]  une  heure  ?[deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze|treize|quatorze|quinze|seize|dix-sept|dix-huit|dix-neuf|vingt|vingt-et-un|vingt-et-une|vingt-deux|vingt-trois|vingt-quatre|vingt-cinq|vingt-six|vingt-sept|vingt-huit|vingt-neuf|trente|trente-et-un|trente-et-une|trente-deux|trente-trois|trente-quatre|trente-cinq|trente-six|trente-sept|trente-huit|trente-neuf|quarante|quarante-et-un|quarante-et-une|quarante-deux|quarante-trois|quarante-quatre|quarante-cinq|quarante-six|quarante-sept|quarante-huit|quarante-neuf|cinquante|cinquante-et-un|cinquante-et-une|cinquante-deux|cinquante-trois|cinquante-quatre|cinquante-cinq|cinquante-six|cinquante-sept|cinquante-huit|cinquante-neuf]¿
+    [à|de|d’]  [deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze|treize|quatorze|quinze|seize|dix-sept|dix-huit|dix-neuf|vingt|vingt-et-une|vingt-deux|vingt-trois|vingt-quatre]  heures  ?[deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze|treize|quatorze|quinze|seize|dix-sept|dix-huit|dix-neuf|vingt|vingt-et-un|vingt-et-une|vingt-deux|vingt-trois|vingt-quatre|vingt-cinq|vingt-six|vingt-sept|vingt-huit|vingt-neuf|trente|trente-et-un|trente-et-une|trente-deux|trente-trois|trente-quatre|trente-cinq|trente-six|trente-sept|trente-huit|trente-neuf|quarante|quarante-et-un|quarante-et-une|quarante-deux|quarante-trois|quarante-quatre|quarante-cinq|quarante-six|quarante-sept|quarante-huit|quarante-neuf|cinquante|cinquante-et-un|cinquante-et-une|cinquante-deux|cinquante-trois|cinquante-quatre|cinquante-cinq|cinquante-six|cinquante-sept|cinquante-huit|cinquante-neuf]¿
+        <<- ~>> *
+
+
+__purge_conditionnelle__
+    au  moins  @¬:[AQ].*:[me]:[si]
+        <<- ~1:2>> *
+
+    au hasard  @:¬:[AQ].*:[me]:[si]
+        <<- ~1:2>> *
+
+    aussi @:W que [nécessaire|possible]
+        <<- ~>> *
+
+    aussi @:W que ce soit [<end>|,]
+        <<- ~1:5>> *
+
+    au sens le [plus|moins] @:A.*:[me]:[si] du terme
+    au sens @:A.*:[me]:[si] du terme
+        <<- ~>> *
+
+    <start> bien entendu
+        <<- ~2:0>> *
+
+    bien entendu
+        <<- morph(<1, ":[NAQR]|>que?/") ~>> *
+
+    comme [moi|toi|lui|elle|nous|vous|eux|elles|ça|cela]
+    comme [celui-ci|celui-là|celle-ci|celle-là|ceux-ci|ceux-là|celles-ci|celles-là]
+    comme le [mien|tien|sien|nôtre|vôtre|leur]
+    comme la [mienne|tienne|sienne|nôtre|vôtre|leur]
+    comme les [miens|tiens|siens|miennes|tiennes|siennes|nôtres|vôtres|leurs]
+        <<- morph(<1, ":[NA]", ":V0") ~>> *
+
+    dans la grande majorité des cas     @¬:A:[me]:[pi]
+        <<- ~1:6>> *
+
+    dans la majorité des cas            @¬:A:[me]:[pi]
+    dans de [très|trop] nombreux cas    @¬:A:[me]:[pi]
+    dans la plupart des cas             @¬:A:[me]:[pi]
+        <<- ~1:5>> *
+
+    dans maints cas                     @¬:A:[me]:[pi]
+        <<- ~1:3>> *
+
+    droit au but
+    droit dans les yeux
+        <<- not morph(<1, ":D.*:[me]:[si]") ~>> *
+
+    droit devant
+        <<- not morph(<1, ":D.*:[me]:[si]") ~1>> *
+
+    du coup @¬:A
+        <<- ~1:2>> *
+
+    en partie @:(?:R|D|[123]s|X)
+        <<- ~1:2>> *
+
     en plus
-    <<- morph(word(1), ":A", False, True) ~>> en
-    <<- __else__ ~>> *
-__[i](p_en_quelques_tps1)__
-    (en quelques (?:années|décennies|semaines|heures|minutes)) +({w_2}) @@0,$
-    <<- not morph(\2, ":[AQ]:[ef]:[si]", False) ~1>> *
-__[i](p_en_quelques_tps2)__
-    (en quelques (?:jours|mois|trimestres|semestres|siècles|millénaires)) +({w_2}) @@0,$
-    <<- not morph(\2, ":[AQ]:[em]:[si]", False) ~1>> *
-__[i](p_entre_pronom_et_pronom)__
-    entre (?:eux|elles|nous|vous)(?: et (?:moi|toi|nous|vous|elles|eux)|)
-    <<- not before(r"(?i)\b(?:il +|n’)$") ~>> *
-__[i](p_haut_et_fort)__             haut et fort <<- not morph(word(-1), ":D", False, False) ~>> *
-__[i](p_hélas)__                    hélas <<- not before(r"(?i)\bt(?:u|oi qui)[ ,]") ~>> *
-__[i](p_nécessité_fait_loi)__       nécessité fait loi <<- not morph(word(-1), ":D", False, False) ~>> *
-__[i](p_non_par_trop)__             (non|par trop) ({w_2}) @@0,$ <<- morph(\2, ":A", False) ~1>> *
-__[i](p_plein_est)__                plein est <<- not morph(word(-1), ":D", False, False) ~>> *
-__[i](p_plus_adv_que_prévu)__       (?:plus|moins|aussi) ({w3}) que prévu @@w <<- morph(\1, ":W", False) ~>> *
-__[i](p_plus_adv_que_les_autres)__  (?:plus|moins|aussi) ({w3}) (que (?:les autres|l’autre)) @@w,$ <<- morphex(\1, ":[AW]", ":G") ~2>> *
-__[i](p_plus_adv_les_uns_que_les_autres)__  plus ({w3}) (les une?s que les autres) @@5,$ <<- morph(\1, ":[AW]", False) ~2>> *
-__[i](p_pour_autant_que_su)__
-    (pour autant (?:que (?:je sache|tu saches|nous sachions|vous sachiez)|qu (?:il|elle)(?: sache|s sachent))) ({w_1})  @@0,$
-    <<- not morph(\2, ":Y", False) ~1>> *
-__[i](p_tambour_battant)__          tambours? battants? <<- morph(word(-1), ":(?:V|N:f)", ":G") ~>> *
-__[i](p_tête_baissée)__             ({w_2}) +(tête baissée) @@0,$ <<- morphex(\1, ":[NV]", ":D") ~2>> *
-__[i](p_tant_que_ça)__              ((?:pas |)tant que ça) ({w1}) @@0,$ <<- not morph(\2, ":(?:3s|X)", False) ~1>> *
-__[i](p_putain_de)__                (?:le|un|ce|[mts]on) (putain d(?:e +|’))({w_2}) @@*,$ <<- morph(\2, ":[me]", False) ~1>> *
-
-# Noms propres
-__[i](p_cocktail_Molotov)__     cocktails? (Molotov) @@$ <<- ~1>> *
-__[i](p_effet_Streisand)__      effets? (Streisand) @@$ <<- ~1>> *
-__[i](p_prix_Nobel)__           prix (Nobel) @@5 <<- ~1>> *
-__[s](p_Amérique)__             Amérique (centrale|du (?:Nord|Sud)) @@$ <<- ~1>> *
-__[s](p_nom_propre_nom_propre)__
-    ([A-ZÉÈÂ][\w-]+) (L[ea] |[vV][oa]n |Ma?c |[dD][eu] |d’|O’|)([A-ZÉÈÂ][\w-]+) @@0,*,$
-    <<- morph(\1, ":M[12]", False) ~3>> *
-    <<- __also__ and \2 != "" ~2>> *
-__[s](p_de_nom_propre_et_ou_de_nom_propre)__
-    (?:de |d’)([A-ZÉÈÂ][\w-]+) +(?:et|ou) +(?:de |d’)([A-ZÉÈÂ][\w-]+) @@w,$
-    <<- morph(\1, ":M", False) and morph(\2, ":M", False) ~>> *
-__[s](p_de_nom_propre)__
-    (?:de |d’)([A-ZÉÈÂ][\w-]+) @@$
-    <<- morph(\1, ":M", False) or not spell(\1) ~>> *
-__[s](p_entre_nom_propre_et_nom_propre)__
-    entre ([A-ZÉÈÂ][\w-]*) +et ([A-ZÉÈÂ][\w-]*) @@6,$
-    <<- morph(\1, ":(?:M[12]|N)") and morph(\2, ":(?:M[12]|N)") ~>> *
-__[s](p_en_nom_propre)__
-    en ([A-ZÉ][\w-]+) @@3 <<- morph(\1, ":MP") ~>> *
-__[u](p_titre_masculin_nom_propre)__
-    (?:[lc]e|du) (?:baron|docteur|député|duc|frère|prince|professeur|roi|sénateur|mir) ([A-ZÉÈÂ][\w-]+) @@$
-    <<- morph(\1, ":M[12]", False) ~1>> *
-__[u](p_titre_féminin_nom_propre)__
-    (?:la|cette) (?:baronne|docteure?|députée|duchesse|sœur|princesse|professeure?|reine|sénatrice) ([A-ZÉÈÂ][\w-]+) @@$
-    <<- morph(\1, ":M[12]", False) ~1>> *
-__[s](p_titre_abrégé_nom_propre)__
-    M(?:r|lle|me|gr|iss) ([A-ZÉÈÂ][\w-]+) @@$ <<- ~1>> *
-__[s](p_nom_propre_et_pronom)__
-    ([A-ZÉÈÊ][\w-]+) +et (lui|elles?|eux|[nv]ous|[mt]oi) @@0,$
-    <<- morph(\1, ":[MT]", False) and morph(word(-1), ":Cs", False, True) and not before(r"\b(?:plus|moins|aussi) .* que +$")
-    ~>> =rewriteSubject(\1,\2)
-
-# après être, après avoir
-__[i](p_être_qqch)__
-    ({etre}) +(à jamais|un jour|sous peu|du moins|avant tout|de passage|frère et sœur|mari et femme|père et mère|papa et maman|mission impossible|monnaie courante|pieds (?:et poings liés|nus)|partie (?:intégrante|prenante))  @@0,$
-    <<- morph(\1, ":V0e", False) ~2>> *
-__[i](p_être_pronom_qqch)__
-    ([ésf]\w+)-(?:ils|[nv]ous|elles) +(frère et sœur|mari et femme|père et mère|papa et maman|bon marché|meilleur marché|mission impossible)  @@0,$
-    <<- morph(\1, ":V0e", False) ~2>> *
-__[i](p_qqch_on_ne_peut_plus_que)__
-    ({w1}) +(on ne peut (?:pas |)(?:plus|moins)|plus que) +({w2})  @@0,w,$
-    <<- morph(\1, ":(?:V0e|N)", False) and morph(\3, ":[AQ]", False) ~2>> *
+        <<- morph(>1, ":A") ~1>> *
+        <<- __else__ ~>> *
+
+    en quelques [années|décennies|semaines|heures|minutes]              @¬:A:[fe]:[pi]
+        <<- ~1:3>> *
+
+    en quelques [jours|mois|trimestres|semestres|siècles|millénaires]   @¬:A:[me]:[pi]
+        <<- ~1:3>> *
+
+    entre (?:eux|elles|nous|vous)
+        <<- not morph(<1, ":Oo|>(?:il|on|n’|ne)") ~>> *
+
+    entre [moi|toi|lui|elle|nous|vous|eux|elles] et [moi|toi|lui|elle|nous|vous|eux|elles]
+        <<- ~>> *
+
+    haut et fort
+        <<- not morph(<1, ":D") ~>> *
+
+    hélas
+        <<- not morph(<1, ":(?:X|Oo)") and not before(r"(?i)\bt(?:u|oi qui)[ ,]") ~>> *
+
+    nécessité fait loi
+        <<- not morph(<1, ":D.*:f:[si]") ~>> *
+
+    nombre [de|des]
+        <<- morph(<1, ":(?:R|C[sc])") ~1>> *
+
+    non @:A
+        <<- not morph(<1, ":D.*:m:[si]") ~1>> *
+
+    par trop @:A
+        <<- ~1:2>> *
+
+    pêle-mêle
+        <<- not morph(<1, ":D.*:[me]") ~>> *
+
+    plein est
+        <<- not morph(<1, ":D.*:m:[si]") ~>> *
+
+    [plus|moins|aussi] @:W que prévu
+        <<- ~>> *
+
+    [plus|moins|aussi]  @:[AW]¬:G   que [les|nous|vous] autres
+    [plus|moins|aussi]  @:[AW]¬:G   que l’ autre
+    [plus|aussi]        @:[AW]      les [uns|unes] que les autres
+        <<- ~3:0>> *
+
+    pour  autant  [que|qu’|qu]  [je|il|elle|on]  le  sache
+    pour  autant  [que|qu’|qu]  tu               le  saches
+    pour  autant  [que|qu’|qu]  nous             le  sachions
+    pour  autant  [que|qu’|qu]  vous             le  sachiez
+    pour  autant  [que|qu’|qu]  [ils|elles]      le  sachent
+        <<- ~>> *
+
+    pour  autant  [que|qu’|qu]  [je|il|elle|on]  sache      @¬:Y
+    pour  autant  [que|qu’|qu]  tu               saches     @¬:Y
+    pour  autant  [que|qu’|qu]  nous             sachions   @¬:Y
+    pour  autant  [que|qu’|qu]  vous             sachiez    @¬:Y
+    pour  autant  [que|qu’|qu]  [ils|elles]      sachent    @¬:Y
+        <<- ~1:5>> *
+
+    [le|un|ce|mon|ton|son]  putain  [de|d’]  @:[NA].*:[me]
+        <<- ~2:3>> *
+
+    tambour battant
+    tambours battants
+        <<- morph(<1, ":(?:V|N:f)", ":G") ~>> *
+
+    tête baissée
+        <<- morph(<1, ":[NV]", ":D.*:[fe]:[si]") ~>> *
+
+    tant  que  ça  @¬:(?:3s|X|Oo)
+        <<- ~1:3>> *
+
+    pas  tant  que  ça  @¬:(?:3s|X|Oo)
+        <<- ~1:4>> *
+
+
+# END OF NG
+#<end>
+#@:[VR]¬[NAP]
+#, @¬:[NA]
+#[ne|n’|me|m’|te|t’|se|s’|le|la|l’|les|leur|leur|mon|ma|ta|sa|notre|votre|mes|tes|ses|ce|cet|cette|ces|je|j’|tu|il|on|nous|vous|ils|ça|ceci|cela|c’|ç’|chaque]
+
+
+__simplication_substantifs__
+    >arc à poulies
+    >arme à feu
+    >armée de l’air
+    >armée terre
+    >armer jusqu aux dents
+    >arme de [poing|guerre]
+    >arme de destruction massive
+    >attestation sur l’ honneur
+    >attendre de pied ferme
+    ayants droit
+    >billet de ~\d+ [>euro|>dollar|>centime|>cent|>livre|>shilling]
+    [>bisphénol|>bisphenol] A
+    >blanche comme neige
+    >blanche comme de la craie
+    [>boîte|>boite] aux lettres
+    [>boîte|>boite] à gants
+    >bombe à [eau|fragmentation|retardement]
+    >canne à [pêche|sucre]
+    >caisse à >outil
+    >chair à [pâté|>canon]
+    >chambre [de|d’] [agriculture|hôte|hôtes|commerce|compensation|décompression|dégrisement]
+    >chemin de [traverse|fer]
+    >chili con carne
+    >claire comme de l’ eau de [boudin|roche|source]
+    >claire comme du cristal
+    >claire comme jus de [boudin|chaussette|chaussettes|chique]
+    >commise d’ office
+    >convention [récepteur|générateur]
+    >conne comme la lune
+    >conne comme un balai
+    >conne comme une valise sans >poignée
+    >coup [de|d’] [balai|bol|cœur|foudre|fil|grâce|jarnac|théâtre|coude|genou|main|patte|pied|poing|poker|pouce|tête|avance|éclat|État|œil|épaule]
+    >coup du sort
+    >course contre la montre
+    [cousu|cousue|cousus|cousues] [main]
+    >crayon à [lèvres|sourcils]
+    [>coût|>cout] de revient
+    >cuillère à [café|soupe]
+    >déclaration sur l’ honneur
+    >délai [de|d’] [attente|carence|connexion|prescription|préavis|rétraction|rigueur]
+    >demande d’ asile
+    >descente aux [enfers|flambeaux]
+    [>dîner|>diner] aux chandelles
+    >digne de [confiance|foi]
+    >digne de ce nom
+    >droite comme un i
+    >eau de [bouleau|bleuet|chaux|coco|javel|jouvence|mer|parfum|pluie|seltz|source|vie]
+    >eau de noix de coco
+    >espérance de vie
+    >état [de|d’] [âme|esprit|urgence|conservation|fait]
+    >état d’ extrême urgence
+    >état de l’ art
+    >expérience [utilisateur|utilisateurs]
+    >fard à paupières
+    >femme [de|d’] [chambre|lettres|loi|ménage|affaires|exception|État|Église|honneur]
+    >femme d’ âge mûr
+    >fille à [papa|maman|>soldat]
+    >fille au pair
+    fils à [papa|maman]
+    >haute comme [trois|3] pommes
+    >homme [de|d’] [lettres|loi|main|paille|affaires|armes|exception|État|Église|honneur]
+    >homme d’ âge mûr
+    >hôtel de ville
+    >garde à vue
+    >garde du corps
+    gaz à effet de serre
+    >infirmière de garde
+    >invitée d’ honneur
+    >invitée surprise
+    >journal de bord
+    >lime à >ongle
+    >liste d’ attente
+    >machine à [café|coudre|laver]
+    >machine à remonter le temps
+    >main d’ œuvre
+    >maison de [passe|retraite]
+    >mal de [tête|ventre|mer]
+    >marché aux puces
+    >maréchale des [logis|logis-chef]
+    >marge de >manœuvre
+    >médecin de garde
+    >mère au foyer
+    >metteuse en scène
+    >mineure de moins de ~\d+ ans
+    >mineure de moins de @:B ans
+    >miroir aux alouettes
+    >monnaie [de|d’] [échange|réserve]
+    >mode de [paiement|scrutin|vie]
+    >mot de passe
+    >motrice [>essence|>diésel|>diesel]
+    >motion de [blâme|censure|défiance]
+    >moule à [>gaufre|>gâteau|brioche|manqué|savarin|charlotte]
+    noix de [cajou|pécan|pecan|coco|lavage|muscade|veau|macadamia]
+    >nue comme un ver
+    >nue comme des vers
+    >oiseau de [malheur|nuit|proie]
+    >oiseau de mauvais augure
+    >onde de choc
+    orge [perlé|mondé|carré]
+    >noire comme la nuit
+    >noire comme une nuit sans lune
+    >papier à [>lettre|musique]
+    >partie de jambes en l’ air
+    >pièce de [théâtre|monnaie]
+    >pièce de ~\d+ [>euro|>dollar|>centime|>cent|>livre|>shilling]
+    >pomme [de|d’] [discorde|terre|reinette|pin|Adam|api|amour|ambre|eau|or]
+    >porte de [service|garage]
+    >poudre aux yeux
+    preuve suffisante du contraire
+    preuves suffisantes du contraire
+    prix de revient
+    quelqu’un d’ autre
+    [réglé|réglée|réglés|réglées] comme du papier à musique
+    [remis|remise|remises] à plat
+    >requête en nullité
+    >requête en non [conciliation|inscription|lieu]
+    >requête en non révocation de sursis
+    >roue [avant|arrière]
+    >rouge à lèvres
+    >roulement à billes
+    >sac à [dos|main|langer|merde|foutre]
+    >sac de [couchage|sport|voyage]
+    >salle à manger
+    >salle [de|d’] [attente|bain|bains|conférence]
+    >saine [de|d’] [corps|esprit]
+    >saine [de|d’] [corps|esprit] et [de|d’] [corps|esprit]
+    >sclérose en plaques
+    >secret défense
+    >silo à [>grains|blé]
+    >soue à >cochonne
+    >système d’ exploitation
+    >système D
+    >taille ~\d+
+    >talon >aiguille
+    taux [de|d’] [abstention|absorption|alcool|alphabétisation|endettement|inflation|intérêt|imposition|occupation|ouverture|œstrogène|urée|usure|change|cholestérol|cholesterol|glycémie|fécondité|participation|testostérone|TVA]
+    >tête de [déterré|déterrée|déterrés|déterrées]
+    >tour de passe-passe
+    >trou à >rat
+    >tueuse à gages
+    >usine à gaz
+    >vache à lait
+    >vectrice [>accélération|>position|>rotation|>vitesse]
+    >vente à domicile
+    vernis à ongles
+    >voie de [recours|perdition]
+    >vol à l’étalage
+    >vol à la [sauvette|tire]
+        <<- ~2:0>> *
+
+
+__purge_locutions_adjectivales__
+    bas de gamme
+    basse consommation
+    bon [enfant|marché|teint]
+    bon chic ?,¿ bon genre
+    [clé|clef] en [main|mains]
+    dernier cri
+    fleur bleue
+    grand [public|luxe|maximum]
+    grandeur nature
+    haut de gamme
+    hautee [résolution|fidélité|tension]
+    longue [distance|portée|durée]
+    meilleur marché
+    numéro un
+    numéro @:B
+    plein cadre
+    top secret
+    vieux jeu
+    open source
+    Créative Commons
+    pair à pair
+    pur [sucre|jus]
+    terre à terre
+        <<- morph(<1, ":(?:N|A|Q|W|V0e)", ":D") ~>> *
+
+
+__purge_couleurs__
+    [beige|blanc|bleu|brun|châtain|cyan|gris|jaune|magenta|marron|orange|pourpre|rose|rouge|vert|violet] [brillant|clair|fluo|foncé|irisé|mat|pâle|pastel|sombre|tendre|vif]
+        <<- morph(<1, ":[NAQ]") ~>> *
+
+    bleu    [ciel|indigo|marine|roi|saphir|turquoise]
+    blond   platine
+    gris    [acier|anthracite|perle|souris]
+    jaune   sable
+    noir    [de|d’] [encre|jais]
+    noir    et blanc
+    rose    [bonbon|chair|corail]
+    rouge   [brique|carmin|écarlate|rubis|sang]
+    vert    [émeraude|olive|pomme]
+        <<- morph(<1, ":[NA]", ":D") ~>> *
+        <<- __else__ and morph(<1, ":D|>(?:être|rester|sembler|demeurer)") ~>> ␣
+        <<- __also__ =>> define(\1, [":A:e:i"])
+
+
+__simplification_noms_propres__
+    don Juan
+        <<- ~1>> *
+
+    >cocktail Molotov
+    >effet Streisand
+    prix Nobel
+        <<- ~2>> *
+
+    Amérique du [Nord|Sud]
+    Amérique centrale
+        <<- ~2:0>> *
+
+    @:M[12]  *WORD
+        <<- \2.istitle() ~2:0>> *
+
+    @:M[12]  [Le|La|von|van|Mac|Mc|De|Du|D’]  *WORD
+        <<- \3.istitle() ~2:0>> *
+
+    [de|d’]  @:M  [et|ou]  [de|d’]  @:M
+    [de|d’]  @:M
+        <<- ~>> *
+
+    entre  @:M  et  @:M
+        <<- ~>> *
+
+    entre  @:N  et  @:N
+        <<- \2.istitle() and \4.istitle() ~>> *
+
+    en  @:MP
+        <<- ~>> *
+
+    [le|ce|du]  [baron|docteur|député|duc|frère|ministre|prince|professeur|président|roi|sénateur|mir]  @:M[12]
+    [la|cette]  [baronne|docteur|docteure|députée|duchesse|ministre|sœur|princesse|présidente|professeure|reine|sénatrice]  @:M[12]
+        <<- ~3>> *
+
+    [Mr|Mlle|Mme|Mgr|miss]  ~^[A-ZÉÈÊ]
+        <<- ~2>> *
+
+    @:Cs  ~^[A-ZÉÈÊ]  et  [moi|toi|lui|elle|nous|vous|eux|elles]
+        <<- morph(\2, ":M") and not before(r"\b(?:plus|moins|aussi) .* que +$")
+        ~2:4>> =rewriteSubject(\2,\4) + "||"
+
+    <start>  ~^[A-ZÉÈÊ]  et  [moi|toi|lui|elle|nous|vous|eux|elles]
+        <<- morph(\2, ":M")
+        ~2:0>> =rewriteSubject(\2,\4) + "||"
+
+
+__purge_après_être__
+    >être [bon|meilleur] marché
+    >être avant tout
+    >être cousin et cousine
+    >être de passage
+    >être du moins
+    >être en partie
+    >être frère et sœur
+    >être mari et femme
+    >être mission impossible
+    >être monnaie courante
+    >être papa et maman
+    >être partie [intégrante|prenante]
+    >être pieds et poings liés
+    >être pieds nus
+    >être père et mère
+    >être somme toute
+    >être sous peu
+    >être tous [deux|trois]
+    >être un jour
+    >être à jamais
+    >être [pas|jamais|plus|point]
+        <<- ~2:0>> *
+
+    ~-ils$ [bon|meilleur] marché
+    ~-ils$ avant tout
+    ~-ils$ cousin et cousine
+    ~-ils$ de passage
+    ~-ils$ du moins
+    ~-ils$ en partie
+    ~-ils$ frère et sœur
+    ~-ils$ mari et femme
+    ~-ils$ mission impossible
+    ~-ils$ monnaie courante
+    ~-ils$ papa et maman
+    ~-ils$ partie [intégrante|prenante]
+    ~-ils$ pieds et poings liés
+    ~-ils$ pieds nus
+    ~-ils$ père et mère
+    ~-ils$ somme toute
+    ~-ils$ sous peu
+    ~-ils$ tous [deux|trois]
+    ~-ils$ un jour
+    ~-ils$ à jamais
+    ~-ils$ [pas|jamais|plus|point]
+        <<- morph(\1, ">V0e", 0, -4) ~2:0>> *
+
+    ~-[nv]ous$ [bon|meilleur] marché
+    ~-[nv]ous$ avant tout
+    ~-[nv]ous$ cousin et cousine
+    ~-[nv]ous$ de passage
+    ~-[nv]ous$ du moins
+    ~-[nv]ous$ en partie
+    ~-[nv]ous$ frère et sœur
+    ~-[nv]ous$ mari et femme
+    ~-[nv]ous$ mission impossible
+    ~-[nv]ous$ monnaie courante
+    ~-[nv]ous$ papa et maman
+    ~-[nv]ous$ partie [intégrante|prenante]
+    ~-[nv]ous$ pieds et poings liés
+    ~-[nv]ous$ pieds nus
+    ~-[nv]ous$ père et mère
+    ~-[nv]ous$ somme toute
+    ~-[nv]ous$ sous peu
+    ~-[nv]ous$ tous [deux|trois]
+    ~-[nv]ous$ un jour
+    ~-[nv]ous$ à jamais
+    ~-[nv]ous$ [pas|jamais|plus|point]
+        <<- morph(\1, ">V0e", 0, -5) ~2:0>> *
+
+    ~-elles$ [bon|meilleur] marché
+    ~-elles$ avant tout
+    ~-elles$ cousin et cousine
+    ~-elles$ de passage
+    ~-elles$ du moins
+    ~-elles$ en partie
+    ~-elles$ frère et sœur
+    ~-elles$ mari et femme
+    ~-elles$ mission impossible
+    ~-elles$ monnaie courante
+    ~-elles$ papa et maman
+    ~-elles$ partie [intégrante|prenante]
+    ~-elles$ pieds et poings liés
+    ~-elles$ pieds nus
+    ~-elles$ père et mère
+    ~-elles$ somme toute
+    ~-elles$ sous peu
+    ~-elles$ tous [deux|trois]
+    ~-elles$ un jour
+    ~-elles$ à jamais
+    ~-elles$ [pas|jamais|plus|point]
+        <<- morph(\1, ">V0e", 0, -6) ~2:0>> *
+
+    >être beaucoup
+    >être bien entendu
+    >être dans [l’|leur|son] ensemble
+    >être [à|en] ce moment  ?précis¿
+    >être [à|en] cet instant ?précis¿
+    >être sans peine
+    >être un [moment|peu|minimum]
+    >être un petit peu
+    >être un tout petit peu
+        <<- morph(>1, ":[QY]") ~2:0>> *
+
+    ~-ils$ beaucoup
+    ~-ils$ bien entendu
+    ~-ils$ dans [l’|leur|son] ensemble
+    ~-ils$ [à|en] ce moment  ?précis¿
+    ~-ils$ [à|en] cet instant ?précis¿
+    ~-ils$ sans peine
+    ~-ils$ un [moment|peu|minimum]
+    ~-ils$ un petit peu
+    ~-ils$ un tout petit peu
+        <<- morph(\1, ">V0e", 0, -4) and morph(>1, ":[QY]") ~2:0>> *
+
+    ~-[nv]ous$ beaucoup
+    ~-[nv]ous$ bien entendu
+    ~-[nv]ous$ dans [l’|leur|son] ensemble
+    ~-[nv]ous$ [à|en] ce moment  ?précis¿
+    ~-[nv]ous$ [à|en] cet instant ?précis¿
+    ~-[nv]ous$ sans peine
+    ~-[nv]ous$ un [moment|peu|minimum]
+    ~-[nv]ous$ un petit peu
+    ~-[nv]ous$ un tout petit peu
+        <<- morph(\1, ">V0e", 0, -5) and morph(>1, ":[QY]") ~2:0>> *
+
+    ~-elles$ beaucoup
+    ~-elles$ bien entendu
+    ~-elles$ dans [l’|leur|son] ensemble
+    ~-elles$ [à|en] ce moment  ?précis¿
+    ~-elles$ [à|en] cet instant ?précis¿
+    ~-elles$ sans peine
+    ~-elles$ un [moment|peu|minimum]
+    ~-elles$ un petit peu
+    ~-elles$ un tout petit peu
+        <<- morph(\1, ">V0e", 0, -6) and morph(>1, ":[QY]") ~2:0>> *
+
+    on ne peut [plus|moins]
+    on ne peut pas [plus|moins]
+    plus que
+        <<- morph(<1, ":(?:V0e|N)") and morph(>1, ":[AQ]") ~>> *
+
+
+
+@@@@
+@@@@END_GRAPH                                                                                      _
+@@@@
+
+
+# après avoir
 __[i](p_avoir_être_loc_adv1)__
-    ({avoir_etre}) +(pas|jamais|plus|en partie|point|tous (?:deux|trois)|somme toute)  @@0,$
+    ({avoir}) +(pas|jamais|plus|en partie|point|tous (?:deux|trois)|somme toute)  @@0,$
     <<- morph(\1, ":V0", False) ~2>> *
 __[i](p_avoir_être_loc_adv2)__
-    ({avoir_etre}) +(beaucoup|bien entendu|dans (?:leur |son |l’)ensemble|à ce(?:t (?:instant|endroit)| moment)|sans peine|un (?:moment|peu|minimum|petit peu|tout petit peu)) +({w_2})  @@0,w,$
+    ({avoir}) +(beaucoup|bien entendu|dans (?:leur |son |l’)ensemble|à ce(?:t (?:instant|endroit)| moment)|sans peine|un (?:moment|peu|minimum|petit peu|tout petit peu)) +({w_2})  @@0,w,$
     <<- morph(\1, ":V0", False) and morph(\3, ":[QY]", False) ~2>> *
 __[i](p_avoir_loc_adv)__
     ({avoir}) +(besoin|bon (?:dos|pied,? bon œil)|carte blanche|confiance|conscience|crainte|faim|forme humaine|honte|partie (?:gagnée|liée)|peur|soif|voix au chapitre)  @@0,$
     <<- morph(\1, ":V0a", False) and not (\2 == "crainte" and before(r"\w")) ~2>> *
 __[i](p_avoir_pronom_loc_adv)__
     ({avoir})-(?:je|tu|ils?|elles?|nous|vous|on) +(besoin|bon (?:dos|pied,? bon œil)|carte blanche|confiance|conscience|crainte|faim|forme humaine|honte|partie (?:gagnée|liée)|peur|soif|voix au chapitre)  @@0,$
     <<- morph(\1, ":V0a", False) ~2>> *
 __[i](p_avoir_tous_toutes_les)__
     ({avoir}) +(tou(?:te|)s les ({w_2})) +({w_2})  @@0,w,>3:$,$
-    <<- morph(\1, ":V0a", False) and morph(\3, ":B", False) and morph(\4, ">besoin |:(?:Q|V1.*:Y)", False) ~2>> *
-
-# elle aussi + adj
-__[i](p_elle_aussi)__
-    (elle aussi) +({w_3}) @@0,$
-    <<- morph(\2, ":A:[fe]:s", False) ~1>> *
-    <<- __else__ and morphex(\2, ":W", ":3s") and morph(word(1), ":A:[fe]:s", False, True) ~1>> *
-__[i](p_elles_aussi)__
-    (elles aussi) +({w_3}) @@0,$
-    <<- morph(\2, ":A:[fe]:p", False) ~1>> *
-    <<- __else__ and morphex(\2, ":W", ":3p") and morph(word(1), ":A:[fe]:p", False, True) ~1>> *
+    <<- morph(\1, ":V0a", False) and morph(\3, ":B", False) and morph(\4, ">besoin/|:(?:Q|V1.*:Y)", False) ~2>> *
+
 
 # après verbe
 __[i](p_verbe_loc_adv1)__       ({w1}) (?:pas |)(jour et nuit|quand même(?: pas|)) @@0,$ <<- morph(\1, ":V", False) ~2>> *
 __[i](p_verbe_loc_adv2)__       ({w_2}) (bien entendu|juste|ensemble) @@0,$ <<- morph(\1, ":V[123]") ~2>> *
 __[i](p_verbe_loc_adv3)__       ({w_2}) ((?:fort|très|super) (?:bien|mal)|bien|mal) @@0,$ <<- morph(\1, ":V[123]", False) ~2>> *
@@ -5584,22 +7888,25 @@
 __[i](p_la_xxx_la_plus_adj)__
     la ({w_2}) (la plus) ({w_2})  @@3,w,$
     <<- morphex(\1, ":[NAQ].*:[fe]", ":G") and morph(\3, ":[AQ].*:[fe]", False) ~2>> *
 __[i](p_les_xxx_les_plus_adj)__
     (?:[lmts]es|nos|vos|leurs) ({w_2}) (les plus) ({w_2})  @@w,w,$
-    <<- morphex(\1, ":[NAQ].*:[pi]", ":[123][sp]") and morph(\3, ":A.*:[pi]", False) ~2>> * 
+    <<- morphex(\1, ":[NAQ].*:[pi]", ":[123][sp]") and morph(\3, ":A.*:[pi]", False) ~2>> *
 __[i](p_le_plus_le_moins)__
     (le (?:plus|moins)) ({w_2})  @@0,$
-    <<- morph(\2, ":A", ":([me]:[si]|G)") and morph(word(-1), ">(?:avoir|être) :V", False) ~1>> *
+    <<- morphex(\2, ":A", ":([me]:[si]|G)") and morph(word(-1), ">(?:avoir|être)/:V", False) ~1>> *
 __[i](p_bien_sûr)__
     bien sûr(?! de) <<- ~>> *
 __[i](p_bien_mal_fort_adj_adv)__
     (bien|mal|(?:fort|super) (?:bien|mal)|fort) +({w_2})  @@0,$
     <<- morph(\2, ":[AW]") ~1>> *
 __[i](p_loc_adj_adv)__
-    (à (?:demi|peine|peu près)|depuis peu|quelque peu|pas très|un (?:petit |)peu(?: plus| moins|)|peu|plus|moins|si) +({w_2})  @@0,$
+    (à (?:demi|peine|peu près)|depuis peu|quelque peu|pas très|un (?:petit |)peu(?: plus| moins|)|peu|plus|moins) +({w_2})  @@0,$
     <<- morph(\2, ":[AW]", False) ~1>> *
+__[i](p_si_adj_adv)__
+    (si) +({w_2})  @@0,$
+    <<- morph(\2, ":[AW]", False) and not (\2 == "bien" and after("^ +que? ")) ~1>> *
 __[i](p_un_brin_chouïa_rien_tantinet_soupçon)__
     (un (?:brin|chou[iï]a|rien|minimum|soupçon|tantinet)(?: trop|)) ({w_2}) @@0,$
     <<- morphex(\2, ":A", ":G") ~1>> *
 __[i](p_assez_trop_adv_xxxment)__
     (?:assez|trop) +(\w+ment)  @@$
@@ -5615,62 +7922,17 @@
 __[i](p_complètement)__
     complètement <<- not morph(word(-1), ":D", False, True) ~>> *
 __[i](p_adverbe_xxxment)__
     (\w+ment)(?: parlant| pas|) @@0 <<- morph(\1, ":W\\b") ~>> *
 
-# couleurs invariables
-__[i](p_couleurs_invariables)__
-    ({w_2}) +((?:beige|blanc|bleu|brun|châtain|cyan|gris|jaune|magenta|marron|orange|pourpre|rose|rouge|vert|violet) (?:clair|fluo|foncé|irisé|pâle|pastel|sombre|vif|tendre)) @@0,$
-    <<- morph(\1, ":[NAQ]", False) ~2>> *
-
-# locutions adjectivales, nominales & couleurs
-__[i](p_locutions_adj_nom_et_couleurs)__
-    ({w_2}) +(bas(?: de gamme|se consommation)|bon (?:enfant|marché|teint|chic,? bon genre)|cl(?:é|ef) en mains?|dernier cri|fleur bleue|grand (?:public|luxe|maximum)|grandeur nature|haut(?: de gamme|e (?:résolution|fidélité|tension))|longue (?:distance|portée|durée)|meilleur marché|numéro (?:un|deux|trois|quatre|cinq|six|sept|huit|neuf|dix(?:-sept|-huit|-neuf)|onze|douze|treize|quatorze|quinze|seize|vingt)|plein cadre|top secret|vieux jeu|open source|Créative Commons|pair à pair|pur (?:sucre|jus)|terre à terre|bleu (?:ciel|marine|roi|saphir|turquoise)|vert (?:émeraude|olive|pomme)|rouge (?:brique|carmin|écarlate|rubis|sang)|rose (?:bonbon|chair|corail)|jaune sable|blond platine|gris (?:acier|anthracite|perle|souris)|noir (?:d(?:’encre|e jais)|et blanc))
-    @@0,$
-    <<- morphex(\1, ":(?:N|A|Q|V0e)", ":D") ~2>> *
-
 # tous / tout / toute / toutes
 __[i](p_tout_déterminant_masculin)__        (tout) (?:le|cet?|[mts]on) @@0              <<- ~1>> *
 __[i](p_toute_déterminant_féminin)__        (toute) (?:la|cette|[mts]a) @@0             <<- ~1>> *
 __[i](p_tous_toutes_déterminant_pluriel)__  (tou(?:te|)s) (?:[ldscsmt]es|[nv]os) @@0    <<- ~1>> *
 
 
-## 1 mot
-__[i](p_ailleurs_ainsi)__               ai(?:lleurs|nsi)                            <<- ~>> *
-__[i](p_alentour_alors)__               al(?:entour|ors)                            <<- ~>> *
-__[i](p_aujourdhui_auparavant)__        au(?:jourd’hui|paravant)                    <<- ~>> *
-__[i](p_bientôt)__                      bientôt                                     <<- ~>> *
-__[i](p_cependant_certes)__             ce(?:pendant|rtes)                          <<- ~>> *
-__[i](p_ci_dessus_dessous)__            ci-desso?us                                 <<- ~>> *
-__[i](p_debout_derechef)__              de(?:bout|rechef)                           <<- ~>> *
-__[i](p_depuis)__                       (depuis), @@0                              <<- ~1>> *
-__[i](p_déjà_désormais)__               dé(?:jà|sormais)                            <<- ~>> *
-__[i](p_donc_dorénavant)__              do(?:nc|rénavant)                           <<- ~>> *
-__[i](p_enfin_ensuite_encore)__         en(?:fin|suite|core)                        <<- ~>> *
-__[i](p_guère)__                        guère                                       <<- ~>> *
-__[i](p_ici)__                          ici                                         <<- ~>> *
-__[i](p_illico)__                       illico                                      <<- ~>> *
-__[i](p_jadis)__                        jadis                                       <<- ~>> *
-__[i](p_jamais1)__                      jamais           <<- not before(r"(?i)\bne +$") ~>> *
-__[i](p_loin_longtemps)__               lo(?:in|ngtemps)                            <<- ~>> *
-__[i](p_mouais)__                       mouais                                      <<- ~>> *
-__[i](p_naguère)__                      n(?:aguère|éanmoins)                        <<- ~>> *
-__[i](p_parfois_partout)__              par(?:fois|tout)                            <<- ~>> *
-__[i](p_presque_primo)__                pr(?:esque|imo)                             <<- ~>> *
-__[i](p_peut_être_plutôt_pourtant)__    p(?:eut-être|lutôt|ourtant)                 <<- ~>> *
-__[i](p_quelquefois)__                  quelquefois                                 <<- ~>> *
-__[i](p_soudain_souvent)__              sou(?:dain|vent)                            <<- ~>> *
-__[i](p_toujours_toutefois)__           tou(?:jours|tefois)                         <<- ~>> *
-__[i](p_secondo)__                      secondo                                     <<- ~>> *
-__[i](p_sur_le_champ_surtout)__         sur(?:-le-champ|tout)                       <<- ~>> *
-__[i](p_tôt_tard_tantôt_tertio_très)__  t(?:ôt|ard|antôt|ertio|rès)                 <<- ~>> *
-__[i](p_vite)__                         vite                                        <<- ~>> *
-__[i](p_volontiers)__                   volontiers                                  <<- ~>> *
-
 # après
-__[i](p_au_fur_et_à_mesure)__           au fur et à mesure                          <<- ~>> *
-__<i>(p_oui_non_entre_autres)__         , +(?:oui|non|entre autres),                <<- ~>> *
 __<s>(p_virgule_virgule)__              , +,                                        <<- ~>> *
 __<s>(p_première_virgule)__             ^ *,                                        <<- ~>> *
 __<s>(p_dernière_virgule)__             , *$                                        <<- ~>> *
 __<s>(p_tiret_tiret)__                  [—–-] +[—–-]                                <<- ~>> *
 __<s>(p_parenthèses_vides)__            [(] +[)]                                    <<- ~>> *
@@ -5718,94 +7980,94 @@
 
 
 ## Simplication des locutions verbales
 __[i](loc_arriver)__
 	(arriv\w+) (([aà]) (?:échéance|point nommé)) @@0,$,w
-	<<- morph(\1, ">arriver ", False) >>>
+	<<- morph(\1, ">arriver/", False) >>>
 	<<- \3 == "a" -3>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
 	<<- ~2>> *
 __[i](p_donner_sens)__
     ((?:re|)donn\w+) +(sens) @@0,$
-    <<- morph(\1, ">(?:re|)donner ", False) ~2>> *
+    <<- morph(\1, ">(?:re|)donner/", False) ~2>> *
 __[i](p_faire_qqch)__
     (f[aiîeo]\w*) +(tous(?: deux| trois|) +|)(allusion|amende honorable|assaut|bande à part|bonne figure|chaud|confiance|compliqué|copain[- ]copain|de (?:[mts]on|leur|[nv]otre) mieux|dé(?:bat|faut)|demi-tour|envie|fausse route|figure|froid|front commun|gr(?:ise mine|and (?:bruit|cas))|h(?:alte|onte)|illusion|long feu|ma(?:chine|rche) arrière|main basse|mouche|office|p(?:art(?:ie(?: intégrante|)|)|eur|laisir|rofil bas)|rage|salle comble|scandale|sens|signe|table rase|volte-face|ce que bon (?:me|te|lui|leur|nous|vous) semble) @@0,*,$
-    <<- morph(\1, ">faire ", False) ~2>> *
+    <<- morph(\1, ">faire/", False) ~2>> *
     <<- __also__ ~3>> *
 __[i](loc_laisser_pour_compte)__
     (laiss\w+) +(pour (co[mn]p?tes?))  @@0,$,$
-    <<- morph(\1, ">laisser ", False) >>>
+    <<- morph(\1, ">laisser/", False) >>>
     <<- \3 != "compte" -3>> compte              # Confusion. Locution “laisser pour compte”.|https://fr.wiktionary.org/wiki/laisser_pour_compte
     <<- ~2>> *
 __[i](loc_mettre_à_qqch)__
     (m(?:et|[iî][mst])\w*) +(([àa]) (?:bas|jour|niveau|plat|l’(?:écart|épreuve)|terre)) @@0,$,w
-    <<- morph(\1, ">mettre ", False) >>>
+    <<- morph(\1, ">mettre/", False) >>>
     <<- \3 == "a" -3>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
     <<- ~2>> *
 __[i](p_mettre_qqch)__
     (m(?:et|[iî][mst])\w*) +(au p(?:oint|as)|en (?:avant|bouche|demeure|garde|jeu|lumière|œuvre|place|scène|terre)) @@0,$
-    <<- morph(\1, ">mettre ", False) ~2>> *
+    <<- morph(\1, ">mettre/", False) ~2>> *
 __[i](loc_mourir_qqch)__
     (m[oe]\w+) +(jeûne)  @@0,$
-    <<- morph(\1, ">mourir ", False) -2>> =\2.replace("û", "u")                 # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
+    <<- morph(\1, ">mourir/", False) -2>> =\2.replace("û", "u")                 # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
 __[i](p_paraitre_qqch)__
     (par\w+) +(jeûnes?)  @@0,$
-    <<- morph(\1, ">para[îi]tre ", False) -2>> =\2.replace("û", "u")            # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
+    <<- morph(\1, ">para[îi]tre/", False) -2>> =\2.replace("û", "u")            # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
 __[i](p_porter_qqch)__
     (port\w+) +(atteinte|bonheur|caution|chance|malheur|plainte|préjudice|secours)  @@0,$
-    <<- morph(\1, ">porter ", False) ~2>> *
+    <<- morph(\1, ">porter/", False) ~2>> *
 __[i](loc_prendre_à_la_légère)__
     (pr[eiî]\w+) +(([àa]) la légère) @@0,$,w
-    <<- morph(\1, ">prendre ", False) >>>
+    <<- morph(\1, ">prendre/", False) >>>
     <<- \3 == "a" -3>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
     <<- ~2>> *
 __[i](p_prendre)__
     (pr[eiî]\w+) +(au (?:dépourvu|sérieux)|congé|conscience|contact|de court|en charge|ombrage|pour argent comptant|par surprise|racine|soin|vie) @@0,$
-    <<- morph(\1, ">prendre ", False) ~2>> *
+    <<- morph(\1, ">prendre/", False) ~2>> *
 __[i](loc_rendre_compte)__
     (rend\w+) +(co[mn]tes?)  @@0,$
-    <<- morph(\1, ">rendre ", False) -2>> compte                                # Confusion probable. Locution “rendre compte”.|https://fr.wiktionary.org/wiki/rendre_compte
+    <<- morph(\1, ">rendre/", False) -2>> compte                                # Confusion probable. Locution “rendre compte”.|https://fr.wiktionary.org/wiki/rendre_compte
     <<- ~1>> *
 __[i](loc_rester_qqch)__
     (rest\w+) +(lettre morte|jeûnes?) @@0,$
-    <<- morph(\1, ">rester ", False) >>>
-    <<- morph(\2, ">jeûne ", False) -2>> =\2.replace("û", "u")                  # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
+    <<- morph(\1, ">rester/", False) >>>
+    <<- morph(\2, ">jeûne/", False) -2>> =\2.replace("û", "u")                  # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
     <<- __else__ ~2>> *
 __[i](loc_semble_qqch)__
     (sembl\w+) +(jeûnes?)  @@0,$
-    <<- morph(\1, ">sembler ", False) -2>> =\2.replace("û", "u")                # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
+    <<- morph(\1, ">sembler/", False) -2>> =\2.replace("û", "u")                # Confusion. Le jeûne est une privation de nourriture.|https://fr.wiktionary.org/wiki/jeune
 __[i](p_sembler_paraitre_être)__
     (sembl\w+|par[au]\w+) +(être|avoir été) +({w_2}) @@0,w,$
-    <<- morph(\1, ">(?:sembler|para[îi]tre) ") and morphex(\3, ":A", ":G") ~2>> *
+    <<- morph(\1, ">(?:sembler|para[îi]tre)/") and morphex(\3, ":A", ":G") ~2>> *
 __[i](loc_suivre_de_près)__
     (suiv\w+) +((?:ça +|ce(?:ci|la) +|)de (pr[èé]s?|prêts?)) @@0,$,$
-    <<- morph(\1, ">suivre ", False) >>>
+    <<- morph(\1, ">suivre/", False) >>>
     <<- \3 != "près" -3>> près                  # Confusion : écrivez “près” pour dire “proche de quelque chose”.|https://fr.wiktionary.org/wiki/pr%C3%A8s
     <<- ~2>> *
 __[i](loc_tenir_à_distance)__
     (t[eiî]\w+) +(([àa]) distance +(?:respectable +|))d(?:es?|u) @@0,*,w
-    <<- morph(\1, ">tenir ", False) >>>
+    <<- morph(\1, ">tenir/", False) >>>
     <<- \3 == "a" -3>> à                        # Confusion : “a” est une conjugaison du verbe “avoir”. Pour la préposition, écrivez “à”.
     <<- ~2>> *
 __[i](loc_tenir_compte)__
     (t[eiî]\w+) +(co(?:mp?|n)tes?|au courant) @@0,$
-    <<- morph(\1, ">tenir ", False) >>>
-    <<- morph(\2, ">co[mn]te(?:sse|) ", False) -2>> compte        # Confusion. Dans la locution “tenir compte”, écrivez “compte” au singulier.|https://fr.wiktionary.org/wiki/tenir_compte
+    <<- morph(\1, ">tenir/", False) >>>
+    <<- morph(\2, ">co[mn]te(?:sse|)/", False) -2>> compte        # Confusion. Dans la locution “tenir compte”, écrivez “compte” au singulier.|https://fr.wiktionary.org/wiki/tenir_compte
     <<- ~2>> *
 __[i](p_tirer_profit)__
     (tir\w+) +(avantage|profit) d(?:es?|u) @@0,w
-    <<- morph(\1, ">tirer ", False) ~2>> *
+    <<- morph(\1, ">tirer/", False) ~2>> *
 __[i](loc_tourner_court)__
     (tourn\w+) +(cour(?:re|t|s|))  @@0,$
-    <<- morph(\1, ">tourner ", False) >>>
+    <<- morph(\1, ">tourner/", False) >>>
     <<- \2 != "court" -2>> court                # Locution : tourner court.|https://fr.wiktionary.org/wiki/tourner_court
     <<- ~2>> *
 __[i](p_trier_sur_le_volet)__
     (tri\w+) (sur le volet) @@0,$
-    <<- morph(\1, ">trier ", False) ~2>> *
+    <<- morph(\1, ">trier/", False) ~2>> *
 __[i](p_venir)__
     (v[eiî]\w+) ((?:on ne sait|je ne sais) (?:pas |)(?:trop |)d’où) @@0,$
-    <<- morph(\1, ">venir ", False) ~2>> *
+    <<- morph(\1, ">venir/", False) ~2>> *
 
 TEST: ce contrat arrive {{a}} échéance.
 TEST: il faut tenir {{contes}} des faits au lieu de nos impressions.
 TEST: prendre {{a}} la légère ce test serait une erreur.
 TEST: on va suivre ça de {{prêt}}.
@@ -5889,23 +8151,33 @@
 TEST: Cette scène que décrit ici Yannick est représentative.
 TEST: attentifs aux spécificités socioculturelles de chaque peuple, constituées dans la longue durée autour d’une langue et de traditions
 TEST: Il était à l’époque chargé de maintenir en état ces machines.
 TEST: Les laissés pour compte ignorés de tous.
 TEST: Ces épreuves sont mission impossible.
+TEST: Ma thèse en 180 secondes.
+TEST: un champ de canne à sucre
+TEST: La batterie se recharge automatiquement grâce au moteur essence.
+TEST: c’est un moteur diésel.
+TEST: cette descente aux enfers interminable.
+TEST: c’est une vache à lait
+TEST: Ses talons aiguille étaient à la denière mode.
+TEST: elles seules peuvent s’en sortir.
+TEST: elle seule peut y arriver
+TEST: elle seules les femmes la font craquer
 
 
 
 #
 # //////////////////////////////////////// RÈGLES DE CONTRÔLE ////////////////////////////////////////
 #
 
 
-!!!! Redondances dans la phrase                                                                     
- 
+!!!! Redondances dans la phrase                                                                   !!
+
 __[i]/redon2(redondances_phrase)__
     ({w_4})[ ,].* (\1)  @@0,$
-    <<- not morph(\1, ":(?:G|V0)|>même ", False) -2>> _             # Dans cette phrase, répétition de « \1 » (à gauche).
+    <<- not morph(\1, ":(?:G|V0)|>même/", False) -2>> _             # Dans cette phrase, répétition de « \1 » (à gauche).
     <<- __also__ -1>> _                                             # Dans cette phrase, répétition de « \1 » (à droite).
 
 TEST: __redon2__ Quelle {{imposture}}, c’est d’un ennui, c’est une {{imposture}}.
 TEST: __redon2__ ils sont là côte à côte.
 TEST: __redon2__ Tu avances petit à petit, et tu réussis.
@@ -5914,11 +8186,11 @@
 
 
 
 !!
 !!
-!!!! Groupe nominal (1)                                                                             
+!!!! Groupe nominal (1)                                                                           !!
 !!
 !!
 
 #### 1 mot
 
@@ -5956,15 +8228,15 @@
     <<- __also__ -1>> les                                                                           # Accord de nombre erroné : « \2 » est au pluriel.
 __[i]/gn(gn_le_accord2)__
     ({w_1}) +(le) +({w_2})  @@0,w,$
     <<- morph(\2, ":D", False) >>>
     <<- morphex(\3, ":[NAQ].*:f", ":(?:e|m|P|G|W|[123][sp]|Y)")
-        or ( morphex(\3, ":[NAQ].*:f", ":[me]") and morphex(\1, ":R", ">(?:e[tn]|ou) ") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
+        or ( morphex(\3, ":[NAQ].*:f", ":[me]") and morphex(\1, ":R", ">(?:e[tn]|ou)/") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
     -2>> =suggLesLa(\3)                                                                             # Accord de genre erroné : « \3 » est féminin.
     <<- __also__ and hasMasForm(\3) -3>> =suggMasSing(@, True)                                      # Accord de genre erroné : « \2 » est un déterminant masculin.
     <<- __else__ and morph(\3, ":[NAQ].*:p")
-        or ( morphex(\3, ":[NAQ].*:p", ":[si]") and morphex(\1, ":[RC]", ">(?:e[tn]|ou)") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
+        or ( morphex(\3, ":[NAQ].*:p", ":[si]") and morphex(\1, ":[RC]", ">(?:e[tn]|ou)/") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
     -3>> =suggMasSing(@)                                                                            # Accord de nombre erroné : « \3 » devrait être au singulier.
     <<- __also__ -2>> les                                                                           # Accord de nombre erroné : « \3 » est au pluriel.
 __[i]/gn(gn_le_accord3)__
     ^ *(le) +({w_2}) @@*,$
     <<- morphex(\2, ":[NAQ].*:f", ":(?:e|m|P|G|W|Y)") -1>> =suggLesLa(\2)                           # Accord de genre erroné : « \2 » est féminin.
@@ -6047,15 +8319,15 @@
     <<- __else__ and morph(\2, ":[NAQ].*:p") -2>> =suggFemSing(@)                                   # Accord de nombre erroné : « \2 » devrait être au singulier.
 __[i]/gn(gn_la_accord2)__
     ({w_1}) +(la) +({w_2})  @@0,w,$
     <<- morph(\2, ":D", False) >>>
     <<- morphex(\3, ":[NAQ].*:m", ":(?:e|f|P|G|W|[1-3][sp]|Y)")
-        or ( morphex(\3, ":[NAQ].*:m", ":[fe]") and morphex(\1, ":[RC]", ">(?:e[tn]|ou) ") and not (morph(\1, ":(?:Rv|C)", False) and morph(\3, ":Y", False)) )
+        or ( morphex(\3, ":[NAQ].*:m", ":[fe]") and morphex(\1, ":[RC]", ">(?:e[tn]|ou)/") and not (morph(\1, ":(?:Rv|C)", False) and morph(\3, ":Y", False)) )
     -2>> le                                                                                         # Accord de genre erroné : « \3 » est masculin.
     <<- __also__ and hasFemForm(\3) -3>> =suggFemSing(@, True)                                      # Accord de genre erroné : « \2 » est un déterminant féminin.
     <<- __else__ and morph(\3, ":[NAQ].*:p")
-        or ( morphex(\3, ":[NAQ].*:p", ":[si]") and morphex(\1, ":[RC]", ">(?:e[tn]|ou)") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
+        or ( morphex(\3, ":[NAQ].*:p", ":[si]") and morphex(\1, ":[RC]", ">(?:e[tn]|ou)/") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
     -3>> =suggFemSing(@)                                                                            # Accord de nombre erroné : « \3 » devrait être au singulier.
 __[i]/gn(gn_la_accord3)__
     ^ *(la) +({w_2})  @@*,$
     <<- morphex(\2, ":[NAQ].*:m", ":[efPGWY]") -1>> le                                              # Accord de genre erroné : « \2 » est masculin.
     <<- __also__ and hasFemForm(\2) -2>> =suggFemSing(@, True)                                      # Accord de genre erroné : « \1 » est un déterminant féminin.
@@ -6157,11 +8429,11 @@
     <<- morph(\2, ":[NAQ].*:p") -1>> leurs                                                          # Accord de nombre erroné avec « \2 ».
     <<- __also__ -2>> =suggSing(@)                                                                  # Accord de nombre erroné : « \2 » devrait être au singulier.
 __[i]/gn(gn_leur_accord2)__
     ({w_1}) +(leur) +({w_2})  @@0,w,$
     <<- morph(\3, ":[NAQ].*:p")
-        or ( morphex(\3, ":[NAQ].*:p", ":[si]") and morphex(\1, ":[RC]|>de ", ">(?:e[tn]|ou)") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
+        or ( morphex(\3, ":[NAQ].*:p", ":[si]") and morphex(\1, ":[RC]|>de/", ">(?:e[tn]|ou)/") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False)) )
     -2>> leurs                                                                                      # Accord de nombre erroné avec « \3 ».
     <<- __also__ -3>> =suggSing(@)                                                                  # Accord de nombre erroné : « \3 » devrait être au singulier.
 __<i]/gn(gn_leur_accord3)__
     ^ *(leur) +({w_2})  @@*,$
     <<- morphex(\2, ":[NAQ].*:p", ":[siGW]") -1>> leurs                                             # Accord de nombre erroné avec « \1 ».
@@ -6196,11 +8468,11 @@
     -2>> =suggPlur(@)                                                                               # Accord de nombre erroné : « \2 » devrait être au pluriel.
 __[i]/gn(gn_les_accord2)__
     ({w_1}) +(les) +({w_2})  @@0,w,$
     <<- morph(\2, ":D", False) >>>
     <<- ( morph(\3, ":[NAQ].*:s")
-        or (morphex(\3, ":[NAQ].*:s", ":[pi]|>avoir") and morphex(\1, ":[RC]", ">(?:e[tn]|ou) ") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False))) )
+        or (morphex(\3, ":[NAQ].*:s", ":[pi]|>avoir") and morphex(\1, ":[RC]", ">(?:e[tn]|ou)/") and not (morph(\1, ":Rv", False) and morph(\3, ":Y", False))) )
         and not (after("^ +(?:et|ou) ") and morph(word(2), ":[NAQ]", True, False))
     -3>> =suggPlur(@)                                                                               # Accord de nombre erroné : « \3 » devrait être au pluriel.
 __[i]/gn(gn_les_accord3)__
     ^ *(les) +({w_2})  @@w,$
     <<- (morphex(\2, ":[NAQ].*:s", ":[ipYPGW]")
@@ -6485,20 +8757,20 @@
 
 
 ##  trouver ça/ceci/cela + adj
 __[i]/gn(gn_trouver_ça_adj)__
     (trouv\w+) +(ça|ce(?:ci|la)) +({w_2})  @@0,w,$
-    <<- morph(\1, ">trouver ", False) and morphex(\3, ":A.*:(?:f|m:p)", ":(?:G|3[sp]|M[12P])")
+    <<- morph(\1, ">trouver/", False) and morphex(\3, ":A.*:(?:f|m:p)", ":(?:G|3[sp]|M[12P])")
     -3>> =suggMasSing(@)                                                                            # Trouver \2 + [adjectif] : l’adjectif s’accorde avec “\2” (au masculin singulier).
 
 TEST: ils trouvent ça de plus en plus {{idiots}}              ->> idiot
 
 
 
 !!
 !!
-!!!! Groupe nominal (2)                                                                             
+!!!! Groupe nominal (2)                                                                           !!
 !!
 !!
 
 ## Sans article
 
@@ -6599,11 +8871,11 @@
     <<- __also__ and hasFemForm(\1) -1>> =switchGender(@)                                           # Accord de genre erroné avec « \2 ».
     <<- not re.search("(?i)^air$", \1) and not \2.startswith("seul")
         and morph(\1, ":[si]") and morph(\2, ":[NAQ].*:p")
         and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]", False, False)
     -2>> =suggSing(@)                                                                               # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
-    
+
 TEST: L’{{amande}} {{amer}}
 TEST: l’{{amicale}} {{animal}}
 TEST: du chien et de l’{{excellente}} {{collier}} qu’il avait autour du cou.
 TEST: du chien et de l’{{étonnante}} {{collier}} qu’il avait autour du cou.
 
@@ -6622,15 +8894,15 @@
 __[i]/gn(gn_2m_un_après_et_ou_de)__
     (?:et +|ou +|d’)un +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[me]", ":(?:B|G|V0|f)") and morph(\2, ":[NAQ].*:f")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \1 » est masculin, « \2 » est féminin.
     <<- morphex(\1, ":[NAQ].*:[si]", ":G") and morph(\2, ":[NAQ].*:p") and not \2.startswith("seul")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQB]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQB]|>(?:et|ou)/", False, False)
     -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 
 TEST: un exercice pas très {{utiles}}.                        ->> utile
 TEST: un homme {{grands}}                                     ->> grand
 TEST: un homme {{futiles}}                                    ->> futile
@@ -6651,15 +8923,15 @@
 __[i]/gn(gn_2m_une_après_et_ou_de)__
     (?:et +|ou +|d’)une +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[fe]", ":(?:B|G|V0|m)") and morph(\2, ":[NAQ].*:m")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggFemSing(@, True)                                                                      # Accord de genre erroné : « \1 » est féminin, « \2 » est masculin.
     <<- \1 != "fois" and morph(\1, ":[NAQ].*:[si]", False) and morph(\2, ":[NAQ].*:p") and not \2.startswith("seul")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQB]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQB]|>(?:et|ou)/", False, False)
     -2>> =suggFemSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 
 TEST: Une grande {{homme}}.
 TEST: une géologue {{intelligents}}
 TEST: Et une femme {{déterminées}}
@@ -6674,25 +8946,25 @@
     <<- morph(\1, ":D", False) >>>
     <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[me]", ":(?:B|G|V0)") and morph(\3, ":[NAQ].*:f")
         and not apposition(\2, \3) and not before(r"\b(?:et|ou|de) +$")
     -3>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \2 » est masculin, « \3 » est féminin.
-    <<- not \3.startswith("seul") 
+    <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[si]", ":G") and morphex(\3, ":[NAQ].*:p", ":[GWsi]")
         and not apposition(\2, \3) and not before(r"\b(?:et|ou|de) +$")
     -3>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \2 » : « \3 » devrait être au singulier.
 __[i]/gn(gn_2m_le_après_et_ou_de)__
     (?:et|ou) +(le) +({w_2}) +({w_2})  @@w,w,$
     <<- morph(\1, ":D", False) >>>
     <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[me]", ":(?:B|G|V0|f)") and morph(\3, ":[NAQ].*:f")
-        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -3>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \2 » est masculin, « \3 » est féminin.
     <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[si]", ":G") and morphex(\3, ":[NAQ].*:p", ":[GWsi]")
-        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
-    -3>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \2 » : « \3 » devrait être au singulier.    
+        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
+    -3>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \2 » : « \3 » devrait être au singulier.
 
 TEST: le test très {{cons}} qu’on a passé hier.
 TEST: c’était le chien {{perdue}} des voisins.
 TEST: viens vite ou le pari {{imperdables}} sera moins facile…
 
@@ -6701,24 +8973,24 @@
     (?<!et |ou |de )(?:cet?|quel|au|ledit) +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[me]", ":(?:B|G|V0)") and morph(\2, ":[NAQ].*:f")
         and not apposition(\1, \2) and not before(r"\b(?:et|ou|de) +$")
     -2>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \1 » est masculin, « \2 » est féminin.
-    <<- not \2.startswith("seul") 
+    <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[si]", ":G") and morphex(\2, ":[NAQ].*:p", ":[GWsi]")
         and not apposition(\1, \2) and not before(r"\b(?:et|ou|de) +$")
     -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 __[i]/gn(gn_2m_det_mas_sing_après_et_ou_de)__
     (?:et|ou|de) +(?:cet?|quel|au|ledit) +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[me]", ":(?:B|G|V0|f)") and morph(\2, ":[NAQ].*:f")
-        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \1 » est masculin, « \2 » est féminin.
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[si]", ":G") and morphex(\2, ":[NAQ].*:p", ":[GWsi]")
-        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
-    -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.    
+        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
+    -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 
 TEST: cet outil {{terribles}} qu’il a dans les mains
 TEST: J’aimerais connaître de quel parti {{gauchistes}} on parle.
 
 
@@ -6726,25 +8998,25 @@
     (?<!et |ou |de )[mts]on +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:m", ":(?:B|G|e|V0|f)") and morph(\2, ":[NAQ].*:f")
         and not apposition(\1, \2) and not before(r"\b(?:et|ou|de) +$")
     -2>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \1 » est masculin, « \2 » est féminin.
-    <<- not \2.startswith("seul") 
+    <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[si]", ":G") and morphex(\2, ":[NAQ].*:p", ":[GWsi]")
         and not apposition(\1, \2) and not before(r"\b(?:et|ou|de) +$")
     -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 __[i]/gn(gn_2m_mon_ton_son_après_et_ou_de)__
     (?:et|ou|de) +[mts]on +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:m", ":(?:B|G|e|V0|f)") and morph(\2, ":[NAQ].*:f")
-        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggMasSing(@, True)                                                                      # Accord de genre erroné : « \1 » est masculin, « \2 » est féminin.
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[si]", ":G") and morphex(\2, ":[NAQ].*:p", ":[GWsi]")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
-    -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.    
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
+    -2>> =suggMasSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 
 TEST: il brandissait avec fougue son drapeau {{déchirés}}
 TEST: comment osez-vous médire de mon héritage {{glorieuse}}
 
 
@@ -6753,24 +9025,24 @@
     <<- morph(\1, ":D", False) >>>
     <<- \2 != "fois" and not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[fe]", ":(?:B|G|V0)") and morph(\3, ":[NAQ].*:m")
         and not apposition(\2, \3) and not before(r"\b(?:et|ou|de) +$")
     -3>> =suggFemSing(@, True)                                                                      # Accord de genre erroné : « \2 » est féminin, « \3 » est masculin.
-    <<- not \3.startswith("seul") 
+    <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[si]", ":G") and morphex(\3, ":[NAQ].*:p", ":[GWsi]")
         and not apposition(\2, \3) and not before(r"\b(?:et|ou|de) +$")
     -3>> =suggFemSing(@)                                                                            # Accord de nombre erroné avec « \2 » : « \3 » devrait être au singulier.
 __[i]/gn(gn_2m_la_après_et_ou_de)__
     (?:et|ou|de) +(la) +({w_2}) +({w_2})  @@w,w,$
     <<- morph(\1, ":D", False) >>>
     <<- \2 != "fois" and not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[fe]", ":(?:B|G|V0|m)") and morph(\3, ":[NAQ].*:m")
-        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -3>> =suggFemSing(@, True)                                                                      # Accord de genre erroné : « \2 » est féminin, « \3 » est masculin.
     <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[si]", ":G") and morphex(\3, ":[NAQ].*:p", ":[GWsi]")
-        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -3>> =suggFemSing(@)                                                                            # Accord de nombre erroné avec « \2 » : « \3 » devrait être au singulier.
 
 TEST: La plus grande {{cinglé}}.
 TEST: il imaginait de la pluie {{noir}} tombant sur une terre dévastée.
 
@@ -6787,15 +9059,15 @@
     -2>> =suggFemSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 __[i]/gn(gn_2m_det_fem_sing_après_et_ou_de)__
     (?:et|ou|de) +(?:[mts]a|cette|quelle|ladite) +({w_2}) +({w_2})  @@w,$
     <<- \1 != "fois" and not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[fe]", ":(?:B|G|V0|m)") and morph(\2, ":[NAQ].*:m")
-        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggFemSing(@, True)                                                                      # Accord de genre erroné : « \1 » est féminin, « \2 » est masculin.
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[si]", ":G") and morphex(\2, ":[NAQ].*:p", ":[GWsi]")
-        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggFemSing(@)                                                                            # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 
 TEST: quelle belle {{étourdi}}, cette gamine
 TEST: j’en ai assez de cette ville {{stressées}} en permanence.
 TEST: Peut-on imaginer de plus {{beaux}} {{enfant}} ?
@@ -6817,16 +9089,16 @@
     (?:et|ou|de) +(leur) +({w_2}) +({w_2})  @@w,w,$
     <<- morph(\1, ":D", False) >>>
     <<- \2 != "fois" and not \3.startswith("seul")
         and ((morphex(\2, ":[NAQ].*:m", ":(?:B|e|G|V0|f)") and morph(\3, ":[NAQ].*:f")) or (morphex(\2, ":[NAQ].*:f", ":(?:B|e|G|V0|m)") and morph(\3, ":[NAQ].*:m")))
         and not apposition(\2, \3)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -3>> =switchGender(@, False)                                                                    # Accord de genre erroné entre « \2 » et « \3 ».
     <<- __also__ and hasFemForm(\2) -1>> =switchGender(@, False)                                    # Accord de genre erroné avec « \3 ».
     <<- not \3.startswith("seul")
         and morphex(\2, ":[NAQ].*:[si]", ":G") and morphex(\3, ":[NAQ].*:p", ":[GWsi]")
-        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\2, \3) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -3>> =suggSing(@)                                                                               # Accord de nombre erroné avec « \2 » : « \3 » devrait être au singulier.
 
 TEST: leur puissance {{perdues}}
 TEST: leur arbre {{élaguée}}
 TEST: je me souviens de leur verve {{décalé}}
@@ -6847,16 +9119,16 @@
 __[i]/gn(gn_2m_det_epi_sing_après_et_ou_de)__
     (?:et|ou|de) +(?:chaque|quelque|[nv]otre) +({w_2}) +({w_2})  @@w,$
     <<- \1 != "fois" and not \2.startswith("seul") and not re.search("(?i)quelque chose", \0)
         and ((morphex(\1, ":[NAQ].*:m", ":(?:B|e|G|V0|f)") and morph(\2, ":[NAQ].*:f")) or (morphex(\1, ":[NAQ].*:f", ":(?:B|e|G|V0|m)") and morph(\2, ":[NAQ].*:m")))
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =switchGender(@, False)                                                                    # Accord de genre erroné entre « \1 » et « \2 ».
     <<- __also__ and hasFemForm(\1) -1>> =switchGender(@, False)                                    # Accord de genre erroné avec « \2 ».
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[si]", ":G") and morphex(\2, ":[NAQ].*:p", ":[GWsi]")
-        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not apposition(\1, \2) and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggSing(@)                                                                               # Accord de nombre erroné avec « \1 » : « \2 » devrait être au singulier.
 
 TEST: chaque élément {{terrestres}}
 TEST: ils viennent de chaque coin {{ignorée}} du pays.
 
@@ -6875,11 +9147,11 @@
 __[i]/gn(gn_2m_det_mas_plur_après_et_ou_de)__
     (?:et|ou|de) +(?:certains|quels|lesdits) +({w_2}) +({w_2})  @@w,$
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[me]", ":(?:B|G|V0|f)") and morph(\2, ":[NAQ].*:f")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggMasPlur(@, True)                                                                      # Accord de genre erroné : « \1 » est masculin, « \2 » est féminin.
     <<- not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[pi]", ":G") and morph(\2, ":[NAQ].*:s")
         and not apposition(\1, \2) and not (after_chk1(r"^ +et +(\w[\w-]+)", ":A") or after_chk1(r"^ *, +(\w[\w-]+)", ":A.*:[si]"))
         and not ( before(r"(?i)\bune? de ") or (\0.startswith("de") and before(r"(?i)\bune? +$")) )
@@ -6905,11 +9177,11 @@
 __[i]/gn(gn_2m_det_fem_plur_après_et_ou_de)__
     (?:et|ou|de) +(?:certaines|quelles|lesdites) +({w_2}) +({w_2})  @@w,$
     <<- \1 != "fois" and not \2.startswith("seul")
         and morphex(\1, ":[NAQ].*:[fe]", ":(?:B|G|V0|m)") and morph(\2, ":[NAQ].*:m")
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =suggFemPlur(@, True)                                                                      # Accord de genre erroné : « \1 » est féminin, « \2 » est masculin.
     <<- not \2.startswith("seul")
         and morph(\1, ":[NAQ].*:[pi]", False) and morph(\2, ":[NAQ].*:s")
         and not apposition(\1, \2) and not (after_chk1(r"^ +et +(\w[\w-]+)", ":A") or after_chk1(r"^ *, +(\w[\w-]+)", ":A.*:[si]"))
         and not ( before(r"(?i)\bune? de ") or (\0.startswith("de") and before(r"(?i)\bune? +$")) )
@@ -6935,11 +9207,11 @@
     (?:et|ou) +(les) +({w_2}) +({w_2})  @@w,w,$
     <<- morph(\1, ":D", False) >>>
     <<- \2 != "fois" and not \3.startswith("seul")
         and ((morphex(\2, ":[NAQ].*:m", ":(?:B|e|G|V0|f)") and morph(\3, ":[NAQ].*:f")) or (morphex(\2, ":[NAQ].*:f", ":(?:B|e|G|V0|m)") and morph(\3, ":[NAQ].*:m")))
         and not apposition(\2, \3)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -3>> =switchGender(@, True)                                                                     # Accord de genre erroné entre « \2 » et « \3 ».
     <<- __also__ and hasFemForm(\2) -2>> =switchGender(@, True)                                     # Accord de genre erroné avec « \3 ».
     <<- \2 != "fois" and not \3.startswith("seul")
         and morph(\2, ":[NAQ].*:[pi]", False) and morph(\3, ":[NAQ].*:s")
         and not apposition(\2, \3) and not (after_chk1(r"^ +et +(\w[\w-]+)", ":A") or after_chk1(r"^ *, +(\w[\w-]+)", ":A.*:[si]"))
@@ -6965,11 +9237,11 @@
 __[i]/gn(gn_2m_det_epi_plur_après_et_ou_de)__
     (?:et|ou|de) +(?:[cmts]es|[nv]os|leurs|quelques|plusieurs|aux|moult) +({w_2}) +({w_2})  @@w,$
     <<- \1 != "fois" and not \2.startswith("seul")
         and ((morphex(\1, ":[NAQ].*:m", ":(?:B|e|G|V0|f)") and morph(\2, ":[NAQ].*:f")) or (morphex(\1, ":[NAQ].*:f", ":(?:B|e|G|V0|m)") and morph(\2, ":[NAQ].*:m")))
         and not apposition(\1, \2)
-        and not morph(word(-1), ":[NAQ]|>(?:et|ou) ", False, False)
+        and not morph(word(-1), ":[NAQ]|>(?:et|ou)/", False, False)
     -2>> =switchGender(@, True)                                                                     # Accord de genre erroné entre « \1 » et « \2 ».
     <<- __also__ and hasFemForm(\1) -1>> =switchGender(@, True)                                     # Accord de genre erroné avec « \2 ».
     <<- \1 != "fois" and not \2.startswith("seul")
         and morph(\1, ":[NAQ].*:[pi]", False) and morph(\2, ":[NAQ].*:s")
         and not apposition(\1, \2) and not (after_chk1(r"^ +et +(\w[\w-]+)", ":A") or after_chk1(r"^ *, +(\w[\w-]+)", ":A.*:[si]"))
@@ -6986,16 +9258,16 @@
 __[i]/gn(gn_2m_des)__
     des +({w_2}) +({w_2})  @@w,$
     <<- \1 != "fois" and not \2.startswith("seul")
         and ( (morphex(\1, ":[NAQ].*:m", ":[fe]") and morph(\2, ":[NAQ].*:f")) or (morphex(\1, ":[NAQ].*:f", ":[me]") and morph(\2, ":[NAQ].*:m")) )
         and not apposition(\1, \2) and not (after_chk1(r"^ +et +(\w[\w-]+)", ":A") or after_chk1(r"^ *, +(\w[\w-]+)", ":A.*:[si]"))
-        and morph(word(-1), ":[VRBX]|>comme ", True, True)
+        and morph(word(-1), ":[VRBX]|>comme/", True, True)
     -2>> =switchGender(@, True)                                                                     # Accord de genre erroné avec « \1 ».
     <<- __also__ and hasFemForm(\1) -1>> =switchGender(@)                                           # Accord de genre erroné avec « \2 ».
     <<- morph(\1, ":[NAQ].*:[pi]", False) and morph(\2, ":[NAQ].*:s")
         and not apposition(\1, \2) and not (after_chk1(r"^ +et +(\w[\w-]+)", ":A") or after_chk1(r"^ *, +(\w[\w-]+)", ":A.*:[si]"))
-        and (morphex(\2, ":N", ":[AQ]") or morph(word(-1), ":[VRBX]|>comme ", True, True))
+        and (morphex(\2, ":N", ":[AQ]") or morph(word(-1), ":[VRBX]|>comme/", True, True))
     -2>> =suggPlur(@)                                                                               # Accord de nombre erroné avec « \1 » : « \2 » devrait être au pluriel.
     <<- checkAgreement(\1, \2) =>> =exclude(\2, ":V")
 
 TEST: faire table rase des passions {{inutile}}               ->> inutiles
 TEST: à bonne distance des {{chiens}} {{méchante}}
@@ -7011,11 +9283,11 @@
 
 
 
 !!
 !!
-!!!! Groupe nominal (3)                                                                             
+!!!! Groupe nominal (3)                                                                           !!
 !!
 !!
 
 ## nombre
 
@@ -7065,11 +9337,11 @@
 
 
 
 !!
 !!
-!!!! Groupe nominal: Accords avec de / des / du                                                     
+!!!! Groupe nominal: Accords avec de / des / du                                                   !!
 !!
 !!
 
 __[i]/gn(gn_devinette1)__
     (?:[lmts]a|une|cette) +{w_2} +d(?:e (?:[lmts]a|cette)|’une) +(?!des )({w_2}) +({w_2})  @@w,$
@@ -7127,11 +9399,11 @@
 
 
 
 !!
 !!
-!!!! Singuliers & Pluriels                                                                          
+!!!! Singuliers & Pluriels                                                                        !!
 !!
 !!
 
 #### Prépositions
 
@@ -7260,11 +9532,11 @@
 #### Locutions
 
 # à
 __[i]/sgpl(sgpl_à_nu)__
     (m[eiî]\w+) +([aà] nu(?:es?|s))  @@0,$
-    <<- morph(\1, ">(?:mettre|mise) ", False) -2>> à nu                     # « nu » est invariable dans cette locution.
+    <<- morph(\1, ">(?:mettre|mise)/", False) -2>> à nu                     # « nu » est invariable dans cette locution.
 
 TEST: Mettre {{à nus}} les hommes.
 
 __[i]/sgpl(sgpl_à_part_égales)__
     à part? égale? <<- ->> à parts égales                                   # Il y a plusieurs parts.
@@ -7280,14 +9552,14 @@
 # affaires
 __[i]/sgpl(sgpl_chiffre_d_affaires)__
     chiffres? d’(affaire) @@$ <<- -1>> affaires                             # Le chiffre d’affaires. Toujours un “s” final.
 __[i]/sgpl(sgpl_faire_affaire_avec)__
     (f[aieî]\w+) (affaires) avec  @@0,w
-    <<- morph(\1, ">faire ", False) -2>> affaire                            # « Faire affaire avec ». Pas de “s”.
+    <<- morph(\1, ">faire/", False) -2>> affaire                            # « Faire affaire avec ». Pas de “s”.
 __[u]/sgpl(sgpl_faire_affaire_à_en)__
     (f[aieî]\w+) (affaire) (?:à|en) ([A-ZÉÈÂ][\w-]+)  @@0,w,$
-    <<- morph(\1, ">faire ", False) and morph(\3, ":(?:N|MP)")
+    <<- morph(\1, ">faire/", False) and morph(\3, ":(?:N|MP)")
     -2>> affaires                                                           # Ajoutez un “s” à « affaire ».
 
 TEST: Quel est son chiffre d’{{affaire}} ?
 TEST: Allez-vous faire {{affaires}} avec ces connards ?
 TEST: Faire {{affaire}} à Paris.
@@ -7342,20 +9614,20 @@
 
 
 # coûter cher
 __[i]/sgpl(sgpl_coûter_cher)__
     ((?:co[uû]t|pa)\w+) +(chers|chères?|chaire?s?)  @@0,$
-    <<- morph(\1, ">(?:co[ûu]ter|payer) ", False)
+    <<- morph(\1, ">(?:co[ûu]ter|payer)/", False)
     -2>> cher                                                                       # Ici, « cher » est un adverbe, invariable.
 
 TEST: ces saloperies coûtent vraiment {{chères}} !
 
 
 # donner lieu
 __[i]/sgpl(sgpl_donner_lieu)__
     (donn\w+) +(lieux) @@0,$
-    <<- morph(\1, ">donner ", False)
+    <<- morph(\1, ">donner/", False)
     -2>> lieu                                                                       # « Donner lieu » : “lieu” est invariable dans cette locution verbale.
 
 TEST: ces conneries donneront {{lieux}} à une enquête approfondie.
 
 
@@ -7367,11 +9639,11 @@
 
 
 # ensemble
 __[i]/sgpl(sgpl_ensemble)__
     ({w_1}) +(ensembles)  @@0,$
-    <<- morphex(\1, ":V.*:[123]p|>(?:tou(?:te|)s|pas|rien|guère|jamais|toujours|souvent) ", ":[DRB]")
+    <<- morphex(\1, ":V.*:[123]p|>(?:tou(?:te|)s|pas|rien|guère|jamais|toujours|souvent)/", ":[DRB]")
     -2>> ensemble                                                                   # S’il s’agit bien de l’adverbe “ensemble”, il est invariable.|https://fr.wiktionary.org/wiki/ensemble
 
 TEST: Elles viendront {{ensembles}}.
 
 
@@ -7398,11 +9670,11 @@
 
 
 # pied
 __[i]/sgpl(sgpl_avoir_pied)__
     ([aeop]\w*) +(?:pas |)(pieds)  @@0,$
-    <<- morph(\1, ">(?:avoir|perdre) ", False) -2>> pied                            # Pas de “s” final.
+    <<- morph(\1, ">(?:avoir|perdre)/", False) -2>> pied                            # Pas de “s” final.
 __[i]/sgpl(sgpl_à_pied)__
     à (pieds)  @@2
     <<- not before(r"(?i)\b(?:lit|fauteuil|armoire|commode|guéridon|tabouret|chaise)s?\b")
     -1>> pied                                                                       # Pas de “s” final.
 __[i]/sgpl(sgpl_au_pied_levé)__
@@ -7494,11 +9766,11 @@
 # vacances
 __[i]/sgpl(sgpl_bonnes_vacances)__
     bonne vacance <<- not morph(word(-1), ":D.*:f:s", False, False) ->> bonnes vacances             # Au pluriel.
 __[i]/sgpl(sgpl_en_vacances)__
     ({w1}) +en (vacance)  @@0,$
-    <<- morph(\1, ">(?:aller|partir) ", False) -2>> vacances                                        # Si vous parlez des congés, « vacance » doit être au pluriel.
+    <<- morph(\1, ">(?:aller|partir)/", False) -2>> vacances                                        # Si vous parlez des congés, « vacance » doit être au pluriel.
 
 TEST: Je pars en {{vacance}}.
 TEST: {{Bonne vacance}} !
 TEST: Il nous reste un poste en vacance.
 TEST: Cette place est en vacance.
@@ -7525,26 +9797,26 @@
 
 
 
 !!
 !!
-!!!! Confusions                                                                                     
+!!!! Confusions                                                                                   !!
 !!
 !!
 
 # à / a
 __[i]/conf(conf_suite_à)__
     suite (a) ({w1}) @@w,$
-    <<- morph(\2, ":D|>[ld] ", False) and isStart() -1>> à          # Confusion : “a” est une forme conjuguée du verbe “avoir”. Pour la préposition, écrivez “à”.
+    <<- morph(\2, ":D|>[ld]/", False) and isStart() -1>> à          # Confusion : “a” est une forme conjuguée du verbe “avoir”. Pour la préposition, écrivez “à”.
 
 TEST: Suite {{a}} ces folies, nous rentrâmes chez nous.
 TEST: il s’avère que, suite {{a}} d’horribles complications, nous renonçâmes.
 
 
 __[i]/conf(conf_pronom_à_l_air)__
     (?:tout|ça|ce(?:ci|la)) (à) l’air +({w_2})  @@w,$
-    <<- morphex(\2, ":[AR]", ">libre ") and morph(word(-1), ":Cs", False, True)
+    <<- morphex(\2, ":[AR]", ">libre/") and morph(word(-1), ":Cs", False, True)
     -1>> a                                                          # Confusion probable : “à” est une préposition. Pour le verbe “avoir”, écrivez “a”.
 
 TEST: lorsque tout {{à}} l’air fini, c’est trompeur.
 TEST: Tout {{à}} l’air complètement foutu…
 TEST: Ça {{à}} l’air génial.
@@ -7579,21 +9851,21 @@
 TEST: un terrain de 3 {{âcres}}.
 
 
 __[i]/conf(conf_âcre)__
     acres?
-    <<- morph(word(-1), ">(?:être|go[ûu]t|humeur|odeur|parole|parfum|remarque|reproche|réponse|saveur|senteur|sensation|vin)", False, False)
+    <<- morph(word(-1), ">(?:être|go[ûu]t|humeur|odeur|parole|parfum|remarque|reproche|réponse|saveur|senteur|sensation|vin)/", False, False)
     ->> =\0.replace("a", "â").replace("A", "Â")
     # Confusion probable : “acre” est une unité de surface agraire. Pour l’adjectif signifiant “irritant”, écrivez :|https://fr.wiktionary.org/wiki/%C3%A2cre
-    
+
 TEST: Il avait ce goût {{acre}} dans la bouche qui ne passait pas.
 
 
 # accro / accroc
 __[i]/conf(conf_être_accro)__
     ({etre}|dev\w+|sembl\w+|par\w+|rend\w+) +(accrocs?)  @@0,$
-    <<- morph(\1, ">(?:être|devenir|para[îi]tre|rendre|sembler) ", False)
+    <<- morph(\1, ">(?:être|devenir|para[îi]tre|rendre|sembler)/", False)
     -2>> =\2.replace("oc", "o")
     # Confusion : “accroc” signifie “déchirure”, “incident”, etc. tandis que “accro” est un terme familier qui signifie “dépendant”.
 __[i]/conf(conf_accro_à)__
     (accrocs?) (?:[àa] (?:la (?:bouffe|cocaïne|cod[ée]ine|course|drogue|coke|meth|méthamphétamine|morphine|nicotine|nourriture|télé(?:vision|)|clope|cigarette|came|poudre|baise|musique)|cette (?:came|émission|merde|poudre|femme|meuf|gonzesse|conne|salope|garce)|ce (?:mec|keum|type|con(?:nard|)|fils de pute)|cet (?:homme|enculé|imbécile|enfoiré)|l’(?:alcool|amour|argent|ecstasy|herbe|héro(?:ïne|)|opium|ordi(?:nateur|))|Facebook|Internet|Twitter|lui|elle)|[ad]u (?:chocolat|cul|jeu|poker|sexe|shopping|smartphone|sport|sucre|tabac|téléphone|travail|LSD|crack)|aux (?:anti-?dépresseurs|bonbons|hommes|mecs|femmes|gonzesses|méd(?:icaments|ocs)|jeux|séries|sucreries))
     @@0
@@ -7613,11 +9885,11 @@
 __[i]/conf(conf_par_acquit_de_conscience)__
     par (acquis) de conscience  @@4
     <<- -1>> acquit                                                                                 # Confusion. On écrit « par acquit de conscience ».
     <<- ~>> *
 __[i]/conf(conf_tenir_pour_acquit)__
-    (t\w+) +pour (acquits?) @@0,$ <<- morph(\1, ">tenir ") -2>> acquis                              # Confusion. On écrit « tenir pour acquis ».
+    (t\w+) +pour (acquits?) @@0,$ <<- morph(\1, ">tenir/") -2>> acquis                              # Confusion. On écrit « tenir pour acquis ».
 
 TEST: Je le tenais pour {{acquit}}.
 TEST: Par {{acquis}} de conscience.
 
 
@@ -7637,24 +9909,24 @@
 
 # amende / amande
 __[i]/conf(conf_yeux_en_amande)__
     yeux en (amendes?) @@$ <<- -1>> amande                                                          # Confusion. Une amende est une peine.|http://www.cnrtl.fr/lexicographie/amende
 __[i]/conf(conf_à_l_amende)__
-    (m\w+) à (l’amande) @@0,$ <<- morph(\1, ">mettre ", False) -2>> l’amende                        # Confusion. L’amande est un fruit.
+    (m\w+) à (l’amande) @@0,$ <<- morph(\1, ">mettre/", False) -2>> l’amende                        # Confusion. L’amande est un fruit.
 __[i]/conf(conf_faire_amende_honorable)__
     (f\w+)(?:-(?:je|tu|ils?|[nv]ous|elles?)|) +(amandes? honorables?) @@0,$
-    <<- morph(\1, ">faire ", False) -2>> amende honorable                                           # Confusion. L’amande est un fruit.
+    <<- morph(\1, ">faire/", False) -2>> amende honorable                                           # Confusion. L’amande est un fruit.
 
 TEST: Avec ses beaux yeux en {{amendes}} nul ne peut lui résister.
 TEST: Nous avons déconné, nous avons été mis à {{l’amande}}.
 TEST: Ces gens-là ne feront jamais {{amande honorable}}.
 
 
 # annales / anal-e-s
 __[i]/conf(conf_annales1)__
     (anale?s?) (?:littéraires?|politiques?|ecclésiastiques?|du (?:bac(?:calauréat|)|brevet)|de (?:physique|chimie|mathématiques|biologie|géographie)|d’histoire)  @@0
-    <<- -1>> annales                                                 # Confusion : “\1” est l’adjectif relatif à l’anus.|http://fr.wiktionary.org/wiki/annales 
+    <<- -1>> annales                                                 # Confusion : “\1” est l’adjectif relatif à l’anus.|http://fr.wiktionary.org/wiki/annales
 __[i]/conf(conf_annales2)__
     [lcdmts]es (anale?s?)  @@4
     <<- -1>> annales                                                 # Confusion : “\1” est l’adjectif relatif à l’anus.|http://fr.wiktionary.org/wiki/annales
 
 TEST: des {{anales}} littéraires
@@ -7680,11 +9952,11 @@
     # Confusion probable. L’hospice est un centre de soins.|https://fr.wiktionary.org/wiki/auspice
 __[i]/conf(conf_sous_les_auspices2)__
     sous (?:les \w+|d’\w+|des? \w+) +(hospices) @@$ <<- -1>> auspices
     # Confusion probable. L’hospice est un centre de soins.|https://fr.wiktionary.org/wiki/auspice
 __[i]/conf(conf_hospice1)__
-    ({etre}|{aller}) +(?:à|dans) l’(auspice) @@0,$ <<- morph(\1, ">(?:être|aller) ", False) -2>> hospice
+    ({etre}|{aller}) +(?:à|dans) l’(auspice) @@0,$ <<- morph(\1, ">(?:être|aller)/", False) -2>> hospice
     # Confusion. Les auspices sont des présages, des devins ou, au sens moderne, les circonstances.|https://fr.wiktionary.org/wiki/auspice
 __[i]/conf(conf_hospice2)__
     dans (?:un|cet|[ldc]es) +(auspices?) @@$ <<- -1>> =\1.replace("auspice", "hospice")
     # Confusion. Les auspices sont des présages, des devins ou, au sens moderne, les circonstances.|https://fr.wiktionary.org/wiki/auspice
 __[i]/conf(conf_hospice3)__
@@ -7711,10 +9983,15 @@
 __[i]/conf(conf_avions)__
     nous (avion) @@5 <<- -1>> avions                                    # Confusion probable : l’avion est un appareil volant.
 
 TEST: Je pense que nous {{avion}} tort.
 
+
+# avoir faim / soif
+__[i]/conf(conf_a_à_faim_peur_honte_soif)__
+    (à) +(faim|peur|honte|soif) @@0,$ <<- -1>> a                        # Avoir “\2”. Confusion : “à” est une préposition. Pour le verbe avoir, écrivez :
+
 
 # banc / ban
 __[i]/conf(conf_arrière_ban)__
     arrière[ -]bancs?
     <<- ->> =\0.replace("c", "").replace("C", "")                       # Confusion. L’arrière-ban est une assemblée de nobles feudataires.|https://fr.wiktionary.org/wiki/arri%C3%A8re-ban
@@ -7727,15 +10004,15 @@
 __[i]/conf(conf_en_rupture_de_ban)__
     en ruptures? de (bancs?)  @@$
     <<- -1>> ban                                                        # Confusion. Locution “en rupture de ban”.|https://fr.wiktionary.org/wiki/en_rupture_de_ban
 __[i]/conf(conf_mettre_au_ban)__
     (m[eiî]\w+) au (banc)  @@0,$
-    <<- morph(\1, ">mettre ", False) and not after("^ +des accusés")
+    <<- morph(\1, ">mettre/", False) and not after("^ +des accusés")
     -2>> ban                                                            # Confusion : « mettre au ban » signifie « faire déchoir ».|https://fr.wiktionary.org/wiki/mettre_au_ban
 __[i]/conf(conf_publier_les_bans)__
     (publi\w+) [dlcmts]es (bancs) @@0,$
-    <<- morph(\1, ">publi(?:er|cation) ", False) -2>> bans              # Confusion.|https://fr.wikipedia.org/wiki/Publication_des_bans
+    <<- morph(\1, ">publi(?:er|cation)/", False) -2>> bans              # Confusion.|https://fr.wikipedia.org/wiki/Publication_des_bans
 
 TEST: Convoquons le ban et l’{{arrière-banc}}.
 TEST: il faut publier les {{bancs}} avant qu’il ne soit trop tard.
 TEST: Les {{bancs}} de mariage sont prêts.
 TEST: des hommes en rupture de {{banc}}
@@ -7812,11 +10089,11 @@
 __[i]/conf(conf_nom_de_cane)__
     (?:œuf|filet)s? de (cannes?) @@$ <<- -1>> cane
     # Confusion. La canne est un bâton ou un roseau. Pour la femelle du canard, écrivez|https://fr.wiktionary.org/wiki/canne
 __[i]/conf(conf_verbe_canne)__
     ((?:appu|batt|frapp|l[eè]v|march)\w+) (?:avec|sur) (?:[dl]es|[mts](?:a|es)|une) (canes?)  @@0,$
-    <<- morph(\1, ">(?:appuyer|battre|frapper|lever|marcher) ", False)
+    <<- morph(\1, ">(?:appuyer|battre|frapper|lever|marcher)/", False)
     -2>> =\2.replace("cane", "canne")
     # Confusion. La cane est la femelle du canard.|https://fr.wiktionary.org/wiki/cane
 __[i]/conf(conf_bec_de_cane)__
     becs?-de-(cannes?) @@$ <<- -1>> cane
     # Confusion. Le bec-de-cane se somme ainsi à cause de la ressemblance avec le bec de l’animal.|https://fr.wiktionary.org/wiki/bec-de-cane
@@ -7840,11 +10117,11 @@
 
 
 # chair / chère
 __[i]/conf(conf_faire_bonne_chère)__
     (f[aioîe]\w+) +(bonnes? ch(?:ai|e)re?) @@0,$
-    <<- morph(\1, ">faire ", False)
+    <<- morph(\1, ">faire/", False)
     -2>> bonne chère                                                    # Confusion. « Faire bonne chère » signifie bien manger, ripailler.
 
 TEST: ils ont fait {{bonne chaire}}.
 
 
@@ -7929,16 +10206,21 @@
     (c[ôo]tes?) de mailles?  @@0
     <<- -1>> =\1.replace("ô", "o").replace("t", "tt")           # Confusion : écrivez « cotte » pour la cotte de mailles.|https://fr.wiktionary.org/wiki/cotte_de_mailles
 __[i]/conf(conf_avoir_la_cote)__
     ({avoir}) +la (côte)  @@0,$
     <<- morph(\1, ":V0a", False) -2>> cote                      # Confusion probable : utilisez « cote » (cotation).|http://fr.wiktionary.org/wiki/cote
+__[i](conf_côte_à_côte)__
+    c[ôo]tt?es? [àaá] c[ôo]tt?es?
+    <<- not re.search("(?i)^côte à côte$", \0) ->> côte à côte      # Locution adverbiale invariable. Écrivez “côte à côte”.|https://fr.wiktionary.org/wiki/c%C3%B4te_%C3%A0_c%C3%B4te
+    <<- ~>> *
 
 TEST: Rien ne vaut une bonne {{cote}} de bœuf.
 TEST: Elles ont passé une radiographie des {{cottes}}.
 TEST: Quelle est sa {{côte}} de popularité
 TEST: il a réussi à percer sa {{cote}} de mailles.
 TEST: Il a la {{côte}} auprès de ses collègues
+TEST: ils sont {{cotte à cotte}}
 TEST: on a atteint la cote d’alerte.
 
 
 # cou / coup / coût
 __[i]/conf(conf_coup_de)__
@@ -7958,15 +10240,15 @@
 TEST: Merci de calculer le {{coup}} de production avant d’établir une facture.
 TEST: Elle a un {{coût}} si gracile.
 
 
 __[i]/conf(conf_tordre_le_cou)__
-    (tord\w*) +le (co[uû][pt]s?) @@0,$ <<- morph(\1, ">tordre ", False) -2>> cou
+    (tord\w*) +le (co[uû][pt]s?) @@0,$ <<- morph(\1, ">tordre/", False) -2>> cou
     # Confusion. Le coût indique ce que ça coûte. Un coup, c’est quelque chose qui frappe. La partie séparant la tête du corps s’écrit “cou”.
 __[i]/conf(conf_rendre_coup_pour_coup)__
     (rend\w*) +(co[uû]t?s? pour co[uû]t?s?)  @@0,$
-    <<- morph(\1, ">rendre ", False) -2>> coup pour coup
+    <<- morph(\1, ">rendre/", False) -2>> coup pour coup
     # Confusion. Le coût indique ce que ça coûte. Un cou est la partie séparant la tête du corps. Pour ce qui frappe, écrivez “coup”.
 
 TEST: Je vais tordre le {{coup}} à toutes ces idées stupides, une par une.
 TEST: Implacable, elle a rendu {{cout pour cout}} sans se départir de son calme.
 
@@ -7975,14 +10257,14 @@
 __[i]/conf(conf_au_cours_de)__
     au (court?) (?:des?|du?) @@3 <<- -1>> cours                                 # Confusion probable. Une cour… Un cours… Adjectif : court(e).
 __[i]/conf(conf_en_cours)__
     en cour(?! martiale?| de (?:cassation|justice)| d’assises) <<- ->> en cours                          # Confusion probable. Une cour… Un cours… Adjectif : court(e).
 __[i]/conf(conf_couper_court)__
-    (coup\w+) (cours?) @@0,$ <<- morph(\1, ">couper ") -2>> court               # « Couper court ». Écourter. Une cour… Un cours… Adjectif : court(e).
+    (coup\w+) (cours?) @@0,$ <<- morph(\1, ">couper/") -2>> court               # « Couper court ». Écourter. Une cour… Un cours… Adjectif : court(e).
 __[i]/conf(conf_laisser_libre_cours)__
     ({w1}) +libre (court?) @@0,$
-    <<- morph(\1, ">(?:avoir|donner|laisser) ", False) -2>> cours               # Confusion probable. Ce qui a « libre cours ».|https://fr.wiktionary.org/wiki/donner_libre_cours
+    <<- morph(\1, ">(?:avoir|donner|laisser)/", False) -2>> cours               # Confusion probable. Ce qui a « libre cours ».|https://fr.wiktionary.org/wiki/donner_libre_cours
 __[i]/conf(conf_à_court_de)__
     à (cours?) de? @@2 <<- -1>> court                                           # Confusion probable : écrivez « à court de … » pour « manquer de … »
 __[i]/conf(conf_à_court_terme)__
     à cour(?:s|ts|) termes? <<- ->> à court terme                               # Confusion. Une cour… Un cours… Adjectif : court(e).
 
@@ -8012,16 +10294,16 @@
 
 
 # desceller / déceler / desseller
 __[i]/conf(conf_erreur_problème_decelé)__
     (erreur|faute|incohérence|problème|bug|bogue|faille|maladie|défaut|défaillance|perturbation|irrégularité)s? .*(des[cs]ell\w+)  @@0,$
-    <<- morph(\2, ">(?:desceller|desseller) ", False)
+    <<- morph(\2, ">(?:desceller|desseller)/", False)
     -2>> =\2.replace("escell", "écel").replace("essell", "écel")
     # Confusion probable si ce mot se rapporte à « \1 ». Desceller signifie briser un sceau, un cachet… Desseller signifie ôter une selle. Si vous voulez dire “remarquer”, “dévoiler”, “découvrir”, écrivez :|http://fr.wiktionary.org/wiki/déceler
 __[i]/conf(conf_deceler_qqch)__
     (des[cs]ell\w+) +(?:(?:une?|l[ae]|des?|ce(?:tte|t|s|)|[mts](?:on|a|es)|[nv]os|leurs?|plusieurs|quelques|deux|trois|quatre|cinq|six|sept|huit|neuf|dix|onze|douze) +|l’)(?:(?:petite?|grande?|énorme|dangeureu(?:x|se)|formidable|forte?|lég(?:er|ère)|merveilleu(?:x|se)|nouv(?:el|elle|eaux?)|vraie?|réel(?:le|)|sévère|véritable)s? +|)(acidité|activité|allergie|anévrisme|anomalie|arnaque|appendicite|atrophie|baisse|bébé|blessure|bug|bogue|carie|cancer|cause|changement|complot|comète|concentration|corrélation|croissance|défaut|défaillance|demande|dépression|diabète|différence|diminution|effluve|épilepsie|erreur|essai|existence|grossesse|grosseur|faille|faute|fuite|fraude|grippe|handicap|hausse|hémorragie|hostilité|hypertrophie|incompatibilité|incohérence|infection|infraction|indice|infidélité|insuffisance|intrigue|irrégularité|leucémie|lésion|lueur|lumière|maladie|malformation|manœuvre|manipulation|molécule|mensonge|mutation|once|perturbation|personnalité|piste|perte|planète|exoplanète|présence|qualité|odeur|opportunité|otite|problème|surdité|talent|tendance|tentative|tumeur|utilisation|hoax|variation|vie|virus)s?  @@0,$
-    <<- morph(\1, ">(?:desceller|desseller) ", False)
+    <<- morph(\1, ">(?:desceller|desseller)/", False)
     -1>> =\1.replace("escell", "écel").replace("essell", "écel")
     # Confusion probable si ce mot se rapporte à « \2 ». Desceller signifie briser un sceau, un cachet… Desseller signifie ôter une selle.|http://fr.wiktionary.org/wiki/déceler
 
 TEST: il y a une erreur qu’on peut {{desceller}} dans ses analyses.
 TEST: elle a {{dessellé}} une forte hostilité dans ses propos.
@@ -8028,21 +10310,21 @@
 
 
 # en train / entrain
 __[i]/conf(conf_en_train)__
     entrain
-    <<- morph(word(-1), ">(?:être|voyager|surprendre|venir|arriver|partir|aller) ", False, False) or before("-(?:ils?|elles?|on|je|tu|nous|vous) +$")
+    <<- morph(word(-1), ">(?:être|voyager|surprendre|venir|arriver|partir|aller)/", False, False) or before("-(?:ils?|elles?|on|je|tu|nous|vous) +$")
     ->> en train                                                                    # Confusion. L’entrain est une fougue, une ardeur à accomplir quelque chose.|https://fr.wiktionary.org/wiki/entrain
 
 TEST: Vous êtes {{entrain}} de vaincre.
 TEST: Viennent-ils {{entrain}} ?
 TEST: ces idiots sont en train de tout foutre en l’air.
 
 
 __[i]/conf(conf_entrain)__
     en train
-    <<- morph(word(-1), ">(?:avec|sans|quel(?:le|)|cet|votre|notre|mon|leur) ", False, False) or before(" [dlDL]’$")
+    <<- morph(word(-1), ">(?:avec|sans|quel(?:le|)|cet|votre|notre|mon|leur)/", False, False) or before(" [dlDL]’$")
     ->> entrain                                                 # Confusion. Soudez les deux mots. L’entrain est une fougue, une ardeur à accomplir quelque chose.|https://fr.wiktionary.org/wiki/entrain
 
 TEST: Avec quel {{en train}}, ils nous ont mené jusque là-haut.
 TEST: Son manque d’{{en train}} était contagieux.
 TEST: c’est l’{{en train}} de cette jeune femme qui force l’admiration de tout le monde.
@@ -8050,11 +10332,11 @@
 
 
 # envi / envie
 __[i]/conf(conf_à_l_envi)__
     à l’(envie)  @@4
-    <<- not morph(word(-1), ">(?:abandonner|céder|résister) ", False) and not after("^ d(?:e |’)")
+    <<- not morph(word(-1), ">(?:abandonner|céder|résister)/", False) and not after("^ d(?:e |’)")
     -1>> envi                                                                                       # Locution adverbiale « à l’envi », signifiant « autant que possible ».
 
 TEST: Ils s’amusèrent à l’{{envie}} et oublièrent tous leurs soucis.
 TEST: Je résiste à l’envie de manger du chocolat.
 TEST: On ne s’intéresse pas à l’école ni à l’âge, mais aux compétences et à l’envie de partager.
@@ -8080,11 +10362,11 @@
 TEST: Béatrice Dalle et Claude
 
 
 __[i]/conf(conf_où_est)__
     où (et) +({w_1}) @@w,$
-    <<- morphex(\2, ":D", ":R|>(?:quand|pourquoi)") or (\2 == "l" and after("^’")) 
+    <<- morphex(\2, ":D", ":R|>(?:quand|pourquoi)") or (\2 == "l" and after("^’"))
     -1>> est                                                                        # Confusion probable : “et” est une conjonction de coordination. Pour le verbe être à la 3ᵉ personne du singulier, écrivez :
 
 TEST: où {{et}} cet ennemi ?
 TEST: où {{et}} l’homme qui est passé ce matin ?
 TEST: Je veux savoir où et quand, où et pouquoi.
@@ -8123,15 +10405,15 @@
 
 
 # foi / fois
 __[i]/conf(conf_bonne_mauvaise_foi)__
     (mauvaise|bonne) (fois)  @@0,$
-    <<- not ( \1 == "bonne" and before(r"(?i)\bune +$") and after("(?i)^ +pour toute") ) 
+    <<- not ( \1 == "bonne" and before(r"(?i)\bune +$") and after("(?i)^ +pour toute") )
     -2>> foi                                                                                        # Confusion probable.|http://fr.wiktionary.org/wiki/foi
 __[i]/conf(conf_faire_perdre_donner_foi)__
     ((?:f[aieî]|perd|donn|[ae])\w*) (fois) @@0,$
-    <<- morph(\1, ">(?:faire|perdre|donner|avoir) ", False) -2>> foi                                      # Confusion probable.|http://fr.wiktionary.org/wiki/foi
+    <<- morph(\1, ">(?:faire|perdre|donner|avoir)/", False) -2>> foi                                      # Confusion probable.|http://fr.wiktionary.org/wiki/foi
 
 TEST: C’est une personne de bonne {{fois}}.
 TEST: Mais il a perdu {{fois}} en l’avenir.
 
 
@@ -8281,17 +10563,17 @@
 TEST: elle se {{l’a}} {{réserve}} pour elle-même.
 
 
 __[i]/conf(conf_il_elle_on_l_a)__
     (?:il|elle|on) (?:vous |nous |)(la)[ @]+({w_2}) @@*,$
-    <<- morphex(\2, ":Q", ":(?:[123][sp]|V[123]......e)|>lui ") -1>> l’a                            # Confusion probable : “\2” est un participe passé. Il faut donc employer l’auxiliaire “avoir”.
+    <<- morphex(\2, ":Q", ":(?:[123][sp]|V[123]......e)|>lui/") -1>> l’a                            # Confusion probable : “\2” est un participe passé. Il faut donc employer l’auxiliaire “avoir”.
 __[i]/conf(conf_ne_l_a)__
     ne (?:vous |nous |)(la)[ @]+({w_2}) @@*,$
-    <<- morphex(\2, ":Q", ":(?:[123][sp]|V[123]......e)|>lui ") -1>> l’a                            # Confusion probable : “\2” est un participe passé. Il faut donc employer l’auxiliaire “avoir”.
+    <<- morphex(\2, ":Q", ":(?:[123][sp]|V[123]......e)|>lui/") -1>> l’a                            # Confusion probable : “\2” est un participe passé. Il faut donc employer l’auxiliaire “avoir”.
 __[i]/conf(conf_me_te_l_a)__
     [mt]e (la)[ @]+({w_2})  @@*,$
-    <<- morphex(\2, ":Q", ":(?:[123][sp]|V[123]......e)|>lui ") -1>> l’a                            # Confusion probable : “\2” est un participe passé. Il faut donc employer l’auxiliaire “avoir”.
+    <<- morphex(\2, ":Q", ":(?:[123][sp]|V[123]......e)|>lui/") -1>> l’a                            # Confusion probable : “\2” est un participe passé. Il faut donc employer l’auxiliaire “avoir”.
 
 TEST: il {{la}} {{donnée}}.
 TEST: ne {{la}} {{donné}} que contraint et forcé…
 TEST: celle-là, il me {{la}} {{commandée}} ?
 
@@ -8314,11 +10596,11 @@
 
 
 # lever un lièvre / soulever
 __[i]/conf(conf_lever_un_lièvre)__
     (soul\w+) +(?:un|le) lièvre  @@0
-    <<- morph(\1, ">soulever ", False) -1>> =\1[3:]
+    <<- morph(\1, ">soulever/", False) -1>> =\1[3:]
     # Expression impropre. On écrit « lever un lièvre ».|http://fr.wiktionary.org/wiki/lever_le_li%C3%A8vre
 
 TEST: j’ai {{soulevé}} un lièvre, là !
 
 
@@ -8332,16 +10614,16 @@
     @@0
     <<- -1>> lieux
     # Confusion probable. Pour désigner un endroit, utilisez “lieu(x)”.|http://fr.wiktionary.org/wiki/lieu
 __[i]/conf(conf_être_à_xxx_lieues)__
     ((?:[eêsf]|demeur|habit|trouv|situ|rest)\w+) à (?:quelques|dix|douze|quinze|seize|vingt|cent|mille|des|\d+) (lieu[sx])  @@0,$
-    <<- morph(\1, ">(?:être|habiter|trouver|situer|rester|demeurer?) ", False)
+    <<- morph(\1, ">(?:être|habiter|trouver|situer|rester|demeurer?)/", False)
     -2>> lieues
     # Confusion probable. Pour désigner une distance, utilisez “lieues”.|http://fr.wiktionary.org/wiki/lieue
 __[i]/conf(conf_avoir_eu_lieu)__
     ({avoir}) +(?:eue?s? +|)(lieu(?:es?|x))  @@0,$
-    <<- morph(\1, ">avoir ", False) -2>> lieu                                                       # Confusion. Dans l’expression « avoir lieu », “lieu” est invariable.
+    <<- morph(\1, ">avoir/", False) -2>> lieu                                                       # Confusion. Dans l’expression « avoir lieu », “lieu” est invariable.
 
 TEST: qui est le responsable des {{lieues}} ?
 TEST: ce sont des {{lieus}} mythiques
 TEST: elle habitait à quelques {{lieux}} d’ici
 TEST: Cette réunion ayant eu {{lieue}} loin d’ici
@@ -8504,11 +10786,11 @@
 __[i]/conf(conf_pain_qqch)__
     (pins?) (?:d’épices?|perdus?|sans glutens?) @@0 <<- -1>> =\1.replace("pin", "pain")
     # Confusion. Le pin est un arbre résineux à aiguilles persistantes. Pour parler la pâte de farine et d’eau cuite au four, écrivez :
 __[i]/conf(conf_manger_pain)__
     ((?:mang|dévor|aval|englout)\w+) +(?:les?|d(?:u|es)|un|[mts](?:on|es)|leurs?|[nv]o(?:s|tre)) +(pins?)  @@0,$
-    <<- morph(\1, ">(?:manger|dévorer|avaler|engloutir) ") -2>> =\2.replace("pin", "pain")
+    <<- morph(\1, ">(?:manger|dévorer|avaler|engloutir)/") -2>> =\2.replace("pin", "pain")
     # Confusion probable. Le pin est un arbre résineux à aiguilles persistantes. Pour parler la pâte de farine et d’eau cuite au four, écrivez :
 __[i]/conf(conf_pomme_de_pin)__
     pommes? de (pains?) @@$ <<- -1>> pin
     # Le pain est une pâte de farine et d’eau cuite au four. La pomme de pin est le fruit du pin.|https://fr.wiktionary.org/wiki/pomme_de_pin
 
@@ -8518,11 +10800,11 @@
 
 
 # pair / paire
 __[i]/conf(conf_aller_de_pair)__
     ((?:all|v|ir)\w+) de (pair(?:es?|s)|perd?s?)  @@0,$
-    <<- morph(\1, ">aller ", False) -2>> pair                                                       # Confusion. On écrit « aller de pair ».
+    <<- morph(\1, ">aller/", False) -2>> pair                                                       # Confusion. On écrit « aller de pair ».
 
 TEST: Ils vont de {{paires}}.
 
 
 # pâle / pale
@@ -8539,19 +10821,19 @@
 TEST: Sous une lumière {{pale}},
 
 
 # parti / partie
 __[i]/conf(conf_prendre_parti)__
-    (pr\w+) +(parti(?:s|es?)) @@0,$ <<- morph(\1, ">prendre ", False) -2>> parti                    # Confusion. On écrit « prendre parti ».
+    (pr\w+) +(parti(?:s|es?)) @@0,$ <<- morph(\1, ">prendre/", False) -2>> parti                    # Confusion. On écrit « prendre parti ».
 __[i]/conf(conf_tirer_parti)__
-    (tir\w+) +(parti(?:s|es?)) @@0,$ <<- morph(\1, ">tirer ", False) -2>> parti                     # Confusion. On écrit « tirer parti ».
+    (tir\w+) +(parti(?:s|es?)) @@0,$ <<- morph(\1, ">tirer/", False) -2>> parti                     # Confusion. On écrit « tirer parti ».
 __[i]/conf(conf_faire_partie)__
-    (f[aieoî]\w+) +(parti(?:s|es|)) @@0,$ <<- morph(\1, ">faire ", False) -2>> partie               # Confusion. On écrit « faire partie ».
+    (f[aieoî]\w+) +(parti(?:s|es|)) @@0,$ <<- morph(\1, ">faire/", False) -2>> partie               # Confusion. On écrit « faire partie ».
 __[i]/conf(conf_juge_et_partie)__
     juges? et partis? <<- ->> juge et partie|juges et parties                                       # Confusion. On écrit « être juge et partie ».
 __[i]/conf(conf_prendre_à_partie)__
-    (pr\w+) +(?:{w_2} +|)([àa] partis?) @@0,$ <<- morph(\1, ">prendre ", False) -2>> à partie       # Confusion. On écrit « prendre à partie ».
+    (pr\w+) +(?:{w_2} +|)([àa] partis?) @@0,$ <<- morph(\1, ">prendre/", False) -2>> à partie       # Confusion. On écrit « prendre à partie ».
 
 TEST: Elle prend toujours {{partie}} aux réunions.
 TEST: Il faut savoir tirer {{partis}} de ces atouts-là.
 TEST: Tu fais {{parti}} de l’élite, enfin, façon de parler.
 TEST: Nous sommes tous d’une manière ou d’une autre {{juge et parti}}.
@@ -8672,11 +10954,11 @@
 #    # Confusion probable : « quelquefois » est un adverbe qui signifie « parfois » ; ne pas confondre avec les quelques fois qu’il est advenu ou qu’il adviendra quelque chose.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4334
 
 
 __[i]/conf(conf_quelquefois_quelques_fois)__
     qu(?: elles? que fois?|elles? que fois?|elque fois) <<- ->> quelquefois|quelques fois
-    # Confusion. Utilisez « quelquefois » si vous voulez dire « parfois ». Utilisez « quelques fois » pour évoquer ce qui est advenu ou adviendra plusieurs fois.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4334  
+    # Confusion. Utilisez « quelquefois » si vous voulez dire « parfois ». Utilisez « quelques fois » pour évoquer ce qui est advenu ou adviendra plusieurs fois.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4334
 
 TEST: {{Quelles que fois}}, on y comprend plus rien.
 TEST: {{Qu’elle que fois}}, on y comprend plus rien.
 TEST: Il y va {{quelque fois}} par an.
 
@@ -8696,11 +10978,11 @@
 
 
 # raisonner / résonner
 __[i]/conf(conf_raisonner)__
     (?:la|les?|[mts]e|[nv]ous) (résonn\w+)  @@$
-    <<- morph(\1, ">résonner ", False) -1>> =\1.replace("réso", "raiso")                  # Confusion probable. Vous utilisez la raison, mais vous ne « sonnez » pas.
+    <<- morph(\1, ">résonner/", False) -1>> =\1.replace("réso", "raiso")                  # Confusion probable. Vous utilisez la raison, mais vous ne « sonnez » pas.
 
 TEST: Vous {{résonnez}} comme un sot.
 TEST: Nous allons le {{résonner}}.
 
 
@@ -8758,20 +11040,20 @@
 __[i]/conf(conf_qqch_septique)__
     (?:fosse|installation|choc|chirurgie|maladie|plaie|blessure|embolie|arthrite|isolement|pneumo-entérite)s? (sceptiques?)  @@$
     <<- -1>> =\1.replace("scep","sep")                          # Confusion possible. Septique = corrompu, infecté. Sceptique = ayant des doutes.
 __[i]/conf(conf_être_sceptique)__
     ({etre}|demeur\w+) +(septiques?)  @@0,$
-    <<- morph(\1, ">(?:être|demeurer) ", False) -2>> =\2.replace("sep", "scep")
+    <<- morph(\1, ">(?:être|demeurer)/", False) -2>> =\2.replace("sep", "scep")
     # Confusion possible. Septique = corrompu, infecté. Sceptique = ayant des doutes.
 
 TEST: cette fosse {{sceptique}} est pleine.
 TEST: Je suis {{septique}} !
 
 
 # s’ensuivre
 __[i]/conf(conf_s_ensuivre)__
-    s’en (sui\w+) @@$ <<- morph(\1, ">suivre ", False) ->> s’en\1                         # Verbe « s’ensuivre ».
+    s’en (sui\w+) @@$ <<- morph(\1, ">suivre/", False) ->> s’en\1                         # Verbe « s’ensuivre ».
 
 TEST: {{S’en suivit}} une guerre de tous les instants.
 TEST: {{S’en suivre}}.
 
 
@@ -8789,14 +11071,14 @@
 __[i]/conf(conf_en_soi)__
     (?<!’)en (soit)  @@3
     <<- morph(word(1), ":[GY]", True, True) and not before("(?i)quel(?:s|les?|) qu $|on $|il $") and not after(" soit ")
     -1>> soi                                                                                        # Confusion probable.
 __[i]/conf(conf_quel_que_soit2)__
-    quel(?:le|)s? que (soi(?:es?|)) @@$ <<- -1>> soit|soient                                        # Confusion probable. 
+    quel(?:le|)s? que (soi(?:es?|)) @@$ <<- -1>> soit|soient                                        # Confusion probable.
 __[i]/conf(conf_soi_même1)__
     (soi[tes]s? mêmes?) @@$
-    <<- morph(word(-1), ":[YQ]|>(?:avec|contre|par|pour|sur) ", False, True) -1>> soi-même          # Confusion probable : moi-même, toi-même, lui-même, elle-même, soi-même, elles-mêmes, eux-mêmes.
+    <<- morph(word(-1), ":[YQ]|>(?:avec|contre|par|pour|sur)/", False, True) -1>> soi-même          # Confusion probable : moi-même, toi-même, lui-même, elle-même, soi-même, elles-mêmes, eux-mêmes.
 __[i]/conf(conf_soi_même2)__
     soi[tes]s?-mêmes? <<- ->> soi-même                                                              # Confusion : moi-même, toi-même, lui-même, elle-même, soi-même, elles-mêmes, eux-mêmes.
 
 TEST: chez {{soit}}, c’est presque toujours mieux.
 TEST: ce n’est pas la philosophie en {{soit}} qui est problématique
@@ -8815,45 +11097,15 @@
     <<- isStart() -1>> soit                                                                         # Confusion probable : pour évoquer une option, écrivez “soit”.|https://fr.wiktionary.org/wiki/soit#Conjonction
 
 TEST: {{soi}} je vais au cinéma, {{soi}} je m’abstiens.
 TEST: {{soie}} j’arrive avant tout le monde.
 
-
-# sur / sûr
-__[i]/conf(conf_sûr_que)__
-    (sure?s?) que?  @@0
-    <<- -1>> =\1.replace("sur", "sûr")
-    # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
-__[i]/conf(conf_sûre_surs_de)__
-    (sur(?:es?|s)) de?  @@0
-    <<- -1>> =\1.replace("sur", "sûr")
-    # Confusion probable : “sur” un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
-__[i]/conf(conf_sûr_de)__
-    (sur) d(?:e (?:m(?:oi|es?|on|a)|t(?:oi|es?|on|a)|vous|nous|l(?:ui|es?)|s(?:oi|es?|on|a)|ce(?:ci|la|s|tte|t|)|ça)|’(?:elles?|eux))  @@0
-    <<- -1>> sûr
-    # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
-__[i]/conf(conf_sûr_de_vinfi)__
-    (sur) de (?:l(?:a |’|es? |ui |eur )|)({infi})  @@0,$
-    <<- morph(\2, ":Y", False)
-    -1>> =\1.replace("sur", "sûr")
-    # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
-__[i]/conf(conf_en_lieu_sûr)__
-    en lieu (sur)  @@8
-    <<- -1>> sûr
-    # Confusion probable : “sur” est une préposition ou un adjectif signifiant acide ou aigre ; utilisez “sûr” pour certain, vrai ou sans danger.|http://fr.wiktionary.org/wiki/sur
-
-TEST: Je suis {{sure}} qu’il ne va pas tarder à venir
-TEST: {{sures}} d’elles-mêmes, elles ne s’en laissent pas conter.
-TEST: {{sur}} de toi et de moi, que peut-il nous arriver, sinon le meilleur.
-TEST: Il est tellement {{sur}} de la trouver.
-TEST: ils sont en lieu {{sur}} et introuvables.
-
 
 # tâche / tache (de chocolat / rousseur / vin / sang / café / gras / graisse / huile / etc.)
 __[i]/conf(conf_tache_de_qqch)__
     (tâches?) d(?:e +|’)({w_2})  @@0,$
-    <<- morphex(\2, ":N", ":[GMY]|>(?:fonds?|grande (?:envergure|ampleur|importance)|envergure|ampleur|importance|départ|surveillance) ") and not before("accompl|dél[éè]gu")
+    <<- morphex(\2, ":N", ":[GMY]|>(?:fonds?|grande (?:envergure|ampleur|importance)|envergure|ampleur|importance|départ|surveillance)/") and not before("accompl|dél[éè]gu")
     -1>> =\1.replace("â", "a")
     # Confusion probable. Une tâche est un travail à accomplir. Pour une salissure, une altération, une marque, une coloration… employez “tache”.
 __[i]/conf(conf_tache_adjectif)__
     (tâches?) +(?:indélébile|rouge|verte|noire|bleue|jaune|grise|blanche|brune|pourpre|chocolat|mauve|fushia|violette|rose|claire|sombre)s?  @@0
     <<- -1>> =\1.replace("â", "a")
@@ -8869,14 +11121,14 @@
 
 
 # taule / tôle
 __[i]/conf(conf_aller_en_taule)__
     ({aller}) +en (t[ôo]les?)  @@0,$
-    <<- morph(\1, ">aller ", False) -2>> taule                            # Confusion. La tôle est une plaque de métal laminé. Pour la prison, écrivez :
+    <<- morph(\1, ">aller/", False) -2>> taule                            # Confusion. La tôle est une plaque de métal laminé. Pour la prison, écrivez :
 __[i]/conf(conf_faire_de_la_taule)__
     (f[aiî]\w+) +de la (t[ôo]les?)  @@0,$
-    <<- morph(\1, ">faire ", False) -2>> taule                            # Confusion. La tôle est une plaque de métal laminé. Pour la prison, écrivez :
+    <<- morph(\1, ">faire/", False) -2>> taule                            # Confusion. La tôle est une plaque de métal laminé. Pour la prison, écrivez :
 __[i]/conf(conf_tôle_qqch)__
     (taules?) (?:(?:boulonné|cintré|émaillé|embouti|galvanisé|gaufré|nervuré|ondulé|perforé|soudé|translucide)e?s?|(?:d(?:e |’)|en )(?:acier|alu|aluminium|bardage|cuivre|étanchéité|fer|festonnage|inox|laiton|métal|trapèze|zinc|éverite|fibro-?ciment|plastique|polycarbonate|PVC)s?)  @@0
     <<- -1>> =\1.replace("au", "ô")                                         # Confusion. La taule est la forme argotique pour évoquer la prison, le bordel ou toute forme d’habitation.
 
 TEST: Demain, il va aller en {{tôle}}.
@@ -8887,11 +11139,11 @@
 # tant / temps (2e partie)
 __[i]/conf(conf_en_tant_que)__
     en (temps|tan) que? @@3 <<- -1>> tant                         # Confusion. Écrivez « en tant que ».|http://fr.wiktionary.org/wiki/en_tant_que
 __[i]/conf(conf_il_être_tant_de)__
     il ({etre}) +(tant?) d(?:e |’)({infi}|ne|en|y)  @@3,w,$
-    <<- morph(\1, ":V0e", False) and morph(\3, ":Y|>(?:ne|en|y) ", False)
+    <<- morph(\1, ":V0e", False) and morph(\3, ":Y|>(?:ne|en|y)/", False)
     -2>> temps                                                              # Confusion.
 
 TEST: en {{tan}} que meneuse intrépide, elle a toujours fait preuve d’une grande imagination.
 TEST: il est bien évidemment {{tant}} d’en finir avec ça.
 
@@ -8909,18 +11161,24 @@
 # tort / tord
 __[i]/conf(conf_à_tort)__
     à (tor[de]?s?) @@2 <<- -1>> tort                                # Confusion : “tord” est une conjugaison du verbe tordre.
 __[i]/conf(conf_avoir_tort)__
     ({avoir}|donn\w+) +(tor[ed]?s?) @@0,$
-    <<- morph(\1, ">(?:avoir|donner) ", False) -2>> tort            # Confusion : “tord” est une conjugaison du verbe tordre.
+    <<- morph(\1, ">(?:avoir|donner)/", False) -2>> tort            # Confusion : “tord” est une conjugaison du verbe tordre.
 
 TEST: elles seront à {{tord}} accusées.
 TEST: ils ont {{tords}}…
 TEST: ils ont {{tord}}.
 TEST: ils n’ont pas {{tord}}.
 TEST: je ne peux pas lui donner {{tord}}.
 
+
+__[i]/conf(conf_tour_à_tour)__
+    tours? [àa] tours?
+    <<- not re.search("(?i)^tour à tour$", \0) ->> tour à tour      # Locution adverbiale invariable. Écrivez “tour à tour”.|https://fr.wiktionary.org/wiki/tour_%C3%A0_tour
+    <<- ~>> *
+
 
 # venimeux / vénéneux
 __[i]/conf(conf_qqch_venimeux)__
     (?:serpent|araignée|scorpion|vipère|cobra|crapaud|grenouille|dendrobate|poulpe|guêpe|abeille|méduse|morsure|piqûre|dard|dent|croc|crochet)s? +(vénéneu(?:x|ses?))  @@$
     <<- -1>> =\1.replace("énén", "enim")                                    # Confusion : “vénéneux” se dit des plantes, employez “venimeux”.
@@ -8970,11 +11228,11 @@
 # nouveau / nouvel
 # TODO
 
 
 
-!!!! Mots composés                                                                                  
+!!!! Mots composés                                                                                !!
 
 __[i]/mc(mc_mot_composé)__
     ({w2})-({w2})  @@0,$
     <<- not \1.isdigit() and not \2.isdigit()
         and not morph(\0, ":", False) and not morph(\2, ":G", False) and spell(\1+\2)
@@ -8988,11 +11246,11 @@
 
 
 
 !!
 !!
-!!!! Casse: majuscules et minuscules                                                                
+!!!! Casse: majuscules et minuscules                                                              !!
 !!
 !!
 
 # Les jours
 __[s]/maj(maj_jours_semaine)__
@@ -9078,11 +11336,11 @@
 
 
 # les langues
 __[s]/maj(maj_langues)__
     ((?:parl|cours|leçon|appr|étud|tradu|enseign|professeur|enseignant|dictionnaire|méthode)\w*) (?:le |d[eu] |l’|d’|qu |)(Afrikaans|Albanais|Allemand|Alsacien|Anglais|Arabe|Aragonais|Arménien|Asturien|Basque|Bengali|Biélorusse|Birman|Bosniaque|Breton|Bulgare|Cantonais|Catalan|Cherokee|Chinois|Corse|Cornique|Coréen|Croate|Danois|Écossais|Espagnol|Espéranto|Estonien|Féroïen|Farsi|Finnois|Flamand|Français|Frison|Galicien|Gallois|Gaulois|Géorgien|Grec|Gujarati|Hakka|Hawaïen|Hébreu|Hindi|Hollandais|Hongrois|Javanais|Ido|Indonésien|Interlingua|Islandais|Italien|Irlandais|Japonais|Kazakh|Khmer|Kurde|Ladino|Laotien|Latin|Ligurien|Limbourgeois|Lituanien|Lombard|Luxembourgeois|Macédonien|Malais|Maldivien|Malgache|Maltais|Mandarin|Maori|Marathi|Marwari|Moldave|Mongol|Napolitain|Néerlandais|Norvégien|Occitan|Ourdou|Ouzbek|Persan|Peul|Piémontais|Polonais|Portugais|Provençal|Quichua|Romanche|Roumain|Russe|Sans[ck]rit|Sarde|Serbe|Sicilien|Sindhi|Slovaque|Slovène|Soudanais|Sorabe|Suédois|Swahili|Tagalog|Tahitien|Tamoul|Tatar|Tchèque|Thaï|Turc|Ukrainien|Vénitien|Vietnamien|Volapük|Wallon|Wo?u|Yiddish|Xhosa|Xiang|Zoulou)  @@0,$
-    <<- morph(\1, ">(?:parler|cours|leçon|apprendre|étudier|traduire|enseigner|professeur|enseignant|dictionnaire|méthode) ", False)
+    <<- morph(\1, ">(?:parler|cours|leçon|apprendre|étudier|traduire|enseigner|professeur|enseignant|dictionnaire|méthode)/", False)
     -2>> =\2.lower()                                                                                # Si vous parlez de la langue, pas de majuscule.
 
 __[s]/maj(maj_en_langue)__
     (?:[Ee]n )(Afrikaans|Albanais|Allemand|Alsacien|Anglais|Arabe|Aragonais|Arménien|Asturien|Basque|Bengali|Biélorusse|Birman|Bosniaque|Breton|Bulgare|Cantonais|Catalan|Cherokee|Chinois|Cornique|Coréen|Croate|Danois|Écossais|Espagnol|Espéranto|Estonien|Féroïen|Farsi|Finnois|Flamand|Français|Frison|Galicien|Gallois|Gaulois|Géorgien|Grec|Gujarati|Hakka|Hawaïen|Hébreu|Hindi|Hollandais|Hongrois|Javanais|Ido|Indonésien|Interlingua|Islandais|Italien|Irlandais|Japonais|Kazakh|Khmer|Kurde|Ladino|Laotien|Latin|Ligurien|Limbourgeois|Lituanien|Lombard|Luxembourgeois|Macédonien|Malais|Maldivien|Malgache|Maltais|Mandarin|Maori|Marathi|Marwari|Moldave|Mongol|Napolitain|Néerlandais|Norvégien|Occitan|Ourdou|Ouzbek|Persan|Peul|Piémontais|Polonais|Portugais|Provençal|Quichua|Romanche|Roumain|Russe|Sans[ck]rit|Sarde|Serbe|Sicilien|Sindhi|Slovaque|Slovène|Soudanais|Sorabe|Suédois|Swahili|Tagalog|Tahitien|Tamoul|Tatar|Tchèque|Thaï|Turc|Ukrainien|Vénitien|Vietnamien|Volapük|Wallon|Wo?u|Yiddish|Xhosa|Xiang|Zoulou)  @@3
     <<- -1>> =\1.lower()                                                                            # Si vous parlez de la langue, pas de majuscule.
@@ -9158,11 +11416,11 @@
 !!
 !!
 !!
 !!
 !!
-!!! Conjugaisons                                                                                    
+!!! Conjugaisons                                                                                  !!
 !!
 !!
 !!
 !!
 !!
@@ -9173,11 +11431,11 @@
 !!
 
 
 !!
 !!
-!!!! Infinitif                                                                                      
+!!!! Infinitif                                                                                    !!
 !!
 !!
 
 __[i]/infi(infi_à_en)__
     à en ({w_2}) @@5
@@ -9217,11 +11475,11 @@
 TEST: y {{mangée}} était un supplice
 
 
 __[i]/infi(infi_pour)__
     pour ({w_2}(?:ée?s?|ez))  @@5
-    <<- morphex(\1, ":V1", ":[NM]") and not morph(word(-1), ">(?:tenir|passer) ", False)
+    <<- morphex(\1, ":V1", ":[NM]") and not morph(word(-1), ">(?:tenir|passer)/", False)
     -1>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: pour {{mangé}} à sa faim, il faudra chasser.
 TEST: C’est pour {{attaqué}} la journée.
 
@@ -9249,11 +11507,11 @@
 TEST: vous {{mangé}}
 
 
 __[i]/infi(infi_devoir_savoir_pouvoir_interrogatif)__
     (d[eouû]\w+|s[auû]\w+|p[eouû]\w+|v[eo]u\w+)-(?:ils?|elles?|on|je|tu|nous|vous) +(?:pas +|)(?:[mts](?:e +|’)|lui +|[nv]ous +|)({w_2})  @@0,$
-    <<- morph(\1, ">(?:devoir|savoir|pouvoir|vouloir) ", False) and morphex(\2, ":(?:Q|A|[123][sp])", ":[GYW]")
+    <<- morph(\1, ">(?:devoir|savoir|pouvoir|vouloir)/", False) and morphex(\2, ":(?:Q|A|[123][sp])", ":[GYW]")
     -2>> =suggVerbInfi(@)                                                                           # Après « \1 » , le verbe devrait être à l’infinitif.
 
 TEST: Peuvent-elles s’{{installaient}} ici ?
 TEST: Peut-il {{chassé}} ces intrus ?
 TEST: Ne veux-tu pas {{gardé}} ton boulot ?
@@ -9269,41 +11527,41 @@
 TEST: Est-ce que Pierre Xazzz va bien ?
 TEST: Qu’est-ce que rapporte réellement Dassault & Co au budget
 
 
 __[i]/infi(infi_commencer_finir_par)__  ((?:commen[cç]|fin[iî])\w+) +par ({w_2}(?:ée?s?|ai[st]))  @@0,$
-    <<- morph(\1, ">(?:commencer|finir) ", False) and morphex(\2, ":V", ":[NGM]") and not \2[0:1].isupper()
+    <<- morph(\1, ">(?:commencer|finir)/", False) and morphex(\2, ":V", ":[NGM]") and not \2[0:1].isupper()
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: commence par {{mangé}} le poulet.
 TEST: enfin la petite finit par {{pleuré}} à chaudes larmes.
 TEST: sa tournée, elle la finit par Rodez.
 
 
 __[i]/infi(infi_verbe_de)__
     ((?:cess|dé[cf]|sugg[éè]r|command|essa|tent|chois|perm[eiî]t|interd)\w*) +(?:pas |plus |point |guère |jamais |peu |rien |) *(?:de +|d’)({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morph(\1, ">(?:cesser|décider|défendre|suggérer|commander|essayer|tenter|choisir|permettre|interdire) ", False) and analysex(\2, ":(?:Q|2p)", ":M")
+    <<- morph(\1, ">(?:cesser|décider|défendre|suggérer|commander|essayer|tenter|choisir|permettre|interdire)/", False) and analysex(\2, ":(?:Q|2p)", ":M")
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: cessez d’{{anesthésié}} ces gens !
 
 
 ## INFINITIFS ERRONÉS
 
 __[i]/infi(infi_adjectifs_masculins_singuliers)__
     ^ *(?:le|un|cet?|[mts]on|quel) (?!verbe)({w_2}) +({w_2}er)  @@w,$
-    <<- morphex(\1, ":N.*:m:[si]", ":G") and morphex(\2, ":Y", ">aller |:(?:M|N.*:m:s)") and isNextVerb()
+    <<- morphex(\1, ":N.*:m:[si]", ":G") and morphex(\2, ":Y", ">aller/|:(?:M|N.*:m:s)") and isNextVerb()
     -2>> =suggVerbPpas(\2, ":m:s")                                                  # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez :
 
 __[i]/infi(infi_adjectifs_féminins_singuliers)__
     ^ *(?:la|une|cette|[mts]a|quelle) ({w_2}) +({w_2}er)  @@w,$
-    <<- morphex(\1, ":N.*:f:[si]", ":G") and morphex(\2, ":Y", ">aller |:M") and isNextVerb()
+    <<- morphex(\1, ":N.*:f:[si]", ":G") and morphex(\2, ":Y", ">aller/|:M") and isNextVerb()
     -2>> =suggVerbPpas(\2, ":f:s")                                                  # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez :
 
 __[i]/infi(infi_adjectifs_singuliers)__
     ^ *(?:leur|[nv]otre) ({w_2}) +({w_2}er)  @@w,$
-    <<- morphex(\1, ":N.*:[si]", ":G") and morphex(\2, ":Y", ">aller |:M") and isNextVerb()
+    <<- morphex(\1, ":N.*:[si]", ":G") and morphex(\2, ":Y", ">aller/|:M") and isNextVerb()
     -2>> =suggVerbPpas(\2, ":s")                                                    # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez :
 
 TEST: ce tableau {{voler}} coûte très cher.
 TEST: la difficulté {{passer}} t’aidera par la suite
 TEST: leur compte {{épurer}} servira encore.
@@ -9310,19 +11568,19 @@
 TEST: Le vieux cocher avait mission
 
 
 __[i]/infi(infi_adjectifs_pluriels)__
     ^ *(?:[lmtsc]es|[nv]os|leurs|quel(?:le|)s) ({w_1}[sxz]) +({w_2}er)  @@w,$
-    <<- morphex(\1, ":N.*:[pi]", ":G") and morphex(\2, ":Y", ">aller |:M") and isNextVerb()
+    <<- morphex(\1, ":N.*:[pi]", ":G") and morphex(\2, ":Y", ">aller/|:M") and isNextVerb()
     -2>> =suggVerbPpas(\2, ":p")                                                    # Confusion probable : “\2” est à verbe à l’infinitif. Pour l’adjectif, écrivez :
 
 TEST: les documents {{scanner}} ne sont pas lisibles.
 TEST: tes doutes {{remâcher}} deviennent difficiles à vivre.
 
 
 
-!!!! Participes présents                                                                             
+!!!! Participes présents                                                                          !!
 
 __[i]/conj(conj_participe_présent)__  (?:ne|lui|me|te|se|nous|vous) ({w_2}ants)  @@$
     <<- morph(\1, ":A", False) -1>> =\1[:-1]                                                        # Un participe présent est invariable.|http://fr.wiktionary.org/wiki/participe_pr%C3%A9sent
 
 TEST: nous {{épuisants}} à la tâche pour des clopinettes, nous défaillîmes.
@@ -9329,11 +11587,11 @@
 
 
 
 !!!
 !!!
-!!! Processeur: simplification des substantifs                                                      
+!!! Processeur: simplification des substantifs                                                    !!
 !!!
 !!!
 
 ### @ : we remove @ we introduced after le/la/les in some cases
 __<s>(p_arobase)__      @ <<- ~>> *
@@ -9350,11 +11608,11 @@
     \w+-(?:je|tu|ils?|elles?|on|[nv]ous) (pas|point|rien|bien|ensemble) @@$ <<- ~1>> *
 
 # sembler le croire/penser/présumer/supposer/envisager/imaginer
 __[i](p_que_semble_le_penser)__
     que +(sembl\w+) +(l(?:e (?:penser|croire|présumer|supposer)|’(?:envisager|imaginer))) @@w,$
-    <<- morph(\1, ">sembler ", False) ~2>> *
+    <<- morph(\1, ">sembler/", False) ~2>> *
 
 ### tous / tout / toute / toutes
 __[i](p_tout_det_mas)__     (tout) (?:le|ce|[mts]on|leur) @@0 <<- ~1>> *
 __[i](p_toute_det_fem)__    (toute) (?:la|cette|[mts](?:a|on)|leur) @@0 <<- ~1>> *
 __[i](p_tous_det_plur)__    (tou(?:te|)s) (?:[csmlt]es|[vn]os|leurs) @@0 <<- ~1>> *
@@ -9371,11 +11629,11 @@
 __[i](p_en_tant_que_tel)__          en tant que tel(?:s|lles?|) <<- ~>> *
 
 # de +
 __[i](p_de_vinfi)__
     d(?:e |’)({infi}) @@$
-    <<- morphex(\1, ":V[123]_i", ">(?:devenir|rester|demeurer) ") and isNextNotCOD() ~>> *
+    <<- morphex(\1, ":V[123]_i", ">(?:devenir|rester|demeurer)/") and isNextNotCOD() ~>> *
 __[i](p_de_manière_façon_xxx_et_xxx)__
     de (?:manière|façon) +(?:non +|)({w_2}) +et +(?:non +|)({w_2})  @@w,$
     <<- morph(\1, ":A", False) and morphex(\2, ":A", ":[GM]") ~>> *
 __[i](p_de_manière_façon)__
     de (?:manière|façon) +(?:non +|)({w_2})  @@$
@@ -9425,11 +11683,11 @@
 
 ## doute que
 __[i](p_nul_doute_que)__
     nul doute qu  <<- isStart() ~>> *
 __[i](p_douter_que)__
-    (dout\w+)( ) *que?  @@0,*  <<- morph(\1, ">douter ", False) and before(r"(?i)\b(?:[mts]e|[nv]ous) +$") ~2>> ,
+    (dout\w+)( ) *que?  @@0,*  <<- morph(\1, ">douter/", False) and before(r"(?i)\b(?:[mts]e|[nv]ous) +$") ~2>> ,
 
 ## de +
 __[i](p_de_nom)__
     d(?:e +|’)(?!autres)({w_2}) @@$
     <<- morphex(\1, ":N", ":[GY]") and isEndOfNG() ~>> *
@@ -9455,11 +11713,11 @@
 TEST: Notre but n’était pas de devenir célèbres.
 TEST: sans qu’on ait à le lui ordonner
 
 
 
-!!!! OCR                                                                                            
+!!!! OCR                                                                                          !!
 
 # Participes passés
 __[i]/ocr(ocr_être_participes_passés)__
     ({etre}) +({w_2}es?) @@0,$
     <<- morph(\1, ":V0e", False) >>>
@@ -9469,11 +11727,11 @@
     -2>> =suggVerbPpas(\2, ":m:p")                                                                  # Erreur de numérisation ?
 
 __[i]/ocr(ocr_avoir_participes_passés)__
     ({avoir}) +({w_2}es?) @@0,$
     <<- morph(\1, ":V0a", False) >>>
-    <<- \2.endswith("e") and morphex(\2, ":V1.*:Ip.*:[13]s", ":[GM]|>envie ")
+    <<- \2.endswith("e") and morphex(\2, ":V1.*:Ip.*:[13]s", ":[GM]|>envie/")
     -2>> =suggVerbPpas(\2, ":m:s")                                                                  # Erreur de numérisation ?
     <<- __else__ and \2.endswith("s") and morphex(\2, ":V1.*:Ip.*:2s", ":[GM]")
     -2>> =suggVerbPpas(\2, ":m:p")                                                                  # Erreur de numérisation ?
 
 TEST: __ocr__ vous serez {{couche}} en terre.
@@ -9493,11 +11751,11 @@
 # TEST: __ocr__ vous êtes {{presses}} de monter à bord de ce train-ci.
 # Fonctionne avec nous serons, mais pas nous sommes (bug de JavaScript?)
 
 
 
-!!!! Confusions                                                                                     
+!!!! Confusions                                                                                   !!
 
 ## guerre / guère
 __[i]/conf(conf_ne_pronom_pronom_verbe_guère)__
     ne (?:[mts]e|la|les?|[nv]ous|lui|leur) (?:la |les? |lui |leur |l’|)\w{w_2} (?:plus |)(guerre)  @@$
     <<- -1>> guère                                                                                  # Confusion. La guerre est conflit. Pour l’adverbe signifiant “peu”, écrivez :
@@ -9548,22 +11806,22 @@
 
 
 ## soit / soie / soi
 __[i]/conf(conf_aller_de_soi)__
     ({aller}) +de (soi[tes])  @@0,$
-    <<- morph(\1, ">aller", False) and not after(" soit ") -2>> soi                                 # Confusion.|https://fr.wiktionary.org/wiki/aller_de_soi
+    <<- morph(\1, ">aller/", False) and not after(" soit ") -2>> soi                                # Confusion.|https://fr.wiktionary.org/wiki/aller_de_soi
 
 TEST: cela ne va pas de {{soit}}.
 
 
 
-!!!! Adverbes après verbe                                                                           
+!!!! Adverbes après verbe                                                                         !!
 
 # fort
 __[i]/sgpl(sgpl_verbe_fort)__
     ({w_2}) +(forts)  @@0,$
-    <<- morphex(\1, ":V", ":[AN].*:[me]:[pi]|>(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre|appara[îi]tre) .*:(?:[123]p|P|Q)|>(?:affirmer|trouver|croire|désirer|estime|préférer|penser|imaginer|voir|vouloir|aimer|adorer|souhaiter) ")
+    <<- morphex(\1, ":V", ":[AN].*:[me]:[pi]|>(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre|appara[îi]tre)/.*:(?:[123]p|P|Q)|>(?:affirmer|trouver|croire|désirer|estime|préférer|penser|imaginer|voir|vouloir|aimer|adorer|souhaiter)/")
         and not morph(word(1), ":A.*:[me]:[pi]", False)
     -2>> fort                                               # Confusion probable. S’il s’agit ici de l’adverbe “fort” (équivalent de “fortement”), écrivez-le au singulier.
 
 TEST: ces emmerdeurs crient bien trop {{forts}}
 TEST: ces animaux paraissent forts, mais ils sont faibles.
@@ -9588,11 +11846,11 @@
 
 
 
 !!
 !!
-!!!! Infinitif                                                                                      
+!!!! Infinitif                                                                                    !!
 !!
 !!
 
 __[i]/infi(infi_d_en_y)__
     d’(?:en|y) +({w_2})  @@$
@@ -9626,11 +11884,11 @@
 TEST: de me le {{facturez}}
 
 
 __[i]/infi(infi_faire)__
     (f(?:ai|[iî]|er|on)\w+) +({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morph(\1, ">faire ", False) and not before(r"(?i)\b(?:en|[mtsldc]es?|[nv]ous|un) +$") and morphex(\2, ":V", ":M")
+    <<- morph(\1, ">faire/", False) and not before(r"(?i)\b(?:en|[mtsldc]es?|[nv]ous|un) +$") and morphex(\2, ":V", ":M")
         and not (re.search("(?i)^fait$", \1) and \2.endswith("é"))
         and not (re.search("(?i)^faits$", \1) and \2.endswith("és"))
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: elle fit peu {{mangé}} les enfants
@@ -9638,11 +11896,11 @@
 TEST: Tu fais {{décoloré}} tes cheveux ?
 
 
 __[i]/infi(infi_vouloir)__
     (v[oe]u\w+) +({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morph(\1, ">vouloir ", False) and not before(r"(?i)\b(?:[mtsldc]es?|[nv]ous|un) +$") and morphex(\2, ":V", ":M")
+    <<- morph(\1, ">vouloir/", False) and not before(r"(?i)\b(?:[mtsldc]es?|[nv]ous|un) +$") and morphex(\2, ":V", ":M")
         and not (re.search("(?i)^vouloir$", \1) and \2.endswith("é"))
         and not (re.search("(?i)^vouloirs$", \1) and \2.endswith("és"))
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: je veux {{changé}}
@@ -9653,11 +11911,11 @@
 TEST: en voulant {{changé}}
 
 
 __[i]/infi(infi_me_te_se_faire)__
     [mts]e (f(?:ai|[iî]|er|on)\w+) +({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morph(\1, ">faire ", False) and morphex(\2, ":V", ":M")
+    <<- morph(\1, ">faire/", False) and morphex(\2, ":V", ":M")
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: me faire constamment {{laminé}} au jeu, ça finit par me fâcher.
 
 
@@ -9669,11 +11927,11 @@
 TEST: Je suis fatigué de vouloir {{essayé}} d’y remédier.
 
 
 __[i]/infi(infi_savoir)__
     (s[auû]\w+) +({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morph(\1, ">savoir :V", False) and morph(\2, ":V", False) and not before(r"(?i)\b(?:[mts]e|[vn]ous|les?|la|un) +$")
+    <<- morph(\1, ">savoir/:V", False) and morph(\2, ":V", False) and not before(r"(?i)\b(?:[mts]e|[vn]ous|les?|la|un) +$")
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: Il faut savoir {{arrêté}} les frais.
 TEST: un certain nombre de savoirs spécialisés
 
@@ -9701,40 +11959,40 @@
 
 
 
 !!
 !!
-!!!! Usage pronominal avec “avoir” au lieu d’“être”                                                 
+!!!! Usage pronominal avec “avoir” au lieu d’“être”                                               !!
 !!
 !!
 
 __[i]/conj(conj_se_conf_être_avoir)__
     (s’)(?:en +|y+ |)({avoir})  @@0,$
-    <<- morph(\2, ">avoir ", False) >>>
+    <<- morph(\2, ">avoir/", False) >>>
     <<- morph(\2, ":3p", False) -2>> sont|étaient|seront|seraient                                   # Confusion. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
     <<- __else__ -2>> est|était|sera|serait                                                         # Confusion. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
 
 TEST: s’en {{ait}} trop
 
 
 __[i]/conj(conj_je_me_conf_être_avoir)__
     je m’(?:en +|y+ |)({avoir})  @@$
-    <<- morph(\1, ">avoir ", False) -1>> suis|étais|serai|serais                                    # Confusion. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
+    <<- morph(\1, ">avoir/", False) -1>> suis|étais|serai|serais                                    # Confusion. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
 
 __[i]/conj(conj_tu_te_conf_être_avoir)__
     tu t’(?:en +|y+ |)({avoir})  @@$
-    <<- morph(\1, ">avoir ", False) and not morph(word(-1), ":V0", False, False)
+    <<- morph(\1, ">avoir/", False) and not morph(word(-1), ":V0", False, False)
     -1>> es|étais|seras|serais                                                                      # Confusion. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
 
 __[i]/conj(conj_nous_nous_conf_être_avoir)__
     (nous) nous (?:en +|y+ |)({avoir})  @@0,$
-    <<- morph(\2, ">avoir ", False) and isStart() -2>> sommes|étions|serons|serions                 # Confusion possible. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
+    <<- morph(\2, ">avoir/", False) and isStart() -2>> sommes|étions|serons|serions                 # Confusion possible. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
     <<- __also__ -1>> nous,                                                                         # S’il ne s’agit pas d’une locution pronominale, mettez une virgule pour séparer les personnes que vous désignez du sujet.
 
 __[i]/conj(conj_vous_vous_conf_être_avoir)__
     (vous) vous (?:en +|y+ |)({avoir})  @@0,$
-    <<- morph(\2, ">avoir ", False) and isStart() -2>> êtes|étiez|serez|seriez                      # Confusion possible. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
+    <<- morph(\2, ">avoir/", False) and isStart() -2>> êtes|étiez|serez|seriez                      # Confusion possible. Sous sa forme pronominale, un verbe s’emploie avec l’auxilaire “être”, non “avoir”.
     <<- __also__ -1>> vous,                                                                         # S’il ne s’agit pas d’une locution pronominale, mettez une virgule pour séparer les personnes que vous désignez du sujet.
 
 TEST: je m’y {{avais}} habitué.
 TEST: tu t’{{avais}} donné du temps pour finir ton mémoire.
 TEST: Ce qu’il a tu t’a donné la nausée.
@@ -9743,11 +12001,11 @@
 
 
 
 !!
 !!
-!!!! Participes passés: se +être +verbe                                                             
+!!!! Participes passés: se +être +verbe                                                           !!
 !!
 !!
 
 __[i]/ppas(ppas_je_me_être_verbe)__
     je +(?:ne +|)m(?:e +|’(?:y +|))(?:s[uo]i[st]|étai[st]|fu(?:sses?|s|t)|serai[st]?) +({w_3}) @@$
@@ -9769,54 +12027,54 @@
 
 
 
 __[i]/ppas(ppas_il_se_être_verbe)__
     il +(?:ne +|)s(?:e +|’(?:y +|))(?:est?|soi[st]|étai[st]|fu(?:sses?|s|t)|serai?[st]?) +({w_3}) @@$
-    <<- morphex(\1, ":Q.*:(?:f|m:p)", ":(?:G|Q.*:m:[si])|>dire ") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not before(r"\b[qQ]ue? +$")) )
+    <<- morphex(\1, ":Q.*:(?:f|m:p)", ":(?:G|Q.*:m:[si])|>dire/") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not before(r"\b[qQ]ue? +$")) )
     -1>> =suggVerbPpas(\1, ":m:s")                                                                  # Si ce participe passé se rapporte bien à “il”, il devrait être au masculin singulier.
 
 TEST: le dédale dans lequel il se serait {{perdue}}
 TEST: il s’était perdu dans la forêt.
 
 
 __[i]/ppas(ppas_elle_se_être_verbe)__
     elle +(?:ne +|)s(?:e +|’(?:y +|))(?:est?|soi[st]|étai[st]|fu(?:sses?|s|t)|serai?[st]?) +({w_3}) @@$
-    <<- morphex(\1, ":Q.*:(?:m|f:p)", ":(?:G|Q.*:f:[si])|>dire ") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not morph(word(-1), ":R|>que ", False, False)) )
+    <<- morphex(\1, ":Q.*:(?:m|f:p)", ":(?:G|Q.*:f:[si])|>dire/") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not morph(word(-1), ":R|>que/", False, False)) )
     -1>> =suggVerbPpas(\1, ":f:s")                                                                  # Si ce participe passé se rapporte bien à “elle”, il devrait être au féminin singulier.
 
 TEST: elle s’y était {{préparé}}.
 TEST: elle s’était trouvé un mari.
 
 
 __[i]/ppas(ppas_nous_nous_être_verbe)__
     nous +(?:ne +|)nous +(?:y +|)(?:sommes|étions|fûmes|fussions|seri?ons) +({w_3}) @@$
-    <<- morphex(\1, ":Q.*:s", ":(?:G|Q.*:[pi])|>dire ") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not morph(word(-1), ":R|>que ", False, False)) )
+    <<- morphex(\1, ":Q.*:s", ":(?:G|Q.*:[pi])|>dire/") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not morph(word(-1), ":R|>que/", False, False)) )
     -1>> =suggVerbPpas(\1, ":p")                                                                    # Si ce participe passé se rapporte bien à “nous”, il devrait être au pluriel.
 
 TEST: Nous nous étions {{cru}} au paradis.
 
 
 __[i]/ppas(ppas_ils_se_être_verbe)__
     ils +(?:ne +|)s(?:e +|’(?:y +|))(?:so(?:ie|)nt|étaient|fu(?:r|ss)ent|ser(?:aie|o)nt) +({w_3}) @@$
-    <<- morphex(\1, ":Q.*:(?:f|m:s)", ":(?:G|Q.*:m:[pi])|>dire ") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not before(r"\b[qQ]ue? +$")) )
+    <<- morphex(\1, ":Q.*:(?:f|m:s)", ":(?:G|Q.*:m:[pi])|>dire/") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not before(r"\b[qQ]ue? +$")) )
     -1>> =suggVerbPpas(\1, ":m:p")                                                                  # Si ce participe passé se rapporte bien à “ils”, il devrait être au masculin pluriel.
 
 TEST: ils s’y étaient {{abandonné}} avec ferveur
 
 
 __[i]/ppas(ppas_elles_se_être_verbe)__
     elles +(?:ne +|)s(?:e +|’(?:y +|))(?:so(?:ie|)nt|étaient|fu(?:r|ss)ent|ser(?:aie|o)nt) +({w_3}) @@$
-    <<- morphex(\1, ":Q.*:(?:m|f:s)", ":(?:G|Q.*:f:[pi])|>dire ") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not morph(word(-1), ":R|>que ", False, False)) )
+    <<- morphex(\1, ":Q.*:(?:m|f:s)", ":(?:G|Q.*:f:[pi])|>dire/") and ( morph(\1, ":V[123]_.__p_e_") or (isRealEnd() and not morph(word(-1), ":R|>que/", False, False)) )
     -1>> =suggVerbPpas(\1, ":f:p")                                                                  # Si ce participe passé se rapporte bien à “elles”, il devrait être au féminin pluriel.
 
 TEST: elles ne s’y étaient pas {{donnée}}.
 TEST: sans fin elles se sont succédé
 
 
 __[i]/ppas(ppas_se_être)__
     [mts](?:e +|’(?:y +|en +|))({etre}) +({w_2})  @@w,$
-    <<- morph(\1, ">être ", False) >>>
+    <<- morph(\1, ">être/", False) >>>
     <<- morphex(\2, ":(?:Y|[123][sp])", ":Q") and not re.search(r"(?i)^t’(?:es|étais)", \0)
     -2>> =suggVerbPpas(@)                                                                           # Incohérence. Après « s’être », le verbe doit être un participe passé.
     <<- __else__ and morph(\1, ":[123]s", False) and morph(\2, ":Q.*:p", False) and not before(r"(?i)\bque?[, ]|\bon (?:ne |)$")
         and not re.search(r"(?i)^t’(?:es|étais)", \0)
     -2>> =suggSing(@)                                                                               # Le participe passé devrait être au singulier.
@@ -9836,17 +12094,17 @@
 
 
 
 !!
 !!
-!!!! Participes passés: se +laisser +adjectif                                                       
+!!!! Participes passés: se +laisser +adjectif                                                     !!
 !!
 !!
 
 __[i]/ppas(ppas_me_te_laisser_adj)__
     ([mt]e|l[ae]) +(laiss\w*) +({w_3})  @@0,w,$
-    <<- morph(\2, ">laisser ", False) and  morphex(\3, ":[AQ].*:p", ":(?:[YG]|[AQ].*:[is])")
+    <<- morph(\2, ">laisser/", False) and  morphex(\3, ":[AQ].*:p", ":(?:[YG]|[AQ].*:[is])")
     -3>> =suggSing(@)                                                                               # Accord avec « \1 » : « \3 » devrait être au singulier.
 
 TEST: Elle te laisse {{épuisés}} par la tâche.
 TEST: Ils la laissèrent {{malades}}.
 TEST: Ils la laissent prendre le train.
@@ -9855,11 +12113,11 @@
 TEST: Il te laisse trois jours de délai.
 
 
 __[i]/ppas(ppas_nous_les_laisser_adj)__
     (nous|les) +(laiss\w*) +({w_3})  @@0,w,$
-    <<- morph(\2, ">laisser ", False) and morphex(\3, ":[AQ].*:s", ":(?:[YG]|[AQ].*:[ip])")
+    <<- morph(\2, ">laisser/", False) and morphex(\3, ":[AQ].*:s", ":(?:[YG]|[AQ].*:[ip])")
         and (\1.endswith("es") or ( \1.endswith("us") and not \2.endswith("ons") ))
     -3>> =suggPlur(@)                                                                               # Accord avec « \1 » : « \3 » devrait être au pluriel.
 
 TEST: je les laisse {{indifférent}}.
 TEST: elle nous laissera {{perdu}} dans nos délires.
@@ -9869,17 +12127,17 @@
 TEST: nous laisserons étourdi cet homme.
 
 
 !!
 !!
-!!!! Participes passés: être, avoir été, sembler (+être via pp), devenir, rester, (re)devenir, paraître + participe passé / adj
+!!!! Participes passés: être, avoir été, sembler (+être via pp), devenir, rester, (re)devenir, paraître + participe passé / adj  !!
 !!
 !!
 
 __[i]/ppas(ppas_je_verbe)__
     j(?:e +|’(?:y +|en +|))(?:ne +|n’|)((?:s[oue]|étai|fus|dev|re(?:dev|st)|par)\w*|a(?:ie?|vais|urais?) +été|eus(?:se|) +été) +({w_2})  @@w,$
-    <<- (morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \1.endswith(" été")) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
+    <<- (morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \1.endswith(" été")) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
     -2>> =suggSing(@)                                                        # Accord avec le sujet « je » : « \2 » devrait être au singulier.
 
 TEST: j’étais {{perdus}}                                                          ->> perdu
 TEST: j’aurais été {{perdus}} sans toi                                            ->> perdu
 TEST: je n’étais pas {{perdus}}                                                   ->> perdu
@@ -9894,21 +12152,21 @@
 TEST: J’y semble être {{perdus}}.
 
 
 __[i]/ppas(ppas_tu_verbe)__
     tu +(?:ne +|n’|)((?:es|étai|fus|se[rm]|soi|dev|re(?:dev|st)|par)\w*|a(?:s|ies|vais|urai?s) +été|eus(?:ses|) +été) +({w_2})  @@w,$
-    <<- (morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \1.endswith(" été")) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
+    <<- (morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \1.endswith(" été")) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
     -2>> =suggSing(@)                                                        # Accord avec le sujet « tu » : « \2 » devrait être au singulier.
 
 TEST: tu n’es pas {{petites}}
 TEST: tu es {{insignifiants}}
 TEST: tu deviens vraiment très {{forts}} à ce jeu.
 
 
 __[i]/ppas(ppas_il_verbe)__
     (il|ce|ce qui|celui +qui|ça +qui|lui +qui|celui-(?:ci|là) +(?:qui +|)|quiconque) +(?:ne +|n’|)((?:es|étai|f[uû]|se[mr]|soi|dev|re(?:dev|st)|par)\w*|a(?:it|vait|ura(?:it|)|) +été|e[uû]t +été) +({w_2})  @@0,w,$
-    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and (morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or morphex(\3, ":[AQ].*:f", ":[GWYme]"))
     -3>> =suggMasSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin singulier.
 
 TEST: Il semble être {{partis}} pour toujours.                                    ->> parti
 TEST: Il est {{demander}} à chacun de participer.
@@ -9918,11 +12176,11 @@
 TEST: c’est ça qui paraît {{stupides}}
 TEST: celui-là semble {{perdus}} dans ses pensées.
 
 __[i]/ppas(ppas_c_être)__
     c’(?:est|était|e[uû]t +été) +({w_2})  @@$
-    <<- not (morph(\1, ">seule ", False) and after("^ +que? "))
+    <<- not (morph(\1, ">seule/", False) and after("^ +que? "))
         and ( morphex(\1, ":[NAQ].*:p", ":[GWYsi]") or ( morphex(\1, ":[AQ].*:f", ":[GWYme]") and not morph(word(1), ":N.*:f", False, False) ) )
     -1>> =suggMasSing(@)                                                     # Accord avec le sujet « c’ » : « \1 » devrait être au masculin singulier.
 
 TEST: c’est {{condescendants}}.                                                   ->> condescendant
 TEST: C’est {{finis}}.
@@ -9937,13 +12195,13 @@
 TEST: Ç’avait été {{horribles}}
 
 
 __[i]/ppas(ppas_ça_verbe)__
     (ça|ce(?:la|ci)|celui-(?:ci|là)) +(?:ne +|n’|)((?:es|étai|f[uû]|se[mr]|soi|par|dev|re(?:dev|st))\w+|a(?:it|vait|ura(?:it|)|) +été|e[uû]t +été) +({w_2})  @@0,w,$
-    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and ( morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or ( morphex(\3, ":[AQ].*:f", ":[GWYme]") and not morph(word(1), ":N.*:f", False, False) ) )
-        and not morph(word(-1), ":(?:R|V...t)|>de ", False, False)
+        and not morph(word(-1), ":(?:R|V...t)|>de/", False, False)
     -3>> =suggMasSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin singulier.
 
 TEST: ça semble {{perdus}}
 TEST: cela paraît {{incroyables}}
 TEST: Je n’arrêtais pas de me répéter que tout cela était peut-être pure imagination
@@ -9951,23 +12209,23 @@
 TEST: De cela a toujours été faite notre vie
 
 
 __[i]/ppas(ppas_lequel_verbe)__
     (lequel) +(?:ne +|n’|)((?:es|étai|f[uû]|se[mr]|soi|par|dev|re(?:dev|st))\w+|a(?:it|vait|ura(?:it|)|) +été|e[uû]t +été) +({w_2})  @@0,w,$
-    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and ( morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or ( morphex(\3, ":[AQ].*:f", ":[GWYme]") and not morph(word(1), ":N.*:f", False, False) ) )
         and not morph(word(-1), ":R", False, False)
     -3>> =suggMasSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin singulier.
 
 TEST: elle avait accompagné cet homme, lequel était {{revenue}} de l’enfer.
 
 
 __[i]/ppas(ppas_elle_verbe)__
     (elle|celle-(?:ci|là)|laquelle) +(?:ne +|n’|)((?:es|étai|f[uû]|se[rm]|soi|dev|re(?:dev|st)|par)\w*|a(?:it|vait|ura(?:it|)|) +été|e[uû]t +été) +({w_2})  @@0,w,$
-    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and (morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or morphex(\3, ":[AQ].*:m", ":[GWYfe]"))
-        and not morph(word(-1), ":R|>de ", False, False)
+        and not morph(word(-1), ":R|>de/", False, False)
     -3>> =suggFemSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin singulier.
 
 TEST: elle a été {{perdu}} sans toi                                               ->> perdue
 TEST: Elle semble être totalement {{ruiné}}.                                      ->> ruinée
 TEST: Elle est complètement {{fol}}.                                              ->> folle
@@ -9975,31 +12233,31 @@
 TEST: Elle est de plus en plus {{belles}}.                                        ->> belle
 
 
 __[i]/ppas(ppas_elle_qui_verbe)__
     (c?elle +qui) +(?:ne +|n’|)((?:es|étai|f[uû]|se[rm]|soi|dev|re(?:dev|st)|par)\w*|a(?:it|vait|ura(?:it|)|) +été|e[uû]t +été) +({w_2})  @@0,w,$
-    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and (morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or morphex(\3, ":[AQ].*:m", ":[GWYfe]"))
     -3>> =suggFemSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin singulier.
 
 TEST: celle qui paraît {{dingues}} de toi
 
 
 __[i]/ppas(ppas_nous_verbe)__
     nous +(?:ne +|n’|)((?:sommes|étions|fûmes|fussions|seri?ons|soyons|sembl|dev|re(?:dev|st)|par)\w*|a(?:vi?ons|uri?ons|yions) +été|e(?:ûme|ussion)s +été) +({w_2})  @@w,$
     <<- not re.search("(?i)^légion$", \2) and not before(r"(?i)\b(?:nous|ne) +$")
-        and ((morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) and morph(\1, ":1p", False)) or \1.endswith(" été"))
+        and ((morph(\1, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) and morph(\1, ":1p", False)) or \1.endswith(" été"))
         and morphex(\2, ":[NAQ].*:s", ":[GWYpi]")
     -2>> =suggPlur(@)                                                        # Accord avec le sujet « nous » : « \2 » devrait être au pluriel.
 
 TEST: nous paraissons {{faible}}
 TEST: Nous paraissons avoir été complètement {{prise}} de panique.                ->> prises
 
 
 __[i]/ppas(ppas_ils_verbe)__
     (ils|c?eux +qui|ceux-ci|ceux-là|lesquels) +(?:ne +|n’|)((?:sont|étaient|fu[rs]|se[rm]|soient|dev|re(?:dev|st)|par)\w*|ont +été|a(?:ient|vaient|ur(?:ont|aient)) +été|eu(?:r|ss)ent +été) +({w_2})  @@0,w,$
-    <<- not re.search("(?i)^légion$", \3) and (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- not re.search("(?i)^légion$", \3) and (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and (morphex(\3, ":[NAQ].*:s", ":[GWYpi]") or morphex(\3, ":[AQ].*:f", ":[GWYme]")) and not before("(?i)ce que? +$")
         and (not re.search("^(?:ceux-(?:ci|là)|lesquels)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggMasPlur(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin pluriel.
 
 TEST: ils sont {{parti}}.                                                         ->> partis
@@ -10014,11 +12272,11 @@
 TEST: ils sont très loin d’être {{idiot}}.
 
 
 __[i]/ppas(ppas_elles_verbe)__
     (elles|c?elles +qui|celles-(?:ci|là)|lesquelles) +(?:ne +|n’|)((?:sont|étai|fu[rs]|se[rm]|soi|dev|re(?:dev|st)|par)\w*|ont +été|a(?:ient|vaient|ur(?:ont|aient)) +été|eu(?:r|ss)ent +été) +({w_2})  @@0,w,$
-    <<- not re.search("(?i)^légion$", \3) and (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre) ", False) or \2.endswith(" été"))
+    <<- not re.search("(?i)^légion$", \3) and (morph(\2, ">(?:être|sembler|devenir|re(?:ster|devenir)|para[îi]tre)/", False) or \2.endswith(" été"))
         and (morphex(\3, ":[NAQ].*:s", ":[GWYpi]") or morphex(\3, ":[AQ].*:m", ":[GWYfe]"))
         and (not re.search("(?i)^(?:elles|celles-(?:ci|là)|lesquelles)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggFemPlur(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin pluriel.
 
 TEST: elles n’ont tout de même pas été {{attaqué}}                                ->> attaquées
@@ -10032,11 +12290,11 @@
     <<- morph(\2, ":V0a", False) >>>
     <<- morphex(\3, ":[123]s", ":[GNAQWY]") -3>> =suggVerbPpas(@)           # Après « avoir été », il faut un participe passé.
     <<- not before("[çcCÇ]’$|[cC]e n’$|[çÇ]a (?:n’|)$") and not before("(?i)^ *ne pas ") and not morph(word(-1), ":Y", False) >>>
     <<- morphex(\3, ":Y", ":A") -1>> _                                      # Tournure familière. Utilisez « être allé » plutôt que « avoir été ».
     <<- morphex(\3, ":V1..t.*:Y", ":A") -3>> =suggVerbPpas(@)               # Incohérence. Après « avoir été », il faut un participe passé (à moins que « avoir été » signifie ici « être allé »).
-    
+
 TEST: j’ai été {{instruis}} par elle
 TEST: avoir été {{prit}} par surprise
 TEST: Ils {{ont été}} {{réaliser}} à partir d’éléments naturels.
 TEST: J’{{ai été}} camper dans les Alpes.
 TEST: Tu {{as été}} prendre du bois.
@@ -10049,20 +12307,20 @@
 TEST: Partir aurait été assurer sa survie.
 
 
 !!
 !!
-!!!! Participes passés: pouvoir/sembler/paraître/vouloir/devoir/croire/déclarer/penser/dire/affirmer + être/avoir été
+!!!! Participes passés: pouvoir/sembler/paraître/vouloir/devoir/croire/déclarer/penser/dire/affirmer + être/avoir été  !!
 !!
 !!
 
 __[i](p_risque_d_être)__
     risqu\w+ +(d’)être @@* <<- ~1>> *
 
 __[i]/ppas(ppas_je_verbe_être)__
     j(?:e|’(?:y|en)) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2}) @@w,$
-    <<- morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
     -2>> =suggSing(@)                                                        # Accord avec le sujet « je » : « \2 » devrait être au singulier.
 
 TEST: Je ne peux pas être {{méchants}}.
 TEST: j’aurais vraiment été {{tentés}}
@@ -10071,11 +12329,11 @@
 TEST: je voudrais bien être dans ses souliers
 
 
 __[i]/ppas(ppas_tu_verbe_être)__
     tu +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@w,$
-    <<- morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
     -2>> =suggSing(@)                                                        # Accord avec le sujet « tu » : « \2 » devrait être au singulier.
 
 TEST: tu ne crois pas être {{meilleurs}}.
 TEST: tu ne crois pas avoir été {{découvertes}}
@@ -10082,11 +12340,11 @@
 TEST: tu vas être {{payées}}
 
 
 __[i]/ppas(ppas_il_verbe_être)__
     (il|ce|ce qui|celui +qui|ça +qui|lui +qui|celui-(?:ci|là) +qui|quiconque) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or morphex(\3, ":[AQ].*:f", ":[GWYme]"))
     -3>> =suggMasSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin singulier.
 
 TEST: Il peut être {{observée}}.
 TEST: celui-là pensait être {{perdue}}
@@ -10095,11 +12353,11 @@
 TEST: lui qui ne pensait jamais être {{reconnus}}.
 
 
 __[i]/ppas(ppas_ça_verbe_être)__
     (ça|ce(?:la|ci)|celui-(?:ci|là)|lequel) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[MWYsi]") or morphex(\3, ":[AQ].*:f", ":[GWYme]"))
         and not morph(word(-1), ":R", False, False)
     -3>> =suggMasSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin singulier.
 
 TEST: ça ne semble pas avoir été {{conçus}} pour ça.
@@ -10106,11 +12364,11 @@
 TEST: lequel allait être {{renvoyée}} de l’établissement.
 
 
 __[i]/ppas(ppas_elle_verbe_être)__
     (elle|celle-(?:ci|là)|laquelle) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[GWYsi]") or morphex(\3, ":[AQ].*:m", ":[GWYfe]"))
         and not morph(word(-1), ":R", False, False)
     -3>> =suggFemSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin singulier.
 
 TEST: elle ne croit pas être {{trompé}}
@@ -10117,40 +12375,40 @@
 TEST: ici, elle ne risque pas d’être {{attaquées}}
 
 
 __[i]/ppas(ppas_elle_qui_verbe_être)__
     (c?elle +qui) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2}) @@0,w,$
-    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[MWYsi]") or morphex(\3, ":[AQ].*:m", ":[GWYfe]"))
     -3>> =suggFemSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin singulier.
 
 TEST: celle qui pense être {{découvert}}
 
 
 __[i]/ppas(ppas_nous_verbe_être)__
     (?<![nN][oO][uU][sS] )nous +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@w,$
-    <<- not re.search("(?i)^légion$", \2) and morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- not re.search("(?i)^légion$", \2) and morph(\1, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and morph(\1, ":1p", False) and morphex(\2, ":[NAQ].*:s", ":[GWYpi]")
     -2>> =suggPlur(@)                                                        # Accord avec le sujet « nous » : « \2 » devrait être au pluriel.
 
 TEST: nous pensons être {{désiré}}
 TEST: nous ne devons pas être {{instruit}}
 
 
 __[i]/ppas(ppas_ils_verbe_être)__
     (ils|c?eux +qui|ceux-(?:ci|là)|lesquels) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@0,w,$
-    <<- not re.search("(?i)^légion$", \3) and morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- not re.search("(?i)^légion$", \3) and morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and (morphex(\3, ":[NAQ].*:s", ":[GWYpi]") or morphex(\3, ":[AQ].*:f", ":[GWYme]"))
         and (not re.search("^(?:ceux-(?:ci|là)|lesquels)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggMasPlur(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin pluriel.
 
 TEST: ils croient être {{perdu}}
 
 
 __[i]/ppas(ppas_elles_verbe_être)__
     (elles|c?elles +qui|celles-(?:ci|là)|lesquelles) +(?:ne +|n’|)((?:p[aeouûr]|s(?:embl|ouhait)|cr[ouû]|d[eouûéiî]|estim|i(?:magin|r)|v(?:[eo]u|a)|a(?:ffirm|im|dor|ll)|risqu)\w*) +(?:être|avoir été) +({w_2})  @@0,w,$
-    <<- not re.search("(?i)^légion$", \3) and morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller) ", False)
+    <<- not re.search("(?i)^légion$", \3) and morph(\2, ">(?:sembler|para[îi]tre|pouvoir|penser|préférer|croire|d(?:evoir|éclarer|ésirer|étester|ire)|vouloir|affirmer|aimer|adorer|souhaiter|estimer|imaginer|risquer|aller)/", False)
         and (morphex(\3, ":[NAQ].*:s", ":[GWYpi]") or morphex(\3, ":[AQ].*:m", ":[GWYfe]"))
         and (not re.search("^(?:elles|celles-(?:ci|là)|lesquelles)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggFemPlur(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin pluriel.
 
 TEST: elles veulent être {{différente}}
@@ -10161,11 +12419,11 @@
 TEST: elles peuvent avoir été {{trompé}}
 TEST: elles souhaitent être plus {{considérée}}
 
 
 
-!!!! Participes passés: accord en nombre avec la conjugaison de « être »                            
+!!!! Participes passés: accord en nombre avec la conjugaison de « être »                          !!
 
 ## Contrôle de l’
 __[i]/ppas(ppas_être_accord_singulier)__
     ({w_2}) +(?:qui +|)(?:ne +|n’|)(?:est|était|f[uû]t|sera(?:it|)|a(?:vait|ura|urait|it|) +été|e[uû]t +été) +({w_2})  @@0,$
     <<- morphex(\2, ":[NAQ].*:p", ":[GMWYsi]") and not morph(\1, ":G", False)
@@ -10175,11 +12433,11 @@
     ({w_2}) +(?:qui +|)(?:ne +|n’|)(?:sont|étaient|fu(?:r|ss)ent|ser(?:ont|aient)|soient|ont +été|a(?:vaient|uront|uraient|ient) +été|eu(?:r|ss)ent +été) +({w_2})  @@0,$
     <<- not re.search("(?i)^légion$", \2) and morphex(\2, ":[NAQ].*:s", ":[GWYpi]") and not morph(\1, ":G", False)
     -2>> =suggPlur(@)                                                        # Accord avec « être » : « \2 » devrait être au pluriel.
 
 
-!!!! Participes passés: accord en genre avec le substantif précédent                                
+!!!! Participes passés: accord en genre avec le substantif précédent                              !!
 
 __[i]/ppas(ppas_sujet_être_accord_genre)__
     (?<![dD]’)(une? |les? |la |l’|ce(?:s|t|tte|) |[mts](?:on|a|es) |[nv]os |leurs? ) *({w_2}) +(?:qui +|)(?:ne +|n’|)(?:est|étai(?:en|)t|f[uû]t|sera(?:i(?:en|)t|)|soi(?:en|)t|s(?:er|)ont|fu(?:r|ss)ent) +({w_2})  @@0,w,$
     <<- not re.search("(?i)^légion$", \3)
         and ((morphex(\3, ":[AQ].*:f", ":[GWme]") and morphex(\2, ":m", ":[Gfe]")) or (morphex(\3, ":[AQ].*:m", ":[GWfe]") and morphex(\2, ":f", ":[Gme]")))
@@ -10216,11 +12474,11 @@
 TEST: Martine n’est pas très {{intelligent}}.
 TEST: Pierre est {{dominée}} par son adversaire.
 
 
 
-!!!! Accords avec l’adjectif précédant le pronom                                                    
+!!!! Accords avec l’adjectif précédant le pronom                                                  !!
 
 __[i]/ppas(ppas_adj_accord_je_tu)__
     ^ *({w_2}s),? (je?|tu)  @@*,$
     <<- morphex(\1, ":A.*:p", ":(?:G|E|M1|W|s|i)")
     -1>> =suggSing(@)                                                       # Si cet adjectif se réfère au pronom « \2 », l’adjectif devrait être au singulier (et accordé en genre).
@@ -10236,19 +12494,19 @@
 TEST: — {{Déçue}}, il s’en est allé.
 
 
 __[i]/ppas(ppas_adj_accord_elle)__
     ^ *({w_2}[éuitsx]),? elle  @@*
-    <<- morphex(\1, ":A.*:[mp]", ":(?:G|E|M1|W|f:[si])|>(?:désoler|pire) ")
+    <<- morphex(\1, ":A.*:[mp]", ":(?:G|E|M1|W|f:[si])|>(?:désoler|pire)/")
     -1>> =suggFemSing(@)                                                    # Si cet adjectif se réfère au pronom « elle », l’adjectif devrait être au féminin singulier.
 
 TEST: — {{Déçu}}, elle s’en est allée.
 
 
 __[i]/ppas(ppas_adj_accord_ils)__
     ^ *({w_2}[eiuéts]),? ils  @@*
-    <<- morphex(\1, ":A.*:[fs]", ":(?:G|E|M1|W|m:[pi])|>(?:désoler|pire) ")
+    <<- morphex(\1, ":A.*:[fs]", ":(?:G|E|M1|W|m:[pi])|>(?:désoler|pire)/")
     -1>> =suggMasPlur(@)                                                    # Si cet adjectif se réfère au pronom « ils », l’adjectif devrait être au masculin pluriel.
 
 TEST: Très vite, ils sont partis
 TEST: Une fois terminé, ils sont revenus.
 TEST: Vraiment {{soucieuse}}, ils sont.
@@ -10256,11 +12514,11 @@
 TEST: Pire, ils piétinent parfois les droits humains.
 
 
 __[i]/ppas(ppas_adj_accord_elles)__
     ^ *({w_2}[eiuétsx]),? elles  @@*
-    <<- morphex(\1, ":A.*:[ms]", ":(?:G|E|M1|W|f:[pi])|>(?:désoler|pire) ")
+    <<- morphex(\1, ":A.*:[ms]", ":(?:G|E|M1|W|f:[pi])|>(?:désoler|pire)/")
     -1>> =suggFemPlur(@)                                                    # Si cet adjectif se réfère au pronom « elles », l’adjectif devrait être au féminin pluriel.
 
 TEST: Absolument {{heureux}}, elles exultèrent de joie.
 
 
@@ -10276,11 +12534,11 @@
 
 
 
 !!
 !!
-!!!! Inversion verbe/sujet                                                                          
+!!!! Inversion verbe/sujet                                                                        !!
 !!
 !!
 __[i]/ppas(ppas_inversion_être_je)__
     (?:s[ou]is|étais|fus(?:sé|)|serais?)-je +({w_2})  @@$
     <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:p)", ":[GWsi]")
@@ -10289,27 +12547,27 @@
     (?:es|étais|fus(?:ses|)|serai?s)-tu +({w_2})  @@$
     <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:p)", ":[GWsi]")
     -1>> =suggSing(@)                                                        # Accord avec le sujet « tu » : « \1 » devrait être au singulier.
 __[i]/ppas(ppas_inversion_être_il_ce)__
     (?:est|était|f[uû]t|sera(?:-t|it))-(il|ce) +({w_2})  @@*,$
-    <<- morphex(\2, ":(?:[123][sp]|Y|[NAQ].*:[pf])", ":(?:G|W|[me]:[si])|question ") and not (\1 == "ce" and morph(\2, ":Y", False))
+    <<- morphex(\2, ":(?:[123][sp]|Y|[NAQ].*:[pf])", ":(?:G|W|[me]:[si])|question/") and not (\1 == "ce" and morph(\2, ":Y", False))
     -2>> =suggMasSing(@)                                                     # Accord avec le sujet « il » : « \2 » devrait être au masculin singulier.
 __[i]/ppas(ppas_inversion_être_elle)__
     (?:est|était|f[uû]t|sera(?:-t|it))-elle +({w_2})  @@$
     <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:[pm])", ":(?:G|W|[fe]:[si])")
     -1>> =suggFemSing(@)                                                     # Accord avec le sujet « elle » : « \1 » devrait être au féminin singulier.
 __[i]/ppas(ppas_inversion_être_nous)__
     (?:sommes|étions|fûmes|fussions|seri?ons)-nous +({w_2})  @@$
-    <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:s)", ":[GWpi]|>dire ")
+    <<- morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:s)", ":[GWpi]|>dire/")
     -1>> =suggPlur(@)                                                        # Accord avec le sujet « nous » : « \1 » devrait être au pluriel.
 __[i]/ppas(ppas_inversion_être_ils)__
     (?:sont|étaient|fu(?:r|ss)ent|ser(?:o|aie)nt)-ils +({w_2})  @@$
-    <<- not re.search("(?i)^légion$", \1) and (morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:s)", ":[GWpi]|>dire ") or morphex(\1, ":(?:[123][sp]|[AQ].*:f)", ":[GWme]|>dire "))
+    <<- not re.search("(?i)^légion$", \1) and (morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:s)", ":[GWpi]|>dire/") or morphex(\1, ":(?:[123][sp]|[AQ].*:f)", ":[GWme]|>dire/"))
     -1>> =suggMasPlur(@)                                                     # Accord avec « ils » : « \1 » devrait être au masculin pluriel.
 __[i]/ppas(ppas_inversion_être_elles)__
     (?:sont|étaient|fu(?:r|ss)ent|ser(?:o|aie)nt)-elles +({w_2})  @@$
-    <<- not re.search("(?i)^légion$", \1) and (morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:s)", ":[GWpi]|>dire ") or morphex(\1, ":(?:[123][sp]|[AQ].*:m)", ":[GWfe]|>dire "))
+    <<- not re.search("(?i)^légion$", \1) and (morphex(\1, ":(?:[123][sp]|Y|[NAQ].*:s)", ":[GWpi]|>dire/") or morphex(\1, ":(?:[123][sp]|[AQ].*:m)", ":[GWfe]|>dire/"))
     -1>> =suggFemPlur(@)                                                     # Accord avec « elles » : « \1 » devrait être au féminin pluriel.
 
 TEST: serais-je {{fâchés}} contre vous ?
 TEST: Est-elle {{arriver}} ?
 TEST: Sont-elles {{arriver}} ?
@@ -10332,11 +12590,11 @@
 TEST: Est-il question de ceci ou de cela ?
 TEST: Est-ce former de futurs travailleurs ou bien des citoyens
 
 
 
-## Accord et incohérences 
+## Accord et incohérences
 __[i]/ppas(ppas_sont)__
     sont ({w_2})  @@5
     <<- morphex(\1, ":[NAQ]", ":[QWGBMpi]") and not re.search("(?i)^(?:légion|nombre|cause)$", \1) and not before(r"(?i)\bce que?\b")
     -1>> =suggPlur(@)               # Incohérence : « \1 » est au singulier. Ou vous confondez « sont » et « son », ou l’accord en nombre est incorrect.
     <<- __else__ and morphex(\1, ":V", ":(?:N|A|Q|W|G|3p)") and not before(r"(?i)\bce que?\b")
@@ -10346,43 +12604,43 @@
 
 
 
 !!
 !!
-!!!! Se croire/considérer/montrer/penser/révéler/savoir/sentir/voir/vouloir + participe passé/adj   
+!!!! Se croire/considérer/montrer/penser/révéler/savoir/sentir/voir/vouloir + participe passé/adj !!
 !!
 !!
 
 __[i]/ppas(ppas_je_me_verbe)__
     je +(?:ne +|)me +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@w,$
-    <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
+    <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
     -2>> =suggSing(@)                                                        # Accord avec le sujet « je » : « \2 » devrait être au singulier.
 
 TEST: je me savais {{implacables}} avec eux
 
 
 __[i]/ppas(ppas_tu_te_verbe)__
     tu +(?:ne +|)te +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@w,$
-    <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
+    <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False) and morphex(\2, ":[NAQ].*:p", ":[GWYsi]")
     -2>> =suggSing(@)                                                        # Accord avec le sujet « je » : « \2 » devrait être au singulier.
 
 TEST: quand tu te montres {{infaillibles}}
 
 
 __[i]/ppas(ppas_il_se_verbe)__
     (il|ce|ce qui|celui +qui|ça +qui|lui +qui|celui-(?:ci|là)|quiconque|lequel) +(?:ne +|)se +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False)
+    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[GWsi]") or morphex(\3, ":[NAQ].*:f", ":[GWYme]"))
         and (not re.search("^(?:celui-(?:ci|là)|lequel)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggMasSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin singulier.
 
 TEST: lequel se veut {{imbattables}} ?
 
 
 __[i]/ppas(ppas_elle_se_verbe)__
     (elle|celle-(?:ci|là)|laquelle) +(?:ne +|)se +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False)
+    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[GWsi]") or morphex(\3, ":[NAQ].*:m", ":[GWYfe]"))
         and not morph(word(-1), ":R", False, False)
     -3>> =suggFemSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin singulier.
 
 TEST: Elle se sait plus {{fortes}} qu’eux tous.
@@ -10389,84 +12647,84 @@
 TEST: elle se vit {{abandonné}}
 
 
 __[i]/ppas(ppas_elle_qui_se_verbe)__
     (c?elle +qui) +(?:ne +|)se +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False)
+    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False)
         and (morphex(\3, ":[NAQ].*:p", ":[GWsi]") or morphex(\3, ":[NAQ].*:m", ":[GWYfe]"))
     -3>> =suggFemSing(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin singulier.
 
 TEST: à celle qui se révélera {{attentif}} à tous ces problèmes.
 
 
 __[i]/ppas(ppas_nous_nous_verbe)__
     nous +(?:ne +|)nous +((?:s[eauû]|montr|pens|rév|v[oiîe])\w*ons) +({w_2})  @@w,$
-    <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False) and morphex(\2, ":[NAQ].*:s", ":[GWpi]")
+    <<- morph(\1, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False) and morphex(\2, ":[NAQ].*:s", ":[GWpi]")
     -2>> =suggPlur(@)                                                        # Accord avec le sujet « nous » : « \2 » devrait être au pluriel.
 
 TEST: nous nous pensions {{invincible}} jusqu’au jour où tout a basculé.
 
 
 __[i]/ppas(ppas_ils_se_verbe)__
     (ils|c?eux +qui|ceux-ci|ceux-là|lesquels) +(?:ne +|)se +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False)
+    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False)
         and (morphex(\3, ":[NAQ].*:s", ":[GWpi]") or morphex(\3, ":[NAQ].*:f", ":[GWYme]"))
         and (not re.search("^(?:ceux-(?:ci|là)|lesquels)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggMasPlur(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au masculin pluriel.
 
 TEST: ils se montrent {{exigeantes}}
 
 
 __[i]/ppas(ppas_elles_se_verbe)__
     (elles|c?elles +qui|celles-(?:ci|là)|lesquelles) +(?:ne +|)se +((?:s[eauû]|montr|pens|rév|v[oiîe])\w+) +({w_2})  @@0,w,$
-    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir) ", False)
+    <<- morph(\2, ">(?:montrer|penser|révéler|savoir|sentir|voir|vouloir)/", False)
         and (morphex(\3, ":[NAQ].*:s", ":[GWpi]") or morphex(\3, ":[NAQ].*:m", ":[GWYfe]"))
         and (not re.search("^(?:elles|celles-(?:ci|là)|lesquelles)$", \1) or not morph(word(-1), ":R", False, False))
     -3>> =suggFemPlur(@)                                                     # Accord avec le sujet « \1 » : « \3 » devrait être au féminin pluriel.
 
 TEST: elles se sentent {{perdu}}
 
 
 __[i]/ppas(ppas_le_verbe_pensée)__
     le ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}[esx])  @@w,$
-    <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\2, ":[AQ].*:(?:[me]:p|f)", ":(?:G|Y|[AQ].*:m:[is])")
+    <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà)/", False) and morphex(\2, ":[AQ].*:(?:[me]:p|f)", ":(?:G|Y|[AQ].*:m:[is])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -2>> =suggMasSing(@)                                                     # Accord avec le COD “le” : « \2 » doit être au masculin singulier.
 __[i]/ppas(ppas_la_verbe_pensée)__
     la ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}[uiéesx])  @@w,$
-    <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\2, ":[AQ].*:(?:[fe]:p|m)", ":(?:G|Y|[AQ]:f:[is])")
+    <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà)/", False) and morphex(\2, ":[AQ].*:(?:[fe]:p|m)", ":(?:G|Y|[AQ]:f:[is])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -2>> =suggFemSing(@)                                                     # Accord avec le COD “la” : « \2 » doit être au féminin singulier.
 __[i]/ppas(ppas_les_verbe_pensée)__
     les ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2})  @@w,$
-    <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])")
+    <<- morph(\1, ">(?:trouver|considérer|croire|rendre|voilà)/", False) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -2>> =suggPlur(@)                                                        # Accord avec le COD “les” : « \2 » doit être au pluriel.
 __[i]/ppas(ppas_me_te_verbe_pensée)__
     ([mt]e) ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2}[sx])  @@0,w,$
-    <<- morph(\2, ">(?:trouver|considérer|croire|rendre|voilà) ", False) and morphex(\3, ":[AQ].*:p", ":(?:G|Y|[AQ].*:[is])")
+    <<- morph(\2, ">(?:trouver|considérer|croire|rendre|voilà)/", False) and morphex(\3, ":[AQ].*:p", ":(?:G|Y|[AQ].*:[is])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -3>> =suggSing(@)                                                        # Accord avec le pronom “\1” : « \3 » doit être au singulier.
 __[i]/ppas(ppas_se_verbe_pensée)__
     se ((?:trouv|consid[éè]r|cr[ouû]|rend)\w*) +({w_3})  @@w,$
-    <<- morph(\1, ">(?:trouver|considérer|croire|rendre) .*:3s", False) and morphex(\2, ":[AQ].*:p", ":(?:G|Y|[AQ].*:[is])")
+    <<- morph(\1, ">(?:trouver|considérer|croire|rendre)/.*:3s", False) and morphex(\2, ":[AQ].*:p", ":(?:G|Y|[AQ].*:[is])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -2>> =suggSing(@)                                                        # Accord avec le pronom “se” (le verbe étant au singulier) : « \2 » doit être au singulier.
-    <<- __else__ and morph(\1, ">(?:trouver|considérer|croire|rendre) .*:3p", False) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])")
+    <<- __else__ and morph(\1, ">(?:trouver|considérer|croire|rendre)/.*:3p", False) and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -2>> =suggPlur(@)                                                        # Accord avec le pronom “se” (le verbe étant au pluriel) : « \2 » doit être au pluriel.
 __[i]/ppas(ppas_nous_verbe_pensée)__
     nous ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2})  @@w,$
-    <<- ( morphex(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", ":1p")
-        or (morph(\1, ">(?:trouver|considérer|croire) .*:1p", False) and before(r"\bn(?:ous|e) +$")) )
+    <<- ( morphex(\1, ">(?:trouver|considérer|croire|rendre|voilà)/", ":1p")
+        or (morph(\1, ">(?:trouver|considérer|croire)/.*:1p", False) and before(r"\bn(?:ous|e) +$")) )
         and morphex(\2, ":[AQ].*:s", ":(?:G|Y|[AQ].*:[ip])")
         and not (morph(\1, ":Y", False) and morph(\2, ":3s", False))
     -2>> =suggPlur(@)                                                        # Accord avec le pronom “nous” : « \2 » doit être au pluriel.
 #__[i]/ppas(ppas_vous_verbe)__
 #    vous ((?:trouv|consid[éè]r|cr[ouû]|rend|voilà)\w*) +({w_2})  @@w,$
-#    <<- ( morphex(\1, ">(?:trouver|considérer|croire|rendre|voilà) ", ":2p")
-#    or (morph(\1, ">(?:trouver|considérer|croire) .*:2p", False) and before(r"\b(?:vous|ne) +$")) )
+#    <<- ( morphex(\1, ">(?:trouver|considérer|croire|rendre|voilà)/", ":2p")
+#    or (morph(\1, ">(?:trouver|considérer|croire)/.*:2p", False) and before(r"\b(?:vous|ne) +$")) )
 #    and morphex(\2, ":[AQ].*:s", ":(?:G|[AQ].*:[ip])")
 #    -2>> =suggPlur(@)                                                        # Accord avec le pronom “vous” : « \2 » doit être au pluriel.
 
 TEST: ces hommes le rendent {{dingues}}
 TEST: Il me considère {{stupides}}
@@ -10490,23 +12748,23 @@
 
 
 
 !!
 !!
-!!!! Avoir + participes passés                                                                      
+!!!! Avoir + participes passés                                                                    !!
 !!
 !!
 
 #__[i]/conj__  fait(s|e|es) ({w1}) <<- morph(\2, ":V") and not morph(\2, ":Y")
 #   ->> fait \1                      # Le participe passé de faire reste au masculin singulier s’il est suivi par un verbe à l’infinitif.
 
 __[i](p_les_avoir_fait_vinfi)__
-    les ({avoir}) +(fait) +(?:[mts](?:e +|’)|)({infi}) @@w,w,$ <<- morph(\1, ">avoir ", False) and morph(\3, ":Y", False) ~2>> _
+    les ({avoir}) +(fait) +(?:[mts](?:e +|’)|)({infi}) @@w,w,$ <<- morph(\1, ">avoir/", False) and morph(\3, ":Y", False) ~2>> _
 
 __[i]/ppas(ppas_pronom_avoir)__
     (?:j’|je |tu |ils? |elles? |on |et )(?:ne +|n’|l(?:ui|eur) +|)({avoir}) +({w_2})  @@w,$
-    <<- not re.search("(?i)^(?:barre|confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \2) and morph(word(-1), ">(?:comme|et|lorsque?|mais|o[uù]|puisque?|qu(?:oique?|i|and)|si(?:non|)) ", False, True)
+    <<- not re.search("(?i)^(?:barre|confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \2) and morph(word(-1), ">(?:comme|et|lorsque?|mais|o[uù]|puisque?|qu(?:oique?|i|and)|si(?:non|))/", False, True)
         and morph(\1, ":V0a", False) and not \2.isupper() and morphex(\2, ":(?:[123][sp]|Q.*:[fp])", ":(?:G|W|Q.*:m:[si])")
     -2>> =suggMasSing(@)
     # Ce verbe devrait être un participe passé au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais
 
 TEST: ils leur avaient {{donnés}} du fil à retordre.
@@ -10518,11 +12776,11 @@
 
 
 __[i]/ppas(ppas_nous_vous_avoir)__
     ([nv]ous) +(?:ne +|n’|l(?:ui|eur) +|)({avoir}) +({w_2})  @@0,w,$
     <<- morph(\1, ":Os", False)
-        and not re.search("(?i)^(?:barre|confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \3) and morph(word(-1), ">(?:comme|et|lorsque?|mais|o[uù]|puisque?|qu(?:oique?|i|and)|si(?:non|)) ", False, True)
+        and not re.search("(?i)^(?:barre|confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \3) and morph(word(-1), ">(?:comme|et|lorsque?|mais|o[uù]|puisque?|qu(?:oique?|i|and)|si(?:non|))/", False, True)
         and morph(\2, ":V0a", False) and not \3.isupper() and morphex(\3, ":(?:[123][sp]|Q.*:[fp])", ":(?:G|W|Q.*:m:[si])")
     -3>> =suggMasSing(@)
     # Ce verbe devrait être un participe passé au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais
 
 TEST: Nous avons {{donne}} tout notre potentiel.
@@ -10530,11 +12788,11 @@
 TEST: D’un côté, le modèle occidental, […], nous a libérés de […]
 
 
 __[i]/ppas(ppas_det_nom_avoir)__
     (l(?:’|es? |a |eurs )|ce(?:s|tte|t|rtaine?s|) |des |quelques |[mts](?:es|on|a) |[nv]o(?:s|tre) ) *({w_2}) +(?:ne +|n’|l(?:ui|eur) +|)({avoir}) +({w_2})  @@0,w,w,$
-    <<- not re.search("(?i)^(?:barre|confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \4) and morph(word(-1), ">(?:comme|et|lorsque?|mais|o[uù]|puisque?|qu(?:oique?|i|and)|si(?:non|)) ", False, True)
+    <<- not re.search("(?i)^(?:barre|confiance|cours|envie|peine|prise|crainte|cure|affaire|hâte|force|recours)$", \4) and morph(word(-1), ">(?:comme|et|lorsque?|mais|o[uù]|puisque?|qu(?:oique?|i|and)|si(?:non|))/", False, True)
         and not morph(\2, ":G", False) and morph(\3, ":V0a", False) and not \4.isupper() and morphex(\4, ":(?:[123][sp]|Q.*:[fp])", ":(?:G|W|Q.*:m:[si])")
         and not (\3 == "avions" and morph(\4, ":3[sp]", False))
     -4>> =suggMasSing(@)
     # Ce verbe devrait être un participe passé au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais
 
@@ -10581,11 +12839,11 @@
 TEST: ces livres m’avaient {{ennuyés}} au-delà du dicible.
 
 
 __[i]/ppas(ppas_qui_avoir)__
     qui +(?:n’|l(?:ui|eur) |ne l(?:ui|eur) |ne +|)({avoir}) +({w_2}[es])  @@w,$
-    <<- morph(\1, ">avoir ", False) and morphex(\2, ":Q.*:(?:f|m:p)", ":m:[si]")
+    <<- morph(\1, ">avoir/", False) and morphex(\2, ":Q.*:(?:f|m:p)", ":m:[si]")
     -2>> =suggMasSing(@)
     # Le participe passé devrait être au masculin singulier.|http://fr.wikipedia.org/wiki/Accord_du_participe_pass%C3%A9_en_fran%C3%A7ais
 
 TEST: des hommes, des femmes, des enfants qui ne leur avaient {{faits}} que du bien.
 
@@ -10629,11 +12887,11 @@
 
 
 ## avoir avec participe passé
 __[i]/ppas(ppas_m_t_l_avoir)__
     [lmt]’(?:en +|y +|)({avoir}) +({w_3}) @@2,$
-    <<- morph(\1, ">avoir ", False) and morphex(\2, ":(?:Y|[123][sp])", ":[QGWMX]")
+    <<- morph(\1, ">avoir/", False) and morphex(\2, ":(?:Y|[123][sp])", ":[QGWMX]")
         and not re.search(r"(?i)^t’as +envie", \0)
     -2>> =suggVerbPpas(@, ":m:s")                                                                   # Confusion : employez un participe passé.
 
 TEST: m’avoir {{terminer}}.
 TEST: il m’a {{souffler}} la bonne réponse.
@@ -10643,11 +12901,11 @@
 
 
 
 !!
 !!
-!!!! COD précédant que                                                                                  
+!!!! COD précédant que                                                                            !!
 !!
 !!
 
 __[i]/ppas(ppas_det_plur_COD_que_avoir)__
     ([ldmtsc]es) +({w_2}) +que? +(?:j’|tu |ils? |[nv]ous |elles? |on ) *(?:ne +|n’|)({avoir}) +({w_2}[éiust]e?)(?! [mts]’)  @@0,w,w,$
@@ -10716,11 +12974,11 @@
 
 TEST: Avoir {{marcher}} toute la journée m’a épuisée.
 
 
 
-!!!! du / dû                                                                                        
+!!!! du / dû                                                                                      !!
 
 __[i]/ppas(ppas_avoir_dû_vinfi)__
     ({avoir}) +(due?s?) +(?:[mts]’|)({w_2})  @@0,w,$
     <<- morph(\1, ":V0a", False) and (morph(\3, ":Y") or re.search("^(?:[mtsn]e|[nv]ous|leur|lui)$", \3))
     -2>> dû                                                                                         # Participe passé de devoir : « dû ».
@@ -10760,11 +13018,11 @@
 TEST: A-t-il déjà {{signer}} le contrat ?
 
 
 !!
 !!
-!!!! Participes passés avec formes interrogatives                                                   
+!!!! Participes passés avec formes interrogatives                                                 !!
 !!
 !!
 
 __[i]/ppas(ppas_avoir_pronom1)__
     (?<![ltm]’)({avoir})[- ](?:je|tu|ils?|elles?|t-(?:ils?|elles?|on)|on) +({w2})  @@0,$
@@ -10780,11 +13038,11 @@
     -2>> =suggMasSing(@)
     # Avec « avoir », il faut un participe passé au masculin singulier.
 
 __[i]/ppas(ppas_l_m_t_avoir_pronom)__
     ([ltm]’)({avoir})[- ](?:je|tu|ils?|elles?|t-(?:ils?|elles?|on)|[nv]ous|on) +({w2}s)  @@0,2,$
-    <<- morph(\2, ":V0a", False) and morphex(\3, ":(?:Y|2p|Q.*:p)", ":[si]") 
+    <<- morph(\2, ":V0a", False) and morphex(\3, ":(?:Y|2p|Q.*:p)", ":[si]")
     -3>> =suggMasSing(@)
     # Accord avec le COD « \1 » : e participe passé « \2 » devrait être au singulier (et accordé en genre).
 
 __[i]/ppas(ppas_les_avoir_pronom)__
     les +({avoir})-(?:je|tu|ils?|elles?|t-(?:ils?|elles?|on)|[nv]ous|on) +({w_1}(?:[éiut]e?|is|se))  @@w,$
@@ -10827,11 +13085,11 @@
 __[i]/conj(conj_vous_verbe2)__
     vous [nm](?:e +(?:les? |l’|la |[nv]ous |)|’)({w_3})  @@$
     <<- morphex(\1, ":V", ":2p") and isStart() -1>> =suggVerb(@, ":2p")         # Conjugaison erronée. Accord avec « vous ». Le verbe devrait être à la 2ᵉ personne du pluriel.
 
 TEST: vous ne l’{{avait}} pas vu.
-TEST: je crois, vous m’{{avais}} trompé… 
+TEST: je crois, vous m’{{avais}} trompé…
 
 
 ## se + incohérence
 __[i]/conj(conj_se_incohérence)__
     s(?:e +(?:les? +|la +|)|’(?:en +|y +|))({w_2}(?:e[zs]|ons|is|us))  @@$
@@ -10844,11 +13102,11 @@
 TEST: se {{crois}} élu par Dieu…
 TEST: avec ceux se trouvant sur leur chemin
 
 
 
-!!!! Confusions ou/où                                                                               
+!!!! Confusions ou/où                                                                             !!
 
 __[i]/conf(conf_det_nom_où_pronom)__
     ^ *(?:l(?:es? +|a +|’)|[nv]o(?:s|tre) +|ce(?:t|tte|s|) +|[mts](?:es|on|a) +|des +)({w_2}) +(ou) +(?:je|tu|ils?|elles? +> +\w+|[nv]ous +> +\w+)  @@w,w
     <<- morphex(\1, ":[NAQ]", ":G")
     -2>> où                                                                         # Confusion probable. Pour évoquer un lieu ou un moment, écrivez :|http://fr.wiktionary.org/wiki/o%C3%B9
@@ -10858,11 +13116,11 @@
 
 
 
 !!!
 !!!
-!!! Processeur avant impératif                                                                      
+!!! Processeur avant impératif                                                                    !!
 !!!
 !!!
 
 __<i>(p_n_importe_qui_quoi)__       n(’)importe quo?i @@1 <<- ~1>> `
 
@@ -10872,11 +13130,11 @@
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
     <<- ~1>> *
 __<i](p_premier_ne_pro_per_obj2)__
     ^( *ne (?:[mt]’|l(?:ui|eur) )en) ({w_2})  @@0,$
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
-    <<- not morph(\1, ":X|>rien ", False) ~1>> *
+    <<- not morph(\1, ":X|>rien/", False) ~1>> *
 __<i](p_premier_ne_pro_per_obj3)__
     ^( *ne (?:[mt]e|[nv]ous) (?:les?|la|en)) ({w_2})  @@0,$
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
     <<- ~1>> *
 __<i](p_premier_ne_pro_per_obj4)__
@@ -10884,19 +13142,19 @@
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
     <<- ~1>> *
 __<i>(p_premier_ne_pro_per_obj5)__
     ^( *n’(?:en |y |))({w_2})  @@0,$
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
-    <<- not morph(\1, ":X|>rien ", False) ~1>> *
+    <<- not morph(\1, ":X|>rien/", False) ~1>> *
 __<i>(p_premier_ne_pro_per_obj6)__
     ^( *ne l’)({w_2})  @@0,$
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
     <<- ~1>> *
 __<i>(p_premier_ne_pro_per_obj7)__
     ^( *ne) ({w_2})  @@0,$
     <<- morph(\2, ":(?:[123][sp]|P)", False) =>> select(\2,":(?:[123][sp]|P)")
-    <<- not morph(\2, ":X|>rien ", False) ~1>> *
+    <<- not morph(\2, ":X|>rien/", False) ~1>> *
 
 TEST: Ne rien céder.
 TEST: Ne pas manger.
 TEST: Ne manquer de rien.
 TEST: Ne jamais miser sur ces tocards.
@@ -10903,11 +13161,11 @@
 TEST: Ne m’en rien laisser.
 
 
 !!
 !!
-!!!! Impératif !                                                                                    
+!!!! Impératif !                                                                                  !!
 !!
 !!
 
 # Confusions
 __[i]/imp(imp_confusion_2e_pers_pluriel)__
@@ -10950,19 +13208,20 @@
 
 # verbes du 2ᵉ et du 3ᵉ groupe en -t
 __[i]/imp(imp_vgroupe2_vgroupe3_t)__
     ^ *(\w+t)(?![- ](?:je|tu|[nv]ous|ils?|elles?|on|t-ils?|t-elles?))  @@$
     <<- morphex(\1, ":V[23].*:Ip.*:3s", ":[GNA]|>(?:devoir|suffire)") and analyse(\1[:-1]+"s", ":E:2s", False)
-        and not (re.search("(?i)^vient$", \1) and after("^ +(?:l[ea]|se |s’)"))
+        and not (re.search("(?i)^vient$", \1) and after("^ +(?:l[ea]|[sd]e |[sd]’)"))
         and not (re.search("(?i)^dit$", \1) and after("^ +[A-ZÉÈÂÎ]"))
     -1>> =\1[:-1]+"s"                                                               # S’il s’agit d’un impératif, la terminaison est “is”, non “it”.
 
 TEST: {{Finit}} ton assiette.
 TEST: Ne {{pourrit}} pas l’ambiance.
 TEST: Suffit de s’en servir.
 TEST: Et ne doit pas être rejeté dans les limbes.
 TEST: Vient s’ajouter à ce contexte la perception, partagée par beaucoup, du caractère fortement menaçant de l’environnement économique et géopolitique.
+TEST: À son bord vient d’embarquer un nouvel équipage
 
 
 # verbes du 3ᵉ groupe en -d
 __[i]/imp(imp_vgroupe3_d)__
     ^ *(\w+d)(?![- ](?:je|tu|[nv]ous|ils?|elles?|on|t-ils?|t-elles?))  @@$
@@ -11035,11 +13294,11 @@
 TEST: explique-{{leurs}} de quoi il est question.
 
 
 !!
 !!
-!!!! Impératif: traits d’union manquants                                                            
+!!!! Impératif: traits d’union manquants                                                          !!
 !!
 !!
 
 __[i]/imp(imp_union_moi_toi)__
     (?<!’)({w_2}) ([mt]oi)(?! même)  @@0,$
@@ -11069,11 +13328,11 @@
 TEST: Prenez les 5 ou 6 revues
 
 
 __[i]/imp(imp_union_le_la_leur)__
     (?<!’)({w_2}) (l(?:e(?:ur|)|a))(?! plus| moins| mieux| peu| plupart| trop| très| une?)  @@0,$
-    <<- morphex(\1, ":E", ":[GM]") and morphex(word(1), ":", ":(?:N|A|Q|Y|MP|H|T)", True) and morph(word(-1), ":Cc", False, True)
+    <<- morphex(\1, ":E", ":[GM]") and morphex(word(1), ":", ":(?:N|A|Q|Y|MP|H|T)|>pour/", True) and morph(word(-1), ":Cc", False, True)
     ->> \1-\2
     # S’il s’agit d’un impératif, mettez un trait d’union.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4206
 
 TEST: {{Prends le}} avec toi.
 TEST: {{Dites leur}} que nous sommes là.
@@ -11084,11 +13343,11 @@
 TEST: deux fois par an, souligne le Dr Assouline
 
 
 __[i]/imp(imp_laisser_le_la_les_infi)__
     ((laiss\w+) l(?:es|a)) +({w_2})  @@0,0,$
-    <<- morph(\2, ">laisser .*:E", False) and morphex(\3, ":(?:Y|X|Oo)", ":[NAB]")
+    <<- morph(\2, ">laisser/.*:E", False) and morphex(\3, ":(?:Y|X|Oo)", ":[NAB]")
     -1>> =\1.replace(" ", "-")
     # S’il s’agit d’un impératif, mettez un trait d’union.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4206
 
 TEST: {{Laisse les}} entrer…
 TEST: {{Laissez la}} venir…
@@ -11097,11 +13356,11 @@
 TEST: le coût humain de la guerre qu’il a laissé les submerger.
 
 
 __<i]/imp(imp_apostrophe_m_t_en)__
     ([ -][mt])-en @@0
-    <<- not (\0.endswith("t-en") and before(r"(?i)\bva$") and morph(word(1), ">guerre ", False, False)) ->> \1’en
+    <<- not (\0.endswith("t-en") and before(r"(?i)\bva$") and morph(word(1), ">guerre/", False, False)) ->> \1’en
     # « \1e » est ici abrégé, c’est une forme élidée. Il faut mettre une apostrophe et non un trait d’union.
 
 TEST: donne{{-m-en}} encore
 
 
@@ -11156,11 +13415,11 @@
 
 
 
 !!!
 !!!
-!!! Processeur: destruction des pronoms qui précèdent un verbe et de l’adverbe de négation “ne”.    
+!!! Processeur: destruction des pronoms qui précèdent un verbe et de l’adverbe de négation “ne”.  !!
 !!!
 !!!
 
 # Brainfuck (ici, prudence !)
 __[i](p_pro_per_obj01)__
@@ -11281,11 +13540,11 @@
     <<- morph(\2, ":(?:[123][sp]|P|Y)", False) =>> select(\2, ":(?:[123][sp]|P|Y)")
     <<- not morph(\2, ":2s", False) or before(r"(?i)\b(?:je|tu|on|ils?|elles?|nous) +$") ~1>> *
 __[i](p_pro_per_obj30)__
     (t’)({w_2}) @@0,$
     <<- morph(\2, ":(?:[123][sp]|P|Y)", False) =>> select(\2, ":(?:[123][sp]|P|Y)")
-    <<- not morph(\2, ":2s|>(ils?|elles?|on) ", False) or before(r"(?i)\b(?:je|tu|on|ils?|elles?|nous) +$") ~1>> *
+    <<- not morph(\2, ":2s|>(ils?|elles?|on)/", False) or before(r"(?i)\b(?:je|tu|on|ils?|elles?|nous) +$") ~1>> *
 __[i>(p_pro_per_obj31)__
     (ne +[mtsl]’)({w_1})  @@0,$
     <<- morph(\2, ":(?:[123][sp]|P|Y)", False) =>> select(\2, ":(?:[123][sp]|P|Y)")
     <<- ~1>> *
 __[i>(p_pro_per_obj32)__
@@ -11304,11 +13563,11 @@
 
 
 
 !!
 !!
-!!!! Confusions                                                                                     
+!!!! Confusions                                                                                   !!
 !!
 !!
 
 #### CONFUSION a / à
 __[i]/conf(conf_pronom_verbe_à)__
@@ -11347,15 +13606,15 @@
 TEST: Notre communauté vous est redevable.
 TEST: l’humour est affaire de culture
 TEST: Aller chercher l’air pur à la campagne est peine perdue.
 
 
-#### CONFUSION veillez/veuillez                                                                     
+#### CONFUSION veillez/veuillez
 
 __[i]/conf(conf_veillez2)__
     (veuillez) +à +(ne|{infi})  @@0,$
-    <<- isStart() and morph(\2, ":Y|>ne ", False) -1>> veillez          # Confusion probable : “veuillez” est une forme conjuguée du verbe “vouloir”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=1939
+    <<- isStart() and morph(\2, ":Y|>ne/", False) -1>> veillez          # Confusion probable : “veuillez” est une forme conjuguée du verbe “vouloir”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=1939
 
 TEST: {{Veuillez}} à ne pas tomber dans ce piège.
 TEST: Et {{veuillez}} surtout à ouvrir grand les yeux.
 TEST: {{Veuillez}}, s’il vous plaît, à prendre vos médicaments.
 TEST: Veuillez à nouveau faire attention à ce problème.
@@ -11363,11 +13622,11 @@
 TEST: Veillez à bien fermer les fenêtres.
 
 
 __[i]/conf(conf_veuillez)__
     (veillez) +(ne|{infi})  @@0,$
-    <<- isStart() and morph(\2, ":Y|>ne ", False) -1>> veuillez
+    <<- isStart() and morph(\2, ":Y|>ne/", False) -1>> veuillez
     # Confusion probable : “veiller” signifie “prendre garde” ou “être vigilant”. Pour inviter à faire quelque chose, écrivez “veuillez”.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=1939
 
 TEST: {{Veillez}} excuser mon retard.
 TEST: {{Veillez}} me contacter.
 TEST: {{Veillez}} me le faire savoir.
@@ -11380,11 +13639,11 @@
 
 
 
 !!
 !!
-!!!! Infinitif                                                                                      
+!!!! Infinitif                                                                                    !!
 !!
 !!
 
 __[i]/infi(infi_comment_où)__
     (?:comment|où) +({w_2}(?:ée?s?|ez))  @@$
@@ -11405,11 +13664,11 @@
 TEST: en train de {{mangez}}
 
 
 __[i]/infi(infi_verbe)__
     ((?:aim|all|v|ir|désir|esp[éè]r|p(?:[eou]|réf[éè]r))\w*) +({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morphex(\1, ">(?:aimer|aller|désirer|devoir|espérer|pouvoir|préférer|souhaiter|venir) ", ":[GN]") and morphex(\2, ":V", ":M")
+    <<- morphex(\1, ">(?:aimer|aller|désirer|devoir|espérer|pouvoir|préférer|souhaiter|venir)/", ":[GN]") and morphex(\2, ":V", ":M")
     -2>> =suggVerbInfi(@)                                                                           # S’il s’agit d’une action à accomplir, le verbe devrait être à l’infinitif.
 
 TEST: elle préférait {{mangée}} seule.
 TEST: Il venait, comme d’habitude, {{discuté}} avec son ami.
 TEST: Ces types-là venaient {{mangé}} chez moi tous les dimanches.
@@ -11419,11 +13678,11 @@
 TEST: Cette affaire ne va rien {{arrangé}}.
 
 
 __[i]/infi(infi_devoir)__
     (d[eouû]\w+) +({w_2}(?:ée?s?|ez))  @@0,$
-    <<- morph(\1, ">devoir ", False) and morphex(\2, ":V", ":M") and not morph(word(-1), ":D", False)
+    <<- morph(\1, ">devoir/", False) and morphex(\2, ":V", ":M") and not morph(word(-1), ":D", False)
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: il devait {{utilisé}} son temps à bon escient.
 TEST: tu dois {{mangé}}
 
@@ -11436,11 +13695,11 @@
 TEST: faut-il {{pensé}} à ces choses-là encore et encore ?
 
 
 __[i]/infi(infi_mieux_valoir)__
     mieux (?:ne |)(va\w+) +({w_2}(?:ée?s?|ez))  @@w,$
-    <<- morph(\1, ">valoir ", False) and morphex(\2, ":(?:Q|2p)", ":[GM]")
+    <<- morph(\1, ">valoir/", False) and morphex(\2, ":(?:Q|2p)", ":[GM]")
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.
 
 TEST: Mieux vaut {{consacré}} son temps à des occupations utiles.
 
 
@@ -11453,11 +13712,11 @@
 TEST: je vais à Rodez.
 
 
 __[i]/infi(infi_avoir_beau)__
     ({avoir}) beau ({w_2}(?:ée?s?|ez|ai[ts]?))  @@0,$
-    <<- morph(\1, ">avoir ", False) and morphex(\2, ":V1", ":N")
+    <<- morph(\1, ">avoir/", False) and morphex(\2, ":V1", ":N")
     -2>> =suggVerbInfi(@)                                                                           # Le verbe devrait être à l’infinitif.|http://fr.wiktionary.org/wiki/avoir_beau
 
 TEST: Ils ont beau {{consacré}} le plus clair de leur temps à ce projet, ça n’avance guère.
 
 
@@ -11484,18 +13743,18 @@
 TEST: Ne pas aimer n’est pas oublier l’autre.
 
 
 !!
 !!
-!!!! Conjugaison                                                                                    
+!!!! Conjugaison                                                                                  !!
 !!
 !!
 
 ## 1sg
 __[i]/conj(conj_j)__
     j’({w_1})  @@2
-    <<- morphex(\1, ":V", ":1s|>(?:en|y) ") >>>
+    <<- morphex(\1, ":V", ":1s|>(?:en|y)/") >>>
     <<- \1 == "est" or \1 == "es" -1>> ai|aie|suis          # Conjugaison erronée. Confusion probable entre “être” et “avoir”. Accord avec « \1 ». Le verbe devrait être à la 1ʳᵉ personne du singulier.
     <<- __else__ -1>> =suggVerb(@, ":1s")                   # Conjugaison erronée. Accord avec « je ». Le verbe devrait être à la 1ʳᵉ personne du singulier.
 __[i]/conj(conj_je)__
     (je) +({w_1})  @@0,$
     <<- morphex(\2, ":V", ":(?:1s|G)") and not (morph(\2, ":[PQ]", False) and morph(word(-1), ":V0.*:1s", False, False)) >>>
@@ -11601,11 +13860,11 @@
 TEST: celui qui {{pensent}} mal de toute chose
 
 
 __[i]/conj(conj_ça)__
     (ça|chacune?|l’une?|ce(?:ci|la|lui-(?:ci|là)|lle-(?:ci|là))|n`importe quo?i|quelqu(?:’une?|e chose)) +(?:qui +|)({w_1})  @@0,$
-    <<- morphex(\2, ":V", ":(?:3s|P|Q|G|3p!)") and not morph(word(-1), ":[VR]|>de ", False, False)
+    <<- morphex(\2, ":V", ":(?:3s|P|Q|G|3p!)") and not morph(word(-1), ":[VR]|>de/", False, False)
     -2>> =suggVerb(@, ":3s")                                 # Conjugaison erronée. Accord avec « \1 ». Le verbe devrait être à la 3ᵉ personne du singulier.
 
 TEST: chacun {{fais}} comme il peut
 TEST: quelqu’un {{sauras}}
 #TEST: quelqu’une se {{montrent}} désagréable  # Fuck you, JavaScript (wait for negative lookbehind assertions)
@@ -11736,11 +13995,11 @@
 TEST: l’un des chants les plus diffusés pendant la Révolution culturelle
 
 
 __[i]/conj(conj_infi)__
     ^ *({infi}) +({w_2})  @@*,$
-    <<- morph(\1, ":Y", False) and morph(\2, ":V.[a-z_!?]+(?!.*:(?:3s|P|Q|Y|3p!))") 
+    <<- morph(\1, ":Y", False) and morph(\2, ":V.[a-z_!?]+(?!.*:(?:3s|P|Q|Y|3p!))")
     -2>> =suggVerb(@, ":3s")                                 # Conjugaison erronée. Accord avec « \1… ». Le verbe devrait être à la 3ᵉ personne du singulier.
 
 TEST: manger {{fais}} grossir.
 TEST: boire immodérément {{nuis}} à la santé
 
@@ -11905,11 +14164,11 @@
 
 # L’accord par syllepse est obligatoire après /la plupart/, ainsi qu’après /nombre/ et /quantité/ employés sans déterminant. L’accord se fait avec le « pseudo-complément ».
 
 __[i]/conj(conj_beaucoup_d_aucuns_la_plupart)__
     (beaucoup|d’aucuns|la plupart) +({w_2})  @@0,$
-    <<- morphex(\2, ":V", ":(?:3p|P|Q|G)") and not morph(word(-1), ":[VR]|>de ", False, False)
+    <<- morphex(\2, ":V", ":(?:3p|P|Q|G)") and not morph(word(-1), ":[VR]|>de/", False, False)
     -2>> =suggVerb(@, ":3p")                                # Conjugaison erronée. Accord avec « \1 ». Le verbe devrait être à la 3ᵉ personne du pluriel.
 
 __[i]/conj(conj_beaucoup_d_aucuns_la_plupart_qui)__
     (beaucoup|d’aucuns|la plupart) +qui +({w_2})  @@0,$
     <<- morphex(\2, ":V", ":(?:3p|P|Q|G)") and not morph(word(-1), ":[VR]", False, False)
@@ -12023,11 +14282,11 @@
 TEST: L’un comme l’autre devaient y renoncer.
 
 
 __[i]/conj(conj_des_nom1)__
     ^ *des +({w_2}) +({w_2})  @@w,$
-    <<- morph(\1, ":[NAQ].*:[pi]", False) and morphex(\2, ":V", ":(?:[13]p|P|G|Q|A.*:[pi])") and morph(word(1), ":(?:R|D.*:p)|>au ", False, True) >>>
+    <<- morph(\1, ":[NAQ].*:[pi]", False) and morphex(\2, ":V", ":(?:[13]p|P|G|Q|A.*:[pi])") and morph(word(1), ":(?:R|D.*:p)|>au/", False, True) >>>
     <<- not morph(\2, ":[NA]", False) -2>> =suggVerb(@, ":3p")                          # Conjugaison erronée. Accord avec « des \1… ». Le verbe devrait être à la 3ᵉ personne du pluriel.
     <<- __else__ and not checkAgreement(\1, \2) -2>> =suggVerb(@, ":3p", suggPlur)      # Conjugaison erronée. Accord avec « des \1… ». Le verbe devrait être à la 3ᵉ personne du pluriel.
 __[i]/conj(conj_des_nom_qui)__
     ^ *des +({w_2}) +qui +({w_2})  @@w,$
     <<- morph(\1, ":[NAQ].*:[pi]", False) and morphex(\2, ":V", ":(?:[13]p|P|G)")
@@ -12036,11 +14295,11 @@
 TEST: Des hommes {{arrive}}.
 TEST: Des femmes ne {{demande}} rien.
 TEST: des femmes qui {{conduise}} la marche du monde.
 
 
-!!!! Quel(le) que soit / quel(le)s que soient                                                       
+!!!! Quel(le) que soit / quel(le)s que soient                                                     !!
 
 # singulier
 __[i]/conj(conj_quel_quelle_que_3sg1)__
     quel(?:le|)s? que ([sf]\w+) +(?:l[ea]|ce(?:t|tte|)|[mts](?:a|on)|[nv]otre|leur)  @@w
     <<- morphex(\1, ":V0e", ":3s")
@@ -12113,11 +14372,11 @@
 
 
 
 !!
 !!
-!!!! Inversion verbe sujet                                                                          
+!!!! Inversion verbe sujet                                                                        !!
 !!
 !!
 
 __[i]/conj(conj_que_où_comment_verbe_sujet_sing)__
     (?:que?|où|comment|combien|dont|quand|pourquoi) +({w1}) (l(?:e(?:ur | )|a |’)|[mts](?:on|a) |ce(?:t|tte|) |[nv]otre |du ) *(?!plupart|majorité)({w1})  @@w,w,$
@@ -12192,11 +14451,11 @@
 
 
 
 !!
 !!
-!!!! Formes interrogatives ?                                                                        
+!!!! Formes interrogatives ?                                                                      !!
 !!
 !!
 
 __[i]/inte(inte_union_xxxe_je)__
     (?<![jJ]’)({w_2}[éèe]) je  @@0
@@ -12210,11 +14469,11 @@
     ({w_1}s) tu  @@0
     <<- morphex(\1, ":V.*:2s", ":[GNW]") and not before(r"(?i)\b(?:je|tu) +$") and morphex(word(1), ":", ":2s", True)
     ->> \1-tu                                                                                       # Forme interrogative ? Mettez un trait d’union.
 __[i]/inte(inte_union_il_on)__
     ({w_2}[td]) (?:il|on)  @@0
-    <<- morphex(\1, ":V.*:3s", ":[GNW]") and not before(r"(?i)\b(?:ce|il|elle|on) +$") and morphex(word(1), ":", ":3s|>y ", True)
+    <<- morphex(\1, ":V.*:3s", ":[GNW]") and not before(r"(?i)\b(?:ce|il|elle|on) +$") and morphex(word(1), ":", ":3s|>y/", True)
     ->> =\0.replace(" ", "-")                                                                       # Forme interrogative ? Mettez un trait d’union.
 __[i]/inte(inte_union_elle)__
     (?<![cC]’)({w_2}[td]) elle  @@0
     <<- morphex(\1, ":V.*:3s", ":[GNW]") and not before(r"(?i)\b(?:ce|il|elle|on) +$") and morphex(word(1), ":", ":3s", True)
     ->> \1-elle                                                                                     # Forme interrogative ? Mettez un trait d’union.
@@ -12222,11 +14481,11 @@
     ({w_2}ons) nous  @@0
     <<- morphex(\1, ":V.*:1p", ":[GNW]") and not morph(word(-1), ":Os", False, False) and morphex(word(1), ":", ":(?:Y|1p)", True)
     ->> \1-nous                                                                                     # Forme interrogative ? Mettez un trait d’union.
 __[i]/inte(inte_union_vous)__
     ({w_2}e[zs]) vous  @@0
-    <<- morphex(\1, ":V.*:2p", ":[GNW]|>vouloir .*:E:2p") and not morph(word(-1), ":Os", False, False) and morphex(word(1), ":", ":(?:Y|2p)", True)
+    <<- morphex(\1, ":V.*:2p", ":[GNW]|>vouloir/.*:E:2p") and not morph(word(-1), ":Os", False, False) and morphex(word(1), ":", ":(?:Y|2p)", True)
     ->> \1-vous                                                                                     # Forme interrogative ? Mettez un trait d’union.
 __[i]/inte(inte_union_ils_elles)__
     (?<![cC]’)({w_1}nt) (?:ils|elles)  @@0
     <<- morphex(\1, ":V.*:3p", ":[GNW]") and not before(r"(?i)\b(?:ce|ils|elles) +$") and morphex(word(1), ":", ":3p", True)
     ->> =\0.replace(" ", "-")                                                                       # Forme interrogative ? Mettez un trait d’union.
@@ -12246,33 +14505,33 @@
 TEST: C’était elle qui avait pris le contrôle.
 
 
 __[i]/inte(inte_je)__
     ({w1})-je  @@0
-    <<- morphex(\1, ":V", ":1[sśŝ]") -1>> =suggVerb(@, ":1ś")                                       # Forme interrogative : « \1 » n’est pas un verbe à la 1ʳᵉ personne du singulier.
+    <<- analysex(\1, ":V", ":1[sśŝ]") -1>> =suggVerb(@, ":1ś")                                      # Forme interrogative : « \1 » n’est pas un verbe à la 1ʳᵉ personne du singulier.
     <<- not morph(\1, ":V", False) -1>> =suggSimil(\1, ":1[sśŝ]", False)                            # Forme interrogative : « \1 » n’est pas un verbe à la 1ʳᵉ personne du singulier.
 
 TEST: {{Vas}}-je                                            ->> Vais
 TEST: {{Prit}}-je                                           ->> Pris
 TEST: {{prix}}-je le temps d’y parvenir ? Oui.
 
 
 __[i]/inte(inte_tu)__
     ({w1})-tu  @@0
-    <<- morphex(\1, ":V", ":[ISK].*:2s") -1>> =suggVerb(@, ":2s")                                   # Forme interrogative. « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
-    <<- not morph(\1, ":V", False) -1>> =suggSimil(\1, ":2s", False)                                # Forme interrogative : « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
+    <<- analysex(\1, ":V", ":[ISK].*:2s") -1>> =suggVerb(@, ":2s")                                  # Forme interrogative. « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
+    <<- not analyse(\1, ":V", False) -1>> =suggSimil(\1, ":2s", False)                              # Forme interrogative : « \1 » n’est pas un verbe à la 2ᵉ personne du singulier.
 
 TEST: {{Peut}}-tu                                           ->> Peux
 TEST: {{peu}}-tu revenir chez moi ?
 
 
 __[i]/inte(inte_il_elle_on)__
     ({w1})-(?:t-|)(il|elle|on)  @@0,$
-    <<- morphex(\1, ":V", ":3s") -1>> =suggVerb(@, ":3s")                                           # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.
-    <<- \1 != "t" and (not \1.endswith("oilà") or \2 != "il") and morphex(\1, ":", ":V")
+    <<- analysex(\1, ":V", ":3s") -1>> =suggVerb(@, ":3s")                                          # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.
+    <<- \1 != "t" and (not \1.endswith("oilà") or \2 != "il") and analysex(\1, ":", ":V")
     -1>> =suggSimil(\1, ":3s", False)                                                               # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.
-    <<- not \2.endswith(("n", "N")) and morphex(\1, ":3p", ":3s") -2>> \2s                          # Forme interrogative : accordez “\2” avec le verbe à la 3ᵉ personne du pluriel.
+    <<- not \2.endswith(("n", "N")) and analysex(\1, ":3p", ":3s") -2>> \2s                         # Forme interrogative : accordez “\2” avec le verbe à la 3ᵉ personne du pluriel.
 
 TEST: {{Peux}}-il                                           ->> Peut
 TEST: {{Attaques}}-t-on                                     ->> Attaque
 TEST: {{Prends}}-elle                                       ->> Prend
 TEST: {{Menthe}}-t-elle souvent ?
@@ -12280,12 +14539,12 @@
 TEST: Le moteur choisi convient-il ?
 
 
 __[s]/inte(inte_ce)__
     ({w_2})-([cs]e)  @@0,$
-    <<- morphex(\1, ":V", ":(?:3s|V0e.*:3p)") -1>> =suggVerb(@, ":3s")      # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
-    <<- morphex(\1, ":", ":V") -1>> =suggSimil(\1, ":3s", False)            # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
+    <<- analysex(\1, ":V", ":(?:3s|V0e.*:3p)") -1>> =suggVerb(@, ":3s")     # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
+    <<- analysex(\1, ":", ":V") -1>> =suggSimil(\1, ":3s", False)           # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du singulier.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
     <<- \2 == "se" -2>> ce                                                  # Forme interrogative. Confusion.|http://bdl.oqlf.gouv.qc.ca/bdl/gabarit_bdl.asp?id=4132
 
 TEST: était-{{se}} cela, la vérité ineffable ?
 TEST: {{étai}}-ce notre destinée de souffrir ?
 TEST: étaient-{{se}} ces hommes-là qui allaient nous guider dans les montagnes ?
@@ -12293,79 +14552,91 @@
 TEST: Eh ! dit Athos, ne sont-ce pas des braconniers qu’on arrête là-bas ?
 
 
 __[i]/inte(inte_nous)__
     ({w1})-nous  @@0
-    <<- morphex(\1, ":V", ":(?:1p|E:2[sp])") -1>> =suggVerb(@, ":1p")                               # Forme interrogative ou impérative incorrecte.
-    <<- morphex(\1, ":", ":V|>chez ") -1>> =suggSimil(\1, ":1p", False)                             # Forme interrogative ou impérative incorrecte.
+    <<- analysex(\1, ":V", ":(?:1p|E:2[sp])") -1>> =suggVerb(@, ":1p")                              # Forme interrogative ou impérative incorrecte.
+    <<- analysex(\1, ":", ":V|>chez/") -1>> =suggSimil(\1, ":1p", False)                            # Forme interrogative ou impérative incorrecte.
 
 TEST: {{Prendront}}-nous                                    ->> Prendrons
 TEST: {{Attendront}}-nous le train                          ->> Attendrons
 
 
 __[i]/inte(inte_vous)__
     ({w1})-vous  @@0
-    <<- morphex(\1, ":V", ":2p") -1>> =suggVerb(@, ":2p")                                           # Forme interrogative ou impérative incorrecte.
-    <<- not morph(\1, ":V|>chez ", False) -1>> =suggSimil(\1, ":2p", False)                         # Forme interrogative ou impérative incorrecte.
+    <<- analysex(\1, ":V", ":2p") -1>> =suggVerb(@, ":2p")                                          # Forme interrogative ou impérative incorrecte.
+    <<- not analyse(\1, ":V|>chez/", False) -1>> =suggSimil(\1, ":2p", False)                       # Forme interrogative ou impérative incorrecte.
 
 TEST: {{Attaquait}}-vous                                    ->> Attaquiez
 TEST: Elle a de nombreux rendez-vous ce matin.
 TEST: êtes-vous là ?
 
 
 __[i]/inte(inte_ils_elles)__
     ({w1})-(?:ils|elles)  @@0
-    <<- morphex(\1, ":V", ":3p") and spell(\1)
+    <<- analysex(\1, ":V", ":3p") and spell(\1)
     -1>> =suggVerb(@, ":3p")                                                                        # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du pluriel.
-    <<- \1 != "t" and not morph(\1, ":V", False) and spell(\1)
+    <<- \1 != "t" and not analyse(\1, ":V", False) and spell(\1)
     -1>> =suggSimil(\1, ":3p", False)                                                               # Forme interrogative : « \1 » n’est pas un verbe à la 3ᵉ personne du pluriel.
 
 TEST: {{attaquant}}-ils                                     ->> attaquent
 TEST: {{prendrons}}-elles un verre avec moi ?
 
 
 
-!!!! Verbe auxiliaire                                                                               
+!!!! Verbe auxiliaire                                                                             !!
 
 __[i]/conf(conf_avoir_sujet_participe_passé)__
     ({avoir})-(?:je|tu|ils?|elles?|on) +({ppas})  @@0,$
-    <<- morph(\1, ">avoir ", False) and morph(\2, ":V.......e_.*:Q", False) -1>> _  # Incohérence. La forme verbale “\2” ne peut pas être utilisé avec l’auxiliaire “avoir”, seulement avec l’auxiliaire “être”.
+    <<- analyse(\1, ">avoir/", False) and analyse(\2, ":V.......e_.*:Q", False) -1>> _  # Incohérence. La forme verbale “\2” ne peut pas être utilisé avec l’auxiliaire “avoir”, seulement avec l’auxiliaire “être”.
 __[i]/conf(conf_sujet_avoir_participe_passé)__
     (?:j’|je |tu |ils? |elles? |on ) *({avoir}) +({ppas})  @@*,$
-    <<- morph(\1, ">avoir ", False) and morph(\2, ":V.......e_.*:Q", False) -1>> _  # Incohérence. La forme verbale “\2” ne peut pas être utilisé avec l’auxiliaire “avoir”, seulement avec l’auxiliaire “être”.
+    <<- morph(\1, ">avoir/", False) and morph(\2, ":V.......e_.*:Q", False) -1>> _  # Incohérence. La forme verbale “\2” ne peut pas être utilisé avec l’auxiliaire “avoir”, seulement avec l’auxiliaire “être”.
 
 TEST: {{Ait}}-il arrivé à ses fins ?
 TEST: je n’{{avais}} pas parti avec eux.
 TEST: Avais-je partie liée avec lui ?
 TEST: il {{avait}} parti.
 
 
+
+
+
+@@@@
+@@@@
+@@@@
+@@@@
+@@@@GRAPH: last_graph
+@@@@
+@@@@
+@@@@
+@@@@
+
 
 !!
 !!
-!!!! Modes verbaux                                                                                  
+!!!! Modes verbaux                                                                                !!
 !!
 !!
 
 # conditionnel / futur
 
-__[i]/vmode(vmode_j_aimerais_vinfi)__
-    j(?:e +|’)(aimerai|préf[éè]rerai|apprécierai|voudrai|souhaiterai|désirerai|adorerai) +({w_1})  @@w,$
-    <<- morphex(\2, ":[YX]|>(?:y|ne|que?) ", ":R") and isStart() -1>> \1s                           # Si vous exprimez un souhait, utilisez le conditionnel et non le futur.
+__vmode_j_aimerais_vinfi__
+    [<start>|,]  [je|j’]  [aimerai|préférerai|préfèrerai|apprécierai|voudrai|souhaiterai|désirerai|adorerai]  @:[YX]|>(?:y|ne|que?)/¬:R
+        <<- /vmode/ -3>> \1s                                                                        # Si vous exprimez un souhait, utilisez le conditionnel et non le futur.
 
 TEST: J’{{aimerai}} savoir ce dont il retourne.
 TEST: dans tous les cas j’{{aimerai}} ne rien savoir
 TEST: Je {{voudrai}} qu’il soit déjà là.
 TEST: J’aimerai ces cours-là autant que les autres.
 TEST: J’aimerai la danse et la musique, puisque vous l’exigez.
 TEST: Je sais que j’aimerai ça, tout comme lui.
 
 
-__[i]/vmode(vmode_j_aurais_aimé_que_avoir_être)__
-    j’(aurai) +(?:aimé|souhaité|préféré|voulu|apprécié|désiré|adoré) +(que?|ne|{infi})  @@2,$
-    <<- morph(\2, ":Y|>(?:ne|que?) ", False)
-    -1>> aurais|eusse                               # Pour un souhait passé, utilisez le conditionnel passé et non le futur antérieur. Exemple pour le futur antérieur : « quand j’aurai fini… »
+__vmode_j_aurais_aimé_que_vinfi__
+    j’  aurai  [aimé|souhaité|préféré|voulu|apprécié|désiré|adoré]  [que|qu’|qu|ne|n’|@:Y]
+        <<- /vmode/ -2>> aurais|eusse                                                               # Pour un souhait passé, utilisez le conditionnel passé et non le futur antérieur. Exemple pour le futur antérieur : « quand j’aurai fini… »
 
 TEST: J’{{aurai}} aimé nous offrir ce magnifique cadeau.
 TEST: j’{{aurai}} voulu être un artiste.
 TEST: j’{{aurai}} préféré ne pas avoir à l’entendre.
 TEST: j’{{aurai}} préféré l’entendre un autre jour.
@@ -12374,41 +14645,39 @@
 TEST: Quand j’aurai fini ce boulot, je ne sais pas ce que je ferai.
 TEST: Quand j’aurai soif et faim, je m’arrêterai.
 
 
 # Si suivi du conditionnel ou du subjonctif
-__[i]/vmode(vmode_si_sujet1)__
-    si +({w1}) +({w_2})  @@w,$
-    <<- morph(\1, ":(?:Os|M)", False) and morphex(\2, ":[SK]", ":(?:G|V0|I)") and isStart()
-    -2>> _                                                                          # Ce verbe ne devrait être ni au conditionnel, ni au subjonctif.
-__[i]/vmode(vmode_si_sujet2)__
-    (?:si [jt]’|s’ils? +)({w_2})  @@$
-    <<- morphex(\1, ":[SK]", ":(?:G|V0|I)") and isStart()
-    -1>> _                                                                          # Ce verbe ne devrait être ni au conditionnel, ni au subjonctif.
+__vmode_si_sujet__
+    [<start>|,]  si     [j’|J’|t’|T’]  @:[SK]¬:(?:G|V0|I)
+    [<start>|,]  si     @:(?:Os|M)     @:[SK]¬:(?:G|V0|I)
+    [<start>|,]  s’     [il|ils]       @:[SK]¬:(?:G|V0|I)
+        <<- /vmode/ -4>> _                                                                          # Ce verbe ne devrait être ni au conditionnel, ni au subjonctif.
 
 TEST: Si Pierre {{avancerait}} sa voiture de quelques mètres, ça nous permettrait de passer.
 TEST: s’ils ne {{mangeraient}} pas tous les jours, ils seraient moins gros.
+TEST: Si j’{{irais}} le faire
 
 
 # Dès que + indicatif
-__[i]/vmode(vmode_dès_que)__
-    dès +que? +({w_2}) +({w_2})  @@w,$
-    <<- morph(\1, ":(?:Os|M)", False) and morphex(\2, ":S", ":[IG]")    -2>> =suggVerbMode(@, ":I", \1)     # Ce verbe ne devrait pas être au subjonctif.
-#    <<- morph(\1, ":(?:Os|M)", False) and morph(\2, ":K", False)        -2>> =suggVerbMode(@, ":If", \1)    # Ce verbe ne devrait pas être au conditionnel.
+__vmode_dès_que__
+    dès  [que|qu’|qu]  @:(?:Os|M)  @:S¬:[IG]
+        <<- /vmode/ -4>> =suggVerbMode(\4, ":I", \3)                                                     # Ce verbe ne devrait pas être au subjonctif.
+#        <<- morph(\1, ":(?:Os|M)", False) and morph(\2, ":K", False)        -2>> =suggVerbMode(@, ":If", \1)    # Ce verbe ne devrait pas être au conditionnel.
 
 #TEST: dès que je le {{verrais}}
 TEST: dès qu’il le {{voie}}
 TEST: donnant à entendre qu’il avait l’intention de violer Laura dès qu’il en aurait l’occasion
 
 
 # verbe que + subjonctif
-__[i]/vmode(vmode_qqch_que_subjonctif1)__
-    (afin|avant|pour|quoi|(?:perm|fa|v[oe]|ordonn|exig|désir|dout|suff|préf[éè]r)\w+) +que? +({w_2}) +({w_2})  @@0,w,$
-    <<- morph(\1, ">(?:afin|avant|pour|quoi|permettre|falloir|vouloir|ordonner|exiger|désirer|douter|préférer|suffire) ", False)
-        and morph(\2, ":(?:Os|M)", False) and morphex(\3, ":I", ":[GYS]")
-        and not (morph(\1, ">douter ", False) and morph(\3, ":(?:If|K)", False))
-    -3>> =suggVerbMode(@, ":S", \2)                                                 # Après « \1 que », ce verbe devrait être au subjonctif.
+__vmode_qqch_que_subjonctif1__
+    [afin|avant|pour|quoi|>permettre|>falloir|>vouloir|>ordonner|>exiger|>désirer|>préférer|>suffire]  [que|qu’|qu]  @:(?:Os|M)  @:I¬:[GYS]
+        <<- /vmode/ -4>> =suggVerbMode(\4, ":S", \3)                                                # Après « \1 que », ce verbe devrait être au subjonctif.
+
+    >douter  [que|qu’|qu]  @:(?:Os|M)  @:I¬:(?:[GYSK]|If)
+        <<- /vmode/ morph(\1, ":V", ":N") -4>> =suggVerbMode(\4, ":S", \3)                          # Après « \1 que », ce verbe devrait être au subjonctif.
 
 TEST: Il suffit qu’il {{court}} plus
 TEST: Je veux qu’il {{finit}} son repas.
 TEST: quoi qu’il en {{conclut}}
 TEST: Je ne veux pas que tu {{es}} des ennuis
@@ -12417,77 +14686,84 @@
 TEST: Je ne doute pas qu’ils réussiront leur mission.
 TEST: Je me doutais bien qu’Apple pourrait marcher
 TEST: il ne fait aucun doute qu’Amazon le sait.
 TEST: quoi que nous autres hommes ayons pu faire
 
+
+__vmode_qqch_que_subjonctif2__
+    à       condition   [que|qu’|qu]    @:(?:Os|M)      @:I¬:[GYS]
+    pour    peu         [que|qu’|qu]    @:(?:Os|M)      @:I¬:[GYS]
+    il      peut        [que|qu’|qu]    @:(?:Os|M)      @:I¬:[GYS]
+        <<- /vmode/ -5>> =suggVerbMode(\5, ":S", \4)                                                    # Ce verbe devrait être au subjonctif.
+
+TEST: à condition qu’il {{finit}} son boulot.
+TEST: pour peu qu’il {{prend}} son devoir sérieux…
+TEST: il se peut que nous {{avons}} tort.
+
 
 # Bien que + subjonctif
-__[i]/vmode(vmode_bien_que_subjonctif)__
-    bien  ?que? ({w_2}) +({w_2})  @@w,$
-    <<- morph(\1, ":(?:Os|M)", False) and morphex(\2, ":V.*:I", ":(?:[GSK]|If)|>(?:hériter|recevoir|donner|offrir) ") and isStart()
-        and not ( morph(\2, ":V0a", False) and morph(word(1), ">(?:hériter|recevoir|donner|offrir) ", False) )
-        and not before0(r"(?i)\bsi ")
-    -2>> =suggVerbMode(@, ":S", \1)                                                                 # Après « bien que », le verbe s’emploie au subjonctif.
+__vmode_bien_que_subjonctif__
+    [<start>|,]  bien  [que|qu’|qu]  @:(?:Os|M)  @:I¬:(?:[GSK]|If|V0a)|>(?:hériter|recevoir|donner|offrir)/
+        <<- /vmode/ -5>> =suggVerbMode(\5, ":S", \1)                                                # Après « bien que », le verbe s’emploie au subjonctif.
+
+    [<start>|,]  bien  [que|qu’|qu]  @:(?:Os|M)  >avoir  @:[QYG]¬>(?:hériter|recevoir|donner|offrir)/
+        <<- /vmode/ morph(\5, ":I", ":S") -5>> =suggVerbMode(\5, ":S", \1)                          # Après « bien que », le verbe s’emploie au subjonctif.
 
 TEST: Il ne le savait pas, bien qu’il en {{avait}} entendu parler.
 TEST: Bien que je {{prends}} mon mal en patience.
 TEST: C’est un joli bien. Bien qu’il a hérité de son oncle, notez bien.
 TEST: Bien qu’il avait donné à ses enfants.
 TEST: si bien que je me suis toujours demandée si cela ne m’avait pas un peu bousillé les yeux
 
-
 # Malgré que + subjonctif
 # «Malgré que» peut être utilisé délibérément pour un parler populaire qui ignore le subjonctif.
 # --> pas de règle de contrôle sur ce point.
 
-__[i]/vmode(vmode_qqch_que_subjonctif2)__
-    (?:à condition|pour peu|il +peut) +que? +({w1}) +({w_2})  @@w,$
-    <<- morph(\1, ":(?:Os|M)", False) and morphex(\2, ":", ":[GYS]") -2>> =suggVerbMode(@, ":S", \1)    # Ce verbe devrait être au subjonctif.
-
-TEST: à condition qu’il {{finit}} son boulot.
-TEST: pour peu qu’il {{prend}} son devoir sérieux… 
-TEST: il se peut que nous {{avons}} tort.
-
 
 # indicatif nécessaire
-__[i]/vmode(vmode_sujet_indicatif)__
-    ^ *(je|j’(?:en|y)|tu|ils?|elles?|on|nous|vous) +({w_2})  @@*,$
-    <<- morphex(\2, ":S", ":[GIK]") and not re.search("^e(?:usse|û[mt]es|ût)", \2) 
-    -2>> =suggVerbMode(@, ":I", \1)                                                                 # Ce verbe ne devrait pas être au subjonctif.
-__[i]/vmode(vmode_j_indicatif)__
-    ^ *j’({w_2})  @@$
-    <<- morphex(\1, ":S", ":[GIK]") and \1 != "eusse" -1>> =suggVerbMode(@, ":I", "je")             # Ce verbe ne devrait pas être au subjonctif.
+__vmode_sujet_indicatif__
+    <start>  [je|tu|il|ils|elle|elles|on|nous|vous]  @:S¬:[GIK]|V0a.*:Sq
+        <<- /vmode/ -3>> =suggVerbMode(\3, ":I", \2)                                                # Ce verbe ne devrait pas être au subjonctif.
+
+    <start>  j’  @:S¬:[GIK]|V0a.*:Sq:1s
+        <<- /vmode/ -3>> =suggVerbMode(\3, ":I", "je")                                              # Ce verbe ne devrait pas être au subjonctif.
+
+    <start>  j’  [en|y]  @:S¬:[GIK]|V0a.*:Sq
+        <<- /vmode/ -4>> =suggVerbMode(\4, ":I", "je")                                              # Ce verbe ne devrait pas être au subjonctif.
 
 TEST: Il {{ait}} parti.
 TEST: Il en {{conclue}} qu’il a eu raison.
 TEST: j’en {{aie}} marre
 TEST: j’{{aie}} faim
 
 
 # Après que + indicatif
-__[i]/vmode(vmode_après_que_indicatif)__
-    après que? ({w_2}) +({w_2})  @@w,$
-    <<- morph(\1, ":(?:Os|M)", False) and (morphex(\2, ":V.*:S", ":[GI]") or morph(\2, ":V0e.*:S", False))
-    -2>> =suggVerbMode(@, ":I", \1)
-    # Après « après que », le verbe ne s’emploie pas au subjonctif mais à l’indicatif, si l’action s’est déroulée de façon certaine.
+__vmode_après_que_indicatif__
+    après  [que|qu’|qu]  @:(?:Os|M)  @:V.*:S¬:[GI]
+    après  [que|qu’|qu]  @:(?:Os|M)  @:V0e.*:S
+        <<- /vmode/ -4>> =suggVerbMode(\4, ":I", \3)                    # Après « après que », le verbe ne s’emploie pas au subjonctif mais à l’indicatif, si l’action s’est déroulée de façon certaine.
 
 TEST: Après qu’il {{ait}} allé
 TEST: Après que Paul {{ait}} mangé son repas.
 TEST: Après qu’il {{soit}} parti, il plut.
 
 
 # Quand/lorsque + indicatif
-__[i]/vmode(vmode_quand_lorsque_indicatif)__
-    (?:quand|lorsque?) ({w_2}) +({w_2})  @@w,$
-    <<- morph(\1, ":(?:Os|M)", False) and (morphex(\2, ":V.*:S", ":[GI]") or morph(\2, ":V0e.*:S", False))
-    -2>> =suggVerbMode(@, ":I", \1)
-    # Après « quand » ou « lorsque », le verbe ne s’emploie pas au subjonctif mais à l’indicatif.
+__vmode_quand_lorsque_indicatif__
+    [quand|lorsque|lorsqu’|lorsqu]  @:(?:Os|M)  @:V.*:S¬:[GI]
+    [quand|lorsque|lorsqu’|lorsqu]  @:(?:Os|M)  @:V0e.*:S
+        <<- /vmode/ -3>> =suggVerbMode(\3, ":I", \2)                                                # Après « quand » ou « lorsque », le verbe ne s’emploie pas au subjonctif mais à l’indicatif.
 
 TEST: quand elle {{rencontrât}} son créateur
 TEST: lorsqu’il y {{eût}} du grabuge, nous montâmes tous sur le pont.
 
 
+@@@@
+@@@@END_GRAPH
+@@@@
+
+
 
 !!
 !!
 !!
 !!
@@ -12505,11 +14781,11 @@
 !!
 !!
 !!
 !!
 !!
-!! TESTS: Faux positifs potentiels                                                                  
+!! TESTS: Faux positifs potentiels                                                                !!
 !!
 !!
 !!
 !!
 !!
@@ -12528,11 +14804,11 @@
 !!
 !!
 !!
 !!
 
-!!! À trier                                                                                         
+!!! À trier                                                                                       !!
 TEST: L’homme sur le bateau de Patrick {{viens}} de temps en temps {{mangé}} chez moi.
 TEST: Ces marchands {{passe}} leur temps à se quereller.
 TEST: Ils jugeront en toute impartialité de ce cas {{délirante}}.
 TEST: Ils sont de manière si étonnante et si admirable {{arrivé}} à ce résultat…
 TEST: Les tests grand public de Jean-Paul {{montre}} des résultats surprenants.
@@ -12567,15 +14843,15 @@
 TODO: André Juin était un sculpteur français.
 TODO: La bataille de Monte Cassino révèle le génie militaire du général Juin.
 TODO: Les côtes sont dans leur ensemble extrêmement découpées.
 
 
-!!! Indécidable                                                                                     
+!!! Indécidable                                                                                   !!
 TEST: Du sable fin grippe les rouages (accord avec ce qui précède).
 TEST: Du monde noir sortent les envahisseurs (accord avec ce qui suit).
 
-!!! Autres tests                                                                                    
+!!! Autres tests                                                                                  !!
 TEST: Ça a l’air de t’aller.
 TEST: Et je m’en sors.
 TEST: C’est à chacun d’entre nous de suivre le modèle d’Amos.
 TEST: C’est toi qui voulais y aller.
 TEST: je ne suis qu’une joueuse en robe de soirée.
@@ -12636,11 +14912,11 @@
 TEST: Ce qu’ils nous ont fait
 TEST: Comment vous expliquez ça ?
 TEST: Comment vous expliquer ça ?
 
 
-!!! Tests historiques                                                                               
+!!! Tests historiques                                                                             !!
 
 ## Version 0.5.14
 TEST: par le léger tissu de rayonne qui les protégeait en ce moment.
 
 ## Version 0.5.11
@@ -13412,11 +15688,11 @@
 TEST: À qui mieux mieux, à qui mieux mieux
 TEST: L’est est loin, la gare de l’est aussi.
 
 
 
-!!! Tests repris de LanguageTool                                                                    
+!!! Tests repris de LanguageTool                                                                  !!
 ## NOTE : ces textes contiennent parfois des erreurs (corrigées quand repérées par le correcteur)
 
 TEST: Au voisinage du zéro absolu de température.
 TEST: La couronne périphérique alterne falaises abruptes et plages.
 TEST: Henri VIII rencontre François Iᵉʳ.
@@ -15477,11 +17753,11 @@
 TEST: Le 29 février 2016.
 TEST: Le 29 février 2020.
 TEST: Le 29-février-2004
 
 
-!!! Le Horla, de Guy de Maupassant                                                                  
+!!! Le Horla, de Guy de Maupassant                                                                !!
 # Nouvelle intégrale (228 lignes)
 # Certains points diffèrent du texte original tiré de Wikisource :
 # — les paragraphes sont souvent scindés pour des raisons pratiques.
 # — les virgules avant les points de suspension ont été supprimées
 # — moyen âge -> Moyen Âge
@@ -15849,11 +18125,11 @@
 TEST: Après l’homme le Horla. — Après celui qui peut mourir tous les jours, à toutes les heures, à toutes les minutes, par tous les accidents, est venu celui qui ne doit mourir qu’à son jour, à son heure, à sa minute, parce qu’il a touché la limite de son existence !
 TEST: Non… non… sans aucun doute, sans aucun doute… il n’est pas mort… Alors… alors… il va donc falloir que je me tue, moi !…
 # FIN DU HORLA
 
 
-!!! Double assassinat dans la rue morgue, d’Edgar Poe                                               
+!!! Double assassinat dans la rue morgue, d’Edgar Poe                                             !!
 # Texte tiré de Wikisource
 # Les paragraphes ont été découpés pour réduire la longueur des tests.
 TEST: DOUBLE ASSASSINAT DANS LA RUE MORGUE — Edgar Poe
 TEST: Quelle chanson chantaient les sirènes ? quel nom Achille avait-il pris, quand il se cachait parmi les femmes ? – Questions embarrassantes, il est vrai, mais qui ne sont pas situées au-delà de toute conjecture.
 TEST: Sir Thomas Browne.
@@ -16393,11 +18669,11 @@
 TEST: Mais, après tout, c’est un brave homme. Je l’adore particulièrement pour un merveilleux genre de cant auquel il doit sa réputation de génie.
 TEST: Je veux parler de sa manie de nier ce qui est, et d’expliquer ce qui n’est pas[2].
 # FIN DU DOUBLE ASSASSINAT DANS LA RUE MORGUE
 
 
-!!! Vers Dorés, de Pythagore                                                                        
+!!! Vers Dorés, de Pythagore                                                                      !!
 # Origine?
 TEST: Aux dieux, suivant les lois, rends de justes hommages ;
 TEST: Respecte le serment, les héros et les sages ;
 TEST: Honore tes parents, tes rois, tes bienfaiteurs ;
 TEST: Choisi parmi tes amis les hommes les meilleurs.
@@ -16493,11 +18769,11 @@
 TEST: Fin des vers dorés de Pythagore
 TEST: Note : Chez les Pythagoriciens, la monade ou l’unité représente Dieu-même, parce qu’elle n’est engendrée par aucun nombre, qu’elle les engendre tous, qu’elle est simple et sans aucune composition. La dyade, ou le nombre deux, est l’image de la nature créée, parce qu’elle est le premier produit de l’unité, parce qu’elle est inspirée, parce qu’ayant des parties elle peut se décomposer et se défendre. La monade et la dyade réunies forment le ternaire, et représentent l’immensité de tout ce qui existe, l’être immuable et la matière altérable et changeante. J’ignore par quelle propriété le quaternaire, le nombre quatre, est encore un emblème de la divinité.
 # FIN DES VERS DORÉS DE PYTHAGORE
 
 
-!!! Épître du feu philosophique, de Jean Pontanus                                                   
+!!! Épître du feu philosophique, de Jean Pontanus                                                 !!
 # Les paragraphes ont été découpés et ne correspondent pas à ceux du texte.
 TEST: Épître du Feu Philosophique
 TEST: Lettre concernant la pierre dite philosophale
 TEST: Jean Pontanus
 TEST: in Theatrum Chimicum, 1614, t. III
@@ -16539,11 +18815,11 @@
 TEST: Si tu penses bien profondément aux propriétés du feu ci-dessus, tu la connaîtras, mais non autrement.
 TEST: Donc, touché d’un mouvement de pitié, j’ai écrit ceci ; mais, et afin que je me satisfasse, le feu n’est point transmué avec la matière, comme je l’ai dit ci-dessus.
 TEST: J’ai bien voulu le dire et en avertir les prudents de ces choses, pour qu’ils ne dépensent pas inutilement leur argent, mais qu’ils sachent auparavant ce qu’ils doivent chercher, et, par ce moyen, parviendront à la vérité de l’Art ; non pas autrement. À Dieu.
 # FIN DE L’ÉPÎTRE DU FEU PHILOSOPHIQUE
 
-!!! Le Misanthrope, de Molière                                                                      
+!!! Le Misanthrope, de Molière                                                                    !!
 TEST: LE MISANTHROPE (1666)
 TEST: de Molière
 TEST: Texte établi par Charles Louandre, Charpentier, 1910 (2, pp. 170-239).
 TEST: PERSONNAGES
 TEST: Alceste, amant de Célimène,
@@ -16555,13 +18831,11 @@
 TEST: Acaste,
 TEST: Clitandre, marquis
 TEST: Basque, valet de Célimène,
 TEST: Un garde de la maréchaussée de France,
 TEST: Dubois, valet d’Alceste.
-
 TEST: La scène se passe à Paris, dans la maison de Célimène.
-
 TEST: ACTE I
 TEST: SCÈNE PREMIÈRE. Philinte, Alceste.
 TEST: PHILINTE. Qu’est-ce donc ? Qu’avez-vous ?
 TEST: ALCESTE, assis. Laissez-moi, je vous prie.
 TEST: PHILINTE. Mais encor, dites-moi, quelle bizarrerie…

Index: gc_lang/fr/webext/content_scripts/panel_lxg.css
==================================================================
--- gc_lang/fr/webext/content_scripts/panel_lxg.css
+++ gc_lang/fr/webext/content_scripts/panel_lxg.css
@@ -88,11 +88,11 @@
     background-color: hsla(150, 50%, 30%, 1);
 }
 div.grammalecte_lxg_token_WORD {
     background-color: hsla(150, 50%, 50%, 1);
 }
-div.grammalecte_lxg_token_ELPFX {
+div.grammalecte_lxg_token_WORD_ELIDED {
     background-color: hsla(150, 30%, 50%, 1);
 }
 div.grammalecte_lxg_token_UNKNOWN {
     background-color: hsla(0, 50%, 50%, 1);
 }

Index: gc_lang/fr/webext/manifest.json
==================================================================
--- gc_lang/fr/webext/manifest.json
+++ gc_lang/fr/webext/manifest.json
@@ -1,10 +1,10 @@
 {
   "manifest_version": 2,
   "name": "Grammalecte [fr]",
   "short_name": "Grammalecte [fr]",
-  "version": "0.6.4.2",
+  "version": "0.7",
 
   "applications": {
     "gecko": {
       "id": "French-GC@grammalecte.net",
       "strict_min_version": "56.0"

Index: gc_lang/fr/xpi/data/lxg_panel.css
==================================================================
--- gc_lang/fr/xpi/data/lxg_panel.css
+++ gc_lang/fr/xpi/data/lxg_panel.css
@@ -56,11 +56,11 @@
     text-decoration: none;
 }
 #wordlist b.WORD {
     background-color: hsla(150, 50%, 50%, 1);
 }
-#wordlist b.ELPFX {
+#wordlist b.WORD_ELIDED {
     background-color: hsla(150, 30%, 50%, 1);
 }
 #wordlist b.UNKNOWN {
     background-color: hsla(0, 50%, 50%, 1);
 }

Index: grammalecte-cli.py
==================================================================
--- grammalecte-cli.py
+++ grammalecte-cli.py
@@ -1,6 +1,10 @@
 #!/usr/bin/env python3
+
+"""
+Grammalecte CLI (command line interface)
+"""
 
 import sys
 import os.path
 import argparse
 import json
@@ -71,10 +75,11 @@
             sText, lLineSet = txt.createParagraphWithLines(lLine)
             yield iParagraph, sText, lLineSet
 
 
 def output (sText, hDst=None):
+    "write in the console or in a file if <hDst> not null"
     if not hDst:
         echo(sText, end="")
     else:
         hDst.write(sText)
 
@@ -92,10 +97,11 @@
         print("# Error: file <" + spf + "> not found.")
         return None
 
 
 def main ():
+    "launch the CLI (command line interface)"
     xParser = argparse.ArgumentParser()
     xParser.add_argument("-f", "--file", help="parse file (UTF-8 required!) [on Windows, -f is similar to -ff]", type=str)
     xParser.add_argument("-ff", "--file_to_file", help="parse file (UTF-8 required!) and create a result file (*.res.txt)", type=str)
     xParser.add_argument("-owe", "--only_when_errors", help="display results only when there are errors", action="store_true")
     xParser.add_argument("-j", "--json", help="generate list of errors in JSON (only with option --file or --file_to_file)", action="store_true")
@@ -232,14 +238,14 @@
             elif sText.startswith("/++ "):
                 for sRule in sText[3:].strip().split():
                     oGrammarChecker.gce.reactivateRule(sRule)
                 echo("done")
             elif sText == "/debug" or sText == "/d":
-                xArgs.debug = not(xArgs.debug)
+                xArgs.debug = not xArgs.debug
                 echo("debug mode on"  if xArgs.debug  else "debug mode off")
             elif sText == "/textformatter" or sText == "/tf":
-                xArgs.textformatter = not(xArgs.textformatter)
+                xArgs.textformatter = not xArgs.textformatter
                 echo("textformatter on"  if xArgs.debug  else "textformatter off")
             elif sText == "/help" or sText == "/h":
                 echo(_HELP)
             elif sText == "/lopt" or sText == "/lo":
                 oGrammarChecker.gce.displayOptions("fr")
@@ -253,16 +259,16 @@
                 # reload (todo)
                 pass
             else:
                 for sParagraph in txt.getParagraph(sText):
                     if xArgs.textformatter:
-                        sText = oTextFormatter.formatText(sText)
-                    sRes = oGrammarChecker.generateParagraph(sText, bEmptyIfNoErrors=xArgs.only_when_errors, nWidth=xArgs.width, bDebug=xArgs.debug)
+                        sText = oTextFormatter.formatText(sParagraph)
+                    sRes = oGrammarChecker.generateParagraph(sParagraph, bEmptyIfNoErrors=xArgs.only_when_errors, nWidth=xArgs.width, bDebug=xArgs.debug)
                     if sRes:
                         echo("\n" + sRes)
                     else:
                         echo("\nNo error found.")
             sText = _getText(sInputText)
 
 
 if __name__ == '__main__':
     main()

Index: grammalecte-server.py
==================================================================
--- grammalecte-server.py
+++ grammalecte-server.py
@@ -1,10 +1,11 @@
  #!/usr/bin/env python3
 
-import sys
-import os.path
-import argparse
+"""
+GRAMMALECTE SERVER
+"""
+
 import json
 import traceback
 import configparser
 import time
 
@@ -19,11 +20,11 @@
 <!DOCTYPE HTML>
 <html>
     <head>
         <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
     </head>
-    
+
     <body class="panel">
         <h1>Grammalecte · Serveur</h1>
 
         <h2>INFORMATIONS</h1>
 
@@ -49,11 +50,11 @@
 
         <h3>Remise à zéro de ses options</h3>
         <p>[adresse_serveur]:8080/reset_options/fr (POST)</p>
 
         <h2>TEST</h2>
-        
+
         <h3>Analyse</h3>
         <form method="post" action="/gc_text/fr" accept-charset="UTF-8">
             <p>Texte à analyser :</p>
             <textarea name="text" cols="120" rows="20" required></textarea>
             <p><label for="tf">Formateur de texte</label> <input id="tf" name="tf" type="checkbox"></p>
@@ -91,10 +92,11 @@
 I'm doomed, but you are not. You can get out of here.
 """
 
 
 def getServerOptions ():
+    "load server options in <grammalecte-server-options._global.ini>, returns server options as dictionary"
     xConfig = configparser.SafeConfigParser()
     try:
         xConfig.read("grammalecte-server-options._global.ini")
         dOpt = xConfig._sections['options']
     except:
@@ -101,11 +103,12 @@
         echo("Options file [grammalecte-server-options._global.ini] not found or not readable")
         exit()
     return dOpt
 
 
-def getConfigOptions (sLang):
+def getLangConfigOptions (sLang):
+    "load options for language <sLang>, returns grammar checker options as dictionary"
     xConfig = configparser.SafeConfigParser()
     try:
         xConfig.read("grammalecte-server-options." + sLang + ".ini")
     except:
         echo("Options file [grammalecte-server-options." + sLang + ".ini] not found or not readable")
@@ -118,10 +121,11 @@
         exit()
     return dGCOpt
 
 
 def genUserId ():
+    "generator: create a user id"
     i = 0
     while True:
         yield str(i)
         i += 1
 
@@ -135,11 +139,11 @@
     oTextFormatter = oGrammarChecker.getTextFormatter()
     gce = oGrammarChecker.getGCEngine()
 
     echo("Grammalecte v{}".format(gce.version))
     dServerOptions = getServerOptions()
-    dGCOptions = getConfigOptions("fr")
+    dGCOptions = getLangConfigOptions("fr")
     if dGCOptions:
         gce.setOptions(dGCOptions)
     dServerGCOptions = gce.getOptions()
     echo("Grammar options:\n" + " | ".join([ k + ": " + str(v)  for k, v in sorted(dServerGCOptions.items()) ]))
     dUser = {}
@@ -148,25 +152,28 @@
     app = Bottle()
 
     # GET
     @app.route("/")
     def mainPage ():
+        "show main page"
         if dServerOptions.get("testpage", False) == "True":
             return HOMEPAGE
             #return template("main", {})
         return SADLIFEOFAMACHINE
 
     @app.route("/get_options/fr")
     def listOptions ():
+        "show language options as JSON string"
         sUserId = request.cookies.user_id
         dOptions = dUser[sUserId]["gc_options"]  if sUserId and sUserId in dUser  else dServerGCOptions
         return '{ "values": ' + json.dumps(dOptions) + ', "labels": ' + json.dumps(gce.getOptionsLabels("fr"), ensure_ascii=False) + ' }'
 
 
     # POST
     @app.route("/gc_text/fr", method="POST")
     def gcText ():
+        "parse text sent via POST, show result as a JSON string"
         #if len(lang) != 2 or lang != "fr":
         #    abort(404, "No grammar checker available for lang “" + str(lang) + "”")
         bComma = False
         dOptions = None
         sError = ""
@@ -195,10 +202,11 @@
         sJSON += "\n]}\n"
         return sJSON
 
     @app.route("/set_options/fr", method="POST")
     def setOptions ():
+        "change options for user_id, returns options as a JSON string"
         if request.forms.options:
             sUserId = request.cookies.user_id  if request.cookies.user_id  else next(userGenerator)
             dOptions = dUser[sUserId]["gc_options"]  if sUserId in dUser  else dict(dServerGCOptions)
             try:
                 dOptions.update(json.loads(request.forms.options))
@@ -210,16 +218,18 @@
                 return '{"error": "options not registered"}'
         return '{"error": "no options received"}'
 
     @app.route("/reset_options/fr", method="POST")
     def resetOptions ():
+        "erase options stored for user_id"
         if request.cookies.user_id and request.cookies.user_id in dUser:
             del dUser[request.cookies.user_id]
         return "done"
 
     @app.route("/format_text/fr", method="POST")
     def formatText ():
+        "returns text modified via the text formatter"
         return oTextFormatter.formatText(request.forms.text)
 
     #@app.route('/static/<filepath:path>')
     #def server_static (filepath):
     #    return static_file(filepath, root='./views/static')
@@ -234,19 +244,19 @@
                 nNowMinusNHours = int(time.time()) - (int(request.forms.hours) * 60 * 60)
                 for nUserId, dValue in dUser.items():
                     if dValue["time"] < nNowMinusNHours:
                         del dUser[nUserId]
                 return "done"
-            else:
-                return "no"
+            return "no"
         except:
             traceback.print_exc()
             return "error"
 
     # ERROR
     @app.error(404)
     def error404 (error):
+        "show error when error 404"
         return 'Error 404.<br/>' + str(error)
 
     run(app, \
         host=dServerOptions.get('host', 'localhost'), \
         port=int(dServerOptions.get('port', 8080)))

Index: graphspell-js/ibdawg.js
==================================================================
--- graphspell-js/ibdawg.js
+++ graphspell-js/ibdawg.js
@@ -512,11 +512,11 @@
                     let iAddr2 = this._convBytesToInteger(this.byDic.slice(iEndArcAddr, iEndArcAddr+this.nBytesNodeAddress));
                     let nRawArc2 = 0;
                     while (!(nRawArc2 & this._lastArcMask)) {
                         let iEndArcAddr2 = iAddr2 + this.nBytesArc;
                         nRawArc2 = this._convBytesToInteger(this.byDic.slice(iAddr2, iEndArcAddr2));
-                        l.push(sStem + " " + this.lArcVal[nRawArc2 & this._arcMask]);
+                        l.push(sStem + "/" + this.lArcVal[nRawArc2 & this._arcMask]);
                         iAddr2 = iEndArcAddr2+this.nBytesNodeAddress;
                     }
                 }
                 iAddr = iEndArcAddr + this.nBytesNodeAddress;
             }

Index: graphspell-js/spellchecker.js
==================================================================
--- graphspell-js/spellchecker.js
+++ graphspell-js/spellchecker.js
@@ -41,10 +41,14 @@
         this.oPersonalDic = this._loadDictionary(personalDic, sPath);
         this.bExtendedDic = Boolean(this.oExtendedDic);
         this.bCommunityDic = Boolean(this.oCommunityDic);
         this.bPersonalDic = Boolean(this.oPersonalDic);
         this.oTokenizer = null;
+        // storage
+        this.bStorage = false;
+        this._dMorphologies = new Map();            // key: flexion, value: list of morphologies
+        this._dLemmas = new Map();                  // key: flexion, value: list of lemmas
     }
 
     _loadDictionary (dictionary, sPath="", bNecessary=false) {
         // returns an IBDAWG object
         if (!dictionary) {
@@ -132,10 +136,26 @@
 
     deactivatePersonalDictionary () {
         this.bPersonalDic = false;
     }
 
+
+    // Storage
+
+    activateStorage () {
+        this.bStorage = true;
+    }
+
+    deactivateStorage () {
+        this.bStorage = false;
+    }
+
+    clearStorage () {
+        this._dLemmas.clear();
+        this._dMorphologies.clear();
+    }
+
 
     // parse text functions
 
     parseParagraph (sText) {
         if (!this.oTokenizer) {
@@ -203,21 +223,40 @@
         return false;
     }
 
     getMorph (sWord) {
         // retrieves morphologies list, different casing allowed
-        let lResult = this.oMainDic.getMorph(sWord);
+        if (this.bStorage && this._dMorphologies.has(sWord)) {
+            return this._dMorphologies.get(sWord);
+        }
+        let lMorph = this.oMainDic.getMorph(sWord);
         if (this.bExtendedDic) {
-            lResult.push(...this.oExtendedDic.getMorph(sWord));
+            lMorph.push(...this.oExtendedDic.getMorph(sWord));
         }
         if (this.bCommunityDic) {
-            lResult.push(...this.oCommunityDic.getMorph(sWord));
+            lMorph.push(...this.oCommunityDic.getMorph(sWord));
         }
         if (this.bPersonalDic) {
-            lResult.push(...this.oPersonalDic.getMorph(sWord));
+            lMorph.push(...this.oPersonalDic.getMorph(sWord));
+        }
+        if (this.bStorage) {
+            this._dMorphologies.set(sWord, lMorph);
+            this._dLemmas.set(sWord, Array.from(new Set(this.getMorph(sWord).map((sMorph) => { return sMorph.slice(1, sMorph.indexOf("/")); }))));
+            //console.log(sWord, this._dLemmas.get(sWord));
+        }
+        return lMorph;
+    }
+
+    getLemma (sWord) {
+        // retrieves lemmas
+        if (this.bStorage) {
+            if (!this._dLemmas.has(sWord)) {
+                this.getMorph(sWord);
+            }
+            return this._dLemmas.get(sWord);
         }
-        return lResult;
+        return Array.from(new Set(this.getMorph(sWord).map((sMorph) => { return sMorph.slice(1, sMorph.indexOf("/")); })));
     }
 
     * suggest (sWord, nSuggLimit=10) {
         // generator: returns 1, 2 or 3 lists of suggestions
         yield this.oMainDic.suggest(sWord, nSuggLimit);

Index: graphspell-js/tokenizer.js
==================================================================
--- graphspell-js/tokenizer.js
+++ graphspell-js/tokenizer.js
@@ -16,37 +16,39 @@
     "default":
         [
             [/^[   \t]+/, 'SPACE'],
             [/^\/(?:~|bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:\/[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_.()-]+)*/, 'FOLDERUNIX'],
             [/^[a-zA-Z]:\\(?:Program Files(?: \(x86\)|)|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st.()]+)(?:\\[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_.()-]+)*/, 'FOLDERWIN'],
-            [/^[,.;:!?…«»“”‘’"(){}\[\]/·–—]+/, 'SEPARATOR'],
-            [/^[A-Z][.][A-Z][.](?:[A-Z][.])*/, 'ACRONYM'],
+            [/^[,.;:!?…«»“”‘’"(){}\[\]·–—]/, 'SEPARATOR'],
+            [/^[A-Z][.][A-Z][.](?:[A-Z][.])*/, 'WORD_ACRONYM'],
             [/^(?:https?:\/\/|www[.]|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_-]+[@.][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_-]{2,}[@.])[a-zA-Z0-9][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_.\/?&!%=+*"'@$#-]+/, 'LINK'],
             [/^[#@][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_-]+/, 'TAG'],
             [/^<[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+.*?>|<\/[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+ *>/, 'HTML'],
             [/^\[\/?[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+\]/, 'PSEUDOHTML'],
             [/^&\w+;(?:\w+;|)/, 'HTMLENTITY'],
             [/^\d\d?h\d\d\b/, 'HOUR'],
             [/^-?\d+(?:[.,]\d+|)/, 'NUM'],
+            [/^[%‰+=*/<>⩾⩽-]/, 'SIGN'],
             [/^[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+(?:[’'`-][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+)*/, 'WORD']
         ],
     "fr":
         [
             [/^[   \t]+/, 'SPACE'],
             [/^\/(?:~|bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:\/[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_.()-]+)*/, 'FOLDERUNIX'],
             [/^[a-zA-Z]:\\(?:Program Files(?: \(x86\)|)|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st.()]+)(?:\\[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_.()-]+)*/, 'FOLDERWIN'],
-            [/^[,.;:!?…«»“”‘’"(){}\[\]/·–—]+/, 'SEPARATOR'],
-            [/^[A-Z][.][A-Z][.](?:[A-Z][.])*/, 'ACRONYM'],
+            [/^[,.;:!?…«»“”‘’"(){}\[\]·–—]/, 'SEPARATOR'],
+            [/^[A-Z][.][A-Z][.](?:[A-Z][.])*/, 'WORD_ACRONYM'],
             [/^(?:https?:\/\/|www[.]|[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_-]+[@.][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_-]{2,}[@.])[a-zA-Z0-9][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_.\/?&!%=+*"'@$#-]+/, 'LINK'],
             [/^[#@][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st_-]+/, 'TAG'],
             [/^<[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+.*?>|<\/[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+ *>/, 'HTML'],
             [/^\[\/?[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+\]/, 'PSEUDOHTML'],
             [/^&\w+;(?:\w+;|)/, 'HTMLENTITY'],
-            [/^(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu)['’`]/i, 'ELPFX'],
+            [/^(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu)['’`]/i, 'WORD_ELIDED'],
             [/^\d\d?[hm]\d\d\b/, 'HOUR'],
-            [/^\d+(?:er|nd|e|de|ième|ème|eme)s?\b/, 'ORDINAL'],
+            [/^\d+(?:ers?|nds?|es?|des?|ièmes?|èmes?|emes?|ᵉʳˢ?|ⁿᵈˢ?|ᵉˢ?|ᵈᵉˢ?)\b/, 'WORD_ORDINAL'],
             [/^-?\d+(?:[.,]\d+|)/, 'NUM'],
+            [/^[%‰+=*/<>⩾⩽-]/, 'SIGN'],
             [/^[a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+(?:[’'`-][a-zA-Zà-öÀ-Ö0-9ø-ÿØ-ßĀ-ʯfi-st]+)*/, 'WORD']
         ]
 };
 
 
@@ -60,36 +62,32 @@
         this.aRules = aTkzPatterns[this.sLang];
     }
 
     * genTokens (sText) {
         let m;
-        let i = 0;
+        let iNext = 0;
         while (sText) {
-            let nCut = 1;
+            let iCut = 1;
+            let iToken = 0;
             for (let [zRegex, sType] of this.aRules) {
                 try {
                     if ((m = zRegex.exec(sText)) !== null) {
-                        if (sType == 'SEPARATOR') {
-                            for (let c of m[0]) {
-                                yield { "sType": sType, "sValue": c, "nStart": i, "nEnd": i + m[0].length }
-                            }
-                        } else {
-                            yield { "sType": sType, "sValue": m[0], "nStart": i, "nEnd": i + m[0].length }
-                        }
-                        nCut = m[0].length;
+                        iToken += 1;
+                        yield { "i": iToken, "sType": sType, "sValue": m[0], "nStart": iNext, "nEnd": iNext + m[0].length }
+                        iCut = m[0].length;
                         break;
                     }
                 }
                 catch (e) {
                     helpers.logerror(e);
                 }
             }
-            i += nCut;
-            sText = sText.slice(nCut);
+            iNext += iCut;
+            sText = sText.slice(iCut);
         }
     }
 }
 
 
 if (typeof(exports) !== 'undefined') {
     exports.Tokenizer = Tokenizer;
 }

Index: graphspell/__init__.py
==================================================================
--- graphspell/__init__.py
+++ graphspell/__init__.py
@@ -1,2 +1,11 @@
+
+"""
+SPELLCHECKER
+using a Direct Acyclic Word Graph
+with a transducer to retrieve
+- lemma of words
+- morphologies
+with a spell suggestion mechanism
+"""
 
 from .spellchecker import *

Index: graphspell/char_player.py
==================================================================
--- graphspell/char_player.py
+++ graphspell/char_player.py
@@ -1,7 +1,9 @@
-# list of similar chars
-# useful for suggestion mechanism
+"""
+List of similar chars
+useful for suggestion mechanism
+"""
 
 import re
 import unicodedata
 
 
@@ -8,10 +10,11 @@
 _xTransCharsForSpelling = str.maketrans({
     'ſ': 's',  'ffi': 'ffi',  'ffl': 'ffl',  'ff': 'ff',  'ſt': 'ft',  'fi': 'fi',  'fl': 'fl',  'st': 'st'
 })
 
 def spellingNormalization (sWord):
+    "nomalization NFC and removing ligatures"
     return unicodedata.normalize("NFC", sWord.translate(_xTransCharsForSpelling))
 
 
 _xTransCharsForSimplification = str.maketrans({
     'à': 'a',  'é': 'e',  'î': 'i',  'ô': 'o',  'û': 'u',  'ÿ': 'i',  "y": "i",
@@ -19,11 +22,11 @@
     'ä': 'a',  'ê': 'e',  'í': 'i',  'ó': 'o',  'ü': 'u',  'ý': 'i',
     'á': 'a',  'ë': 'e',  'ì': 'i',  'ò': 'o',  'ú': 'u',  'ỳ': 'i',
     'ā': 'a',  'ē': 'e',  'ī': 'i',  'ō': 'o',  'ū': 'u',  'ȳ': 'i',
     'ç': 'c',  'ñ': 'n',  'k': 'q',  'w': 'v',
     'œ': 'oe',  'æ': 'ae',
-    'ſ': 's',  'ffi': 'ffi',  'ffl': 'ffl',  'ff': 'ff',  'ſt': 'ft',  'fi': 'fi',  'fl': 'fl',  'st': 'st', 
+    'ſ': 's',  'ffi': 'ffi',  'ffl': 'ffl',  'ff': 'ff',  'ſt': 'ft',  'fi': 'fi',  'fl': 'fl',  'st': 'st',
 })
 
 def simplifyWord (sWord):
     "word simplication before calculating distance between words"
     sWord = sWord.lower().translate(_xTransCharsForSimplification)
@@ -92,11 +95,11 @@
     "f": "fF",
     "F": "Ff",
 
     "g": "gGjJĵĴ",
     "G": "GgJjĴĵ",
-    
+
     "h": "hH",
     "H": "Hh",
 
     "i": "iIîÎïÏyYíÍìÌīĪÿŸ",
     "I": "IiÎîÏïYyÍíÌìĪīŸÿ",
@@ -237,10 +240,11 @@
     "Z": ("SS", "ZH"),
 }
 
 
 def get1toXReplacement (cPrev, cCur, cNext):
+    "return tuple of replacements for <cCur>"
     if cCur in aConsonant  and  (cPrev in aConsonant  or  cNext in aConsonant):
         return ()
     return d1toX.get(cCur, ())
 
 

Index: graphspell/dawg.py
==================================================================
--- graphspell/dawg.py
+++ graphspell/dawg.py
@@ -1,15 +1,16 @@
 #!python3
 
-# FSA DICTIONARY BUILDER
-#
-# by Olivier R.
-# License: MPL 2
-#
-# This tool encodes lexicon into an indexable binary dictionary 
-# Input files MUST be encoded in UTF-8.
-
+"""
+FSA DICTIONARY BUILDER
+
+by Olivier R.
+License: MPL 2
+
+This tool encodes lexicon into an indexable binary dictionary
+Input files MUST be encoded in UTF-8.
+"""
 
 import sys
 import os
 import collections
 import json
@@ -21,10 +22,11 @@
 from .progressbar import ProgressBar
 
 
 
 def readFile (spf):
+    "generator: read file <spf> and return for each line a list of elements separated by a tabulation."
     print(" < Read lexicon: " + spf)
     if os.path.isfile(spf):
         with open(spf, "r", encoding="utf-8") as hSrc:
             for sLine in hSrc:
                 sLine = sLine.strip()
@@ -97,23 +99,23 @@
                     nTag += 1
                 dTagOccur[sTag] = dTagOccur.get(sTag, 0) + 1
                 aEntry.add((sFlex, dAff[sAff], dTag[sTag]))
         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
         dValOccur = dict( [ (dChar[c], dCharOccur[c])  for c in dChar ] \
                         + [ (dAff[aff]+nChar, dAffOccur[aff]) for aff in dAff ] \
                         + [ (dTag[tag]+nChar+nAff, dTagOccur[tag]) for tag in dTag ] )
-        
+
         self.sFileName = src  if type(src) is str  else "[None]"
         self.sLangCode = sLangCode
         self.sLangName = sLangName
         self.sDicName = sDicName
         self.nEntry = len(lWord)
@@ -132,15 +134,15 @@
         self.nArcVal = len(lVal)
         self.nTag = self.nArcVal - self.nChar - nAff
         self.cStemming = cStemming
         if cStemming == "A":
             self.funcStemming = st.changeWordWithAffixCode
-        elif cStemming == "S":    
+        elif cStemming == "S":
             self.funcStemming = st.changeWordWithSuffixCode
         else:
             self.funcStemming = st.noStemming
-        
+
         # build
         lWord.sort()
         oProgBar = ProgressBar(0, len(lWord))
         for aEntry in lWord:
             self.insert(aEntry)
@@ -147,20 +149,21 @@
             oProgBar.increment(1)
         oProgBar.done()
         self.finish()
         self.countNodes()
         self.countArcs()
-        self.sortNodes()         # version 2 and 3 
+        self.sortNodes()         # version 2 and 3
         self.sortNodeArcs(dValOccur)
         #self.sortNodeArcs2 (self.oRoot, "")
         self.displayInfo()
 
     # BUILD DAWG
     def insert (self, aEntry):
+        "insert a new entry (insertion must be made in alphabetical order)."
         if aEntry < self.aPreviousEntry:
             sys.exit("# Error: Words must be inserted in alphabetical order.")
-        
+
         # find common prefix between word and previous word
         nCommonPrefix = 0
         for i in range(min(len(aEntry), len(self.aPreviousEntry))):
             if aEntry[i] != self.aPreviousEntry[i]:
                 break
@@ -179,11 +182,11 @@
         iChar = nCommonPrefix
         for c in aEntry[nCommonPrefix:]:
             oNextNode = DawgNode()
             oNode.arcs[c] = oNextNode
             self.lUncheckedNodes.append((oNode, c, oNextNode))
-            if iChar == (len(aEntry) - 2): 
+            if iChar == (len(aEntry) - 2):
                 oNode.final = True
             iChar += 1
             oNode = oNextNode
         oNode.final = True
         self.aPreviousEntry = aEntry
@@ -203,54 +206,61 @@
                 # add the state to the minimized nodes.
                 self.lMinimizedNodes[oChildNode] = oChildNode
             self.lUncheckedNodes.pop()
 
     def countNodes (self):
+        "count the number of nodes of the whole word graph"
         self.nNode = len(self.lMinimizedNodes)
 
     def countArcs (self):
+        "count the number of arcs in the whole word graph"
         self.nArc = 0
         for oNode in self.lMinimizedNodes:
             self.nArc += len(oNode.arcs)
-    
+
     def sortNodeArcs (self, dValOccur):
+        "sort arcs of each node according to <dValOccur>"
         print(" > Sort node arcs")
         self.oRoot.sortArcs(dValOccur)
         for oNode in self.lMinimizedNodes:
             oNode.sortArcs(dValOccur)
-    
+
     def sortNodeArcs2 (self, oNode, cPrevious=""):
+        "sort arcs of each node depending on the previous char"
         # recursive function
         dCharOccur = getCharOrderAfterChar(cPrevious)
         if dCharOccur:
             oNode.sortArcs2(dCharOccur, self.lArcVal)
         for nArcVal, oNextNode in oNode.arcs.items():
             self.sortNodeArcs2(oNextNode, self.lArcVal[nArcVal])
 
     def sortNodes (self):
+        "sort nodes"
         print(" > Sort nodes")
         for oNode in self.oRoot.arcs.values():
             self._parseNodes(oNode)
-    
+
     def _parseNodes (self, oNode):
         # Warning: recursive method
         if oNode.pos > 0:
             return
         oNode.setPos()
         self.lSortedNodes.append(oNode)
         for oNextNode in oNode.arcs.values():
-             self._parseNodes(oNextNode)
-        
+            self._parseNodes(oNextNode)
+
     def lookup (self, sWord):
+        "return True if <sWord> is within the word graph (debugging)"
         oNode = self.oRoot
         for c in sWord:
             if self.dChar.get(c, '') not in oNode.arcs:
                 return False
             oNode = oNode.arcs[self.dChar[c]]
         return oNode.final
 
     def morph (self, sWord):
+        "return a string of the morphologies of <sWord> (debugging)"
         oNode = self.oRoot
         for c in sWord:
             if self.dChar.get(c, '') not in oNode.arcs:
                 return ''
             oNode = oNode.arcs[self.dChar[c]]
@@ -265,10 +275,11 @@
                     s += "]"
             return s
         return ''
 
     def displayInfo (self):
+        "display informations about the word graph"
         print(" * {:<12} {:>16,}".format("Entries:", self.nEntry))
         print(" * {:<12} {:>16,}".format("Characters:", self.nChar))
         print(" * {:<12} {:>16,}".format("Affixes:", self.nAff))
         print(" * {:<12} {:>16,}".format("Tags:", self.nTag))
         print(" * {:<12} {:>16,}".format("Arc values:", self.nArcVal))
@@ -275,10 +286,11 @@
         print(" * {:<12} {:>16,}".format("Nodes:", self.nNode))
         print(" * {:<12} {:>16,}".format("Arcs:", self.nArc))
         print(" * {:<12} {:>16}".format("Stemming:", self.cStemming + "FX"))
 
     def getArcStats (self):
+        "return a string with statistics about nodes and arcs"
         d = {}
         for oNode in self.lMinimizedNodes:
             n = len(oNode.arcs)
             d[n] = d.get(n, 0) + 1
         s = " * Nodes:\n"
@@ -285,10 +297,11 @@
         for n in d:
             s = s + " {:>9} nodes have {:>3} arcs\n".format(d[n], n)
         return s
 
     def writeInfo (self, sPathFile):
+        "write informations in file <sPathFile>"
         print(" > Write informations")
         with open(sPathFile, 'w', encoding='utf-8', newline="\n") as hDst:
             hDst.write(self.getArcStats())
             hDst.write("\n * Values:\n")
             for i, s in enumerate(self.lArcVal):
@@ -394,10 +407,11 @@
                 if self.lSortedNodes[i].size != nSize:
                     self.lSortedNodes[i].size = nSize
                     bEnd = False
 
     def getBinaryAsJSON (self, nCompressionMethod=1, bBinaryDictAsHexString=True):
+        "return a JSON string containing all necessary data of the dictionary (compressed as a binary string)"
         self._calculateBinary(nCompressionMethod)
         byDic = b""
         if nCompressionMethod == 1:
             byDic = self.oRoot.convToBytes1(self.nBytesArc, self.nBytesNodeAddress)
             for oNode in self.lMinimizedNodes:
@@ -436,10 +450,11 @@
             # https://github.com/mozilla/addons-linter/issues/1361
             "sByDic": byDic.hex()  if bBinaryDictAsHexString  else [ e  for e in byDic ]
         }
 
     def writeAsJSObject (self, spfDst, nCompressionMethod, bInJSModule=False, bBinaryDictAsHexString=True):
+        "write a file (JSON or JS module) with all the necessary data"
         if not spfDst.endswith(".json"):
             spfDst += "."+str(nCompressionMethod)+".json"
         with open(spfDst, "w", encoding="utf-8", newline="\n") as hDst:
             if bInJSModule:
                 hDst.write('// JavaScript\n// Generated data (do not edit)\n\n"use strict";\n\nconst dictionary = ')
@@ -447,17 +462,19 @@
             if bInJSModule:
                 hDst.write(";\n\nexports.dictionary = dictionary;\n")
 
     def writeBinary (self, sPathFile, nCompressionMethod, bDebug=False):
         """
+        Save as a binary file.
+
         Format of the binary indexable dictionary:
         Each section is separated with 4 bytes of \0
-        
+
         - Section Header:
             /grammalecte-fsa/[compression method]
                 * compression method is an ASCII string
-        
+
         - Section Informations:
             /[lang code]
             /[lang name]
             /[dictionary name]
             /[date creation]
@@ -472,14 +489,14 @@
             /[stemming code]
                 * "S" means stems are generated by /suffix_code/,
                   "A" means they are generated by /affix_code/
                   See defineSuffixCode() and defineAffixCode() for details.
                   "N" means no stemming
-        
+
         - Section Values:
                 * a list of strings encoded in binary from utf-8, each value separated with a tabulation
-        
+
         - Section Word Graph (nodes / arcs)
                 * A list of nodes which are a list of arcs with an address of the next node.
                   See DawgNode.convToBytes() for details.
         """
         self._calculateBinary(nCompressionMethod)
@@ -520,30 +537,32 @@
     def _writeNodes (self, sPathFile, nCompressionMethod):
         "for debugging only"
         print(" > Write nodes")
         with open(sPathFile+".nodes."+str(nCompressionMethod)+".txt", 'w', encoding='utf-8', newline="\n") as hDst:
             if nCompressionMethod == 1:
-                hDst.write(self.oRoot.getTxtRepr1(self.nBytesArc, self.nBytesNodeAddress, self.lArcVal)+"\n")
+                hDst.write(self.oRoot.getTxtRepr1(self.nBytesArc, self.lArcVal)+"\n")
                 #hDst.write( ''.join( [ "%02X " %  z  for z in self.oRoot.convToBytes1(self.nBytesArc, self.nBytesNodeAddress) ] ).strip() )
                 for oNode in self.lMinimizedNodes:
-                    hDst.write(oNode.getTxtRepr1(self.nBytesArc, self.nBytesNodeAddress, self.lArcVal)+"\n")
+                    hDst.write(oNode.getTxtRepr1(self.nBytesArc, self.lArcVal)+"\n")
             if nCompressionMethod == 2:
-                hDst.write(self.oRoot.getTxtRepr2(self.nBytesArc, self.nBytesNodeAddress, self.lArcVal)+"\n")
+                hDst.write(self.oRoot.getTxtRepr2(self.nBytesArc, self.lArcVal)+"\n")
                 for oNode in self.lSortedNodes:
-                    hDst.write(oNode.getTxtRepr2(self.nBytesArc, self.nBytesNodeAddress, self.lArcVal)+"\n")
+                    hDst.write(oNode.getTxtRepr2(self.nBytesArc, self.lArcVal)+"\n")
             if nCompressionMethod == 3:
-                hDst.write(self.oRoot.getTxtRepr3(self.nBytesArc, self.nBytesNodeAddress, self.nBytesOffset, self.lArcVal)+"\n")
+                hDst.write(self.oRoot.getTxtRepr3(self.nBytesArc, self.nBytesOffset, self.lArcVal)+"\n")
                 #hDst.write( ''.join( [ "%02X " %  z  for z in self.oRoot.convToBytes3(self.nBytesArc, self.nBytesNodeAddress, self.nBytesOffset) ] ).strip() )
                 for oNode in self.lSortedNodes:
-                    hDst.write(oNode.getTxtRepr3(self.nBytesArc, self.nBytesNodeAddress, self.nBytesOffset, self.lArcVal)+"\n")
+                    hDst.write(oNode.getTxtRepr3(self.nBytesArc, self.nBytesOffset, self.lArcVal)+"\n")
 
 
 
 class DawgNode:
+    """Node of the word graph"""
+
     NextId = 0
     NextPos = 1 # (version 2)
-    
+
     def __init__ (self):
         self.i = DawgNode.NextId
         DawgNode.NextId += 1
         self.final = False
         self.arcs = {}          # key: arc value; value: a node
@@ -551,19 +570,21 @@
         self.pos = 0            # position in the binary dictionary (version 2)
         self.size = 0           # size of node in bytes (version 3)
 
     @classmethod
     def resetNextId (cls):
+        "set NextId to 0 "
         cls.NextId = 0
 
     def setPos (self): # version 2
+        "define a position for node (version 2)"
         self.pos = DawgNode.NextPos
         DawgNode.NextPos += 1
 
     def __str__ (self):
         # Caution! this function is used for hashing and comparison!
-        sFinalChar = "1"  if self.final  else "0";
+        sFinalChar = "1"  if self.final  else "0"
         l = [sFinalChar]
         for (key, node) in self.arcs.items():
             l.append(str(key))
             l.append(str(node.i))
         return "_".join(l)
@@ -576,36 +597,40 @@
         # Used as a key in a python dictionary.
         # Nodes are equivalent if they have identical arcs, and each identical arc leads to identical states.
         return self.__str__() == other.__str__()
 
     def sortArcs (self, dValOccur):
+        "sort arcs of node according to <dValOccur>"
         self.arcs = collections.OrderedDict(sorted(self.arcs.items(), key=lambda t: dValOccur.get(t[0], 0), reverse=True))
 
     def sortArcs2 (self, dValOccur, lArcVal):
+        "sort arcs of each node depending on the previous char"
         self.arcs = collections.OrderedDict(sorted(self.arcs.items(), key=lambda t: dValOccur.get(lArcVal[t[0]], 0), reverse=True))
 
     # VERSION 1 =====================================================================================================
     def convToBytes1 (self, nBytesArc, nBytesNodeAddress):
         """
+        Convert to bytes (method 1).
+
         Node scheme:
         - Arc length is defined by nBytesArc
         - Address length is defined by nBytesNodeAddress
-                                       
+
         |                Arc                |                         Address of next node                          |
         |                                   |                                                                       |
-         /---------------\ /---------------\ /---------------\ /---------------\ /---------------\ /---------------\
-         | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-         \---------------/ \---------------/ \---------------/ \---------------/ \---------------/ \---------------/
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
          [...]
-         /---------------\ /---------------\ /---------------\ /---------------\ /---------------\ /---------------\
-         | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-         \---------------/ \---------------/ \---------------/ \---------------/ \---------------/ \---------------/
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
           ^ ^
-          | |
-          | |
-          |  \___ if 1, last arc of this node
-           \_____ if 1, this node is final (only on the first arc)
+          ┃ ┃
+          ┃ ┃
+          ┃ ┗━━━ if 1, last arc of this node
+          ┗━━━━━ if 1, this node is final (only on the first arc)
         """
         nArc = len(self.arcs)
         nFinalNodeMask = 1 << ((nBytesArc*8)-1)
         nFinalArcMask = 1 << ((nBytesArc*8)-2)
         if len(self.arcs) == 0:
@@ -621,12 +646,13 @@
             if i == nArc:
                 val = val | nFinalArcMask
             by += val.to_bytes(nBytesArc, byteorder='big')
             by += self.arcs[arc].addr.to_bytes(nBytesNodeAddress, byteorder='big')
         return by
-        
-    def getTxtRepr1 (self, nBytesArc, nBytesNodeAddress, lVal):
+
+    def getTxtRepr1 (self, nBytesArc, lVal):
+        "return representation as string of node (method 1)"
         nArc = len(self.arcs)
         nFinalNodeMask = 1 << ((nBytesArc*8)-1)
         nFinalArcMask = 1 << ((nBytesArc*8)-2)
         s = "i{:_>10} -- #{:_>10}\n".format(self.i, self.addr)
         if len(self.arcs) == 0:
@@ -642,28 +668,30 @@
         return s
 
     # VERSION 2 =====================================================================================================
     def convToBytes2 (self, nBytesArc, nBytesNodeAddress):
         """
+        Convert to bytes (method 2).
+
         Node scheme:
         - Arc length is defined by nBytesArc
         - Address length is defined by nBytesNodeAddress
-                                       
+
         |                Arc                |                         Address of next node                          |
         |                                   |                                                                       |
-         /---------------\ /---------------\ /---------------\ /---------------\ /---------------\ /---------------\
-         | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-         \---------------/ \---------------/ \---------------/ \---------------/ \---------------/ \---------------/
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
          [...]
-         /---------------\ /---------------\ /---------------\ /---------------\ /---------------\ /---------------\
-         | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-         \---------------/ \---------------/ \---------------/ \---------------/ \---------------/ \---------------/
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
           ^ ^ ^
-          | | |
-          | |  \_ if 1, caution, no address: next node is the following node
-          |  \___ if 1, last arc of this node
-           \_____ if 1, this node is final (only on the first arc)
+          ┃ ┃ ┃
+          ┃ ┃ ┗━━ if 1, caution, no address: next node is the following node
+          ┃ ┗━━━━ if 1, last arc of this node
+          ┗━━━━━━ if 1, this node is final (only on the first arc)
         """
         nArc = len(self.arcs)
         nFinalNodeMask = 1 << ((nBytesArc*8)-1)
         nFinalArcMask = 1 << ((nBytesArc*8)-2)
         nNextNodeMask = 1 << ((nBytesArc*8)-3)
@@ -684,12 +712,13 @@
                 by += val.to_bytes(nBytesArc, byteorder='big')
             else:
                 by += val.to_bytes(nBytesArc, byteorder='big')
                 by += self.arcs[arc].addr.to_bytes(nBytesNodeAddress, byteorder='big')
         return by
-        
-    def getTxtRepr2 (self, nBytesArc, nBytesNodeAddress, lVal):
+
+    def getTxtRepr2 (self, nBytesArc, lVal):
+        "return representation as string of node (method 2)"
         nArc = len(self.arcs)
         nFinalNodeMask = 1 << ((nBytesArc*8)-1)
         nFinalArcMask = 1 << ((nBytesArc*8)-2)
         nNextNodeMask = 1 << ((nBytesArc*8)-3)
         s = "i{:_>10} -- #{:_>10}\n".format(self.i, self.addr)
@@ -702,41 +731,43 @@
                 val = val | nFinalNodeMask
             if i == nArc:
                 val = val | nFinalArcMask
             if (self.pos + 1) == self.arcs[arc].pos  and self.i != 0:
                 val = val | nNextNodeMask
-                s += "  {:<20}  {:0>16}\n".format(lVal[arc], bin(val)[2:], "")
+                s += "  {:<20}  {:0>16}\n".format(lVal[arc], bin(val)[2:])
             else:
                 s += "  {:<20}  {:0>16}  i{:_>10}   #{:_>10}\n".format(lVal[arc], bin(val)[2:], self.arcs[arc].i, self.arcs[arc].addr)
         return s
 
     # VERSION 3 =====================================================================================================
     def convToBytes3 (self, nBytesArc, nBytesNodeAddress, nBytesOffset):
         """
+        Convert to bytes (method 3).
+
         Node scheme:
         - Arc length is defined by nBytesArc
         - Address length is defined by nBytesNodeAddress
         - Offset length is defined by nBytesOffset
-                                       
+
         |                Arc                |            Address of next node  or  offset to next node              |
         |                                   |                                                                       |
-         /---------------\ /---------------\ /---------------\ /---------------\ /---------------\ /---------------\
-         |1|0|0| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-         \---------------/ \---------------/ \---------------/ \---------------/ \---------------/ \---------------/
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃1┃0┃0┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
          [...]
-         /---------------\ /---------------\ /---------------\
-         |0|0|1| | | | | | | | | | | | | | | | | | | | | | | |     Offsets are shorter than addresses
-         \---------------/ \---------------/ \---------------/ 
-         /---------------\ /---------------\ /---------------\ /---------------\ /---------------\ /---------------\
-         |0|1|0| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-         \---------------/ \---------------/ \---------------/ \---------------/ \---------------/ \---------------/
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃0┃0┃1┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃     Offsets are shorter than addresses
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
+         ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━┓
+         ┃0┃1┃0┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
+         ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
 
           ^ ^ ^
-          | | |
-          | |  \_ if 1, offset instead of address of next node
-          |  \___ if 1, last arc of this node
-           \_____ if 1, this node is final (only on the first arc)
+          ┃ ┃ ┃
+          ┃ ┃ ┗━━ if 1, offset instead of address of next node
+          ┃ ┗━━━━ if 1, last arc of this node
+          ┗━━━━━━ if 1, this node is final (only on the first arc)
         """
         nArc = len(self.arcs)
         nFinalNodeMask = 1 << ((nBytesArc*8)-1)
         nFinalArcMask = 1 << ((nBytesArc*8)-2)
         nNextNodeMask = 1 << ((nBytesArc*8)-3)
@@ -759,12 +790,13 @@
                 by += (self.arcs[arc].addr-self.addr).to_bytes(nBytesOffset, byteorder='big')
             else:
                 by += val.to_bytes(nBytesArc, byteorder='big')
                 by += self.arcs[arc].addr.to_bytes(nBytesNodeAddress, byteorder='big')
         return by
-        
-    def getTxtRepr3 (self, nBytesArc, nBytesNodeAddress, nBytesOffset, lVal):
+
+    def getTxtRepr3 (self, nBytesArc, nBytesOffset, lVal):
+        "return representation as string of node (method 3)"
         nArc = len(self.arcs)
         nFinalNodeMask = 1 << ((nBytesArc*8)-1)
         nFinalArcMask = 1 << ((nBytesArc*8)-2)
         nNextNodeMask = 1 << ((nBytesArc*8)-3)
         nMaxOffset = (2 ** (nBytesOffset * 8)) - 1
@@ -794,20 +826,23 @@
     "": {}
 }
 
 
 def addWordToCharDict (sWord):
+    "for each character of <sWord>, count how many times it appears after the previous character, and store result in a <_dCharOrder>"
     cPrevious = ""
     for cChar in sWord:
         if cPrevious not in _dCharOrder:
             _dCharOrder[cPrevious] = {}
         _dCharOrder[cPrevious][cChar] = _dCharOrder[cPrevious].get(cChar, 0) + 1
         cPrevious = cChar
 
 
 def getCharOrderAfterChar (cChar):
+    "return a dictionary of chars with number of times it appears after character <cChar>"
     return _dCharOrder.get(cChar, None)
 
 
 def displayCharOrder ():
+    "display how many times each character appear after another one"
     for key, value in _dCharOrder.items():
         print("[" + key + "]: ", ", ".join([ c+":"+str(n)  for c, n  in  sorted(value.items(), key=lambda t: t[1], reverse=True) ]))

Index: graphspell/echo.py
==================================================================
--- graphspell/echo.py
+++ graphspell/echo.py
@@ -1,9 +1,13 @@
 #!python3
 
-# The most boring yet indispensable function: print!
+"""
+The most boring yet indispensable function: print!
+Because you can print on Windows console without being sure the script won’t crash…
 
+Windows console don’t accept many characters.
+"""
 
 import sys
 
 
 _CHARMAP = str.maketrans({  'œ': 'ö',  'Œ': 'Ö',  'ʳ': "r",  'ᵉ': "e",  '…': "_",  \
@@ -22,8 +26,8 @@
     if sys.platform != "win32":
         print(obj, sep=sep, end=end, file=file, flush=flush)
         return True
     try:
         print(str(obj).translate(_CHARMAP), sep=sep, end=end, file=file, flush=flush)
-    except:
+    except Exception:
         print(str(obj).encode('ascii', 'replace').decode('ascii', 'replace'), sep=sep, end=end, file=file, flush=flush)
     return True

ADDED   graphspell/fr.py
Index: graphspell/fr.py
==================================================================
--- /dev/null
+++ graphspell/fr.py
@@ -0,0 +1,46 @@
+"""
+Default suggestion for French language
+"""
+
+dSugg = {
+    "bcp": "beaucoup",
+    "ca": "ça",
+    "cad": "c’est-à-dire",
+    "cb": "combien|CB",
+    "cdlt": "cordialement",
+    "construirent": "construire|construisirent|construisent|construiront",
+    "càd": "c’est-à-dire",
+    "dc": "de|donc",
+    "email": "courriel|e-mail|émail",
+    "emails": "courriels|e-mails",
+    "Etes-vous": "Êtes-vous",
+    "Etiez-vous": "Étiez-vous",
+    "Etions-nous": "Étions-nous",
+    "parce-que": "parce que",
+    "pcq": "parce que",
+    "pd": "pendant",
+    "pdq": "pendant que",
+    "pdt": "pendant",
+    "pdtq": "pendant que",
+    "pk": "pourquoi",
+    "pq": "pourquoi|PQ",
+    "prq": "presque",
+    "prsq": "presque",
+    "qcq": "quiconque",
+    "qq": "quelque",
+    "qqch": "quelque chose",
+    "qqn": "quelqu’un",
+    "qqne": "quelqu’une",
+    "qqs": "quelques",
+    "qqunes": "quelques-unes",
+    "qquns": "quelques-uns",
+    "tdq": "tandis que",
+    "tj": "toujours",
+    "tjs": "toujours",
+    "tq": "tant que|tandis que",
+    "ts": "tous",
+    "tt": "tant|tout",
+    "tte": "toute",
+    "ttes": "toutes",
+    "y’a": "y a"
+}

Index: graphspell/ibdawg.py
==================================================================
--- graphspell/ibdawg.py
+++ graphspell/ibdawg.py
@@ -1,8 +1,13 @@
 #!python3
 
-import os
+"""
+INDEXABLE BINARY DIRECT ACYCLIC WORD GRAPH
+Implementation of a spellchecker as a transducer (storing transformation code to get lemma and morphologies)
+and a spell suggestion mechanim
+"""
+
 import traceback
 import pkgutil
 import re
 from functools import wraps
 import time
@@ -19,10 +24,11 @@
 
 def timethis (func):
     "decorator for the execution time"
     @wraps(func)
     def wrapper (*args, **kwargs):
+        "something to prevent pylint whining"
         fStart = time.time()
         result = func(*args, **kwargs)
         fEnd = time.time()
         print(func.__name__, fEnd - fStart)
         return result
@@ -56,11 +62,11 @@
                 self.aSugg.add(sSugg)
                 if nDist < self.nMinDist:
                     self.nMinDist = nDist
                 self.nDistLimit = min(self.nDistLimit, self.nMinDist+2)
 
-    def getSuggestions (self, nSuggLimit=10, nDistLimit=-1):
+    def getSuggestions (self, nSuggLimit=10):
         "return a list of suggestions"
         if self.dSugg[0]:
             # we sort the better results with the original word
             self.dSugg[0].sort(key=lambda sSugg: st.distanceDamerauLevenshtein(self.sWord, sSugg))
         lRes = self.dSugg.pop(0)
@@ -75,10 +81,11 @@
         elif self.sWord[0:1].isupper():
             lRes = list(map(lambda sSugg: sSugg[0:1].upper()+sSugg[1:], lRes))  # dont’ use <.istitle>
         return lRes[:nSuggLimit]
 
     def reset (self):
+        "clear data"
         self.aSugg.clear()
         self.dSugg.clear()
 
 
 class IBDAWG:
@@ -147,11 +154,11 @@
             raise ValueError("# Error. Unknown dictionary version: {}".format(self.by[17:18]))
         try:
             header, info, values, bdic = self.by.split(b"\0\0\0\0", 3)
         except Exception:
             raise Exception
-        
+
         self.nCompressionMethod = int(self.by[17:18].decode("utf-8"))
         self.sHeader = header.decode("utf-8")
         self.lArcVal = values.decode("utf-8").split("\t")
         self.nArcVal = len(self.lArcVal)
         self.byDic = bdic
@@ -182,10 +189,11 @@
         self.__dict__.update(oJSON)
         self.byDic = binascii.unhexlify(self.sByDic)
         self.dCharVal = { v: k  for k, v in self.dChar.items() }
 
     def getInfo (self):
+        "return string about the IBDAWG"
         return  "  Language: {0.sLangName}   Lang code: {0.sLangCode}   Dictionary name: {0.sDicName}" \
                 "  Compression method: {0.nCompressionMethod:>2}   Date: {0.sDate}   Stemming: {0.cStemming}FX\n" \
                 "  Arcs values:  {0.nArcVal:>10,} = {0.nChar:>5,} characters,  {0.nAff:>6,} affixes,  {0.nTag:>6,} tags\n" \
                 "  Dictionary: {0.nEntry:>12,} entries,    {0.nNode:>11,} nodes,   {0.nArc:>11,} arcs\n" \
                 "  Address size: {0.nBytesNodeAddress:>1} bytes,  Arc size: {0.nBytesArc:>1} bytes\n".format(self)
@@ -194,35 +202,35 @@
         "write IBDAWG as a JavaScript object in a JavaScript module"
         with open(spfDest, "w", encoding="utf-8", newline="\n") as hDst:
             if bInJSModule:
                 hDst.write('// JavaScript\n// Generated data (do not edit)\n\n"use strict";\n\nconst dictionary = ')
             hDst.write(json.dumps({
-                            "sHeader": "/grammalecte-fsa/",
-                            "sLangCode": self.sLangCode,
-                            "sLangName": self.sLangName,
-                            "sDicName": self.sDicName,
-                            "sFileName": self.sFileName,
-                            "sDate": self.sDate,
-                            "nEntry": self.nEntry,
-                            "nChar": self.nChar,
-                            "nAff": self.nAff,
-                            "nTag": self.nTag,
-                            "cStemming": self.cStemming,
-                            "dChar": self.dChar,
-                            "nNode": self.nNode,
-                            "nArc": self.nArc,
-                            "nArcVal": self.nArcVal,
-                            "lArcVal": self.lArcVal,
-                            "nCompressionMethod": self.nCompressionMethod,
-                            "nBytesArc": self.nBytesArc,
-                            "nBytesNodeAddress": self.nBytesNodeAddress,
-                            "nBytesOffset": self.nBytesOffset,
-                            # JavaScript is a pile of shit, so Mozilla’s JS parser don’t like file bigger than 4 Mb!
-                            # So, if necessary, we use an hexadecimal string, that we will convert later in Firefox’s extension.
-                            # https://github.com/mozilla/addons-linter/issues/1361
-                            "sByDic": self.byDic.hex()  if bBinaryDictAsHexString  else [ e  for e in self.byDic ]
-                        }, ensure_ascii=False))
+                "sHeader": "/grammalecte-fsa/",
+                "sLangCode": self.sLangCode,
+                "sLangName": self.sLangName,
+                "sDicName": self.sDicName,
+                "sFileName": self.sFileName,
+                "sDate": self.sDate,
+                "nEntry": self.nEntry,
+                "nChar": self.nChar,
+                "nAff": self.nAff,
+                "nTag": self.nTag,
+                "cStemming": self.cStemming,
+                "dChar": self.dChar,
+                "nNode": self.nNode,
+                "nArc": self.nArc,
+                "nArcVal": self.nArcVal,
+                "lArcVal": self.lArcVal,
+                "nCompressionMethod": self.nCompressionMethod,
+                "nBytesArc": self.nBytesArc,
+                "nBytesNodeAddress": self.nBytesNodeAddress,
+                "nBytesOffset": self.nBytesOffset,
+                # JavaScript is a pile of shit, so Mozilla’s JS parser don’t like file bigger than 4 Mb!
+                # So, if necessary, we use an hexadecimal string, that we will convert later in Firefox’s extension.
+                # https://github.com/mozilla/addons-linter/issues/1361
+                "sByDic": self.byDic.hex()  if bBinaryDictAsHexString  else [ e  for e in self.byDic ]
+            }, ensure_ascii=False))
             if bInJSModule:
                 hDst.write(";\n\nexports.dictionary = dictionary;\n")
 
     def isValidToken (self, sToken):
         "checks if <sToken> is valid (if there is hyphens in <sToken>, <sToken> is split, each part is checked)"
@@ -265,11 +273,11 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return False
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return False
         return bool(int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask)
 
     def getMorph (self, sWord):
         "retrieves morphologies list, different casing allowed"
@@ -344,17 +352,17 @@
                 self._suggest(oSuggResult, "", nMaxSwitch, nMaxDel, nMaxHardRepl, nMaxJump, nDist, nDeep+1, iAddr, sNewWord, True) # remove last char and go on
                 for sRepl in cp.dFinal1.get(sRemain, ()):
                     self._suggest(oSuggResult, sRepl, nMaxSwitch, nMaxDel, nMaxHardRepl, nMaxJump, nDist, nDeep+1, iAddr, sNewWord, True)
 
     #@timethis
-    def suggest2 (self, sWord, nMaxSugg=10):
+    def suggest2 (self, sWord, nSuggLimit=10):
         "returns a set of suggestions for <sWord>"
         sWord = cp.spellingNormalization(sWord)
         sPfx, sWord, sSfx = cp.cut(sWord)
         oSuggResult = SuggResult(sWord)
         self._suggest2(oSuggResult)
-        aSugg = oSuggResult.getSuggestions()
+        aSugg = oSuggResult.getSuggestions(nSuggLimit)
         if sSfx or sPfx:
             # we add what we removed
             return list(map(lambda sSug: sPfx + sSug + sSfx, aSugg))
         return aSugg
 
@@ -407,21 +415,21 @@
         "show the path taken by <sWord> in the graph"
         sWord = cp.spellingNormalization(sWord)
         c1 = sWord[0:1]  if sWord  else " "
         iPos = -1
         n = 0
-        print(c1 + ": ", end="")
+        echo(c1 + ": ", end="")
         for c2, jAddr in self._getCharArcs(iAddr):
-            print(c2, end="")
+            echo(c2, end="")
             if c2 == sWord[0:1]:
                 iNextNodeAddr = jAddr
                 iPos = n
             n += 1
         if not sWord:
             return
         if iPos >= 0:
-            print("\n   "+ " " * iPos + "|")
+            echo("\n   " + " " * iPos + "|")
             self.drawPath(sWord[1:], iNextNodeAddr)
 
     def getSimilarEntries (self, sWord, nSuggLimit=10):
         "return a list of tuples (similar word, stem, morphology)"
         if not sWord:
@@ -469,29 +477,29 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return []
-        if (int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask):
+        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
             l = []
             nRawArc = 0
             while not (nRawArc & self._lastArcMask):
                 iEndArcAddr = iAddr + self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
-                    # This value is not a char, this is a stemming code 
+                    # This value is not a char, this is a stemming code
                     sStem = ">" + self.funcStemming(sWord, self.lArcVal[nArc])
                     # Now , we go to the next node and retrieve all following arcs values, all of them are tags
                     iAddr2 = int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
                     nRawArc2 = 0
                     while not (nRawArc2 & self._lastArcMask):
                         iEndArcAddr2 = iAddr2 + self.nBytesArc
                         nRawArc2 = int.from_bytes(self.byDic[iAddr2:iEndArcAddr2], byteorder='big')
-                        l.append(sStem + " " + self.lArcVal[nRawArc2 & self._arcMask])
+                        l.append(sStem + "/" + self.lArcVal[nRawArc2 & self._arcMask])
                         iAddr2 = iEndArcAddr2+self.nBytesNodeAddress
                 iAddr = iEndArcAddr+self.nBytesNodeAddress
             return l
         return []
 
@@ -500,21 +508,21 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return []
-        if (int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask):
+        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
             l = []
             nRawArc = 0
             while not (nRawArc & self._lastArcMask):
                 iEndArcAddr = iAddr + self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
-                    # This value is not a char, this is a stemming code 
+                    # This value is not a char, this is a stemming code
                     l.append(self.funcStemming(sWord, self.lArcVal[nArc]))
                 iAddr = iEndArcAddr+self.nBytesNodeAddress
             return l
         return []
 
@@ -522,33 +530,33 @@
         "looks if <nVal> is an arc at the node at <iAddr>, if yes, returns address of next node else None"
         while True:
             iEndArcAddr = iAddr+self.nBytesArc
             nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
             if nVal == (nRawArc & self._arcMask):
-                # the value we are looking for 
+                # the value we are looking for
                 # we return the address of the next node
                 return int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
             else:
                 # value not found
-                if (nRawArc & self._lastArcMask):
+                if nRawArc & self._lastArcMask:
                     return None
                 iAddr = iEndArcAddr+self.nBytesNodeAddress
 
     def _getArcs1 (self, iAddr):
         "generator: return all arcs at <iAddr> as tuples of (nVal, iAddr)"
         while True:
             iEndArcAddr = iAddr+self.nBytesArc
             nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
-            yield (nRawArc & self._arcMask, int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big'))
-            if (nRawArc & self._lastArcMask):
+            yield nRawArc & self._arcMask, int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
+            if nRawArc & self._lastArcMask:
                 break
             iAddr = iEndArcAddr+self.nBytesNodeAddress
 
     def _writeNodes1 (self, spfDest):
         "for debugging only"
         print(" > Write binary nodes")
-        with codecs.open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
+        with open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
             iAddr = 0
             hDst.write("i{:_>10} -- #{:_>10}\n".format("0", iAddr))
             while iAddr < len(self.byDic):
                 iEndArcAddr = iAddr+self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
@@ -567,21 +575,21 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return []
-        if (int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask):
+        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
             l = []
             nRawArc = 0
             while not (nRawArc & self._lastArcMask):
                 iEndArcAddr = iAddr + self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
-                    # This value is not a char, this is a stemming code 
+                    # This value is not a char, this is a stemming code
                     sStem = ">" + self.funcStemming(sWord, self.lArcVal[nArc])
                     # Now , we go to the next node and retrieve all following arcs values, all of them are tags
                     if not (nRawArc & self._addrBitMask):
                         iAddr2 = int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
                     else:
@@ -592,11 +600,11 @@
                             iAddr2 += self.nBytesArc + self.nBytesNodeAddress
                     nRawArc2 = 0
                     while not (nRawArc2 & self._lastArcMask):
                         iEndArcAddr2 = iAddr2 + self.nBytesArc
                         nRawArc2 = int.from_bytes(self.byDic[iAddr2:iEndArcAddr2], byteorder='big')
-                        l.append(sStem + " " + self.lArcVal[nRawArc2 & self._arcMask])
+                        l.append(sStem + "/" + self.lArcVal[nRawArc2 & self._arcMask])
                         iAddr2 = iEndArcAddr2+self.nBytesNodeAddress  if not (nRawArc2 & self._addrBitMask) else iEndArcAddr2
                 iAddr = iEndArcAddr+self.nBytesNodeAddress  if not (nRawArc & self._addrBitMask)  else iEndArcAddr
             return l
         return []
 
@@ -605,21 +613,21 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return []
-        if (int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask):
+        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
             l = []
             nRawArc = 0
             while not (nRawArc & self._lastArcMask):
                 iEndArcAddr = iAddr + self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
-                    # This value is not a char, this is a stemming code 
+                    # This value is not a char, this is a stemming code
                     l.append(self.funcStemming(sWord, self.lArcVal[nArc]))
                     # Now , we go to the next node
                     if not (nRawArc & self._addrBitMask):
                         iAddr2 = int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
                     else:
@@ -636,11 +644,11 @@
         "looks if <nVal> is an arc at the node at <iAddr>, if yes, returns address of next node else None"
         while True:
             iEndArcAddr = iAddr+self.nBytesArc
             nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
             if nVal == (nRawArc & self._arcMask):
-                # the value we are looking for 
+                # the value we are looking for
                 if not (nRawArc & self._addrBitMask):
                     # we return the address of the next node
                     return int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
                 else:
                     # we go to the end of the node
@@ -649,18 +657,18 @@
                         nRawArc = int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big')
                         iAddr += self.nBytesArc + self.nBytesNodeAddress  if not (nRawArc & self._addrBitMask)  else self.nBytesArc
                     return iAddr
             else:
                 # value not found
-                if (nRawArc & self._lastArcMask):
+                if nRawArc & self._lastArcMask:
                     return None
                 iAddr = iEndArcAddr+self.nBytesNodeAddress  if not (nRawArc & self._addrBitMask)  else iEndArcAddr
 
     def _writeNodes2 (self, spfDest):
         "for debugging only"
         print(" > Write binary nodes")
-        with codecs.open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
+        with open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
             iAddr = 0
             hDst.write("i{:_>10} -- #{:_>10}\n".format("0", iAddr))
             while iAddr < len(self.byDic):
                 iEndArcAddr = iAddr+self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
@@ -670,11 +678,11 @@
                     hDst.write("  {:<20}  {:0>16}  i{:>10}   #{:_>10}\n".format(self.lArcVal[nArc], bin(nRawArc)[2:], "?", iNextNodeAddr))
                     iAddr = iEndArcAddr+self.nBytesNodeAddress
                 else:
                     hDst.write("  {:<20}  {:0>16}\n".format(self.lArcVal[nArc], bin(nRawArc)[2:]))
                     iAddr = iEndArcAddr
-                if (nRawArc & self._lastArcMask):
+                if nRawArc & self._lastArcMask:
                     hDst.write("\ni{:_>10} -- #{:_>10}\n".format("?", iAddr))
             hDst.close()
 
     # VERSION 3
     def _morph3 (self, sWord):
@@ -682,22 +690,22 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return []
-        if (int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask):
+        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
             l = []
             nRawArc = 0
             iAddrNode = iAddr
             while not (nRawArc & self._lastArcMask):
                 iEndArcAddr = iAddr + self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
-                    # This value is not a char, this is a stemming code 
+                    # This value is not a char, this is a stemming code
                     sStem = ">" + self.funcStemming(sWord, self.lArcVal[nArc])
                     # Now , we go to the next node and retrieve all following arcs values, all of them are tags
                     if not (nRawArc & self._addrBitMask):
                         iAddr2 = int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
                     else:
@@ -704,11 +712,11 @@
                         iAddr2 = iAddrNode + int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesOffset], byteorder='big')
                     nRawArc2 = 0
                     while not (nRawArc2 & self._lastArcMask):
                         iEndArcAddr2 = iAddr2 + self.nBytesArc
                         nRawArc2 = int.from_bytes(self.byDic[iAddr2:iEndArcAddr2], byteorder='big')
-                        l.append(sStem + " " + self.lArcVal[nRawArc2 & self._arcMask])
+                        l.append(sStem + "/" + self.lArcVal[nRawArc2 & self._arcMask])
                         iAddr2 = iEndArcAddr2+self.nBytesNodeAddress  if not (nRawArc2 & self._addrBitMask) else iEndArcAddr2+self.nBytesOffset
                 iAddr = iEndArcAddr+self.nBytesNodeAddress  if not (nRawArc & self._addrBitMask)  else iEndArcAddr+self.nBytesOffset
             return l
         return []
 
@@ -717,22 +725,22 @@
         iAddr = 0
         for c in sWord:
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
-            if iAddr == None:
+            if iAddr is None:
                 return []
-        if (int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask):
+        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
             l = []
             nRawArc = 0
-            iAddrNode = iAddr
+            #iAddrNode = iAddr
             while not (nRawArc & self._lastArcMask):
                 iEndArcAddr = iAddr + self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
-                    # This value is not a char, this is a stemming code 
+                    # This value is not a char, this is a stemming code
                     l.append(self.funcStemming(sWord, self.lArcVal[nArc]))
                 iAddr = iEndArcAddr+self.nBytesNodeAddress  if not (nRawArc & self._addrBitMask)  else iEndArcAddr+self.nBytesOffset
             return l
         return []
 
@@ -741,25 +749,25 @@
         iAddrNode = iAddr
         while True:
             iEndArcAddr = iAddr+self.nBytesArc
             nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
             if nVal == (nRawArc & self._arcMask):
-                # the value we are looking for 
+                # the value we are looking for
                 if not (nRawArc & self._addrBitMask):
                     return int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
                 else:
                     return iAddrNode + int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesOffset], byteorder='big')
             else:
                 # value not found
-                if (nRawArc & self._lastArcMask):
+                if nRawArc & self._lastArcMask:
                     return None
                 iAddr = iEndArcAddr+self.nBytesNodeAddress  if not (nRawArc & self._addrBitMask)  else iEndArcAddr+self.nBytesOffset
 
     def _writeNodes3 (self, spfDest):
         "for debugging only"
         print(" > Write binary nodes")
-        with codecs.open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
+        with open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
             iAddr = 0
             hDst.write("i{:_>10} -- #{:_>10}\n".format("0", iAddr))
             while iAddr < len(self.byDic):
                 iEndArcAddr = iAddr+self.nBytesArc
                 nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
@@ -770,8 +778,8 @@
                     iAddr = iEndArcAddr+self.nBytesNodeAddress
                 else:
                     iNextNodeAddr = int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesOffset], byteorder='big')
                     hDst.write("  {:<20}  {:0>16}  i{:>10}   +{:_>10}\n".format(self.lArcVal[nArc], bin(nRawArc)[2:], "?", iNextNodeAddr))
                     iAddr = iEndArcAddr+self.nBytesOffset
-                if (nRawArc & self._lastArcMask):
+                if nRawArc & self._lastArcMask:
                     hDst.write("\ni{:_>10} -- #{:_>10}\n".format("?", iAddr))
             hDst.close()

Index: graphspell/keyboard_chars_proximity.py
==================================================================
--- graphspell/keyboard_chars_proximity.py
+++ graphspell/keyboard_chars_proximity.py
@@ -1,13 +1,18 @@
-# Keyboard chars proximity
+
+"""
+Keyboard chars proximity
+"""
 
 
 def getKeyboardMap (sKeyboard):
+    "return keyboard map as a dictionary of chars"
     return _dKeyboardMap.get(sKeyboard.lower(), {})
 
 
 def getKeyboardList ():
+    "return list of keyboards available"
     return _dKeyboardMap.keys()
 
 
 _dKeyboardMap = {
     # keyboards by alphabetical order

Index: graphspell/progressbar.py
==================================================================
--- graphspell/progressbar.py
+++ graphspell/progressbar.py
@@ -1,14 +1,17 @@
-# Textual progressbar
+"""
+Textual progressbar
+"""
+
 # by Olivier R.
 # License: MPL 2
 
 import time
 
 class ProgressBar:
     "Textual progressbar"
-    
+
     def __init__ (self, nMin=0, nMax=100, nWidth=78):
         "initiate with minimum nMin to maximum nMax"
         self.nMin = nMin
         self.nMax = nMax
         self.nSpan = nMax - nMin
@@ -17,19 +20,19 @@
         self.nCurVal = nMin
         self.startTime = time.time()
         self._update()
 
     def _update (self):
-        fDone = ((self.nCurVal - self.nMin) / self.nSpan)
+        fDone = (self.nCurVal - self.nMin) / self.nSpan
         nAdvance = int(fDone * self.nWidth)
-        if (nAdvance > self.nAdvance):
+        if nAdvance > self.nAdvance:
             self.nAdvance = nAdvance
             print("\r[ {}{}  {}% ] ".format('>'*nAdvance, ' '*(self.nWidth-nAdvance), round(fDone*100)), end="")
 
     def increment (self, n=1):
         "increment value by n (1 by default)"
         self.nCurVal += n
         self._update()
-    
+
     def done (self):
         "to call when it’s finished"
         print("\r[ task done in {:.1f} s ] ".format(time.time() - self.startTime))

Index: graphspell/spellchecker.py
==================================================================
--- graphspell/spellchecker.py
+++ graphspell/spellchecker.py
@@ -1,16 +1,17 @@
-# Spellchecker
-# Wrapper for the IBDAWG class.
-# Useful to check several dictionaries at once.
-
-# To avoid iterating over a pile of dictionaries, it is assumed that 3 are enough:
-# - the main dictionary, bundled with the package
-# - the extended dictionary
-# - the community dictionary, added by an organization
-# - the personal dictionary, created by the user for its own convenience
-
-
+"""
+Spellchecker.
+Useful to check several dictionaries at once.
+
+To avoid iterating over a pile of dictionaries, it is assumed that 3 are enough:
+- the main dictionary, bundled with the package
+- the extended dictionary
+- the community dictionary, added by an organization
+- the personal dictionary, created by the user for its own convenience
+"""
+
+import importlib
 import traceback
 
 from . import ibdawg
 from . import tokenizer
 
@@ -20,10 +21,11 @@
     "en": "en.bdic"
 }
 
 
 class SpellChecker ():
+    "SpellChecker: wrapper for the IBDAWG class"
 
     def __init__ (self, sLangCode, sfMainDic="", sfExtendedDic="", sfCommunityDic="", sfPersonalDic=""):
         "returns True if the main dictionary is loaded"
         self.sLangCode = sLangCode
         if not sfMainDic:
@@ -34,10 +36,17 @@
         self.oPersonalDic = self._loadDictionary(sfPersonalDic)
         self.bExtendedDic = bool(self.oExtendedDic)
         self.bCommunityDic = bool(self.oCommunityDic)
         self.bPersonalDic = bool(self.oPersonalDic)
         self.oTokenizer = None
+        # Default suggestions
+        self.dDefaultSugg = None
+        self.loadSuggestions(sLangCode)
+        # storage
+        self.bStorage = False
+        self._dMorphologies = {}        # key: flexion, value: list of morphologies
+        self._dLemmas = {}              # key: flexion, value: list of lemmas
 
     def _loadDictionary (self, source, bNecessary=False):
         "returns an IBDAWG object"
         if not source:
             return None
@@ -48,23 +57,24 @@
                 raise Exception(str(e), "Error: <" + str(source) + "> not loaded.")
             print("Error: <" + str(source) + "> not loaded.")
             traceback.print_exc()
             return None
 
-    def loadTokenizer (self):
+    def _loadTokenizer (self):
         self.oTokenizer = tokenizer.Tokenizer(self.sLangCode)
 
     def getTokenizer (self):
+        "load and return the tokenizer object"
         if not self.oTokenizer:
-            self.loadTokenizer()
+            self._loadTokenizer()
         return self.oTokenizer
 
     def setMainDictionary (self, source):
         "returns True if the dictionary is loaded"
         self.oMainDic = self._loadDictionary(source, True)
         return bool(self.oMainDic)
-            
+
     def setExtendedDictionary (self, source, bActivate=True):
         "returns True if the dictionary is loaded"
         self.oExtendedDic = self._loadDictionary(source)
         self.bExtendedDic = False  if not bActivate  else bool(self.oExtendedDic)
         return bool(self.oExtendedDic)
@@ -80,33 +90,68 @@
         self.oPersonalDic = self._loadDictionary(source)
         self.bPersonalDic = False  if not bActivate  else bool(self.oPersonalDic)
         return bool(self.oPersonalDic)
 
     def activateExtendedDictionary (self):
+        "activate extended dictionary (if available)"
         self.bExtendedDic = bool(self.oExtendedDic)
 
     def activateCommunityDictionary (self):
+        "activate community dictionary (if available)"
         self.bCommunityDic = bool(self.oCommunityDic)
 
     def activatePersonalDictionary (self):
+        "activate personal dictionary (if available)"
         self.bPersonalDic = bool(self.oPersonalDic)
 
     def deactivateExtendedDictionary (self):
+        "deactivate extended dictionary"
         self.bExtendedDic = False
 
     def deactivateCommunityDictionary (self):
+        "deactivate community dictionary"
         self.bCommunityDic = False
 
     def deactivatePersonalDictionary (self):
+        "deactivate personal dictionary"
         self.bPersonalDic = False
 
+
+    # Default suggestions
+
+    def loadSuggestions (self, sLangCode):
+        "load default suggestion module for <sLangCode>"
+        try:
+            suggest = importlib.import_module("."+sLangCode, "graphspell")
+        except ImportError:
+            print("No suggestion module for language <"+sLangCode+">")
+            return
+        self.dDefaultSugg = suggest.dSugg
+
+
+    # Storage
+
+    def activateStorage (self):
+        "store all lemmas and morphologies retrieved from the word graph"
+        self.bStorage = True
+
+    def deactivateStorage (self):
+        "stop storing all lemmas and morphologies retrieved from the word graph"
+        self.bStorage = False
+
+    def clearStorage (self):
+        "clear all stored data"
+        self._dLemmas.clear()
+        self._dMorphologies.clear()
+
 
     # parse text functions
 
     def parseParagraph (self, sText, bSpellSugg=False):
+        "return a list of tokens where token value doesn’t exist in the word graph"
         if not self.oTokenizer:
-            self.loadTokenizer()
+            self._loadTokenizer()
         aSpellErrs = []
         for dToken in self.oTokenizer.genTokens(sText):
             if dToken['sType'] == "WORD" and not self.isValidToken(dToken['sValue']):
                 if bSpellSugg:
                     dToken['aSuggestions'] = []
@@ -114,12 +159,14 @@
                         dToken['aSuggestions'].extend(lSugg)
                 aSpellErrs.append(dToken)
         return aSpellErrs
 
     def countWordsOccurrences (self, sText, bByLemma=False, bOnlyUnknownWords=False, dWord={}):
+        """count word occurrences.
+           <dWord> can be used to cumulate count from several texts."""
         if not self.oTokenizer:
-            self.loadTokenizer()
+            self._loadTokenizer()
         for dToken in self.oTokenizer.genTokens(sText):
             if dToken['sType'] == "WORD":
                 if bOnlyUnknownWords:
                     if not self.isValidToken(dToken['sValue']):
                         dWord[dToken['sValue']] = dWord.get(dToken['sValue'], 0) + 1
@@ -149,11 +196,11 @@
         "checks if sWord is valid (different casing tested if the first letter is a capital)"
         if self.oMainDic.isValid(sWord):
             return True
         if self.bExtendedDic and self.oExtendedDic.isValid(sWord):
             return True
-        if self.bCommunityDic and self.oCommunityDic.isValid(sToken):
+        if self.bCommunityDic and self.oCommunityDic.isValid(sWord):
             return True
         if self.bPersonalDic and self.oPersonalDic.isValid(sWord):
             return True
         return False
 
@@ -161,33 +208,52 @@
         "checks if sWord is in dictionary as is (strict verification)"
         if self.oMainDic.lookup(sWord):
             return True
         if self.bExtendedDic and self.oExtendedDic.lookup(sWord):
             return True
-        if self.bCommunityDic and self.oCommunityDic.lookup(sToken):
+        if self.bCommunityDic and self.oCommunityDic.lookup(sWord):
             return True
         if self.bPersonalDic 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.bStorage and sWord in self._dMorphologies:
+            return self._dMorphologies[sWord]
+        lMorph = self.oMainDic.getMorph(sWord)
         if self.bExtendedDic:
-            lResult.extend(self.oExtendedDic.getMorph(sWord))
+            lMorph.extend(self.oExtendedDic.getMorph(sWord))
         if self.bCommunityDic:
-            lResult.extend(self.oCommunityDic.getMorph(sWord))
+            lMorph.extend(self.oCommunityDic.getMorph(sWord))
         if self.bPersonalDic:
-            lResult.extend(self.oPersonalDic.getMorph(sWord))
-        return lResult
+            lMorph.extend(self.oPersonalDic.getMorph(sWord))
+        if self.bStorage:
+            self._dMorphologies[sWord] = lMorph
+            self._dLemmas[sWord] = set([ s[1:s.find("/")]  for s in lMorph ])
+        return lMorph
 
     def getLemma (self, sWord):
-        return set([ s[1:s.find(" ")]  for s in self.getMorph(sWord) ])
+        "retrieves lemmas"
+        if self.bStorage:
+            if sWord not in self._dLemmas:
+                self.getMorph(sWord)
+            return self._dLemmas[sWord]
+        return set([ s[1:s.find("/")]  for s in self.getMorph(sWord) ])
 
     def suggest (self, sWord, nSuggLimit=10):
         "generator: returns 1, 2 or 3 lists of suggestions"
-        yield self.oMainDic.suggest(sWord, nSuggLimit)
+        if self.dDefaultSugg:
+            if sWord in self.dDefaultSugg:
+                yield self.dDefaultSugg[sWord].split("|")
+            elif sWord.istitle() and sWord.lower() in self.dDefaultSugg:
+                lRes = self.dDefaultSugg[sWord.lower()].split("|")
+                yield list(map(lambda sSugg: sSugg[0:1].upper()+sSugg[1:], lRes))
+            else:
+                yield self.oMainDic.suggest(sWord, nSuggLimit)
+        else:
+            yield self.oMainDic.suggest(sWord, nSuggLimit)
         if self.bExtendedDic:
             yield self.oExtendedDic.suggest(sWord, nSuggLimit)
         if self.bCommunityDic:
             yield self.oCommunityDic.suggest(sWord, nSuggLimit)
         if self.bPersonalDic:
@@ -202,10 +268,11 @@
             yield from self.oCommunityDic.select(sFlexPattern, sTagsPattern)
         if self.bPersonalDic:
             yield from self.oPersonalDic.select(sFlexPattern, sTagsPattern)
 
     def drawPath (self, sWord):
+        "draw the path taken by <sWord> within the word graph: display matching nodes and their arcs"
         self.oMainDic.drawPath(sWord)
         if self.bExtendedDic:
             print("-----")
             self.oExtendedDic.drawPath(sWord)
         if self.bCommunityDic:

Index: graphspell/str_transform.py
==================================================================
--- graphspell/str_transform.py
+++ graphspell/str_transform.py
@@ -1,25 +1,32 @@
 #!python3
 
+"""
+Operations on strings:
+- calculate distance between two strings
+- transform strings with transformation codes
+"""
+
 
 #### DISTANCE CALCULATIONS
 
 def longestCommonSubstring (s1, s2):
+    "longest common substring"
     # http://en.wikipedia.org/wiki/Longest_common_substring_problem
     # http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring
-    M = [ [0]*(1+len(s2)) for i in range(1+len(s1)) ]
-    longest, x_longest = 0, 0
+    lMatrix = [ [0]*(1+len(s2)) for i in range(1+len(s1)) ]
+    nLongest, nLongestX = 0, 0
     for x in range(1, 1+len(s1)):
         for y in range(1, 1+len(s2)):
             if s1[x-1] == s2[y-1]:
-                M[x][y] = M[x-1][y-1] + 1
-                if M[x][y] > longest:
-                    longest = M[x][y]
-                    x_longest = x
+                lMatrix[x][y] = lMatrix[x-1][y-1] + 1
+                if lMatrix[x][y] > nLongest:
+                    nLongest = lMatrix[x][y]
+                    nLongestX = x
             else:
-                M[x][y] = 0
-    return s1[x_longest-longest : x_longest]
+                lMatrix[x][y] = 0
+    return s1[nLongestX-nLongest : nLongestX]
 
 
 def distanceDamerauLevenshtein (s1, s2):
     "distance of Damerau-Levenshtein between <s1> and <s2>"
     # https://fr.wikipedia.org/wiki/Distance_de_Damerau-Levenshtein
@@ -54,11 +61,11 @@
     i1, i2 = 0, 0   # Cursors for each string
     nLargestCS = 0  # Largest common substring
     nLocalCS = 0    # Local common substring
     nTrans = 0      # Number of transpositions ('ab' vs 'ba')
     lOffset = []    # Offset pair array, for computing the transpositions
- 
+
     while i1 < nLen1 and i2 < nLen2:
         if s1[i1] == s2[i2]:
             nLocalCS += 1
             # Check if current match is a transposition
             bTrans = False
@@ -103,10 +110,11 @@
     nLargestCS += nLocalCS
     return round(max(nLen1, nLen2) - nLargestCS + nTrans)
 
 
 def showDistance (s1, s2):
+    "display Damerau-Levenshtein distance and Sift4 distance between <s1> and <s2>"
     print("Damerau-Levenshtein: " + s1 + "/" + s2 + " = " + distanceDamerauLevenshtein(s1, s2))
     print("Sift4:" + s1 + "/" + s2 + " = " + distanceSift4(s1, s2))
 
 
 
@@ -114,23 +122,27 @@
 #### STEMMING OPERATIONS
 
 ## No stemming
 
 def noStemming (sFlex, sStem):
+    "return <sStem>"
     return sStem
 
-def rebuildWord (sFlex, cmd1, cmd2):
-    if cmd1 == "_":
+def rebuildWord (sFlex, sCode1, sCode2):
+    """ Change <sFlex> with codes (each inserts a char at a defined possition).
+        <I forgot what purpose it has…>
+    """
+    if sCode1 == "_":
+        return sFlex
+    n, c = sCode1.split(":")
+    sFlex = sFlex[:n] + c + sFlex[n:]
+    if sCode2 == "_":
         return sFlex
-    n, c = cmd1.split(":")
-    s = s[:n] + c + s[n:]
-    if cmd2 == "_":
-        return s
-    n, c = cmd2.split(":")
-    return s[:n] + c + s[n:]
-
-    
+    n, c = sCode2.split(":")
+    return sFlex[:n] + c + sFlex[n:]
+
+
 ## Define affixes for stemming
 
 # Note: 48 is the ASCII code for "0"
 
 
@@ -150,14 +162,15 @@
     jSfx = 0
     for i in range(min(len(sFlex), len(sStem))):
         if sFlex[i] != sStem[i]:
             break
         jSfx += 1
-    return chr(len(sFlex)-jSfx+48) + sStem[jSfx:]  
+    return chr(len(sFlex)-jSfx+48) + sStem[jSfx:]
 
 
 def changeWordWithSuffixCode (sWord, sSfxCode):
+    "apply transformation code <sSfxCode> on <sWord> and return the result string"
     if sSfxCode == "0":
         return sWord
     return sWord[:-(ord(sSfxCode[0])-48)] + sSfxCode[1:]  if sSfxCode[0] != '0'  else sWord + sSfxCode[1:]
 
 
@@ -167,11 +180,11 @@
     """ Returns a string defining how to get stem from flexion. Examples:
             "0" if stem = flexion
             "stem" if no common substring
             "n(pfx)/m(sfx)"
         with n and m: chars with numeric meaning, "0" = 0, "1" = 1, ... ":" = 10, etc. (See ASCII table.) Says how many letters to strip from flexion.
-            pfx [optional]: string to add before the flexion 
+            pfx [optional]: string to add before the flexion
             sfx [optional]: string to add after the flexion
     """
     if sFlex == sStem:
         return "0"
     # is stem a substring of flexion?
@@ -189,13 +202,13 @@
         return chr(n+48) + sPfx + "/" + chr(m+48) + sSfx
     return sStem
 
 
 def changeWordWithAffixCode (sWord, sAffCode):
+    "apply transformation code <sAffCode> on <sWord> and return the result string"
     if sAffCode == "0":
         return sWord
     if '/' not in sAffCode:
         return sAffCode
     sPfxCode, sSfxCode = sAffCode.split('/')
-    sWord = sPfxCode[1:] + sWord[(ord(sPfxCode[0])-48):] 
+    sWord = sPfxCode[1:] + sWord[(ord(sPfxCode[0])-48):]
     return sWord[:-(ord(sSfxCode[0])-48)] + sSfxCode[1:]  if sSfxCode[0] != '0'  else sWord + sSfxCode[1:]
-

Index: graphspell/tokenizer.py
==================================================================
--- graphspell/tokenizer.py
+++ graphspell/tokenizer.py
@@ -1,49 +1,62 @@
-# Very simple tokenizer
+"""
+Very simple tokenizer
+using regular expressions
+"""
 
 import re
 
 _PATTERNS = {
     "default":
         (
             r'(?P<FOLDERUNIX>/(?:bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:/[\w.()-]+)*)',
             r'(?P<FOLDERWIN>[a-zA-Z]:\\(?:Program Files(?: [(]x86[)]|)|[\w.()]+)(?:\\[\w.()-]+)*)',
-            r'(?P<PUNC>[.,?!:;…«»“”"()/·]+)',
-            r'(?P<ACRONYM>[A-Z][.][A-Z][.](?:[A-Z][.])*)',
+            r'(?P<PUNC>[][,.;:!?…«»“”‘’"(){}·–—])',
+            r'(?P<WORD_ACRONYM>[A-Z][.][A-Z][.](?:[A-Z][.])*)',
             r'(?P<LINK>(?:https?://|www[.]|\w+[@.]\w\w+[@.])\w[\w./?&!%=+*"\'@$#-]+)',
             r'(?P<HASHTAG>[#@][\w-]+)',
             r'(?P<HTML><\w+.*?>|</\w+ *>)',
             r'(?P<PSEUDOHTML>\[/?\w+\])',
             r'(?P<HOUR>\d\d?h\d\d\b)',
             r'(?P<NUM>-?\d+(?:[.,]\d+))',
+            r'(?P<SIGN>[%‰+=*/<>⩾⩽-])',
             r"(?P<WORD>\w+(?:[’'`-]\w+)*)"
         ),
     "fr":
         (
             r'(?P<FOLDERUNIX>/(?:bin|boot|dev|etc|home|lib|mnt|opt|root|sbin|tmp|usr|var|Bureau|Documents|Images|Musique|Public|Téléchargements|Vidéos)(?:/[\w.()-]+)*)',
             r'(?P<FOLDERWIN>[a-zA-Z]:\\(?:Program Files(?: [(]x86[)]|)|[\w.()]+)(?:\\[\w.()-]+)*)',
-            r'(?P<PUNC>[.,?!:;…«»“”"()/·]+)',
-            r'(?P<ACRONYM>[A-Z][.][A-Z][.](?:[A-Z][.])*)',
+            r'(?P<PUNC>[][,.;:!?…«»“”‘’"(){}·–—])',
+            r'(?P<WORD_ACRONYM>[A-Z][.][A-Z][.](?:[A-Z][.])*)',
             r'(?P<LINK>(?:https?://|www[.]|\w+[@.]\w\w+[@.])\w[\w./?&!%=+*"\'@$#-]+)',
             r'(?P<HASHTAG>[#@][\w-]+)',
             r'(?P<HTML><\w+.*?>|</\w+ *>)',
             r'(?P<PSEUDOHTML>\[/?\w+\])',
-            r"(?P<ELPFX>(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu)['’`])",
-            r'(?P<ORDINAL>\d+(?:er|nd|e|de|ième|ème|eme)\b)',
+            r"(?P<WORD_ELIDED>(?:l|d|n|m|t|s|j|c|ç|lorsqu|puisqu|jusqu|quoiqu|qu)['’`])",
+            r'(?P<WORD_ORDINAL>\d+(?:ers?|nds?|es?|des?|ièmes?|èmes?|emes?|ᵉʳˢ?|ⁿᵈˢ?|ᵉˢ?|ᵈᵉˢ?)\b)',
             r'(?P<HOUR>\d\d?h\d\d\b)',
             r'(?P<NUM>-?\d+(?:[.,]\d+|))',
+            r'(?P<SIGN>[%‰+=*/<>⩾⩽-])',
             r"(?P<WORD>\w+(?:[’'`-]\w+)*)"
         )
 }
 
 
 class Tokenizer:
+    "Tokenizer: transforms a text in a list of tokens"
 
     def __init__ (self, sLang):
         self.sLang = sLang
         if sLang not in _PATTERNS:
             self.sLang = "default"
         self.zToken = re.compile( "(?i)" + '|'.join(sRegex for sRegex in _PATTERNS[sLang]) )
 
-    def genTokens (self, sText):
-        for m in self.zToken.finditer(sText):
-            yield { "sType": m.lastgroup, "sValue": m.group(), "nStart": m.start(), "nEnd": m.end() }
+    def genTokens (self, sText, bStartEndToken=False):
+        "generator: tokenize <sText>"
+        i = 0
+        if bStartEndToken:
+            yield { "i": 0, "sType": "INFO", "sValue": "<start>", "nStart": 0, "nEnd": 0, "lMorph": ["<start>"] }
+        for i, m in enumerate(self.zToken.finditer(sText), 1):
+            yield { "i": i, "sType": m.lastgroup, "sValue": m.group(), "nStart": m.start(), "nEnd": m.end() }
+        if bStartEndToken:
+            iEnd = len(sText)
+            yield { "i": i+1, "sType": "INFO", "sValue": "<end>", "nStart": iEnd, "nEnd": iEnd, "lMorph": ["<end>"] }

Index: make.py
==================================================================
--- make.py
+++ make.py
@@ -1,11 +1,14 @@
  #!/usr/bin/env python3
 # coding: UTF-8
+
+"""
+Grammalecte builder
+"""
 
 import sys
 import os
-import subprocess
 import re
 import zipfile
 import traceback
 import configparser
 import datetime
@@ -15,40 +18,43 @@
 import json
 import platform
 
 from distutils import dir_util, file_util
 
-import dialog_bundled
+#import dialog_bundled
 import compile_rules
 import helpers
 import lex_build
 
 
 sWarningMessage = "The content of this folder is generated by code and replaced at each build.\n"
 
 
 def getConfig (sLang):
+    "load config.ini in <sLang> at gc_lang/<sLang>, returns xConfigParser object"
     xConfig = configparser.SafeConfigParser()
     xConfig.optionxform = str
     try:
-        xConfig.read("gc_lang/" + sLang + "/config.ini", encoding="utf-8")
-    except:
+        xConfig.read_file(open("gc_lang/" + sLang + "/config.ini", "r", encoding="utf-8"))
+    except FileNotFoundError:
         print("# Error. Can’t read config file [" + sLang + "]")
         exit()
     return xConfig
 
 
 def createOptionsLabelProperties (dOptLbl):
+    "create content for .properties files (LibreOffice)"
     sContent = ""
     for sOpt, tLabel in dOptLbl.items():
         sContent += sOpt + "=" + tLabel[0] + "\n"
         if tLabel[1]:
             sContent += "hlp_" + sOpt + "=" + tLabel[1] + "\n"
     return sContent
 
 
 def createDialogOptionsXDL (dVars):
+    "create bundled dialog options file .xdl (LibreOffice)"
     sFixedline = '<dlg:fixedline dlg:id="{0}" dlg:tab-index="{1}" dlg:top="{2}" dlg:left="5" dlg:width="{3}" dlg:height="10" dlg:value="&amp;{0}" />\n'
     sCheckbox = '<dlg:checkbox dlg:id="{0}" dlg:tab-index="{1}" dlg:top="{2}" dlg:left="{3}" dlg:width="{4}" dlg:height="10" dlg:value="&amp;{0}" dlg:checked="{5}" {6} />\n'
     iTabIndex = 1
     nPosY = 5
     nWidth = 240
@@ -133,17 +139,17 @@
     if bInstall:
         print("> installation in Writer")
         if dVars.get('unopkg', False):
             cmd = '"'+os.path.abspath(dVars.get('unopkg')+'" add -f '+spfZip)
             print(cmd)
-            #subprocess.run(cmd)
             os.system(cmd)
         else:
             print("# Error: path and filename of unopkg not set in config.ini")
 
 
 def createServerOptions (sLang, dOptData):
+    "create file options for Grammalecte server"
     with open("grammalecte-server-options."+sLang+".ini", "w", encoding="utf-8", newline="\n") as hDst:
         hDst.write("# Server options. Lang: " + sLang + "\n\n[gc_options]\n")
         for sSection, lOpt in dOptData["lStructOpt"]:
             hDst.write("\n########## " + dOptData["dOptLabel"][sLang].get(sSection, sSection + "[no label found]")[0] + " ##########\n")
             for lLineOpt in lOpt:
@@ -164,10 +170,11 @@
         hZip.write(spf)
     hZip.writestr("setup.py", helpers.fileFile("gc_lang/fr/setup.py", dVars))
 
 
 def copyGrammalectePyPackageInZipFile (hZip, spLangPack, sAddPath=""):
+    "copy Grammalecte Python package in zip file"
     for sf in os.listdir("grammalecte"):
         if not os.path.isdir("grammalecte/"+sf):
             hZip.write("grammalecte/"+sf, sAddPath+"grammalecte/"+sf)
     for sf in os.listdir("grammalecte/graphspell"):
         if not os.path.isdir("grammalecte/graphspell/"+sf):
@@ -179,10 +186,11 @@
         if not os.path.isdir(spLangPack+"/"+sf):
             hZip.write(spLangPack+"/"+sf, sAddPath+spLangPack+"/"+sf)
 
 
 def create (sLang, xConfig, bInstallOXT, bJavaScript):
+    "make Grammalecte for project <sLang>"
     oNow = datetime.datetime.now()
     print("============== MAKE GRAMMALECTE [{0}] at {1.hour:>2} h {1.minute:>2} min {1.second:>2} s ==============".format(sLang, oNow))
 
     #### READ CONFIGURATION
     print("> read configuration...")
@@ -228,10 +236,11 @@
 
     # TEST FILES
     with open("grammalecte/"+sLang+"/gc_test.txt", "w", encoding="utf-8", newline="\n") as hDstPy:
         hDstPy.write("# TESTS FOR LANG [" + sLang + "]\n\n")
         hDstPy.write(dVars['gctests'])
+        hDstPy.write("\n")
 
     createOXT(spLang, dVars, xConfig._sections['oxt'], spLangPack, bInstallOXT)
 
     createServerOptions(sLang, dVars)
     createPackageZip(sLang, dVars, spLangPack)
@@ -250,11 +259,11 @@
 
         # options data struct
         dVars["dOptJavaScript"] = json.dumps(list(dVars["dOptJavaScript"].items()))
         dVars["dOptFirefox"] = json.dumps(list(dVars["dOptFirefox"].items()))
         dVars["dOptThunderbird"] = json.dumps(list(dVars["dOptThunderbird"].items()))
-        
+
         # create folder
         spLangPack = "grammalecte-js/"+sLang
         helpers.createCleanFolder(spLangPack)
 
         # create files
@@ -273,20 +282,21 @@
                 helpers.copyAndFileTemplate(spLang+"/modules-js/"+sf, spLangPack+"/"+sf, dVars)
                 print(sf, end=", ")
         print()
 
         try:
-            build_module = importlib.import_module("gc_lang."+sLang+".build")
+            buildjs = importlib.import_module("gc_lang."+sLang+".build")
         except ImportError:
             print("# No complementary builder <build.py> in folder gc_lang/"+sLang)
         else:
-            build_module.build(sLang, dVars, spLangPack)
+            buildjs.build(sLang, dVars, spLangPack)
 
     return dVars['version']
 
 
 def copyGraphspellCore (bJavaScript=False):
+    "copy Graphspell package in Grammalecte package"
     helpers.createCleanFolder("grammalecte/graphspell")
     dir_util.mkpath("grammalecte/graphspell/_dictionaries")
     for sf in os.listdir("graphspell"):
         if not os.path.isdir("graphspell/"+sf):
             file_util.copy_file("graphspell/"+sf, "grammalecte/graphspell")
@@ -301,10 +311,11 @@
                 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, bCommunityDict=False, bPersonalDict=False):
+    "copy requested Graphspell dictionaries in Grammalecte package"
     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"] = ""
@@ -333,16 +344,17 @@
     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):
+    "build binary dictionary for Graphspell from lexicons"
     if sType == "main":
         spfLexSrc = dVars['lexicon_src']
-        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):
+        lSfDictDst = dVars['dic_filenames'].split(",")
+        lDicName = dVars['dic_name'].split(",")
+        lFilter = dVars['dic_filter'].split(",")
+        for sfDictDst, sDicName, sFilter in zip(lSfDictDst, lDicName, lFilter):
             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']
@@ -358,10 +370,11 @@
         lex_build.build(spfLexSrc, dVars['lang'], dVars['lang_name'], sfDictDst, bJavaScript, sDicName, "", dVars['stemming_method'], int(dVars['fsa_method']))
 
 
 
 def main ():
+    "build Grammalecte with requested options"
     print("Python: " + sys.version)
     xParser = argparse.ArgumentParser()
     xParser.add_argument("lang", type=str, nargs='+', help="lang project to generate (name of folder in /lang)")
     xParser.add_argument("-b", "--build_data", help="launch build_data.py (part 1 and 2)", action="store_true")
     xParser.add_argument("-bb", "--build_data_before", help="launch build_data.py (only part 1: before dictionary building)", action="store_true")
@@ -403,29 +416,29 @@
                 xArgs.add_community_dictionary = False
             if not dVars["lexicon_personal_src"]:
                 xArgs.add_personal_dictionary = False
 
             # build data
-            build_data_module = None
+            databuild = None
             if xArgs.build_data_before or xArgs.build_data_after:
                 # lang data
                 try:
-                    build_data_module = importlib.import_module("gc_lang."+sLang+".build_data")
+                    databuild = importlib.import_module("gc_lang."+sLang+".build_data")
                 except ImportError:
                     print("# Error. Couldn’t import file build_data.py in folder gc_lang/"+sLang)
-            if build_data_module and xArgs.build_data_before:
-                build_data_module.before('gc_lang/'+sLang, dVars, xArgs.javascript)
+            if databuild and xArgs.build_data_before:
+                databuild.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)
+            if databuild and xArgs.build_data_after:
+                databuild.after('gc_lang/'+sLang, dVars, xArgs.javascript)
 
             # copy dictionaries from Graphspell
             copyGraphspellDictionaries(dVars, xArgs.javascript, xArgs.add_extended_dictionary, xArgs.add_community_dictionary, xArgs.add_personal_dictionary)
 
             # make
@@ -446,16 +459,15 @@
                         unittest.TextTestRunner().run(xTestSuite)
                     if xArgs.perf or xArgs.perf_memo:
                         hDst = open("./gc_lang/"+sLang+"/perf_memo.txt", "a", encoding="utf-8", newline="\n")  if xArgs.perf_memo  else None
                         tests.perf(sVersion, hDst)
 
-            # Firefox
-            if False:
-                # obsolete
-                with helpers.cd("_build/xpi/"+sLang):
-                    spfFirefox = dVars['win_fx_dev_path']  if platform.system() == "Windows"  else dVars['linux_fx_dev_path']
-                    os.system('jpm run -b "' + spfFirefox + '"')
+            # Firefox (obsolete)
+            #if False:
+            #    with helpers.cd("_build/xpi/"+sLang):
+            #        spfFirefox = dVars['win_fx_dev_path']  if platform.system() == "Windows"  else dVars['linux_fx_dev_path']
+            #        os.system('jpm run -b "' + spfFirefox + '"')
 
             if xArgs.web_ext or xArgs.firefox:
                 with helpers.cd("_build/webext/"+sLang):
                     if xArgs.lint_web_ext:
                         os.system(r'web-ext lint -o text')

Index: misc/grammalecte.sublime-syntax
==================================================================
--- misc/grammalecte.sublime-syntax
+++ misc/grammalecte.sublime-syntax
@@ -24,10 +24,23 @@
 
     # Bookmarks
     - match: '^!!.*|^\[\+\+\].*'
       scope: bookmark
 
+    # Bookmarks
+    - match: '^GRAPH_NAME:.*'
+      scope: bookmark
+
+    # Graph
+    - match: '^@@@@GRAPH: *(\w+) *'
+      scope: graphline
+      captures:
+        1: string.graphname
+
+    - match: '^@@@@(?:END_GRAPH *| *)'
+      scope: graphline
+
     # Keywords are if, else.
     # Note that blackslashes don't need to be escaped within single quoted
     # strings in YAML. When using single quoted strings, only single quotes
     # need to be escaped: this is done by using two single quotes next to each
     # other.
@@ -35,11 +48,11 @@
       scope: keyword.python
 
     - match: '\b(?:True|False|None)\b'
       scope: constant.language
     
-    - match: '\b(?:spell|morph|morphex|stem|textarea0?\w*|before0?\w*|after0?\w*|word|option|define|select|exclude|analysex?|apposition|is[A-Z]\w+|rewriteSubject|checkD\w+|getD\w+|has[A-Z]\w+|sugg[A-Z]\w+|switch[A-Z]\w+|ceOrCet|formatN\w+|mbUnit)\b'
+    - match: '\b(?:spell|morph|morphex|stem|textarea0?\w*|before0?\w*|after0?\w*|word|option|define|select|exclude|analysex?|tag_|apposition|is[A-Z]\w+|rewriteSubject|checkD\w+|getD\w+|has[A-Z]\w+|sugg[A-Z]\w+|switch[A-Z]\w+|ceOrCet|formatN\w+|mbUnit)\b'
       scope: entity.name.function
 
     - match: '\b(?:replace|endswith|startswith|search|upper|lower|capitalize|strip|rstrip|is(?:upper|lower|digit|title))\b'
       scope: support.function
 
@@ -47,19 +60,31 @@
       scope: support.function.debug
 
     - match: '\bre\b'
       scope: support.class
 
-    # Rule options
+    # Regex rule option
     - match: '^__[\[<]([isu])[\]>](/\w+|)(\(\w+\)|)(![0-9]|)__|</?js>'
       scope: rule.options
       captures:
         1: rule.casing
         2: rule.optionname
         3: rule.rulename
         4: rule.priority
 
+    # Graph rules option
+    - match: '^__(\w+)(![0-9]|)__'
+      scope: rule.options
+      captures:
+        1: rule.rulename2
+        2: rule.priority
+
+    - match: '/(\w+)/'
+      scope: rule.options
+      captures:
+        1: rule.optionname
+
     # Definitions and options
     - match: '^OPT(?:GROUP|LANG|PRIORITY)/|^OPTSOFTWARE:'
       scope: options.command
 
     - match: '^OPT(?:LABEL|)/'
@@ -84,20 +109,48 @@
       scope: keyword.action
     - match: '__also__'
       scope: keyword.condition.green
     - match: '__else__'
       scope: keyword.condition.red
-    - match: '-(\d*)>>'
+    - match: '-(\d*(?::\d+|))>>'
       scope: keyword.error
       captures:
         1: keyword.error.group
-    - match: '~(\d*)>>'
+    - match: '~(\d*(?::\d+|))>>'
       scope: keyword.textprocessor
       captures:
         1: keyword.textprocessor.group
     - match: '=>>'
       scope: keyword.disambiguator
+    - match: '/(\d*)>>'
+      scope: keyword.tag
+      captures:
+        1: keyword.tag.group
+
+
+    # Tokens
+    - match: '(>)\w+'
+      scope: string.lemma
+      captures:
+        1: keyword.valid
+
+    - match: '(~)(?!(?:\d+(?::\d+|)|)>>)[^\s]+'
+      scope: string.regex
+      captures:
+        1: keyword.valid
+
+    - match: '(@)([^@][^\s¬]+)'
+      scope: string.morph
+      captures:
+        1: keyword.valid
+        2: string.morph.pattern
+
+    - match: '(¬)(\S+)'
+      scope: string.morph
+      captures:
+        1: keyword.invalid
+        2: string.morph.antipattern  
 
     # Escaped chars
     - match: '\\(?:\d+|w|d|b|n|s|t)'
       scope: constant.character.escape
 
@@ -108,11 +161,11 @@
     # Example errors
     - match: '{{.+?}}'
       scope: message.error
 
     # special chars
-    - match: '[@=*^?!:+<>]'
+    - match: '[@=*^?¿!:+<>~]'
       scope: keyword.other
 
     - match: '\(\?(?:[:=!]|<!)|[(|)]'
       scope: keyword.parenthesis
 

Index: misc/grammalecte.tmTheme
==================================================================
--- misc/grammalecte.tmTheme
+++ misc/grammalecte.tmTheme
@@ -66,10 +66,25 @@
 				<string>#A0F0FF</string>
 				<key>background</key>
 				<string>#0050A0</string>
 			</dict>
 		</dict>
+		<dict>
+			<key>name</key>
+			<string>Graphline</string>
+			<key>scope</key>
+			<string>graphline</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>hsl(0, 100%, 80%)</string>
+				<key>background</key>
+				<string>hsl(0, 100%, 20%</string>
+				<key>fontStyle</key>
+				<string>bold</string>
+			</dict>
+		</dict>
 		<dict>
 			<key>name</key>
 			<string>String</string>
 			<key>scope</key>
 			<string>string</string>
@@ -233,10 +248,40 @@
 				<string>#602020</string>
 				<key>fontStyle</key>
 				<string>bold</string>
 			</dict>
 		</dict>
+		<dict>
+			<key>name</key>
+			<string>Keyword tag</string>
+			<key>scope</key>
+			<string>keyword.tag</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>#FF70FF</string>
+				<key>background</key>
+				<string>#602060</string>
+				<key>fontStyle</key>
+				<string>bold</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>Keyword tag group</string>
+			<key>scope</key>
+			<string>keyword.tag.group</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>#F0B0F0</string>
+				<key>background</key>
+				<string>#602060</string>
+				<key>fontStyle</key>
+				<string>bold</string>
+			</dict>
+		</dict>
 		<dict>
 			<key>name</key>
 			<string>Keyword textprocessor</string>
 			<key>scope</key>
 			<string>keyword.textprocessor</string>
@@ -291,10 +336,41 @@
 				<key>foreground</key>
 				<string>#A0A0A0</string>
 			</dict>
 		</dict>
 
+		<dict>
+			<key>name</key>
+			<string>Keyword Valid</string>
+			<key>scope</key>
+			<string>keyword.valid</string>
+			<key>settings</key>
+			<dict>
+				<key>fontStyle</key>
+				<string>bold</string>
+				<key>foreground</key>
+				<string>hsl(150, 100%, 80%)</string>
+				<key>background</key>
+				<string>hsl(150, 100%, 20%)</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>Keyword Invalid</string>
+			<key>scope</key>
+			<string>keyword.invalid</string>
+			<key>settings</key>
+			<dict>
+				<key>fontStyle</key>
+				<string>bold</string>
+				<key>foreground</key>
+				<string>hsl(0, 100%, 80%)</string>
+				<key>background</key>
+				<string>hsl(0, 100%, 20%)</string>
+			</dict>
+		</dict>
+
 		<dict>
 			<key>name</key>
 			<string>Rule options</string>
 			<key>scope</key>
 			<string>rule.options</string>
@@ -344,10 +420,21 @@
 				<string>italic</string>
 				<key>foreground</key>
 				<string>#A0A0A0</string>
 			</dict>
 		</dict>
+		<dict>
+			<key>name</key>
+			<string>Rule name</string>
+			<key>scope</key>
+			<string>rule.rulename2</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>#F0D080</string>
+			</dict>
+		</dict>
 		<dict>
 			<key>name</key>
 			<string>Rule priority</string>
 			<key>scope</key>
 			<string>rule.priority</string>
@@ -356,10 +443,63 @@
 				<key>foreground</key>
 				<string>#F06060</string>
 			</dict>
 		</dict>
 		
+		<dict>
+			<key>name</key>
+			<string>String lemma</string>
+			<key>scope</key>
+			<string>string.lemma</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>hsl(210, 100%, 80%)</string>
+				<key>background</key>
+				<string>hsl(210, 100%, 15%)</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>String regex</string>
+			<key>scope</key>
+			<string>string.regex</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>hsl(60, 100%, 80%)</string>
+				<key>background</key>
+				<string>hsl(60, 100%, 10%)</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>String morph pattern</string>
+			<key>scope</key>
+			<string>string.morph.pattern</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>hsl(150, 80%, 90%)</string>
+				<key>background</key>
+				<string>hsl(150, 80%, 10%)</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>name</key>
+			<string>String morph antipattern</string>
+			<key>scope</key>
+			<string>string.morph.antipattern</string>
+			<key>settings</key>
+			<dict>
+				<key>foreground</key>
+				<string>hsl(0, 80%, 90%)</string>
+				<key>background</key>
+				<string>hsl(0, 80%, 10%)</string>
+			</dict>
+		</dict>
+
 
 		<dict>
 			<key>name</key>
 			<string>JavaScript Dollar</string>
 			<key>scope</key>