Grammalecte  Hex Artifact Content

Artifact 74625aeb66ba678401e43e56119c890fd7ffc7e4c537ec7570c5ec82f1c29dd9:


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 61 53 75 67 67 2e 64 69  ex).    aSugg.di
1f40: 73 63 61 72 64 28 22 22 29 0a 20 20 20 20 69 66  scard("").    if
1f50: 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20   aSugg:.        
1f60: 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28  return "|".join(
1f70: 61 53 75 67 67 29 0a 20 20 20 20 72 65 74 75 72  aSugg).    retur
1f80: 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75 67 67 53  n ""...def suggS
1f90: 69 6e 67 20 28 73 46 6c 65 78 2c 20 62 53 65 6c  ing (sFlex, bSel
1fa0: 66 53 75 67 67 3d 54 72 75 65 29 3a 0a 20 20 20  fSugg=True):.   
1fb0: 20 22 72 65 74 75 72 6e 73 20 73 69 6e 67 75 6c   "returns singul
1fc0: 61 72 20 66 6f 72 6d 73 20 61 73 73 75 6d 69 6e  ar forms assumin
1fd0: 67 20 73 46 6c 65 78 20 69 73 20 70 6c 75 72 61  g sFlex is plura
1fe0: 6c 22 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73  l".    aSugg = s
1ff0: 65 74 28 29 0a 20 20 20 20 69 66 20 73 46 6c 65  et().    if sFle
2000: 78 2e 65 6e 64 73 77 69 74 68 28 22 75 78 22 29  x.endswith("ux")
2010: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 5f 6f 53  :.        if _oS
2020: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73 56 61  pellChecker.isVa
2030: 6c 69 64 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b 22  lid(sFlex[:-2]+"
2040: 6c 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  l"):.           
2050: 20 61 53 75 67 67 2e 61 64 64 28 73 46 6c 65 78   aSugg.add(sFlex
2060: 5b 3a 2d 32 5d 2b 22 6c 22 29 0a 20 20 20 20 20  [:-2]+"l").     
2070: 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43 68 65     if _oSpellChe
2080: 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46 6c  cker.isValid(sFl
2090: 65 78 5b 3a 2d 32 5d 2b 22 69 6c 22 29 3a 0a 20  ex[:-2]+"il"):. 
20a0: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
20b0: 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b  .add(sFlex[:-2]+
20c0: 22 69 6c 22 29 0a 20 20 20 20 69 66 20 73 46 6c  "il").    if sFl
20d0: 65 78 2e 65 6e 64 73 77 69 74 68 28 22 55 58 22  ex.endswith("UX"
20e0: 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 5f 6f  ):.        if _o
20f0: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73 56  SpellChecker.isV
2100: 61 6c 69 64 28 73 46 6c 65 78 5b 3a 2d 32 5d 2b  alid(sFlex[:-2]+
2110: 22 4c 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  "L"):.          
2120: 20 20 61 53 75 67 67 2e 61 64 64 28 73 46 6c 65    aSugg.add(sFle
2130: 78 5b 3a 2d 32 5d 2b 22 4c 22 29 0a 20 20 20 20  x[:-2]+"L").    
2140: 20 20 20 20 69 66 20 5f 6f 53 70 65 6c 6c 43 68      if _oSpellCh
2150: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46  ecker.isValid(sF
2160: 6c 65 78 5b 3a 2d 32 5d 2b 22 49 4c 22 29 3a 0a  lex[:-2]+"IL"):.
2170: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
2180: 67 2e 61 64 64 28 73 46 6c 65 78 5b 3a 2d 32 5d  g.add(sFlex[:-2]
2190: 2b 22 49 4c 22 29 0a 20 20 20 20 69 66 20 73 46  +"IL").    if sF
21a0: 6c 65 78 2e 65 6e 64 73 77 69 74 68 28 28 22 73  lex.endswith(("s
21b0: 22 2c 20 22 78 22 2c 20 22 53 22 2c 20 22 58 22  ", "x", "S", "X"
21c0: 29 29 20 61 6e 64 20 5f 6f 53 70 65 6c 6c 43 68  )) and _oSpellCh
21d0: 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28 73 46  ecker.isValid(sF
21e0: 6c 65 78 5b 3a 2d 31 5d 29 3a 0a 20 20 20 20 20  lex[:-1]):.     
21f0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 46 6c     aSugg.add(sFl
2200: 65 78 5b 3a 2d 31 5d 29 0a 20 20 20 20 69 66 20  ex[:-1]).    if 
2210: 62 53 65 6c 66 53 75 67 67 20 61 6e 64 20 6e 6f  bSelfSugg and no
2220: 74 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20  t aSugg:.       
2230: 20 61 53 75 67 67 2e 61 64 64 28 73 46 6c 65 78   aSugg.add(sFlex
2240: 29 0a 20 20 20 20 61 53 75 67 67 2e 64 69 73 63  ).    aSugg.disc
2250: 61 72 64 28 22 22 29 0a 20 20 20 20 69 66 20 61  ard("").    if a
2260: 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20 72 65  Sugg:.        re
2270: 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61 53  turn "|".join(aS
2280: 75 67 67 29 0a 20 20 20 20 72 65 74 75 72 6e 20  ugg).    return 
2290: 22 22 0a 0a 0a 64 65 66 20 73 75 67 67 4d 61 73  ""...def suggMas
22a0: 53 69 6e 67 20 28 73 46 6c 65 78 2c 20 62 53 75  Sing (sFlex, bSu
22b0: 67 67 53 69 6d 69 6c 3d 46 61 6c 73 65 29 3a 0a  ggSimil=False):.
22c0: 20 20 20 20 22 72 65 74 75 72 6e 73 20 6d 61 73      "returns mas
22d0: 63 75 6c 69 6e 65 20 73 69 6e 67 75 6c 61 72 20  culine singular 
22e0: 66 6f 72 6d 73 22 0a 20 20 20 20 61 53 75 67 67  forms".    aSugg
22f0: 20 3d 20 73 65 74 28 29 0a 20 20 20 20 66 6f 72   = set().    for
2300: 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65   sMorph in _oSpe
2310: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
2320: 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20  ph(sFlex):.     
2330: 20 20 20 69 66 20 6e 6f 74 20 22 3a 56 22 20 69     if not ":V" i
2340: 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20  n sMorph:.      
2350: 20 20 20 20 20 20 23 20 6e 6f 74 20 61 20 76 65        # not a ve
2360: 72 62 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  rb.            i
2370: 66 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72 70 68  f ":m" in sMorph
2380: 20 6f 72 20 22 3a 65 22 20 69 6e 20 73 4d 6f 72   or ":e" in sMor
2390: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
23a0: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75      aSugg.add(su
23b0: 67 67 53 69 6e 67 28 73 46 6c 65 78 29 29 0a 20  ggSing(sFlex)). 
23c0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
23d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
23e0: 20 73 53 74 65 6d 20 3d 20 63 72 2e 67 65 74 4c   sStem = cr.getL
23f0: 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72  emmaOfMorph(sMor
2400: 70 68 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph).            
2410: 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73 4d 61      if mfsp.isMa
2420: 73 46 6f 72 6d 28 73 53 74 65 6d 29 3a 0a 20 20  sForm(sStem):.  
2430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2440: 20 20 61 53 75 67 67 2e 61 64 64 28 73 53 74 65    aSugg.add(sSte
2450: 6d 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a  m).        else:
2460: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61  .            # a
2470: 20 76 65 72 62 0a 20 20 20 20 20 20 20 20 20 20   verb.          
2480: 20 20 73 56 65 72 62 20 3d 20 63 72 2e 67 65 74    sVerb = cr.get
2490: 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f  LemmaOfMorph(sMo
24a0: 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20 20  rph).           
24b0: 20 69 66 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a   if conj.hasConj
24c0: 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22  (sVerb, ":PQ", "
24d0: 3a 51 31 22 29 20 61 6e 64 20 63 6f 6e 6a 2e 68  :Q1") and conj.h
24e0: 61 73 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a  asConj(sVerb, ":
24f0: 50 51 22 2c 20 22 3a 51 33 22 29 3a 0a 20 20 20  PQ", ":Q3"):.   
2500: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 57               # W
2510: 65 20 61 6c 73 6f 20 63 68 65 63 6b 20 69 66 20  e also check if 
2520: 74 68 65 20 76 65 72 62 20 68 61 73 20 61 20 66  the verb has a f
2530: 65 6d 69 6e 69 6e 65 20 66 6f 72 6d 2e 0a 20 20  eminine form..  
2540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
2550: 49 66 20 6e 6f 74 2c 20 77 65 20 63 6f 6e 73 69  If not, we consi
2560: 64 65 72 20 69 74 e2 80 99 73 20 62 65 74 74 65  der it...s bette
2570: 72 20 74 6f 20 6e 6f 74 20 73 75 67 67 65 73 74  r to not suggest
2580: 20 74 68 65 20 6d 61 73 63 75 6c 69 6e 65 20 6f   the masculine o
2590: 6e 65 2c 20 61 73 20 69 74 20 63 61 6e 20 62 65  ne, as it can be
25a0: 20 63 6f 6e 73 69 64 65 72 65 64 20 69 6e 76 61   considered inva
25b0: 72 69 61 62 6c 65 2e 0a 20 20 20 20 20 20 20 20  riable..        
25c0: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64          aSugg.ad
25d0: 64 28 63 6f 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73  d(conj.getConj(s
25e0: 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51  Verb, ":PQ", ":Q
25f0: 31 22 29 29 0a 20 20 20 20 69 66 20 62 53 75 67  1")).    if bSug
2600: 67 53 69 6d 69 6c 3a 0a 20 20 20 20 20 20 20 20  gSimil:.        
2610: 66 6f 72 20 65 20 69 6e 20 70 68 6f 6e 65 74 2e  for e in phonet.
2620: 73 65 6c 65 63 74 53 69 6d 69 6c 28 73 46 6c 65  selectSimil(sFle
2630: 78 2c 20 22 3a 6d 3a 5b 73 69 5d 22 29 3a 0a 20  x, ":m:[si]"):. 
2640: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
2650: 2e 61 64 64 28 65 29 0a 20 20 20 20 61 53 75 67  .add(e).    aSug
2660: 67 2e 64 69 73 63 61 72 64 28 22 22 29 0a 20 20  g.discard("").  
2670: 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20    if aSugg:.    
2680: 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a      return "|".j
2690: 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72  oin(aSugg).    r
26a0: 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 73  eturn ""...def s
26b0: 75 67 67 4d 61 73 50 6c 75 72 20 28 73 46 6c 65  uggMasPlur (sFle
26c0: 78 2c 20 62 53 75 67 67 53 69 6d 69 6c 3d 46 61  x, bSuggSimil=Fa
26d0: 6c 73 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72  lse):.    "retur
26e0: 6e 73 20 6d 61 73 63 75 6c 69 6e 65 20 70 6c 75  ns masculine plu
26f0: 72 61 6c 20 66 6f 72 6d 73 22 0a 20 20 20 20 61  ral forms".    a
2700: 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20  Sugg = set().   
2710: 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f   for sMorph in _
2720: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
2730: 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20  tMorph(sFlex):. 
2740: 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 22 3a         if not ":
2750: 56 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20  V" in sMorph:.  
2760: 20 20 20 20 20 20 20 20 20 20 23 20 6e 6f 74 20            # not 
2770: 61 20 76 65 72 62 0a 20 20 20 20 20 20 20 20 20  a verb.         
2780: 20 20 20 69 66 20 22 3a 6d 22 20 69 6e 20 73 4d     if ":m" in sM
2790: 6f 72 70 68 20 6f 72 20 22 3a 65 22 20 69 6e 20  orph or ":e" in 
27a0: 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20  sMorph:.        
27b0: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64          aSugg.ad
27c0: 64 28 73 75 67 67 50 6c 75 72 28 73 46 6c 65 78  d(suggPlur(sFlex
27d0: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65  )).            e
27e0: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
27f0: 20 20 20 20 20 73 53 74 65 6d 20 3d 20 63 72 2e       sStem = cr.
2800: 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28  getLemmaOfMorph(
2810: 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20  sMorph).        
2820: 20 20 20 20 20 20 20 20 69 66 20 6d 66 73 70 2e          if mfsp.
2830: 69 73 4d 61 73 46 6f 72 6d 28 73 53 74 65 6d 29  isMasForm(sStem)
2840: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2850: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2860: 73 75 67 67 50 6c 75 72 28 73 53 74 65 6d 29 29  suggPlur(sStem))
2870: 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20  .        else:. 
2880: 20 20 20 20 20 20 20 20 20 20 20 23 20 61 20 76             # a v
2890: 65 72 62 0a 20 20 20 20 20 20 20 20 20 20 20 20  erb.            
28a0: 73 56 65 72 62 20 3d 20 63 72 2e 67 65 74 4c 65  sVerb = 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 69  h).            i
28d0: 66 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73  f conj.hasConj(s
28e0: 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51  Verb, ":PQ", ":Q
28f0: 32 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  2"):.           
2900: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 63       aSugg.add(c
2910: 6f 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72  onj.getConj(sVer
2920: 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 32 22 29  b, ":PQ", ":Q2")
2930: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  ).            el
2940: 69 66 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28  if conj.hasConj(
2950: 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a  sVerb, ":PQ", ":
2960: 51 31 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  Q1"):.          
2970: 20 20 20 20 20 20 73 53 75 67 67 20 3d 20 63 6f        sSugg = co
2980: 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62  nj.getConj(sVerb
2990: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 0a  , ":PQ", ":Q1").
29a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29b0: 23 20 69 74 20 69 73 20 6e 65 63 65 73 73 61 72  # it is necessar
29c0: 79 20 74 6f 20 66 69 6c 74 65 72 20 74 68 65 73  y to filter thes
29d0: 65 20 66 6c 65 78 69 6f 6e 73 2c 20 6c 69 6b 65  e flexions, like
29e0: 20 e2 80 9c 73 75 63 63 c3 a9 64 c3 a9 e2 80 9d   ...succ..d.....
29f0: 20 6f 72 20 e2 80 9c 61 67 69 e2 80 9d 20 74 68   or ...agi... th
2a00: 61 74 20 61 72 65 20 6e 6f 74 20 6d 61 73 63 75  at are not mascu
2a10: 6c 69 6e 65 20 70 6c 75 72 61 6c 2e 0a 20 20 20  line plural..   
2a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
2a30: 73 53 75 67 67 2e 65 6e 64 73 77 69 74 68 28 22  sSugg.endswith("
2a40: 73 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  s"):.           
2a50: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61           aSugg.a
2a60: 64 64 28 73 53 75 67 67 29 0a 20 20 20 20 69 66  dd(sSugg).    if
2a70: 20 62 53 75 67 67 53 69 6d 69 6c 3a 0a 20 20 20   bSuggSimil:.   
2a80: 20 20 20 20 20 66 6f 72 20 65 20 69 6e 20 70 68       for e in ph
2a90: 6f 6e 65 74 2e 73 65 6c 65 63 74 53 69 6d 69 6c  onet.selectSimil
2aa0: 28 73 46 6c 65 78 2c 20 22 3a 6d 3a 5b 70 69 5d  (sFlex, ":m:[pi]
2ab0: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
2ac0: 61 53 75 67 67 2e 61 64 64 28 65 29 0a 20 20 20  aSugg.add(e).   
2ad0: 20 61 53 75 67 67 2e 64 69 73 63 61 72 64 28 22   aSugg.discard("
2ae0: 22 29 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a  ").    if aSugg:
2af0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
2b00: 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a  "|".join(aSugg).
2b10: 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a      return ""...
2b20: 64 65 66 20 73 75 67 67 46 65 6d 53 69 6e 67 20  def suggFemSing 
2b30: 28 73 46 6c 65 78 2c 20 62 53 75 67 67 53 69 6d  (sFlex, bSuggSim
2b40: 69 6c 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22  il=False):.    "
2b50: 72 65 74 75 72 6e 73 20 66 65 6d 69 6e 69 6e 65  returns feminine
2b60: 20 73 69 6e 67 75 6c 61 72 20 66 6f 72 6d 73 22   singular forms"
2b70: 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73 65 74  .    aSugg = set
2b80: 28 29 0a 20 20 20 20 66 6f 72 20 73 4d 6f 72 70  ().    for sMorp
2b90: 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  h in _oSpellChec
2ba0: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c  ker.getMorph(sFl
2bb0: 65 78 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20  ex):.        if 
2bc0: 6e 6f 74 20 22 3a 56 22 20 69 6e 20 73 4d 6f 72  not ":V" in sMor
2bd0: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
2be0: 23 20 6e 6f 74 20 61 20 76 65 72 62 0a 20 20 20  # not a verb.   
2bf0: 20 20 20 20 20 20 20 20 20 69 66 20 22 3a 66 22           if ":f"
2c00: 20 69 6e 20 73 4d 6f 72 70 68 20 6f 72 20 22 3a   in sMorph or ":
2c10: 65 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20  e" in sMorph:.  
2c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53                aS
2c30: 75 67 67 2e 61 64 64 28 73 75 67 67 53 69 6e 67  ugg.add(suggSing
2c40: 28 73 46 6c 65 78 29 29 0a 20 20 20 20 20 20 20  (sFlex)).       
2c50: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
2c60: 20 20 20 20 20 20 20 20 20 20 20 73 53 74 65 6d             sStem
2c70: 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d 61 4f 66   = cr.getLemmaOf
2c80: 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29 0a 20 20  Morph(sMorph).  
2c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
2ca0: 20 6d 66 73 70 2e 69 73 4d 61 73 46 6f 72 6d 28   mfsp.isMasForm(
2cb0: 73 53 74 65 6d 29 3a 0a 20 20 20 20 20 20 20 20  sStem):.        
2cc0: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
2cd0: 67 2e 75 70 64 61 74 65 28 6d 66 73 70 2e 67 65  g.update(mfsp.ge
2ce0: 74 46 65 6d 46 6f 72 6d 28 73 53 74 65 6d 2c 20  tFemForm(sStem, 
2cf0: 46 61 6c 73 65 29 29 0a 20 20 20 20 20 20 20 20  False)).        
2d00: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
2d10: 20 20 23 20 61 20 76 65 72 62 0a 20 20 20 20 20    # a verb.     
2d20: 20 20 20 20 20 20 20 73 56 65 72 62 20 3d 20 63         sVerb = c
2d30: 72 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70  r.getLemmaOfMorp
2d40: 68 28 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20  h(sMorph).      
2d50: 20 20 20 20 20 20 69 66 20 63 6f 6e 6a 2e 68 61        if conj.ha
2d60: 73 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50  sConj(sVerb, ":P
2d70: 51 22 2c 20 22 3a 51 33 22 29 3a 0a 20 20 20 20  Q", ":Q3"):.    
2d80: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
2d90: 67 2e 61 64 64 28 63 6f 6e 6a 2e 67 65 74 43 6f  g.add(conj.getCo
2da0: 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c  nj(sVerb, ":PQ",
2db0: 20 22 3a 51 33 22 29 29 0a 20 20 20 20 69 66 20   ":Q3")).    if 
2dc0: 62 53 75 67 67 53 69 6d 69 6c 3a 0a 20 20 20 20  bSuggSimil:.    
2dd0: 20 20 20 20 66 6f 72 20 65 20 69 6e 20 70 68 6f      for e in pho
2de0: 6e 65 74 2e 73 65 6c 65 63 74 53 69 6d 69 6c 28  net.selectSimil(
2df0: 73 46 6c 65 78 2c 20 22 3a 66 3a 5b 73 69 5d 22  sFlex, ":f:[si]"
2e00: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61  ):.            a
2e10: 53 75 67 67 2e 61 64 64 28 65 29 0a 20 20 20 20  Sugg.add(e).    
2e20: 61 53 75 67 67 2e 64 69 73 63 61 72 64 28 22 22  aSugg.discard(""
2e30: 29 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a  ).    if aSugg:.
2e40: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
2e50: 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20  |".join(aSugg). 
2e60: 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64     return ""...d
2e70: 65 66 20 73 75 67 67 46 65 6d 50 6c 75 72 20 28  ef suggFemPlur (
2e80: 73 46 6c 65 78 2c 20 62 53 75 67 67 53 69 6d 69  sFlex, bSuggSimi
2e90: 6c 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 72  l=False):.    "r
2ea0: 65 74 75 72 6e 73 20 66 65 6d 69 6e 69 6e 65 20  eturns feminine 
2eb0: 70 6c 75 72 61 6c 20 66 6f 72 6d 73 22 0a 20 20  plural forms".  
2ec0: 20 20 61 53 75 67 67 20 3d 20 73 65 74 28 29 0a    aSugg = set().
2ed0: 20 20 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69      for sMorph i
2ee0: 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  n _oSpellChecker
2ef0: 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c 65 78 29  .getMorph(sFlex)
2f00: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74  :.        if not
2f10: 20 22 3a 56 22 20 69 6e 20 73 4d 6f 72 70 68 3a   ":V" in sMorph:
2f20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6e  .            # n
2f30: 6f 74 20 61 20 76 65 72 62 0a 20 20 20 20 20 20  ot a verb.      
2f40: 20 20 20 20 20 20 69 66 20 22 3a 66 22 20 69 6e        if ":f" in
2f50: 20 73 4d 6f 72 70 68 20 6f 72 20 22 3a 65 22 20   sMorph or ":e" 
2f60: 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20  in sMorph:.     
2f70: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
2f80: 2e 61 64 64 28 73 75 67 67 50 6c 75 72 28 73 46  .add(suggPlur(sF
2f90: 6c 65 78 29 29 0a 20 20 20 20 20 20 20 20 20 20  lex)).          
2fa0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2fb0: 20 20 20 20 20 20 20 20 73 53 74 65 6d 20 3d 20          sStem = 
2fc0: 63 72 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72  cr.getLemmaOfMor
2fd0: 70 68 28 73 4d 6f 72 70 68 29 0a 20 20 20 20 20  ph(sMorph).     
2fe0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6d 66             if mf
2ff0: 73 70 2e 69 73 4d 61 73 46 6f 72 6d 28 73 53 74  sp.isMasForm(sSt
3000: 65 6d 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  em):.           
3010: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 75           aSugg.u
3020: 70 64 61 74 65 28 6d 66 73 70 2e 67 65 74 46 65  pdate(mfsp.getFe
3030: 6d 46 6f 72 6d 28 73 53 74 65 6d 2c 20 54 72 75  mForm(sStem, Tru
3040: 65 29 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  e)).        else
3050: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
3060: 61 20 76 65 72 62 0a 20 20 20 20 20 20 20 20 20  a verb.         
3070: 20 20 20 73 56 65 72 62 20 3d 20 63 72 2e 67 65     sVerb = cr.ge
3080: 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d  tLemmaOfMorph(sM
3090: 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20  orph).          
30a0: 20 20 69 66 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e    if conj.hasCon
30b0: 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20  j(sVerb, ":PQ", 
30c0: 22 3a 51 34 22 29 3a 0a 20 20 20 20 20 20 20 20  ":Q4"):.        
30d0: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64          aSugg.ad
30e0: 64 28 63 6f 6e 6a 2e 67 65 74 43 6f 6e 6a 28 73  d(conj.getConj(s
30f0: 56 65 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51  Verb, ":PQ", ":Q
3100: 34 22 29 29 0a 20 20 20 20 69 66 20 62 53 75 67  4")).    if bSug
3110: 67 53 69 6d 69 6c 3a 0a 20 20 20 20 20 20 20 20  gSimil:.        
3120: 66 6f 72 20 65 20 69 6e 20 70 68 6f 6e 65 74 2e  for e in phonet.
3130: 73 65 6c 65 63 74 53 69 6d 69 6c 28 73 46 6c 65  selectSimil(sFle
3140: 78 2c 20 22 3a 66 3a 5b 70 69 5d 22 29 3a 0a 20  x, ":f:[pi]"):. 
3150: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
3160: 2e 61 64 64 28 65 29 0a 20 20 20 20 61 53 75 67  .add(e).    aSug
3170: 67 2e 64 69 73 63 61 72 64 28 22 22 29 0a 20 20  g.discard("").  
3180: 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20 20 20    if aSugg:.    
3190: 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22 2e 6a      return "|".j
31a0: 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20 20 72  oin(aSugg).    r
31b0: 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 68  eturn ""...def h
31c0: 61 73 46 65 6d 46 6f 72 6d 20 28 73 46 6c 65 78  asFemForm (sFlex
31d0: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 20 54  ):.    "return T
31e0: 72 75 65 20 69 66 20 74 68 65 72 65 20 69 73 20  rue if there is 
31f0: 61 20 66 65 6d 69 6e 69 6e 65 20 66 6f 72 6d 20  a feminine form 
3200: 6f 66 20 3c 73 46 6c 65 78 3e 22 0a 20 20 20 20  of <sFlex>".    
3210: 66 6f 72 20 73 53 74 65 6d 20 69 6e 20 5f 6f 53  for sStem in _oS
3220: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c  pellChecker.getL
3230: 65 6d 6d 61 28 73 46 6c 65 78 29 3a 0a 20 20 20  emma(sFlex):.   
3240: 20 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73 4d       if mfsp.isM
3250: 61 73 46 6f 72 6d 28 73 53 74 65 6d 29 20 6f 72  asForm(sStem) or
3260: 20 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 53   conj.hasConj(sS
3270: 74 65 6d 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33  tem, ":PQ", ":Q3
3280: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
3290: 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20  return True.    
32a0: 69 66 20 70 68 6f 6e 65 74 2e 68 61 73 53 69 6d  if phonet.hasSim
32b0: 69 6c 28 73 46 6c 65 78 2c 20 22 3a 66 22 29 3a  il(sFlex, ":f"):
32c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
32d0: 54 72 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20  True.    return 
32e0: 46 61 6c 73 65 0a 0a 0a 64 65 66 20 68 61 73 4d  False...def hasM
32f0: 61 73 46 6f 72 6d 20 28 73 46 6c 65 78 29 3a 0a  asForm (sFlex):.
3300: 20 20 20 20 22 72 65 74 75 72 6e 20 54 72 75 65      "return True
3310: 20 69 66 20 74 68 65 72 65 20 69 73 20 61 20 6d   if there is a m
3320: 61 73 63 75 6c 69 6e 65 20 66 6f 72 6d 20 6f 66  asculine form of
3330: 20 3c 73 46 6c 65 78 3e 22 0a 20 20 20 20 66 6f   <sFlex>".    fo
3340: 72 20 73 53 74 65 6d 20 69 6e 20 5f 6f 53 70 65  r sStem in _oSpe
3350: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d  llChecker.getLem
3360: 6d 61 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20  ma(sFlex):.     
3370: 20 20 20 69 66 20 6d 66 73 70 2e 69 73 4d 61 73     if mfsp.isMas
3380: 46 6f 72 6d 28 73 53 74 65 6d 29 20 6f 72 20 63  Form(sStem) or c
3390: 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 53 74 65  onj.hasConj(sSte
33a0: 6d 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29  m, ":PQ", ":Q1")
33b0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
33c0: 77 68 61 74 20 68 61 73 20 61 20 66 65 6d 69 6e  what has a femin
33d0: 69 6e 65 20 66 6f 72 6d 20 61 6c 73 6f 20 68 61  ine form also ha
33e0: 73 20 61 20 6d 61 73 63 75 6c 69 6e 65 20 66 6f  s a masculine fo
33f0: 72 6d 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  rm.            r
3400: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 69  eturn True.    i
3410: 66 20 70 68 6f 6e 65 74 2e 68 61 73 53 69 6d 69  f phonet.hasSimi
3420: 6c 28 73 46 6c 65 78 2c 20 22 3a 6d 22 29 3a 0a  l(sFlex, ":m"):.
3430: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
3440: 72 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20 46  rue.    return F
3450: 61 6c 73 65 0a 0a 0a 64 65 66 20 73 77 69 74 63  alse...def switc
3460: 68 47 65 6e 64 65 72 20 28 73 46 6c 65 78 2c 20  hGender (sFlex, 
3470: 62 50 6c 75 72 3d 4e 6f 6e 65 29 3a 0a 20 20 20  bPlur=None):.   
3480: 20 22 72 65 74 75 72 6e 20 66 65 6d 69 6e 69 6e   "return feminin
3490: 65 20 6f 72 20 6d 61 73 63 75 6c 69 6e 65 20 66  e or masculine f
34a0: 6f 72 6d 28 73 29 20 6f 66 20 3c 73 46 6c 65 78  orm(s) of <sFlex
34b0: 3e 22 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73  >".    aSugg = s
34c0: 65 74 28 29 0a 20 20 20 20 69 66 20 62 50 6c 75  et().    if bPlu
34d0: 72 20 69 73 20 4e 6f 6e 65 3a 0a 20 20 20 20 20  r is None:.     
34e0: 20 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e     for sMorph in
34f0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
3500: 67 65 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a  getMorph(sFlex):
3510: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
3520: 22 3a 66 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a  ":f" in sMorph:.
3530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3540: 69 66 20 22 3a 73 22 20 69 6e 20 73 4d 6f 72 70  if ":s" in sMorp
3550: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
3560: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
3570: 28 73 75 67 67 4d 61 73 53 69 6e 67 28 73 46 6c  (suggMasSing(sFl
3580: 65 78 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  ex)).           
3590: 20 20 20 20 20 65 6c 69 66 20 22 3a 70 22 20 69       elif ":p" i
35a0: 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20  n sMorph:.      
35b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53                aS
35c0: 75 67 67 2e 61 64 64 28 73 75 67 67 4d 61 73 50  ugg.add(suggMasP
35d0: 6c 75 72 28 73 46 6c 65 78 29 29 0a 20 20 20 20  lur(sFlex)).    
35e0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 22 3a 6d          elif ":m
35f0: 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20  " in sMorph:.   
3600: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
3610: 22 3a 73 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a  ":s" in sMorph:.
3620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3630: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75      aSugg.add(su
3640: 67 67 46 65 6d 53 69 6e 67 28 73 46 6c 65 78 29  ggFemSing(sFlex)
3650: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
3660: 20 20 65 6c 69 66 20 22 3a 70 22 20 69 6e 20 73    elif ":p" in s
3670: 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20  Morph:.         
3680: 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67             aSugg
3690: 2e 61 64 64 28 73 75 67 67 46 65 6d 50 6c 75 72  .add(suggFemPlur
36a0: 28 73 46 6c 65 78 29 29 0a 20 20 20 20 20 20 20  (sFlex)).       
36b0: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
36c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
36d0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
36e0: 67 46 65 6d 53 69 6e 67 28 73 46 6c 65 78 29 29  gFemSing(sFlex))
36f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3700: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73       aSugg.add(s
3710: 75 67 67 46 65 6d 50 6c 75 72 28 73 46 6c 65 78  uggFemPlur(sFlex
3720: 29 29 0a 20 20 20 20 65 6c 69 66 20 62 50 6c 75  )).    elif bPlu
3730: 72 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 73  r:.        for s
3740: 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c  Morph in _oSpell
3750: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
3760: 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20  (sFlex):.       
3770: 20 20 20 20 20 69 66 20 22 3a 66 22 20 69 6e 20       if ":f" in 
3780: 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20  sMorph:.        
3790: 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64          aSugg.ad
37a0: 64 28 73 75 67 67 4d 61 73 50 6c 75 72 28 73 46  d(suggMasPlur(sF
37b0: 6c 65 78 29 29 0a 20 20 20 20 20 20 20 20 20 20  lex)).          
37c0: 20 20 65 6c 69 66 20 22 3a 6d 22 20 69 6e 20 73    elif ":m" in s
37d0: 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20  Morph:.         
37e0: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
37f0: 28 73 75 67 67 46 65 6d 50 6c 75 72 28 73 46 6c  (suggFemPlur(sFl
3800: 65 78 29 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20  ex)).    else:. 
3810: 20 20 20 20 20 20 20 66 6f 72 20 73 4d 6f 72 70         for sMorp
3820: 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  h in _oSpellChec
3830: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c  ker.getMorph(sFl
3840: 65 78 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ex):.           
3850: 20 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72   if ":f" in sMor
3860: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
3870: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75      aSugg.add(su
3880: 67 67 4d 61 73 53 69 6e 67 28 73 46 6c 65 78 29  ggMasSing(sFlex)
3890: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  ).            el
38a0: 69 66 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72 70  if ":m" in sMorp
38b0: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
38c0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
38d0: 67 46 65 6d 53 69 6e 67 28 73 46 6c 65 78 29 29  gFemSing(sFlex))
38e0: 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a 20  .    if aSugg:. 
38f0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 7c         return "|
3900: 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20 20  ".join(aSugg).  
3910: 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65    return ""...de
3920: 66 20 73 77 69 74 63 68 50 6c 75 72 61 6c 20 28  f switchPlural (
3930: 73 46 6c 65 78 29 3a 0a 20 20 20 20 22 72 65 74  sFlex):.    "ret
3940: 75 72 6e 20 70 6c 75 72 61 6c 20 6f 72 20 73 69  urn plural or si
3950: 6e 67 75 6c 61 72 20 66 6f 72 6d 28 73 29 20 6f  ngular form(s) o
3960: 66 20 3c 73 46 6c 65 78 3e 22 0a 20 20 20 20 61  f <sFlex>".    a
3970: 53 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20  Sugg = set().   
3980: 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f   for sMorph in _
3990: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
39a0: 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20  tMorph(sFlex):. 
39b0: 20 20 20 20 20 20 20 69 66 20 22 3a 73 22 20 69         if ":s" i
39c0: 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20  n sMorph:.      
39d0: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
39e0: 73 75 67 67 50 6c 75 72 28 73 46 6c 65 78 29 29  suggPlur(sFlex))
39f0: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 22 3a  .        elif ":
3a00: 70 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20  p" in sMorph:.  
3a10: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
3a20: 61 64 64 28 73 75 67 67 53 69 6e 67 28 73 46 6c  add(suggSing(sFl
3a30: 65 78 29 29 0a 20 20 20 20 69 66 20 61 53 75 67  ex)).    if aSug
3a40: 67 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  g:.        retur
3a50: 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67  n "|".join(aSugg
3a60: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a  ).    return "".
3a70: 0a 0a 64 65 66 20 68 61 73 53 69 6d 69 6c 20 28  ..def hasSimil (
3a80: 73 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e 3d  sWord, sPattern=
3a90: 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 72 65 74 75  None):.    "retu
3aa0: 72 6e 20 54 72 75 65 20 69 66 20 74 68 65 72 65  rn True if there
3ab0: 20 69 73 20 77 6f 72 64 73 20 70 68 6f 6e 65 74   is words phonet
3ac0: 69 63 61 6c 6c 79 20 73 69 6d 69 6c 61 72 20 74  ically similar t
3ad0: 6f 20 3c 73 57 6f 72 64 3e 20 28 61 63 63 6f 72  o <sWord> (accor
3ae0: 64 69 6e 67 20 74 6f 20 3c 73 50 61 74 74 65 72  ding to <sPatter
3af0: 6e 3e 20 69 66 20 72 65 71 75 69 72 65 64 29 22  n> if required)"
3b00: 0a 20 20 20 20 72 65 74 75 72 6e 20 70 68 6f 6e  .    return phon
3b10: 65 74 2e 68 61 73 53 69 6d 69 6c 28 73 57 6f 72  et.hasSimil(sWor
3b20: 64 2c 20 73 50 61 74 74 65 72 6e 29 0a 0a 0a 64  d, sPattern)...d
3b30: 65 66 20 73 75 67 67 53 69 6d 69 6c 20 28 73 57  ef suggSimil (sW
3b40: 6f 72 64 2c 20 73 50 61 74 74 65 72 6e 3d 4e 6f  ord, sPattern=No
3b50: 6e 65 2c 20 62 53 75 62 73 74 3d 46 61 6c 73 65  ne, bSubst=False
3b60: 2c 20 62 56 43 3d 46 61 6c 73 65 29 3a 0a 20 20  , bVC=False):.  
3b70: 20 20 22 72 65 74 75 72 6e 20 6c 69 73 74 20 6f    "return list o
3b80: 66 20 77 6f 72 64 73 20 70 68 6f 6e 65 74 69 63  f words phonetic
3b90: 61 6c 6c 79 20 73 69 6d 69 6c 61 72 20 74 6f 20  ally similar to 
3ba0: 73 57 6f 72 64 20 61 6e 64 20 77 68 6f 6d 20 50  sWord and whom P
3bb0: 4f 53 20 69 73 20 6d 61 74 63 68 69 6e 67 20 73  OS is matching s
3bc0: 50 61 74 74 65 72 6e 22 0a 20 20 20 20 69 66 20  Pattern".    if 
3bd0: 62 56 43 3a 0a 20 20 20 20 20 20 20 20 73 57 6f  bVC:.        sWo
3be0: 72 64 2c 20 73 53 66 78 20 3d 20 73 70 6c 69 74  rd, sSfx = split
3bf0: 56 65 72 62 28 73 57 6f 72 64 29 0a 20 20 20 20  Verb(sWord).    
3c00: 61 53 75 67 67 20 3d 20 70 68 6f 6e 65 74 2e 73  aSugg = phonet.s
3c10: 65 6c 65 63 74 53 69 6d 69 6c 28 73 57 6f 72 64  electSimil(sWord
3c20: 2c 20 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20  , sPattern).    
3c30: 69 66 20 6e 6f 74 20 61 53 75 67 67 20 6f 72 20  if not aSugg or 
3c40: 6e 6f 74 20 62 53 75 62 73 74 3a 0a 20 20 20 20  not bSubst:.    
3c50: 20 20 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69      for sMorph i
3c60: 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  n _oSpellChecker
3c70: 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64 29  .getMorph(sWord)
3c80: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53  :.            aS
3c90: 75 67 67 2e 75 70 64 61 74 65 28 63 6f 6e 6a 2e  ugg.update(conj.
3ca0: 67 65 74 53 69 6d 69 6c 28 73 57 6f 72 64 2c 20  getSimil(sWord, 
3cb0: 73 4d 6f 72 70 68 2c 20 62 53 75 62 73 74 29 29  sMorph, bSubst))
3cc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65  .            bre
3cd0: 61 6b 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a  ak.    if aSugg:
3ce0: 0a 20 20 20 20 20 20 20 20 69 66 20 62 56 43 3a  .        if bVC:
3cf0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75  .            aSu
3d00: 67 67 20 3d 20 6c 69 73 74 28 6d 61 70 28 6c 61  gg = list(map(la
3d10: 6d 62 64 61 20 73 53 75 67 3a 20 73 53 75 67 20  mbda sSug: sSug 
3d20: 2b 20 73 53 66 78 2c 20 61 53 75 67 67 29 29 0a  + sSfx, aSugg)).
3d30: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
3d40: 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20  |".join(aSugg). 
3d50: 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64     return ""...d
3d60: 65 66 20 73 75 67 67 43 65 4f 72 43 65 74 20 28  ef suggCeOrCet (
3d70: 73 57 6f 72 64 29 3a 0a 20 20 20 20 22 73 75 67  sWord):.    "sug
3d80: 67 65 73 74 20 e2 80 9c 63 65 e2 80 9d 20 6f 72  gest ...ce... or
3d90: 20 e2 80 9c 63 65 74 e2 80 9d 20 6f 72 20 62 6f   ...cet... or bo
3da0: 74 68 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20  th according to 
3db0: 74 68 65 20 66 69 72 73 74 20 6c 65 74 74 65 72  the first letter
3dc0: 20 6f 66 20 3c 73 57 6f 72 64 3e 22 0a 20 20 20   of <sWord>".   
3dd0: 20 69 66 20 72 65 2e 6d 61 74 63 68 28 22 28 3f   if re.match("(?
3de0: 69 29 5b 61 65 c3 a9 c3 a8 c3 aa 69 6f 75 79 c3  i)[ae......iouy.
3df0: a2 c3 ae c3 af 5d 22 2c 20 73 57 6f 72 64 29 3a  .....]", sWord):
3e00: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3e10: 22 63 65 74 22 0a 20 20 20 20 69 66 20 73 57 6f  "cet".    if sWo
3e20: 72 64 5b 30 3a 31 5d 20 69 6e 20 22 68 48 22 3a  rd[0:1] in "hH":
3e30: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3e40: 22 63 65 7c 63 65 74 22 0a 20 20 20 20 72 65 74  "ce|cet".    ret
3e50: 75 72 6e 20 22 63 65 22 0a 0a 0a 64 65 66 20 73  urn "ce"...def s
3e60: 75 67 67 4c 65 73 4c 61 20 28 73 57 6f 72 64 29  uggLesLa (sWord)
3e70: 3a 0a 20 20 20 20 22 73 75 67 67 65 73 74 20 e2  :.    "suggest .
3e80: 80 9c 6c 65 73 e2 80 9d 20 6f 72 20 e2 80 9c 6c  ..les... or ...l
3e90: 61 e2 80 9d 20 61 63 63 6f 72 64 69 6e 67 20 74  a... according t
3ea0: 6f 20 3c 73 57 6f 72 64 3e 22 0a 20 20 20 20 69  o <sWord>".    i
3eb0: 66 20 61 6e 79 28 20 22 3a 70 22 20 69 6e 20 73  f any( ":p" in s
3ec0: 4d 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72 70  Morph  for sMorp
3ed0: 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  h in _oSpellChec
3ee0: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f  ker.getMorph(sWo
3ef0: 72 64 29 20 29 3a 0a 20 20 20 20 20 20 20 20 72  rd) ):.        r
3f00: 65 74 75 72 6e 20 22 6c 65 73 7c 6c 61 22 0a 20  eturn "les|la". 
3f10: 20 20 20 72 65 74 75 72 6e 20 22 6c 61 22 0a 0a     return "la"..
3f20: 0a 5f 7a 42 69 6e 61 72 79 20 3d 20 72 65 2e 63  ._zBinary = re.c
3f30: 6f 6d 70 69 6c 65 28 22 5e 5b 30 31 5d 2b 24 22  ompile("^[01]+$"
3f40: 29 0a 0a 64 65 66 20 66 6f 72 6d 61 74 4e 75 6d  )..def formatNum
3f50: 62 65 72 20 28 73 4e 75 6d 62 65 72 29 3a 0a 20  ber (sNumber):. 
3f60: 20 20 20 22 61 64 64 20 73 70 61 63 65 73 20 6f     "add spaces o
3f70: 72 20 68 79 70 68 65 6e 73 20 74 6f 20 62 69 67  r hyphens to big
3f80: 20 6e 75 6d 62 65 72 73 22 0a 20 20 20 20 6e 4c   numbers".    nL
3f90: 65 6e 20 3d 20 6c 65 6e 28 73 4e 75 6d 62 65 72  en = len(sNumber
3fa0: 29 0a 20 20 20 20 69 66 20 6e 4c 65 6e 20 3c 20  ).    if nLen < 
3fb0: 34 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  4:.        retur
3fc0: 6e 20 73 4e 75 6d 62 65 72 0a 20 20 20 20 73 52  n sNumber.    sR
3fd0: 65 73 20 3d 20 22 22 0a 20 20 20 20 69 66 20 22  es = "".    if "
3fe0: 2c 22 20 6e 6f 74 20 69 6e 20 73 4e 75 6d 62 65  ," not in sNumbe
3ff0: 72 3a 0a 20 20 20 20 20 20 20 20 23 20 6e 6f 6d  r:.        # nom
4000: 62 72 65 20 65 6e 74 69 65 72 0a 20 20 20 20 20  bre entier.     
4010: 20 20 20 73 52 65 73 20 3d 20 5f 66 6f 72 6d 61     sRes = _forma
4020: 74 4e 75 6d 62 65 72 28 73 4e 75 6d 62 65 72 2c  tNumber(sNumber,
4030: 20 33 29 0a 20 20 20 20 20 20 20 20 23 20 62 69   3).        # bi
4040: 6e 61 69 72 65 0a 20 20 20 20 20 20 20 20 69 66  naire.        if
4050: 20 5f 7a 42 69 6e 61 72 79 2e 73 65 61 72 63 68   _zBinary.search
4060: 28 73 4e 75 6d 62 65 72 29 3a 0a 20 20 20 20 20  (sNumber):.     
4070: 20 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22         sRes += "
4080: 7c 22 20 2b 20 5f 66 6f 72 6d 61 74 4e 75 6d 62  |" + _formatNumb
4090: 65 72 28 73 4e 75 6d 62 65 72 2c 20 34 29 0a 20  er(sNumber, 4). 
40a0: 20 20 20 20 20 20 20 23 20 6e 75 6d c3 a9 72 6f         # num..ro
40b0: 73 20 64 65 20 74 c3 a9 6c c3 a9 70 68 6f 6e 65  s de t..l..phone
40c0: 0a 20 20 20 20 20 20 20 20 69 66 20 6e 4c 65 6e  .        if nLen
40d0: 20 3d 3d 20 31 30 3a 0a 20 20 20 20 20 20 20 20   == 10:.        
40e0: 20 20 20 20 69 66 20 73 4e 75 6d 62 65 72 2e 73      if sNumber.s
40f0: 74 61 72 74 73 77 69 74 68 28 22 30 22 29 3a 0a  tartswith("0"):.
4100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4110: 73 52 65 73 20 2b 3d 20 22 7c 22 20 2b 20 5f 66  sRes += "|" + _f
4120: 6f 72 6d 61 74 4e 75 6d 62 65 72 28 73 4e 75 6d  ormatNumber(sNum
4130: 62 65 72 2c 20 32 29 20 20 20 20 20 20 20 20 20  ber, 2)         
4140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4170: 20 20 20 20 20 20 20 20 23 20 74 c3 a9 6c c3 a9          # t..l..
4180: 70 68 6f 6e 65 20 66 72 61 6e c3 a7 61 69 73 0a  phone fran..ais.
4190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
41a0: 69 66 20 73 4e 75 6d 62 65 72 5b 31 5d 20 3d 3d  if sNumber[1] ==
41b0: 20 22 34 22 20 61 6e 64 20 28 73 4e 75 6d 62 65   "4" and (sNumbe
41c0: 72 5b 32 5d 3d 3d 22 37 22 20 6f 72 20 73 4e 75  r[2]=="7" or sNu
41d0: 6d 62 65 72 5b 32 5d 3d 3d 22 38 22 20 6f 72 20  mber[2]=="8" or 
41e0: 73 4e 75 6d 62 65 72 5b 32 5d 3d 3d 22 39 22 29  sNumber[2]=="9")
41f0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
4200: 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c        sRes += "|
4210: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 34 5d  " + sNumber[0:4]
4220: 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65   + ".." + sNumbe
4230: 72 5b 34 3a 36 5d 20 2b 20 22 c2 a0 22 20 2b 20  r[4:6] + ".." + 
4240: 73 4e 75 6d 62 65 72 5b 36 3a 38 5d 20 2b 20 22  sNumber[6:8] + "
4250: c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 38 3a  .." + sNumber[8:
4260: 5d 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6d  ]            # m
4270: 6f 62 69 6c 65 20 62 65 6c 67 65 0a 20 20 20 20  obile belge.    
4280: 20 20 20 20 20 20 20 20 20 20 20 20 73 52 65 73              sRes
4290: 20 2b 3d 20 22 7c 22 20 2b 20 73 4e 75 6d 62 65   += "|" + sNumbe
42a0: 72 5b 30 3a 33 5d 20 2b 20 22 c2 a0 22 20 2b 20  r[0:3] + ".." + 
42b0: 73 4e 75 6d 62 65 72 5b 33 3a 36 5d 20 2b 20 22  sNumber[3:6] + "
42c0: c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 36 3a  .." + sNumber[6:
42d0: 38 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d  8] + ".." + sNum
42e0: 62 65 72 5b 38 3a 5d 20 20 20 20 20 20 20 20 20  ber[8:]         
42f0: 20 20 20 20 20 20 20 23 20 74 c3 a9 6c c3 a9 70         # t..l..p
4300: 68 6f 6e 65 20 73 75 69 73 73 65 0a 20 20 20 20  hone suisse.    
4310: 20 20 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20          sRes += 
4320: 22 7c 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a  "|" + sNumber[0:
4330: 34 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d  4] + ".." + sNum
4340: 62 65 72 5b 34 3a 37 5d 20 2b 20 22 2d 22 20 2b  ber[4:7] + "-" +
4350: 20 73 4e 75 6d 62 65 72 5b 37 3a 5d 20 20 20 20   sNumber[7:]    
4360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4380: 20 20 20 20 20 23 20 74 c3 a9 6c c3 a9 70 68 6f       # t..l..pho
4390: 6e 65 20 63 61 6e 61 64 69 65 6e 20 6f 75 20 61  ne canadien ou a
43a0: 6d c3 a9 72 69 63 61 69 6e 0a 20 20 20 20 20 20  m..ricain.      
43b0: 20 20 65 6c 69 66 20 6e 4c 65 6e 20 3d 3d 20 39    elif nLen == 9
43c0: 20 61 6e 64 20 73 4e 75 6d 62 65 72 2e 73 74 61   and sNumber.sta
43d0: 72 74 73 77 69 74 68 28 22 30 22 29 3a 0a 20 20  rtswith("0"):.  
43e0: 20 20 20 20 20 20 20 20 20 20 73 52 65 73 20 2b            sRes +
43f0: 3d 20 22 7c 22 20 2b 20 73 4e 75 6d 62 65 72 5b  = "|" + sNumber[
4400: 30 3a 33 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e  0:3] + ".." + sN
4410: 75 6d 62 65 72 5b 33 3a 35 5d 20 2b 20 22 c2 a0  umber[3:5] + "..
4420: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 35 3a 37 5d  " + sNumber[5:7]
4430: 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65   + ".." + sNumbe
4440: 72 5b 37 3a 39 5d 20 20 20 20 20 20 20 20 20 20  r[7:9]          
4450: 20 20 20 20 20 20 20 20 20 23 20 66 69 78 65 20           # fixe 
4460: 62 65 6c 67 65 20 31 0a 20 20 20 20 20 20 20 20  belge 1.        
4470: 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20      sRes += "|" 
4480: 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 32 5d 20 2b  + sNumber[0:2] +
4490: 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b   ".." + sNumber[
44a0: 32 3a 35 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e  2:5] + ".." + sN
44b0: 75 6d 62 65 72 5b 35 3a 37 5d 20 2b 20 22 c2 a0  umber[5:7] + "..
44c0: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 37 3a 39 5d  " + sNumber[7:9]
44d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44e0: 20 20 20 23 20 66 69 78 65 20 62 65 6c 67 65 20     # fixe belge 
44f0: 32 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20  2.    else:.    
4500: 20 20 20 20 23 20 4e 6f 6d 62 72 65 20 72 c3 a9      # Nombre r..
4510: 65 6c 0a 20 20 20 20 20 20 20 20 73 49 6e 74 2c  el.        sInt,
4520: 20 73 46 6c 6f 61 74 20 3d 20 73 4e 75 6d 62 65   sFloat = sNumbe
4530: 72 2e 73 70 6c 69 74 28 22 2c 22 2c 20 31 29 0a  r.split(",", 1).
4540: 20 20 20 20 20 20 20 20 73 52 65 73 20 3d 20 5f          sRes = _
4550: 66 6f 72 6d 61 74 4e 75 6d 62 65 72 28 73 49 6e  formatNumber(sIn
4560: 74 2c 20 33 29 20 2b 20 22 2c 22 20 2b 20 73 46  t, 3) + "," + sF
4570: 6c 6f 61 74 0a 20 20 20 20 72 65 74 75 72 6e 20  loat.    return 
4580: 73 52 65 73 0a 0a 64 65 66 20 5f 66 6f 72 6d 61  sRes..def _forma
4590: 74 4e 75 6d 62 65 72 20 28 73 4e 75 6d 62 65 72  tNumber (sNumber
45a0: 2c 20 6e 47 72 6f 75 70 3d 33 29 3a 0a 20 20 20  , nGroup=3):.   
45b0: 20 73 52 65 73 20 3d 20 22 22 0a 20 20 20 20 6e   sRes = "".    n
45c0: 45 6e 64 20 3d 20 6c 65 6e 28 73 4e 75 6d 62 65  End = len(sNumbe
45d0: 72 29 0a 20 20 20 20 77 68 69 6c 65 20 6e 45 6e  r).    while nEn
45e0: 64 20 3e 20 30 3a 0a 20 20 20 20 20 20 20 20 6e  d > 0:.        n
45f0: 53 74 61 72 74 20 3d 20 6d 61 78 28 6e 45 6e 64  Start = max(nEnd
4600: 2d 6e 47 72 6f 75 70 2c 20 30 29 0a 20 20 20 20  -nGroup, 0).    
4610: 20 20 20 20 73 52 65 73 20 3d 20 73 4e 75 6d 62      sRes = sNumb
4620: 65 72 5b 6e 53 74 61 72 74 3a 6e 45 6e 64 5d 20  er[nStart:nEnd] 
4630: 2b 20 22 c2 a0 22 20 2b 20 73 52 65 73 20 20 69  + ".." + sRes  i
4640: 66 20 73 52 65 73 20 20 65 6c 73 65 20 73 4e 75  f sRes  else sNu
4650: 6d 62 65 72 5b 6e 53 74 61 72 74 3a 6e 45 6e 64  mber[nStart:nEnd
4660: 5d 0a 20 20 20 20 20 20 20 20 6e 45 6e 64 20 3d  ].        nEnd =
4670: 20 6e 45 6e 64 20 2d 20 6e 47 72 6f 75 70 0a 20   nEnd - nGroup. 
4680: 20 20 20 72 65 74 75 72 6e 20 73 52 65 73 0a 0a     return sRes..
4690: 0a 64 65 66 20 66 6f 72 6d 61 74 4e 46 20 28 73  .def formatNF (s
46a0: 29 3a 0a 20 20 20 20 22 74 79 70 6f 67 72 61 70  ):.    "typograp
46b0: 68 79 3a 20 66 6f 72 6d 61 74 20 4e 46 20 72 65  hy: format NF re
46c0: 66 65 72 65 6e 63 65 20 28 6e 6f 72 6d 65 20 66  ference (norme f
46d0: 72 61 6e c3 a7 61 69 73 65 29 22 0a 20 20 20 20  ran..aise)".    
46e0: 74 72 79 3a 0a 20 20 20 20 20 20 20 20 6d 20 3d  try:.        m =
46f0: 20 72 65 2e 6d 61 74 63 68 28 22 4e 46 5b 20 c2   re.match("NF[ .
4700: a0 2d 5d 3f 28 43 7c 45 7c 50 7c 51 7c 53 7c 58  .-]?(C|E|P|Q|S|X
4710: 7c 5a 7c 45 4e 28 3f 3a 5b 20 c2 a0 2d 5d 49 53  |Z|EN(?:[ ..-]IS
4720: 4f 7c 29 29 5b 20 c2 a0 2d 5d 3f 28 5b 30 2d 39  O|))[ ..-]?([0-9
4730: 5d 2b 28 3f 3a 5b 2f e2 80 91 2d 5d 5b 30 2d 39  ]+(?:[/...-][0-9
4740: 5d 2b 7c 29 29 22 2c 20 73 29 0a 20 20 20 20 20  ]+|))", s).     
4750: 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20     if not m:.   
4760: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
4770: 22 22 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  "".        retur
4780: 6e 20 22 4e 46 c2 a0 22 20 2b 20 6d 2e 67 72 6f  n "NF.." + m.gro
4790: 75 70 28 31 29 2e 75 70 70 65 72 28 29 2e 72 65  up(1).upper().re
47a0: 70 6c 61 63 65 28 22 20 22 2c 20 22 c2 a0 22 29  place(" ", "..")
47b0: 2e 72 65 70 6c 61 63 65 28 22 2d 22 2c 20 22 c2  .replace("-", ".
47c0: a0 22 29 20 2b 20 22 c2 a0 22 20 2b 20 6d 2e 67  .") + ".." + m.g
47d0: 72 6f 75 70 28 32 29 2e 72 65 70 6c 61 63 65 28  roup(2).replace(
47e0: 22 2f 22 2c 20 22 e2 80 91 22 29 2e 72 65 70 6c  "/", "...").repl
47f0: 61 63 65 28 22 2d 22 2c 20 22 e2 80 91 22 29 0a  ace("-", "...").
4800: 20 20 20 20 65 78 63 65 70 74 20 28 72 65 2e 65      except (re.e
4810: 72 72 6f 72 2c 20 49 6e 64 65 78 45 72 72 6f 72  rror, IndexError
4820: 29 3a 0a 20 20 20 20 20 20 20 20 74 72 61 63 65  ):.        trace
4830: 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63 28 29  back.print_exc()
4840: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
4850: 22 23 20 65 72 72 65 75 72 20 23 22 0a 0a 0a 64  "# erreur #"...d
4860: 65 66 20 75 6e 64 6f 4c 69 67 61 74 75 72 65 20  ef undoLigature 
4870: 28 63 29 3a 0a 20 20 20 20 22 74 79 70 6f 67 72  (c):.    "typogr
4880: 61 70 68 79 3a 20 73 70 6c 69 74 20 6c 69 67 61  aphy: split liga
4890: 74 75 72 65 20 63 68 61 72 61 63 74 65 72 20 3c  ture character <
48a0: 63 3e 20 69 6e 20 73 65 76 65 72 61 6c 20 63 68  c> in several ch
48b0: 61 72 73 22 0a 20 20 20 20 69 66 20 63 20 3d 3d  ars".    if c ==
48c0: 20 22 ef ac 81 22 3a 0a 20 20 20 20 20 20 20 20   "...":.        
48d0: 72 65 74 75 72 6e 20 22 66 69 22 0a 20 20 20 20  return "fi".    
48e0: 69 66 20 63 20 3d 3d 20 22 ef ac 82 22 3a 0a 20  if c == "...":. 
48f0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 66         return "f
4900: 6c 22 0a 20 20 20 20 69 66 20 63 20 3d 3d 20 22  l".    if c == "
4910: ef ac 80 22 3a 0a 20 20 20 20 20 20 20 20 72 65  ...":.        re
4920: 74 75 72 6e 20 22 66 66 22 0a 20 20 20 20 69 66  turn "ff".    if
4930: 20 63 20 3d 3d 20 22 ef ac 83 22 3a 0a 20 20 20   c == "...":.   
4940: 20 20 20 20 20 72 65 74 75 72 6e 20 22 66 66 69       return "ffi
4950: 22 0a 20 20 20 20 69 66 20 63 20 3d 3d 20 22 ef  ".    if c == ".
4960: ac 84 22 3a 0a 20 20 20 20 20 20 20 20 72 65 74  ..":.        ret
4970: 75 72 6e 20 22 66 66 6c 22 0a 20 20 20 20 69 66  urn "ffl".    if
4980: 20 63 20 3d 3d 20 22 ef ac 85 22 3a 0a 20 20 20   c == "...":.   
4990: 20 20 20 20 20 72 65 74 75 72 6e 20 22 66 74 22       return "ft"
49a0: 0a 20 20 20 20 69 66 20 63 20 3d 3d 20 22 ef ac  .    if c == "..
49b0: 86 22 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  .":.        retu
49c0: 72 6e 20 22 73 74 22 0a 20 20 20 20 72 65 74 75  rn "st".    retu
49d0: 72 6e 20 22 5f 22 0a 0a 0a 0a 0a 5f 78 4e 6f 72  rn "_"....._xNor
49e0: 6d 61 6c 69 7a 65 64 43 68 61 72 73 46 6f 72 49  malizedCharsForI
49f0: 6e 63 6c 75 73 69 76 65 57 72 69 74 69 6e 67 20  nclusiveWriting 
4a00: 3d 20 73 74 72 2e 6d 61 6b 65 74 72 61 6e 73 28  = str.maketrans(
4a10: 7b 0a 20 20 20 20 27 28 27 3a 20 27 5f 27 2c 20  {.    '(': '_', 
4a20: 20 27 29 27 3a 20 27 5f 27 2c 0a 20 20 20 20 27   ')': '_',.    '
4a30: 2e 27 3a 20 27 5f 27 2c 20 20 27 c2 b7 27 3a 20  .': '_',  '..': 
4a40: 27 5f 27 2c 20 20 27 e2 80 a2 27 3a 20 27 5f 27  '_',  '...': '_'
4a50: 2c 0a 20 20 20 20 27 e2 80 93 27 3a 20 27 5f 27  ,.    '...': '_'
4a60: 2c 20 20 27 e2 80 94 27 3a 20 27 5f 27 2c 0a 20  ,  '...': '_',. 
4a70: 20 20 20 27 2f 27 3a 20 27 5f 27 0a 7d 29 0a 0a     '/': '_'.})..
4a80: 0a 64 65 66 20 6e 6f 72 6d 61 6c 69 7a 65 49 6e  .def normalizeIn
4a90: 63 6c 75 73 69 76 65 57 72 69 74 69 6e 67 20 28  clusiveWriting (
4aa0: 73 54 6f 6b 65 6e 29 3a 0a 20 20 20 20 22 74 79  sToken):.    "ty
4ab0: 70 6f 67 72 61 70 68 79 3a 20 72 65 70 6c 61 63  pography: replac
4ac0: 65 20 77 6f 72 64 20 73 65 70 61 72 61 74 6f 72  e word separator
4ad0: 73 20 75 73 65 64 20 69 6e 20 69 6e 63 6c 75 73  s used in inclus
4ae0: 69 76 65 20 77 72 69 74 69 6e 67 20 62 79 20 75  ive writing by u
4af0: 6e 64 65 72 73 63 6f 72 65 20 28 5f 29 22 0a 20  nderscore (_)". 
4b00: 20 20 20 72 65 74 75 72 6e 20 73 54 6f 6b 65 6e     return sToken
4b10: 2e 74 72 61 6e 73 6c 61 74 65 28 5f 78 4e 6f 72  .translate(_xNor
4b20: 6d 61 6c 69 7a 65 64 43 68 61 72 73 46 6f 72 49  malizedCharsForI
4b30: 6e 63 6c 75 73 69 76 65 57 72 69 74 69 6e 67 29  nclusiveWriting)
4b40: 0a                                               .