Grammalecte  Hex Artifact Content

Artifact 48d9a59bcc62cd620a2e0772525d3f2901611e568478611ce83b7d4a19d4b691:


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 22  a sSug: sSug + "
14a0: 73 22 20 2b 20 73 53 66 78 20 20 69 66 20 73 53  s" + sSfx  if sS
14b0: 66 78 2e 65 6e 64 73 77 69 74 68 28 28 22 2d 65  fx.endswith(("-e
14c0: 6e 22 2c 20 22 2d 79 22 29 29 20 61 6e 64 20 73  n", "-y")) and s
14d0: 53 75 67 2e 65 6e 64 73 77 69 74 68 28 28 22 65  Sug.endswith(("e
14e0: 22 2c 20 22 61 22 29 29 20 20 65 6c 73 65 20 73  ", "a"))  else s
14f0: 53 75 67 20 2b 20 73 53 66 78 2c 20 61 53 75 67  Sug + sSfx, aSug
1500: 67 29 29 0a 20 20 20 20 20 20 20 20 72 65 74 75  g)).        retu
1510: 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67  rn "|".join(aSug
1520: 67 29 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22  g).    return ""
1530: 0a 0a 0a 64 65 66 20 73 75 67 67 56 65 72 62 49  ...def suggVerbI
1540: 6e 66 69 20 28 73 46 6c 65 78 29 3a 0a 20 20 20  nfi (sFlex):.   
1550: 20 22 72 65 74 75 72 6e 73 20 69 6e 66 69 6e 69   "returns infini
1560: 74 69 76 65 20 66 6f 72 6d 73 20 6f 66 20 3c 73  tive forms of <s
1570: 46 6c 65 78 3e 22 0a 20 20 20 20 72 65 74 75 72  Flex>".    retur
1580: 6e 20 22 7c 22 2e 6a 6f 69 6e 28 5b 20 73 53 74  n "|".join([ sSt
1590: 65 6d 20 20 66 6f 72 20 73 53 74 65 6d 20 69 6e  em  for sStem in
15a0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
15b0: 67 65 74 4c 65 6d 6d 61 28 73 46 6c 65 78 29 20  getLemma(sFlex) 
15c0: 20 69 66 20 63 6f 6e 6a 2e 69 73 56 65 72 62 28   if conj.isVerb(
15d0: 73 53 74 65 6d 29 20 5d 29 0a 0a 0a 5f 64 51 75  sStem) ])..._dQu
15e0: 69 45 73 74 20 3d 20 7b 20 22 6a 65 22 3a 20 22  iEst = { "je": "
15f0: 3a 31 73 22 2c 20 22 6a e2 80 99 22 3a 20 22 3a  :1s", "j...": ":
1600: 31 73 22 2c 20 22 74 75 22 3a 20 22 3a 32 73 22  1s", "tu": ":2s"
1610: 2c 20 22 69 6c 22 3a 20 22 3a 33 73 22 2c 20 22  , "il": ":3s", "
1620: 6f 6e 22 3a 20 22 3a 33 73 22 2c 20 22 65 6c 6c  on": ":3s", "ell
1630: 65 22 3a 20 22 3a 33 73 22 2c 20 22 69 65 6c 22  e": ":3s", "iel"
1640: 3a 20 22 3a 33 73 22 2c 20 5c 0a 20 20 20 20 20  : ":3s", \.     
1650: 20 20 20 20 20 20 20 20 22 6e 6f 75 73 22 3a 20          "nous": 
1660: 22 3a 31 70 22 2c 20 22 76 6f 75 73 22 3a 20 22  ":1p", "vous": "
1670: 3a 32 70 22 2c 20 22 69 6c 73 22 3a 20 22 3a 33  :2p", "ils": ":3
1680: 70 22 2c 20 22 65 6c 6c 65 73 22 3a 20 22 3a 33  p", "elles": ":3
1690: 70 22 2c 20 22 69 65 6c 73 22 3a 20 22 3a 33 70  p", "iels": ":3p
16a0: 22 20 7d 0a 5f 6c 49 6e 64 69 63 61 74 69 66 20  " }._lIndicatif 
16b0: 3d 20 5b 22 3a 49 70 22 2c 20 22 3a 49 71 22 2c  = [":Ip", ":Iq",
16c0: 20 22 3a 49 73 22 2c 20 22 3a 49 66 22 5d 0a 5f   ":Is", ":If"]._
16d0: 6c 53 75 62 6a 6f 6e 63 74 69 66 20 3d 20 5b 22  lSubjonctif = ["
16e0: 3a 53 70 22 2c 20 22 3a 53 71 22 5d 0a 0a 64 65  :Sp", ":Sq"]..de
16f0: 66 20 73 75 67 67 56 65 72 62 4d 6f 64 65 20 28  f suggVerbMode (
1700: 73 46 6c 65 78 2c 20 63 4d 6f 64 65 2c 20 73 53  sFlex, cMode, sS
1710: 75 6a 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e  uj):.    "return
1720: 73 20 6f 74 68 65 72 20 63 6f 6e 6a 75 67 61 74  s other conjugat
1730: 69 6f 6e 73 20 6f 66 20 3c 73 46 6c 65 78 3e 20  ions of <sFlex> 
1740: 61 63 63 6f 6e 64 69 6e 67 20 74 6f 20 3c 63 4d  acconding to <cM
1750: 6f 64 65 3e 20 61 6e 64 20 3c 73 53 75 6a 3e 22  ode> and <sSuj>"
1760: 0a 20 20 20 20 69 66 20 63 4d 6f 64 65 20 3d 3d  .    if cMode ==
1770: 20 22 3a 49 22 3a 0a 20 20 20 20 20 20 20 20 6c   ":I":.        l
1780: 4d 6f 64 65 20 3d 20 5f 6c 49 6e 64 69 63 61 74  Mode = _lIndicat
1790: 69 66 0a 20 20 20 20 65 6c 69 66 20 63 4d 6f 64  if.    elif cMod
17a0: 65 20 3d 3d 20 22 3a 53 22 3a 0a 20 20 20 20 20  e == ":S":.     
17b0: 20 20 20 6c 4d 6f 64 65 20 3d 20 5f 6c 53 75 62     lMode = _lSub
17c0: 6a 6f 6e 63 74 69 66 0a 20 20 20 20 65 6c 69 66  jonctif.    elif
17d0: 20 63 4d 6f 64 65 2e 73 74 61 72 74 73 77 69 74   cMode.startswit
17e0: 68 28 28 22 3a 49 22 2c 20 22 3a 53 22 29 29 3a  h((":I", ":S")):
17f0: 0a 20 20 20 20 20 20 20 20 6c 4d 6f 64 65 20 3d  .        lMode =
1800: 20 5b 63 4d 6f 64 65 5d 0a 20 20 20 20 65 6c 73   [cMode].    els
1810: 65 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  e:.        retur
1820: 6e 20 22 22 0a 20 20 20 20 73 57 68 6f 20 3d 20  n "".    sWho = 
1830: 5f 64 51 75 69 45 73 74 2e 67 65 74 28 73 53 75  _dQuiEst.get(sSu
1840: 6a 2e 6c 6f 77 65 72 28 29 2c 20 22 3a 33 73 22  j.lower(), ":3s"
1850: 29 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73 65  ).    aSugg = se
1860: 74 28 29 0a 20 20 20 20 66 6f 72 20 73 53 74 65  t().    for sSte
1870: 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  m in _oSpellChec
1880: 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28 73 46 6c  ker.getLemma(sFl
1890: 65 78 29 3a 0a 20 20 20 20 20 20 20 20 74 54 61  ex):.        tTa
18a0: 67 73 20 3d 20 63 6f 6e 6a 2e 5f 67 65 74 54 61  gs = conj._getTa
18b0: 67 73 28 73 53 74 65 6d 29 0a 20 20 20 20 20 20  gs(sStem).      
18c0: 20 20 69 66 20 74 54 61 67 73 3a 0a 20 20 20 20    if tTags:.    
18d0: 20 20 20 20 20 20 20 20 66 6f 72 20 73 54 65 6e          for sTen
18e0: 73 65 20 69 6e 20 6c 4d 6f 64 65 3a 0a 20 20 20  se in lMode:.   
18f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
1900: 63 6f 6e 6a 2e 5f 68 61 73 43 6f 6e 6a 57 69 74  conj._hasConjWit
1910: 68 54 61 67 73 28 74 54 61 67 73 2c 20 73 54 65  hTags(tTags, sTe
1920: 6e 73 65 2c 20 73 57 68 6f 29 3a 0a 20 20 20 20  nse, sWho):.    
1930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1940: 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 5f  aSugg.add(conj._
1950: 67 65 74 43 6f 6e 6a 57 69 74 68 54 61 67 73 28  getConjWithTags(
1960: 73 53 74 65 6d 2c 20 74 54 61 67 73 2c 20 73 54  sStem, tTags, sT
1970: 65 6e 73 65 2c 20 73 57 68 6f 29 29 0a 20 20 20  ense, sWho)).   
1980: 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20   if aSugg:.     
1990: 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f     return "|".jo
19a0: 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65  in(aSugg).    re
19b0: 74 75 72 6e 20 22 22 0a 0a 0a 23 23 20 4e 6f 75  turn ""...## Nou
19c0: 6e 73 20 61 6e 64 20 61 64 6a 65 63 74 69 76 65  ns and adjective
19d0: 73 0a 0a 64 65 66 20 73 75 67 67 50 6c 75 72 20  s..def suggPlur 
19e0: 28 73 46 6c 65 78 2c 20 73 57 6f 72 64 54 6f 41  (sFlex, sWordToA
19f0: 67 72 65 65 3d 4e 6f 6e 65 2c 20 62 53 65 6c 66  gree=None, bSelf
1a00: 53 75 67 67 3d 46 61 6c 73 65 29 3a 0a 20 20 20  Sugg=False):.   
1a10: 20 22 72 65 74 75 72 6e 73 20 70 6c 75 72 61 6c   "returns plural
1a20: 20 66 6f 72 6d 73 20 61 73 73 75 6d 69 6e 67 20   forms assuming 
1a30: 73 46 6c 65 78 20 69 73 20 73 69 6e 67 75 6c 61  sFlex is singula
1a40: 72 22 0a 20 20 20 20 69 66 20 73 57 6f 72 64 54  r".    if sWordT
1a50: 6f 41 67 72 65 65 3a 0a 20 20 20 20 20 20 20 20  oAgree:.        
1a60: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
1a70: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
1a80: 28 73 46 6c 65 78 29 0a 20 20 20 20 20 20 20 20  (sFlex).        
1a90: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20  if not lMorph:. 
1aa0: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
1ab0: 6e 20 22 22 0a 20 20 20 20 20 20 20 20 73 47 65  n "".        sGe
1ac0: 6e 64 65 72 20 3d 20 63 72 2e 67 65 74 47 65 6e  nder = cr.getGen
1ad0: 64 65 72 28 6c 4d 6f 72 70 68 29 0a 20 20 20 20  der(lMorph).    
1ae0: 20 20 20 20 69 66 20 73 47 65 6e 64 65 72 20 3d      if sGender =
1af0: 3d 20 22 3a 6d 22 3a 0a 20 20 20 20 20 20 20 20  = ":m":.        
1b00: 20 20 20 20 72 65 74 75 72 6e 20 73 75 67 67 4d      return suggM
1b10: 61 73 50 6c 75 72 28 73 46 6c 65 78 29 0a 20 20  asPlur(sFlex).  
1b20: 20 20 20 20 20 20 69 66 20 73 47 65 6e 64 65 72        if sGender
1b30: 20 3d 3d 20 22 3a 66 22 3a 0a 20 20 20 20 20 20   == ":f":.      
1b40: 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 75 67        return sug
1b50: 67 46 65 6d 50 6c 75 72 28 73 46 6c 65 78 29 0a  gFemPlur(sFlex).
1b60: 20 20 20 20 61 53 75 67 67 20 3d 20 73 65 74 28      aSugg = set(
1b70: 29 0a 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65  ).    if sFlex.e
1b80: 6e 64 73 77 69 74 68 28 22 6c 22 29 3a 0a 20 20  ndswith("l"):.  
1b90: 20 20 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65        if sFlex.e
1ba0: 6e 64 73 77 69 74 68 28 22 61 6c 22 29 20 61 6e  ndswith("al") an
1bb0: 64 20 6c 65 6e 28 73 46 6c 65 78 29 20 3e 20 32  d len(sFlex) > 2
1bc0: 20 61 6e 64 20 5f 6f 53 70 65 6c 6c 43 68 65 63   and _oSpellChec
1bd0: 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46 6c 65  ker.isValid(sFle
1be0: 78 5b 3a 2d 31 5d 2b 22 75 78 22 29 3a 0a 20 20  x[:-1]+"ux"):.  
1bf0: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
1c00: 61 64 64 28 73 46 6c 65 78 5b 3a 2d 31 5d 2b 22  add(sFlex[:-1]+"
1c10: 75 78 22 29 0a 20 20 20 20 20 20 20 20 69 66 20  ux").        if 
1c20: 73 46 6c 65 78 2e 65 6e 64 73 77 69 74 68 28 22  sFlex.endswith("
1c30: 61 69 6c 22 29 20 61 6e 64 20 6c 65 6e 28 73 46  ail") and len(sF
1c40: 6c 65 78 29 20 3e 20 33 20 61 6e 64 20 5f 6f 53  lex) > 3 and _oS
1c50: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73 56 61  pellChecker.isVa
1c60: 6c 69 64 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22  lid(sFlex[:-2]+"
1c70: 75 78 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ux"):.          
1c80: 20 20 61 53 75 67 67 2e 61 64 64 28 73 46 6c 65    aSugg.add(sFle
1c90: 78 5b 3a 2d 32 5d 2b 22 75 78 22 29 0a 20 20 20  x[:-2]+"ux").   
1ca0: 20 69 66 20 73 46 6c 65 78 2e 65 6e 64 73 77 69   if sFlex.endswi
1cb0: 74 68 28 22 4c 22 29 3a 0a 20 20 20 20 20 20 20  th("L"):.       
1cc0: 20 69 66 20 73 46 6c 65 78 2e 65 6e 64 73 77 69   if sFlex.endswi
1cd0: 74 68 28 22 41 4c 22 29 20 61 6e 64 20 6c 65 6e  th("AL") and len
1ce0: 28 73 46 6c 65 78 29 20 3e 20 32 20 61 6e 64 20  (sFlex) > 2 and 
1cf0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69  _oSpellChecker.i
1d00: 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d 31  sValid(sFlex[:-1
1d10: 5d 2b 22 55 58 22 29 3a 0a 20 20 20 20 20 20 20  ]+"UX"):.       
1d20: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73       aSugg.add(s
1d30: 46 6c 65 78 5b 3a 2d 31 5d 2b 22 55 58 22 29 0a  Flex[:-1]+"UX").
1d40: 20 20 20 20 20 20 20 20 69 66 20 73 46 6c 65 78          if sFlex
1d50: 2e 65 6e 64 73 77 69 74 68 28 22 41 49 4c 22 29  .endswith("AIL")
1d60: 20 61 6e 64 20 6c 65 6e 28 73 46 6c 65 78 29 20   and len(sFlex) 
1d70: 3e 20 33 20 61 6e 64 20 5f 6f 53 70 65 6c 6c 43  > 3 and _oSpellC
1d80: 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73  hecker.isValid(s
1d90: 46 6c 65 78 5b 3a 2d 32 5d 2b 22 55 58 22 29 3a  Flex[:-2]+"UX"):
1da0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75  .            aSu
1db0: 67 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32  gg.add(sFlex[:-2
1dc0: 5d 2b 22 55 58 22 29 0a 20 20 20 20 69 66 20 73  ]+"UX").    if s
1dd0: 46 6c 65 78 5b 2d 31 3a 5d 2e 69 73 6c 6f 77 65  Flex[-1:].islowe
1de0: 72 28 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20  r():.        if 
1df0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69  _oSpellChecker.i
1e00: 73 56 61 6c 69 64 28 73 46 6c 65 78 2b 22 73 22  sValid(sFlex+"s"
1e10: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61  ):.            a
1e20: 53 75 67 67 2e 61 64 64 28 73 46 6c 65 78 2b 22  Sugg.add(sFlex+"
1e30: 73 22 29 0a 20 20 20 20 20 20 20 20 69 66 20 5f  s").        if _
1e40: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73  oSpellChecker.is
1e50: 56 61 6c 69 64 28 73 46 6c 65 78 2b 22 78 22 29  Valid(sFlex+"x")
1e60: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53  :.            aS
1e70: 75 67 67 2e 61 64 64 28 73 46 6c 65 78 2b 22 78  ugg.add(sFlex+"x
1e80: 22 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20  ").    else:.   
1e90: 20 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43       if _oSpellC
1ea0: 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73  hecker.isValid(s
1eb0: 46 6c 65 78 2b 22 53 22 29 3a 0a 20 20 20 20 20  Flex+"S"):.     
1ec0: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
1ed0: 28 73 46 6c 65 78 2b 22 73 22 29 0a 20 20 20 20  (sFlex+"s").    
1ee0: 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43 68      if _oSpellCh
1ef0: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46  ecker.isValid(sF
1f00: 6c 65 78 2b 22 58 22 29 3a 0a 20 20 20 20 20 20  lex+"X"):.      
1f10: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
1f20: 73 46 6c 65 78 2b 22 78 22 29 0a 20 20 20 20 69  sFlex+"x").    i
1f30: 66 20 6d 66 73 70 2e 68 61 73 4d 69 73 63 50 6c  f mfsp.hasMiscPl
1f40: 75 72 61 6c 28 73 46 6c 65 78 29 3a 0a 20 20 20  ural(sFlex):.   
1f50: 20 20 20 20 20 61 53 75 67 67 2e 75 70 64 61 74       aSugg.updat
1f60: 65 28 6d 66 73 70 2e 67 65 74 4d 69 73 63 50 6c  e(mfsp.getMiscPl
1f70: 75 72 61 6c 28 73 46 6c 65 78 29 29 0a 20 20 20  ural(sFlex)).   
1f80: 20 69 66 20 6e 6f 74 20 61 53 75 67 67 20 61 6e   if not aSugg an
1f90: 64 20 62 53 65 6c 66 53 75 67 67 20 61 6e 64 20  d bSelfSugg and 
1fa0: 73 46 6c 65 78 2e 65 6e 64 73 77 69 74 68 28 28  sFlex.endswith((
1fb0: 22 73 22 2c 20 22 78 22 2c 20 22 53 22 2c 20 22  "s", "x", "S", "
1fc0: 58 22 29 29 3a 0a 20 20 20 20 20 20 20 20 61 53  X")):.        aS
1fd0: 75 67 67 2e 61 64 64 28 73 46 6c 65 78 29 0a 20  ugg.add(sFlex). 
1fe0: 20 20 20 61 53 75 67 67 2e 64 69 73 63 61 72 64     aSugg.discard
1ff0: 28 22 22 29 0a 20 20 20 20 69 66 20 61 53 75 67  ("").    if aSug
2000: 67 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  g:.        retur
2010: 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67  n "|".join(aSugg
2020: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a  ).    return "".
2030: 0a 0a 64 65 66 20 73 75 67 67 53 69 6e 67 20 28  ..def suggSing (
2040: 73 46 6c 65 78 2c 20 62 53 65 6c 66 53 75 67 67  sFlex, bSelfSugg
2050: 3d 54 72 75 65 29 3a 0a 20 20 20 20 22 72 65 74  =True):.    "ret
2060: 75 72 6e 73 20 73 69 6e 67 75 6c 61 72 20 66 6f  urns singular fo
2070: 72 6d 73 20 61 73 73 75 6d 69 6e 67 20 73 46 6c  rms assuming sFl
2080: 65 78 20 69 73 20 70 6c 75 72 61 6c 22 0a 20 20  ex is plural".  
2090: 20 20 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a    aSugg = set().
20a0: 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65 6e 64      if sFlex.end
20b0: 73 77 69 74 68 28 22 75 78 22 29 3a 0a 20 20 20  swith("ux"):.   
20c0: 20 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43       if _oSpellC
20d0: 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73  hecker.isValid(s
20e0: 46 6c 65 78 5b 3a 2d 32 5d 2b 22 6c 22 29 3a 0a  Flex[:-2]+"l"):.
20f0: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
2100: 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32 5d  g.add(sFlex[:-2]
2110: 2b 22 6c 22 29 0a 20 20 20 20 20 20 20 20 69 66  +"l").        if
2120: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
2130: 69 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d  isValid(sFlex[:-
2140: 32 5d 2b 22 69 6c 22 29 3a 0a 20 20 20 20 20 20  2]+"il"):.      
2150: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2160: 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22 69 6c 22 29  sFlex[:-2]+"il")
2170: 0a 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65 6e  .    if sFlex.en
2180: 64 73 77 69 74 68 28 22 55 58 22 29 3a 0a 20 20  dswith("UX"):.  
2190: 20 20 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c        if _oSpell
21a0: 43 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28  Checker.isValid(
21b0: 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22 4c 22 29 3a  sFlex[:-2]+"L"):
21c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75  .            aSu
21d0: 67 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32  gg.add(sFlex[:-2
21e0: 5d 2b 22 4c 22 29 0a 20 20 20 20 20 20 20 20 69  ]+"L").        i
21f0: 66 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  f _oSpellChecker
2200: 2e 69 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a  .isValid(sFlex[:
2210: 2d 32 5d 2b 22 49 4c 22 29 3a 0a 20 20 20 20 20  -2]+"IL"):.     
2220: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
2230: 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22 49 4c 22  (sFlex[:-2]+"IL"
2240: 29 0a 20 20 20 20 69 66 20 73 46 6c 65 78 2e 65  ).    if sFlex.e
2250: 6e 64 73 77 69 74 68 28 28 22 73 22 2c 20 22 78  ndswith(("s", "x
2260: 22 2c 20 22 53 22 2c 20 22 58 22 29 29 20 61 6e  ", "S", "X")) an
2270: 64 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  d _oSpellChecker
2280: 2e 69 73 56 61 6c 69 64 28 73 46 6c 65 78 5b 3a  .isValid(sFlex[:
2290: 2d 31 5d 29 3a 0a 20 20 20 20 20 20 20 20 61 53  -1]):.        aS
22a0: 75 67 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d  ugg.add(sFlex[:-
22b0: 31 5d 29 0a 20 20 20 20 69 66 20 62 53 65 6c 66  1]).    if bSelf
22c0: 53 75 67 67 20 61 6e 64 20 6e 6f 74 20 61 53 75  Sugg and not aSu
22d0: 67 67 3a 0a 20 20 20 20 20 20 20 20 61 53 75 67  gg:.        aSug
22e0: 67 2e 61 64 64 28 73 46 6c 65 78 29 0a 20 20 20  g.add(sFlex).   
22f0: 20 61 53 75 67 67 2e 64 69 73 63 61 72 64 28 22   aSugg.discard("
2300: 22 29 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a  ").    if aSugg:
2310: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
2320: 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a  "|".join(aSugg).
2330: 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a      return ""...
2340: 64 65 66 20 73 75 67 67 4d 61 73 53 69 6e 67 20  def suggMasSing 
2350: 28 73 46 6c 65 78 2c 20 62 53 75 67 67 53 69 6d  (sFlex, bSuggSim
2360: 69 6c 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22  il=False):.    "
2370: 72 65 74 75 72 6e 73 20 6d 61 73 63 75 6c 69 6e  returns masculin
2380: 65 20 73 69 6e 67 75 6c 61 72 20 66 6f 72 6d 73  e singular forms
2390: 22 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73 65  ".    aSugg = se
23a0: 74 28 29 0a 20 20 20 20 66 6f 72 20 73 4d 6f 72  t().    for sMor
23b0: 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65  ph in _oSpellChe
23c0: 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46  cker.getMorph(sF
23d0: 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20 69 66  lex):.        if
23e0: 20 6e 6f 74 20 22 3a 56 22 20 69 6e 20 73 4d 6f   not ":V" in sMo
23f0: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rph:.           
2400: 20 23 20 6e 6f 74 20 61 20 76 65 72 62 0a 20 20   # not a verb.  
2410: 20 20 20 20 20 20 20 20 20 20 69 66 20 22 3a 6d            if ":m
2420: 22 20 69 6e 20 73 4d 6f 72 70 68 20 6f 72 20 22  " in sMorph or "
2430: 3a 65 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :e" in sMorph:. 
2440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
2450: 53 75 67 67 2e 61 64 64 28 73 75 67 67 53 69 6e  Sugg.add(suggSin
2460: 67 28 73 46 6c 65 78 29 29 0a 20 20 20 20 20 20  g(sFlex)).      
2470: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
2480: 20 20 20 20 20 20 20 20 20 20 20 20 73 53 74 65              sSte
2490: 6d 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d 61 4f  m = cr.getLemmaO
24a0: 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29 0a 20  fMorph(sMorph). 
24b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
24c0: 66 20 6d 66 73 70 2e 69 73 4d 61 73 46 6f 72 6d  f mfsp.isMasForm
24d0: 28 73 53 74 65 6d 29 3a 0a 20 20 20 20 20 20 20  (sStem):.       
24e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75               aSu
24f0: 67 67 2e 61 64 64 28 73 53 74 65 6d 29 0a 20 20  gg.add(sStem).  
2500: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
2510: 20 20 20 20 20 20 20 20 23 20 61 20 76 65 72 62          # a verb
2520: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 56 65  .            sVe
2530: 72 62 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d 61  rb = cr.getLemma
2540: 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29 0a  OfMorph(sMorph).
2550: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 63              if c
2560: 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65 72  onj.hasConj(sVer
2570: 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29  b, ":PQ", ":Q1")
2580: 20 61 6e 64 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e   and conj.hasCon
2590: 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20  j(sVerb, ":PQ", 
25a0: 22 3a 51 33 22 29 3a 0a 20 20 20 20 20 20 20 20  ":Q3"):.        
25b0: 20 20 20 20 20 20 20 20 23 20 57 65 20 61 6c 73          # We als
25c0: 6f 20 63 68 65 63 6b 20 69 66 20 74 68 65 20 76  o check if the v
25d0: 65 72 62 20 68 61 73 20 61 20 66 65 6d 69 6e 69  erb has a femini
25e0: 6e 65 20 66 6f 72 6d 2e 0a 20 20 20 20 20 20 20  ne form..       
25f0: 20 20 20 20 20 20 20 20 20 23 20 49 66 20 6e 6f           # If no
2600: 74 2c 20 77 65 20 63 6f 6e 73 69 64 65 72 20 69  t, we consider i
2610: 74 e2 80 99 73 20 62 65 74 74 65 72 20 74 6f 20  t...s better to 
2620: 6e 6f 74 20 73 75 67 67 65 73 74 20 74 68 65 20  not suggest the 
2630: 6d 61 73 63 75 6c 69 6e 65 20 6f 6e 65 2c 20 61  masculine one, a
2640: 73 20 69 74 20 63 61 6e 20 62 65 20 63 6f 6e 73  s it can be cons
2650: 69 64 65 72 65 64 20 69 6e 76 61 72 69 61 62 6c  idered invariabl
2660: 65 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e..             
2670: 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e     aSugg.add(con
2680: 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62 2c  j.getConj(sVerb,
2690: 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 29 0a   ":PQ", ":Q1")).
26a0: 20 20 20 20 69 66 20 62 53 75 67 67 53 69 6d 69      if bSuggSimi
26b0: 6c 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 65  l:.        for e
26c0: 20 69 6e 20 70 68 6f 6e 65 74 2e 73 65 6c 65 63   in phonet.selec
26d0: 74 53 69 6d 69 6c 28 73 46 6c 65 78 2c 20 22 3a  tSimil(sFlex, ":
26e0: 6d 3a 5b 73 69 5d 22 29 3a 0a 20 20 20 20 20 20  m:[si]"):.      
26f0: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2700: 65 29 0a 20 20 20 20 61 53 75 67 67 2e 64 69 73  e).    aSugg.dis
2710: 63 61 72 64 28 22 22 29 0a 20 20 20 20 69 66 20  card("").    if 
2720: 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20 72  aSugg:.        r
2730: 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61  eturn "|".join(a
2740: 53 75 67 67 29 0a 20 20 20 20 72 65 74 75 72 6e  Sugg).    return
2750: 20 22 22 0a 0a 0a 64 65 66 20 73 75 67 67 4d 61   ""...def suggMa
2760: 73 50 6c 75 72 20 28 73 46 6c 65 78 2c 20 62 53  sPlur (sFlex, bS
2770: 75 67 67 53 69 6d 69 6c 3d 46 61 6c 73 65 29 3a  uggSimil=False):
2780: 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20 6d 61  .    "returns ma
2790: 73 63 75 6c 69 6e 65 20 70 6c 75 72 61 6c 20 66  sculine plural f
27a0: 6f 72 6d 73 22 0a 20 20 20 20 61 53 75 67 67 20  orms".    aSugg 
27b0: 3d 20 73 65 74 28 29 0a 20 20 20 20 66 6f 72 20  = set().    for 
27c0: 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c  sMorph in _oSpel
27d0: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70  lChecker.getMorp
27e0: 68 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20  h(sFlex):.      
27f0: 20 20 69 66 20 6e 6f 74 20 22 3a 56 22 20 69 6e    if not ":V" in
2800: 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   sMorph:.       
2810: 20 20 20 20 20 23 20 6e 6f 74 20 61 20 76 65 72       # not a ver
2820: 62 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  b.            if
2830: 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72 70 68 20   ":m" in sMorph 
2840: 6f 72 20 22 3a 65 22 20 69 6e 20 73 4d 6f 72 70  or ":e" in sMorp
2850: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
2860: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
2870: 67 50 6c 75 72 28 73 46 6c 65 78 29 29 0a 20 20  gPlur(sFlex)).  
2880: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
2890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28a0: 73 53 74 65 6d 20 3d 20 63 72 2e 67 65 74 4c 65  sStem = cr.getLe
28b0: 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70  mmaOfMorph(sMorp
28c0: 68 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h).             
28d0: 20 20 20 69 66 20 6d 66 73 70 2e 69 73 4d 61 73     if mfsp.isMas
28e0: 46 6f 72 6d 28 73 53 74 65 6d 29 3a 0a 20 20 20  Form(sStem):.   
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2900: 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67 50   aSugg.add(suggP
2910: 6c 75 72 28 73 53 74 65 6d 29 29 0a 20 20 20 20  lur(sStem)).    
2920: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2930: 20 20 20 20 20 20 23 20 61 20 76 65 72 62 0a 20        # a verb. 
2940: 20 20 20 20 20 20 20 20 20 20 20 73 56 65 72 62             sVerb
2950: 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d 61 4f 66   = cr.getLemmaOf
2960: 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29 0a 20 20  Morph(sMorph).  
2970: 20 20 20 20 20 20 20 20 20 20 69 66 20 63 6f 6e            if con
2980: 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65 72 62 2c  j.hasConj(sVerb,
2990: 20 22 3a 50 51 22 2c 20 22 3a 51 32 22 29 3a 0a   ":PQ", ":Q2"):.
29a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29b0: 61 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 67  aSugg.add(conj.g
29c0: 65 74 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a  etConj(sVerb, ":
29d0: 50 51 22 2c 20 22 3a 51 32 22 29 29 0a 20 20 20  PQ", ":Q2")).   
29e0: 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 6f           elif co
29f0: 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65 72 62  nj.hasConj(sVerb
2a00: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 3a  , ":PQ", ":Q1"):
2a10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2a20: 20 73 53 75 67 67 20 3d 20 63 6f 6e 6a 2e 67 65   sSugg = conj.ge
2a30: 74 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50  tConj(sVerb, ":P
2a40: 51 22 2c 20 22 3a 51 31 22 29 0a 20 20 20 20 20  Q", ":Q1").     
2a50: 20 20 20 20 20 20 20 20 20 20 20 23 20 69 74 20             # it 
2a60: 69 73 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20  is necessary to 
2a70: 66 69 6c 74 65 72 20 74 68 65 73 65 20 66 6c 65  filter these fle
2a80: 78 69 6f 6e 73 2c 20 6c 69 6b 65 20 e2 80 9c 73  xions, like ...s
2a90: 75 63 63 c3 a9 64 c3 a9 e2 80 9d 20 6f 72 20 e2  ucc..d..... or .
2aa0: 80 9c 61 67 69 e2 80 9d 20 74 68 61 74 20 61 72  ..agi... that ar
2ab0: 65 20 6e 6f 74 20 6d 61 73 63 75 6c 69 6e 65 20  e not masculine 
2ac0: 70 6c 75 72 61 6c 2e 0a 20 20 20 20 20 20 20 20  plural..        
2ad0: 20 20 20 20 20 20 20 20 69 66 20 73 53 75 67 67          if sSugg
2ae0: 2e 65 6e 64 73 77 69 74 68 28 22 73 22 29 3a 0a  .endswith("s"):.
2af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b00: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 53      aSugg.add(sS
2b10: 75 67 67 29 0a 20 20 20 20 69 66 20 62 53 75 67  ugg).    if bSug
2b20: 67 53 69 6d 69 6c 3a 0a 20 20 20 20 20 20 20 20  gSimil:.        
2b30: 66 6f 72 20 65 20 69 6e 20 70 68 6f 6e 65 74 2e  for e in phonet.
2b40: 73 65 6c 65 63 74 53 69 6d 69 6c 28 73 46 6c 65  selectSimil(sFle
2b50: 78 2c 20 22 3a 6d 3a 5b 70 69 5d 22 29 3a 0a 20  x, ":m:[pi]"):. 
2b60: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
2b70: 2e 61 64 64 28 65 29 0a 20 20 20 20 61 53 75 67  .add(e).    aSug
2b80: 67 2e 64 69 73 63 61 72 64 28 22 22 29 0a 20 20  g.discard("").  
2b90: 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20    if aSugg:.    
2ba0: 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a      return "|".j
2bb0: 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72  oin(aSugg).    r
2bc0: 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73  eturn ""...def s
2bd0: 75 67 67 46 65 6d 53 69 6e 67 20 28 73 46 6c 65  uggFemSing (sFle
2be0: 78 2c 20 62 53 75 67 67 53 69 6d 69 6c 3d 46 61  x, bSuggSimil=Fa
2bf0: 6c 73 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72  lse):.    "retur
2c00: 6e 73 20 66 65 6d 69 6e 69 6e 65 20 73 69 6e 67  ns feminine sing
2c10: 75 6c 61 72 20 66 6f 72 6d 73 22 0a 20 20 20 20  ular forms".    
2c20: 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20  aSugg = set().  
2c30: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
2c40: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
2c50: 65 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a  etMorph(sFlex):.
2c60: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 22          if not "
2c70: 3a 56 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :V" in sMorph:. 
2c80: 20 20 20 20 20 20 20 20 20 20 20 23 20 6e 6f 74             # not
2c90: 20 61 20 76 65 72 62 0a 20 20 20 20 20 20 20 20   a verb.        
2ca0: 20 20 20 20 69 66 20 22 3a 66 22 20 69 6e 20 73      if ":f" in s
2cb0: 4d 6f 72 70 68 20 6f 72 20 22 3a 65 22 20 69 6e  Morph or ":e" in
2cc0: 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   sMorph:.       
2cd0: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61           aSugg.a
2ce0: 64 64 28 73 75 67 67 53 69 6e 67 28 73 46 6c 65  dd(suggSing(sFle
2cf0: 78 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  x)).            
2d00: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
2d10: 20 20 20 20 20 20 73 53 74 65 6d 20 3d 20 63 72        sStem = cr
2d20: 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68  .getLemmaOfMorph
2d30: 28 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20  (sMorph).       
2d40: 20 20 20 20 20 20 20 20 20 69 66 20 6d 66 73 70           if mfsp
2d50: 2e 69 73 4d 61 73 46 6f 72 6d 28 73 53 74 65 6d  .isMasForm(sStem
2d60: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
2d70: 20 20 20 20 20 20 20 61 53 75 67 67 2e 75 70 64         aSugg.upd
2d80: 61 74 65 28 6d 66 73 70 2e 67 65 74 46 65 6d 46  ate(mfsp.getFemF
2d90: 6f 72 6d 28 73 53 74 65 6d 2c 20 46 61 6c 73 65  orm(sStem, False
2da0: 29 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a  )).        else:
2db0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61  .            # a
2dc0: 20 76 65 72 62 0a 20 20 20 20 20 20 20 20 20 20   verb.          
2dd0: 20 20 73 56 65 72 62 20 3d 20 63 72 2e 67 65 74    sVerb = cr.get
2de0: 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f  LemmaOfMorph(sMo
2df0: 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20 20  rph).           
2e00: 20 69 66 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a   if conj.hasConj
2e10: 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22  (sVerb, ":PQ", "
2e20: 3a 51 33 22 29 3a 0a 20 20 20 20 20 20 20 20 20  :Q3"):.         
2e30: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
2e40: 28 63 6f 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73 56  (conj.getConj(sV
2e50: 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33  erb, ":PQ", ":Q3
2e60: 22 29 29 0a 20 20 20 20 69 66 20 62 53 75 67 67  ")).    if bSugg
2e70: 53 69 6d 69 6c 3a 0a 20 20 20 20 20 20 20 20 66  Simil:.        f
2e80: 6f 72 20 65 20 69 6e 20 70 68 6f 6e 65 74 2e 73  or e in phonet.s
2e90: 65 6c 65 63 74 53 69 6d 69 6c 28 73 46 6c 65 78  electSimil(sFlex
2ea0: 2c 20 22 3a 66 3a 5b 73 69 5d 22 29 3a 0a 20 20  , ":f:[si]"):.  
2eb0: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
2ec0: 61 64 64 28 65 29 0a 20 20 20 20 61 53 75 67 67  add(e).    aSugg
2ed0: 2e 64 69 73 63 61 72 64 28 22 22 29 0a 20 20 20  .discard("").   
2ee0: 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20   if aSugg:.     
2ef0: 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f     return "|".jo
2f00: 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65  in(aSugg).    re
2f10: 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75  turn ""...def su
2f20: 67 67 46 65 6d 50 6c 75 72 20 28 73 46 6c 65 78  ggFemPlur (sFlex
2f30: 2c 20 62 53 75 67 67 53 69 6d 69 6c 3d 46 61 6c  , bSuggSimil=Fal
2f40: 73 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e  se):.    "return
2f50: 73 20 66 65 6d 69 6e 69 6e 65 20 70 6c 75 72 61  s feminine plura
2f60: 6c 20 66 6f 72 6d 73 22 0a 20 20 20 20 61 53 75  l forms".    aSu
2f70: 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20 20 66  gg = set().    f
2f80: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
2f90: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
2fa0: 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20  orph(sFlex):.   
2fb0: 20 20 20 20 20 69 66 20 6e 6f 74 20 22 3a 56 22       if not ":V"
2fc0: 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20   in sMorph:.    
2fd0: 20 20 20 20 20 20 20 20 23 20 6e 6f 74 20 61 20          # not a 
2fe0: 76 65 72 62 0a 20 20 20 20 20 20 20 20 20 20 20  verb.           
2ff0: 20 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72   if ":f" in sMor
3000: 70 68 20 6f 72 20 22 3a 65 22 20 69 6e 20 73 4d  ph or ":e" in sM
3010: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
3020: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
3030: 73 75 67 67 50 6c 75 72 28 73 46 6c 65 78 29 29  suggPlur(sFlex))
3040: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
3050: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
3060: 20 20 20 73 53 74 65 6d 20 3d 20 63 72 2e 67 65     sStem = cr.ge
3070: 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d  tLemmaOfMorph(sM
3080: 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20  orph).          
3090: 20 20 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73        if mfsp.is
30a0: 4d 61 73 46 6f 72 6d 28 73 53 74 65 6d 29 3a 0a  MasForm(sStem):.
30b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30c0: 20 20 20 20 61 53 75 67 67 2e 75 70 64 61 74 65      aSugg.update
30d0: 28 6d 66 73 70 2e 67 65 74 46 65 6d 46 6f 72 6d  (mfsp.getFemForm
30e0: 28 73 53 74 65 6d 2c 20 54 72 75 65 29 29 0a 20  (sStem, True)). 
30f0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
3100: 20 20 20 20 20 20 20 20 20 23 20 61 20 76 65 72           # a ver
3110: 62 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 56  b.            sV
3120: 65 72 62 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d  erb = cr.getLemm
3130: 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29  aOfMorph(sMorph)
3140: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
3150: 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65  conj.hasConj(sVe
3160: 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 34 22  rb, ":PQ", ":Q4"
3170: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
3180: 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e     aSugg.add(con
3190: 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62 2c  j.getConj(sVerb,
31a0: 20 22 3a 50 51 22 2c 20 22 3a 51 34 22 29 29 0a   ":PQ", ":Q4")).
31b0: 20 20 20 20 69 66 20 62 53 75 67 67 53 69 6d 69      if bSuggSimi
31c0: 6c 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 65  l:.        for e
31d0: 20 69 6e 20 70 68 6f 6e 65 74 2e 73 65 6c 65 63   in phonet.selec
31e0: 74 53 69 6d 69 6c 28 73 46 6c 65 78 2c 20 22 3a  tSimil(sFlex, ":
31f0: 66 3a 5b 70 69 5d 22 29 3a 0a 20 20 20 20 20 20  f:[pi]"):.      
3200: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
3210: 65 29 0a 20 20 20 20 61 53 75 67 67 2e 64 69 73  e).    aSugg.dis
3220: 63 61 72 64 28 22 22 29 0a 20 20 20 20 69 66 20  card("").    if 
3230: 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20 72  aSugg:.        r
3240: 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61  eturn "|".join(a
3250: 53 75 67 67 29 0a 20 20 20 20 72 65 74 75 72 6e  Sugg).    return
3260: 20 22 22 0a 0a 0a 64 65 66 20 68 61 73 46 65 6d   ""...def hasFem
3270: 46 6f 72 6d 20 28 73 46 6c 65 78 29 3a 0a 20 20  Form (sFlex):.  
3280: 20 20 22 72 65 74 75 72 6e 20 54 72 75 65 20 69    "return True i
3290: 66 20 74 68 65 72 65 20 69 73 20 61 20 66 65 6d  f there is a fem
32a0: 69 6e 69 6e 65 20 66 6f 72 6d 20 6f 66 20 3c 73  inine form of <s
32b0: 46 6c 65 78 3e 22 0a 20 20 20 20 66 6f 72 20 73  Flex>".    for s
32c0: 53 74 65 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c 43  Stem in _oSpellC
32d0: 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28  hecker.getLemma(
32e0: 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20  sFlex):.        
32f0: 69 66 20 6d 66 73 70 2e 69 73 4d 61 73 46 6f 72  if mfsp.isMasFor
3300: 6d 28 73 53 74 65 6d 29 20 6f 72 20 63 6f 6e 6a  m(sStem) or conj
3310: 2e 68 61 73 43 6f 6e 6a 28 73 53 74 65 6d 2c 20  .hasConj(sStem, 
3320: 22 3a 50 51 22 2c 20 22 3a 51 33 22 29 3a 0a 20  ":PQ", ":Q3"):. 
3330: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
3340: 6e 20 54 72 75 65 0a 20 20 20 20 69 66 20 70 68  n True.    if ph
3350: 6f 6e 65 74 2e 68 61 73 53 69 6d 69 6c 28 73 46  onet.hasSimil(sF
3360: 6c 65 78 2c 20 22 3a 66 22 29 3a 0a 20 20 20 20  lex, ":f"):.    
3370: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
3380: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
3390: 0a 0a 0a 64 65 66 20 68 61 73 4d 61 73 46 6f 72  ...def hasMasFor
33a0: 6d 20 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 22  m (sFlex):.    "
33b0: 72 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 74  return True if t
33c0: 68 65 72 65 20 69 73 20 61 20 6d 61 73 63 75 6c  here is a mascul
33d0: 69 6e 65 20 66 6f 72 6d 20 6f 66 20 3c 73 46 6c  ine form of <sFl
33e0: 65 78 3e 22 0a 20 20 20 20 66 6f 72 20 73 53 74  ex>".    for sSt
33f0: 65 6d 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65  em in _oSpellChe
3400: 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28 73 46  cker.getLemma(sF
3410: 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20 69 66  lex):.        if
3420: 20 6d 66 73 70 2e 69 73 4d 61 73 46 6f 72 6d 28   mfsp.isMasForm(
3430: 73 53 74 65 6d 29 20 6f 72 20 63 6f 6e 6a 2e 68  sStem) or conj.h
3440: 61 73 43 6f 6e 6a 28 73 53 74 65 6d 2c 20 22 3a  asConj(sStem, ":
3450: 50 51 22 2c 20 22 3a 51 31 22 29 3a 0a 20 20 20  PQ", ":Q1"):.   
3460: 20 20 20 20 20 20 20 20 20 23 20 77 68 61 74 20           # what 
3470: 68 61 73 20 61 20 66 65 6d 69 6e 69 6e 65 20 66  has a feminine f
3480: 6f 72 6d 20 61 6c 73 6f 20 68 61 73 20 61 20 6d  orm also has a m
3490: 61 73 63 75 6c 69 6e 65 20 66 6f 72 6d 0a 20 20  asculine form.  
34a0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
34b0: 20 54 72 75 65 0a 20 20 20 20 69 66 20 70 68 6f   True.    if pho
34c0: 6e 65 74 2e 68 61 73 53 69 6d 69 6c 28 73 46 6c  net.hasSimil(sFl
34d0: 65 78 2c 20 22 3a 6d 22 29 3a 0a 20 20 20 20 20  ex, ":m"):.     
34e0: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20     return True. 
34f0: 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a     return False.
3500: 0a 0a 64 65 66 20 73 77 69 74 63 68 47 65 6e 64  ..def switchGend
3510: 65 72 20 28 73 46 6c 65 78 2c 20 62 50 6c 75 72  er (sFlex, bPlur
3520: 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 72 65 74  =None):.    "ret
3530: 75 72 6e 20 66 65 6d 69 6e 69 6e 65 20 6f 72 20  urn feminine or 
3540: 6d 61 73 63 75 6c 69 6e 65 20 66 6f 72 6d 28 73  masculine form(s
3550: 29 20 6f 66 20 3c 73 46 6c 65 78 3e 22 0a 20 20  ) of <sFlex>".  
3560: 20 20 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a    aSugg = set().
3570: 20 20 20 20 69 66 20 62 50 6c 75 72 20 69 73 20      if bPlur is 
3580: 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 20 20 66 6f  None:.        fo
3590: 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70  r sMorph in _oSp
35a0: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f  ellChecker.getMo
35b0: 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20 20  rph(sFlex):.    
35c0: 20 20 20 20 20 20 20 20 69 66 20 22 3a 66 22 20          if ":f" 
35d0: 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20  in sMorph:.     
35e0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22 3a             if ":
35f0: 73 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20  s" in sMorph:.  
3600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3610: 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67    aSugg.add(sugg
3620: 4d 61 73 53 69 6e 67 28 73 46 6c 65 78 29 29 0a  MasSing(sFlex)).
3630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3640: 65 6c 69 66 20 22 3a 70 22 20 69 6e 20 73 4d 6f  elif ":p" in sMo
3650: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rph:.           
3660: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61           aSugg.a
3670: 64 64 28 73 75 67 67 4d 61 73 50 6c 75 72 28 73  dd(suggMasPlur(s
3680: 46 6c 65 78 29 29 0a 20 20 20 20 20 20 20 20 20  Flex)).         
3690: 20 20 20 65 6c 69 66 20 22 3a 6d 22 20 69 6e 20     elif ":m" in 
36a0: 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20  sMorph:.        
36b0: 20 20 20 20 20 20 20 20 69 66 20 22 3a 73 22 20          if ":s" 
36c0: 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20  in sMorph:.     
36d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
36e0: 53 75 67 67 2e 61 64 64 28 73 75 67 67 46 65 6d  Sugg.add(suggFem
36f0: 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20 20  Sing(sFlex)).   
3700: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69               eli
3710: 66 20 22 3a 70 22 20 69 6e 20 73 4d 6f 72 70 68  f ":p" in sMorph
3720: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
3730: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
3740: 73 75 67 67 46 65 6d 50 6c 75 72 28 73 46 6c 65  suggFemPlur(sFle
3750: 78 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  x)).            
3760: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
3770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53                aS
3780: 75 67 67 2e 61 64 64 28 73 75 67 67 46 65 6d 53  ugg.add(suggFemS
3790: 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20 20 20  ing(sFlex)).    
37a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37b0: 61 53 75 67 67 2e 61 64 64 28 73 75 67 67 46 65  aSugg.add(suggFe
37c0: 6d 50 6c 75 72 28 73 46 6c 65 78 29 29 0a 20 20  mPlur(sFlex)).  
37d0: 20 20 65 6c 69 66 20 62 50 6c 75 72 3a 0a 20 20    elif bPlur:.  
37e0: 20 20 20 20 20 20 66 6f 72 20 73 4d 6f 72 70 68        for sMorph
37f0: 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b   in _oSpellCheck
3800: 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c 65  er.getMorph(sFle
3810: 78 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  x):.            
3820: 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72 70  if ":f" in sMorp
3830: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
3840: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
3850: 67 4d 61 73 50 6c 75 72 28 73 46 6c 65 78 29 29  gMasPlur(sFlex))
3860: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69  .            eli
3870: 66 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72 70 68  f ":m" in sMorph
3880: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
3890: 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67    aSugg.add(sugg
38a0: 46 65 6d 50 6c 75 72 28 73 46 6c 65 78 29 29 0a  FemPlur(sFlex)).
38b0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
38c0: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
38d0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
38e0: 65 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a  etMorph(sFlex):.
38f0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22              if "
3900: 3a 66 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :f" in sMorph:. 
3910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
3920: 53 75 67 67 2e 61 64 64 28 73 75 67 67 4d 61 73  Sugg.add(suggMas
3930: 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20 20  Sing(sFlex)).   
3940: 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 22 3a           elif ":
3950: 6d 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20  m" in sMorph:.  
3960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53                aS
3970: 75 67 67 2e 61 64 64 28 73 75 67 67 46 65 6d 53  ugg.add(suggFemS
3980: 69 6e 67 28 73 46 6c 65 78 29 29 0a 20 20 20 20  ing(sFlex)).    
3990: 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20  if aSugg:.      
39a0: 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69    return "|".joi
39b0: 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65 74  n(aSugg).    ret
39c0: 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 77 69  urn ""...def swi
39d0: 74 63 68 50 6c 75 72 61 6c 20 28 73 46 6c 65 78  tchPlural (sFlex
39e0: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 20 70  ):.    "return p
39f0: 6c 75 72 61 6c 20 6f 72 20 73 69 6e 67 75 6c 61  lural or singula
3a00: 72 20 66 6f 72 6d 28 73 29 20 6f 66 20 3c 73 46  r form(s) of <sF
3a10: 6c 65 78 3e 22 0a 20 20 20 20 61 53 75 67 67 20  lex>".    aSugg 
3a20: 3d 20 73 65 74 28 29 0a 20 20 20 20 66 6f 72 20  = set().    for 
3a30: 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c  sMorph in _oSpel
3a40: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70  lChecker.getMorp
3a50: 68 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20  h(sFlex):.      
3a60: 20 20 69 66 20 22 3a 73 22 20 69 6e 20 73 4d 6f    if ":s" in sMo
3a70: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rph:.           
3a80: 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67 50   aSugg.add(suggP
3a90: 6c 75 72 28 73 46 6c 65 78 29 29 0a 20 20 20 20  lur(sFlex)).    
3aa0: 20 20 20 20 65 6c 69 66 20 22 3a 70 22 20 69 6e      elif ":p" in
3ab0: 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   sMorph:.       
3ac0: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73       aSugg.add(s
3ad0: 75 67 67 53 69 6e 67 28 73 46 6c 65 78 29 29 0a  uggSing(sFlex)).
3ae0: 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20      if aSugg:.  
3af0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22        return "|"
3b00: 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20  .join(aSugg).   
3b10: 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66   return ""...def
3b20: 20 68 61 73 53 69 6d 69 6c 20 28 73 57 6f 72 64   hasSimil (sWord
3b30: 2c 20 73 50 61 74 74 65 72 6e 3d 4e 6f 6e 65 29  , sPattern=None)
3b40: 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 20 54 72  :.    "return Tr
3b50: 75 65 20 69 66 20 74 68 65 72 65 20 69 73 20 77  ue if there is w
3b60: 6f 72 64 73 20 70 68 6f 6e 65 74 69 63 61 6c 6c  ords phoneticall
3b70: 79 20 73 69 6d 69 6c 61 72 20 74 6f 20 3c 73 57  y similar to <sW
3b80: 6f 72 64 3e 20 28 61 63 63 6f 72 64 69 6e 67 20  ord> (according 
3b90: 74 6f 20 3c 73 50 61 74 74 65 72 6e 3e 20 69 66  to <sPattern> if
3ba0: 20 72 65 71 75 69 72 65 64 29 22 0a 20 20 20 20   required)".    
3bb0: 72 65 74 75 72 6e 20 70 68 6f 6e 65 74 2e 68 61  return phonet.ha
3bc0: 73 53 69 6d 69 6c 28 73 57 6f 72 64 2c 20 73 50  sSimil(sWord, sP
3bd0: 61 74 74 65 72 6e 29 0a 0a 0a 64 65 66 20 73 75  attern)...def su
3be0: 67 67 53 69 6d 69 6c 20 28 73 57 6f 72 64 2c 20  ggSimil (sWord, 
3bf0: 73 50 61 74 74 65 72 6e 3d 4e 6f 6e 65 2c 20 62  sPattern=None, b
3c00: 53 75 62 73 74 3d 46 61 6c 73 65 2c 20 62 56 43  Subst=False, bVC
3c10: 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 72 65  =False):.    "re
3c20: 74 75 72 6e 20 6c 69 73 74 20 6f 66 20 77 6f 72  turn list of wor
3c30: 64 73 20 70 68 6f 6e 65 74 69 63 61 6c 6c 79 20  ds phonetically 
3c40: 73 69 6d 69 6c 61 72 20 74 6f 20 73 57 6f 72 64  similar to sWord
3c50: 20 61 6e 64 20 77 68 6f 6d 20 50 4f 53 20 69 73   and whom POS is
3c60: 20 6d 61 74 63 68 69 6e 67 20 73 50 61 74 74 65   matching sPatte
3c70: 72 6e 22 0a 20 20 20 20 69 66 20 62 56 43 3a 0a  rn".    if bVC:.
3c80: 20 20 20 20 20 20 20 20 73 57 6f 72 64 2c 20 73          sWord, s
3c90: 53 66 78 20 3d 20 73 70 6c 69 74 56 65 72 62 28  Sfx = splitVerb(
3ca0: 73 57 6f 72 64 29 0a 20 20 20 20 61 53 75 67 67  sWord).    aSugg
3cb0: 20 3d 20 70 68 6f 6e 65 74 2e 73 65 6c 65 63 74   = phonet.select
3cc0: 53 69 6d 69 6c 28 73 57 6f 72 64 2c 20 73 50 61  Simil(sWord, sPa
3cd0: 74 74 65 72 6e 29 0a 20 20 20 20 69 66 20 6e 6f  ttern).    if no
3ce0: 74 20 61 53 75 67 67 20 6f 72 20 6e 6f 74 20 62  t aSugg or not b
3cf0: 53 75 62 73 74 3a 0a 20 20 20 20 20 20 20 20 66  Subst:.        f
3d00: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
3d10: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
3d20: 6f 72 70 68 28 73 57 6f 72 64 29 3a 0a 20 20 20  orph(sWord):.   
3d30: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 75           aSugg.u
3d40: 70 64 61 74 65 28 63 6f 6e 6a 2e 67 65 74 53 69  pdate(conj.getSi
3d50: 6d 69 6c 28 73 57 6f 72 64 2c 20 73 4d 6f 72 70  mil(sWord, sMorp
3d60: 68 2c 20 62 53 75 62 73 74 29 29 0a 20 20 20 20  h, bSubst)).    
3d70: 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20          break.  
3d80: 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20    if aSugg:.    
3d90: 20 20 20 20 69 66 20 62 56 43 3a 0a 20 20 20 20      if bVC:.    
3da0: 20 20 20 20 20 20 20 20 61 53 75 67 67 20 3d 20          aSugg = 
3db0: 6c 69 73 74 28 6d 61 70 28 6c 61 6d 62 64 61 20  list(map(lambda 
3dc0: 73 53 75 67 3a 20 73 53 75 67 20 2b 20 73 53 66  sSug: sSug + sSf
3dd0: 78 2c 20 61 53 75 67 67 29 29 0a 20 20 20 20 20  x, aSugg)).     
3de0: 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f     return "|".jo
3df0: 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72 65  in(aSugg).    re
3e00: 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75  turn ""...def su
3e10: 67 67 43 65 4f 72 43 65 74 20 28 73 57 6f 72 64  ggCeOrCet (sWord
3e20: 29 3a 0a 20 20 20 20 22 73 75 67 67 65 73 74 20  ):.    "suggest 
3e30: e2 80 9c 63 65 e2 80 9d 20 6f 72 20 e2 80 9c 63  ...ce... or ...c
3e40: 65 74 e2 80 9d 20 6f 72 20 62 6f 74 68 20 61 63  et... or both ac
3e50: 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20 66  cording to the f
3e60: 69 72 73 74 20 6c 65 74 74 65 72 20 6f 66 20 3c  irst letter of <
3e70: 73 57 6f 72 64 3e 22 0a 20 20 20 20 69 66 20 72  sWord>".    if r
3e80: 65 2e 6d 61 74 63 68 28 22 28 3f 69 29 5b 61 65  e.match("(?i)[ae
3e90: c3 a9 c3 a8 c3 aa 69 6f 75 79 c3 a2 c3 ae c3 af  ......iouy......
3ea0: 5d 22 2c 20 73 57 6f 72 64 29 3a 0a 20 20 20 20  ]", sWord):.    
3eb0: 20 20 20 20 72 65 74 75 72 6e 20 22 63 65 74 22      return "cet"
3ec0: 0a 20 20 20 20 69 66 20 73 57 6f 72 64 5b 30 3a  .    if sWord[0:
3ed0: 31 5d 20 69 6e 20 22 68 48 22 3a 0a 20 20 20 20  1] in "hH":.    
3ee0: 20 20 20 20 72 65 74 75 72 6e 20 22 63 65 7c 63      return "ce|c
3ef0: 65 74 22 0a 20 20 20 20 72 65 74 75 72 6e 20 22  et".    return "
3f00: 63 65 22 0a 0a 0a 64 65 66 20 73 75 67 67 4c 65  ce"...def suggLe
3f10: 73 4c 61 20 28 73 57 6f 72 64 29 3a 0a 20 20 20  sLa (sWord):.   
3f20: 20 22 73 75 67 67 65 73 74 20 e2 80 9c 6c 65 73   "suggest ...les
3f30: e2 80 9d 20 6f 72 20 e2 80 9c 6c 61 e2 80 9d 20  ... or ...la... 
3f40: 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 3c 73 57  according to <sW
3f50: 6f 72 64 3e 22 0a 20 20 20 20 69 66 20 61 6e 79  ord>".    if any
3f60: 28 20 22 3a 70 22 20 69 6e 20 73 4d 6f 72 70 68  ( ":p" in sMorph
3f70: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
3f80: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
3f90: 65 74 4d 6f 72 70 68 28 73 57 6f 72 64 29 20 29  etMorph(sWord) )
3fa0: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
3fb0: 20 22 6c 65 73 7c 6c 61 22 0a 20 20 20 20 72 65   "les|la".    re
3fc0: 74 75 72 6e 20 22 6c 61 22 0a 0a 0a 5f 7a 42 69  turn "la"..._zBi
3fd0: 6e 61 72 79 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  nary = re.compil
3fe0: 65 28 22 5e 5b 30 31 5d 2b 24 22 29 0a 0a 64 65  e("^[01]+$")..de
3ff0: 66 20 66 6f 72 6d 61 74 4e 75 6d 62 65 72 20 28  f formatNumber (
4000: 73 4e 75 6d 62 65 72 29 3a 0a 20 20 20 20 22 61  sNumber):.    "a
4010: 64 64 20 73 70 61 63 65 73 20 6f 72 20 68 79 70  dd spaces or hyp
4020: 68 65 6e 73 20 74 6f 20 62 69 67 20 6e 75 6d 62  hens to big numb
4030: 65 72 73 22 0a 20 20 20 20 6e 4c 65 6e 20 3d 20  ers".    nLen = 
4040: 6c 65 6e 28 73 4e 75 6d 62 65 72 29 0a 20 20 20  len(sNumber).   
4050: 20 69 66 20 6e 4c 65 6e 20 3c 20 34 3a 0a 20 20   if nLen < 4:.  
4060: 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 4e 75        return sNu
4070: 6d 62 65 72 0a 20 20 20 20 73 52 65 73 20 3d 20  mber.    sRes = 
4080: 22 22 0a 20 20 20 20 69 66 20 22 2c 22 20 6e 6f  "".    if "," no
4090: 74 20 69 6e 20 73 4e 75 6d 62 65 72 3a 0a 20 20  t in sNumber:.  
40a0: 20 20 20 20 20 20 23 20 6e 6f 6d 62 72 65 20 65        # nombre e
40b0: 6e 74 69 65 72 0a 20 20 20 20 20 20 20 20 73 52  ntier.        sR
40c0: 65 73 20 3d 20 5f 66 6f 72 6d 61 74 4e 75 6d 62  es = _formatNumb
40d0: 65 72 28 73 4e 75 6d 62 65 72 2c 20 33 29 0a 20  er(sNumber, 3). 
40e0: 20 20 20 20 20 20 20 23 20 62 69 6e 61 69 72 65         # binaire
40f0: 0a 20 20 20 20 20 20 20 20 69 66 20 5f 7a 42 69  .        if _zBi
4100: 6e 61 72 79 2e 73 65 61 72 63 68 28 73 4e 75 6d  nary.search(sNum
4110: 62 65 72 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ber):.          
4120: 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b 20    sRes += "|" + 
4130: 5f 66 6f 72 6d 61 74 4e 75 6d 62 65 72 28 73 4e  _formatNumber(sN
4140: 75 6d 62 65 72 2c 20 34 29 0a 20 20 20 20 20 20  umber, 4).      
4150: 20 20 23 20 6e 75 6d c3 a9 72 6f 73 20 64 65 20    # num..ros de 
4160: 74 c3 a9 6c c3 a9 70 68 6f 6e 65 0a 20 20 20 20  t..l..phone.    
4170: 20 20 20 20 69 66 20 6e 4c 65 6e 20 3d 3d 20 31      if nLen == 1
4180: 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  0:.            i
4190: 66 20 73 4e 75 6d 62 65 72 2e 73 74 61 72 74 73  f sNumber.starts
41a0: 77 69 74 68 28 22 30 22 29 3a 0a 20 20 20 20 20  with("0"):.     
41b0: 20 20 20 20 20 20 20 20 20 20 20 73 52 65 73 20             sRes 
41c0: 2b 3d 20 22 7c 22 20 2b 20 5f 66 6f 72 6d 61 74  += "|" + _format
41d0: 4e 75 6d 62 65 72 28 73 4e 75 6d 62 65 72 2c 20  Number(sNumber, 
41e0: 32 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2)              
41f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4220: 20 20 20 23 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65     # t..l..phone
4230: 20 66 72 61 6e c3 a7 61 69 73 0a 20 20 20 20 20   fran..ais.     
4240: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4e             if sN
4250: 75 6d 62 65 72 5b 31 5d 20 3d 3d 20 22 34 22 20  umber[1] == "4" 
4260: 61 6e 64 20 28 73 4e 75 6d 62 65 72 5b 32 5d 3d  and (sNumber[2]=
4270: 3d 22 37 22 20 6f 72 20 73 4e 75 6d 62 65 72 5b  ="7" or sNumber[
4280: 32 5d 3d 3d 22 38 22 20 6f 72 20 73 4e 75 6d 62  2]=="8" or sNumb
4290: 65 72 5b 32 5d 3d 3d 22 39 22 29 3a 0a 20 20 20  er[2]=="9"):.   
42a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42b0: 20 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b 20 73   sRes += "|" + s
42c0: 4e 75 6d 62 65 72 5b 30 3a 34 5d 20 2b 20 22 c2  Number[0:4] + ".
42d0: a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 34 3a 36  ." + sNumber[4:6
42e0: 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62  ] + ".." + sNumb
42f0: 65 72 5b 36 3a 38 5d 20 2b 20 22 c2 a0 22 20 2b  er[6:8] + ".." +
4300: 20 73 4e 75 6d 62 65 72 5b 38 3a 5d 20 20 20 20   sNumber[8:]    
4310: 20 20 20 20 20 20 20 20 23 20 6d 6f 62 69 6c 65          # mobile
4320: 20 62 65 6c 67 65 0a 20 20 20 20 20 20 20 20 20   belge.         
4330: 20 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22         sRes += "
4340: 7c 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 33  |" + sNumber[0:3
4350: 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62  ] + ".." + sNumb
4360: 65 72 5b 33 3a 36 5d 20 2b 20 22 c2 a0 22 20 2b  er[3:6] + ".." +
4370: 20 73 4e 75 6d 62 65 72 5b 36 3a 38 5d 20 2b 20   sNumber[6:8] + 
4380: 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 38  ".." + sNumber[8
4390: 3a 5d 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :]              
43a0: 20 20 23 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65 20    # t..l..phone 
43b0: 73 75 69 73 73 65 0a 20 20 20 20 20 20 20 20 20  suisse.         
43c0: 20 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b     sRes += "|" +
43d0: 20 73 4e 75 6d 62 65 72 5b 30 3a 34 5d 20 2b 20   sNumber[0:4] + 
43e0: 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 34  ".." + sNumber[4
43f0: 3a 37 5d 20 2b 20 22 2d 22 20 2b 20 73 4e 75 6d  :7] + "-" + sNum
4400: 62 65 72 5b 37 3a 5d 20 20 20 20 20 20 20 20 20  ber[7:]         
4410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4430: 23 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65 20 63 61  # t..l..phone ca
4440: 6e 61 64 69 65 6e 20 6f 75 20 61 6d c3 a9 72 69  nadien ou am..ri
4450: 63 61 69 6e 0a 20 20 20 20 20 20 20 20 65 6c 69  cain.        eli
4460: 66 20 6e 4c 65 6e 20 3d 3d 20 39 20 61 6e 64 20  f nLen == 9 and 
4470: 73 4e 75 6d 62 65 72 2e 73 74 61 72 74 73 77 69  sNumber.startswi
4480: 74 68 28 22 30 22 29 3a 0a 20 20 20 20 20 20 20  th("0"):.       
4490: 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c 22       sRes += "|"
44a0: 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 33 5d 20   + sNumber[0:3] 
44b0: 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72  + ".." + sNumber
44c0: 5b 33 3a 35 5d 20 2b 20 22 c2 a0 22 20 2b 20 73  [3:5] + ".." + s
44d0: 4e 75 6d 62 65 72 5b 35 3a 37 5d 20 2b 20 22 c2  Number[5:7] + ".
44e0: a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 37 3a 39  ." + sNumber[7:9
44f0: 5d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ]               
4500: 20 20 20 20 23 20 66 69 78 65 20 62 65 6c 67 65      # fixe belge
4510: 20 31 0a 20 20 20 20 20 20 20 20 20 20 20 20 73   1.            s
4520: 52 65 73 20 2b 3d 20 22 7c 22 20 2b 20 73 4e 75  Res += "|" + sNu
4530: 6d 62 65 72 5b 30 3a 32 5d 20 2b 20 22 c2 a0 22  mber[0:2] + ".."
4540: 20 2b 20 73 4e 75 6d 62 65 72 5b 32 3a 35 5d 20   + sNumber[2:5] 
4550: 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72  + ".." + sNumber
4560: 5b 35 3a 37 5d 20 2b 20 22 c2 a0 22 20 2b 20 73  [5:7] + ".." + s
4570: 4e 75 6d 62 65 72 5b 37 3a 39 5d 20 20 20 20 20  Number[7:9]     
4580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
4590: 66 69 78 65 20 62 65 6c 67 65 20 32 0a 20 20 20  fixe belge 2.   
45a0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 23   else:.        #
45b0: 20 4e 6f 6d 62 72 65 20 72 c3 a9 65 6c 0a 20 20   Nombre r..el.  
45c0: 20 20 20 20 20 20 73 49 6e 74 2c 20 73 46 6c 6f        sInt, sFlo
45d0: 61 74 20 3d 20 73 4e 75 6d 62 65 72 2e 73 70 6c  at = sNumber.spl
45e0: 69 74 28 22 2c 22 2c 20 31 29 0a 20 20 20 20 20  it(",", 1).     
45f0: 20 20 20 73 52 65 73 20 3d 20 5f 66 6f 72 6d 61     sRes = _forma
4600: 74 4e 75 6d 62 65 72 28 73 49 6e 74 2c 20 33 29  tNumber(sInt, 3)
4610: 20 2b 20 22 2c 22 20 2b 20 73 46 6c 6f 61 74 0a   + "," + sFloat.
4620: 20 20 20 20 72 65 74 75 72 6e 20 73 52 65 73 0a      return sRes.
4630: 0a 64 65 66 20 5f 66 6f 72 6d 61 74 4e 75 6d 62  .def _formatNumb
4640: 65 72 20 28 73 4e 75 6d 62 65 72 2c 20 6e 47 72  er (sNumber, nGr
4650: 6f 75 70 3d 33 29 3a 0a 20 20 20 20 73 52 65 73  oup=3):.    sRes
4660: 20 3d 20 22 22 0a 20 20 20 20 6e 45 6e 64 20 3d   = "".    nEnd =
4670: 20 6c 65 6e 28 73 4e 75 6d 62 65 72 29 0a 20 20   len(sNumber).  
4680: 20 20 77 68 69 6c 65 20 6e 45 6e 64 20 3e 20 30    while nEnd > 0
4690: 3a 0a 20 20 20 20 20 20 20 20 6e 53 74 61 72 74  :.        nStart
46a0: 20 3d 20 6d 61 78 28 6e 45 6e 64 2d 6e 47 72 6f   = max(nEnd-nGro
46b0: 75 70 2c 20 30 29 0a 20 20 20 20 20 20 20 20 73  up, 0).        s
46c0: 52 65 73 20 3d 20 73 4e 75 6d 62 65 72 5b 6e 53  Res = sNumber[nS
46d0: 74 61 72 74 3a 6e 45 6e 64 5d 20 2b 20 22 c2 a0  tart:nEnd] + "..
46e0: 22 20 2b 20 73 52 65 73 20 20 69 66 20 73 52 65  " + sRes  if sRe
46f0: 73 20 20 65 6c 73 65 20 73 4e 75 6d 62 65 72 5b  s  else sNumber[
4700: 6e 53 74 61 72 74 3a 6e 45 6e 64 5d 0a 20 20 20  nStart:nEnd].   
4710: 20 20 20 20 20 6e 45 6e 64 20 3d 20 6e 45 6e 64       nEnd = nEnd
4720: 20 2d 20 6e 47 72 6f 75 70 0a 20 20 20 20 72 65   - nGroup.    re
4730: 74 75 72 6e 20 73 52 65 73 0a 0a 0a 64 65 66 20  turn sRes...def 
4740: 66 6f 72 6d 61 74 4e 46 20 28 73 29 3a 0a 20 20  formatNF (s):.  
4750: 20 20 22 74 79 70 6f 67 72 61 70 68 79 3a 20 66    "typography: f
4760: 6f 72 6d 61 74 20 4e 46 20 72 65 66 65 72 65 6e  ormat NF referen
4770: 63 65 20 28 6e 6f 72 6d 65 20 66 72 61 6e c3 a7  ce (norme fran..
4780: 61 69 73 65 29 22 0a 20 20 20 20 74 72 79 3a 0a  aise)".    try:.
4790: 20 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d          m = re.m
47a0: 61 74 63 68 28 22 4e 46 5b 20 c2 a0 2d 5d 3f 28  atch("NF[ ..-]?(
47b0: 43 7c 45 7c 50 7c 51 7c 53 7c 58 7c 5a 7c 45 4e  C|E|P|Q|S|X|Z|EN
47c0: 28 3f 3a 5b 20 c2 a0 2d 5d 49 53 4f 7c 29 29 5b  (?:[ ..-]ISO|))[
47d0: 20 c2 a0 2d 5d 3f 28 5b 30 2d 39 5d 2b 28 3f 3a   ..-]?([0-9]+(?:
47e0: 5b 2f e2 80 91 2d 5d 5b 30 2d 39 5d 2b 7c 29 29  [/...-][0-9]+|))
47f0: 22 2c 20 73 29 0a 20 20 20 20 20 20 20 20 69 66  ", s).        if
4800: 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20   not m:.        
4810: 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 20 20      return "".  
4820: 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 4e 46        return "NF
4830: c2 a0 22 20 2b 20 6d 2e 67 72 6f 75 70 28 31 29  .." + m.group(1)
4840: 2e 75 70 70 65 72 28 29 2e 72 65 70 6c 61 63 65  .upper().replace
4850: 28 22 20 22 2c 20 22 c2 a0 22 29 2e 72 65 70 6c  (" ", "..").repl
4860: 61 63 65 28 22 2d 22 2c 20 22 c2 a0 22 29 20 2b  ace("-", "..") +
4870: 20 22 c2 a0 22 20 2b 20 6d 2e 67 72 6f 75 70 28   ".." + m.group(
4880: 32 29 2e 72 65 70 6c 61 63 65 28 22 2f 22 2c 20  2).replace("/", 
4890: 22 e2 80 91 22 29 2e 72 65 70 6c 61 63 65 28 22  "...").replace("
48a0: 2d 22 2c 20 22 e2 80 91 22 29 0a 20 20 20 20 65  -", "...").    e
48b0: 78 63 65 70 74 20 28 72 65 2e 65 72 72 6f 72 2c  xcept (re.error,
48c0: 20 49 6e 64 65 78 45 72 72 6f 72 29 3a 0a 20 20   IndexError):.  
48d0: 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b 2e        traceback.
48e0: 70 72 69 6e 74 5f 65 78 63 28 29 0a 20 20 20 20  print_exc().    
48f0: 20 20 20 20 72 65 74 75 72 6e 20 22 23 20 65 72      return "# er
4900: 72 65 75 72 20 23 22 0a 0a 0a 64 65 66 20 75 6e  reur #"...def un
4910: 64 6f 4c 69 67 61 74 75 72 65 20 28 63 29 3a 0a  doLigature (c):.
4920: 20 20 20 20 22 74 79 70 6f 67 72 61 70 68 79 3a      "typography:
4930: 20 73 70 6c 69 74 20 6c 69 67 61 74 75 72 65 20   split ligature 
4940: 63 68 61 72 61 63 74 65 72 20 3c 63 3e 20 69 6e  character <c> in
4950: 20 73 65 76 65 72 61 6c 20 63 68 61 72 73 22 0a   several chars".
4960: 20 20 20 20 69 66 20 63 20 3d 3d 20 22 ef ac 81      if c == "...
4970: 22 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ":.        retur
4980: 6e 20 22 66 69 22 0a 20 20 20 20 69 66 20 63 20  n "fi".    if c 
4990: 3d 3d 20 22 ef ac 82 22 3a 0a 20 20 20 20 20 20  == "...":.      
49a0: 20 20 72 65 74 75 72 6e 20 22 66 6c 22 0a 20 20    return "fl".  
49b0: 20 20 69 66 20 63 20 3d 3d 20 22 ef ac 80 22 3a    if c == "...":
49c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
49d0: 22 66 66 22 0a 20 20 20 20 69 66 20 63 20 3d 3d  "ff".    if c ==
49e0: 20 22 ef ac 83 22 3a 0a 20 20 20 20 20 20 20 20   "...":.        
49f0: 72 65 74 75 72 6e 20 22 66 66 69 22 0a 20 20 20  return "ffi".   
4a00: 20 69 66 20 63 20 3d 3d 20 22 ef ac 84 22 3a 0a   if c == "...":.
4a10: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
4a20: 66 66 6c 22 0a 20 20 20 20 69 66 20 63 20 3d 3d  ffl".    if c ==
4a30: 20 22 ef ac 85 22 3a 0a 20 20 20 20 20 20 20 20   "...":.        
4a40: 72 65 74 75 72 6e 20 22 66 74 22 0a 20 20 20 20  return "ft".    
4a50: 69 66 20 63 20 3d 3d 20 22 ef ac 86 22 3a 0a 20  if c == "...":. 
4a60: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 73         return "s
4a70: 74 22 0a 20 20 20 20 72 65 74 75 72 6e 20 22 5f  t".    return "_
4a80: 22 0a 0a 0a 0a 0a 5f 78 4e 6f 72 6d 61 6c 69 7a  "....._xNormaliz
4a90: 65 64 43 68 61 72 73 46 6f 72 49 6e 63 6c 75 73  edCharsForInclus
4aa0: 69 76 65 57 72 69 74 69 6e 67 20 3d 20 73 74 72  iveWriting = str
4ab0: 2e 6d 61 6b 65 74 72 61 6e 73 28 7b 0a 20 20 20  .maketrans({.   
4ac0: 20 27 28 27 3a 20 27 c2 b7 27 2c 20 20 27 29 27   '(': '..',  ')'
4ad0: 3a 20 27 c2 b7 27 2c 0a 20 20 20 20 27 2e 27 3a  : '..',.    '.':
4ae0: 20 27 c2 b7 27 2c 20 20 27 c2 b7 27 3a 20 27 c2   '..',  '..': '.
4af0: b7 27 2c 20 20 27 e2 80 a2 27 3a 20 27 c2 b7 27  .',  '...': '..'
4b00: 2c 0a 20 20 20 20 27 e2 80 93 27 3a 20 27 c2 b7  ,.    '...': '..
4b10: 27 2c 20 20 27 e2 80 94 27 3a 20 27 c2 b7 27 2c  ',  '...': '..',
4b20: 0a 20 20 20 20 27 2f 27 3a 20 27 c2 b7 27 0a 7d  .    '/': '..'.}
4b30: 29 0a 0a 0a 64 65 66 20 6e 6f 72 6d 61 6c 69 7a  )...def normaliz
4b40: 65 49 6e 63 6c 75 73 69 76 65 57 72 69 74 69 6e  eInclusiveWritin
4b50: 67 20 28 73 54 6f 6b 65 6e 29 3a 0a 20 20 20 20  g (sToken):.    
4b60: 22 74 79 70 6f 67 72 61 70 68 79 3a 20 72 65 70  "typography: rep
4b70: 6c 61 63 65 20 77 6f 72 64 20 73 65 70 61 72 61  lace word separa
4b80: 74 6f 72 73 20 75 73 65 64 20 69 6e 20 69 6e 63  tors used in inc
4b90: 6c 75 73 69 76 65 20 77 72 69 74 69 6e 67 20 62  lusive writing b
4ba0: 79 20 75 6e 64 65 72 73 63 6f 72 65 20 28 5f 29  y underscore (_)
4bb0: 22 0a 20 20 20 20 72 65 74 75 72 6e 20 73 54 6f  ".    return sTo
4bc0: 6b 65 6e 2e 74 72 61 6e 73 6c 61 74 65 28 5f 78  ken.translate(_x
4bd0: 4e 6f 72 6d 61 6c 69 7a 65 64 43 68 61 72 73 46  NormalizedCharsF
4be0: 6f 72 49 6e 63 6c 75 73 69 76 65 57 72 69 74 69  orInclusiveWriti
4bf0: 6e 67 29 2e 72 65 70 6c 61 63 65 28 22 c3 a8 72  ng).replace("..r
4c00: c2 b7 22 2c 20 22 65 72 c2 b7 22 29 2e 72 65 70  ..", "er..").rep
4c10: 6c 61 63 65 28 22 c3 88 52 c2 b7 22 2c 20 22 45  lace("..R..", "E
4c20: 52 c2 b7 22 29 0a                                R..").