Grammalecte  Hex Artifact Content

Artifact cfe989f25d023b68ba59e41abbf2f4239ac458f309fdb68db9c67cca844be86b:


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 2c 20 4e 6f 6e 65 2c  lur(sStem, None,
2920: 20 54 72 75 65 29 29 0a 20 20 20 20 20 20 20 20   True)).        
2930: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
2940: 20 20 23 20 61 20 76 65 72 62 0a 20 20 20 20 20    # a verb.     
2950: 20 20 20 20 20 20 20 73 56 65 72 62 20 3d 20 63         sVerb = c
2960: 72 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d 6f 72 70  r.getLemmaOfMorp
2970: 68 28 73 4d 6f 72 70 68 29 0a 20 20 20 20 20 20  h(sMorph).      
2980: 20 20 20 20 20 20 69 66 20 63 6f 6e 6a 2e 68 61        if conj.ha
2990: 73 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50  sConj(sVerb, ":P
29a0: 51 22 2c 20 22 3a 51 32 22 29 3a 0a 20 20 20 20  Q", ":Q2"):.    
29b0: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
29c0: 67 2e 61 64 64 28 63 6f 6e 6a 2e 67 65 74 43 6f  g.add(conj.getCo
29d0: 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c  nj(sVerb, ":PQ",
29e0: 20 22 3a 51 32 22 29 29 0a 20 20 20 20 20 20 20   ":Q2")).       
29f0: 20 20 20 20 20 65 6c 69 66 20 63 6f 6e 6a 2e 68       elif conj.h
2a00: 61 73 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a  asConj(sVerb, ":
2a10: 50 51 22 2c 20 22 3a 51 31 22 29 3a 0a 20 20 20  PQ", ":Q1"):.   
2a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 53 75               sSu
2a30: 67 67 20 3d 20 63 6f 6e 6a 2e 67 65 74 43 6f 6e  gg = conj.getCon
2a40: 6a 28 73 56 65 72 62 2c 20 22 3a 50 51 22 2c 20  j(sVerb, ":PQ", 
2a50: 22 3a 51 31 22 29 0a 20 20 20 20 20 20 20 20 20  ":Q1").         
2a60: 20 20 20 20 20 20 20 23 20 69 74 20 69 73 20 6e         # it is n
2a70: 65 63 65 73 73 61 72 79 20 74 6f 20 66 69 6c 74  ecessary to filt
2a80: 65 72 20 74 68 65 73 65 20 66 6c 65 78 69 6f 6e  er these flexion
2a90: 73 2c 20 6c 69 6b 65 20 e2 80 9c 73 75 63 63 c3  s, like ...succ.
2aa0: a9 64 c3 a9 e2 80 9d 20 6f 72 20 e2 80 9c 61 67  .d..... or ...ag
2ab0: 69 e2 80 9d 20 74 68 61 74 20 61 72 65 20 6e 6f  i... that are no
2ac0: 74 20 6d 61 73 63 75 6c 69 6e 65 20 70 6c 75 72  t masculine plur
2ad0: 61 6c 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20  al..            
2ae0: 20 20 20 20 69 66 20 73 53 75 67 67 2e 65 6e 64      if sSugg.end
2af0: 73 77 69 74 68 28 22 73 22 29 3a 0a 20 20 20 20  swith("s"):.    
2b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2b10: 61 53 75 67 67 2e 61 64 64 28 73 53 75 67 67 29  aSugg.add(sSugg)
2b20: 0a 20 20 20 20 69 66 20 62 53 75 67 67 53 69 6d  .    if bSuggSim
2b30: 69 6c 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20  il:.        for 
2b40: 65 20 69 6e 20 70 68 6f 6e 65 74 2e 73 65 6c 65  e in phonet.sele
2b50: 63 74 53 69 6d 69 6c 28 73 46 6c 65 78 2c 20 22  ctSimil(sFlex, "
2b60: 3a 6d 3a 5b 70 69 5d 22 29 3a 0a 20 20 20 20 20  :m:[pi]"):.     
2b70: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
2b80: 28 65 29 0a 20 20 20 20 61 53 75 67 67 2e 64 69  (e).    aSugg.di
2b90: 73 63 61 72 64 28 22 22 29 0a 20 20 20 20 69 66  scard("").    if
2ba0: 20 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20   aSugg:.        
2bb0: 72 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28  return "|".join(
2bc0: 61 53 75 67 67 29 0a 20 20 20 20 72 65 74 75 72  aSugg).    retur
2bd0: 6e 20 22 22 0a 0a 0a 64 65 66 20 73 75 67 67 46  n ""...def suggF
2be0: 65 6d 53 69 6e 67 20 28 73 46 6c 65 78 2c 20 62  emSing (sFlex, b
2bf0: 53 75 67 67 53 69 6d 69 6c 3d 46 61 6c 73 65 29  SuggSimil=False)
2c00: 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20 66  :.    "returns f
2c10: 65 6d 69 6e 69 6e 65 20 73 69 6e 67 75 6c 61 72  eminine singular
2c20: 20 66 6f 72 6d 73 22 0a 20 20 20 20 61 53 75 67   forms".    aSug
2c30: 67 20 3d 20 73 65 74 28 29 0a 20 20 20 20 66 6f  g = set().    fo
2c40: 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70  r sMorph in _oSp
2c50: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f  ellChecker.getMo
2c60: 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20 20 20  rph(sFlex):.    
2c70: 20 20 20 20 69 66 20 6e 6f 74 20 22 3a 56 22 20      if not ":V" 
2c80: 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20  in sMorph:.     
2c90: 20 20 20 20 20 20 20 23 20 6e 6f 74 20 61 20 76         # not a v
2ca0: 65 72 62 0a 20 20 20 20 20 20 20 20 20 20 20 20  erb.            
2cb0: 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72 70  if ":f" in sMorp
2cc0: 68 20 6f 72 20 22 3a 65 22 20 69 6e 20 73 4d 6f  h or ":e" in sMo
2cd0: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rph:.           
2ce0: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73       aSugg.add(s
2cf0: 75 67 67 53 69 6e 67 28 73 46 6c 65 78 29 29 0a  uggSing(sFlex)).
2d00: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
2d10: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2d20: 20 20 73 53 74 65 6d 20 3d 20 63 72 2e 67 65 74    sStem = cr.get
2d30: 4c 65 6d 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f  LemmaOfMorph(sMo
2d40: 72 70 68 29 0a 20 20 20 20 20 20 20 20 20 20 20  rph).           
2d50: 20 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73 4d       if mfsp.isM
2d60: 61 73 46 6f 72 6d 28 73 53 74 65 6d 29 3a 0a 20  asForm(sStem):. 
2d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d80: 20 20 20 61 53 75 67 67 2e 75 70 64 61 74 65 28     aSugg.update(
2d90: 6d 66 73 70 2e 67 65 74 46 65 6d 46 6f 72 6d 28  mfsp.getFemForm(
2da0: 73 53 74 65 6d 2c 20 46 61 6c 73 65 29 29 0a 20  sStem, False)). 
2db0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2dc0: 20 20 20 20 20 20 20 20 20 23 20 61 20 76 65 72           # a ver
2dd0: 62 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 56  b.            sV
2de0: 65 72 62 20 3d 20 63 72 2e 67 65 74 4c 65 6d 6d  erb = cr.getLemm
2df0: 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68 29  aOfMorph(sMorph)
2e00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
2e10: 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 56 65  conj.hasConj(sVe
2e20: 72 62 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33 22  rb, ":PQ", ":Q3"
2e30: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
2e40: 20 20 20 61 53 75 67 67 2e 61 64 64 28 63 6f 6e     aSugg.add(con
2e50: 6a 2e 67 65 74 43 6f 6e 6a 28 73 56 65 72 62 2c  j.getConj(sVerb,
2e60: 20 22 3a 50 51 22 2c 20 22 3a 51 33 22 29 29 0a   ":PQ", ":Q3")).
2e70: 20 20 20 20 69 66 20 62 53 75 67 67 53 69 6d 69      if bSuggSimi
2e80: 6c 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 65  l:.        for e
2e90: 20 69 6e 20 70 68 6f 6e 65 74 2e 73 65 6c 65 63   in phonet.selec
2ea0: 74 53 69 6d 69 6c 28 73 46 6c 65 78 2c 20 22 3a  tSimil(sFlex, ":
2eb0: 66 3a 5b 73 69 5d 22 29 3a 0a 20 20 20 20 20 20  f:[si]"):.      
2ec0: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
2ed0: 65 29 0a 20 20 20 20 61 53 75 67 67 2e 64 69 73  e).    aSugg.dis
2ee0: 63 61 72 64 28 22 22 29 0a 20 20 20 20 69 66 20  card("").    if 
2ef0: 61 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20 72  aSugg:.        r
2f00: 65 74 75 72 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61  eturn "|".join(a
2f10: 53 75 67 67 29 0a 20 20 20 20 72 65 74 75 72 6e  Sugg).    return
2f20: 20 22 22 0a 0a 0a 64 65 66 20 73 75 67 67 46 65   ""...def suggFe
2f30: 6d 50 6c 75 72 20 28 73 46 6c 65 78 2c 20 62 53  mPlur (sFlex, bS
2f40: 75 67 67 53 69 6d 69 6c 3d 46 61 6c 73 65 29 3a  uggSimil=False):
2f50: 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20 66 65  .    "returns fe
2f60: 6d 69 6e 69 6e 65 20 70 6c 75 72 61 6c 20 66 6f  minine plural fo
2f70: 72 6d 73 22 0a 20 20 20 20 61 53 75 67 67 20 3d  rms".    aSugg =
2f80: 20 73 65 74 28 29 0a 20 20 20 20 66 6f 72 20 73   set().    for s
2f90: 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c  Morph in _oSpell
2fa0: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
2fb0: 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20  (sFlex):.       
2fc0: 20 69 66 20 6e 6f 74 20 22 3a 56 22 20 69 6e 20   if not ":V" in 
2fd0: 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20  sMorph:.        
2fe0: 20 20 20 20 23 20 6e 6f 74 20 61 20 76 65 72 62      # not a verb
2ff0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
3000: 22 3a 66 22 20 69 6e 20 73 4d 6f 72 70 68 20 6f  ":f" in sMorph o
3010: 72 20 22 3a 65 22 20 69 6e 20 73 4d 6f 72 70 68  r ":e" in sMorph
3020: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
3030: 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67    aSugg.add(sugg
3040: 50 6c 75 72 28 73 46 6c 65 78 29 29 0a 20 20 20  Plur(sFlex)).   
3050: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
3060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
3070: 53 74 65 6d 20 3d 20 63 72 2e 67 65 74 4c 65 6d  Stem = cr.getLem
3080: 6d 61 4f 66 4d 6f 72 70 68 28 73 4d 6f 72 70 68  maOfMorph(sMorph
3090: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
30a0: 20 20 69 66 20 6d 66 73 70 2e 69 73 4d 61 73 46    if mfsp.isMasF
30b0: 6f 72 6d 28 73 53 74 65 6d 29 3a 0a 20 20 20 20  orm(sStem):.    
30c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30d0: 61 53 75 67 67 2e 75 70 64 61 74 65 28 6d 66 73  aSugg.update(mfs
30e0: 70 2e 67 65 74 46 65 6d 46 6f 72 6d 28 73 53 74  p.getFemForm(sSt
30f0: 65 6d 2c 20 54 72 75 65 29 29 0a 20 20 20 20 20  em, True)).     
3100: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
3110: 20 20 20 20 20 23 20 61 20 76 65 72 62 0a 20 20       # a verb.  
3120: 20 20 20 20 20 20 20 20 20 20 73 56 65 72 62 20            sVerb 
3130: 3d 20 63 72 2e 67 65 74 4c 65 6d 6d 61 4f 66 4d  = cr.getLemmaOfM
3140: 6f 72 70 68 28 73 4d 6f 72 70 68 29 0a 20 20 20  orph(sMorph).   
3150: 20 20 20 20 20 20 20 20 20 69 66 20 63 6f 6e 6a           if conj
3160: 2e 68 61 73 43 6f 6e 6a 28 73 56 65 72 62 2c 20  .hasConj(sVerb, 
3170: 22 3a 50 51 22 2c 20 22 3a 51 34 22 29 3a 0a 20  ":PQ", ":Q4"):. 
3180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
3190: 53 75 67 67 2e 61 64 64 28 63 6f 6e 6a 2e 67 65  Sugg.add(conj.ge
31a0: 74 43 6f 6e 6a 28 73 56 65 72 62 2c 20 22 3a 50  tConj(sVerb, ":P
31b0: 51 22 2c 20 22 3a 51 34 22 29 29 0a 20 20 20 20  Q", ":Q4")).    
31c0: 69 66 20 62 53 75 67 67 53 69 6d 69 6c 3a 0a 20  if bSuggSimil:. 
31d0: 20 20 20 20 20 20 20 66 6f 72 20 65 20 69 6e 20         for e in 
31e0: 70 68 6f 6e 65 74 2e 73 65 6c 65 63 74 53 69 6d  phonet.selectSim
31f0: 69 6c 28 73 46 6c 65 78 2c 20 22 3a 66 3a 5b 70  il(sFlex, ":f:[p
3200: 69 5d 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  i]"):.          
3210: 20 20 61 53 75 67 67 2e 61 64 64 28 65 29 0a 20    aSugg.add(e). 
3220: 20 20 20 61 53 75 67 67 2e 64 69 73 63 61 72 64     aSugg.discard
3230: 28 22 22 29 0a 20 20 20 20 69 66 20 61 53 75 67  ("").    if aSug
3240: 67 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  g:.        retur
3250: 6e 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67  n "|".join(aSugg
3260: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a  ).    return "".
3270: 0a 0a 64 65 66 20 67 5f 73 75 67 67 41 67 72 65  ..def g_suggAgre
3280: 65 20 28 64 54 6f 6b 65 6e 44 73 74 2c 20 64 54  e (dTokenDst, dT
3290: 6f 6b 65 6e 53 72 63 29 3a 0a 20 20 20 20 22 72  okenSrc):.    "r
32a0: 65 74 75 72 6e 73 20 73 75 67 67 65 73 74 69 6f  eturns suggestio
32b0: 6e 73 20 66 6f 72 20 3c 64 54 6f 6b 65 6e 44 73  ns for <dTokenDs
32c0: 74 3e 20 74 68 61 74 20 6d 61 74 63 68 65 73 20  t> that matches 
32d0: 61 67 72 65 65 6d 65 6e 74 20 77 69 74 68 20 3c  agreement with <
32e0: 64 54 6f 6b 65 6e 53 72 63 3e 22 0a 20 20 20 20  dTokenSrc>".    
32f0: 6c 4d 6f 72 70 68 53 72 63 20 3d 20 64 54 6f 6b  lMorphSrc = dTok
3300: 65 6e 53 72 63 5b 22 6c 4d 6f 72 70 68 22 5d 20  enSrc["lMorph"] 
3310: 20 69 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20   if "lMorph" in 
3320: 64 54 6f 6b 65 6e 53 72 63 20 20 65 6c 73 65 20  dTokenSrc  else 
3330: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
3340: 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 53  getMorph(dTokenS
3350: 72 63 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20  rc["sValue"]).  
3360: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 53    if not lMorphS
3370: 72 63 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  rc:.        retu
3380: 72 6e 20 22 22 0a 20 20 20 20 73 47 65 6e 64 65  rn "".    sGende
3390: 72 2c 20 73 4e 75 6d 62 65 72 20 3d 20 63 72 2e  r, sNumber = cr.
33a0: 67 65 74 47 65 6e 64 65 72 4e 75 6d 62 65 72 28  getGenderNumber(
33b0: 6c 4d 6f 72 70 68 53 72 63 29 0a 20 20 20 20 69  lMorphSrc).    i
33c0: 66 20 73 47 65 6e 64 65 72 20 3d 3d 20 22 3a 6d  f sGender == ":m
33d0: 22 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 4e  ":.        if sN
33e0: 75 6d 62 65 72 20 3d 3d 20 22 3a 73 22 3a 0a 20  umber == ":s":. 
33f0: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
3400: 6e 20 73 75 67 67 4d 61 73 53 69 6e 67 28 64 54  n suggMasSing(dT
3410: 6f 6b 65 6e 44 73 74 5b 22 73 56 61 6c 75 65 22  okenDst["sValue"
3420: 5d 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  ]).        elif 
3430: 73 4e 75 6d 62 65 72 20 3d 3d 20 22 3a 70 22 3a  sNumber == ":p":
3440: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
3450: 75 72 6e 20 73 75 67 67 4d 61 73 50 6c 75 72 28  urn suggMasPlur(
3460: 64 54 6f 6b 65 6e 44 73 74 5b 22 73 56 61 6c 75  dTokenDst["sValu
3470: 65 22 5d 29 0a 20 20 20 20 20 20 20 20 72 65 74  e"]).        ret
3480: 75 72 6e 20 73 75 67 67 4d 61 73 53 69 6e 67 28  urn suggMasSing(
3490: 64 54 6f 6b 65 6e 44 73 74 5b 22 73 56 61 6c 75  dTokenDst["sValu
34a0: 65 22 5d 29 0a 20 20 20 20 65 6c 69 66 20 73 47  e"]).    elif sG
34b0: 65 6e 64 65 72 20 3d 3d 20 22 3a 66 22 3a 0a 20  ender == ":f":. 
34c0: 20 20 20 20 20 20 20 69 66 20 73 4e 75 6d 62 65         if sNumbe
34d0: 72 20 3d 3d 20 22 3a 73 22 3a 0a 20 20 20 20 20  r == ":s":.     
34e0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 75         return su
34f0: 67 67 46 65 6d 53 69 6e 67 28 64 54 6f 6b 65 6e  ggFemSing(dToken
3500: 44 73 74 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20  Dst["sValue"]). 
3510: 20 20 20 20 20 20 20 65 6c 69 66 20 73 4e 75 6d         elif sNum
3520: 62 65 72 20 3d 3d 20 22 3a 70 22 3a 0a 20 20 20  ber == ":p":.   
3530: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
3540: 73 75 67 67 46 65 6d 50 6c 75 72 28 64 54 6f 6b  suggFemPlur(dTok
3550: 65 6e 44 73 74 5b 22 73 56 61 6c 75 65 22 5d 29  enDst["sValue"])
3560: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3570: 73 75 67 67 46 65 6d 53 69 6e 67 28 64 54 6f 6b  suggFemSing(dTok
3580: 65 6e 44 73 74 5b 22 73 56 61 6c 75 65 22 5d 29  enDst["sValue"])
3590: 0a 20 20 20 20 65 6c 69 66 20 73 47 65 6e 64 65  .    elif sGende
35a0: 72 20 3d 3d 20 22 3a 65 22 3a 0a 20 20 20 20 20  r == ":e":.     
35b0: 20 20 20 69 66 20 73 4e 75 6d 62 65 72 20 3d 3d     if sNumber ==
35c0: 20 22 3a 73 22 3a 0a 20 20 20 20 20 20 20 20 20   ":s":.         
35d0: 20 20 20 72 65 74 75 72 6e 20 73 75 67 67 53 69     return suggSi
35e0: 6e 67 28 64 54 6f 6b 65 6e 44 73 74 5b 22 73 56  ng(dTokenDst["sV
35f0: 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20 20  alue"]).        
3600: 65 6c 69 66 20 73 4e 75 6d 62 65 72 20 3d 3d 20  elif sNumber == 
3610: 22 3a 70 22 3a 0a 20 20 20 20 20 20 20 20 20 20  ":p":.          
3620: 20 20 72 65 74 75 72 6e 20 73 75 67 67 50 6c 75    return suggPlu
3630: 72 28 64 54 6f 6b 65 6e 44 73 74 5b 22 73 56 61  r(dTokenDst["sVa
3640: 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20 20 72  lue"]).        r
3650: 65 74 75 72 6e 20 64 54 6f 6b 65 6e 44 73 74 5b  eturn dTokenDst[
3660: 22 73 56 61 6c 75 65 22 5d 0a 20 20 20 20 72 65  "sValue"].    re
3670: 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66 20 68 61  turn ""...def ha
3680: 73 46 65 6d 46 6f 72 6d 20 28 73 46 6c 65 78 29  sFemForm (sFlex)
3690: 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 20 54 72  :.    "return Tr
36a0: 75 65 20 69 66 20 74 68 65 72 65 20 69 73 20 61  ue if there is a
36b0: 20 66 65 6d 69 6e 69 6e 65 20 66 6f 72 6d 20 6f   feminine form o
36c0: 66 20 3c 73 46 6c 65 78 3e 22 0a 20 20 20 20 66  f <sFlex>".    f
36d0: 6f 72 20 73 53 74 65 6d 20 69 6e 20 5f 6f 53 70  or sStem in _oSp
36e0: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65  ellChecker.getLe
36f0: 6d 6d 61 28 73 46 6c 65 78 29 3a 0a 20 20 20 20  mma(sFlex):.    
3700: 20 20 20 20 69 66 20 6d 66 73 70 2e 69 73 4d 61      if mfsp.isMa
3710: 73 46 6f 72 6d 28 73 53 74 65 6d 29 20 6f 72 20  sForm(sStem) or 
3720: 63 6f 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 53 74  conj.hasConj(sSt
3730: 65 6d 2c 20 22 3a 50 51 22 2c 20 22 3a 51 33 22  em, ":PQ", ":Q3"
3740: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  ):.            r
3750: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 69  eturn True.    i
3760: 66 20 70 68 6f 6e 65 74 2e 68 61 73 53 69 6d 69  f phonet.hasSimi
3770: 6c 28 73 46 6c 65 78 2c 20 22 3a 66 22 29 3a 0a  l(sFlex, ":f"):.
3780: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
3790: 72 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20 46  rue.    return F
37a0: 61 6c 73 65 0a 0a 0a 64 65 66 20 68 61 73 4d 61  alse...def hasMa
37b0: 73 46 6f 72 6d 20 28 73 46 6c 65 78 29 3a 0a 20  sForm (sFlex):. 
37c0: 20 20 20 22 72 65 74 75 72 6e 20 54 72 75 65 20     "return True 
37d0: 69 66 20 74 68 65 72 65 20 69 73 20 61 20 6d 61  if there is a ma
37e0: 73 63 75 6c 69 6e 65 20 66 6f 72 6d 20 6f 66 20  sculine form of 
37f0: 3c 73 46 6c 65 78 3e 22 0a 20 20 20 20 66 6f 72  <sFlex>".    for
3800: 20 73 53 74 65 6d 20 69 6e 20 5f 6f 53 70 65 6c   sStem in _oSpel
3810: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d  lChecker.getLemm
3820: 61 28 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20  a(sFlex):.      
3830: 20 20 69 66 20 6d 66 73 70 2e 69 73 4d 61 73 46    if mfsp.isMasF
3840: 6f 72 6d 28 73 53 74 65 6d 29 20 6f 72 20 63 6f  orm(sStem) or co
3850: 6e 6a 2e 68 61 73 43 6f 6e 6a 28 73 53 74 65 6d  nj.hasConj(sStem
3860: 2c 20 22 3a 50 51 22 2c 20 22 3a 51 31 22 29 3a  , ":PQ", ":Q1"):
3870: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 77  .            # w
3880: 68 61 74 20 68 61 73 20 61 20 66 65 6d 69 6e 69  hat has a femini
3890: 6e 65 20 66 6f 72 6d 20 61 6c 73 6f 20 68 61 73  ne form also has
38a0: 20 61 20 6d 61 73 63 75 6c 69 6e 65 20 66 6f 72   a masculine for
38b0: 6d 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  m.            re
38c0: 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 69 66  turn True.    if
38d0: 20 70 68 6f 6e 65 74 2e 68 61 73 53 69 6d 69 6c   phonet.hasSimil
38e0: 28 73 46 6c 65 78 2c 20 22 3a 6d 22 29 3a 0a 20  (sFlex, ":m"):. 
38f0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
3900: 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20 46 61  ue.    return Fa
3910: 6c 73 65 0a 0a 0a 64 65 66 20 73 77 69 74 63 68  lse...def switch
3920: 47 65 6e 64 65 72 20 28 73 46 6c 65 78 2c 20 62  Gender (sFlex, b
3930: 50 6c 75 72 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20  Plur=None):.    
3940: 22 72 65 74 75 72 6e 20 66 65 6d 69 6e 69 6e 65  "return feminine
3950: 20 6f 72 20 6d 61 73 63 75 6c 69 6e 65 20 66 6f   or masculine fo
3960: 72 6d 28 73 29 20 6f 66 20 3c 73 46 6c 65 78 3e  rm(s) of <sFlex>
3970: 22 0a 20 20 20 20 61 53 75 67 67 20 3d 20 73 65  ".    aSugg = se
3980: 74 28 29 0a 20 20 20 20 69 66 20 62 50 6c 75 72  t().    if bPlur
3990: 20 69 73 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20   is None:.      
39a0: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
39b0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
39c0: 65 74 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a  etMorph(sFlex):.
39d0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22              if "
39e0: 3a 66 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :f" in sMorph:. 
39f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
3a00: 66 20 22 3a 73 22 20 69 6e 20 73 4d 6f 72 70 68  f ":s" in sMorph
3a10: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
3a20: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
3a30: 73 75 67 67 4d 61 73 53 69 6e 67 28 73 46 6c 65  suggMasSing(sFle
3a40: 78 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  x)).            
3a50: 20 20 20 20 65 6c 69 66 20 22 3a 70 22 20 69 6e      elif ":p" in
3a60: 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   sMorph:.       
3a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75               aSu
3a80: 67 67 2e 61 64 64 28 73 75 67 67 4d 61 73 50 6c  gg.add(suggMasPl
3a90: 75 72 28 73 46 6c 65 78 29 29 0a 20 20 20 20 20  ur(sFlex)).     
3aa0: 20 20 20 20 20 20 20 65 6c 69 66 20 22 3a 6d 22         elif ":m"
3ab0: 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20   in sMorph:.    
3ac0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22              if "
3ad0: 3a 73 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20  :s" in sMorph:. 
3ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3af0: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
3b00: 67 46 65 6d 53 69 6e 67 28 73 46 6c 65 78 29 29  gFemSing(sFlex))
3b10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3b20: 20 65 6c 69 66 20 22 3a 70 22 20 69 6e 20 73 4d   elif ":p" in sM
3b30: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
3b40: 20 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e            aSugg.
3b50: 61 64 64 28 73 75 67 67 46 65 6d 50 6c 75 72 28  add(suggFemPlur(
3b60: 73 46 6c 65 78 29 29 0a 20 20 20 20 20 20 20 20  sFlex)).        
3b70: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
3b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3b90: 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67    aSugg.add(sugg
3ba0: 46 65 6d 53 69 6e 67 28 73 46 6c 65 78 29 29 0a  FemSing(sFlex)).
3bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3bc0: 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75      aSugg.add(su
3bd0: 67 67 46 65 6d 50 6c 75 72 28 73 46 6c 65 78 29  ggFemPlur(sFlex)
3be0: 29 0a 20 20 20 20 65 6c 69 66 20 62 50 6c 75 72  ).    elif bPlur
3bf0: 3a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 73 4d  :.        for sM
3c00: 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43  orph in _oSpellC
3c10: 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28  hecker.getMorph(
3c20: 73 46 6c 65 78 29 3a 0a 20 20 20 20 20 20 20 20  sFlex):.        
3c30: 20 20 20 20 69 66 20 22 3a 66 22 20 69 6e 20 73      if ":f" in s
3c40: 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20  Morph:.         
3c50: 20 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64         aSugg.add
3c60: 28 73 75 67 67 4d 61 73 50 6c 75 72 28 73 46 6c  (suggMasPlur(sFl
3c70: 65 78 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  ex)).           
3c80: 20 65 6c 69 66 20 22 3a 6d 22 20 69 6e 20 73 4d   elif ":m" in sM
3c90: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
3ca0: 20 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28        aSugg.add(
3cb0: 73 75 67 67 46 65 6d 50 6c 75 72 28 73 46 6c 65  suggFemPlur(sFle
3cc0: 78 29 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  x)).    else:.  
3cd0: 20 20 20 20 20 20 66 6f 72 20 73 4d 6f 72 70 68        for sMorph
3ce0: 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b   in _oSpellCheck
3cf0: 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 46 6c 65  er.getMorph(sFle
3d00: 78 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  x):.            
3d10: 69 66 20 22 3a 66 22 20 69 6e 20 73 4d 6f 72 70  if ":f" in sMorp
3d20: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  h:.             
3d30: 20 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67     aSugg.add(sug
3d40: 67 4d 61 73 53 69 6e 67 28 73 46 6c 65 78 29 29  gMasSing(sFlex))
3d50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69  .            eli
3d60: 66 20 22 3a 6d 22 20 69 6e 20 73 4d 6f 72 70 68  f ":m" in sMorph
3d70: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
3d80: 20 20 61 53 75 67 67 2e 61 64 64 28 73 75 67 67    aSugg.add(sugg
3d90: 46 65 6d 53 69 6e 67 28 73 46 6c 65 78 29 29 0a  FemSing(sFlex)).
3da0: 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a 20 20      if aSugg:.  
3db0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 7c 22        return "|"
3dc0: 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20 20 20  .join(aSugg).   
3dd0: 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65 66   return ""...def
3de0: 20 73 77 69 74 63 68 50 6c 75 72 61 6c 20 28 73   switchPlural (s
3df0: 46 6c 65 78 29 3a 0a 20 20 20 20 22 72 65 74 75  Flex):.    "retu
3e00: 72 6e 20 70 6c 75 72 61 6c 20 6f 72 20 73 69 6e  rn plural or sin
3e10: 67 75 6c 61 72 20 66 6f 72 6d 28 73 29 20 6f 66  gular form(s) of
3e20: 20 3c 73 46 6c 65 78 3e 22 0a 20 20 20 20 61 53   <sFlex>".    aS
3e30: 75 67 67 20 3d 20 73 65 74 28 29 0a 20 20 20 20  ugg = set().    
3e40: 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f  for sMorph in _o
3e50: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74  SpellChecker.get
3e60: 4d 6f 72 70 68 28 73 46 6c 65 78 29 3a 0a 20 20  Morph(sFlex):.  
3e70: 20 20 20 20 20 20 69 66 20 22 3a 73 22 20 69 6e        if ":s" in
3e80: 20 73 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20   sMorph:.       
3e90: 20 20 20 20 20 61 53 75 67 67 2e 61 64 64 28 73       aSugg.add(s
3ea0: 75 67 67 50 6c 75 72 28 73 46 6c 65 78 29 29 0a  uggPlur(sFlex)).
3eb0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 22 3a 70          elif ":p
3ec0: 22 20 69 6e 20 73 4d 6f 72 70 68 3a 0a 20 20 20  " in sMorph:.   
3ed0: 20 20 20 20 20 20 20 20 20 61 53 75 67 67 2e 61           aSugg.a
3ee0: 64 64 28 73 75 67 67 53 69 6e 67 28 73 46 6c 65  dd(suggSing(sFle
3ef0: 78 29 29 0a 20 20 20 20 69 66 20 61 53 75 67 67  x)).    if aSugg
3f00: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
3f10: 20 22 7c 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29   "|".join(aSugg)
3f20: 0a 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a 0a  .    return ""..
3f30: 0a 64 65 66 20 68 61 73 53 69 6d 69 6c 20 28 73  .def hasSimil (s
3f40: 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e 3d 4e  Word, sPattern=N
3f50: 6f 6e 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72  one):.    "retur
3f60: 6e 20 54 72 75 65 20 69 66 20 74 68 65 72 65 20  n True if there 
3f70: 69 73 20 77 6f 72 64 73 20 70 68 6f 6e 65 74 69  is words phoneti
3f80: 63 61 6c 6c 79 20 73 69 6d 69 6c 61 72 20 74 6f  cally similar to
3f90: 20 3c 73 57 6f 72 64 3e 20 28 61 63 63 6f 72 64   <sWord> (accord
3fa0: 69 6e 67 20 74 6f 20 3c 73 50 61 74 74 65 72 6e  ing to <sPattern
3fb0: 3e 20 69 66 20 72 65 71 75 69 72 65 64 29 22 0a  > if required)".
3fc0: 20 20 20 20 72 65 74 75 72 6e 20 70 68 6f 6e 65      return phone
3fd0: 74 2e 68 61 73 53 69 6d 69 6c 28 73 57 6f 72 64  t.hasSimil(sWord
3fe0: 2c 20 73 50 61 74 74 65 72 6e 29 0a 0a 0a 64 65  , sPattern)...de
3ff0: 66 20 73 75 67 67 53 69 6d 69 6c 20 28 73 57 6f  f suggSimil (sWo
4000: 72 64 2c 20 73 50 61 74 74 65 72 6e 3d 4e 6f 6e  rd, sPattern=Non
4010: 65 2c 20 62 53 75 62 73 74 3d 46 61 6c 73 65 2c  e, bSubst=False,
4020: 20 62 56 43 3d 46 61 6c 73 65 29 3a 0a 20 20 20   bVC=False):.   
4030: 20 22 72 65 74 75 72 6e 20 6c 69 73 74 20 6f 66   "return list of
4040: 20 77 6f 72 64 73 20 70 68 6f 6e 65 74 69 63 61   words phonetica
4050: 6c 6c 79 20 73 69 6d 69 6c 61 72 20 74 6f 20 73  lly similar to s
4060: 57 6f 72 64 20 61 6e 64 20 77 68 6f 6d 20 50 4f  Word and whom PO
4070: 53 20 69 73 20 6d 61 74 63 68 69 6e 67 20 73 50  S is matching sP
4080: 61 74 74 65 72 6e 22 0a 20 20 20 20 69 66 20 62  attern".    if b
4090: 56 43 3a 0a 20 20 20 20 20 20 20 20 73 57 6f 72  VC:.        sWor
40a0: 64 2c 20 73 53 66 78 20 3d 20 73 70 6c 69 74 56  d, sSfx = splitV
40b0: 65 72 62 28 73 57 6f 72 64 29 0a 20 20 20 20 61  erb(sWord).    a
40c0: 53 75 67 67 20 3d 20 70 68 6f 6e 65 74 2e 73 65  Sugg = phonet.se
40d0: 6c 65 63 74 53 69 6d 69 6c 28 73 57 6f 72 64 2c  lectSimil(sWord,
40e0: 20 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20 69   sPattern).    i
40f0: 66 20 6e 6f 74 20 61 53 75 67 67 20 6f 72 20 6e  f not aSugg or n
4100: 6f 74 20 62 53 75 62 73 74 3a 0a 20 20 20 20 20  ot bSubst:.     
4110: 20 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e     for sMorph in
4120: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
4130: 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64 29 3a  getMorph(sWord):
4140: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75  .            aSu
4150: 67 67 2e 75 70 64 61 74 65 28 63 6f 6e 6a 2e 67  gg.update(conj.g
4160: 65 74 53 69 6d 69 6c 28 73 57 6f 72 64 2c 20 73  etSimil(sWord, s
4170: 4d 6f 72 70 68 2c 20 62 53 75 62 73 74 29 29 0a  Morph, bSubst)).
4180: 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61              brea
4190: 6b 0a 20 20 20 20 69 66 20 61 53 75 67 67 3a 0a  k.    if aSugg:.
41a0: 20 20 20 20 20 20 20 20 69 66 20 62 56 43 3a 0a          if bVC:.
41b0: 20 20 20 20 20 20 20 20 20 20 20 20 61 53 75 67              aSug
41c0: 67 20 3d 20 6c 69 73 74 28 6d 61 70 28 6c 61 6d  g = list(map(lam
41d0: 62 64 61 20 73 53 75 67 3a 20 73 53 75 67 20 2b  bda sSug: sSug +
41e0: 20 73 53 66 78 2c 20 61 53 75 67 67 29 29 0a 20   sSfx, aSugg)). 
41f0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 7c         return "|
4200: 22 2e 6a 6f 69 6e 28 61 53 75 67 67 29 0a 20 20  ".join(aSugg).  
4210: 20 20 72 65 74 75 72 6e 20 22 22 0a 0a 0a 64 65    return ""...de
4220: 66 20 73 75 67 67 43 65 4f 72 43 65 74 20 28 73  f suggCeOrCet (s
4230: 57 6f 72 64 29 3a 0a 20 20 20 20 22 73 75 67 67  Word):.    "sugg
4240: 65 73 74 20 e2 80 9c 63 65 e2 80 9d 20 6f 72 20  est ...ce... or 
4250: e2 80 9c 63 65 74 e2 80 9d 20 6f 72 20 62 6f 74  ...cet... or bot
4260: 68 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 74  h according to t
4270: 68 65 20 66 69 72 73 74 20 6c 65 74 74 65 72 20  he first letter 
4280: 6f 66 20 3c 73 57 6f 72 64 3e 22 0a 20 20 20 20  of <sWord>".    
4290: 69 66 20 72 65 2e 6d 61 74 63 68 28 22 28 3f 69  if re.match("(?i
42a0: 29 5b 61 65 c3 a9 c3 a8 c3 aa 69 6f 75 79 c3 a2  )[ae......iouy..
42b0: c3 ae c3 af 5d 22 2c 20 73 57 6f 72 64 29 3a 0a  ....]", sWord):.
42c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
42d0: 63 65 74 22 0a 20 20 20 20 69 66 20 73 57 6f 72  cet".    if sWor
42e0: 64 5b 30 3a 31 5d 20 69 6e 20 22 68 48 22 3a 0a  d[0:1] in "hH":.
42f0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22          return "
4300: 63 65 7c 63 65 74 22 0a 20 20 20 20 72 65 74 75  ce|cet".    retu
4310: 72 6e 20 22 63 65 22 0a 0a 0a 64 65 66 20 73 75  rn "ce"...def su
4320: 67 67 4c 65 73 4c 61 20 28 73 57 6f 72 64 29 3a  ggLesLa (sWord):
4330: 0a 20 20 20 20 22 73 75 67 67 65 73 74 20 e2 80  .    "suggest ..
4340: 9c 6c 65 73 e2 80 9d 20 6f 72 20 e2 80 9c 6c 61  .les... or ...la
4350: e2 80 9d 20 61 63 63 6f 72 64 69 6e 67 20 74 6f  ... according to
4360: 20 3c 73 57 6f 72 64 3e 22 0a 20 20 20 20 69 66   <sWord>".    if
4370: 20 61 6e 79 28 20 22 3a 70 22 20 69 6e 20 73 4d   any( ":p" in sM
4380: 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72 70 68  orph  for sMorph
4390: 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b   in _oSpellCheck
43a0: 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f 72  er.getMorph(sWor
43b0: 64 29 20 29 3a 0a 20 20 20 20 20 20 20 20 72 65  d) ):.        re
43c0: 74 75 72 6e 20 22 6c 65 73 7c 6c 61 22 0a 20 20  turn "les|la".  
43d0: 20 20 72 65 74 75 72 6e 20 22 6c 61 22 0a 0a 0a    return "la"...
43e0: 5f 7a 42 69 6e 61 72 79 20 3d 20 72 65 2e 63 6f  _zBinary = re.co
43f0: 6d 70 69 6c 65 28 22 5e 5b 30 31 5d 2b 24 22 29  mpile("^[01]+$")
4400: 0a 0a 64 65 66 20 66 6f 72 6d 61 74 4e 75 6d 62  ..def formatNumb
4410: 65 72 20 28 73 4e 75 6d 62 65 72 2c 20 62 4f 6e  er (sNumber, bOn
4420: 6c 79 53 69 6d 70 6c 65 46 6f 72 6d 61 74 3d 46  lySimpleFormat=F
4430: 61 6c 73 65 29 3a 0a 20 20 20 20 22 61 64 64 20  alse):.    "add 
4440: 73 70 61 63 65 73 20 6f 72 20 68 79 70 68 65 6e  spaces or hyphen
4450: 73 20 74 6f 20 62 69 67 20 6e 75 6d 62 65 72 73  s to big numbers
4460: 22 0a 20 20 20 20 6e 4c 65 6e 20 3d 20 6c 65 6e  ".    nLen = len
4470: 28 73 4e 75 6d 62 65 72 29 0a 20 20 20 20 69 66  (sNumber).    if
4480: 20 6e 4c 65 6e 20 3c 20 34 3a 0a 20 20 20 20 20   nLen < 4:.     
4490: 20 20 20 72 65 74 75 72 6e 20 73 4e 75 6d 62 65     return sNumbe
44a0: 72 0a 20 20 20 20 73 52 65 73 20 3d 20 22 22 0a  r.    sRes = "".
44b0: 20 20 20 20 69 66 20 22 2c 22 20 6e 6f 74 20 69      if "," not i
44c0: 6e 20 73 4e 75 6d 62 65 72 3a 0a 20 20 20 20 20  n sNumber:.     
44d0: 20 20 20 23 20 6e 6f 6d 62 72 65 20 65 6e 74 69     # nombre enti
44e0: 65 72 0a 20 20 20 20 20 20 20 20 73 52 65 73 20  er.        sRes 
44f0: 3d 20 5f 66 6f 72 6d 61 74 4e 75 6d 62 65 72 28  = _formatNumber(
4500: 73 4e 75 6d 62 65 72 2c 20 33 29 0a 20 20 20 20  sNumber, 3).    
4510: 20 20 20 20 69 66 20 6e 6f 74 20 62 4f 6e 6c 79      if not bOnly
4520: 53 69 6d 70 6c 65 46 6f 72 6d 61 74 3a 0a 20 20  SimpleFormat:.  
4530: 20 20 20 20 20 20 20 20 20 20 23 20 62 69 6e 61            # bina
4540: 69 72 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  ire.            
4550: 69 66 20 5f 7a 42 69 6e 61 72 79 2e 73 65 61 72  if _zBinary.sear
4560: 63 68 28 73 4e 75 6d 62 65 72 29 3a 0a 20 20 20  ch(sNumber):.   
4570: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 52 65               sRe
4580: 73 20 2b 3d 20 22 7c 22 20 2b 20 5f 66 6f 72 6d  s += "|" + _form
4590: 61 74 4e 75 6d 62 65 72 28 73 4e 75 6d 62 65 72  atNumber(sNumber
45a0: 2c 20 34 29 0a 20 20 20 20 20 20 20 20 20 20 20  , 4).           
45b0: 20 23 20 6e 75 6d c3 a9 72 6f 73 20 64 65 20 74   # num..ros de t
45c0: c3 a9 6c c3 a9 70 68 6f 6e 65 0a 20 20 20 20 20  ..l..phone.     
45d0: 20 20 20 20 20 20 20 69 66 20 6e 4c 65 6e 20 3d         if nLen =
45e0: 3d 20 31 30 3a 0a 20 20 20 20 20 20 20 20 20 20  = 10:.          
45f0: 20 20 20 20 20 20 69 66 20 73 4e 75 6d 62 65 72        if sNumber
4600: 2e 73 74 61 72 74 73 77 69 74 68 28 22 30 22 29  .startswith("0")
4610: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
4620: 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c        sRes += "|
4630: 22 20 2b 20 5f 66 6f 72 6d 61 74 4e 75 6d 62 65  " + _formatNumbe
4640: 72 28 73 4e 75 6d 62 65 72 2c 20 32 29 20 20 20  r(sNumber, 2)   
4650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
4690: 74 c3 a9 6c c3 a9 70 68 6f 6e 65 20 66 72 61 6e  t..l..phone fran
46a0: c3 a7 61 69 73 0a 20 20 20 20 20 20 20 20 20 20  ..ais.          
46b0: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4e 75            if sNu
46c0: 6d 62 65 72 5b 31 5d 20 3d 3d 20 22 34 22 20 61  mber[1] == "4" a
46d0: 6e 64 20 28 73 4e 75 6d 62 65 72 5b 32 5d 3d 3d  nd (sNumber[2]==
46e0: 22 37 22 20 6f 72 20 73 4e 75 6d 62 65 72 5b 32  "7" or sNumber[2
46f0: 5d 3d 3d 22 38 22 20 6f 72 20 73 4e 75 6d 62 65  ]=="8" or sNumbe
4700: 72 5b 32 5d 3d 3d 22 39 22 29 3a 0a 20 20 20 20  r[2]=="9"):.    
4710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4720: 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c 22 20      sRes += "|" 
4730: 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 34 5d 20 2b  + sNumber[0:4] +
4740: 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b   ".." + sNumber[
4750: 34 3a 36 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e  4:6] + ".." + sN
4760: 75 6d 62 65 72 5b 36 3a 38 5d 20 2b 20 22 c2 a0  umber[6:8] + "..
4770: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 38 3a 5d 20  " + sNumber[8:] 
4780: 20 20 20 20 20 20 20 20 20 20 20 23 20 6d 6f 62             # mob
4790: 69 6c 65 20 62 65 6c 67 65 0a 20 20 20 20 20 20  ile belge.      
47a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 52                sR
47b0: 65 73 20 2b 3d 20 22 7c 22 20 2b 20 73 4e 75 6d  es += "|" + sNum
47c0: 62 65 72 5b 30 3a 33 5d 20 2b 20 22 c2 a0 22 20  ber[0:3] + ".." 
47d0: 2b 20 73 4e 75 6d 62 65 72 5b 33 3a 36 5d 20 2b  + sNumber[3:6] +
47e0: 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b   ".." + sNumber[
47f0: 36 3a 38 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e  6:8] + ".." + sN
4800: 75 6d 62 65 72 5b 38 3a 5d 20 20 20 20 20 20 20  umber[8:]       
4810: 20 20 20 20 20 20 20 20 20 23 20 74 c3 a9 6c c3           # t..l.
4820: a9 70 68 6f 6e 65 20 73 75 69 73 73 65 0a 20 20  .phone suisse.  
4830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 52                sR
4840: 65 73 20 2b 3d 20 22 7c 22 20 2b 20 73 4e 75 6d  es += "|" + sNum
4850: 62 65 72 5b 30 3a 34 5d 20 2b 20 22 c2 a0 22 20  ber[0:4] + ".." 
4860: 2b 20 73 4e 75 6d 62 65 72 5b 34 3a 37 5d 20 2b  + sNumber[4:7] +
4870: 20 22 2d 22 20 2b 20 73 4e 75 6d 62 65 72 5b 37   "-" + sNumber[7
4880: 3a 5d 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :]              
4890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
48a0: 20 20 20 20 20 20 20 20 20 20 20 23 20 74 c3 a9             # t..
48b0: 6c c3 a9 70 68 6f 6e 65 20 63 61 6e 61 64 69 65  l..phone canadie
48c0: 6e 20 6f 75 20 61 6d c3 a9 72 69 63 61 69 6e 0a  n ou am..ricain.
48d0: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66              elif
48e0: 20 6e 4c 65 6e 20 3d 3d 20 39 20 61 6e 64 20 73   nLen == 9 and s
48f0: 4e 75 6d 62 65 72 2e 73 74 61 72 74 73 77 69 74  Number.startswit
4900: 68 28 22 30 22 29 3a 0a 20 20 20 20 20 20 20 20  h("0"):.        
4910: 20 20 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20          sRes += 
4920: 22 7c 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a  "|" + sNumber[0:
4930: 33 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d  3] + ".." + sNum
4940: 62 65 72 5b 33 3a 35 5d 20 2b 20 22 c2 a0 22 20  ber[3:5] + ".." 
4950: 2b 20 73 4e 75 6d 62 65 72 5b 35 3a 37 5d 20 2b  + sNumber[5:7] +
4960: 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b   ".." + sNumber[
4970: 37 3a 39 5d 20 20 20 20 20 20 20 20 20 20 20 20  7:9]            
4980: 20 20 20 20 20 20 20 23 20 66 69 78 65 20 62 65         # fixe be
4990: 6c 67 65 20 31 0a 20 20 20 20 20 20 20 20 20 20  lge 1.          
49a0: 20 20 20 20 20 20 73 52 65 73 20 2b 3d 20 22 7c        sRes += "|
49b0: 22 20 2b 20 73 4e 75 6d 62 65 72 5b 30 3a 32 5d  " + sNumber[0:2]
49c0: 20 2b 20 22 c2 a0 22 20 2b 20 73 4e 75 6d 62 65   + ".." + sNumbe
49d0: 72 5b 32 3a 35 5d 20 2b 20 22 c2 a0 22 20 2b 20  r[2:5] + ".." + 
49e0: 73 4e 75 6d 62 65 72 5b 35 3a 37 5d 20 2b 20 22  sNumber[5:7] + "
49f0: c2 a0 22 20 2b 20 73 4e 75 6d 62 65 72 5b 37 3a  .." + sNumber[7:
4a00: 39 5d 20 20 20 20 20 20 20 20 20 20 20 20 20 20  9]              
4a10: 20 20 20 20 20 23 20 66 69 78 65 20 62 65 6c 67       # fixe belg
4a20: 65 20 32 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  e 2.    else:.  
4a30: 20 20 20 20 20 20 23 20 4e 6f 6d 62 72 65 20 72        # Nombre r
4a40: c3 a9 65 6c 0a 20 20 20 20 20 20 20 20 73 49 6e  ..el.        sIn
4a50: 74 2c 20 73 46 6c 6f 61 74 20 3d 20 73 4e 75 6d  t, sFloat = sNum
4a60: 62 65 72 2e 73 70 6c 69 74 28 22 2c 22 2c 20 31  ber.split(",", 1
4a70: 29 0a 20 20 20 20 20 20 20 20 73 52 65 73 20 3d  ).        sRes =
4a80: 20 5f 66 6f 72 6d 61 74 4e 75 6d 62 65 72 28 73   _formatNumber(s
4a90: 49 6e 74 2c 20 33 29 20 2b 20 22 2c 22 20 2b 20  Int, 3) + "," + 
4aa0: 73 46 6c 6f 61 74 0a 20 20 20 20 72 65 74 75 72  sFloat.    retur
4ab0: 6e 20 73 52 65 73 0a 0a 64 65 66 20 5f 66 6f 72  n sRes..def _for
4ac0: 6d 61 74 4e 75 6d 62 65 72 20 28 73 4e 75 6d 62  matNumber (sNumb
4ad0: 65 72 2c 20 6e 47 72 6f 75 70 3d 33 29 3a 0a 20  er, nGroup=3):. 
4ae0: 20 20 20 73 52 65 73 20 3d 20 22 22 0a 20 20 20     sRes = "".   
4af0: 20 6e 45 6e 64 20 3d 20 6c 65 6e 28 73 4e 75 6d   nEnd = len(sNum
4b00: 62 65 72 29 0a 20 20 20 20 77 68 69 6c 65 20 6e  ber).    while n
4b10: 45 6e 64 20 3e 20 30 3a 0a 20 20 20 20 20 20 20  End > 0:.       
4b20: 20 6e 53 74 61 72 74 20 3d 20 6d 61 78 28 6e 45   nStart = max(nE
4b30: 6e 64 2d 6e 47 72 6f 75 70 2c 20 30 29 0a 20 20  nd-nGroup, 0).  
4b40: 20 20 20 20 20 20 73 52 65 73 20 3d 20 73 4e 75        sRes = sNu
4b50: 6d 62 65 72 5b 6e 53 74 61 72 74 3a 6e 45 6e 64  mber[nStart:nEnd
4b60: 5d 20 2b 20 22 c2 a0 22 20 2b 20 73 52 65 73 20  ] + ".." + sRes 
4b70: 20 69 66 20 73 52 65 73 20 20 65 6c 73 65 20 73   if sRes  else s
4b80: 4e 75 6d 62 65 72 5b 6e 53 74 61 72 74 3a 6e 45  Number[nStart:nE
4b90: 6e 64 5d 0a 20 20 20 20 20 20 20 20 6e 45 6e 64  nd].        nEnd
4ba0: 20 3d 20 6e 45 6e 64 20 2d 20 6e 47 72 6f 75 70   = nEnd - nGroup
4bb0: 0a 20 20 20 20 72 65 74 75 72 6e 20 73 52 65 73  .    return sRes
4bc0: 0a 0a 0a 64 65 66 20 66 6f 72 6d 61 74 4e 46 20  ...def formatNF 
4bd0: 28 73 29 3a 0a 20 20 20 20 22 74 79 70 6f 67 72  (s):.    "typogr
4be0: 61 70 68 79 3a 20 66 6f 72 6d 61 74 20 4e 46 20  aphy: format NF 
4bf0: 72 65 66 65 72 65 6e 63 65 20 28 6e 6f 72 6d 65  reference (norme
4c00: 20 66 72 61 6e c3 a7 61 69 73 65 29 22 0a 20 20   fran..aise)".  
4c10: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 6d    try:.        m
4c20: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4e 46 5b   = re.match("NF[
4c30: 20 c2 a0 2d 5d 3f 28 43 7c 45 7c 50 7c 51 7c 53   ..-]?(C|E|P|Q|S
4c40: 7c 58 7c 5a 7c 45 4e 28 3f 3a 5b 20 c2 a0 2d 5d  |X|Z|EN(?:[ ..-]
4c50: 49 53 4f 7c 29 29 5b 20 c2 a0 2d 5d 3f 28 5b 30  ISO|))[ ..-]?([0
4c60: 2d 39 5d 2b 28 3f 3a 5b 2f e2 80 91 2d 5d 5b 30  -9]+(?:[/...-][0
4c70: 2d 39 5d 2b 7c 29 29 22 2c 20 73 29 0a 20 20 20  -9]+|))", s).   
4c80: 20 20 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20       if not m:. 
4c90: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
4ca0: 6e 20 22 22 0a 20 20 20 20 20 20 20 20 72 65 74  n "".        ret
4cb0: 75 72 6e 20 22 4e 46 c2 a0 22 20 2b 20 6d 2e 67  urn "NF.." + m.g
4cc0: 72 6f 75 70 28 31 29 2e 75 70 70 65 72 28 29 2e  roup(1).upper().
4cd0: 72 65 70 6c 61 63 65 28 22 20 22 2c 20 22 c2 a0  replace(" ", "..
4ce0: 22 29 2e 72 65 70 6c 61 63 65 28 22 2d 22 2c 20  ").replace("-", 
4cf0: 22 c2 a0 22 29 20 2b 20 22 c2 a0 22 20 2b 20 6d  "..") + ".." + m
4d00: 2e 67 72 6f 75 70 28 32 29 2e 72 65 70 6c 61 63  .group(2).replac
4d10: 65 28 22 2f 22 2c 20 22 e2 80 91 22 29 2e 72 65  e("/", "...").re
4d20: 70 6c 61 63 65 28 22 2d 22 2c 20 22 e2 80 91 22  place("-", "..."
4d30: 29 0a 20 20 20 20 65 78 63 65 70 74 20 28 72 65  ).    except (re
4d40: 2e 65 72 72 6f 72 2c 20 49 6e 64 65 78 45 72 72  .error, IndexErr
4d50: 6f 72 29 3a 0a 20 20 20 20 20 20 20 20 74 72 61  or):.        tra
4d60: 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63  ceback.print_exc
4d70: 28 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ().        retur
4d80: 6e 20 22 23 20 65 72 72 65 75 72 20 23 22 0a 0a  n "# erreur #"..
4d90: 0a 64 65 66 20 75 6e 64 6f 4c 69 67 61 74 75 72  .def undoLigatur
4da0: 65 20 28 63 29 3a 0a 20 20 20 20 22 74 79 70 6f  e (c):.    "typo
4db0: 67 72 61 70 68 79 3a 20 73 70 6c 69 74 20 6c 69  graphy: split li
4dc0: 67 61 74 75 72 65 20 63 68 61 72 61 63 74 65 72  gature character
4dd0: 20 3c 63 3e 20 69 6e 20 73 65 76 65 72 61 6c 20   <c> in several 
4de0: 63 68 61 72 73 22 0a 20 20 20 20 69 66 20 63 20  chars".    if c 
4df0: 3d 3d 20 22 ef ac 81 22 3a 0a 20 20 20 20 20 20  == "...":.      
4e00: 20 20 72 65 74 75 72 6e 20 22 66 69 22 0a 20 20    return "fi".  
4e10: 20 20 69 66 20 63 20 3d 3d 20 22 ef ac 82 22 3a    if c == "...":
4e20: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
4e30: 22 66 6c 22 0a 20 20 20 20 69 66 20 63 20 3d 3d  "fl".    if c ==
4e40: 20 22 ef ac 80 22 3a 0a 20 20 20 20 20 20 20 20   "...":.        
4e50: 72 65 74 75 72 6e 20 22 66 66 22 0a 20 20 20 20  return "ff".    
4e60: 69 66 20 63 20 3d 3d 20 22 ef ac 83 22 3a 0a 20  if c == "...":. 
4e70: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 66         return "f
4e80: 66 69 22 0a 20 20 20 20 69 66 20 63 20 3d 3d 20  fi".    if c == 
4e90: 22 ef ac 84 22 3a 0a 20 20 20 20 20 20 20 20 72  "...":.        r
4ea0: 65 74 75 72 6e 20 22 66 66 6c 22 0a 20 20 20 20  eturn "ffl".    
4eb0: 69 66 20 63 20 3d 3d 20 22 ef ac 85 22 3a 0a 20  if c == "...":. 
4ec0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 66         return "f
4ed0: 74 22 0a 20 20 20 20 69 66 20 63 20 3d 3d 20 22  t".    if c == "
4ee0: ef ac 86 22 3a 0a 20 20 20 20 20 20 20 20 72 65  ...":.        re
4ef0: 74 75 72 6e 20 22 73 74 22 0a 20 20 20 20 72 65  turn "st".    re
4f00: 74 75 72 6e 20 22 5f 22 0a 0a 0a 0a 0a 5f 78 4e  turn "_"....._xN
4f10: 6f 72 6d 61 6c 69 7a 65 64 43 68 61 72 73 46 6f  ormalizedCharsFo
4f20: 72 49 6e 63 6c 75 73 69 76 65 57 72 69 74 69 6e  rInclusiveWritin
4f30: 67 20 3d 20 73 74 72 2e 6d 61 6b 65 74 72 61 6e  g = str.maketran
4f40: 73 28 7b 0a 20 20 20 20 27 28 27 3a 20 27 c2 b7  s({.    '(': '..
4f50: 27 2c 20 20 27 29 27 3a 20 27 c2 b7 27 2c 0a 20  ',  ')': '..',. 
4f60: 20 20 20 27 2e 27 3a 20 27 c2 b7 27 2c 20 20 27     '.': '..',  '
4f70: c2 b7 27 3a 20 27 c2 b7 27 2c 20 20 27 e2 80 a2  ..': '..',  '...
4f80: 27 3a 20 27 c2 b7 27 2c 0a 20 20 20 20 27 e2 80  ': '..',.    '..
4f90: 93 27 3a 20 27 c2 b7 27 2c 20 20 27 e2 80 94 27  .': '..',  '...'
4fa0: 3a 20 27 c2 b7 27 2c 0a 20 20 20 20 27 2f 27 3a  : '..',.    '/':
4fb0: 20 27 c2 b7 27 0a 7d 29 0a 0a 0a 64 65 66 20 6e   '..'.})...def n
4fc0: 6f 72 6d 61 6c 69 7a 65 49 6e 63 6c 75 73 69 76  ormalizeInclusiv
4fd0: 65 57 72 69 74 69 6e 67 20 28 73 54 6f 6b 65 6e  eWriting (sToken
4fe0: 29 3a 0a 20 20 20 20 22 74 79 70 6f 67 72 61 70  ):.    "typograp
4ff0: 68 79 3a 20 72 65 70 6c 61 63 65 20 77 6f 72 64  hy: replace word
5000: 20 73 65 70 61 72 61 74 6f 72 73 20 75 73 65 64   separators used
5010: 20 69 6e 20 69 6e 63 6c 75 73 69 76 65 20 77 72   in inclusive wr
5020: 69 74 69 6e 67 20 62 79 20 75 6e 64 65 72 73 63  iting by undersc
5030: 6f 72 65 20 28 5f 29 22 0a 20 20 20 20 72 65 74  ore (_)".    ret
5040: 75 72 6e 20 73 54 6f 6b 65 6e 2e 74 72 61 6e 73  urn sToken.trans
5050: 6c 61 74 65 28 5f 78 4e 6f 72 6d 61 6c 69 7a 65  late(_xNormalize
5060: 64 43 68 61 72 73 46 6f 72 49 6e 63 6c 75 73 69  dCharsForInclusi
5070: 76 65 57 72 69 74 69 6e 67 29 2e 72 65 70 6c 61  veWriting).repla
5080: 63 65 28 22 c3 a8 72 c2 b7 22 2c 20 22 65 72 c2  ce("..r..", "er.
5090: b7 22 29 2e 72 65 70 6c 61 63 65 28 22 c3 88 52  .").replace("..R
50a0: c2 b7 22 2c 20 22 45 52 c2 b7 22 29 0a           ..", "ER..").