Grammalecte  Hex Artifact Content

Artifact fa34b4b458ae9db04653ce3821fa99b4cc25ff6254aea7154619829d84b4bda0:


0000: 23 23 23 23 20 47 52 41 4d 4d 41 52 20 43 48 45  #### GRAMMAR CHE
0010: 43 4b 49 4e 47 20 45 4e 47 49 4e 45 20 50 4c 55  CKING ENGINE PLU
0020: 47 49 4e 3a 20 53 75 67 67 65 73 74 69 6f 6e 20  GIN: Suggestion 
0030: 6d 65 63 68 61 6e 69 73 6d 73 0a 0a 66 72 6f 6d  mechanisms..from
0040: 20 2e 20 69 6d 70 6f 72 74 20 63 6f 6e 6a 0a 66   . import conj.f
0050: 72 6f 6d 20 2e 20 69 6d 70 6f 72 74 20 6d 66 73  rom . import mfs
0060: 70 0a 66 72 6f 6d 20 2e 20 69 6d 70 6f 72 74 20  p.from . import 
0070: 70 68 6f 6e 65 74 0a 0a 0a 23 23 20 56 65 72 62  phonet...## Verb
0080: 73 0a 0a 64 65 66 20 73 70 6c 69 74 56 65 72 62  s..def splitVerb
0090: 20 28 73 56 65 72 62 29 3a 0a 20 20 20 20 22 72   (sVerb):.    "r
00a0: 65 6e 76 6f 69 65 20 6c 65 20 76 65 72 62 65 20  envoie le verbe 
00b0: 65 74 20 6c 65 73 20 70 72 6f 6e 6f 6d 73 20 73  et les pronoms s
00c0: c3 a9 70 61 72 c3 a9 6d 65 6e 74 22 0a 20 20 20  ..par..ment".   
00d0: 20 69 52 69 67 68 74 20 3d 20 73 56 65 72 62 2e   iRight = sVerb.
00e0: 72 66 69 6e 64 28 22 2d 22 29 0a 20 20 20 20 73  rfind("-").    s
00f0: 53 75 66 66 69 78 20 3d 20 73 56 65 72 62 5b 69  Suffix = sVerb[i
0100: 52 69 67 68 74 3a 5d 0a 20 20 20 20 73 56 65 72  Right:].    sVer
0110: 62 20 3d 20 73 56 65 72 62 5b 3a 69 52 69 67 68  b = sVerb[:iRigh
0120: 74 5d 0a 20 20 20 20 69 66 20 73 56 65 72 62 2e  t].    if sVerb.
0130: 65 6e 64 73 77 69 74 68 28 28 22 2d 74 22 2c 20  endswith(("-t", 
0140: 22 2d 6c 65 22 2c 20 22 2d 6c 61 22 2c 20 22 2d  "-le", "-la", "-
0150: 6c 65 73 22 29 29 3a 0a 20 20 20 20 20 20 20 20  les")):.        
0160: 69 52 69 67 68 74 20 3d 20 73 56 65 72 62 2e 72  iRight = sVerb.r
0170: 66 69 6e 64 28 22 2d 22 29 0a 20 20 20 20 20 20  find("-").      
0180: 20 20 73 53 75 66 66 69 78 20 3d 20 73 56 65 72    sSuffix = sVer
0190: 62 5b 69 52 69 67 68 74 3a 5d 20 2b 20 73 53 75  b[iRight:] + sSu
01a0: 66 66 69 78 0a 20 20 20 20 20 20 20 20 73 56 65  ffix.        sVe
01b0: 72 62 20 3d 20 73 56 65 72 62 5b 3a 69 52 69 67  rb = sVerb[:iRig
01c0: 68 74 5d 0a 20 20 20 20 72 65 74 75 72 6e 20 73  ht].    return s
01d0: 56 65 72 62 2c 20 73 53 75 66 66 69 78 0a 0a 0a  Verb, sSuffix...
01e0: 64 65 66 20 73 75 67 67 56 65 72 62 20 28 73 46  def suggVerb (sF
01f0: 6c 65 78 2c 20 73 57 68 6f 2c 20 66 75 6e 63 53  lex, sWho, funcS
0200: 75 67 67 32 3d 4e 6f 6e 65 2c 20 62 56 43 3d 46  ugg2=None, bVC=F
0210: 61 6c 73 65 29 3a 0a 20 20 20 20 22 63 68 61 6e  alse):.    "chan
0220: 67 65 20 3c 73 46 6c 65 78 3e 20 63 6f 6e 6a 75  ge <sFlex> conju
0230: 67 61 74 69 6f 6e 20 61 63 63 6f 72 64 69 6e 67  gation according
0240: 20 74 6f 20 3c 73 57 68 6f 3e 22 0a 20 20 20 20   to <sWho>".    
0250: 69 66 20 62 56 43 3a 0a 20 20 20 20 20 20 20 20  if bVC:.        
0260: 73 46 6c 65 78 2c 20 73 53 66 78 20 3d 20 73 70  sFlex, sSfx = sp
0270: 6c 69 74 56 65 72 62 28 73 46 6c 65 78 29 0a 20  litVerb(sFlex). 
0280: 20 20 20 61 53 75 67 67 20 3d 20 73 65 74 28 29     aSugg = set()
0290: 0a 20 20 20 20 66 6f 72 20 73 53 74 65 6d 20 69  .    for sStem i
02a0: 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  n _oSpellChecker
02b0: 2e 67 65 74 4c 65 6d 6d 61 28 73 46 6c 65 78 29  .getLemma(sFlex)
02c0: 3a 0a 20 20 20 20 20 20 20 20 74 54 61 67 73 20  :.        tTags 
02d0: 3d 20 63 6f 6e 6a 2e 5f 67 65 74 54 61 67 73 28  = conj._getTags(
02e0: 73 53 74 65 6d 29 0a 20 20 20 20 20 20 20 20 69  sStem).        i
02f0: 66 20 74 54 61 67 73 3a 0a 20 20 20 20 20 20 20  f tTags:.       
0300: 20 20 20 20 20 23 20 77 65 20 67 65 74 20 74 68       # we get th
0310: 65 20 74 65 6e 73 65 0a 20 20 20 20 20 20 20 20  e tense.        
0320: 20 20 20 20 61 54 65 6e 73 65 20 3d 20 73 65 74      aTense = set
0330: 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  ().            f
0340: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
0350: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
0360: 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20  orph(sFlex):.   
0370: 20 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72               for
0380: 20 6d 20 69 6e 20 72 65 2e 66 69 6e 64 69 74 65   m in re.findite
0390: 72 28 22 3e 22 2b 73 53 74 65 6d 2b 22 2f 2e 2a  r(">"+sStem+"/.*
03a0: 3f 28 3a 28 3f 3a 59 7c 49 5b 70 71 73 66 5d 7c  ?(:(?:Y|I[pqsf]|
03b0: 53 5b 70 71 5d 7c 4b 7c 50 7c 51 29 29 22 2c 20  S[pq]|K|P|Q))", 
03c0: 73 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20 20  sMorph):.       
03d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 73               # s
03e0: 74 65 6d 20 6d 75 73 74 20 62 65 20 75 73 65 64  tem must be used
03f0: 20 69 6e 20 72 65 67 65 78 20 74 6f 20 70 72 65   in regex to pre
0400: 76 65 6e 74 20 63 6f 6e 66 75 73 69 6f 6e 20 62  vent confusion b
0410: 65 74 77 65 65 6e 20 64 69 66 66 65 72 65 6e 74  etween different
0420: 20 76 65 72 62 73 20 28 65 2e 67 2e 20 73 61 75   verbs (e.g. sau
0430: 72 61 73 20 68 61 73 20 32 20 73 74 65 6d 73 3a  ras has 2 stems:
0440: 20 73 61 76 6f 69 72 20 61 6e 64 20 73 61 75 72   savoir and saur
0450: 65 72 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  er).            
0460: 20 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20          if m:.  
0470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0480: 20 20 20 20 20 20 69 66 20 6d 2e 67 72 6f 75 70        if m.group
0490: 28 31 29 20 3d 3d 20 22 3a 59 22 20 6f 72 20 6d  (1) == ":Y" or m
04a0: 2e 67 72 6f 75 70 28 31 29 20 3d 3d 20 22 3a 51  .group(1) == ":Q
04b0: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
04d0: 54 65 6e 73 65 2e 61 64 64 28 22 3a 49 70 22 29  Tense.add(":Ip")
04e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
04f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 61 54 65               aTe
0500: 6e 73 65 2e 61 64 64 28 22 3a 49 71 22 29 0a 20  nse.add(":Iq"). 
0510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0520: 20 20 20 20 20 20 20 20 20 20 20 61 54 65 6e 73             aTens
0530: 65 2e 61 64 64 28 22 3a 49 73 22 29 0a 20 20 20  e.add(":Is").   
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0550: 20 20 20 20 20 65 6c 69 66 20 6d 2e 67 72 6f 75       elif m.grou
0560: 70 28 31 29 20 3d 3d 20 22 3a 50 22 3a 0a 20 20  p(1) == ":P":.  
0570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0580: 20 20 20 20 20 20 20 20 20 20 61 54 65 6e 73 65            aTense
0590: 2e 61 64 64 28 22 3a 49 70 22 29 0a 20 20 20 20  .add(":Ip").    
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05b0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
05c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05d0: 20 20 20 20 20 20 61 54 65 6e 73 65 2e 61 64 64        aTense.add
05e0: 28 6d 2e 67 72 6f 75 70 28 31 29 29 0a 20 20 20  (m.group(1)).   
05f0: 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 54 65           for sTe
0600: 6e 73 65 20 69 6e 20 61 54 65 6e 73 65 3a 0a 20  nse in aTense:. 
0610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
0620: 66 20 73 57 68 6f 20 3d 3d 20 22 3a 31 c5 9b 22  f sWho == ":1.."
0630: 20 61 6e 64 20 6e 6f 74 20 63 6f 6e 6a 2e 5f 68   and not conj._h
0640: 61 73 43 6f 6e 6a 57 69 74 68 54 61 67 73 28 74  asConjWithTags(t
0650: 54 61 67 73 2c 20 73 54 65 6e 73 65 2c 20 22 3a  Tags, sTense, ":
0660: 31 c5 9b 22 29 3a 0a 20 20 20 20 20 20 20 20 20  1.."):.         
0670: 20 20 20 20 20 20 20 20 20 20 20 73 57 68 6f 20             sWho 
0680: 3d 20 22 3a 31 73 22 0a 20 20 20 20 20 20 20 20  = ":1s".        
0690: 20 20 20 20 20 20 20 20 69 66 20 63 6f 6e 6a 2e          if conj.
06a0: 5f 68 61 73 43 6f 6e 6a 57 69 74 68 54 61 67 73  _hasConjWithTags
06b0: 28 74 54 61 67 73 2c 20 73 54 65 6e 73 65 2c 20  (tTags, sTense, 
06c0: 73 57 68 6f 29 3a 0a 20 20 20 20 20 20 20 20 20  sWho):.         
06d0: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
06e0: 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67 65 74 43 6f  .add(conj._getCo
06f0: 6e 6a 57 69 74 68 54 61 67 73 28 73 53 74 65 6d  njWithTags(sStem
0700: 2c 20 74 54 61 67 73 2c 20 73 54 65 6e 73 65 2c  , tTags, sTense,
0710: 20 73 57 68 6f 29 29 0a 20 20 20 20 69 66 20 66   sWho)).    if f
0720: 75 6e 63 53 75 67 67 32 3a 0a 20 20 20 20 20 20  uncSugg2:.      
0730: 20 20 61 53 75 67 67 32 20 3d 20 66 75 6e 63 53    aSugg2 = funcS
0740: 75 67 67 32 28 73 46 6c 65 78 29 0a 20 20 20 20  ugg2(sFlex).    
0750: 20 20 20 20 69 66 20 61 53 75 67 67 32 3a 0a 20      if aSugg2:. 
0760: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
0770: 2e 61 64 64 28 61 53 75 67 67 32 29 0a 20 20 20  .add(aSugg2).   
0780: 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20   if aSugg:.     
0790: 20 20 20 69 66 20 62 56 43 3a 0a 20 20 20 20 20     if bVC:.     
07a0: 20 20 20 20 20 20 20 61 53 75 67 67 20 3d 20 6c         aSugg = l
07b0: 69 73 74 28 6d 61 70 28 6c 61 6d 62 64 61 20 73  ist(map(lambda s
07c0: 53 75 67 3a 20 73 53 75 67 20 2b 20 73 53 66 78  Sug: sSug + sSfx
07d0: 2c 20 61 53 75 67 67 29 29 0a 20 20 20 20 20 20  , aSugg)).      
07e0: 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69    return "|".joi
07f0: 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65 74  n(aSugg).    ret
0800: 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75 67  urn ""...def sug
0810: 67 56 65 72 62 50 70 61 73 20 28 73 46 6c 65 78  gVerbPpas (sFlex
0820: 2c 20 73 50 61 74 74 65 72 6e 3d 4e 6f 6e 65 29  , sPattern=None)
0830: 3a 0a 20 20 20 20 22 73 75 67 67 65 73 74 20 70  :.    "suggest p
0840: 61 73 74 20 70 61 72 74 69 63 69 70 6c 65 73 20  ast participles 
0850: 66 6f 72 20 3c 73 46 6c 65 78 3e 22 0a 20 20 20  for <sFlex>".   
0860: 20 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20   aSugg = set(). 
0870: 20 20 20 66 6f 72 20 73 53 74 65 6d 20 69 6e 20     for sStem in 
0880: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
0890: 65 74 4c 65 6d 6d 61 28 73 46 6c 65 78 29 3a 0a  etLemma(sFlex):.
08a0: 20 20 20 20 20 20 20 20 74 54 61 67 73 20 3d 20          tTags = 
08b0: 63 6f 6e 6a 2e 5f 67 65 74 54 61 67 73 28 73 53  conj._getTags(sS
08c0: 74 65 6d 29 0a 20 20 20 20 20 20 20 20 69 66 20  tem).        if 
08d0: 74 54 61 67 73 3a 0a 20 20 20 20 20 20 20 20 20  tTags:.         
08e0: 20 20 20 69 66 20 6e 6f 74 20 73 50 61 74 74 65     if not sPatte
08f0: 72 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  rn:.            
0900: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f      aSugg.add(co
0910: 6e 6a 2e 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54  nj._getConjWithT
0920: 61 67 73 28 73 53 74 65 6d 2c 20 74 54 61 67 73  ags(sStem, tTags
0930: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 29  , ":PQ", ":Q1"))
0940: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0950: 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e   aSugg.add(conj.
0960: 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73  _getConjWithTags
0970: 28 73 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 22  (sStem, tTags, "
0980: 3a 50 51 22 2c 20 22 3a 51 32 22 29 29 0a 20 20  :PQ", ":Q2")).  
0990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53                aS
09a0: 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67 65  ugg.add(conj._ge
09b0: 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28 73 53  tConjWithTags(sS
09c0: 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a 50 51  tem, tTags, ":PQ
09d0: 22 2c 20 22 3a 51 33 22 29 29 0a 20 20 20 20 20  ", ":Q3")).     
09e0: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
09f0: 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67 65 74 43 6f  .add(conj._getCo
0a00: 6e 6a 57 69 74 68 54 61 67 73 28 73 53 74 65 6d  njWithTags(sStem
0a10: 2c 20 74 54 61 67 73 2c 20 22 3a 50 51 22 2c 20  , tTags, ":PQ", 
0a20: 22 3a 51 34 22 29 29 0a 20 20 20 20 20 20 20 20  ":Q4")).        
0a30: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 64 69          aSugg.di
0a40: 73 63 61 72 64 28 22 22 29 0a 20 20 20 20 20 20  scard("").      
0a50: 20 20 20 20 20 20 65 6c 69 66 20 73 50 61 74 74        elif sPatt
0a60: 65 72 6e 20 3d 3d 20 22 3a 6d 3a 73 22 3a 0a 20  ern == ":m:s":. 
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
0a80: 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67  Sugg.add(conj._g
0a90: 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28 73  etConjWithTags(s
0aa0: 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a 50  Stem, tTags, ":P
0ab0: 51 22 2c 20 22 3a 51 31 22 29 29 0a 20 20 20 20  Q", ":Q1")).    
0ac0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 50 61          elif sPa
0ad0: 74 74 65 72 6e 20 3d 3d 20 22 3a 6d 3a 70 22 3a  ttern == ":m:p":
0ae0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0af0: 20 69 66 20 63 6f 6e 6a 2e 5f 68 61 73 43 6f 6e   if conj._hasCon
0b00: 6a 57 69 74 68 54 61 67 73 28 74 54 61 67 73 2c  jWithTags(tTags,
0b10: 20 22 3a 50 51 22 2c 20 22 3a 51 32 22 29 3a 0a   ":PQ", ":Q2"):.
0b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b30: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f      aSugg.add(co
0b40: 6e 6a 2e 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54  nj._getConjWithT
0b50: 61 67 73 28 73 53 74 65 6d 2c 20 74 54 61 67 73  ags(sStem, tTags
0b60: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 32 22 29 29  , ":PQ", ":Q2"))
0b70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0b80: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
0b90: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
0ba0: 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67 65 74 43 6f  .add(conj._getCo
0bb0: 6e 6a 57 69 74 68 54 61 67 73 28 73 53 74 65 6d  njWithTags(sStem
0bc0: 2c 20 74 54 61 67 73 2c 20 22 3a 50 51 22 2c 20  , tTags, ":PQ", 
0bd0: 22 3a 51 31 22 29 29 0a 20 20 20 20 20 20 20 20  ":Q1")).        
0be0: 20 20 20 20 65 6c 69 66 20 73 50 61 74 74 65 72      elif sPatter
0bf0: 6e 20 3d 3d 20 22 3a 66 3a 73 22 3a 0a 20 20 20  n == ":f:s":.   
0c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
0c10: 63 6f 6e 6a 2e 5f 68 61 73 43 6f 6e 6a 57 69 74  conj._hasConjWit
0c20: 68 54 61 67 73 28 74 54 61 67 73 2c 20 22 3a 50  hTags(tTags, ":P
0c30: 51 22 2c 20 22 3a 51 33 22 29 3a 0a 20 20 20 20  Q", ":Q3"):.    
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c50: 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f  aSugg.add(conj._
0c60: 67 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28  getConjWithTags(
0c70: 73 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a  sStem, tTags, ":
0c80: 50 51 22 2c 20 22 3a 51 33 22 29 29 0a 20 20 20  PQ", ":Q3")).   
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73               els
0ca0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
0cb0: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
0cc0: 28 63 6f 6e 6a 2e 5f 67 65 74 43 6f 6e 6a 57 69  (conj._getConjWi
0cd0: 74 68 54 61 67 73 28 73 53 74 65 6d 2c 20 74 54  thTags(sStem, tT
0ce0: 61 67 73 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31  ags, ":PQ", ":Q1
0cf0: 22 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ")).            
0d00: 65 6c 69 66 20 73 50 61 74 74 65 72 6e 20 3d 3d  elif sPattern ==
0d10: 20 22 3a 66 3a 70 22 3a 0a 20 20 20 20 20 20 20   ":f:p":.       
0d20: 20 20 20 20 20 20 20 20 20 69 66 20 63 6f 6e 6a           if conj
0d30: 2e 5f 68 61 73 43 6f 6e 6a 57 69 74 68 54 61 67  ._hasConjWithTag
0d40: 73 28 74 54 61 67 73 2c 20 22 3a 50 51 22 2c 20  s(tTags, ":PQ", 
0d50: 22 3a 51 34 22 29 3a 0a 20 20 20 20 20 20 20 20  ":Q4"):.        
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
0d70: 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67 65 74 43  g.add(conj._getC
0d80: 6f 6e 6a 57 69 74 68 54 61 67 73 28 73 53 74 65  onjWithTags(sSte
0d90: 6d 2c 20 74 54 61 67 73 2c 20 22 3a 50 51 22 2c  m, tTags, ":PQ",
0da0: 20 22 3a 51 34 22 29 29 0a 20 20 20 20 20 20 20   ":Q4")).       
0db0: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0dd0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e     aSugg.add(con
0de0: 6a 2e 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54 61  j._getConjWithTa
0df0: 67 73 28 73 53 74 65 6d 2c 20 74 54 61 67 73 2c  gs(sStem, tTags,
0e00: 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 29 0a   ":PQ", ":Q1")).
0e10: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66              elif
0e20: 20 73 50 61 74 74 65 72 6e 20 3d 3d 20 22 3a 73   sPattern == ":s
0e30: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
0e40: 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e     aSugg.add(con
0e50: 6a 2e 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54 61  j._getConjWithTa
0e60: 67 73 28 73 53 74 65 6d 2c 20 74 54 61 67 73 2c  gs(sStem, tTags,
0e70: 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 29 0a   ":PQ", ":Q1")).
0e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e90: 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f  aSugg.add(conj._
0ea0: 67 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28  getConjWithTags(
0eb0: 73 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a  sStem, tTags, ":
0ec0: 50 51 22 2c 20 22 3a 51 33 22 29 29 0a 20 20 20  PQ", ":Q3")).   
0ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75               aSu
0ee0: 67 67 2e 64 69 73 63 61 72 64 28 22 22 29 0a 20  gg.discard(""). 
0ef0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20             elif 
0f00: 73 50 61 74 74 65 72 6e 20 3d 3d 20 22 3a 70 22  sPattern == ":p"
0f10: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
0f20: 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a    aSugg.add(conj
0f30: 2e 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54 61 67  ._getConjWithTag
0f40: 73 28 73 53 74 65 6d 2c 20 74 54 61 67 73 2c 20  s(sStem, tTags, 
0f50: 22 3a 50 51 22 2c 20 22 3a 51 32 22 29 29 0a 20  ":PQ", ":Q2")). 
0f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
0f70: 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67  Sugg.add(conj._g
0f80: 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28 73  etConjWithTags(s
0f90: 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a 50  Stem, tTags, ":P
0fa0: 51 22 2c 20 22 3a 51 34 22 29 29 0a 20 20 20 20  Q", ":Q4")).    
0fb0: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
0fc0: 67 2e 64 69 73 63 61 72 64 28 22 22 29 0a 20 20  g.discard("").  
0fd0: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
0fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ff0: 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f  aSugg.add(conj._
1000: 67 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28  getConjWithTags(
1010: 73 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a  sStem, tTags, ":
1020: 50 51 22 2c 20 22 3a 51 31 22 29 29 0a 20 20 20  PQ", ":Q1")).   
1030: 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20   if aSugg:.     
1040: 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f     return "|".jo
1050: 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65  in(aSugg).    re
1060: 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75  turn ""...def su
1070: 67 67 56 65 72 62 54 65 6e 73 65 20 28 73 46 6c  ggVerbTense (sFl
1080: 65 78 2c 20 73 54 65 6e 73 65 2c 20 73 57 68 6f  ex, sTense, sWho
1090: 29 3a 0a 20 20 20 20 22 63 68 61 6e 67 65 20 3c  ):.    "change <
10a0: 73 46 6c 65 78 3e 20 74 6f 20 61 20 76 65 72 62  sFlex> to a verb
10b0: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 3c 73   according to <s
10c0: 54 65 6e 73 65 3e 20 61 6e 64 20 3c 73 57 68 6f  Tense> and <sWho
10d0: 3e 22 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73  >".    aSugg = s
10e0: 65 74 28 29 0a 20 20 20 20 66 6f 72 20 73 53 74  et().    for sSt
10f0: 65 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65  em in _oSpellChe
1100: 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28 73 46  cker.getLemma(sF
1110: 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20 69 66  lex):.        if
1120: 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 53   conj.hasConj(sS
1130: 74 65 6d 2c 20 73 54 65 6e 73 65 2c 20 73 57 68  tem, sTense, sWh
1140: 6f 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  o):.            
1150: 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 67  aSugg.add(conj.g
1160: 65 74 43 6f 6e 6a 28 73 53 74 65 6d 2c 20 73 54  etConj(sStem, sT
1170: 65 6e 73 65 2c 20 73 57 68 6f 29 29 0a 20 20 20  ense, sWho)).   
1180: 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20   if aSugg:.     
1190: 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f     return "|".jo
11a0: 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65  in(aSugg).    re
11b0: 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75  turn ""...def su
11c0: 67 67 56 65 72 62 49 6d 70 65 20 28 73 46 6c 65  ggVerbImpe (sFle
11d0: 78 2c 20 62 56 43 3d 46 61 6c 73 65 29 3a 0a 20  x, bVC=False):. 
11e0: 20 20 20 22 63 68 61 6e 67 65 20 3c 73 46 6c 65     "change <sFle
11f0: 78 3e 20 74 6f 20 61 20 76 65 72 62 20 61 74 20  x> to a verb at 
1200: 69 6d 70 65 72 61 74 69 76 65 20 66 6f 72 6d 22  imperative form"
1210: 0a 20 20 20 20 69 66 20 62 56 43 3a 0a 20 20 20  .    if bVC:.   
1220: 20 20 20 20 20 73 46 6c 65 78 2c 20 73 53 66 78       sFlex, sSfx
1230: 20 3d 20 73 70 6c 69 74 56 65 72 62 28 73 46 6c   = splitVerb(sFl
1240: 65 78 29 0a 20 20 20 20 61 53 75 67 67 20 3d 20  ex).    aSugg = 
1250: 73 65 74 28 29 0a 20 20 20 20 66 6f 72 20 73 53  set().    for sS
1260: 74 65 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68  tem in _oSpellCh
1270: 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28 73  ecker.getLemma(s
1280: 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20 74  Flex):.        t
1290: 54 61 67 73 20 3d 20 63 6f 6e 6a 2e 5f 67 65 74  Tags = conj._get
12a0: 54 61 67 73 28 73 53 74 65 6d 29 0a 20 20 20 20  Tags(sStem).    
12b0: 20 20 20 20 69 66 20 74 54 61 67 73 3a 0a 20 20      if tTags:.  
12c0: 20 20 20 20 20 20 20 20 20 20 69 66 20 63 6f 6e            if con
12d0: 6a 2e 5f 68 61 73 43 6f 6e 6a 57 69 74 68 54 61  j._hasConjWithTa
12e0: 67 73 28 74 54 61 67 73 2c 20 22 3a 45 22 2c 20  gs(tTags, ":E", 
12f0: 22 3a 32 73 22 29 3a 0a 20 20 20 20 20 20 20 20  ":2s"):.        
1300: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64          aSugg.ad
1310: 64 28 63 6f 6e 6a 2e 5f 67 65 74 43 6f 6e 6a 57  d(conj._getConjW
1320: 69 74 68 54 61 67 73 28 73 53 74 65 6d 2c 20 74  ithTags(sStem, t
1330: 54 61 67 73 2c 20 22 3a 45 22 2c 20 22 3a 32 73  Tags, ":E", ":2s
1340: 22 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ")).            
1350: 69 66 20 63 6f 6e 6a 2e 5f 68 61 73 43 6f 6e 6a  if conj._hasConj
1360: 57 69 74 68 54 61 67 73 28 74 54 61 67 73 2c 20  WithTags(tTags, 
1370: 22 3a 45 22 2c 20 22 3a 31 70 22 29 3a 0a 20 20  ":E", ":1p"):.  
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53                aS
1390: 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f 67 65  ugg.add(conj._ge
13a0: 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28 73 53  tConjWithTags(sS
13b0: 74 65 6d 2c 20 74 54 61 67 73 2c 20 22 3a 45 22  tem, tTags, ":E"
13c0: 2c 20 22 3a 31 70 22 29 29 0a 20 20 20 20 20 20  , ":1p")).      
13d0: 20 20 20 20 20 20 69 66 20 63 6f 6e 6a 2e 5f 68        if conj._h
13e0: 61 73 43 6f 6e 6a 57 69 74 68 54 61 67 73 28 74  asConjWithTags(t
13f0: 54 61 67 73 2c 20 22 3a 45 22 2c 20 22 3a 32 70  Tags, ":E", ":2p
1400: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
1410: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f      aSugg.add(co
1420: 6e 6a 2e 5f 67 65 74 43 6f 6e 6a 57 69 74 68 54  nj._getConjWithT
1430: 61 67 73 28 73 53 74 65 6d 2c 20 74 54 61 67 73  ags(sStem, tTags
1440: 2c 20 22 3a 45 22 2c 20 22 3a 32 70 22 29 29 0a  , ":E", ":2p")).
1450: 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20      if aSugg:.  
1460: 20 20 20 20 20 20 69 66 20 62 56 43 3a 0a 20 20        if bVC:.  
1470: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 20            aSugg 
1480: 3d 20 6c 69 73 74 28 6d 61 70 28 6c 61 6d 62 64  = list(map(lambd
1490: 61 20 73 53 75 67 3a 20 73 53 75 67 20 2b 20 73  a sSug: sSug + s
14a0: 53 66 78 2c 20 61 53 75 67 67 29 29 0a 20 20 20  Sfx, aSugg)).   
14b0: 20 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e       return "|".
14c0: 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20  join(aSugg).    
14d0: 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20  return ""...def 
14e0: 73 75 67 67 56 65 72 62 49 6e 66 69 20 28 73 46  suggVerbInfi (sF
14f0: 6c 65 78 29 3a 0a 20 20 20 20 22 72 65 74 75 72  lex):.    "retur
1500: 6e 73 20 69 6e 66 69 6e 69 74 69 76 65 20 66 6f  ns infinitive fo
1510: 72 6d 73 20 6f 66 20 3c 73 46 6c 65 78 3e 22 0a  rms of <sFlex>".
1520: 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a      return "|".j
1530: 6f 69 6e 28 5b 20 73 53 74 65 6d 20 20 66 6f 72  oin([ sStem  for
1540: 20 73 53 74 65 6d 20 69 6e 20 5f 6f 53 70 65 6c   sStem in _oSpel
1550: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d  lChecker.getLemm
1560: 61 28 73 46 6c 65 78 29 20 20 69 66 20 63 6f 6e  a(sFlex)  if con
1570: 6a 2e 69 73 56 65 72 62 28 73 53 74 65 6d 29 20  j.isVerb(sStem) 
1580: 5d 29 0a 0a 0a 5f 64 51 75 69 45 73 74 20 3d 20  ])..._dQuiEst = 
1590: 7b 20 22 6a 65 22 3a 20 22 3a 31 73 22 2c 20 22  { "je": ":1s", "
15a0: 6a e2 80 99 22 3a 20 22 3a 31 73 22 2c 20 22 6a  j...": ":1s", "j
15b0: e2 80 99 65 6e 22 3a 20 22 3a 31 73 22 2c 20 22  ...en": ":1s", "
15c0: 6a e2 80 99 79 22 3a 20 22 3a 31 73 22 2c 20 5c  j...y": ":1s", \
15d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 22 74  .             "t
15e0: 75 22 3a 20 22 3a 32 73 22 2c 20 22 69 6c 22 3a  u": ":2s", "il":
15f0: 20 22 3a 33 73 22 2c 20 22 6f 6e 22 3a 20 22 3a   ":3s", "on": ":
1600: 33 73 22 2c 20 22 65 6c 6c 65 22 3a 20 22 3a 33  3s", "elle": ":3
1610: 73 22 2c 20 22 6e 6f 75 73 22 3a 20 22 3a 31 70  s", "nous": ":1p
1620: 22 2c 20 22 76 6f 75 73 22 3a 20 22 3a 32 70 22  ", "vous": ":2p"
1630: 2c 20 22 69 6c 73 22 3a 20 22 3a 33 70 22 2c 20  , "ils": ":3p", 
1640: 22 65 6c 6c 65 73 22 3a 20 22 3a 33 70 22 20 7d  "elles": ":3p" }
1650: 0a 5f 6c 49 6e 64 69 63 61 74 69 66 20 3d 20 5b  ._lIndicatif = [
1660: 22 3a 49 70 22 2c 20 22 3a 49 71 22 2c 20 22 3a  ":Ip", ":Iq", ":
1670: 49 73 22 2c 20 22 3a 49 66 22 5d 0a 5f 6c 53 75  Is", ":If"]._lSu
1680: 62 6a 6f 6e 63 74 69 66 20 3d 20 5b 22 3a 53 70  bjonctif = [":Sp
1690: 22 2c 20 22 3a 53 71 22 5d 0a 0a 64 65 66 20 73  ", ":Sq"]..def s
16a0: 75 67 67 56 65 72 62 4d 6f 64 65 20 28 73 46 6c  uggVerbMode (sFl
16b0: 65 78 2c 20 63 4d 6f 64 65 2c 20 73 53 75 6a 29  ex, cMode, sSuj)
16c0: 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20 6f  :.    "returns o
16d0: 74 68 65 72 20 63 6f 6e 6a 75 67 61 74 69 6f 6e  ther conjugation
16e0: 73 20 6f 66 20 3c 73 46 6c 65 78 3e 20 61 63 63  s of <sFlex> acc
16f0: 6f 6e 64 69 6e 67 20 74 6f 20 3c 63 4d 6f 64 65  onding to <cMode
1700: 3e 20 61 6e 64 20 3c 73 53 75 6a 3e 22 0a 20 20  > and <sSuj>".  
1710: 20 20 69 66 20 63 4d 6f 64 65 20 3d 3d 20 22 3a    if cMode == ":
1720: 49 22 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 64  I":.        lMod
1730: 65 20 3d 20 5f 6c 49 6e 64 69 63 61 74 69 66 0a  e = _lIndicatif.
1740: 20 20 20 20 65 6c 69 66 20 63 4d 6f 64 65 20 3d      elif cMode =
1750: 3d 20 22 3a 53 22 3a 0a 20 20 20 20 20 20 20 20  = ":S":.        
1760: 6c 4d 6f 64 65 20 3d 20 5f 6c 53 75 62 6a 6f 6e  lMode = _lSubjon
1770: 63 74 69 66 0a 20 20 20 20 65 6c 69 66 20 63 4d  ctif.    elif cM
1780: 6f 64 65 2e 73 74 61 72 74 73 77 69 74 68 28 28  ode.startswith((
1790: 22 3a 49 22 2c 20 22 3a 53 22 29 29 3a 0a 20 20  ":I", ":S")):.  
17a0: 20 20 20 20 20 20 6c 4d 6f 64 65 20 3d 20 5b 63        lMode = [c
17b0: 4d 6f 64 65 5d 0a 20 20 20 20 65 6c 73 65 3a 0a  Mode].    else:.
17c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
17d0: 22 0a 20 20 20 20 73 57 68 6f 20 3d 20 5f 64 51  ".    sWho = _dQ
17e0: 75 69 45 73 74 2e 67 65 74 28 73 53 75 6a 2e 6c  uiEst.get(sSuj.l
17f0: 6f 77 65 72 28 29 2c 20 4e 6f 6e 65 29 0a 20 20  ower(), None).  
1800: 20 20 69 66 20 6e 6f 74 20 73 57 68 6f 3a 0a 20    if not sWho:. 
1810: 20 20 20 20 20 20 20 69 66 20 73 53 75 6a 5b 30         if sSuj[0
1820: 3a 31 5d 2e 69 73 6c 6f 77 65 72 28 29 3a 20 23  :1].islower(): #
1830: 20 70 61 73 20 75 6e 20 70 72 6f 6e 6f 6d 2c 20   pas un pronom, 
1840: 6e 69 20 75 6e 20 6e 6f 6d 20 70 72 6f 70 72 65  ni un nom propre
1850: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
1860: 75 72 6e 20 22 22 0a 20 20 20 20 20 20 20 20 73  urn "".        s
1870: 57 68 6f 20 3d 20 22 3a 33 73 22 0a 20 20 20 20  Who = ":3s".    
1880: 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20  aSugg = set().  
1890: 20 20 66 6f 72 20 73 53 74 65 6d 20 69 6e 20 5f    for sStem in _
18a0: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
18b0: 74 4c 65 6d 6d 61 28 73 46 6c 65 78 29 3a 0a 20  tLemma(sFlex):. 
18c0: 20 20 20 20 20 20 20 74 54 61 67 73 20 3d 20 63         tTags = c
18d0: 6f 6e 6a 2e 5f 67 65 74 54 61 67 73 28 73 53 74  onj._getTags(sSt
18e0: 65 6d 29 0a 20 20 20 20 20 20 20 20 69 66 20 74  em).        if t
18f0: 54 61 67 73 3a 0a 20 20 20 20 20 20 20 20 20 20  Tags:.          
1900: 20 20 66 6f 72 20 73 54 65 6e 73 65 20 69 6e 20    for sTense in 
1910: 6c 4d 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20  lMode:.         
1920: 20 20 20 20 20 20 20 69 66 20 63 6f 6e 6a 2e 5f         if conj._
1930: 68 61 73 43 6f 6e 6a 57 69 74 68 54 61 67 73 28  hasConjWithTags(
1940: 74 54 61 67 73 2c 20 73 54 65 6e 73 65 2c 20 73  tTags, sTense, s
1950: 57 68 6f 29 3a 0a 20 20 20 20 20 20 20 20 20 20  Who):.          
1960: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
1970: 61 64 64 28 63 6f 6e 6a 2e 5f 67 65 74 43 6f 6e  add(conj._getCon
1980: 6a 57 69 74 68 54 61 67 73 28 73 53 74 65 6d 2c  jWithTags(sStem,
1990: 20 74 54 61 67 73 2c 20 73 54 65 6e 73 65 2c 20   tTags, sTense, 
19a0: 73 57 68 6f 29 29 0a 20 20 20 20 69 66 20 61 53  sWho)).    if aS
19b0: 75 67 67 3a 0a 20 20 20 20 20 20 20 20 72 65 74  ugg:.        ret
19c0: 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75  urn "|".join(aSu
19d0: 67 67 29 0a 20 20 20 20 72 65 74 75 72 6e 20 22  gg).    return "
19e0: 22 0a 0a 0a 23 23 20 4e 6f 75 6e 73 20 61 6e 64  "...## Nouns and
19f0: 20 61 64 6a 65 63 74 69 76 65 73 0a 0a 64 65 66   adjectives..def
1a00: 20 73 75 67 67 50 6c 75 72 20 28 73 46 6c 65 78   suggPlur (sFlex
1a10: 2c 20 73 57 6f 72 64 54 6f 41 67 72 65 65 3d 4e  , sWordToAgree=N
1a20: 6f 6e 65 2c 20 62 53 65 6c 66 53 75 67 67 3d 46  one, bSelfSugg=F
1a30: 61 6c 73 65 29 3a 0a 20 20 20 20 22 72 65 74 75  alse):.    "retu
1a40: 72 6e 73 20 70 6c 75 72 61 6c 20 66 6f 72 6d 73  rns plural forms
1a50: 20 61 73 73 75 6d 69 6e 67 20 73 46 6c 65 78 20   assuming sFlex 
1a60: 69 73 20 73 69 6e 67 75 6c 61 72 22 0a 20 20 20  is singular".   
1a70: 20 69 66 20 73 57 6f 72 64 54 6f 41 67 72 65 65   if sWordToAgree
1a80: 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72 70 68  :.        lMorph
1a90: 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65   = _oSpellChecke
1aa0: 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c 65 78  r.getMorph(sFlex
1ab0: 29 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74  ).        if not
1ac0: 20 6c 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   lMorph:.       
1ad0: 20 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 20       return "". 
1ae0: 20 20 20 20 20 20 20 73 47 65 6e 64 65 72 20 3d         sGender =
1af0: 20 63 72 2e 67 65 74 47 65 6e 64 65 72 28 6c 4d   cr.getGender(lM
1b00: 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20 69 66  orph).        if
1b10: 20 73 47 65 6e 64 65 72 20 3d 3d 20 22 3a 6d 22   sGender == ":m"
1b20: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  :.            re
1b30: 74 75 72 6e 20 73 75 67 67 4d 61 73 50 6c 75 72  turn suggMasPlur
1b40: 28 73 46 6c 65 78 29 0a 20 20 20 20 20 20 20 20  (sFlex).        
1b50: 69 66 20 73 47 65 6e 64 65 72 20 3d 3d 20 22 3a  if sGender == ":
1b60: 66 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  f":.            
1b70: 72 65 74 75 72 6e 20 73 75 67 67 46 65 6d 50 6c  return suggFemPl
1b80: 75 72 28 73 46 6c 65 78 29 0a 20 20 20 20 61 53  ur(sFlex).    aS
1b90: 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20 20  ugg = set().    
1ba0: 69 66 20 73 46 6c 65 78 2e 65 6e 64 73 77 69 74  if sFlex.endswit
1bb0: 68 28 22 6c 22 29 3a 0a 20 20 20 20 20 20 20 20  h("l"):.        
1bc0: 69 66 20 73 46 6c 65 78 2e 65 6e 64 73 77 69 74  if sFlex.endswit
1bd0: 68 28 22 61 6c 22 29 20 61 6e 64 20 6c 65 6e 28  h("al") and len(
1be0: 73 46 6c 65 78 29 20 3e 20 32 20 61 6e 64 20 5f  sFlex) > 2 and _
1bf0: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73  oSpellChecker.is
1c00: 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d 31 5d  Valid(sFlex[:-1]
1c10: 2b 22 75 78 22 29 3a 0a 20 20 20 20 20 20 20 20  +"ux"):.        
1c20: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 46      aSugg.add(sF
1c30: 6c 65 78 5b 3a 2d 31 5d 2b 22 75 78 22 29 0a 20  lex[:-1]+"ux"). 
1c40: 20 20 20 20 20 20 20 69 66 20 73 46 6c 65 78 2e         if sFlex.
1c50: 65 6e 64 73 77 69 74 68 28 22 61 69 6c 22 29 20  endswith("ail") 
1c60: 61 6e 64 20 6c 65 6e 28 73 46 6c 65 78 29 20 3e  and len(sFlex) >
1c70: 20 33 20 61 6e 64 20 5f 6f 53 70 65 6c 6c 43 68   3 and _oSpellCh
1c80: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46  ecker.isValid(sF
1c90: 6c 65 78 5b 3a 2d 32 5d 2b 22 75 78 22 29 3a 0a  lex[:-2]+"ux"):.
1ca0: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
1cb0: 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32 5d  g.add(sFlex[:-2]
1cc0: 2b 22 75 78 22 29 0a 20 20 20 20 69 66 20 73 46  +"ux").    if sF
1cd0: 6c 65 78 2e 65 6e 64 73 77 69 74 68 28 22 4c 22  lex.endswith("L"
1ce0: 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 46  ):.        if sF
1cf0: 6c 65 78 2e 65 6e 64 73 77 69 74 68 28 22 41 4c  lex.endswith("AL
1d00: 22 29 20 61 6e 64 20 6c 65 6e 28 73 46 6c 65 78  ") and len(sFlex
1d10: 29 20 3e 20 32 20 61 6e 64 20 5f 6f 53 70 65 6c  ) > 2 and _oSpel
1d20: 6c 43 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64  lChecker.isValid
1d30: 28 73 46 6c 65 78 5b 3a 2d 31 5d 2b 22 55 58 22  (sFlex[:-1]+"UX"
1d40: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61  ):.            a
1d50: 53 75 67 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a  Sugg.add(sFlex[:
1d60: 2d 31 5d 2b 22 55 58 22 29 0a 20 20 20 20 20 20  -1]+"UX").      
1d70: 20 20 69 66 20 73 46 6c 65 78 2e 65 6e 64 73 77    if sFlex.endsw
1d80: 69 74 68 28 22 41 49 4c 22 29 20 61 6e 64 20 6c  ith("AIL") and l
1d90: 65 6e 28 73 46 6c 65 78 29 20 3e 20 33 20 61 6e  en(sFlex) > 3 an
1da0: 64 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  d _oSpellChecker
1db0: 2e 69 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a  .isValid(sFlex[:
1dc0: 2d 32 5d 2b 22 55 58 22 29 3a 0a 20 20 20 20 20  -2]+"UX"):.     
1dd0: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
1de0: 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22 55 58 22  (sFlex[:-2]+"UX"
1df0: 29 0a 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c  ).    if _oSpell
1e00: 43 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28  Checker.isValid(
1e10: 73 46 6c 65 78 2b 22 73 22 29 3a 0a 20 20 20 20  sFlex+"s"):.    
1e20: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 46      aSugg.add(sF
1e30: 6c 65 78 2b 22 73 22 29 0a 20 20 20 20 69 66 20  lex+"s").    if 
1e40: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69  _oSpellChecker.i
1e50: 73 56 61 6c 69 64 28 73 46 6c 65 78 2b 22 78 22  sValid(sFlex+"x"
1e60: 29 3a 0a 20 20 20 20 20 20 20 20 61 53 75 67 67  ):.        aSugg
1e70: 2e 61 64 64 28 73 46 6c 65 78 2b 22 78 22 29 0a  .add(sFlex+"x").
1e80: 20 20 20 20 69 66 20 6d 66 73 70 2e 68 61 73 4d      if mfsp.hasM
1e90: 69 73 63 50 6c 75 72 61 6c 28 73 46 6c 65 78 29  iscPlural(sFlex)
1ea0: 3a 0a 20 20 20 20 20 20 20 20 61 53 75 67 67 2e  :.        aSugg.
1eb0: 75 70 64 61 74 65 28 6d 66 73 70 2e 67 65 74 4d  update(mfsp.getM
1ec0: 69 73 63 50 6c 75 72 61 6c 28 73 46 6c 65 78 29  iscPlural(sFlex)
1ed0: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 61 53 75  ).    if not aSu
1ee0: 67 67 20 61 6e 64 20 62 53 65 6c 66 53 75 67 67  gg and bSelfSugg
1ef0: 20 61 6e 64 20 73 46 6c 65 78 2e 65 6e 64 73 77   and sFlex.endsw
1f00: 69 74 68 28 28 22 73 22 2c 20 22 78 22 2c 20 22  ith(("s", "x", "
1f10: 53 22 2c 20 22 58 22 29 29 3a 0a 20 20 20 20 20  S", "X")):.     
1f20: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 46 6c     aSugg.add(sFl
1f30: 65 78 29 0a 20 20 20 20 69 66 20 61 53 75 67 67  ex).    if aSugg
1f40: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
1f50: 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29   "|".join(aSugg)
1f60: 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a  .    return ""..
1f70: 0a 64 65 66 20 73 75 67 67 53 69 6e 67 20 28 73  .def suggSing (s
1f80: 46 6c 65 78 2c 20 62 53 65 6c 66 53 75 67 67 3d  Flex, bSelfSugg=
1f90: 54 72 75 65 29 3a 0a 20 20 20 20 22 72 65 74 75  True):.    "retu
1fa0: 72 6e 73 20 73 69 6e 67 75 6c 61 72 20 66 6f 72  rns singular for
1fb0: 6d 73 20 61 73 73 75 6d 69 6e 67 20 73 46 6c 65  ms assuming sFle
1fc0: 78 20 69 73 20 70 6c 75 72 61 6c 22 0a 20 20 20  x is plural".   
1fd0: 20 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20   aSugg = set(). 
1fe0: 20 20 20 69 66 20 73 46 6c 65 78 2e 65 6e 64 73     if sFlex.ends
1ff0: 77 69 74 68 28 22 75 78 22 29 3a 0a 20 20 20 20  with("ux"):.    
2000: 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43 68      if _oSpellCh
2010: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46  ecker.isValid(sF
2020: 6c 65 78 5b 3a 2d 32 5d 2b 22 6c 22 29 3a 0a 20  lex[:-2]+"l"):. 
2030: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
2040: 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b  .add(sFlex[:-2]+
2050: 22 6c 22 29 0a 20 20 20 20 20 20 20 20 69 66 20  "l").        if 
2060: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69  _oSpellChecker.i
2070: 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d 32  sValid(sFlex[:-2
2080: 5d 2b 22 69 6c 22 29 3a 0a 20 20 20 20 20 20 20  ]+"il"):.       
2090: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73       aSugg.add(s
20a0: 46 6c 65 78 5b 3a 2d 32 5d 2b 22 69 6c 22 29 0a  Flex[:-2]+"il").
20b0: 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65 6e 64      if sFlex.end
20c0: 73 77 69 74 68 28 22 55 58 22 29 3a 0a 20 20 20  swith("UX"):.   
20d0: 20 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43       if _oSpellC
20e0: 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73  hecker.isValid(s
20f0: 46 6c 65 78 5b 3a 2d 32 5d 2b 22 4c 22 29 3a 0a  Flex[:-2]+"L"):.
2100: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
2110: 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32 5d  g.add(sFlex[:-2]
2120: 2b 22 4c 22 29 0a 20 20 20 20 20 20 20 20 69 66  +"L").        if
2130: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
2140: 69 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d  isValid(sFlex[:-
2150: 32 5d 2b 22 49 4c 22 29 3a 0a 20 20 20 20 20 20  2]+"IL"):.      
2160: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2170: 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22 49 4c 22 29  sFlex[:-2]+"IL")
2180: 0a 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65 6e  .    if sFlex.en
2190: 64 73 77 69 74 68 28 28 22 73 22 2c 20 22 78 22  dswith(("s", "x"
21a0: 2c 20 22 53 22 2c 20 22 58 22 29 29 20 61 6e 64  , "S", "X")) and
21b0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
21c0: 69 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d  isValid(sFlex[:-
21d0: 31 5d 29 3a 0a 20 20 20 20 20 20 20 20 61 53 75  1]):.        aSu
21e0: 67 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 31  gg.add(sFlex[:-1
21f0: 5d 29 0a 20 20 20 20 69 66 20 62 53 65 6c 66 53  ]).    if bSelfS
2200: 75 67 67 20 61 6e 64 20 6e 6f 74 20 61 53 75 67  ugg and not aSug
2210: 67 3a 0a 20 20 20 20 20 20 20 20 61 53 75 67 67  g:.        aSugg
2220: 2e 61 64 64 28 73 46 6c 65 78 29 0a 20 20 20 20  .add(sFlex).    
2230: 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20  if aSugg:.      
2240: 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69    return "|".joi
2250: 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65 74  n(aSugg).    ret
2260: 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75 67  urn ""...def sug
2270: 67 4d 61 73 53 69 6e 67 20 28 73 46 6c 65 78 2c  gMasSing (sFlex,
2280: 20 62 53 75 67 67 53 69 6d 69 6c 3d 46 61 6c 73   bSuggSimil=Fals
2290: 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73  e):.    "returns
22a0: 20 6d 61 73 63 75 6c 69 6e 65 20 73 69 6e 67 75   masculine singu
22b0: 6c 61 72 20 66 6f 72 6d 73 22 0a 20 20 20 20 61  lar forms".    a
22c0: 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20  Sugg = set().   
22d0: 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f   for sMorph in _
22e0: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
22f0: 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20  tMorph(sFlex):. 
2300: 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 22 3a         if not ":
2310: 56 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20  V" in sMorph:.  
2320: 20 20 20 20 20 20 20 20 20 20 23 20 6e 6f 74 20            # not 
2330: 61 20 76 65 72 62 0a 20 20 20 20 20 20 20 20 20  a verb.         
2340: 20 20 20 69 66 20 22 3a 6d 22 20 69 6e 20 73 4d     if ":m" in sM
2350: 6f 72 70 68 20 6f 72 20 22 3a 65 22 20 69 6e 20  orph or ":e" in 
2360: 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20  sMorph:.        
2370: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64          aSugg.ad
2380: 64 28 73 75 67 67 53 69 6e 67 28 73 46 6c 65 78  d(suggSing(sFlex
2390: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65  )).            e
23a0: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
23b0: 20 20 20 20 20 73 53 74 65 6d 20 3d 20 63 72 2e       sStem = cr.
23c0: 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28  getLemmaOfMorph(
23d0: 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20  sMorph).        
23e0: 20 20 20 20 20 20 20 20 69 66 20 6d 66 73 70 2e          if mfsp.
23f0: 69 73 4d 61 73 46 6f 72 6d 28 73 53 74 65 6d 29  isMasForm(sStem)
2400: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2410: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2420: 73 53 74 65 6d 29 0a 20 20 20 20 20 20 20 20 65  sStem).        e
2430: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
2440: 20 23 20 61 20 76 65 72 62 0a 20 20 20 20 20 20   # a verb.      
2450: 20 20 20 20 20 20 73 56 65 72 62 20 3d 20 63 72        sVerb = cr
2460: 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68  .getLemmaOfMorph
2470: 28 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20  (sMorph).       
2480: 20 20 20 20 20 69 66 20 63 6f 6e 6a 2e 68 61 73       if conj.has
2490: 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50 51  Conj(sVerb, ":PQ
24a0: 22 2c 20 22 3a 51 31 22 29 20 61 6e 64 20 63 6f  ", ":Q1") and co
24b0: 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65 72 62  nj.hasConj(sVerb
24c0: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33 22 29 3a  , ":PQ", ":Q3"):
24d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
24e0: 20 23 20 57 65 20 61 6c 73 6f 20 63 68 65 63 6b   # We also check
24f0: 20 69 66 20 74 68 65 20 76 65 72 62 20 68 61 73   if the verb has
2500: 20 61 20 66 65 6d 69 6e 69 6e 65 20 66 6f 72 6d   a feminine form
2510: 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ..              
2520: 20 20 23 20 49 66 20 6e 6f 74 2c 20 77 65 20 63    # If not, we c
2530: 6f 6e 73 69 64 65 72 20 69 74 e2 80 99 73 20 62  onsider it...s b
2540: 65 74 74 65 72 20 74 6f 20 6e 6f 74 20 73 75 67  etter to not sug
2550: 67 65 73 74 20 74 68 65 20 6d 61 73 63 75 6c 69  gest the masculi
2560: 6e 65 20 6f 6e 65 2c 20 61 73 20 69 74 20 63 61  ne one, as it ca
2570: 6e 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 20  n be considered 
2580: 69 6e 76 61 72 69 61 62 6c 65 2e 0a 20 20 20 20  invariable..    
2590: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
25a0: 67 2e 61 64 64 28 63 6f 6e 6a 2e 67 65 74 43 6f  g.add(conj.getCo
25b0: 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c  nj(sVerb, ":PQ",
25c0: 20 22 3a 51 31 22 29 29 0a 20 20 20 20 69 66 20   ":Q1")).    if 
25d0: 62 53 75 67 67 53 69 6d 69 6c 3a 0a 20 20 20 20  bSuggSimil:.    
25e0: 20 20 20 20 66 6f 72 20 65 20 69 6e 20 70 68 6f      for e in pho
25f0: 6e 65 74 2e 73 65 6c 65 63 74 53 69 6d 69 6c 28  net.selectSimil(
2600: 73 46 6c 65 78 2c 20 22 3a 6d 3a 5b 73 69 5d 22  sFlex, ":m:[si]"
2610: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61  ):.            a
2620: 53 75 67 67 2e 61 64 64 28 65 29 0a 20 20 20 20  Sugg.add(e).    
2630: 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20  if aSugg:.      
2640: 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69    return "|".joi
2650: 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65 74  n(aSugg).    ret
2660: 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75 67  urn ""...def sug
2670: 67 4d 61 73 50 6c 75 72 20 28 73 46 6c 65 78 2c  gMasPlur (sFlex,
2680: 20 62 53 75 67 67 53 69 6d 69 6c 3d 46 61 6c 73   bSuggSimil=Fals
2690: 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73  e):.    "returns
26a0: 20 6d 61 73 63 75 6c 69 6e 65 20 70 6c 75 72 61   masculine plura
26b0: 6c 20 66 6f 72 6d 73 22 0a 20 20 20 20 61 53 75  l forms".    aSu
26c0: 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20 20 66  gg = set().    f
26d0: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
26e0: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
26f0: 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20  orph(sFlex):.   
2700: 20 20 20 20 20 69 66 20 6e 6f 74 20 22 3a 56 22       if not ":V"
2710: 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20   in sMorph:.    
2720: 20 20 20 20 20 20 20 20 23 20 6e 6f 74 20 61 20          # not a 
2730: 76 65 72 62 0a 20 20 20 20 20 20 20 20 20 20 20  verb.           
2740: 20 69 66 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72   if ":m" in sMor
2750: 70 68 20 6f 72 20 22 3a 65 22 20 69 6e 20 73 4d  ph or ":e" in sM
2760: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
2770: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2780: 73 75 67 67 50 6c 75 72 28 73 46 6c 65 78 29 29  suggPlur(sFlex))
2790: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
27a0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
27b0: 20 20 20 73 53 74 65 6d 20 3d 20 63 72 2e 67 65     sStem = cr.ge
27c0: 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d  tLemmaOfMorph(sM
27d0: 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20  orph).          
27e0: 20 20 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73        if mfsp.is
27f0: 4d 61 73 46 6f 72 6d 28 73 53 74 65 6d 29 3a 0a  MasForm(sStem):.
2800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2810: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75      aSugg.add(su
2820: 67 67 50 6c 75 72 28 73 53 74 65 6d 29 29 0a 20  ggPlur(sStem)). 
2830: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2840: 20 20 20 20 20 20 20 20 20 23 20 61 20 76 65 72           # a ver
2850: 62 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 56  b.            sV
2860: 65 72 62 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d  erb = cr.getLemm
2870: 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29  aOfMorph(sMorph)
2880: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
2890: 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65  conj.hasConj(sVe
28a0: 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 32 22  rb, ":PQ", ":Q2"
28b0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
28c0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e     aSugg.add(con
28d0: 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62 2c  j.getConj(sVerb,
28e0: 20 22 3a 50 51 22 2c 20 22 3a 51 32 22 29 29 0a   ":PQ", ":Q2")).
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66              elif
2900: 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56   conj.hasConj(sV
2910: 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31  erb, ":PQ", ":Q1
2920: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
2930: 20 20 20 20 73 53 75 67 67 20 3d 20 63 6f 6e 6a      sSugg = conj
2940: 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62 2c 20  .getConj(sVerb, 
2950: 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 0a 20 20  ":PQ", ":Q1").  
2960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
2970: 69 74 20 69 73 20 6e 65 63 65 73 73 61 72 79 20  it is necessary 
2980: 74 6f 20 66 69 6c 74 65 72 20 74 68 65 73 65 20  to filter these 
2990: 66 6c 65 78 69 6f 6e 73 2c 20 6c 69 6b 65 20 e2  flexions, like .
29a0: 80 9c 73 75 63 63 c3 a9 64 c3 a9 e2 80 9d 20 6f  ..succ..d..... o
29b0: 72 20 e2 80 9c 61 67 69 e2 80 9d 20 74 68 61 74  r ...agi... that
29c0: 20 61 72 65 20 6e 6f 74 20 6d 61 73 63 75 6c 69   are not masculi
29d0: 6e 65 20 70 6c 75 72 61 6c 2e 0a 20 20 20 20 20  ne plural..     
29e0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73 53             if sS
29f0: 75 67 67 2e 65 6e 64 73 77 69 74 68 28 22 73 22  ugg.endswith("s"
2a00: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
2a10: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
2a20: 28 73 53 75 67 67 29 0a 20 20 20 20 69 66 20 62  (sSugg).    if b
2a30: 53 75 67 67 53 69 6d 69 6c 3a 0a 20 20 20 20 20  SuggSimil:.     
2a40: 20 20 20 66 6f 72 20 65 20 69 6e 20 70 68 6f 6e     for e in phon
2a50: 65 74 2e 73 65 6c 65 63 74 53 69 6d 69 6c 28 73  et.selectSimil(s
2a60: 46 6c 65 78 2c 20 22 3a 6d 3a 5b 70 69 5d 22 29  Flex, ":m:[pi]")
2a70: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53  :.            aS
2a80: 75 67 67 2e 61 64 64 28 65 29 0a 20 20 20 20 69  ugg.add(e).    i
2a90: 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20  f aSugg:.       
2aa0: 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e   return "|".join
2ab0: 28 61 53 75 67 67 29 0a 20 20 20 20 72 65 74 75  (aSugg).    retu
2ac0: 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75 67 67  rn ""...def sugg
2ad0: 46 65 6d 53 69 6e 67 20 28 73 46 6c 65 78 2c 20  FemSing (sFlex, 
2ae0: 62 53 75 67 67 53 69 6d 69 6c 3d 46 61 6c 73 65  bSuggSimil=False
2af0: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20  ):.    "returns 
2b00: 66 65 6d 69 6e 69 6e 65 20 73 69 6e 67 75 6c 61  feminine singula
2b10: 72 20 66 6f 72 6d 73 22 0a 20 20 20 20 61 53 75  r forms".    aSu
2b20: 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20 20 66  gg = set().    f
2b30: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
2b40: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
2b50: 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20  orph(sFlex):.   
2b60: 20 20 20 20 20 69 66 20 6e 6f 74 20 22 3a 56 22       if not ":V"
2b70: 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20   in sMorph:.    
2b80: 20 20 20 20 20 20 20 20 23 20 6e 6f 74 20 61 20          # not a 
2b90: 76 65 72 62 0a 20 20 20 20 20 20 20 20 20 20 20  verb.           
2ba0: 20 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72   if ":f" in sMor
2bb0: 70 68 20 6f 72 20 22 3a 65 22 20 69 6e 20 73 4d  ph or ":e" in sM
2bc0: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
2bd0: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2be0: 73 75 67 67 53 69 6e 67 28 73 46 6c 65 78 29 29  suggSing(sFlex))
2bf0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
2c00: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
2c10: 20 20 20 73 53 74 65 6d 20 3d 20 63 72 2e 67 65     sStem = cr.ge
2c20: 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d  tLemmaOfMorph(sM
2c30: 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20  orph).          
2c40: 20 20 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73        if mfsp.is
2c50: 4d 61 73 46 6f 72 6d 28 73 53 74 65 6d 29 3a 0a  MasForm(sStem):.
2c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c70: 20 20 20 20 61 53 75 67 67 2e 75 70 64 61 74 65      aSugg.update
2c80: 28 6d 66 73 70 2e 67 65 74 46 65 6d 46 6f 72 6d  (mfsp.getFemForm
2c90: 28 73 53 74 65 6d 2c 20 46 61 6c 73 65 29 29 0a  (sStem, False)).
2ca0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
2cb0: 20 20 20 20 20 20 20 20 20 20 23 20 61 20 76 65            # a ve
2cc0: 72 62 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  rb.            s
2cd0: 56 65 72 62 20 3d 20 63 72 2e 67 65 74 4c 65 6d  Verb = cr.getLem
2ce0: 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68  maOfMorph(sMorph
2cf0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ).            if
2d00: 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56   conj.hasConj(sV
2d10: 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33  erb, ":PQ", ":Q3
2d20: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
2d30: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f      aSugg.add(co
2d40: 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62  nj.getConj(sVerb
2d50: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33 22 29 29  , ":PQ", ":Q3"))
2d60: 0a 20 20 20 20 69 66 20 62 53 75 67 67 53 69 6d  .    if bSuggSim
2d70: 69 6c 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20  il:.        for 
2d80: 65 20 69 6e 20 70 68 6f 6e 65 74 2e 73 65 6c 65  e in phonet.sele
2d90: 63 74 53 69 6d 69 6c 28 73 46 6c 65 78 2c 20 22  ctSimil(sFlex, "
2da0: 3a 66 3a 5b 73 69 5d 22 29 3a 0a 20 20 20 20 20  :f:[si]"):.     
2db0: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
2dc0: 28 65 29 0a 20 20 20 20 69 66 20 61 53 75 67 67  (e).    if aSugg
2dd0: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
2de0: 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29   "|".join(aSugg)
2df0: 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a  .    return ""..
2e00: 0a 64 65 66 20 73 75 67 67 46 65 6d 50 6c 75 72  .def suggFemPlur
2e10: 20 28 73 46 6c 65 78 2c 20 62 53 75 67 67 53 69   (sFlex, bSuggSi
2e20: 6d 69 6c 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20  mil=False):.    
2e30: 22 72 65 74 75 72 6e 73 20 66 65 6d 69 6e 69 6e  "returns feminin
2e40: 65 20 70 6c 75 72 61 6c 20 66 6f 72 6d 73 22 0a  e plural forms".
2e50: 20 20 20 20 61 53 75 67 67 20 3d 20 73 65 74 28      aSugg = set(
2e60: 29 0a 20 20 20 20 66 6f 72 20 73 4d 6f 72 70 68  ).    for sMorph
2e70: 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b   in _oSpellCheck
2e80: 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c 65  er.getMorph(sFle
2e90: 78 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e  x):.        if n
2ea0: 6f 74 20 22 3a 56 22 20 69 6e 20 73 4d 6f 72 70  ot ":V" in sMorp
2eb0: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  h:.            #
2ec0: 20 6e 6f 74 20 61 20 76 65 72 62 0a 20 20 20 20   not a verb.    
2ed0: 20 20 20 20 20 20 20 20 69 66 20 22 3a 66 22 20          if ":f" 
2ee0: 69 6e 20 73 4d 6f 72 70 68 20 6f 72 20 22 3a 65  in sMorph or ":e
2ef0: 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20  " in sMorph:.   
2f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75               aSu
2f10: 67 67 2e 61 64 64 28 73 75 67 67 50 6c 75 72 28  gg.add(suggPlur(
2f20: 73 46 6c 65 78 29 29 0a 20 20 20 20 20 20 20 20  sFlex)).        
2f30: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2f40: 20 20 20 20 20 20 20 20 20 20 73 53 74 65 6d 20            sStem 
2f50: 3d 20 63 72 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d  = cr.getLemmaOfM
2f60: 6f 72 70 68 28 73 4d 6f 72 70 68 29 0a 20 20 20  orph(sMorph).   
2f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
2f80: 6d 66 73 70 2e 69 73 4d 61 73 46 6f 72 6d 28 73  mfsp.isMasForm(s
2f90: 53 74 65 6d 29 3a 0a 20 20 20 20 20 20 20 20 20  Stem):.         
2fa0: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
2fb0: 2e 75 70 64 61 74 65 28 6d 66 73 70 2e 67 65 74  .update(mfsp.get
2fc0: 46 65 6d 46 6f 72 6d 28 73 53 74 65 6d 2c 20 54  FemForm(sStem, T
2fd0: 72 75 65 29 29 0a 20 20 20 20 20 20 20 20 65 6c  rue)).        el
2fe0: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
2ff0: 23 20 61 20 76 65 72 62 0a 20 20 20 20 20 20 20  # a verb.       
3000: 20 20 20 20 20 73 56 65 72 62 20 3d 20 63 72 2e       sVerb = cr.
3010: 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28  getLemmaOfMorph(
3020: 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20  sMorph).        
3030: 20 20 20 20 69 66 20 63 6f 6e 6a 2e 68 61 73 43      if conj.hasC
3040: 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22  onj(sVerb, ":PQ"
3050: 2c 20 22 3a 51 34 22 29 3a 0a 20 20 20 20 20 20  , ":Q4"):.      
3060: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
3070: 61 64 64 28 63 6f 6e 6a 2e 67 65 74 43 6f 6e 6a  add(conj.getConj
3080: 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22  (sVerb, ":PQ", "
3090: 3a 51 34 22 29 29 0a 20 20 20 20 69 66 20 62 53  :Q4")).    if bS
30a0: 75 67 67 53 69 6d 69 6c 3a 0a 20 20 20 20 20 20  uggSimil:.      
30b0: 20 20 66 6f 72 20 65 20 69 6e 20 70 68 6f 6e 65    for e in phone
30c0: 74 2e 73 65 6c 65 63 74 53 69 6d 69 6c 28 73 46  t.selectSimil(sF
30d0: 6c 65 78 2c 20 22 3a 66 3a 5b 70 69 5d 22 29 3a  lex, ":f:[pi]"):
30e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75  .            aSu
30f0: 67 67 2e 61 64 64 28 65 29 0a 20 20 20 20 69 66  gg.add(e).    if
3100: 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20   aSugg:.        
3110: 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28  return "|".join(
3120: 61 53 75 67 67 29 0a 20 20 20 20 72 65 74 75 72  aSugg).    retur
3130: 6e 20 22 22 0a 0a 0a 64 65 66 20 68 61 73 46 65  n ""...def hasFe
3140: 6d 46 6f 72 6d 20 28 73 46 6c 65 78 29 3a 0a 20  mForm (sFlex):. 
3150: 20 20 20 22 72 65 74 75 72 6e 20 54 72 75 65 20     "return True 
3160: 69 66 20 74 68 65 72 65 20 69 73 20 61 20 66 65  if there is a fe
3170: 6d 69 6e 69 6e 65 20 66 6f 72 6d 20 6f 66 20 3c  minine form of <
3180: 73 46 6c 65 78 3e 22 0a 20 20 20 20 66 6f 72 20  sFlex>".    for 
3190: 73 53 74 65 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c  sStem in _oSpell
31a0: 43 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61  Checker.getLemma
31b0: 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20  (sFlex):.       
31c0: 20 69 66 20 6d 66 73 70 2e 69 73 4d 61 73 46 6f   if mfsp.isMasFo
31d0: 72 6d 28 73 53 74 65 6d 29 20 6f 72 20 63 6f 6e  rm(sStem) or con
31e0: 6a 2e 68 61 73 43 6f 6e 6a 28 73 53 74 65 6d 2c  j.hasConj(sStem,
31f0: 20 22 3a 50 51 22 2c 20 22 3a 51 33 22 29 3a 0a   ":PQ", ":Q3"):.
3200: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
3210: 72 6e 20 54 72 75 65 0a 20 20 20 20 69 66 20 70  rn True.    if p
3220: 68 6f 6e 65 74 2e 68 61 73 53 69 6d 69 6c 28 73  honet.hasSimil(s
3230: 46 6c 65 78 2c 20 22 3a 66 22 29 3a 0a 20 20 20  Flex, ":f"):.   
3240: 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65       return True
3250: 0a 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73  .    return Fals
3260: 65 0a 0a 0a 64 65 66 20 68 61 73 4d 61 73 46 6f  e...def hasMasFo
3270: 72 6d 20 28 73 46 6c 65 78 29 3a 0a 20 20 20 20  rm (sFlex):.    
3280: 22 72 65 74 75 72 6e 20 54 72 75 65 20 69 66 20  "return True if 
3290: 74 68 65 72 65 20 69 73 20 61 20 6d 61 73 63 75  there is a mascu
32a0: 6c 69 6e 65 20 66 6f 72 6d 20 6f 66 20 3c 73 46  line form of <sF
32b0: 6c 65 78 3e 22 0a 20 20 20 20 66 6f 72 20 73 53  lex>".    for sS
32c0: 74 65 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68  tem in _oSpellCh
32d0: 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28 73  ecker.getLemma(s
32e0: 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20 69  Flex):.        i
32f0: 66 20 6d 66 73 70 2e 69 73 4d 61 73 46 6f 72 6d  f mfsp.isMasForm
3300: 28 73 53 74 65 6d 29 20 6f 72 20 63 6f 6e 6a 2e  (sStem) or conj.
3310: 68 61 73 43 6f 6e 6a 28 73 53 74 65 6d 2c 20 22  hasConj(sStem, "
3320: 3a 50 51 22 2c 20 22 3a 51 31 22 29 3a 0a 20 20  :PQ", ":Q1"):.  
3330: 20 20 20 20 20 20 20 20 20 20 23 20 77 68 61 74            # what
3340: 20 68 61 73 20 61 20 66 65 6d 69 6e 69 6e 65 20   has a feminine 
3350: 66 6f 72 6d 20 61 6c 73 6f 20 68 61 73 20 61 20  form also has a 
3360: 6d 61 73 63 75 6c 69 6e 65 20 66 6f 72 6d 0a 20  masculine form. 
3370: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
3380: 6e 20 54 72 75 65 0a 20 20 20 20 69 66 20 70 68  n True.    if ph
3390: 6f 6e 65 74 2e 68 61 73 53 69 6d 69 6c 28 73 46  onet.hasSimil(sF
33a0: 6c 65 78 2c 20 22 3a 6d 22 29 3a 0a 20 20 20 20  lex, ":m"):.    
33b0: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
33c0: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
33d0: 0a 0a 0a 64 65 66 20 73 77 69 74 63 68 47 65 6e  ...def switchGen
33e0: 64 65 72 20 28 73 46 6c 65 78 2c 20 62 50 6c 75  der (sFlex, bPlu
33f0: 72 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 72 65  r=None):.    "re
3400: 74 75 72 6e 20 66 65 6d 69 6e 69 6e 65 20 6f 72  turn feminine or
3410: 20 6d 61 73 63 75 6c 69 6e 65 20 66 6f 72 6d 28   masculine form(
3420: 73 29 20 6f 66 20 3c 73 46 6c 65 78 3e 22 0a 20  s) of <sFlex>". 
3430: 20 20 20 61 53 75 67 67 20 3d 20 73 65 74 28 29     aSugg = set()
3440: 0a 20 20 20 20 69 66 20 62 50 6c 75 72 20 69 73  .    if bPlur is
3450: 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 20 20 66   None:.        f
3460: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
3470: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
3480: 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20  orph(sFlex):.   
3490: 20 20 20 20 20 20 20 20 20 69 66 20 22 3a 66 22           if ":f"
34a0: 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20   in sMorph:.    
34b0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22              if "
34c0: 3a 73 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :s" in sMorph:. 
34d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
34e0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
34f0: 67 4d 61 73 53 69 6e 67 28 73 46 6c 65 78 29 29  gMasSing(sFlex))
3500: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3510: 20 65 6c 69 66 20 22 3a 70 22 20 69 6e 20 73 4d   elif ":p" in sM
3520: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
3530: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
3540: 61 64 64 28 73 75 67 67 4d 61 73 50 6c 75 72 28  add(suggMasPlur(
3550: 73 46 6c 65 78 29 29 0a 20 20 20 20 20 20 20 20  sFlex)).        
3560: 20 20 20 20 65 6c 69 66 20 22 3a 6d 22 20 69 6e      elif ":m" in
3570: 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   sMorph:.       
3580: 20 20 20 20 20 20 20 20 20 69 66 20 22 3a 73 22           if ":s"
3590: 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20   in sMorph:.    
35a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35b0: 61 53 75 67 67 2e 61 64 64 28 73 75 67 67 46 65  aSugg.add(suggFe
35c0: 6d 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20  mSing(sFlex)).  
35d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
35e0: 69 66 20 22 3a 70 22 20 69 6e 20 73 4d 6f 72 70  if ":p" in sMorp
35f0: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
3600: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
3610: 28 73 75 67 67 46 65 6d 50 6c 75 72 28 73 46 6c  (suggFemPlur(sFl
3620: 65 78 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  ex)).           
3630: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
3640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
3650: 53 75 67 67 2e 61 64 64 28 73 75 67 67 46 65 6d  Sugg.add(suggFem
3660: 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20 20  Sing(sFlex)).   
3670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3680: 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67 46   aSugg.add(suggF
3690: 65 6d 50 6c 75 72 28 73 46 6c 65 78 29 29 0a 20  emPlur(sFlex)). 
36a0: 20 20 20 65 6c 69 66 20 62 50 6c 75 72 3a 0a 20     elif bPlur:. 
36b0: 20 20 20 20 20 20 20 66 6f 72 20 73 4d 6f 72 70         for sMorp
36c0: 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  h in _oSpellChec
36d0: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c  ker.getMorph(sFl
36e0: 65 78 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ex):.           
36f0: 20 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72   if ":f" in sMor
3700: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
3710: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75      aSugg.add(su
3720: 67 67 4d 61 73 50 6c 75 72 28 73 46 6c 65 78 29  ggMasPlur(sFlex)
3730: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  ).            el
3740: 69 66 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72 70  if ":m" in sMorp
3750: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
3760: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
3770: 67 46 65 6d 50 6c 75 72 28 73 46 6c 65 78 29 29  gFemPlur(sFlex))
3780: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
3790: 20 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e     for sMorph in
37a0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
37b0: 67 65 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a  getMorph(sFlex):
37c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
37d0: 22 3a 66 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a  ":f" in sMorph:.
37e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37f0: 61 53 75 67 67 2e 61 64 64 28 73 75 67 67 4d 61  aSugg.add(suggMa
3800: 73 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20  sSing(sFlex)).  
3810: 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 22            elif "
3820: 3a 6d 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :m" in sMorph:. 
3830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
3840: 53 75 67 67 2e 61 64 64 28 73 75 67 67 46 65 6d  Sugg.add(suggFem
3850: 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20 20  Sing(sFlex)).   
3860: 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20   if aSugg:.     
3870: 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f     return "|".jo
3880: 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65  in(aSugg).    re
3890: 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 77  turn ""...def sw
38a0: 69 74 63 68 50 6c 75 72 61 6c 20 28 73 46 6c 65  itchPlural (sFle
38b0: 78 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 20  x):.    "return 
38c0: 70 6c 75 72 61 6c 20 6f 72 20 73 69 6e 67 75 6c  plural or singul
38d0: 61 72 20 66 6f 72 6d 28 73 29 20 6f 66 20 3c 73  ar form(s) of <s
38e0: 46 6c 65 78 3e 22 0a 20 20 20 20 61 53 75 67 67  Flex>".    aSugg
38f0: 20 3d 20 73 65 74 28 29 0a 20 20 20 20 66 6f 72   = set().    for
3900: 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65   sMorph in _oSpe
3910: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
3920: 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20  ph(sFlex):.     
3930: 20 20 20 69 66 20 22 3a 73 22 20 69 6e 20 73 4d     if ":s" in sM
3940: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
3950: 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67    aSugg.add(sugg
3960: 50 6c 75 72 28 73 46 6c 65 78 29 29 0a 20 20 20  Plur(sFlex)).   
3970: 20 20 20 20 20 65 6c 69 66 20 22 3a 70 22 20 69       elif ":p" i
3980: 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20  n sMorph:.      
3990: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
39a0: 73 75 67 67 53 69 6e 67 28 73 46 6c 65 78 29 29  suggSing(sFlex))
39b0: 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a 20  .    if aSugg:. 
39c0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 7c         return "|
39d0: 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20 20  ".join(aSugg).  
39e0: 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65    return ""...de
39f0: 66 20 68 61 73 53 69 6d 69 6c 20 28 73 57 6f 72  f hasSimil (sWor
3a00: 64 2c 20 73 50 61 74 74 65 72 6e 3d 4e 6f 6e 65  d, sPattern=None
3a10: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 20 54  ):.    "return T
3a20: 72 75 65 20 69 66 20 74 68 65 72 65 20 69 73 20  rue if there is 
3a30: 77 6f 72 64 73 20 70 68 6f 6e 65 74 69 63 61 6c  words phonetical
3a40: 6c 79 20 73 69 6d 69 6c 61 72 20 74 6f 20 3c 73  ly similar to <s
3a50: 57 6f 72 64 3e 20 28 61 63 63 6f 72 64 69 6e 67  Word> (according
3a60: 20 74 6f 20 3c 73 50 61 74 74 65 72 6e 3e 20 69   to <sPattern> i
3a70: 66 20 72 65 71 75 69 72 65 64 29 22 0a 20 20 20  f required)".   
3a80: 20 72 65 74 75 72 6e 20 70 68 6f 6e 65 74 2e 68   return phonet.h
3a90: 61 73 53 69 6d 69 6c 28 73 57 6f 72 64 2c 20 73  asSimil(sWord, s
3aa0: 50 61 74 74 65 72 6e 29 0a 0a 0a 64 65 66 20 73  Pattern)...def s
3ab0: 75 67 67 53 69 6d 69 6c 20 28 73 57 6f 72 64 2c  uggSimil (sWord,
3ac0: 20 73 50 61 74 74 65 72 6e 3d 4e 6f 6e 65 2c 20   sPattern=None, 
3ad0: 62 53 75 62 73 74 3d 46 61 6c 73 65 2c 20 62 56  bSubst=False, bV
3ae0: 43 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 72  C=False):.    "r
3af0: 65 74 75 72 6e 20 6c 69 73 74 20 6f 66 20 77 6f  eturn list of wo
3b00: 72 64 73 20 70 68 6f 6e 65 74 69 63 61 6c 6c 79  rds phonetically
3b10: 20 73 69 6d 69 6c 61 72 20 74 6f 20 73 57 6f 72   similar to sWor
3b20: 64 20 61 6e 64 20 77 68 6f 6d 20 50 4f 53 20 69  d and whom POS i
3b30: 73 20 6d 61 74 63 68 69 6e 67 20 73 50 61 74 74  s matching sPatt
3b40: 65 72 6e 22 0a 20 20 20 20 69 66 20 62 56 43 3a  ern".    if bVC:
3b50: 0a 20 20 20 20 20 20 20 20 73 57 6f 72 64 2c 20  .        sWord, 
3b60: 73 53 66 78 20 3d 20 73 70 6c 69 74 56 65 72 62  sSfx = splitVerb
3b70: 28 73 57 6f 72 64 29 0a 20 20 20 20 61 53 75 67  (sWord).    aSug
3b80: 67 20 3d 20 70 68 6f 6e 65 74 2e 73 65 6c 65 63  g = phonet.selec
3b90: 74 53 69 6d 69 6c 28 73 57 6f 72 64 2c 20 73 50  tSimil(sWord, sP
3ba0: 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66 20 6e  attern).    if n
3bb0: 6f 74 20 61 53 75 67 67 20 6f 72 20 6e 6f 74 20  ot aSugg or not 
3bc0: 62 53 75 62 73 74 3a 0a 20 20 20 20 20 20 20 20  bSubst:.        
3bd0: 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f  for sMorph in _o
3be0: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74  SpellChecker.get
3bf0: 4d 6f 72 70 68 28 73 57 6f 72 64 29 3a 0a 20 20  Morph(sWord):.  
3c00: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
3c10: 75 70 64 61 74 65 28 63 6f 6e 6a 2e 67 65 74 53  update(conj.getS
3c20: 69 6d 69 6c 28 73 57 6f 72 64 2c 20 73 4d 6f 72  imil(sWord, sMor
3c30: 70 68 2c 20 62 53 75 62 73 74 29 29 0a 20 20 20  ph, bSubst)).   
3c40: 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20           break. 
3c50: 20 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20     if aSugg:.   
3c60: 20 20 20 20 20 69 66 20 62 56 43 3a 0a 20 20 20       if bVC:.   
3c70: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 20 3d           aSugg =
3c80: 20 6c 69 73 74 28 6d 61 70 28 6c 61 6d 62 64 61   list(map(lambda
3c90: 20 73 53 75 67 3a 20 73 53 75 67 20 2b 20 73 53   sSug: sSug + sS
3ca0: 66 78 2c 20 61 53 75 67 67 29 29 0a 20 20 20 20  fx, aSugg)).    
3cb0: 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a      return "|".j
3cc0: 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72  oin(aSugg).    r
3cd0: 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73  eturn ""...def s
3ce0: 75 67 67 43 65 4f 72 43 65 74 20 28 73 57 6f 72  uggCeOrCet (sWor
3cf0: 64 29 3a 0a 20 20 20 20 22 73 75 67 67 65 73 74  d):.    "suggest
3d00: 20 e2 80 9c 63 65 e2 80 9d 20 6f 72 20 e2 80 9c   ...ce... or ...
3d10: 63 65 74 e2 80 9d 20 6f 72 20 62 6f 74 68 20 61  cet... or both a
3d20: 63 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20  ccording to the 
3d30: 66 69 72 73 74 20 6c 65 74 74 65 72 20 6f 66 20  first letter of 
3d40: 3c 73 57 6f 72 64 3e 22 0a 20 20 20 20 69 66 20  <sWord>".    if 
3d50: 72 65 2e 6d 61 74 63 68 28 22 28 3f 69 29 5b 61  re.match("(?i)[a
3d60: 65 c3 a9 c3 a8 c3 aa 69 6f 75 79 c3 a2 c3 ae c3  e......iouy.....
3d70: af 5d 22 2c 20 73 57 6f 72 64 29 3a 0a 20 20 20  .]", sWord):.   
3d80: 20 20 20 20 20 72 65 74 75 72 6e 20 22 63 65 74       return "cet
3d90: 22 0a 20 20 20 20 69 66 20 73 57 6f 72 64 5b 30  ".    if sWord[0
3da0: 3a 31 5d 20 69 6e 20 22 68 48 22 3a 0a 20 20 20  :1] in "hH":.   
3db0: 20 20 20 20 20 72 65 74 75 72 6e 20 22 63 65 7c       return "ce|
3dc0: 63 65 74 22 0a 20 20 20 20 72 65 74 75 72 6e 20  cet".    return 
3dd0: 22 63 65 22 0a 0a 0a 64 65 66 20 73 75 67 67 4c  "ce"...def suggL
3de0: 65 73 4c 61 20 28 73 57 6f 72 64 29 3a 0a 20 20  esLa (sWord):.  
3df0: 20 20 22 73 75 67 67 65 73 74 20 e2 80 9c 6c 65    "suggest ...le
3e00: 73 e2 80 9d 20 6f 72 20 e2 80 9c 6c 61 e2 80 9d  s... or ...la...
3e10: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 3c 73   according to <s
3e20: 57 6f 72 64 3e 22 0a 20 20 20 20 69 66 20 61 6e  Word>".    if an
3e30: 79 28 20 22 3a 70 22 20 69 6e 20 73 4d 6f 72 70  y( ":p" in sMorp
3e40: 68 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  h  for sMorph in
3e50: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
3e60: 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64 29 20  getMorph(sWord) 
3e70: 29 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ):.        retur
3e80: 6e 20 22 6c 65 73 7c 6c 61 22 0a 20 20 20 20 72  n "les|la".    r
3e90: 65 74 75 72 6e 20 22 6c 61 22 0a 0a 0a 5f 7a 42  eturn "la"..._zB
3ea0: 69 6e 61 72 79 20 3d 20 72 65 2e 63 6f 6d 70 69  inary = re.compi
3eb0: 6c 65 28 22 5e 5b 30 31 5d 2b 24 22 29 0a 0a 64  le("^[01]+$")..d
3ec0: 65 66 20 66 6f 72 6d 61 74 4e 75 6d 62 65 72 20  ef formatNumber 
3ed0: 28 73 4e 75 6d 62 65 72 29 3a 0a 20 20 20 20 22  (sNumber):.    "
3ee0: 61 64 64 20 73 70 61 63 65 73 20 6f 72 20 68 79  add spaces or hy
3ef0: 70 68 65 6e 73 20 74 6f 20 62 69 67 20 6e 75 6d  phens to big num
3f00: 62 65 72 73 22 0a 20 20 20 20 6e 4c 65 6e 20 3d  bers".    nLen =
3f10: 20 6c 65 6e 28 73 4e 75 6d 62 65 72 29 0a 20 20   len(sNumber).  
3f20: 20 20 69 66 20 6e 4c 65 6e 20 3c 20 34 3a 0a 20    if nLen < 4:. 
3f30: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 4e         return sN
3f40: 75 6d 62 65 72 0a 20 20 20 20 73 52 65 73 20 3d  umber.    sRes =
3f50: 20 22 22 0a 20 20 20 20 69 66 20 22 2c 22 20 6e   "".    if "," n
3f60: 6f 74 20 69 6e 20 73 4e 75 6d 62 65 72 3a 0a 20  ot in sNumber:. 
3f70: 20 20 20 20 20 20 20 23 20 6e 6f 6d 62 72 65 20         # nombre 
3f80: 65 6e 74 69 65 72 0a 20 20 20 20 20 20 20 20 73  entier.        s
3f90: 52 65 73 20 3d 20 5f 66 6f 72 6d 61 74 4e 75 6d  Res = _formatNum
3fa0: 62 65 72 28 73 4e 75 6d 62 65 72 2c 20 33 29 0a  ber(sNumber, 3).
3fb0: 20 20 20 20 20 20 20 20 23 20 62 69 6e 61 69 72          # binair
3fc0: 65 0a 20 20 20 20 20 20 20 20 69 66 20 5f 7a 42  e.        if _zB
3fd0: 69 6e 61 72 79 2e 73 65 61 72 63 68 28 73 4e 75  inary.search(sNu
3fe0: 6d 62 65 72 29 3a 0a 20 20 20 20 20 20 20 20 20  mber):.         
3ff0: 20 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b     sRes += "|" +
4000: 20 5f 66 6f 72 6d 61 74 4e 75 6d 62 65 72 28 73   _formatNumber(s
4010: 4e 75 6d 62 65 72 2c 20 34 29 0a 20 20 20 20 20  Number, 4).     
4020: 20 20 20 23 20 6e 75 6d c3 a9 72 6f 73 20 64 65     # num..ros de
4030: 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65 0a 20 20 20   t..l..phone.   
4040: 20 20 20 20 20 69 66 20 6e 4c 65 6e 20 3d 3d 20       if nLen == 
4050: 31 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  10:.            
4060: 69 66 20 73 4e 75 6d 62 65 72 2e 73 74 61 72 74  if sNumber.start
4070: 73 77 69 74 68 28 22 30 22 29 3a 0a 20 20 20 20  swith("0"):.    
4080: 20 20 20 20 20 20 20 20 20 20 20 20 73 52 65 73              sRes
4090: 20 2b 3d 20 22 7c 22 20 2b 20 5f 66 6f 72 6d 61   += "|" + _forma
40a0: 74 4e 75 6d 62 65 72 28 73 4e 75 6d 62 65 72 2c  tNumber(sNumber,
40b0: 20 32 29 20 20 20 20 20 20 20 20 20 20 20 20 20   2)             
40c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40f0: 20 20 20 20 23 20 74 c3 a9 6c c3 a9 70 68 6f 6e      # t..l..phon
4100: 65 20 66 72 61 6e c3 a7 61 69 73 0a 20 20 20 20  e fran..ais.    
4110: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73              if s
4120: 4e 75 6d 62 65 72 5b 31 5d 20 3d 3d 20 22 34 22  Number[1] == "4"
4130: 20 61 6e 64 20 28 73 4e 75 6d 62 65 72 5b 32 5d   and (sNumber[2]
4140: 3d 3d 22 37 22 20 6f 72 20 73 4e 75 6d 62 65 72  =="7" or sNumber
4150: 5b 32 5d 3d 3d 22 38 22 20 6f 72 20 73 4e 75 6d  [2]=="8" or sNum
4160: 62 65 72 5b 32 5d 3d 3d 22 39 22 29 3a 0a 20 20  ber[2]=="9"):.  
4170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4180: 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b 20    sRes += "|" + 
4190: 73 4e 75 6d 62 65 72 5b 30 3a 34 5d 20 2b 20 22  sNumber[0:4] + "
41a0: c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 34 3a  .." + sNumber[4:
41b0: 36 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d  6] + ".." + sNum
41c0: 62 65 72 5b 36 3a 38 5d 20 2b 20 22 c2 a0 22 20  ber[6:8] + ".." 
41d0: 2b 20 73 4e 75 6d 62 65 72 5b 38 3a 5d 20 20 20  + sNumber[8:]   
41e0: 20 20 20 20 20 20 20 20 20 23 20 6d 6f 62 69 6c           # mobil
41f0: 65 20 62 65 6c 67 65 0a 20 20 20 20 20 20 20 20  e belge.        
4200: 20 20 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20          sRes += 
4210: 22 7c 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a  "|" + sNumber[0:
4220: 33 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d  3] + ".." + sNum
4230: 62 65 72 5b 33 3a 36 5d 20 2b 20 22 c2 a0 22 20  ber[3:6] + ".." 
4240: 2b 20 73 4e 75 6d 62 65 72 5b 36 3a 38 5d 20 2b  + sNumber[6:8] +
4250: 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b   ".." + sNumber[
4260: 38 3a 5d 20 20 20 20 20 20 20 20 20 20 20 20 20  8:]             
4270: 20 20 20 23 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65     # t..l..phone
4280: 20 73 75 69 73 73 65 0a 20 20 20 20 20 20 20 20   suisse.        
4290: 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20      sRes += "|" 
42a0: 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 34 5d 20 2b  + sNumber[0:4] +
42b0: 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b   ".." + sNumber[
42c0: 34 3a 37 5d 20 2b 20 22 2d 22 20 2b 20 73 4e 75  4:7] + "-" + sNu
42d0: 6d 62 65 72 5b 37 3a 5d 20 20 20 20 20 20 20 20  mber[7:]        
42e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4300: 20 23 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65 20 63   # t..l..phone c
4310: 61 6e 61 64 69 65 6e 20 6f 75 20 61 6d c3 a9 72  anadien ou am..r
4320: 69 63 61 69 6e 0a 20 20 20 20 20 20 20 20 65 6c  icain.        el
4330: 69 66 20 6e 4c 65 6e 20 3d 3d 20 39 20 61 6e 64  if nLen == 9 and
4340: 20 73 4e 75 6d 62 65 72 2e 73 74 61 72 74 73 77   sNumber.startsw
4350: 69 74 68 28 22 30 22 29 3a 0a 20 20 20 20 20 20  ith("0"):.      
4360: 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c        sRes += "|
4370: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 33 5d  " + sNumber[0:3]
4380: 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65   + ".." + sNumbe
4390: 72 5b 33 3a 35 5d 20 2b 20 22 c2 a0 22 20 2b 20  r[3:5] + ".." + 
43a0: 73 4e 75 6d 62 65 72 5b 35 3a 37 5d 20 2b 20 22  sNumber[5:7] + "
43b0: c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 37 3a  .." + sNumber[7:
43c0: 39 5d 20 20 20 20 20 20 20 20 20 20 20 20 20 20  9]              
43d0: 20 20 20 20 20 23 20 66 69 78 65 20 62 65 6c 67       # fixe belg
43e0: 65 20 31 0a 20 20 20 20 20 20 20 20 20 20 20 20  e 1.            
43f0: 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b 20 73 4e  sRes += "|" + sN
4400: 75 6d 62 65 72 5b 30 3a 32 5d 20 2b 20 22 c2 a0  umber[0:2] + "..
4410: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 32 3a 35 5d  " + sNumber[2:5]
4420: 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65   + ".." + sNumbe
4430: 72 5b 35 3a 37 5d 20 2b 20 22 c2 a0 22 20 2b 20  r[5:7] + ".." + 
4440: 73 4e 75 6d 62 65 72 5b 37 3a 39 5d 20 20 20 20  sNumber[7:9]    
4450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
4460: 20 66 69 78 65 20 62 65 6c 67 65 20 32 0a 20 20   fixe belge 2.  
4470: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
4480: 23 20 4e 6f 6d 62 72 65 20 72 c3 a9 65 6c 0a 20  # Nombre r..el. 
4490: 20 20 20 20 20 20 20 73 49 6e 74 2c 20 73 46 6c         sInt, sFl
44a0: 6f 61 74 20 3d 20 73 4e 75 6d 62 65 72 2e 73 70  oat = sNumber.sp
44b0: 6c 69 74 28 22 2c 22 2c 20 31 29 0a 20 20 20 20  lit(",", 1).    
44c0: 20 20 20 20 73 52 65 73 20 3d 20 5f 66 6f 72 6d      sRes = _form
44d0: 61 74 4e 75 6d 62 65 72 28 73 49 6e 74 2c 20 33  atNumber(sInt, 3
44e0: 29 20 2b 20 22 2c 22 20 2b 20 73 46 6c 6f 61 74  ) + "," + sFloat
44f0: 0a 20 20 20 20 72 65 74 75 72 6e 20 73 52 65 73  .    return sRes
4500: 0a 0a 64 65 66 20 5f 66 6f 72 6d 61 74 4e 75 6d  ..def _formatNum
4510: 62 65 72 20 28 73 4e 75 6d 62 65 72 2c 20 6e 47  ber (sNumber, nG
4520: 72 6f 75 70 3d 33 29 3a 0a 20 20 20 20 73 52 65  roup=3):.    sRe
4530: 73 20 3d 20 22 22 0a 20 20 20 20 6e 45 6e 64 20  s = "".    nEnd 
4540: 3d 20 6c 65 6e 28 73 4e 75 6d 62 65 72 29 0a 20  = len(sNumber). 
4550: 20 20 20 77 68 69 6c 65 20 6e 45 6e 64 20 3e 20     while nEnd > 
4560: 30 3a 0a 20 20 20 20 20 20 20 20 6e 53 74 61 72  0:.        nStar
4570: 74 20 3d 20 6d 61 78 28 6e 45 6e 64 2d 6e 47 72  t = max(nEnd-nGr
4580: 6f 75 70 2c 20 30 29 0a 20 20 20 20 20 20 20 20  oup, 0).        
4590: 73 52 65 73 20 3d 20 73 4e 75 6d 62 65 72 5b 6e  sRes = sNumber[n
45a0: 53 74 61 72 74 3a 6e 45 6e 64 5d 20 2b 20 22 c2  Start:nEnd] + ".
45b0: a0 22 20 2b 20 73 52 65 73 20 20 69 66 20 73 52  ." + sRes  if sR
45c0: 65 73 20 20 65 6c 73 65 20 73 4e 75 6d 62 65 72  es  else sNumber
45d0: 5b 6e 53 74 61 72 74 3a 6e 45 6e 64 5d 0a 20 20  [nStart:nEnd].  
45e0: 20 20 20 20 20 20 6e 45 6e 64 20 3d 20 6e 45 6e        nEnd = nEn
45f0: 64 20 2d 20 6e 47 72 6f 75 70 0a 20 20 20 20 72  d - nGroup.    r
4600: 65 74 75 72 6e 20 73 52 65 73 0a 0a 0a 64 65 66  eturn sRes...def
4610: 20 66 6f 72 6d 61 74 4e 46 20 28 73 29 3a 0a 20   formatNF (s):. 
4620: 20 20 20 22 74 79 70 6f 67 72 61 70 68 79 3a 20     "typography: 
4630: 66 6f 72 6d 61 74 20 4e 46 20 72 65 66 65 72 65  format NF refere
4640: 6e 63 65 20 28 6e 6f 72 6d 65 20 66 72 61 6e c3  nce (norme fran.
4650: a7 61 69 73 65 29 22 0a 20 20 20 20 74 72 79 3a  .aise)".    try:
4660: 0a 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e  .        m = re.
4670: 6d 61 74 63 68 28 22 4e 46 5b 20 c2 a0 2d 5d 3f  match("NF[ ..-]?
4680: 28 43 7c 45 7c 50 7c 51 7c 53 7c 58 7c 5a 7c 45  (C|E|P|Q|S|X|Z|E
4690: 4e 28 3f 3a 5b 20 c2 a0 2d 5d 49 53 4f 7c 29 29  N(?:[ ..-]ISO|))
46a0: 5b 20 c2 a0 2d 5d 3f 28 5b 30 2d 39 5d 2b 28 3f  [ ..-]?([0-9]+(?
46b0: 3a 5b 2f e2 80 91 2d 5d 5b 30 2d 39 5d 2b 7c 29  :[/...-][0-9]+|)
46c0: 29 22 2c 20 73 29 0a 20 20 20 20 20 20 20 20 69  )", s).        i
46d0: 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20  f not m:.       
46e0: 20 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 20       return "". 
46f0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 4e         return "N
4700: 46 c2 a0 22 20 2b 20 6d 2e 67 72 6f 75 70 28 31  F.." + m.group(1
4710: 29 2e 75 70 70 65 72 28 29 2e 72 65 70 6c 61 63  ).upper().replac
4720: 65 28 22 20 22 2c 20 22 c2 a0 22 29 2e 72 65 70  e(" ", "..").rep
4730: 6c 61 63 65 28 22 2d 22 2c 20 22 c2 a0 22 29 20  lace("-", "..") 
4740: 2b 20 22 c2 a0 22 20 2b 20 6d 2e 67 72 6f 75 70  + ".." + m.group
4750: 28 32 29 2e 72 65 70 6c 61 63 65 28 22 2f 22 2c  (2).replace("/",
4760: 20 22 e2 80 91 22 29 2e 72 65 70 6c 61 63 65 28   "...").replace(
4770: 22 2d 22 2c 20 22 e2 80 91 22 29 0a 20 20 20 20  "-", "...").    
4780: 65 78 63 65 70 74 20 28 72 65 2e 65 72 72 6f 72  except (re.error
4790: 2c 20 49 6e 64 65 78 45 72 72 6f 72 29 3a 0a 20  , IndexError):. 
47a0: 20 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b         traceback
47b0: 2e 70 72 69 6e 74 5f 65 78 63 28 29 0a 20 20 20  .print_exc().   
47c0: 20 20 20 20 20 72 65 74 75 72 6e 20 22 23 20 65       return "# e
47d0: 72 72 65 75 72 20 23 22 0a 0a 0a 64 65 66 20 75  rreur #"...def u
47e0: 6e 64 6f 4c 69 67 61 74 75 72 65 20 28 63 29 3a  ndoLigature (c):
47f0: 0a 20 20 20 20 22 74 79 70 6f 67 72 61 70 68 79  .    "typography
4800: 3a 20 73 70 6c 69 74 20 6c 69 67 61 74 75 72 65  : split ligature
4810: 20 63 68 61 72 61 63 74 65 72 20 3c 63 3e 20 69   character <c> i
4820: 6e 20 73 65 76 65 72 61 6c 20 63 68 61 72 73 22  n several chars"
4830: 0a 20 20 20 20 69 66 20 63 20 3d 3d 20 22 ef ac  .    if c == "..
4840: 81 22 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  .":.        retu
4850: 72 6e 20 22 66 69 22 0a 20 20 20 20 69 66 20 63  rn "fi".    if c
4860: 20 3d 3d 20 22 ef ac 82 22 3a 0a 20 20 20 20 20   == "...":.     
4870: 20 20 20 72 65 74 75 72 6e 20 22 66 6c 22 0a 20     return "fl". 
4880: 20 20 20 69 66 20 63 20 3d 3d 20 22 ef ac 80 22     if c == "..."
4890: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
48a0: 20 22 66 66 22 0a 20 20 20 20 69 66 20 63 20 3d   "ff".    if c =
48b0: 3d 20 22 ef ac 83 22 3a 0a 20 20 20 20 20 20 20  = "...":.       
48c0: 20 72 65 74 75 72 6e 20 22 66 66 69 22 0a 20 20   return "ffi".  
48d0: 20 20 69 66 20 63 20 3d 3d 20 22 ef ac 84 22 3a    if c == "...":
48e0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
48f0: 22 66 66 6c 22 0a 20 20 20 20 69 66 20 63 20 3d  "ffl".    if c =
4900: 3d 20 22 ef ac 85 22 3a 0a 20 20 20 20 20 20 20  = "...":.       
4910: 20 72 65 74 75 72 6e 20 22 66 74 22 0a 20 20 20   return "ft".   
4920: 20 69 66 20 63 20 3d 3d 20 22 ef ac 86 22 3a 0a   if c == "...":.
4930: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
4940: 73 74 22 0a 20 20 20 20 72 65 74 75 72 6e 20 22  st".    return "
4950: 5f 22 0a 0a 0a 0a 0a 5f 78 4e 6f 72 6d 61 6c 69  _"....._xNormali
4960: 7a 65 64 43 68 61 72 73 46 6f 72 49 6e 63 6c 75  zedCharsForInclu
4970: 73 69 76 65 57 72 69 74 69 6e 67 20 3d 20 73 74  siveWriting = st
4980: 72 2e 6d 61 6b 65 74 72 61 6e 73 28 7b 0a 20 20  r.maketrans({.  
4990: 20 20 27 28 27 3a 20 27 5f 27 2c 20 20 27 29 27    '(': '_',  ')'
49a0: 3a 20 27 5f 27 2c 0a 20 20 20 20 27 2e 27 3a 20  : '_',.    '.': 
49b0: 27 5f 27 2c 20 20 27 c2 b7 27 3a 20 27 5f 27 2c  '_',  '..': '_',
49c0: 20 20 27 e2 80 a2 27 3a 20 27 5f 27 2c 0a 20 20    '...': '_',.  
49d0: 20 20 27 e2 80 93 27 3a 20 27 5f 27 2c 20 20 27    '...': '_',  '
49e0: e2 80 94 27 3a 20 27 5f 27 2c 0a 20 20 20 20 27  ...': '_',.    '
49f0: 2f 27 3a 20 27 5f 27 0a 7d 29 0a 0a 0a 64 65 66  /': '_'.})...def
4a00: 20 6e 6f 72 6d 61 6c 69 7a 65 49 6e 63 6c 75 73   normalizeInclus
4a10: 69 76 65 57 72 69 74 69 6e 67 20 28 73 54 6f 6b  iveWriting (sTok
4a20: 65 6e 29 3a 0a 20 20 20 20 22 74 79 70 6f 67 72  en):.    "typogr
4a30: 61 70 68 79 3a 20 72 65 70 6c 61 63 65 20 77 6f  aphy: replace wo
4a40: 72 64 20 73 65 70 61 72 61 74 6f 72 73 20 75 73  rd separators us
4a50: 65 64 20 69 6e 20 69 6e 63 6c 75 73 69 76 65 20  ed in inclusive 
4a60: 77 72 69 74 69 6e 67 20 62 79 20 75 6e 64 65 72  writing by under
4a70: 73 63 6f 72 65 20 28 5f 29 22 0a 20 20 20 20 72  score (_)".    r
4a80: 65 74 75 72 6e 20 73 54 6f 6b 65 6e 2e 74 72 61  eturn sToken.tra
4a90: 6e 73 6c 61 74 65 28 5f 78 4e 6f 72 6d 61 6c 69  nslate(_xNormali
4aa0: 7a 65 64 43 68 61 72 73 46 6f 72 49 6e 63 6c 75  zedCharsForInclu
4ab0: 73 69 76 65 57 72 69 74 69 6e 67 29 0a           siveWriting).