Grammalecte  Hex Artifact Content

Artifact 5975c8681485b501c2316a3e01dd245e216f8ec590931510c10614d47d48df61:


0000: 23 20 47 72 61 6d 6d 61 6c 65 63 74 65 0a 23 20  # Grammalecte.# 
0010: 47 72 61 6d 6d 61 72 20 63 68 65 63 6b 65 72 20  Grammar checker 
0020: 65 6e 67 69 6e 65 0a 0a 69 6d 70 6f 72 74 20 72  engine..import r
0030: 65 0a 69 6d 70 6f 72 74 20 73 79 73 0a 69 6d 70  e.import sys.imp
0040: 6f 72 74 20 6f 73 0a 69 6d 70 6f 72 74 20 74 72  ort os.import tr
0050: 61 63 65 62 61 63 6b 0a 23 69 6d 70 6f 72 74 20  aceback.#import 
0060: 75 6e 69 63 6f 64 65 64 61 74 61 0a 66 72 6f 6d  unicodedata.from
0070: 20 69 74 65 72 74 6f 6f 6c 73 20 69 6d 70 6f 72   itertools impor
0080: 74 20 63 68 61 69 6e 0a 0a 66 72 6f 6d 20 2e 2e  t chain..from ..
0090: 67 72 61 70 68 73 70 65 6c 6c 2e 73 70 65 6c 6c  graphspell.spell
00a0: 63 68 65 63 6b 65 72 20 69 6d 70 6f 72 74 20 53  checker import S
00b0: 70 65 6c 6c 43 68 65 63 6b 65 72 0a 66 72 6f 6d  pellChecker.from
00c0: 20 2e 2e 67 72 61 70 68 73 70 65 6c 6c 2e 65 63   ..graphspell.ec
00d0: 68 6f 20 69 6d 70 6f 72 74 20 65 63 68 6f 0a 66  ho import echo.f
00e0: 72 6f 6d 20 2e 20 69 6d 70 6f 72 74 20 67 63 5f  rom . import gc_
00f0: 6f 70 74 69 6f 6e 73 0a 0a 66 72 6f 6d 20 2e 2e  options..from ..
0100: 67 72 61 70 68 73 70 65 6c 6c 2e 74 6f 6b 65 6e  graphspell.token
0110: 69 7a 65 72 20 69 6d 70 6f 72 74 20 54 6f 6b 65  izer import Toke
0120: 6e 69 7a 65 72 0a 66 72 6f 6d 20 2e 67 63 5f 72  nizer.from .gc_r
0130: 75 6c 65 73 5f 67 72 61 70 68 20 69 6d 70 6f 72  ules_graph impor
0140: 74 20 64 47 72 61 70 68 2c 20 64 52 75 6c 65 0a  t dGraph, dRule.
0150: 0a 0a 5f 5f 61 6c 6c 5f 5f 20 3d 20 5b 20 22 6c  ..__all__ = [ "l
0160: 61 6e 67 22 2c 20 22 6c 6f 63 61 6c 65 73 22 2c  ang", "locales",
0170: 20 22 70 6b 67 22 2c 20 22 6e 61 6d 65 22 2c 20   "pkg", "name", 
0180: 22 76 65 72 73 69 6f 6e 22 2c 20 22 61 75 74 68  "version", "auth
0190: 6f 72 22 2c 20 5c 0a 20 20 20 20 20 20 20 20 20  or", \.         
01a0: 20 20 20 22 6c 6f 61 64 22 2c 20 22 70 61 72 73     "load", "pars
01b0: 65 22 2c 20 22 67 65 74 53 70 65 6c 6c 43 68 65  e", "getSpellChe
01c0: 63 6b 65 72 22 2c 20 5c 0a 20 20 20 20 20 20 20  cker", \.       
01d0: 20 20 20 20 20 22 73 65 74 4f 70 74 69 6f 6e 22       "setOption"
01e0: 2c 20 22 73 65 74 4f 70 74 69 6f 6e 73 22 2c 20  , "setOptions", 
01f0: 22 67 65 74 4f 70 74 69 6f 6e 73 22 2c 20 22 67  "getOptions", "g
0200: 65 74 44 65 66 61 75 6c 74 4f 70 74 69 6f 6e 73  etDefaultOptions
0210: 22 2c 20 22 67 65 74 4f 70 74 69 6f 6e 73 4c 61  ", "getOptionsLa
0220: 62 65 6c 73 22 2c 20 22 72 65 73 65 74 4f 70 74  bels", "resetOpt
0230: 69 6f 6e 73 22 2c 20 22 64 69 73 70 6c 61 79 4f  ions", "displayO
0240: 70 74 69 6f 6e 73 22 2c 20 5c 0a 20 20 20 20 20  ptions", \.     
0250: 20 20 20 20 20 20 20 22 69 67 6e 6f 72 65 52 75         "ignoreRu
0260: 6c 65 22 2c 20 22 72 65 73 65 74 49 67 6e 6f 72  le", "resetIgnor
0270: 65 52 75 6c 65 73 22 2c 20 22 72 65 61 63 74 69  eRules", "reacti
0280: 76 61 74 65 52 75 6c 65 22 2c 20 22 6c 69 73 74  vateRule", "list
0290: 52 75 6c 65 73 22 2c 20 22 64 69 73 70 6c 61 79  Rules", "display
02a0: 52 75 6c 65 73 22 20 5d 0a 0a 5f 5f 76 65 72 73  Rules" ]..__vers
02b0: 69 6f 6e 5f 5f 20 3d 20 22 24 7b 76 65 72 73 69  ion__ = "${versi
02c0: 6f 6e 7d 22 0a 0a 0a 6c 61 6e 67 20 3d 20 22 24  on}"...lang = "$
02d0: 7b 6c 61 6e 67 7d 22 0a 6c 6f 63 61 6c 65 73 20  {lang}".locales 
02e0: 3d 20 24 7b 6c 6f 63 7d 0a 70 6b 67 20 3d 20 22  = ${loc}.pkg = "
02f0: 24 7b 69 6d 70 6c 6e 61 6d 65 7d 22 0a 6e 61 6d  ${implname}".nam
0300: 65 20 3d 20 22 24 7b 6e 61 6d 65 7d 22 0a 76 65  e = "${name}".ve
0310: 72 73 69 6f 6e 20 3d 20 22 24 7b 76 65 72 73 69  rsion = "${versi
0320: 6f 6e 7d 22 0a 61 75 74 68 6f 72 20 3d 20 22 24  on}".author = "$
0330: 7b 61 75 74 68 6f 72 7d 22 0a 0a 5f 72 75 6c 65  {author}".._rule
0340: 73 20 3d 20 4e 6f 6e 65 20 20 20 20 20 20 20 20  s = None        
0350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0360: 20 20 20 20 20 20 20 23 20 6d 6f 64 75 6c 65 20         # module 
0370: 67 63 5f 72 75 6c 65 73 0a 0a 23 20 64 61 74 61  gc_rules..# data
0380: 0a 5f 73 41 70 70 43 6f 6e 74 65 78 74 20 3d 20  ._sAppContext = 
0390: 22 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ""              
03a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 77               # w
03b0: 68 61 74 20 73 6f 66 74 77 61 72 65 20 69 73 20  hat software is 
03c0: 72 75 6e 6e 69 6e 67 0a 5f 64 4f 70 74 69 6f 6e  running._dOption
03d0: 73 20 3d 20 4e 6f 6e 65 0a 5f 61 49 67 6e 6f 72  s = None._aIgnor
03e0: 65 64 52 75 6c 65 73 20 3d 20 73 65 74 28 29 0a  edRules = set().
03f0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 20 3d  _oSpellChecker =
0400: 20 4e 6f 6e 65 0a 5f 6f 54 6f 6b 65 6e 69 7a 65   None._oTokenize
0410: 72 20 3d 20 4e 6f 6e 65 0a 0a 0a 23 23 23 23 20  r = None...#### 
0420: 50 61 72 73 69 6e 67 0a 0a 64 65 66 20 70 61 72  Parsing..def par
0430: 73 65 20 28 73 54 65 78 74 2c 20 73 43 6f 75 6e  se (sText, sCoun
0440: 74 72 79 3d 22 24 7b 63 6f 75 6e 74 72 79 5f 64  try="${country_d
0450: 65 66 61 75 6c 74 7d 22 2c 20 62 44 65 62 75 67  efault}", bDebug
0460: 3d 46 61 6c 73 65 2c 20 64 4f 70 74 69 6f 6e 73  =False, dOptions
0470: 3d 4e 6f 6e 65 2c 20 62 43 6f 6e 74 65 78 74 3d  =None, bContext=
0480: 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 61 6e 61  False):.    "ana
0490: 6c 79 73 65 73 20 74 68 65 20 70 61 72 61 67 72  lyses the paragr
04a0: 61 70 68 20 73 54 65 78 74 20 61 6e 64 20 72 65  aph sText and re
04b0: 74 75 72 6e 73 20 6c 69 73 74 20 6f 66 20 65 72  turns list of er
04c0: 72 6f 72 73 22 0a 20 20 20 20 23 73 54 65 78 74  rors".    #sText
04d0: 20 3d 20 75 6e 69 63 6f 64 65 64 61 74 61 2e 6e   = unicodedata.n
04e0: 6f 72 6d 61 6c 69 7a 65 28 22 4e 46 43 22 2c 20  ormalize("NFC", 
04f0: 73 54 65 78 74 29 0a 20 20 20 20 61 45 72 72 6f  sText).    aErro
0500: 72 73 20 3d 20 4e 6f 6e 65 0a 20 20 20 20 73 52  rs = None.    sR
0510: 65 61 6c 54 65 78 74 20 3d 20 73 54 65 78 74 0a  ealText = sText.
0520: 20 20 20 20 64 44 41 20 3d 20 7b 7d 20 20 20 20      dDA = {}    
0530: 20 20 20 20 23 20 44 69 73 61 6d 62 69 67 75 69      # Disambigui
0540: 73 61 74 6f 72 2e 20 4b 65 79 20 3d 20 70 6f 73  sator. Key = pos
0550: 69 74 69 6f 6e 3b 20 76 61 6c 75 65 20 3d 20 6c  ition; value = l
0560: 69 73 74 20 6f 66 20 6d 6f 72 70 68 6f 6c 6f 67  ist of morpholog
0570: 69 65 73 0a 20 20 20 20 64 50 72 69 6f 72 69 74  ies.    dPriorit
0580: 79 20 3d 20 7b 7d 20 20 23 20 4b 65 79 20 3d 20  y = {}  # Key = 
0590: 70 6f 73 69 74 69 6f 6e 3b 20 76 61 6c 75 65 20  position; value 
05a0: 3d 20 70 72 69 6f 72 69 74 79 0a 20 20 20 20 64  = priority.    d
05b0: 4f 70 74 20 3d 20 5f 64 4f 70 74 69 6f 6e 73 20  Opt = _dOptions 
05c0: 20 69 66 20 6e 6f 74 20 64 4f 70 74 69 6f 6e 73   if not dOptions
05d0: 20 20 65 6c 73 65 20 64 4f 70 74 69 6f 6e 73 0a    else dOptions.
05e0: 20 20 20 20 62 53 68 6f 77 52 75 6c 65 49 64 20      bShowRuleId 
05f0: 3d 20 6f 70 74 69 6f 6e 28 27 69 64 72 75 6c 65  = option('idrule
0600: 27 29 0a 0a 20 20 20 20 23 20 70 61 72 73 65 20  ')..    # parse 
0610: 70 61 72 61 67 72 61 70 68 0a 20 20 20 20 74 72  paragraph.    tr
0620: 79 3a 0a 20 20 20 20 20 20 20 20 73 4e 65 77 2c  y:.        sNew,
0630: 20 61 45 72 72 6f 72 73 20 3d 20 5f 70 72 6f 6f   aErrors = _proo
0640: 66 72 65 61 64 28 73 54 65 78 74 2c 20 73 52 65  fread(sText, sRe
0650: 61 6c 54 65 78 74 2c 20 30 2c 20 54 72 75 65 2c  alText, 0, True,
0660: 20 64 44 41 2c 20 64 50 72 69 6f 72 69 74 79 2c   dDA, dPriority,
0670: 20 73 43 6f 75 6e 74 72 79 2c 20 64 4f 70 74 2c   sCountry, dOpt,
0680: 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 44   bShowRuleId, bD
0690: 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74 29 0a  ebug, bContext).
06a0: 20 20 20 20 20 20 20 20 69 66 20 73 4e 65 77 3a          if sNew:
06b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 54 65  .            sTe
06c0: 78 74 20 3d 20 73 4e 65 77 0a 20 20 20 20 65 78  xt = sNew.    ex
06d0: 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 72 61  cept:.        ra
06e0: 69 73 65 0a 0a 20 20 20 20 23 20 63 6c 65 61 6e  ise..    # clean
06f0: 75 70 0a 20 20 20 20 69 66 20 22 c2 a0 22 20 69  up.    if ".." i
0700: 6e 20 73 54 65 78 74 3a 0a 20 20 20 20 20 20 20  n sText:.       
0710: 20 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e 72   sText = sText.r
0720: 65 70 6c 61 63 65 28 22 c2 a0 22 2c 20 27 20 27  eplace("..", ' '
0730: 29 20 23 20 6e 62 73 70 0a 20 20 20 20 69 66 20  ) # nbsp.    if 
0740: 22 e2 80 af 22 20 69 6e 20 73 54 65 78 74 3a 0a  "..." in sText:.
0750: 20 20 20 20 20 20 20 20 73 54 65 78 74 20 3d 20          sText = 
0760: 73 54 65 78 74 2e 72 65 70 6c 61 63 65 28 22 e2  sText.replace(".
0770: 80 af 22 2c 20 27 20 27 29 20 23 20 6e 6e 62 73  ..", ' ') # nnbs
0780: 70 0a 20 20 20 20 69 66 20 22 27 22 20 69 6e 20  p.    if "'" in 
0790: 73 54 65 78 74 3a 0a 20 20 20 20 20 20 20 20 73  sText:.        s
07a0: 54 65 78 74 20 3d 20 73 54 65 78 74 2e 72 65 70  Text = sText.rep
07b0: 6c 61 63 65 28 22 27 22 2c 20 22 e2 80 99 22 29  lace("'", "...")
07c0: 0a 20 20 20 20 69 66 20 22 e2 80 91 22 20 69 6e  .    if "..." in
07d0: 20 73 54 65 78 74 3a 0a 20 20 20 20 20 20 20 20   sText:.        
07e0: 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e 72 65  sText = sText.re
07f0: 70 6c 61 63 65 28 22 e2 80 91 22 2c 20 22 2d 22  place("...", "-"
0800: 29 20 23 20 6e 6f 62 72 65 61 6b 64 61 73 68 0a  ) # nobreakdash.
0810: 0a 20 20 20 20 23 20 70 61 72 73 65 20 73 65 6e  .    # parse sen
0820: 74 65 6e 63 65 73 0a 20 20 20 20 66 6f 72 20 69  tences.    for i
0830: 53 74 61 72 74 2c 20 69 45 6e 64 20 69 6e 20 5f  Start, iEnd in _
0840: 67 65 74 53 65 6e 74 65 6e 63 65 42 6f 75 6e 64  getSentenceBound
0850: 61 72 69 65 73 28 73 54 65 78 74 29 3a 0a 20 20  aries(sText):.  
0860: 20 20 20 20 20 20 69 66 20 34 20 3c 20 28 69 45        if 4 < (iE
0870: 6e 64 20 2d 20 69 53 74 61 72 74 29 20 3c 20 32  nd - iStart) < 2
0880: 30 30 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20  000:.           
0890: 20 64 44 41 2e 63 6c 65 61 72 28 29 0a 20 20 20   dDA.clear().   
08a0: 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20           try:.  
08b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
08c0: 72 65 67 65 78 20 70 61 72 73 65 72 0a 20 20 20  regex parser.   
08d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5f 2c 20               _, 
08e0: 65 72 72 73 20 3d 20 5f 70 72 6f 6f 66 72 65 61  errs = _proofrea
08f0: 64 28 73 54 65 78 74 5b 69 53 74 61 72 74 3a 69  d(sText[iStart:i
0900: 45 6e 64 5d 2c 20 73 52 65 61 6c 54 65 78 74 5b  End], sRealText[
0910: 69 53 74 61 72 74 3a 69 45 6e 64 5d 2c 20 69 53  iStart:iEnd], iS
0920: 74 61 72 74 2c 20 46 61 6c 73 65 2c 20 64 44 41  tart, False, dDA
0930: 2c 20 64 50 72 69 6f 72 69 74 79 2c 20 73 43 6f  , dPriority, sCo
0940: 75 6e 74 72 79 2c 20 64 4f 70 74 2c 20 62 53 68  untry, dOpt, bSh
0950: 6f 77 52 75 6c 65 49 64 2c 20 62 44 65 62 75 67  owRuleId, bDebug
0960: 2c 20 62 43 6f 6e 74 65 78 74 29 0a 20 20 20 20  , bContext).    
0970: 20 20 20 20 20 20 20 20 20 20 20 20 61 45 72 72              aErr
0980: 6f 72 73 2e 75 70 64 61 74 65 28 65 72 72 73 29  ors.update(errs)
0990: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
09a0: 20 23 20 74 6f 6b 65 6e 20 70 61 72 73 65 72 0a   # token parser.
09b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09c0: 6f 53 65 6e 74 65 6e 63 65 20 3d 20 54 6f 6b 65  oSentence = Toke
09d0: 6e 53 65 6e 74 65 6e 63 65 28 73 54 65 78 74 5b  nSentence(sText[
09e0: 69 53 74 61 72 74 3a 69 45 6e 64 5d 2c 20 73 52  iStart:iEnd], sR
09f0: 65 61 6c 54 65 78 74 5b 69 53 74 61 72 74 3a 69  ealText[iStart:i
0a00: 45 6e 64 5d 2c 20 69 53 74 61 72 74 29 0a 20 20  End], iStart).  
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5f 2c                _,
0a20: 20 65 72 72 73 20 3d 20 6f 53 65 6e 74 65 6e 63   errs = oSentenc
0a30: 65 2e 70 61 72 73 65 28 64 50 72 69 6f 72 69 74  e.parse(dPriorit
0a40: 79 2c 20 73 43 6f 75 6e 74 72 79 2c 20 64 4f 70  y, sCountry, dOp
0a50: 74 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20  t, bShowRuleId, 
0a60: 62 44 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74  bDebug, bContext
0a70: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
0a80: 20 20 61 45 72 72 6f 72 73 2e 75 70 64 61 74 65    aErrors.update
0a90: 28 65 72 72 73 29 0a 20 20 20 20 20 20 20 20 20  (errs).         
0aa0: 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20     except:.     
0ab0: 20 20 20 20 20 20 20 20 20 20 20 72 61 69 73 65             raise
0ac0: 0a 20 20 20 20 72 65 74 75 72 6e 20 61 45 72 72  .    return aErr
0ad0: 6f 72 73 2e 76 61 6c 75 65 73 28 29 20 23 20 74  ors.values() # t
0ae0: 68 69 73 20 69 73 20 61 20 76 69 65 77 20 28 69  his is a view (i
0af0: 74 65 72 61 62 6c 65 29 0a 0a 0a 64 65 66 20 5f  terable)...def _
0b00: 67 65 74 53 65 6e 74 65 6e 63 65 42 6f 75 6e 64  getSentenceBound
0b10: 61 72 69 65 73 20 28 73 54 65 78 74 29 3a 0a 20  aries (sText):. 
0b20: 20 20 20 69 53 74 61 72 74 20 3d 20 5f 7a 42 65     iStart = _zBe
0b30: 67 69 6e 4f 66 50 61 72 61 67 72 61 70 68 2e 6d  ginOfParagraph.m
0b40: 61 74 63 68 28 73 54 65 78 74 29 2e 65 6e 64 28  atch(sText).end(
0b50: 29 0a 20 20 20 20 66 6f 72 20 6d 20 69 6e 20 5f  ).    for m in _
0b60: 7a 45 6e 64 4f 66 53 65 6e 74 65 6e 63 65 2e 66  zEndOfSentence.f
0b70: 69 6e 64 69 74 65 72 28 73 54 65 78 74 29 3a 0a  inditer(sText):.
0b80: 20 20 20 20 20 20 20 20 79 69 65 6c 64 20 28 69          yield (i
0b90: 53 74 61 72 74 2c 20 6d 2e 65 6e 64 28 29 29 0a  Start, m.end()).
0ba0: 20 20 20 20 20 20 20 20 69 53 74 61 72 74 20 3d          iStart =
0bb0: 20 6d 2e 65 6e 64 28 29 0a 0a 0a 64 65 66 20 5f   m.end()...def _
0bc0: 70 72 6f 6f 66 72 65 61 64 20 28 73 2c 20 73 78  proofread (s, sx
0bd0: 2c 20 6e 4f 66 66 73 65 74 2c 20 62 50 61 72 61  , nOffset, bPara
0be0: 67 72 61 70 68 2c 20 64 44 41 2c 20 64 50 72 69  graph, dDA, dPri
0bf0: 6f 72 69 74 79 2c 20 73 43 6f 75 6e 74 72 79 2c  ority, sCountry,
0c00: 20 64 4f 70 74 69 6f 6e 73 2c 20 62 53 68 6f 77   dOptions, bShow
0c10: 52 75 6c 65 49 64 2c 20 62 44 65 62 75 67 2c 20  RuleId, bDebug, 
0c20: 62 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 64  bContext):.    d
0c30: 45 72 72 73 20 3d 20 7b 7d 0a 20 20 20 20 62 43  Errs = {}.    bC
0c40: 68 61 6e 67 65 20 3d 20 46 61 6c 73 65 0a 20 20  hange = False.  
0c50: 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 6c    for sOption, l
0c60: 52 75 6c 65 47 72 6f 75 70 20 69 6e 20 5f 67 65  RuleGroup in _ge
0c70: 74 52 75 6c 65 73 28 62 50 61 72 61 67 72 61 70  tRules(bParagrap
0c80: 68 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e  h):.        if n
0c90: 6f 74 20 73 4f 70 74 69 6f 6e 20 6f 72 20 64 4f  ot sOption or dO
0ca0: 70 74 69 6f 6e 73 2e 67 65 74 28 73 4f 70 74 69  ptions.get(sOpti
0cb0: 6f 6e 2c 20 46 61 6c 73 65 29 3a 0a 20 20 20 20  on, False):.    
0cc0: 20 20 20 20 20 20 20 20 66 6f 72 20 7a 52 65 67          for zReg
0cd0: 65 78 2c 20 62 55 70 70 65 72 63 61 73 65 2c 20  ex, bUppercase, 
0ce0: 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64  sLineId, sRuleId
0cf0: 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 6c 41 63  , nPriority, lAc
0d00: 74 69 6f 6e 73 20 69 6e 20 6c 52 75 6c 65 47 72  tions in lRuleGr
0d10: 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20  oup:.           
0d20: 20 20 20 20 20 69 66 20 73 52 75 6c 65 49 64 20       if sRuleId 
0d30: 6e 6f 74 20 69 6e 20 5f 61 49 67 6e 6f 72 65 64  not in _aIgnored
0d40: 52 75 6c 65 73 3a 0a 20 20 20 20 20 20 20 20 20  Rules:.         
0d50: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 6d             for m
0d60: 20 69 6e 20 7a 52 65 67 65 78 2e 66 69 6e 64 69   in zRegex.findi
0d70: 74 65 72 28 73 29 3a 0a 20 20 20 20 20 20 20 20  ter(s):.        
0d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d90: 62 43 6f 6e 64 4d 65 6d 6f 20 3d 20 4e 6f 6e 65  bCondMemo = None
0da0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0db0: 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 46 75           for sFu
0dc0: 6e 63 43 6f 6e 64 2c 20 63 41 63 74 69 6f 6e 54  ncCond, cActionT
0dd0: 79 70 65 2c 20 73 57 68 61 74 2c 20 2a 65 41 63  ype, sWhat, *eAc
0de0: 74 20 69 6e 20 6c 41 63 74 69 6f 6e 73 3a 0a 20  t in lActions:. 
0df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e00: 20 20 20 20 20 20 20 20 20 20 20 23 20 61 63 74             # act
0e10: 69 6f 6e 20 69 6e 20 6c 41 63 74 69 6f 6e 73 3a  ion in lActions:
0e20: 20 5b 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 61 63   [ condition, ac
0e30: 74 69 6f 6e 20 74 79 70 65 2c 20 72 65 70 6c 61  tion type, repla
0e40: 63 65 6d 65 6e 74 2f 73 75 67 67 65 73 74 69 6f  cement/suggestio
0e50: 6e 2f 61 63 74 69 6f 6e 5b 2c 20 69 47 72 6f 75  n/action[, iGrou
0e60: 70 5b 2c 20 6d 65 73 73 61 67 65 2c 20 55 52 4c  p[, message, URL
0e70: 5d 5d 20 5d 0a 20 20 20 20 20 20 20 20 20 20 20  ]] ].           
0e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e90: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20   try:.          
0ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0eb0: 20 20 20 20 20 20 62 43 6f 6e 64 4d 65 6d 6f 20        bCondMemo 
0ec0: 3d 20 6e 6f 74 20 73 46 75 6e 63 43 6f 6e 64 20  = not sFuncCond 
0ed0: 6f 72 20 67 6c 6f 62 61 6c 73 28 29 5b 73 46 75  or globals()[sFu
0ee0: 6e 63 43 6f 6e 64 5d 28 73 2c 20 73 78 2c 20 6d  ncCond](s, sx, m
0ef0: 2c 20 64 44 41 2c 20 73 43 6f 75 6e 74 72 79 2c  , dDA, sCountry,
0f00: 20 62 43 6f 6e 64 4d 65 6d 6f 29 0a 20 20 20 20   bCondMemo).    
0f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f20: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
0f30: 43 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20 20 20  CondMemo:.      
0f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
0f60: 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20   cActionType == 
0f70: 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "-":.           
0f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 67               # g
0fa0: 72 61 6d 6d 61 72 20 65 72 72 6f 72 0a 20 20 20  rammar error.   
0fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0fd0: 20 20 20 20 20 6e 45 72 72 6f 72 53 74 61 72 74       nErrorStart
0fe0: 20 3d 20 6e 4f 66 66 73 65 74 20 2b 20 6d 2e 73   = nOffset + m.s
0ff0: 74 61 72 74 28 65 41 63 74 5b 30 5d 29 0a 20 20  tart(eAct[0]).  
1000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1020: 20 20 20 20 20 20 69 66 20 6e 45 72 72 6f 72 53        if nErrorS
1030: 74 61 72 74 20 6e 6f 74 20 69 6e 20 64 45 72 72  tart not in dErr
1040: 73 20 6f 72 20 6e 50 72 69 6f 72 69 74 79 20 3e  s or nPriority >
1050: 20 64 50 72 69 6f 72 69 74 79 5b 6e 45 72 72 6f   dPriority[nErro
1060: 72 53 74 61 72 74 5d 3a 0a 20 20 20 20 20 20 20  rStart]:.       
1070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1090: 20 20 20 20 20 64 45 72 72 73 5b 6e 45 72 72 6f       dErrs[nErro
10a0: 72 53 74 61 72 74 5d 20 3d 20 5f 63 72 65 61 74  rStart] = _creat
10b0: 65 52 65 67 65 78 45 72 72 6f 72 28 73 2c 20 73  eRegexError(s, s
10c0: 78 2c 20 73 57 68 61 74 2c 20 6e 4f 66 66 73 65  x, sWhat, nOffse
10d0: 74 2c 20 6d 2c 20 65 41 63 74 5b 30 5d 2c 20 73  t, m, eAct[0], s
10e0: 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c  LineId, sRuleId,
10f0: 20 62 55 70 70 65 72 63 61 73 65 2c 20 65 41 63   bUppercase, eAc
1100: 74 5b 31 5d 2c 20 65 41 63 74 5b 32 5d 2c 20 62  t[1], eAct[2], b
1110: 53 68 6f 77 52 75 6c 65 49 64 2c 20 73 4f 70 74  ShowRuleId, sOpt
1120: 69 6f 6e 2c 20 62 43 6f 6e 74 65 78 74 29 0a 20  ion, bContext). 
1130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1150: 20 20 20 20 20 20 20 20 20 20 20 64 50 72 69 6f             dPrio
1160: 72 69 74 79 5b 6e 45 72 72 6f 72 53 74 61 72 74  rity[nErrorStart
1170: 5d 20 3d 20 6e 50 72 69 6f 72 69 74 79 0a 20 20  ] = nPriority.  
1180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11a0: 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54 79    elif cActionTy
11b0: 70 65 20 3d 3d 20 22 7e 22 3a 0a 20 20 20 20 20  pe == "~":.     
11c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11e0: 20 20 20 23 20 74 65 78 74 20 70 72 6f 63 65 73     # text proces
11f0: 73 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20  sor.            
1200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1210: 20 20 20 20 20 20 20 20 20 20 20 20 73 20 3d 20              s = 
1220: 5f 72 65 77 72 69 74 65 28 73 2c 20 73 57 68 61  _rewrite(s, sWha
1230: 74 2c 20 65 41 63 74 5b 30 5d 2c 20 6d 2c 20 62  t, eAct[0], m, b
1240: 55 70 70 65 72 63 61 73 65 29 0a 20 20 20 20 20  Uppercase).     
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1270: 20 20 20 62 43 68 61 6e 67 65 20 3d 20 54 72 75     bChange = Tru
1280: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
1290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12a0: 20 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65            if bDe
12b0: 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20  bug:.           
12c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12e0: 20 65 63 68 6f 28 22 7e 20 22 20 2b 20 73 20 2b   echo("~ " + s +
12f0: 20 22 20 20 2d 2d 20 22 20 2b 20 6d 2e 67 72 6f   "  -- " + m.gro
1300: 75 70 28 65 41 63 74 5b 30 5d 29 20 2b 20 22 20  up(eAct[0]) + " 
1310: 20 23 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a   # " + sLineId).
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1340: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
1350: 54 79 70 65 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  Type == "=":.   
1360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1380: 20 20 20 20 20 23 20 64 69 73 61 6d 62 69 67 75       # disambigu
1390: 61 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20  ation.          
13a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 67 6c                gl
13c0: 6f 62 61 6c 73 28 29 5b 73 57 68 61 74 5d 28 73  obals()[sWhat](s
13d0: 2c 20 6d 2c 20 64 44 41 29 0a 20 20 20 20 20 20  , m, dDA).      
13e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1400: 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20    if bDebug:.   
1410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1430: 20 20 20 20 20 20 20 20 20 65 63 68 6f 28 22 3d           echo("=
1440: 20 22 20 2b 20 6d 2e 67 72 6f 75 70 28 30 29 20   " + m.group(0) 
1450: 2b 20 22 20 20 23 20 22 20 2b 20 73 4c 69 6e 65  + "  # " + sLine
1460: 49 64 20 2b 20 22 5c 6e 44 41 3a 20 22 20 2b 20  Id + "\nDA: " + 
1470: 73 74 72 28 64 44 41 29 29 0a 20 20 20 20 20 20  str(dDA)).      
1480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
14a0: 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d  if cActionType =
14b0: 3d 20 22 3e 22 3a 0a 20 20 20 20 20 20 20 20 20  = ">":.         
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
14e0: 20 77 65 20 64 6f 20 6e 6f 74 68 69 6e 67 2c 20   we do nothing, 
14f0: 74 68 69 73 20 74 65 73 74 20 69 73 20 6a 75 73  this test is jus
1500: 74 20 61 20 63 6f 6e 64 69 74 69 6f 6e 20 74 6f  t a condition to
1510: 20 61 70 70 6c 79 20 61 6c 6c 20 66 6f 6c 6c 6f   apply all follo
1520: 77 69 6e 67 20 61 63 74 69 6f 6e 73 0a 20 20 20  wing actions.   
1530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1550: 20 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 20       pass.      
1560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
1580: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
1590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15a0: 20 20 20 20 20 20 20 20 20 20 20 20 65 63 68 6f              echo
15b0: 28 22 23 20 65 72 72 6f 72 3a 20 75 6e 6b 6e 6f  ("# error: unkno
15c0: 77 6e 20 61 63 74 69 6f 6e 20 61 74 20 22 20 2b  wn action at " +
15d0: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
15e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15f0: 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63            elif c
1600: 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 3e  ActionType == ">
1610: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
1620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1630: 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20 20         break.   
1640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1650: 20 20 20 20 20 20 20 20 20 65 78 63 65 70 74 20           except 
1660: 45 78 63 65 70 74 69 6f 6e 20 61 73 20 65 3a 0a  Exception as e:.
1670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1690: 72 61 69 73 65 20 45 78 63 65 70 74 69 6f 6e 28  raise Exception(
16a0: 73 74 72 28 65 29 2c 20 22 23 20 22 20 2b 20 73  str(e), "# " + s
16b0: 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20 2b  LineId + " # " +
16c0: 20 73 52 75 6c 65 49 64 29 0a 20 20 20 20 69 66   sRuleId).    if
16d0: 20 62 43 68 61 6e 67 65 3a 0a 20 20 20 20 20 20   bChange:.      
16e0: 20 20 72 65 74 75 72 6e 20 28 73 2c 20 64 45 72    return (s, dEr
16f0: 72 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20 28  rs).    return (
1700: 46 61 6c 73 65 2c 20 64 45 72 72 73 29 0a 0a 0a  False, dErrs)...
1710: 64 65 66 20 5f 63 72 65 61 74 65 52 65 67 65 78  def _createRegex
1720: 57 72 69 74 65 72 45 72 72 6f 72 20 28 73 2c 20  WriterError (s, 
1730: 73 78 2c 20 73 52 65 70 6c 2c 20 6e 4f 66 66 73  sx, sRepl, nOffs
1740: 65 74 2c 20 6d 2c 20 69 47 72 6f 75 70 2c 20 73  et, m, iGroup, s
1750: 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c  LineId, sRuleId,
1760: 20 62 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73   bUppercase, sMs
1770: 67 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75  g, sURL, bShowRu
1780: 6c 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62  leId, sOption, b
1790: 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 22 65  Context):.    "e
17a0: 72 72 6f 72 20 66 6f 72 20 57 72 69 74 65 72 20  rror for Writer 
17b0: 28 4c 4f 2f 4f 4f 29 22 0a 20 20 20 20 78 45 72  (LO/OO)".    xEr
17c0: 72 20 3d 20 53 69 6e 67 6c 65 50 72 6f 6f 66 72  r = SingleProofr
17d0: 65 61 64 69 6e 67 45 72 72 6f 72 28 29 0a 20 20  eadingError().  
17e0: 20 20 23 78 45 72 72 20 3d 20 75 6e 6f 2e 63 72    #xErr = uno.cr
17f0: 65 61 74 65 55 6e 6f 53 74 72 75 63 74 28 20 22  eateUnoStruct( "
1800: 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 6c 69 6e  com.sun.star.lin
1810: 67 75 69 73 74 69 63 32 2e 53 69 6e 67 6c 65 50  guistic2.SingleP
1820: 72 6f 6f 66 72 65 61 64 69 6e 67 45 72 72 6f 72  roofreadingError
1830: 22 20 29 0a 20 20 20 20 78 45 72 72 2e 6e 45 72  " ).    xErr.nEr
1840: 72 6f 72 53 74 61 72 74 20 3d 20 6e 4f 66 66 73  rorStart = nOffs
1850: 65 74 20 2b 20 6d 2e 73 74 61 72 74 28 69 47 72  et + m.start(iGr
1860: 6f 75 70 29 0a 20 20 20 20 78 45 72 72 2e 6e 45  oup).    xErr.nE
1870: 72 72 6f 72 4c 65 6e 67 74 68 20 3d 20 6d 2e 65  rrorLength = m.e
1880: 6e 64 28 69 47 72 6f 75 70 29 20 2d 20 6d 2e 73  nd(iGroup) - m.s
1890: 74 61 72 74 28 69 47 72 6f 75 70 29 0a 20 20 20  tart(iGroup).   
18a0: 20 78 45 72 72 2e 6e 45 72 72 6f 72 54 79 70 65   xErr.nErrorType
18b0: 20 3d 20 50 52 4f 4f 46 52 45 41 44 49 4e 47 0a   = PROOFREADING.
18c0: 20 20 20 20 78 45 72 72 2e 61 52 75 6c 65 49 64      xErr.aRuleId
18d0: 65 6e 74 69 66 69 65 72 20 3d 20 73 52 75 6c 65  entifier = sRule
18e0: 49 64 0a 20 20 20 20 23 20 73 75 67 67 65 73 74  Id.    # suggest
18f0: 69 6f 6e 73 0a 20 20 20 20 69 66 20 73 52 65 70  ions.    if sRep
1900: 6c 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20  l[0:1] == "=":. 
1910: 20 20 20 20 20 20 20 73 75 67 67 20 3d 20 67 6c         sugg = gl
1920: 6f 62 61 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a  obals()[sRepl[1:
1930: 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20 20 20 20  ]](s, m).       
1940: 20 69 66 20 73 75 67 67 3a 0a 20 20 20 20 20 20   if sugg:.      
1950: 20 20 20 20 20 20 69 66 20 62 55 70 70 65 72 63        if bUpperc
1960: 61 73 65 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28  ase and m.group(
1970: 69 47 72 6f 75 70 29 5b 30 3a 31 5d 2e 69 73 75  iGroup)[0:1].isu
1980: 70 70 65 72 28 29 3a 0a 20 20 20 20 20 20 20 20  pper():.        
1990: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 75          xErr.aSu
19a0: 67 67 65 73 74 69 6f 6e 73 20 3d 20 74 75 70 6c  ggestions = tupl
19b0: 65 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61  e(map(str.capita
19c0: 6c 69 7a 65 2c 20 73 75 67 67 2e 73 70 6c 69 74  lize, sugg.split
19d0: 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20  ("|"))).        
19e0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
19f0: 20 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61            xErr.a
1a00: 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74 75  Suggestions = tu
1a10: 70 6c 65 28 73 75 67 67 2e 73 70 6c 69 74 28 22  ple(sugg.split("
1a20: 7c 22 29 29 0a 20 20 20 20 20 20 20 20 65 6c 73  |")).        els
1a30: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 78  e:.            x
1a40: 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73  Err.aSuggestions
1a50: 20 3d 20 28 29 0a 20 20 20 20 65 6c 69 66 20 73   = ().    elif s
1a60: 52 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20  Repl == "_":.   
1a70: 20 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65       xErr.aSugge
1a80: 73 74 69 6f 6e 73 20 3d 20 28 29 0a 20 20 20 20  stions = ().    
1a90: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 69 66  else:.        if
1aa0: 20 62 55 70 70 65 72 63 61 73 65 20 61 6e 64 20   bUppercase and 
1ab0: 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75 70 29 5b  m.group(iGroup)[
1ac0: 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a  0:1].isupper():.
1ad0: 20 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72              xErr
1ae0: 2e 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20  .aSuggestions = 
1af0: 74 75 70 6c 65 28 6d 61 70 28 73 74 72 2e 63 61  tuple(map(str.ca
1b00: 70 69 74 61 6c 69 7a 65 2c 20 6d 2e 65 78 70 61  pitalize, m.expa
1b10: 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c 69 74 28  nd(sRepl).split(
1b20: 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20 65  "|"))).        e
1b30: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
1b40: 20 78 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f   xErr.aSuggestio
1b50: 6e 73 20 3d 20 74 75 70 6c 65 28 6d 2e 65 78 70  ns = tuple(m.exp
1b60: 61 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c 69 74  and(sRepl).split
1b70: 28 22 7c 22 29 29 0a 20 20 20 20 23 20 4d 65 73  ("|")).    # Mes
1b80: 73 61 67 65 0a 20 20 20 20 69 66 20 73 4d 73 67  sage.    if sMsg
1b90: 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20  [0:1] == "=":.  
1ba0: 20 20 20 20 20 20 73 4d 65 73 73 61 67 65 20 3d        sMessage =
1bb0: 20 67 6c 6f 62 61 6c 73 28 29 5b 73 4d 73 67 5b   globals()[sMsg[
1bc0: 31 3a 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20 65  1:]](s, m).    e
1bd0: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 73 4d 65  lse:.        sMe
1be0: 73 73 61 67 65 20 3d 20 6d 2e 65 78 70 61 6e 64  ssage = m.expand
1bf0: 28 73 4d 73 67 29 0a 20 20 20 20 78 45 72 72 2e  (sMsg).    xErr.
1c00: 61 53 68 6f 72 74 43 6f 6d 6d 65 6e 74 20 3d 20  aShortComment = 
1c10: 73 4d 65 73 73 61 67 65 20 20 20 23 20 73 4d 65  sMessage   # sMe
1c20: 73 73 61 67 65 2e 73 70 6c 69 74 28 22 7c 22 29  ssage.split("|")
1c30: 5b 30 5d 20 20 20 20 20 23 20 69 6e 20 63 6f 6e  [0]     # in con
1c40: 74 65 78 74 20 6d 65 6e 75 0a 20 20 20 20 78 45  text menu.    xE
1c50: 72 72 2e 61 46 75 6c 6c 43 6f 6d 6d 65 6e 74 20  rr.aFullComment 
1c60: 3d 20 73 4d 65 73 73 61 67 65 20 20 20 23 20 73  = sMessage   # s
1c70: 4d 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22 7c  Message.split("|
1c80: 22 29 5b 2d 31 5d 20 20 20 20 23 20 69 6e 20 64  ")[-1]    # in d
1c90: 69 61 6c 6f 67 0a 20 20 20 20 69 66 20 62 53 68  ialog.    if bSh
1ca0: 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20 20 20 20  owRuleId:.      
1cb0: 20 20 78 45 72 72 2e 61 53 68 6f 72 74 43 6f 6d    xErr.aShortCom
1cc0: 6d 65 6e 74 20 2b 3d 20 22 20 20 23 20 22 20 2b  ment += "  # " +
1cd0: 20 73 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22   sLineId + " # "
1ce0: 20 2b 20 73 52 75 6c 65 49 64 0a 20 20 20 20 23   + sRuleId.    #
1cf0: 20 55 52 4c 0a 20 20 20 20 69 66 20 73 55 52 4c   URL.    if sURL
1d00: 3a 0a 20 20 20 20 20 20 20 20 70 20 3d 20 50 72  :.        p = Pr
1d10: 6f 70 65 72 74 79 56 61 6c 75 65 28 29 0a 20 20  opertyValue().  
1d20: 20 20 20 20 20 20 70 2e 4e 61 6d 65 20 3d 20 22        p.Name = "
1d30: 46 75 6c 6c 43 6f 6d 6d 65 6e 74 55 52 4c 22 0a  FullCommentURL".
1d40: 20 20 20 20 20 20 20 20 70 2e 56 61 6c 75 65 20          p.Value 
1d50: 3d 20 73 55 52 4c 0a 20 20 20 20 20 20 20 20 78  = sURL.        x
1d60: 45 72 72 2e 61 50 72 6f 70 65 72 74 69 65 73 20  Err.aProperties 
1d70: 3d 20 28 70 2c 29 0a 20 20 20 20 65 6c 73 65 3a  = (p,).    else:
1d80: 0a 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 50  .        xErr.aP
1d90: 72 6f 70 65 72 74 69 65 73 20 3d 20 28 29 0a 20  roperties = (). 
1da0: 20 20 20 72 65 74 75 72 6e 20 78 45 72 72 0a 0a     return xErr..
1db0: 0a 64 65 66 20 5f 63 72 65 61 74 65 52 65 67 65  .def _createRege
1dc0: 78 44 69 63 74 45 72 72 6f 72 20 28 73 2c 20 73  xDictError (s, s
1dd0: 78 2c 20 73 52 65 70 6c 2c 20 6e 4f 66 66 73 65  x, sRepl, nOffse
1de0: 74 2c 20 6d 2c 20 69 47 72 6f 75 70 2c 20 73 4c  t, m, iGroup, sL
1df0: 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20  ineId, sRuleId, 
1e00: 62 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73 67  bUppercase, sMsg
1e10: 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75 6c  , sURL, bShowRul
1e20: 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62 43  eId, sOption, bC
1e30: 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 22 65 72  ontext):.    "er
1e40: 72 6f 72 20 61 73 20 61 20 64 69 63 74 69 6f 6e  ror as a diction
1e50: 61 72 79 22 0a 20 20 20 20 64 45 72 72 20 3d 20  ary".    dErr = 
1e60: 7b 7d 0a 20 20 20 20 64 45 72 72 5b 22 6e 53 74  {}.    dErr["nSt
1e70: 61 72 74 22 5d 20 3d 20 6e 4f 66 66 73 65 74 20  art"] = nOffset 
1e80: 2b 20 6d 2e 73 74 61 72 74 28 69 47 72 6f 75 70  + m.start(iGroup
1e90: 29 0a 20 20 20 20 64 45 72 72 5b 22 6e 45 6e 64  ).    dErr["nEnd
1ea0: 22 5d 20 3d 20 6e 4f 66 66 73 65 74 20 2b 20 6d  "] = nOffset + m
1eb0: 2e 65 6e 64 28 69 47 72 6f 75 70 29 0a 20 20 20  .end(iGroup).   
1ec0: 20 64 45 72 72 5b 22 73 4c 69 6e 65 49 64 22 5d   dErr["sLineId"]
1ed0: 20 3d 20 73 4c 69 6e 65 49 64 0a 20 20 20 20 64   = sLineId.    d
1ee0: 45 72 72 5b 22 73 52 75 6c 65 49 64 22 5d 20 3d  Err["sRuleId"] =
1ef0: 20 73 52 75 6c 65 49 64 0a 20 20 20 20 64 45 72   sRuleId.    dEr
1f00: 72 5b 22 73 54 79 70 65 22 5d 20 3d 20 73 4f 70  r["sType"] = sOp
1f10: 74 69 6f 6e 20 20 69 66 20 73 4f 70 74 69 6f 6e  tion  if sOption
1f20: 20 20 65 6c 73 65 20 22 6e 6f 74 79 70 65 22 0a    else "notype".
1f30: 20 20 20 20 23 20 73 75 67 67 65 73 74 69 6f 6e      # suggestion
1f40: 73 0a 20 20 20 20 69 66 20 73 52 65 70 6c 5b 30  s.    if sRepl[0
1f50: 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20  :1] == "=":.    
1f60: 20 20 20 20 73 75 67 67 20 3d 20 67 6c 6f 62 61      sugg = globa
1f70: 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a 5d 5d 28  ls()[sRepl[1:]](
1f80: 73 2c 20 6d 29 0a 20 20 20 20 20 20 20 20 69 66  s, m).        if
1f90: 20 73 75 67 67 3a 0a 20 20 20 20 20 20 20 20 20   sugg:.         
1fa0: 20 20 20 69 66 20 62 55 70 70 65 72 63 61 73 65     if bUppercase
1fb0: 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 69 47 72   and m.group(iGr
1fc0: 6f 75 70 29 5b 30 3a 31 5d 2e 69 73 75 70 70 65  oup)[0:1].isuppe
1fd0: 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  r():.           
1fe0: 20 20 20 20 20 64 45 72 72 5b 22 61 53 75 67 67       dErr["aSugg
1ff0: 65 73 74 69 6f 6e 73 22 5d 20 3d 20 6c 69 73 74  estions"] = list
2000: 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61 6c  (map(str.capital
2010: 69 7a 65 2c 20 73 75 67 67 2e 73 70 6c 69 74 28  ize, sugg.split(
2020: 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20 20  "|"))).         
2030: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
2040: 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61           dErr["a
2050: 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20  Suggestions"] = 
2060: 73 75 67 67 2e 73 70 6c 69 74 28 22 7c 22 29 0a  sugg.split("|").
2070: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
2080: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
2090: 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d  aSuggestions"] =
20a0: 20 5b 5d 0a 20 20 20 20 65 6c 69 66 20 73 52 65   [].    elif sRe
20b0: 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20 20  pl == "_":.     
20c0: 20 20 20 64 45 72 72 5b 22 61 53 75 67 67 65 73     dErr["aSugges
20d0: 74 69 6f 6e 73 22 5d 20 3d 20 5b 5d 0a 20 20 20  tions"] = [].   
20e0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 69   else:.        i
20f0: 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e 64  f bUppercase and
2100: 20 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75 70 29   m.group(iGroup)
2110: 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 3a  [0:1].isupper():
2120: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72  .            dEr
2130: 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e 73 22  r["aSuggestions"
2140: 5d 20 3d 20 6c 69 73 74 28 6d 61 70 28 73 74 72  ] = list(map(str
2150: 2e 63 61 70 69 74 61 6c 69 7a 65 2c 20 6d 2e 65  .capitalize, m.e
2160: 78 70 61 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c  xpand(sRepl).spl
2170: 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20  it("|"))).      
2180: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2190: 20 20 20 20 64 45 72 72 5b 22 61 53 75 67 67 65      dErr["aSugge
21a0: 73 74 69 6f 6e 73 22 5d 20 3d 20 6d 2e 65 78 70  stions"] = m.exp
21b0: 61 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c 69 74  and(sRepl).split
21c0: 28 22 7c 22 29 0a 20 20 20 20 23 20 4d 65 73 73  ("|").    # Mess
21d0: 61 67 65 0a 20 20 20 20 69 66 20 73 4d 73 67 5b  age.    if sMsg[
21e0: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
21f0: 20 20 20 20 20 73 4d 65 73 73 61 67 65 20 3d 20       sMessage = 
2200: 67 6c 6f 62 61 6c 73 28 29 5b 73 4d 73 67 5b 31  globals()[sMsg[1
2210: 3a 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20 65 6c  :]](s, m).    el
2220: 73 65 3a 0a 20 20 20 20 20 20 20 20 73 4d 65 73  se:.        sMes
2230: 73 61 67 65 20 3d 20 6d 2e 65 78 70 61 6e 64 28  sage = m.expand(
2240: 73 4d 73 67 29 0a 20 20 20 20 64 45 72 72 5b 22  sMsg).    dErr["
2250: 73 4d 65 73 73 61 67 65 22 5d 20 3d 20 73 4d 65  sMessage"] = sMe
2260: 73 73 61 67 65 0a 20 20 20 20 69 66 20 62 53 68  ssage.    if bSh
2270: 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20 20 20 20  owRuleId:.      
2280: 20 20 64 45 72 72 5b 22 73 4d 65 73 73 61 67 65    dErr["sMessage
2290: 22 5d 20 2b 3d 20 22 20 20 23 20 22 20 2b 20 73  "] += "  # " + s
22a0: 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20 2b  LineId + " # " +
22b0: 20 73 52 75 6c 65 49 64 0a 20 20 20 20 23 20 55   sRuleId.    # U
22c0: 52 4c 0a 20 20 20 20 64 45 72 72 5b 22 55 52 4c  RL.    dErr["URL
22d0: 22 5d 20 3d 20 73 55 52 4c 20 20 69 66 20 73 55  "] = sURL  if sU
22e0: 52 4c 20 20 65 6c 73 65 20 22 22 0a 20 20 20 20  RL  else "".    
22f0: 23 20 43 6f 6e 74 65 78 74 0a 20 20 20 20 69 66  # Context.    if
2300: 20 62 43 6f 6e 74 65 78 74 3a 0a 20 20 20 20 20   bContext:.     
2310: 20 20 20 64 45 72 72 5b 27 73 55 6e 64 65 72 6c     dErr['sUnderl
2320: 69 6e 65 64 27 5d 20 3d 20 73 78 5b 6d 2e 73 74  ined'] = sx[m.st
2330: 61 72 74 28 69 47 72 6f 75 70 29 3a 6d 2e 65 6e  art(iGroup):m.en
2340: 64 28 69 47 72 6f 75 70 29 5d 0a 20 20 20 20 20  d(iGroup)].     
2350: 20 20 20 64 45 72 72 5b 27 73 42 65 66 6f 72 65     dErr['sBefore
2360: 27 5d 20 3d 20 73 78 5b 6d 61 78 28 30 2c 6d 2e  '] = sx[max(0,m.
2370: 73 74 61 72 74 28 69 47 72 6f 75 70 29 2d 38 30  start(iGroup)-80
2380: 29 3a 6d 2e 73 74 61 72 74 28 69 47 72 6f 75 70  ):m.start(iGroup
2390: 29 5d 0a 20 20 20 20 20 20 20 20 64 45 72 72 5b  )].        dErr[
23a0: 27 73 41 66 74 65 72 27 5d 20 3d 20 73 78 5b 6d  'sAfter'] = sx[m
23b0: 2e 65 6e 64 28 69 47 72 6f 75 70 29 3a 6d 2e 65  .end(iGroup):m.e
23c0: 6e 64 28 69 47 72 6f 75 70 29 2b 38 30 5d 0a 20  nd(iGroup)+80]. 
23d0: 20 20 20 72 65 74 75 72 6e 20 64 45 72 72 0a 0a     return dErr..
23e0: 0a 64 65 66 20 5f 63 72 65 61 74 65 54 6f 6b 65  .def _createToke
23f0: 6e 57 72 69 74 65 72 45 72 72 6f 72 20 28 6c 54  nWriterError (lT
2400: 6f 6b 65 6e 2c 20 73 53 65 6e 74 65 6e 63 65 2c  oken, sSentence,
2410: 20 73 53 65 6e 74 65 6e 63 65 30 2c 20 73 52 65   sSentence0, sRe
2420: 70 6c 2c 20 69 46 69 72 73 74 54 6f 6b 65 6e 2c  pl, iFirstToken,
2430: 20 6e 53 74 61 72 74 2c 20 6e 45 6e 64 2c 20 73   nStart, nEnd, s
2440: 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c  LineId, sRuleId,
2450: 20 62 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73   bUppercase, sMs
2460: 67 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75  g, sURL, bShowRu
2470: 6c 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62  leId, sOption, b
2480: 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 22 65  Context):.    "e
2490: 72 72 6f 72 20 66 6f 72 20 57 72 69 74 65 72 20  rror for Writer 
24a0: 28 4c 4f 2f 4f 4f 29 22 0a 20 20 20 20 78 45 72  (LO/OO)".    xEr
24b0: 72 20 3d 20 53 69 6e 67 6c 65 50 72 6f 6f 66 72  r = SingleProofr
24c0: 65 61 64 69 6e 67 45 72 72 6f 72 28 29 0a 20 20  eadingError().  
24d0: 20 20 23 78 45 72 72 20 3d 20 75 6e 6f 2e 63 72    #xErr = uno.cr
24e0: 65 61 74 65 55 6e 6f 53 74 72 75 63 74 28 20 22  eateUnoStruct( "
24f0: 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 6c 69 6e  com.sun.star.lin
2500: 67 75 69 73 74 69 63 32 2e 53 69 6e 67 6c 65 50  guistic2.SingleP
2510: 72 6f 6f 66 72 65 61 64 69 6e 67 45 72 72 6f 72  roofreadingError
2520: 22 20 29 0a 20 20 20 20 78 45 72 72 2e 6e 45 72  " ).    xErr.nEr
2530: 72 6f 72 53 74 61 72 74 20 3d 20 6e 53 74 61 72  rorStart = nStar
2540: 74 0a 20 20 20 20 78 45 72 72 2e 6e 45 72 72 6f  t.    xErr.nErro
2550: 72 4c 65 6e 67 74 68 20 3d 20 6e 45 6e 64 20 2d  rLength = nEnd -
2560: 20 6e 53 74 61 72 74 0a 20 20 20 20 78 45 72 72   nStart.    xErr
2570: 2e 6e 45 72 72 6f 72 54 79 70 65 20 3d 20 50 52  .nErrorType = PR
2580: 4f 4f 46 52 45 41 44 49 4e 47 0a 20 20 20 20 78  OOFREADING.    x
2590: 45 72 72 2e 61 52 75 6c 65 49 64 65 6e 74 69 66  Err.aRuleIdentif
25a0: 69 65 72 20 3d 20 73 52 75 6c 65 49 64 0a 20 20  ier = sRuleId.  
25b0: 20 20 23 20 73 75 67 67 65 73 74 69 6f 6e 73 0a    # suggestions.
25c0: 20 20 20 20 69 66 20 73 52 65 70 6c 5b 30 3a 31      if sRepl[0:1
25d0: 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20  ] == "=":.      
25e0: 20 20 73 53 75 67 67 20 3d 20 67 6c 6f 62 61 6c    sSugg = global
25f0: 73 28 29 5b 73 52 65 70 6c 5b 31 3a 5d 5d 28 6c  s()[sRepl[1:]](l
2600: 54 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20 20 69  Token).        i
2610: 66 20 73 53 75 67 67 3a 0a 20 20 20 20 20 20 20  f sSugg:.       
2620: 20 20 20 20 20 69 66 20 62 55 70 70 65 72 63 61       if bUpperca
2630: 73 65 20 61 6e 64 20 6c 54 6f 6b 65 6e 5b 69 46  se and lToken[iF
2640: 69 72 73 74 54 6f 6b 65 6e 5d 5b 22 73 56 61 6c  irstToken]["sVal
2650: 75 65 22 5d 5b 30 3a 31 5d 2e 69 73 75 70 70 65  ue"][0:1].isuppe
2660: 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  r():.           
2670: 20 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65       xErr.aSugge
2680: 73 74 69 6f 6e 73 20 3d 20 74 75 70 6c 65 28 6d  stions = tuple(m
2690: 61 70 28 73 74 72 2e 63 61 70 69 74 61 6c 69 7a  ap(str.capitaliz
26a0: 65 2c 20 73 53 75 67 67 2e 73 70 6c 69 74 28 22  e, sSugg.split("
26b0: 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20 20 20  |"))).          
26c0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
26d0: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 75          xErr.aSu
26e0: 67 67 65 73 74 69 6f 6e 73 20 3d 20 74 75 70 6c  ggestions = tupl
26f0: 65 28 73 53 75 67 67 2e 73 70 6c 69 74 28 22 7c  e(sSugg.split("|
2700: 22 29 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  ")).        else
2710: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 78 45  :.            xE
2720: 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73 20  rr.aSuggestions 
2730: 3d 20 28 29 0a 20 20 20 20 65 6c 69 66 20 73 52  = ().    elif sR
2740: 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20  epl == "_":.    
2750: 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65 73      xErr.aSugges
2760: 74 69 6f 6e 73 20 3d 20 28 29 0a 20 20 20 20 65  tions = ().    e
2770: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 69 66 20  lse:.        if 
2780: 62 55 70 70 65 72 63 61 73 65 20 61 6e 64 20 6c  bUppercase and l
2790: 54 6f 6b 65 6e 5b 69 46 69 72 73 74 54 6f 6b 65  Token[iFirstToke
27a0: 6e 5d 5b 22 73 56 61 6c 75 65 22 5d 5b 30 3a 31  n]["sValue"][0:1
27b0: 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20  ].isupper():.   
27c0: 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53           xErr.aS
27d0: 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74 75 70  uggestions = tup
27e0: 6c 65 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74  le(map(str.capit
27f0: 61 6c 69 7a 65 2c 20 73 52 65 70 6c 2e 73 70 6c  alize, sRepl.spl
2800: 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20  it("|"))).      
2810: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2820: 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65 73      xErr.aSugges
2830: 74 69 6f 6e 73 20 3d 20 74 75 70 6c 65 28 73 52  tions = tuple(sR
2840: 65 70 6c 2e 73 70 6c 69 74 28 22 7c 22 29 29 0a  epl.split("|")).
2850: 20 20 20 20 23 20 4d 65 73 73 61 67 65 0a 20 20      # Message.  
2860: 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20 3d    if sMsg[0:1] =
2870: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 73  = "=":.        s
2880: 4d 65 73 73 61 67 65 20 3d 20 67 6c 6f 62 61 6c  Message = global
2890: 73 28 29 5b 73 4d 73 67 5b 31 3a 5d 5d 28 6c 54  s()[sMsg[1:]](lT
28a0: 6f 6b 65 6e 29 0a 20 20 20 20 65 6c 73 65 3a 0a  oken).    else:.
28b0: 20 20 20 20 20 20 20 20 73 4d 65 73 73 61 67 65          sMessage
28c0: 20 3d 20 73 4d 73 67 0a 20 20 20 20 78 45 72 72   = sMsg.    xErr
28d0: 2e 61 53 68 6f 72 74 43 6f 6d 6d 65 6e 74 20 3d  .aShortComment =
28e0: 20 73 4d 65 73 73 61 67 65 20 20 20 23 20 73 4d   sMessage   # sM
28f0: 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22 7c 22  essage.split("|"
2900: 29 5b 30 5d 20 20 20 20 20 23 20 69 6e 20 63 6f  )[0]     # in co
2910: 6e 74 65 78 74 20 6d 65 6e 75 0a 20 20 20 20 78  ntext menu.    x
2920: 45 72 72 2e 61 46 75 6c 6c 43 6f 6d 6d 65 6e 74  Err.aFullComment
2930: 20 3d 20 73 4d 65 73 73 61 67 65 20 20 20 23 20   = sMessage   # 
2940: 73 4d 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22  sMessage.split("
2950: 7c 22 29 5b 2d 31 5d 20 20 20 20 23 20 69 6e 20  |")[-1]    # in 
2960: 64 69 61 6c 6f 67 0a 20 20 20 20 69 66 20 62 53  dialog.    if bS
2970: 68 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20 20 20  howRuleId:.     
2980: 20 20 20 78 45 72 72 2e 61 53 68 6f 72 74 43 6f     xErr.aShortCo
2990: 6d 6d 65 6e 74 20 2b 3d 20 22 20 20 22 20 2b 20  mment += "  " + 
29a0: 73 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20  sLineId + " # " 
29b0: 2b 20 73 52 75 6c 65 49 64 0a 20 20 20 20 23 20  + sRuleId.    # 
29c0: 55 52 4c 0a 20 20 20 20 69 66 20 73 55 52 4c 3a  URL.    if sURL:
29d0: 0a 20 20 20 20 20 20 20 20 70 20 3d 20 50 72 6f  .        p = Pro
29e0: 70 65 72 74 79 56 61 6c 75 65 28 29 0a 20 20 20  pertyValue().   
29f0: 20 20 20 20 20 70 2e 4e 61 6d 65 20 3d 20 22 46       p.Name = "F
2a00: 75 6c 6c 43 6f 6d 6d 65 6e 74 55 52 4c 22 0a 20  ullCommentURL". 
2a10: 20 20 20 20 20 20 20 70 2e 56 61 6c 75 65 20 3d         p.Value =
2a20: 20 73 55 52 4c 0a 20 20 20 20 20 20 20 20 78 45   sURL.        xE
2a30: 72 72 2e 61 50 72 6f 70 65 72 74 69 65 73 20 3d  rr.aProperties =
2a40: 20 28 70 2c 29 0a 20 20 20 20 65 6c 73 65 3a 0a   (p,).    else:.
2a50: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 50 72          xErr.aPr
2a60: 6f 70 65 72 74 69 65 73 20 3d 20 28 29 0a 20 20  operties = ().  
2a70: 20 20 72 65 74 75 72 6e 20 78 45 72 72 0a 0a 20    return xErr.. 
2a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ab0: 20 20 20 20 20 20 20 20 0a 64 65 66 20 5f 63 72          .def _cr
2ac0: 65 61 74 65 54 6f 6b 65 6e 44 69 63 74 45 72 72  eateTokenDictErr
2ad0: 6f 72 20 28 6c 54 6f 6b 65 6e 2c 20 73 53 65 6e  or (lToken, sSen
2ae0: 74 65 6e 63 65 2c 20 73 53 65 6e 74 65 6e 63 65  tence, sSentence
2af0: 30 2c 20 73 52 65 70 6c 2c 20 69 46 69 72 73 74  0, sRepl, iFirst
2b00: 54 6f 6b 65 6e 2c 20 6e 53 74 61 72 74 2c 20 6e  Token, nStart, n
2b10: 45 6e 64 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52  End, sLineId, sR
2b20: 75 6c 65 49 64 2c 20 62 55 70 70 65 72 63 61 73  uleId, bUppercas
2b30: 65 2c 20 73 4d 73 67 2c 20 73 55 52 4c 2c 20 62  e, sMsg, sURL, b
2b40: 53 68 6f 77 52 75 6c 65 49 64 2c 20 73 4f 70 74  ShowRuleId, sOpt
2b50: 69 6f 6e 2c 20 62 43 6f 6e 74 65 78 74 29 3a 0a  ion, bContext):.
2b60: 20 20 20 20 22 65 72 72 6f 72 20 61 73 20 61 20      "error as a 
2b70: 64 69 63 74 69 6f 6e 61 72 79 22 0a 20 20 20 20  dictionary".    
2b80: 64 45 72 72 20 3d 20 7b 7d 0a 20 20 20 20 64 45  dErr = {}.    dE
2b90: 72 72 5b 22 6e 53 74 61 72 74 22 5d 20 3d 20 6e  rr["nStart"] = n
2ba0: 53 74 61 72 74 0a 20 20 20 20 64 45 72 72 5b 22  Start.    dErr["
2bb0: 6e 45 6e 64 22 5d 20 3d 20 6e 45 6e 64 0a 20 20  nEnd"] = nEnd.  
2bc0: 20 20 64 45 72 72 5b 22 73 4c 69 6e 65 49 64 22    dErr["sLineId"
2bd0: 5d 20 3d 20 73 4c 69 6e 65 49 64 0a 20 20 20 20  ] = sLineId.    
2be0: 64 45 72 72 5b 22 73 52 75 6c 65 49 64 22 5d 20  dErr["sRuleId"] 
2bf0: 3d 20 73 52 75 6c 65 49 64 0a 20 20 20 20 64 45  = sRuleId.    dE
2c00: 72 72 5b 22 73 54 79 70 65 22 5d 20 3d 20 73 4f  rr["sType"] = sO
2c10: 70 74 69 6f 6e 20 20 69 66 20 73 4f 70 74 69 6f  ption  if sOptio
2c20: 6e 20 20 65 6c 73 65 20 22 6e 6f 74 79 70 65 22  n  else "notype"
2c30: 0a 20 20 20 20 23 20 73 75 67 67 65 73 74 69 6f  .    # suggestio
2c40: 6e 73 0a 20 20 20 20 69 66 20 73 52 65 70 6c 5b  ns.    if sRepl[
2c50: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
2c60: 20 20 20 20 20 73 75 67 67 20 3d 20 67 6c 6f 62       sugg = glob
2c70: 61 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a 5d 5d  als()[sRepl[1:]]
2c80: 28 6c 54 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20  (lToken).       
2c90: 20 69 66 20 73 75 67 67 3a 0a 20 20 20 20 20 20   if sugg:.      
2ca0: 20 20 20 20 20 20 69 66 20 62 55 70 70 65 72 63        if bUpperc
2cb0: 61 73 65 20 61 6e 64 20 6c 54 6f 6b 65 6e 5b 69  ase and lToken[i
2cc0: 46 69 72 73 74 54 6f 6b 65 6e 5d 5b 22 73 56 61  FirstToken]["sVa
2cd0: 6c 75 65 22 5d 5b 30 3a 31 5d 2e 69 73 75 70 70  lue"][0:1].isupp
2ce0: 65 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20  er():.          
2cf0: 20 20 20 20 20 20 64 45 72 72 5b 22 61 53 75 67        dErr["aSug
2d00: 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20 6c 69 73  gestions"] = lis
2d10: 74 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61  t(map(str.capita
2d20: 6c 69 7a 65 2c 20 73 75 67 67 2e 73 70 6c 69 74  lize, sugg.split
2d30: 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20  ("|"))).        
2d40: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2d50: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
2d60: 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d  aSuggestions"] =
2d70: 20 73 75 67 67 2e 73 70 6c 69 74 28 22 7c 22 29   sugg.split("|")
2d80: 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20  .        else:. 
2d90: 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b             dErr[
2da0: 22 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20  "aSuggestions"] 
2db0: 3d 20 5b 5d 0a 20 20 20 20 65 6c 69 66 20 73 52  = [].    elif sR
2dc0: 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20  epl == "_":.    
2dd0: 20 20 20 20 64 45 72 72 5b 22 61 53 75 67 67 65      dErr["aSugge
2de0: 73 74 69 6f 6e 73 22 5d 20 3d 20 5b 5d 0a 20 20  stions"] = [].  
2df0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2e00: 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e  if bUppercase an
2e10: 64 20 6c 54 6f 6b 65 6e 5b 69 46 69 72 73 74 54  d lToken[iFirstT
2e20: 6f 6b 65 6e 5d 5b 22 73 56 61 6c 75 65 22 5d 5b  oken]["sValue"][
2e30: 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a  0:1].isupper():.
2e40: 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72              dErr
2e50: 5b 22 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d  ["aSuggestions"]
2e60: 20 3d 20 6c 69 73 74 28 6d 61 70 28 73 74 72 2e   = list(map(str.
2e70: 63 61 70 69 74 61 6c 69 7a 65 2c 20 73 52 65 70  capitalize, sRep
2e80: 6c 2e 73 70 6c 69 74 28 22 7c 22 29 29 29 0a 20  l.split("|"))). 
2e90: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2ea0: 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61           dErr["a
2eb0: 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20  Suggestions"] = 
2ec0: 73 52 65 70 6c 2e 73 70 6c 69 74 28 22 7c 22 29  sRepl.split("|")
2ed0: 0a 20 20 20 20 23 20 4d 65 73 73 61 67 65 0a 20  .    # Message. 
2ee0: 20 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20     if sMsg[0:1] 
2ef0: 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20  == "=":.        
2f00: 73 4d 65 73 73 61 67 65 20 3d 20 67 6c 6f 62 61  sMessage = globa
2f10: 6c 73 28 29 5b 73 4d 73 67 5b 31 3a 5d 5d 28 6c  ls()[sMsg[1:]](l
2f20: 54 6f 6b 65 6e 29 0a 20 20 20 20 65 6c 73 65 3a  Token).    else:
2f30: 0a 20 20 20 20 20 20 20 20 73 4d 65 73 73 61 67  .        sMessag
2f40: 65 20 3d 20 73 4d 73 67 0a 20 20 20 20 64 45 72  e = sMsg.    dEr
2f50: 72 5b 22 73 4d 65 73 73 61 67 65 22 5d 20 3d 20  r["sMessage"] = 
2f60: 73 4d 65 73 73 61 67 65 0a 20 20 20 20 69 66 20  sMessage.    if 
2f70: 62 53 68 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20  bShowRuleId:.   
2f80: 20 20 20 20 20 64 45 72 72 5b 22 73 4d 65 73 73       dErr["sMess
2f90: 61 67 65 22 5d 20 2b 3d 20 22 20 20 22 20 2b 20  age"] += "  " + 
2fa0: 73 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20  sLineId + " # " 
2fb0: 2b 20 73 52 75 6c 65 49 64 0a 20 20 20 20 23 20  + sRuleId.    # 
2fc0: 55 52 4c 0a 20 20 20 20 64 45 72 72 5b 22 55 52  URL.    dErr["UR
2fd0: 4c 22 5d 20 3d 20 73 55 52 4c 20 20 69 66 20 73  L"] = sURL  if s
2fe0: 55 52 4c 20 20 65 6c 73 65 20 22 22 0a 20 20 20  URL  else "".   
2ff0: 20 23 20 43 6f 6e 74 65 78 74 0a 20 20 20 20 69   # Context.    i
3000: 66 20 62 43 6f 6e 74 65 78 74 3a 0a 20 20 20 20  f bContext:.    
3010: 20 20 20 20 64 45 72 72 5b 27 73 55 6e 64 65 72      dErr['sUnder
3020: 6c 69 6e 65 64 27 5d 20 3d 20 73 53 65 6e 74 65  lined'] = sSente
3030: 6e 63 65 30 5b 64 45 72 72 5b 22 6e 53 74 61 72  nce0[dErr["nStar
3040: 74 22 5d 3a 64 45 72 72 5b 22 6e 45 6e 64 22 5d  t"]:dErr["nEnd"]
3050: 5d 0a 20 20 20 20 20 20 20 20 64 45 72 72 5b 27  ].        dErr['
3060: 73 42 65 66 6f 72 65 27 5d 20 3d 20 73 53 65 6e  sBefore'] = sSen
3070: 74 65 6e 63 65 30 5b 6d 61 78 28 30 2c 64 45 72  tence0[max(0,dEr
3080: 72 5b 22 6e 53 74 61 72 74 22 5d 2d 38 30 29 3a  r["nStart"]-80):
3090: 64 45 72 72 5b 22 6e 53 74 61 72 74 22 5d 5d 0a  dErr["nStart"]].
30a0: 20 20 20 20 20 20 20 20 64 45 72 72 5b 27 73 41          dErr['sA
30b0: 66 74 65 72 27 5d 20 3d 20 73 53 65 6e 74 65 6e  fter'] = sSenten
30c0: 63 65 30 5b 64 45 72 72 5b 22 6e 45 6e 64 22 5d  ce0[dErr["nEnd"]
30d0: 3a 64 45 72 72 5b 22 6e 45 6e 64 22 5d 2b 38 30  :dErr["nEnd"]+80
30e0: 5d 0a 20 20 20 20 72 65 74 75 72 6e 20 64 45 72  ].    return dEr
30f0: 72 0a 0a 0a 64 65 66 20 5f 72 65 77 72 69 74 65  r...def _rewrite
3100: 20 28 73 53 65 6e 74 65 6e 63 65 2c 20 73 52 65   (sSentence, sRe
3110: 70 6c 2c 20 69 47 72 6f 75 70 2c 20 6d 2c 20 62  pl, iGroup, m, b
3120: 55 70 70 65 72 63 61 73 65 29 3a 0a 20 20 20 20  Uppercase):.    
3130: 22 74 65 78 74 20 70 72 6f 63 65 73 73 6f 72 3a  "text processor:
3140: 20 77 72 69 74 65 20 3c 73 52 65 70 6c 3e 20 69   write <sRepl> i
3150: 6e 20 3c 73 53 65 6e 74 65 6e 63 65 3e 20 61 74  n <sSentence> at
3160: 20 3c 69 47 72 6f 75 70 3e 20 70 6f 73 69 74 69   <iGroup> positi
3170: 6f 6e 22 0a 20 20 20 20 6e 4c 65 6e 20 3d 20 6d  on".    nLen = m
3180: 2e 65 6e 64 28 69 47 72 6f 75 70 29 20 2d 20 6d  .end(iGroup) - m
3190: 2e 73 74 61 72 74 28 69 47 72 6f 75 70 29 0a 20  .start(iGroup). 
31a0: 20 20 20 69 66 20 73 52 65 70 6c 20 3d 3d 20 22     if sRepl == "
31b0: 2a 22 3a 0a 20 20 20 20 20 20 20 20 73 4e 65 77  *":.        sNew
31c0: 20 3d 20 22 20 22 20 2a 20 6e 4c 65 6e 0a 20 20   = " " * nLen.  
31d0: 20 20 65 6c 69 66 20 73 52 65 70 6c 20 3d 3d 20    elif sRepl == 
31e0: 22 5f 22 3a 0a 20 20 20 20 20 20 20 20 73 4e 65  "_":.        sNe
31f0: 77 20 3d 20 73 52 65 70 6c 20 2b 20 22 20 22 20  w = sRepl + " " 
3200: 2a 20 28 6e 4c 65 6e 2d 31 29 0a 20 20 20 20 65  * (nLen-1).    e
3210: 6c 69 66 20 73 52 65 70 6c 5b 30 3a 31 5d 20 3d  lif sRepl[0:1] =
3220: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 73  = "=":.        s
3230: 4e 65 77 20 3d 20 67 6c 6f 62 61 6c 73 28 29 5b  New = globals()[
3240: 73 52 65 70 6c 5b 31 3a 5d 5d 28 73 53 65 6e 74  sRepl[1:]](sSent
3250: 65 6e 63 65 2c 20 6d 29 0a 20 20 20 20 20 20 20  ence, m).       
3260: 20 73 4e 65 77 20 3d 20 73 4e 65 77 20 2b 20 22   sNew = sNew + "
3270: 20 22 20 2a 20 28 6e 4c 65 6e 2d 6c 65 6e 28 73   " * (nLen-len(s
3280: 4e 65 77 29 29 0a 20 20 20 20 20 20 20 20 69 66  New)).        if
3290: 20 62 55 70 70 65 72 63 61 73 65 20 61 6e 64 20   bUppercase and 
32a0: 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75 70 29 5b  m.group(iGroup)[
32b0: 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a  0:1].isupper():.
32c0: 20 20 20 20 20 20 20 20 20 20 20 20 73 4e 65 77              sNew
32d0: 20 3d 20 73 4e 65 77 2e 63 61 70 69 74 61 6c 69   = sNew.capitali
32e0: 7a 65 28 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20  ze().    else:. 
32f0: 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20 6d 2e         sNew = m.
3300: 65 78 70 61 6e 64 28 73 52 65 70 6c 29 0a 20 20  expand(sRepl).  
3310: 20 20 20 20 20 20 73 4e 65 77 20 3d 20 73 4e 65        sNew = sNe
3320: 77 20 2b 20 22 20 22 20 2a 20 28 6e 4c 65 6e 2d  w + " " * (nLen-
3330: 6c 65 6e 28 73 4e 65 77 29 29 0a 20 20 20 20 72  len(sNew)).    r
3340: 65 74 75 72 6e 20 73 53 65 6e 74 65 6e 63 65 5b  eturn sSentence[
3350: 30 3a 6d 2e 73 74 61 72 74 28 69 47 72 6f 75 70  0:m.start(iGroup
3360: 29 5d 20 2b 20 73 4e 65 77 20 2b 20 73 53 65 6e  )] + sNew + sSen
3370: 74 65 6e 63 65 5b 6d 2e 65 6e 64 28 69 47 72 6f  tence[m.end(iGro
3380: 75 70 29 3a 5d 0a 0a 0a 64 65 66 20 69 67 6e 6f  up):]...def igno
3390: 72 65 52 75 6c 65 20 28 73 52 75 6c 65 49 64 29  reRule (sRuleId)
33a0: 3a 0a 20 20 20 20 5f 61 49 67 6e 6f 72 65 64 52  :.    _aIgnoredR
33b0: 75 6c 65 73 2e 61 64 64 28 73 52 75 6c 65 49 64  ules.add(sRuleId
33c0: 29 0a 0a 0a 64 65 66 20 72 65 73 65 74 49 67 6e  )...def resetIgn
33d0: 6f 72 65 52 75 6c 65 73 20 28 29 3a 0a 20 20 20  oreRules ():.   
33e0: 20 5f 61 49 67 6e 6f 72 65 64 52 75 6c 65 73 2e   _aIgnoredRules.
33f0: 63 6c 65 61 72 28 29 0a 0a 0a 64 65 66 20 72 65  clear()...def re
3400: 61 63 74 69 76 61 74 65 52 75 6c 65 20 28 73 52  activateRule (sR
3410: 75 6c 65 49 64 29 3a 0a 20 20 20 20 5f 61 49 67  uleId):.    _aIg
3420: 6e 6f 72 65 64 52 75 6c 65 73 2e 64 69 73 63 61  noredRules.disca
3430: 72 64 28 73 52 75 6c 65 49 64 29 0a 0a 0a 64 65  rd(sRuleId)...de
3440: 66 20 6c 69 73 74 52 75 6c 65 73 20 28 73 46 69  f listRules (sFi
3450: 6c 74 65 72 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20  lter=None):.    
3460: 22 67 65 6e 65 72 61 74 6f 72 3a 20 72 65 74 75  "generator: retu
3470: 72 6e 73 20 74 79 70 6c 65 20 28 73 4f 70 74 69  rns typle (sOpti
3480: 6f 6e 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75  on, sLineId, sRu
3490: 6c 65 49 64 29 22 0a 20 20 20 20 69 66 20 73 46  leId)".    if sF
34a0: 69 6c 74 65 72 3a 0a 20 20 20 20 20 20 20 20 74  ilter:.        t
34b0: 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ry:.            
34c0: 7a 46 69 6c 74 65 72 20 3d 20 72 65 2e 63 6f 6d  zFilter = re.com
34d0: 70 69 6c 65 28 73 46 69 6c 74 65 72 29 0a 20 20  pile(sFilter).  
34e0: 20 20 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20        except:.  
34f0: 20 20 20 20 20 20 20 20 20 20 65 63 68 6f 28 22            echo("
3500: 23 20 45 72 72 6f 72 2e 20 4c 69 73 74 20 72 75  # Error. List ru
3510: 6c 65 73 3a 20 77 72 6f 6e 67 20 72 65 67 65 78  les: wrong regex
3520: 2e 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  .").            
3530: 73 46 69 6c 74 65 72 20 3d 20 4e 6f 6e 65 0a 20  sFilter = None. 
3540: 20 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20     for sOption, 
3550: 6c 52 75 6c 65 47 72 6f 75 70 20 69 6e 20 63 68  lRuleGroup in ch
3560: 61 69 6e 28 5f 67 65 74 52 75 6c 65 73 28 54 72  ain(_getRules(Tr
3570: 75 65 29 2c 20 5f 67 65 74 52 75 6c 65 73 28 46  ue), _getRules(F
3580: 61 6c 73 65 29 29 3a 0a 20 20 20 20 20 20 20 20  alse)):.        
3590: 66 6f 72 20 5f 2c 20 5f 2c 20 73 4c 69 6e 65 49  for _, _, sLineI
35a0: 64 2c 20 73 52 75 6c 65 49 64 2c 20 5f 2c 20 5f  d, sRuleId, _, _
35b0: 20 69 6e 20 6c 52 75 6c 65 47 72 6f 75 70 3a 0a   in lRuleGroup:.
35c0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e              if n
35d0: 6f 74 20 73 46 69 6c 74 65 72 20 6f 72 20 7a 46  ot sFilter or zF
35e0: 69 6c 74 65 72 2e 73 65 61 72 63 68 28 73 52 75  ilter.search(sRu
35f0: 6c 65 49 64 29 3a 0a 20 20 20 20 20 20 20 20 20  leId):.         
3600: 20 20 20 20 20 20 20 79 69 65 6c 64 20 28 73 4f         yield (sO
3610: 70 74 69 6f 6e 2c 20 73 4c 69 6e 65 49 64 2c 20  ption, sLineId, 
3620: 73 52 75 6c 65 49 64 29 0a 0a 0a 64 65 66 20 64  sRuleId)...def d
3630: 69 73 70 6c 61 79 52 75 6c 65 73 20 28 73 46 69  isplayRules (sFi
3640: 6c 74 65 72 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20  lter=None):.    
3650: 65 63 68 6f 28 22 4c 69 73 74 20 6f 66 20 72 75  echo("List of ru
3660: 6c 65 73 2e 20 46 69 6c 74 65 72 3a 20 3c 3c 20  les. Filter: << 
3670: 22 20 2b 20 73 74 72 28 73 46 69 6c 74 65 72 29  " + str(sFilter)
3680: 20 2b 20 22 20 3e 3e 22 29 0a 20 20 20 20 66 6f   + " >>").    fo
3690: 72 20 73 4f 70 74 69 6f 6e 2c 20 73 4c 69 6e 65  r sOption, sLine
36a0: 49 64 2c 20 73 52 75 6c 65 49 64 20 69 6e 20 6c  Id, sRuleId in l
36b0: 69 73 74 52 75 6c 65 73 28 73 46 69 6c 74 65 72  istRules(sFilter
36c0: 29 3a 0a 20 20 20 20 20 20 20 20 65 63 68 6f 28  ):.        echo(
36d0: 22 7b 3a 3c 31 30 7d 20 7b 3a 3c 31 30 7d 20 7b  "{:<10} {:<10} {
36e0: 7d 22 2e 66 6f 72 6d 61 74 28 73 4f 70 74 69 6f  }".format(sOptio
36f0: 6e 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c  n, sLineId, sRul
3700: 65 49 64 29 29 0a 0a 0a 23 23 23 23 20 69 6e 69  eId))...#### ini
3710: 74 0a 0a 74 72 79 3a 0a 20 20 20 20 23 20 4c 69  t..try:.    # Li
3720: 62 72 65 4f 66 66 69 63 65 20 2f 20 4f 70 65 6e  breOffice / Open
3730: 4f 66 66 69 63 65 0a 20 20 20 20 66 72 6f 6d 20  Office.    from 
3740: 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 6c 69 6e  com.sun.star.lin
3750: 67 75 69 73 74 69 63 32 20 69 6d 70 6f 72 74 20  guistic2 import 
3760: 53 69 6e 67 6c 65 50 72 6f 6f 66 72 65 61 64 69  SingleProofreadi
3770: 6e 67 45 72 72 6f 72 0a 20 20 20 20 66 72 6f 6d  ngError.    from
3780: 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 74 65   com.sun.star.te
3790: 78 74 2e 54 65 78 74 4d 61 72 6b 75 70 54 79 70  xt.TextMarkupTyp
37a0: 65 20 69 6d 70 6f 72 74 20 50 52 4f 4f 46 52 45  e import PROOFRE
37b0: 41 44 49 4e 47 0a 20 20 20 20 66 72 6f 6d 20 63  ADING.    from c
37c0: 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 62 65 61 6e  om.sun.star.bean
37d0: 73 20 69 6d 70 6f 72 74 20 50 72 6f 70 65 72 74  s import Propert
37e0: 79 56 61 6c 75 65 0a 20 20 20 20 23 69 6d 70 6f  yValue.    #impo
37f0: 72 74 20 6c 69 67 68 74 70 72 6f 6f 66 5f 68 61  rt lightproof_ha
3800: 6e 64 6c 65 72 5f 24 7b 69 6d 70 6c 6e 61 6d 65  ndler_${implname
3810: 7d 20 61 73 20 6f 70 74 0a 20 20 20 20 5f 63 72  } as opt.    _cr
3820: 65 61 74 65 52 65 67 65 78 45 72 72 6f 72 20 3d  eateRegexError =
3830: 20 5f 63 72 65 61 74 65 52 65 67 65 78 57 72 69   _createRegexWri
3840: 74 65 72 45 72 72 6f 72 0a 20 20 20 20 5f 63 72  terError.    _cr
3850: 65 61 74 65 54 6f 6b 65 6e 45 72 72 6f 72 20 3d  eateTokenError =
3860: 20 5f 63 72 65 61 74 65 54 6f 6b 65 6e 57 72 69   _createTokenWri
3870: 74 65 72 45 72 72 6f 72 0a 65 78 63 65 70 74 20  terError.except 
3880: 49 6d 70 6f 72 74 45 72 72 6f 72 3a 0a 20 20 20  ImportError:.   
3890: 20 5f 63 72 65 61 74 65 52 65 67 65 78 45 72 72   _createRegexErr
38a0: 6f 72 20 3d 20 5f 63 72 65 61 74 65 52 65 67 65  or = _createRege
38b0: 78 44 69 63 74 45 72 72 6f 72 0a 20 20 20 20 5f  xDictError.    _
38c0: 63 72 65 61 74 65 54 6f 6b 65 6e 45 72 72 6f 72  createTokenError
38d0: 20 3d 20 5f 63 72 65 61 74 65 54 6f 6b 65 6e 44   = _createTokenD
38e0: 69 63 74 45 72 72 6f 72 0a 0a 0a 64 65 66 20 6c  ictError...def l
38f0: 6f 61 64 20 28 73 43 6f 6e 74 65 78 74 3d 22 50  oad (sContext="P
3900: 79 74 68 6f 6e 22 29 3a 0a 20 20 20 20 67 6c 6f  ython"):.    glo
3910: 62 61 6c 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b  bal _oSpellCheck
3920: 65 72 0a 20 20 20 20 67 6c 6f 62 61 6c 20 5f 73  er.    global _s
3930: 41 70 70 43 6f 6e 74 65 78 74 0a 20 20 20 20 67  AppContext.    g
3940: 6c 6f 62 61 6c 20 5f 64 4f 70 74 69 6f 6e 73 0a  lobal _dOptions.
3950: 20 20 20 20 67 6c 6f 62 61 6c 20 5f 6f 54 6f 6b      global _oTok
3960: 65 6e 69 7a 65 72 0a 20 20 20 20 74 72 79 3a 0a  enizer.    try:.
3970: 20 20 20 20 20 20 20 20 5f 6f 53 70 65 6c 6c 43          _oSpellC
3980: 68 65 63 6b 65 72 20 3d 20 53 70 65 6c 6c 43 68  hecker = SpellCh
3990: 65 63 6b 65 72 28 22 24 7b 6c 61 6e 67 7d 22 2c  ecker("${lang}",
39a0: 20 22 24 7b 64 69 63 5f 6d 61 69 6e 5f 66 69 6c   "${dic_main_fil
39b0: 65 6e 61 6d 65 5f 70 79 7d 22 2c 20 22 24 7b 64  ename_py}", "${d
39c0: 69 63 5f 65 78 74 65 6e 64 65 64 5f 66 69 6c 65  ic_extended_file
39d0: 6e 61 6d 65 5f 70 79 7d 22 2c 20 22 24 7b 64 69  name_py}", "${di
39e0: 63 5f 63 6f 6d 6d 75 6e 69 74 79 5f 66 69 6c 65  c_community_file
39f0: 6e 61 6d 65 5f 70 79 7d 22 2c 20 22 24 7b 64 69  name_py}", "${di
3a00: 63 5f 70 65 72 73 6f 6e 61 6c 5f 66 69 6c 65 6e  c_personal_filen
3a10: 61 6d 65 5f 70 79 7d 22 29 0a 20 20 20 20 20 20  ame_py}").      
3a20: 20 20 5f 73 41 70 70 43 6f 6e 74 65 78 74 20 3d    _sAppContext =
3a30: 20 73 43 6f 6e 74 65 78 74 0a 20 20 20 20 20 20   sContext.      
3a40: 20 20 5f 64 4f 70 74 69 6f 6e 73 20 3d 20 64 69    _dOptions = di
3a50: 63 74 28 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  ct(gc_options.ge
3a60: 74 4f 70 74 69 6f 6e 73 28 73 43 6f 6e 74 65 78  tOptions(sContex
3a70: 74 29 29 20 20 20 23 20 64 75 70 6c 69 63 61 74  t))   # duplicat
3a80: 69 6f 6e 20 6e 65 63 65 73 73 61 72 79 2c 20 74  ion necessary, t
3a90: 6f 20 62 65 20 61 62 6c 65 20 74 6f 20 72 65 73  o be able to res
3aa0: 65 74 20 74 6f 20 64 65 66 61 75 6c 74 0a 20 20  et to default.  
3ab0: 20 20 20 20 20 20 5f 6f 54 6f 6b 65 6e 69 7a 65        _oTokenize
3ac0: 72 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b  r = _oSpellCheck
3ad0: 65 72 2e 67 65 74 54 6f 6b 65 6e 69 7a 65 72 28  er.getTokenizer(
3ae0: 29 0a 20 20 20 20 20 20 20 20 5f 6f 53 70 65 6c  ).        _oSpel
3af0: 6c 43 68 65 63 6b 65 72 2e 61 63 74 69 76 61 74  lChecker.activat
3b00: 65 53 74 6f 72 61 67 65 28 29 0a 20 20 20 20 65  eStorage().    e
3b10: 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 74  xcept:.        t
3b20: 72 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65  raceback.print_e
3b30: 78 63 28 29 0a 0a 0a 64 65 66 20 73 65 74 4f 70  xc()...def setOp
3b40: 74 69 6f 6e 20 28 73 4f 70 74 2c 20 62 56 61 6c  tion (sOpt, bVal
3b50: 29 3a 0a 20 20 20 20 69 66 20 73 4f 70 74 20 69  ):.    if sOpt i
3b60: 6e 20 5f 64 4f 70 74 69 6f 6e 73 3a 0a 20 20 20  n _dOptions:.   
3b70: 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e 73 5b 73       _dOptions[s
3b80: 4f 70 74 5d 20 3d 20 62 56 61 6c 0a 0a 0a 64 65  Opt] = bVal...de
3b90: 66 20 73 65 74 4f 70 74 69 6f 6e 73 20 28 64 4f  f setOptions (dO
3ba0: 70 74 29 3a 0a 20 20 20 20 66 6f 72 20 73 4b 65  pt):.    for sKe
3bb0: 79 2c 20 62 56 61 6c 20 69 6e 20 64 4f 70 74 2e  y, bVal in dOpt.
3bc0: 69 74 65 6d 73 28 29 3a 0a 20 20 20 20 20 20 20  items():.       
3bd0: 20 69 66 20 73 4b 65 79 20 69 6e 20 5f 64 4f 70   if sKey in _dOp
3be0: 74 69 6f 6e 73 3a 0a 20 20 20 20 20 20 20 20 20  tions:.         
3bf0: 20 20 20 5f 64 4f 70 74 69 6f 6e 73 5b 73 4b 65     _dOptions[sKe
3c00: 79 5d 20 3d 20 62 56 61 6c 0a 0a 0a 64 65 66 20  y] = bVal...def 
3c10: 67 65 74 4f 70 74 69 6f 6e 73 20 28 29 3a 0a 20  getOptions ():. 
3c20: 20 20 20 72 65 74 75 72 6e 20 5f 64 4f 70 74 69     return _dOpti
3c30: 6f 6e 73 0a 0a 0a 64 65 66 20 67 65 74 44 65 66  ons...def getDef
3c40: 61 75 6c 74 4f 70 74 69 6f 6e 73 20 28 29 3a 0a  aultOptions ():.
3c50: 20 20 20 20 72 65 74 75 72 6e 20 64 69 63 74 28      return dict(
3c60: 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65 74 4f 70  gc_options.getOp
3c70: 74 69 6f 6e 73 28 5f 73 41 70 70 43 6f 6e 74 65  tions(_sAppConte
3c80: 78 74 29 29 0a 0a 0a 64 65 66 20 67 65 74 4f 70  xt))...def getOp
3c90: 74 69 6f 6e 73 4c 61 62 65 6c 73 20 28 73 4c 61  tionsLabels (sLa
3ca0: 6e 67 29 3a 0a 20 20 20 20 72 65 74 75 72 6e 20  ng):.    return 
3cb0: 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65 74 55 49  gc_options.getUI
3cc0: 28 73 4c 61 6e 67 29 0a 0a 0a 64 65 66 20 64 69  (sLang)...def di
3cd0: 73 70 6c 61 79 4f 70 74 69 6f 6e 73 20 28 73 4c  splayOptions (sL
3ce0: 61 6e 67 29 3a 0a 20 20 20 20 65 63 68 6f 28 22  ang):.    echo("
3cf0: 4c 69 73 74 20 6f 66 20 6f 70 74 69 6f 6e 73 22  List of options"
3d00: 29 0a 20 20 20 20 65 63 68 6f 28 22 5c 6e 22 2e  ).    echo("\n".
3d10: 6a 6f 69 6e 28 20 5b 20 6b 2b 22 3a 5c 74 22 2b  join( [ k+":\t"+
3d20: 73 74 72 28 76 29 2b 22 5c 74 22 2b 67 63 5f 6f  str(v)+"\t"+gc_o
3d30: 70 74 69 6f 6e 73 2e 67 65 74 55 49 28 73 4c 61  ptions.getUI(sLa
3d40: 6e 67 29 2e 67 65 74 28 6b 2c 20 28 22 3f 22 2c  ng).get(k, ("?",
3d50: 20 22 22 29 29 5b 30 5d 20 20 66 6f 72 20 6b 2c   ""))[0]  for k,
3d60: 20 76 20 20 69 6e 20 73 6f 72 74 65 64 28 5f 64   v  in sorted(_d
3d70: 4f 70 74 69 6f 6e 73 2e 69 74 65 6d 73 28 29 29  Options.items())
3d80: 20 5d 20 29 29 0a 20 20 20 20 65 63 68 6f 28 22   ] )).    echo("
3d90: 22 29 0a 0a 0a 64 65 66 20 72 65 73 65 74 4f 70  ")...def resetOp
3da0: 74 69 6f 6e 73 20 28 29 3a 0a 20 20 20 20 67 6c  tions ():.    gl
3db0: 6f 62 61 6c 20 5f 64 4f 70 74 69 6f 6e 73 0a 20  obal _dOptions. 
3dc0: 20 20 20 5f 64 4f 70 74 69 6f 6e 73 20 3d 20 64     _dOptions = d
3dd0: 69 63 74 28 67 63 5f 6f 70 74 69 6f 6e 73 2e 67  ict(gc_options.g
3de0: 65 74 4f 70 74 69 6f 6e 73 28 5f 73 41 70 70 43  etOptions(_sAppC
3df0: 6f 6e 74 65 78 74 29 29 0a 0a 0a 64 65 66 20 67  ontext))...def g
3e00: 65 74 53 70 65 6c 6c 43 68 65 63 6b 65 72 20 28  etSpellChecker (
3e10: 29 3a 0a 20 20 20 20 72 65 74 75 72 6e 20 5f 6f  ):.    return _o
3e20: 53 70 65 6c 6c 43 68 65 63 6b 65 72 0a 0a 0a 64  SpellChecker...d
3e30: 65 66 20 5f 67 65 74 52 75 6c 65 73 20 28 62 50  ef _getRules (bP
3e40: 61 72 61 67 72 61 70 68 29 3a 0a 20 20 20 20 74  aragraph):.    t
3e50: 72 79 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e  ry:.        if n
3e60: 6f 74 20 62 50 61 72 61 67 72 61 70 68 3a 0a 20  ot bParagraph:. 
3e70: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
3e80: 6e 20 5f 72 75 6c 65 73 2e 6c 53 65 6e 74 65 6e  n _rules.lSenten
3e90: 63 65 52 75 6c 65 73 0a 20 20 20 20 20 20 20 20  ceRules.        
3ea0: 72 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 50  return _rules.lP
3eb0: 61 72 61 67 72 61 70 68 52 75 6c 65 73 0a 20 20  aragraphRules.  
3ec0: 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20    except:.      
3ed0: 20 20 5f 6c 6f 61 64 52 75 6c 65 73 28 29 0a 20    _loadRules(). 
3ee0: 20 20 20 69 66 20 6e 6f 74 20 62 50 61 72 61 67     if not bParag
3ef0: 72 61 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65  raph:.        re
3f00: 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 53 65 6e  turn _rules.lSen
3f10: 74 65 6e 63 65 52 75 6c 65 73 0a 20 20 20 20 72  tenceRules.    r
3f20: 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 50 61  eturn _rules.lPa
3f30: 72 61 67 72 61 70 68 52 75 6c 65 73 0a 0a 0a 64  ragraphRules...d
3f40: 65 66 20 5f 6c 6f 61 64 52 75 6c 65 73 20 28 29  ef _loadRules ()
3f50: 3a 0a 20 20 20 20 66 72 6f 6d 20 2e 20 69 6d 70  :.    from . imp
3f60: 6f 72 74 20 67 63 5f 72 75 6c 65 73 0a 20 20 20  ort gc_rules.   
3f70: 20 67 6c 6f 62 61 6c 20 5f 72 75 6c 65 73 0a 20   global _rules. 
3f80: 20 20 20 5f 72 75 6c 65 73 20 3d 20 67 63 5f 72     _rules = gc_r
3f90: 75 6c 65 73 0a 20 20 20 20 23 20 63 6f 6d 70 69  ules.    # compi
3fa0: 6c 65 20 72 75 6c 65 73 20 72 65 67 65 78 0a 20  le rules regex. 
3fb0: 20 20 20 66 6f 72 20 6c 52 75 6c 65 47 72 6f 75     for lRuleGrou
3fc0: 70 20 69 6e 20 63 68 61 69 6e 28 5f 72 75 6c 65  p in chain(_rule
3fd0: 73 2e 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65  s.lParagraphRule
3fe0: 73 2c 20 5f 72 75 6c 65 73 2e 6c 53 65 6e 74 65  s, _rules.lSente
3ff0: 6e 63 65 52 75 6c 65 73 29 3a 0a 20 20 20 20 20  nceRules):.     
4000: 20 20 20 66 6f 72 20 72 75 6c 65 20 69 6e 20 6c     for rule in l
4010: 52 75 6c 65 47 72 6f 75 70 5b 31 5d 3a 0a 20 20  RuleGroup[1]:.  
4020: 20 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20            try:. 
4030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
4040: 75 6c 65 5b 30 5d 20 3d 20 72 65 2e 63 6f 6d 70  ule[0] = re.comp
4050: 69 6c 65 28 72 75 6c 65 5b 30 5d 29 0a 20 20 20  ile(rule[0]).   
4060: 20 20 20 20 20 20 20 20 20 65 78 63 65 70 74 3a           except:
4070: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4080: 20 65 63 68 6f 28 22 42 61 64 20 72 65 67 75 6c   echo("Bad regul
4090: 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 69 6e  ar expression in
40a0: 20 23 20 22 20 2b 20 73 74 72 28 72 75 6c 65 5b   # " + str(rule[
40b0: 32 5d 29 29 0a 20 20 20 20 20 20 20 20 20 20 20  2])).           
40c0: 20 20 20 20 20 72 75 6c 65 5b 30 5d 20 3d 20 22       rule[0] = "
40d0: 28 3f 69 29 3c 47 72 61 6d 6d 61 6c 65 63 74 65  (?i)<Grammalecte
40e0: 3e 22 0a 0a 0a 64 65 66 20 5f 67 65 74 50 61 74  >"...def _getPat
40f0: 68 20 28 29 3a 0a 20 20 20 20 72 65 74 75 72 6e  h ():.    return
4100: 20 6f 73 2e 70 61 74 68 2e 6a 6f 69 6e 28 6f 73   os.path.join(os
4110: 2e 70 61 74 68 2e 64 69 72 6e 61 6d 65 28 73 79  .path.dirname(sy
4120: 73 2e 6d 6f 64 75 6c 65 73 5b 5f 5f 6e 61 6d 65  s.modules[__name
4130: 5f 5f 5d 2e 5f 5f 66 69 6c 65 5f 5f 29 2c 20 5f  __].__file__), _
4140: 5f 6e 61 6d 65 5f 5f 20 2b 20 22 2e 70 79 22 29  _name__ + ".py")
4150: 0a 0a 0a 0a 23 23 23 23 20 63 6f 6d 6d 6f 6e 20  ....#### common 
4160: 66 75 6e 63 74 69 6f 6e 73 0a 0a 23 20 63 6f 6d  functions..# com
4170: 6d 6f 6e 20 72 65 67 65 78 65 73 0a 5f 7a 45 6e  mon regexes._zEn
4180: 64 4f 66 53 65 6e 74 65 6e 63 65 20 3d 20 72 65  dOfSentence = re
4190: 2e 63 6f 6d 70 69 6c 65 28 72 27 28 5b 2e 3f 21  .compile(r'([.?!
41a0: 3a 3b e2 80 a6 5d 5b 20 2e 3f 21 e2 80 a6 20 c2  :;...][ .?!... .
41b0: bb e2 80 9d 22 29 5d 2a 7c 2e 24 29 27 29 0a 5f  ....")]*|.$)')._
41c0: 7a 42 65 67 69 6e 4f 66 50 61 72 61 67 72 61 70  zBeginOfParagrap
41d0: 68 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72  h = re.compile(r
41e0: 22 5e 5c 57 2a 22 29 0a 5f 7a 45 6e 64 4f 66 50  "^\W*")._zEndOfP
41f0: 61 72 61 67 72 61 70 68 20 3d 20 72 65 2e 63 6f  aragraph = re.co
4200: 6d 70 69 6c 65 28 72 22 5c 57 2a 24 22 29 0a 5f  mpile(r"\W*$")._
4210: 7a 4e 65 78 74 57 6f 72 64 20 3d 20 72 65 2e 63  zNextWord = re.c
4220: 6f 6d 70 69 6c 65 28 72 22 20 2b 28 5c 77 5b 5c  ompile(r" +(\w[\
4230: 77 2d 5d 2a 29 22 29 0a 5f 7a 50 72 65 76 57 6f  w-]*)")._zPrevWo
4240: 72 64 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28  rd = re.compile(
4250: 72 22 28 5c 77 5b 5c 77 2d 5d 2a 29 20 2b 24 22  r"(\w[\w-]*) +$"
4260: 29 0a 0a 0a 64 65 66 20 6f 70 74 69 6f 6e 20 28  )...def option (
4270: 73 4f 70 74 29 3a 0a 20 20 20 20 22 72 65 74 75  sOpt):.    "retu
4280: 72 6e 20 54 72 75 65 20 69 66 20 6f 70 74 69 6f  rn True if optio
4290: 6e 20 73 4f 70 74 20 69 73 20 61 63 74 69 76 65  n sOpt is active
42a0: 22 0a 20 20 20 20 72 65 74 75 72 6e 20 5f 64 4f  ".    return _dO
42b0: 70 74 69 6f 6e 73 2e 67 65 74 28 73 4f 70 74 2c  ptions.get(sOpt,
42c0: 20 46 61 6c 73 65 29 0a 0a 0a 64 65 66 20 64 69   False)...def di
42d0: 73 70 6c 61 79 49 6e 66 6f 20 28 64 44 41 2c 20  splayInfo (dDA, 
42e0: 74 57 6f 72 64 29 3a 0a 20 20 20 20 22 66 6f 72  tWord):.    "for
42f0: 20 64 65 62 75 67 67 69 6e 67 3a 20 72 65 74 72   debugging: retr
4300: 69 65 76 65 20 69 6e 66 6f 20 6f 66 20 77 6f 72  ieve info of wor
4310: 64 22 0a 20 20 20 20 69 66 20 6e 6f 74 20 74 57  d".    if not tW
4320: 6f 72 64 3a 0a 20 20 20 20 20 20 20 20 65 63 68  ord:.        ech
4330: 6f 28 22 3e 20 6e 6f 74 68 69 6e 67 20 74 6f 20  o("> nothing to 
4340: 66 69 6e 64 22 29 0a 20 20 20 20 20 20 20 20 72  find").        r
4350: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 6c  eturn True.    l
4360: 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43  Morph = _oSpellC
4370: 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28  hecker.getMorph(
4380: 74 57 6f 72 64 5b 31 5d 29 0a 20 20 20 20 69 66  tWord[1]).    if
4390: 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20 20 20   not lMorph:.   
43a0: 20 20 20 20 20 65 63 68 6f 28 22 3e 20 6e 6f 74       echo("> not
43b0: 20 69 6e 20 64 69 63 74 69 6f 6e 61 72 79 22 29   in dictionary")
43c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
43d0: 54 72 75 65 0a 20 20 20 20 69 66 20 74 57 6f 72  True.    if tWor
43e0: 64 5b 30 5d 20 69 6e 20 64 44 41 3a 0a 20 20 20  d[0] in dDA:.   
43f0: 20 20 20 20 20 65 63 68 6f 28 22 44 41 3a 20 22       echo("DA: "
4400: 20 2b 20 73 74 72 28 64 44 41 5b 74 57 6f 72 64   + str(dDA[tWord
4410: 5b 30 5d 5d 29 29 0a 20 20 20 20 65 63 68 6f 28  [0]])).    echo(
4420: 22 46 53 41 3a 20 22 20 2b 20 73 74 72 28 6c 4d  "FSA: " + str(lM
4430: 6f 72 70 68 29 29 0a 20 20 20 20 72 65 74 75 72  orph)).    retur
4440: 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20 6d 6f 72  n True...def mor
4450: 70 68 20 28 64 44 41 2c 20 74 57 6f 72 64 2c 20  ph (dDA, tWord, 
4460: 73 50 61 74 74 65 72 6e 2c 20 62 53 74 72 69 63  sPattern, bStric
4470: 74 3d 54 72 75 65 2c 20 62 4e 6f 57 6f 72 64 3d  t=True, bNoWord=
4480: 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 61 6e 61  False):.    "ana
4490: 6c 79 73 65 20 61 20 74 75 70 6c 65 20 28 70 6f  lyse a tuple (po
44a0: 73 69 74 69 6f 6e 2c 20 77 6f 72 64 29 2c 20 72  sition, word), r
44b0: 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 73 50  eturn True if sP
44c0: 61 74 74 65 72 6e 20 69 6e 20 6d 6f 72 70 68 6f  attern in morpho
44d0: 6c 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69 67  logies (disambig
44e0: 75 61 74 69 6f 6e 20 6f 6e 29 22 0a 20 20 20 20  uation on)".    
44f0: 69 66 20 6e 6f 74 20 74 57 6f 72 64 3a 0a 20 20  if not tWord:.  
4500: 20 20 20 20 20 20 72 65 74 75 72 6e 20 62 4e 6f        return bNo
4510: 57 6f 72 64 0a 20 20 20 20 6c 4d 6f 72 70 68 20  Word.    lMorph 
4520: 3d 20 64 44 41 5b 74 57 6f 72 64 5b 30 5d 5d 20  = dDA[tWord[0]] 
4530: 20 69 66 20 74 57 6f 72 64 5b 30 5d 20 69 6e 20   if tWord[0] in 
4540: 64 44 41 20 20 65 6c 73 65 20 5f 6f 53 70 65 6c  dDA  else _oSpel
4550: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70  lChecker.getMorp
4560: 68 28 74 57 6f 72 64 5b 31 5d 29 0a 20 20 20 20  h(tWord[1]).    
4570: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20  if not lMorph:. 
4580: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
4590: 6c 73 65 0a 20 20 20 20 70 20 3d 20 72 65 2e 63  lse.    p = re.c
45a0: 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29  ompile(sPattern)
45b0: 0a 20 20 20 20 69 66 20 62 53 74 72 69 63 74 3a  .    if bStrict:
45c0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
45d0: 61 6c 6c 28 70 2e 73 65 61 72 63 68 28 73 29 20  all(p.search(s) 
45e0: 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68   for s in lMorph
45f0: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79  ).    return any
4600: 28 70 2e 73 65 61 72 63 68 28 73 29 20 20 66 6f  (p.search(s)  fo
4610: 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a  r s in lMorph)..
4620: 0a 64 65 66 20 6d 6f 72 70 68 65 78 20 28 64 44  .def morphex (dD
4630: 41 2c 20 74 57 6f 72 64 2c 20 73 50 61 74 74 65  A, tWord, sPatte
4640: 72 6e 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 2c  rn, sNegPattern,
4650: 20 62 4e 6f 57 6f 72 64 3d 46 61 6c 73 65 29 3a   bNoWord=False):
4660: 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20  .    "analyse a 
4670: 74 75 70 6c 65 20 28 70 6f 73 69 74 69 6f 6e 2c  tuple (position,
4680: 20 77 6f 72 64 29 2c 20 72 65 74 75 72 6e 73 20   word), returns 
4690: 54 72 75 65 20 69 66 20 6e 6f 74 20 73 4e 65 67  True if not sNeg
46a0: 50 61 74 74 65 72 6e 20 69 6e 20 77 6f 72 64 20  Pattern in word 
46b0: 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 61 6e 64  morphologies and
46c0: 20 73 50 61 74 74 65 72 6e 20 69 6e 20 77 6f 72   sPattern in wor
46d0: 64 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28  d morphologies (
46e0: 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f  disambiguation o
46f0: 6e 29 22 0a 20 20 20 20 69 66 20 6e 6f 74 20 74  n)".    if not t
4700: 57 6f 72 64 3a 0a 20 20 20 20 20 20 20 20 72 65  Word:.        re
4710: 74 75 72 6e 20 62 4e 6f 57 6f 72 64 0a 20 20 20  turn bNoWord.   
4720: 20 6c 4d 6f 72 70 68 20 3d 20 64 44 41 5b 74 57   lMorph = dDA[tW
4730: 6f 72 64 5b 30 5d 5d 20 20 69 66 20 74 57 6f 72  ord[0]]  if tWor
4740: 64 5b 30 5d 20 69 6e 20 64 44 41 20 20 65 6c 73  d[0] in dDA  els
4750: 65 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  e _oSpellChecker
4760: 2e 67 65 74 4d 6f 72 70 68 28 74 57 6f 72 64 5b  .getMorph(tWord[
4770: 31 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c  1]).    if not l
4780: 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 72  Morph:.        r
4790: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
47a0: 23 20 63 68 65 63 6b 20 6e 65 67 61 74 69 76 65  # check negative
47b0: 20 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 6e   condition.    n
47c0: 70 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73  p = re.compile(s
47d0: 4e 65 67 50 61 74 74 65 72 6e 29 0a 20 20 20 20  NegPattern).    
47e0: 69 66 20 61 6e 79 28 6e 70 2e 73 65 61 72 63 68  if any(np.search
47f0: 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d  (s)  for s in lM
4800: 6f 72 70 68 29 3a 0a 20 20 20 20 20 20 20 20 72  orph):.        r
4810: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
4820: 23 20 73 65 61 72 63 68 20 73 50 61 74 74 65 72  # search sPatter
4830: 6e 0a 20 20 20 20 70 20 3d 20 72 65 2e 63 6f 6d  n.    p = re.com
4840: 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20  pile(sPattern). 
4850: 20 20 20 72 65 74 75 72 6e 20 61 6e 79 28 70 2e     return any(p.
4860: 73 65 61 72 63 68 28 73 29 20 20 66 6f 72 20 73  search(s)  for s
4870: 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 64 65   in lMorph)...de
4880: 66 20 61 6e 61 6c 79 73 65 20 28 73 57 6f 72 64  f analyse (sWord
4890: 2c 20 73 50 61 74 74 65 72 6e 2c 20 62 53 74 72  , sPattern, bStr
48a0: 69 63 74 3d 54 72 75 65 29 3a 0a 20 20 20 20 22  ict=True):.    "
48b0: 61 6e 61 6c 79 73 65 20 61 20 77 6f 72 64 2c 20  analyse a word, 
48c0: 72 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 73  return True if s
48d0: 50 61 74 74 65 72 6e 20 69 6e 20 6d 6f 72 70 68  Pattern in morph
48e0: 6f 6c 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69  ologies (disambi
48f0: 67 75 61 74 69 6f 6e 20 6f 66 66 29 22 0a 20 20  guation off)".  
4900: 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65    lMorph = _oSpe
4910: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
4920: 70 68 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66  ph(sWord).    if
4930: 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20 20 20   not lMorph:.   
4940: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
4950: 65 0a 20 20 20 20 70 20 3d 20 72 65 2e 63 6f 6d  e.    p = re.com
4960: 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20  pile(sPattern). 
4970: 20 20 20 69 66 20 62 53 74 72 69 63 74 3a 0a 20     if bStrict:. 
4980: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 61 6c         return al
4990: 6c 28 70 2e 73 65 61 72 63 68 28 73 29 20 20 66  l(p.search(s)  f
49a0: 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a  or s in lMorph).
49b0: 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79 28 70      return any(p
49c0: 2e 73 65 61 72 63 68 28 73 29 20 20 66 6f 72 20  .search(s)  for 
49d0: 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 64  s in lMorph)...d
49e0: 65 66 20 61 6e 61 6c 79 73 65 78 20 28 73 57 6f  ef analysex (sWo
49f0: 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e  rd, sPattern, sN
4a00: 65 67 50 61 74 74 65 72 6e 29 3a 0a 20 20 20 20  egPattern):.    
4a10: 22 61 6e 61 6c 79 73 65 20 61 20 77 6f 72 64 2c  "analyse a word,
4a20: 20 72 65 74 75 72 6e 73 20 54 72 75 65 20 69 66   returns True if
4a30: 20 6e 6f 74 20 73 4e 65 67 50 61 74 74 65 72 6e   not sNegPattern
4a40: 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70 68 6f 6c   in word morphol
4a50: 6f 67 69 65 73 20 61 6e 64 20 73 50 61 74 74 65  ogies and sPatte
4a60: 72 6e 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70 68  rn in word morph
4a70: 6f 6c 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69  ologies (disambi
4a80: 67 75 61 74 69 6f 6e 20 6f 66 66 29 22 0a 20 20  guation off)".  
4a90: 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65    lMorph = _oSpe
4aa0: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
4ab0: 70 68 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66  ph(sWord).    if
4ac0: 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20 20 20   not lMorph:.   
4ad0: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
4ae0: 65 0a 20 20 20 20 23 20 63 68 65 63 6b 20 6e 65  e.    # check ne
4af0: 67 61 74 69 76 65 20 63 6f 6e 64 69 74 69 6f 6e  gative condition
4b00: 0a 20 20 20 20 6e 70 20 3d 20 72 65 2e 63 6f 6d  .    np = re.com
4b10: 70 69 6c 65 28 73 4e 65 67 50 61 74 74 65 72 6e  pile(sNegPattern
4b20: 29 0a 20 20 20 20 69 66 20 61 6e 79 28 6e 70 2e  ).    if any(np.
4b30: 73 65 61 72 63 68 28 73 29 20 20 66 6f 72 20 73  search(s)  for s
4b40: 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20   in lMorph):.   
4b50: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
4b60: 65 0a 20 20 20 20 23 20 73 65 61 72 63 68 20 73  e.    # search s
4b70: 50 61 74 74 65 72 6e 0a 20 20 20 20 70 20 3d 20  Pattern.    p = 
4b80: 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74  re.compile(sPatt
4b90: 65 72 6e 29 0a 20 20 20 20 72 65 74 75 72 6e 20  ern).    return 
4ba0: 61 6e 79 28 70 2e 73 65 61 72 63 68 28 73 29 20  any(p.search(s) 
4bb0: 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68   for s in lMorph
4bc0: 29 0a 0a 0a 0a 23 23 20 66 75 6e 63 74 69 6f 6e  )....## function
4bd0: 73 20 74 6f 20 67 65 74 20 74 65 78 74 20 6f 75  s to get text ou
4be0: 74 73 69 64 65 20 70 61 74 74 65 72 6e 20 73 63  tside pattern sc
4bf0: 6f 70 65 0a 0a 23 20 77 61 72 6e 69 6e 67 3a 20  ope..# warning: 
4c00: 63 68 65 63 6b 20 63 6f 6d 70 69 6c 65 5f 72 75  check compile_ru
4c10: 6c 65 73 2e 70 79 20 74 6f 20 75 6e 64 65 72 73  les.py to unders
4c20: 74 61 6e 64 20 68 6f 77 20 69 74 20 77 6f 72 6b  tand how it work
4c30: 73 0a 0a 64 65 66 20 6e 65 78 74 77 6f 72 64 20  s..def nextword 
4c40: 28 73 2c 20 69 53 74 61 72 74 2c 20 6e 29 3a 0a  (s, iStart, n):.
4c50: 20 20 20 20 22 67 65 74 20 74 68 65 20 6e 74 68      "get the nth
4c60: 20 77 6f 72 64 20 6f 66 20 74 68 65 20 69 6e 70   word of the inp
4c70: 75 74 20 73 74 72 69 6e 67 20 6f 72 20 65 6d 70  ut string or emp
4c80: 74 79 20 73 74 72 69 6e 67 22 0a 20 20 20 20 6d  ty string".    m
4c90: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 28 3f 3a   = re.match("(?:
4ca0: 20 2b 5b 5c 5c 77 25 2d 5d 2b 29 7b 22 20 2b 20   +[\\w%-]+){" + 
4cb0: 73 74 72 28 6e 2d 31 29 20 2b 20 22 7d 20 2b 28  str(n-1) + "} +(
4cc0: 5b 5c 5c 77 25 2d 5d 2b 29 22 2c 20 73 5b 69 53  [\\w%-]+)", s[iS
4cd0: 74 61 72 74 3a 5d 29 0a 20 20 20 20 69 66 20 6e  tart:]).    if n
4ce0: 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 72 65  ot m:.        re
4cf0: 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20 72 65  turn None.    re
4d00: 74 75 72 6e 20 28 69 53 74 61 72 74 2b 6d 2e 73  turn (iStart+m.s
4d10: 74 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75 70  tart(1), m.group
4d20: 28 31 29 29 0a 0a 0a 64 65 66 20 70 72 65 76 77  (1))...def prevw
4d30: 6f 72 64 20 28 73 2c 20 69 45 6e 64 2c 20 6e 29  ord (s, iEnd, n)
4d40: 3a 0a 20 20 20 20 22 67 65 74 20 74 68 65 20 28  :.    "get the (
4d50: 2d 29 6e 74 68 20 77 6f 72 64 20 6f 66 20 74 68  -)nth word of th
4d60: 65 20 69 6e 70 75 74 20 73 74 72 69 6e 67 20 6f  e input string o
4d70: 72 20 65 6d 70 74 79 20 73 74 72 69 6e 67 22 0a  r empty string".
4d80: 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63      m = re.searc
4d90: 68 28 22 28 5b 5c 5c 77 25 2d 5d 2b 29 20 2b 28  h("([\\w%-]+) +(
4da0: 3f 3a 5b 5c 5c 77 25 2d 5d 2b 20 2b 29 7b 22 20  ?:[\\w%-]+ +){" 
4db0: 2b 20 73 74 72 28 6e 2d 31 29 20 2b 20 22 7d 24  + str(n-1) + "}$
4dc0: 22 2c 20 73 5b 3a 69 45 6e 64 5d 29 0a 20 20 20  ", s[:iEnd]).   
4dd0: 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20   if not m:.     
4de0: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20     return None. 
4df0: 20 20 20 72 65 74 75 72 6e 20 28 6d 2e 73 74 61     return (m.sta
4e00: 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75 70 28 31  rt(1), m.group(1
4e10: 29 29 0a 0a 0a 64 65 66 20 6e 65 78 74 77 6f 72  ))...def nextwor
4e20: 64 31 20 28 73 2c 20 69 53 74 61 72 74 29 3a 0a  d1 (s, iStart):.
4e30: 20 20 20 20 22 67 65 74 20 6e 65 78 74 20 77 6f      "get next wo
4e40: 72 64 20 28 6f 70 74 69 6d 69 7a 61 74 69 6f 6e  rd (optimization
4e50: 29 22 0a 20 20 20 20 6d 20 3d 20 5f 7a 4e 65 78  )".    m = _zNex
4e60: 74 57 6f 72 64 2e 6d 61 74 63 68 28 73 5b 69 53  tWord.match(s[iS
4e70: 74 61 72 74 3a 5d 29 0a 20 20 20 20 69 66 20 6e  tart:]).    if n
4e80: 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 72 65  ot m:.        re
4e90: 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20 72 65  turn None.    re
4ea0: 74 75 72 6e 20 28 69 53 74 61 72 74 2b 6d 2e 73  turn (iStart+m.s
4eb0: 74 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75 70  tart(1), m.group
4ec0: 28 31 29 29 0a 0a 0a 64 65 66 20 70 72 65 76 77  (1))...def prevw
4ed0: 6f 72 64 31 20 28 73 2c 20 69 45 6e 64 29 3a 0a  ord1 (s, iEnd):.
4ee0: 20 20 20 20 22 67 65 74 20 70 72 65 76 69 6f 75      "get previou
4ef0: 73 20 77 6f 72 64 20 28 6f 70 74 69 6d 69 7a 61  s word (optimiza
4f00: 74 69 6f 6e 29 22 0a 20 20 20 20 6d 20 3d 20 5f  tion)".    m = _
4f10: 7a 50 72 65 76 57 6f 72 64 2e 73 65 61 72 63 68  zPrevWord.search
4f20: 28 73 5b 3a 69 45 6e 64 5d 29 0a 20 20 20 20 69  (s[:iEnd]).    i
4f30: 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20  f not m:.       
4f40: 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20   return None.   
4f50: 20 72 65 74 75 72 6e 20 28 6d 2e 73 74 61 72 74   return (m.start
4f60: 28 31 29 2c 20 6d 2e 67 72 6f 75 70 28 31 29 29  (1), m.group(1))
4f70: 0a 0a 0a 64 65 66 20 6c 6f 6f 6b 20 28 73 2c 20  ...def look (s, 
4f80: 73 50 61 74 74 65 72 6e 2c 20 73 4e 65 67 50 61  sPattern, sNegPa
4f90: 74 74 65 72 6e 3d 4e 6f 6e 65 29 3a 0a 20 20 20  ttern=None):.   
4fa0: 20 22 73 65 65 6b 20 73 50 61 74 74 65 72 6e 20   "seek sPattern 
4fb0: 69 6e 20 73 20 28 62 65 66 6f 72 65 2f 61 66 74  in s (before/aft
4fc0: 65 72 2f 66 75 6c 6c 74 65 78 74 29 2c 20 69 66  er/fulltext), if
4fd0: 20 73 4e 65 67 50 61 74 74 65 72 6e 20 6e 6f 74   sNegPattern not
4fe0: 20 69 6e 20 73 22 0a 20 20 20 20 69 66 20 73 4e   in s".    if sN
4ff0: 65 67 50 61 74 74 65 72 6e 20 61 6e 64 20 72 65  egPattern and re
5000: 2e 73 65 61 72 63 68 28 73 4e 65 67 50 61 74 74  .search(sNegPatt
5010: 65 72 6e 2c 20 73 29 3a 0a 20 20 20 20 20 20 20  ern, s):.       
5020: 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20   return False.  
5030: 20 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 73    if re.search(s
5040: 50 61 74 74 65 72 6e 2c 20 73 29 3a 0a 20 20 20  Pattern, s):.   
5050: 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65       return True
5060: 0a 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73  .    return Fals
5070: 65 0a 0a 0a 64 65 66 20 6c 6f 6f 6b 5f 63 68 6b  e...def look_chk
5080: 31 20 28 64 44 41 2c 20 73 2c 20 6e 4f 66 66 73  1 (dDA, s, nOffs
5090: 65 74 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 50  et, sPattern, sP
50a0: 61 74 74 65 72 6e 47 72 6f 75 70 31 2c 20 73 4e  atternGroup1, sN
50b0: 65 67 50 61 74 74 65 72 6e 47 72 6f 75 70 31 3d  egPatternGroup1=
50c0: 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 72 65 74 75  None):.    "retu
50d0: 72 6e 73 20 54 72 75 65 20 69 66 20 73 20 68 61  rns True if s ha
50e0: 73 20 70 61 74 74 65 72 6e 20 73 50 61 74 74 65  s pattern sPatte
50f0: 72 6e 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 31  rn and m.group(1
5100: 29 20 68 61 73 20 70 61 74 74 65 72 6e 20 73 50  ) has pattern sP
5110: 61 74 74 65 72 6e 47 72 6f 75 70 31 22 0a 20 20  atternGroup1".  
5120: 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28    m = re.search(
5130: 73 50 61 74 74 65 72 6e 2c 20 73 29 0a 20 20 20  sPattern, s).   
5140: 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20   if not m:.     
5150: 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a     return False.
5160: 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20      try:.       
5170: 20 73 57 6f 72 64 20 3d 20 6d 2e 67 72 6f 75 70   sWord = m.group
5180: 28 31 29 0a 20 20 20 20 20 20 20 20 6e 50 6f 73  (1).        nPos
5190: 20 3d 20 6d 2e 73 74 61 72 74 28 31 29 20 2b 20   = m.start(1) + 
51a0: 6e 4f 66 66 73 65 74 0a 20 20 20 20 65 78 63 65  nOffset.    exce
51b0: 70 74 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  pt:.        retu
51c0: 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 69 66 20  rn False.    if 
51d0: 73 4e 65 67 50 61 74 74 65 72 6e 47 72 6f 75 70  sNegPatternGroup
51e0: 31 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  1:.        retur
51f0: 6e 20 6d 6f 72 70 68 65 78 28 64 44 41 2c 20 28  n morphex(dDA, (
5200: 6e 50 6f 73 2c 20 73 57 6f 72 64 29 2c 20 73 50  nPos, sWord), sP
5210: 61 74 74 65 72 6e 47 72 6f 75 70 31 2c 20 73 4e  atternGroup1, sN
5220: 65 67 50 61 74 74 65 72 6e 47 72 6f 75 70 31 29  egPatternGroup1)
5230: 0a 20 20 20 20 72 65 74 75 72 6e 20 6d 6f 72 70  .    return morp
5240: 68 28 64 44 41 2c 20 28 6e 50 6f 73 2c 20 73 57  h(dDA, (nPos, sW
5250: 6f 72 64 29 2c 20 73 50 61 74 74 65 72 6e 47 72  ord), sPatternGr
5260: 6f 75 70 31 2c 20 46 61 6c 73 65 29 0a 0a 0a 23  oup1, False)...#
5270: 23 23 23 20 44 69 73 61 6d 62 69 67 75 61 74 6f  ### Disambiguato
5280: 72 0a 0a 64 65 66 20 73 65 6c 65 63 74 20 28 64  r..def select (d
5290: 44 41 2c 20 6e 50 6f 73 2c 20 73 57 6f 72 64 2c  DA, nPos, sWord,
52a0: 20 73 50 61 74 74 65 72 6e 2c 20 6c 44 65 66 61   sPattern, lDefa
52b0: 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 69  ult=None):.    i
52c0: 66 20 6e 6f 74 20 73 57 6f 72 64 3a 0a 20 20 20  f not sWord:.   
52d0: 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65       return True
52e0: 0a 20 20 20 20 69 66 20 6e 50 6f 73 20 69 6e 20  .    if nPos in 
52f0: 64 44 41 3a 0a 20 20 20 20 20 20 20 20 72 65 74  dDA:.        ret
5300: 75 72 6e 20 54 72 75 65 0a 20 20 20 20 6c 4d 6f  urn True.    lMo
5310: 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65  rph = _oSpellChe
5320: 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 57  cker.getMorph(sW
5330: 6f 72 64 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  ord).    if not 
5340: 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e 28 6c 4d  lMorph or len(lM
5350: 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20 20 20 20  orph) == 1:.    
5360: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
5370: 20 20 20 20 6c 53 65 6c 65 63 74 20 3d 20 5b 20      lSelect = [ 
5380: 73 4d 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72  sMorph  for sMor
5390: 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20 20 69 66  ph in lMorph  if
53a0: 20 72 65 2e 73 65 61 72 63 68 28 73 50 61 74 74   re.search(sPatt
53b0: 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20 5d 0a 20  ern, sMorph) ]. 
53c0: 20 20 20 69 66 20 6c 53 65 6c 65 63 74 3a 0a 20     if lSelect:. 
53d0: 20 20 20 20 20 20 20 69 66 20 6c 65 6e 28 6c 53         if len(lS
53e0: 65 6c 65 63 74 29 20 21 3d 20 6c 65 6e 28 6c 4d  elect) != len(lM
53f0: 6f 72 70 68 29 3a 0a 20 20 20 20 20 20 20 20 20  orph):.         
5400: 20 20 20 64 44 41 5b 6e 50 6f 73 5d 20 3d 20 6c     dDA[nPos] = l
5410: 53 65 6c 65 63 74 0a 20 20 20 20 65 6c 69 66 20  Select.    elif 
5420: 6c 44 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20  lDefault:.      
5430: 20 20 64 44 41 5b 6e 50 6f 73 5d 20 3d 20 6c 44    dDA[nPos] = lD
5440: 65 66 61 75 6c 74 0a 20 20 20 20 72 65 74 75 72  efault.    retur
5450: 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20 65 78 63  n True...def exc
5460: 6c 75 64 65 20 28 64 44 41 2c 20 6e 50 6f 73 2c  lude (dDA, nPos,
5470: 20 73 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e   sWord, sPattern
5480: 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f 6e 65 29  , lDefault=None)
5490: 3a 0a 20 20 20 20 69 66 20 6e 6f 74 20 73 57 6f  :.    if not sWo
54a0: 72 64 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  rd:.        retu
54b0: 72 6e 20 54 72 75 65 0a 20 20 20 20 69 66 20 6e  rn True.    if n
54c0: 50 6f 73 20 69 6e 20 64 44 41 3a 0a 20 20 20 20  Pos in dDA:.    
54d0: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
54e0: 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53      lMorph = _oS
54f0: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
5500: 6f 72 70 68 28 73 57 6f 72 64 29 0a 20 20 20 20  orph(sWord).    
5510: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f 72  if not lMorph or
5520: 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d 20   len(lMorph) == 
5530: 31 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  1:.        retur
5540: 6e 20 54 72 75 65 0a 20 20 20 20 6c 53 65 6c 65  n True.    lSele
5550: 63 74 20 3d 20 5b 20 73 4d 6f 72 70 68 20 20 66  ct = [ sMorph  f
5560: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f  or sMorph in lMo
5570: 72 70 68 20 20 69 66 20 6e 6f 74 20 72 65 2e 73  rph  if not re.s
5580: 65 61 72 63 68 28 73 50 61 74 74 65 72 6e 2c 20  earch(sPattern, 
5590: 73 4d 6f 72 70 68 29 20 5d 0a 20 20 20 20 69 66  sMorph) ].    if
55a0: 20 6c 53 65 6c 65 63 74 3a 0a 20 20 20 20 20 20   lSelect:.      
55b0: 20 20 69 66 20 6c 65 6e 28 6c 53 65 6c 65 63 74    if len(lSelect
55c0: 29 20 21 3d 20 6c 65 6e 28 6c 4d 6f 72 70 68 29  ) != len(lMorph)
55d0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 44  :.            dD
55e0: 41 5b 6e 50 6f 73 5d 20 3d 20 6c 53 65 6c 65 63  A[nPos] = lSelec
55f0: 74 0a 20 20 20 20 65 6c 69 66 20 6c 44 65 66 61  t.    elif lDefa
5600: 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 64 44 41  ult:.        dDA
5610: 5b 6e 50 6f 73 5d 20 3d 20 6c 44 65 66 61 75 6c  [nPos] = lDefaul
5620: 74 0a 20 20 20 20 72 65 74 75 72 6e 20 54 72 75  t.    return Tru
5630: 65 0a 0a 0a 64 65 66 20 64 65 66 69 6e 65 20 28  e...def define (
5640: 64 44 41 2c 20 6e 50 6f 73 2c 20 6c 4d 6f 72 70  dDA, nPos, lMorp
5650: 68 29 3a 0a 20 20 20 20 64 44 41 5b 6e 50 6f 73  h):.    dDA[nPos
5660: 5d 20 3d 20 6c 4d 6f 72 70 68 0a 20 20 20 20 72  ] = lMorph.    r
5670: 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 23 23 23  eturn True...###
5680: 23 20 47 52 41 4d 4d 41 52 20 43 48 45 43 4b 45  # GRAMMAR CHECKE
5690: 52 20 50 4c 55 47 49 4e 53 0a 0a 24 7b 70 6c 75  R PLUGINS..${plu
56a0: 67 69 6e 73 7d 0a 0a 0a 23 23 23 23 20 43 41 4c  gins}...#### CAL
56b0: 4c 41 42 4c 45 53 20 28 67 65 6e 65 72 61 74 65  LABLES (generate
56c0: 64 20 63 6f 64 65 29 0a 0a 24 7b 63 61 6c 6c 61  d code)..${calla
56d0: 62 6c 65 73 7d 0a 0a 0a 0a 23 23 23 23 20 54 4f  bles}....#### TO
56e0: 4b 45 4e 20 53 45 4e 54 45 4e 43 45 20 43 48 45  KEN SENTENCE CHE
56f0: 43 4b 45 52 0a 0a 63 6c 61 73 73 20 54 6f 6b 65  CKER..class Toke
5700: 6e 53 65 6e 74 65 6e 63 65 3a 0a 0a 20 20 20 20  nSentence:..    
5710: 64 65 66 20 5f 5f 69 6e 69 74 5f 5f 20 28 73 65  def __init__ (se
5720: 6c 66 2c 20 73 53 65 6e 74 65 6e 63 65 2c 20 73  lf, sSentence, s
5730: 53 65 6e 74 65 6e 63 65 30 2c 20 69 53 74 61 72  Sentence0, iStar
5740: 74 29 3a 0a 20 20 20 20 20 20 20 20 73 65 6c 66  t):.        self
5750: 2e 73 53 65 6e 74 65 6e 63 65 20 3d 20 73 53 65  .sSentence = sSe
5760: 6e 74 65 6e 63 65 0a 20 20 20 20 20 20 20 20 73  ntence.        s
5770: 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 30 20 3d  elf.sSentence0 =
5780: 20 73 53 65 6e 74 65 6e 63 65 30 0a 20 20 20 20   sSentence0.    
5790: 20 20 20 20 73 65 6c 66 2e 69 53 74 61 72 74 20      self.iStart 
57a0: 3d 20 69 53 74 61 72 74 0a 20 20 20 20 20 20 20  = iStart.       
57b0: 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 20 3d 20 6c   self.lToken = l
57c0: 69 73 74 28 5f 6f 54 6f 6b 65 6e 69 7a 65 72 2e  ist(_oTokenizer.
57d0: 67 65 6e 54 6f 6b 65 6e 73 28 73 53 65 6e 74 65  genTokens(sSente
57e0: 6e 63 65 2c 20 54 72 75 65 29 29 0a 0a 20 20 20  nce, True))..   
57f0: 20 64 65 66 20 5f 67 65 74 4e 65 78 74 4d 61 74   def _getNextMat
5800: 63 68 69 6e 67 4e 6f 64 65 73 20 28 73 65 6c 66  chingNodes (self
5810: 2c 20 64 54 6f 6b 65 6e 2c 20 64 4e 6f 64 65 29  , dToken, dNode)
5820: 3a 0a 20 20 20 20 20 20 20 20 22 67 65 6e 65 72  :.        "gener
5830: 61 74 6f 72 3a 20 72 65 74 75 72 6e 20 6e 6f 64  ator: return nod
5840: 65 73 20 77 68 65 72 65 20 3c 64 54 6f 6b 65 6e  es where <dToken
5850: 3e 20 e2 80 9c 76 61 6c 75 65 73 e2 80 9d 20 6d  > ...values... m
5860: 61 74 63 68 20 3c 64 4e 6f 64 65 3e 20 61 72 63  atch <dNode> arc
5870: 73 22 0a 20 20 20 20 20 20 20 20 23 20 74 6f 6b  s".        # tok
5880: 65 6e 20 76 61 6c 75 65 0a 20 20 20 20 20 20 20  en value.       
5890: 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c   if dToken["sVal
58a0: 75 65 22 5d 20 69 6e 20 64 4e 6f 64 65 3a 0a 20  ue"] in dNode:. 
58b0: 20 20 20 20 20 20 20 20 20 20 20 23 70 72 69 6e             #prin
58c0: 74 28 22 76 61 6c 75 65 20 66 6f 75 6e 64 3a 20  t("value found: 
58d0: 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ", dToken["sValu
58e0: 65 22 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20  e"]).           
58f0: 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e   yield dGraph[dN
5900: 6f 64 65 5b 64 54 6f 6b 65 6e 5b 22 73 56 61 6c  ode[dToken["sVal
5910: 75 65 22 5d 5d 5d 0a 20 20 20 20 20 20 20 20 23  ue"]]].        #
5920: 20 74 6f 6b 65 6e 20 6c 65 6d 6d 61 73 0a 20 20   token lemmas.  
5930: 20 20 20 20 20 20 69 66 20 22 3c 6c 65 6d 6d 61        if "<lemma
5940: 73 3e 22 20 69 6e 20 64 4e 6f 64 65 3a 0a 20 20  s>" in dNode:.  
5950: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 4c            for sL
5960: 65 6d 6d 61 20 69 6e 20 5f 6f 53 70 65 6c 6c 43  emma in _oSpellC
5970: 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28  hecker.getLemma(
5980: 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d  dToken["sValue"]
5990: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
59a0: 20 20 20 69 66 20 73 4c 65 6d 6d 61 20 69 6e 20     if sLemma in 
59b0: 64 4e 6f 64 65 5b 22 3c 6c 65 6d 6d 61 73 3e 22  dNode["<lemmas>"
59c0: 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]:.             
59d0: 20 20 20 20 20 20 20 23 70 72 69 6e 74 28 22 6c         #print("l
59e0: 65 6d 6d 61 20 66 6f 75 6e 64 3a 20 22 2c 20 73  emma found: ", s
59f0: 4c 65 6d 6d 61 29 0a 20 20 20 20 20 20 20 20 20  Lemma).         
5a00: 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64             yield
5a10: 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c   dGraph[dNode["<
5a20: 6c 65 6d 6d 61 73 3e 22 5d 5b 73 4c 65 6d 6d 61  lemmas>"][sLemma
5a30: 5d 5d 0a 20 20 20 20 20 20 20 20 23 20 75 6e 69  ]].        # uni
5a40: 76 65 72 73 61 6c 20 61 72 63 0a 20 20 20 20 20  versal arc.     
5a50: 20 20 20 69 66 20 22 2a 22 20 69 6e 20 64 4e 6f     if "*" in dNo
5a60: 64 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  de:.            
5a70: 23 70 72 69 6e 74 28 22 67 65 6e 65 72 69 63 20  #print("generic 
5a80: 61 72 63 22 29 0a 20 20 20 20 20 20 20 20 20 20  arc").          
5a90: 20 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64    yield dGraph[d
5aa0: 4e 6f 64 65 5b 22 2a 22 5d 5d 0a 20 20 20 20 20  Node["*"]].     
5ab0: 20 20 20 23 20 72 65 67 65 78 20 76 61 6c 75 65     # regex value
5ac0: 20 61 72 63 73 0a 20 20 20 20 20 20 20 20 69 66   arcs.        if
5ad0: 20 22 3c 72 65 5f 76 61 6c 75 65 3e 22 20 69 6e   "<re_value>" in
5ae0: 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20   dNode:.        
5af0: 20 20 20 20 66 6f 72 20 73 52 65 67 65 78 20 69      for sRegex i
5b00: 6e 20 64 4e 6f 64 65 5b 22 3c 72 65 5f 76 61 6c  n dNode["<re_val
5b10: 75 65 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20  ue>"]:.         
5b20: 20 20 20 20 20 20 20 69 66 20 72 65 2e 73 65 61         if re.sea
5b30: 72 63 68 28 73 52 65 67 65 78 2c 20 64 54 6f 6b  rch(sRegex, dTok
5b40: 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 3a 0a 20  en["sValue"]):. 
5b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b60: 20 20 20 23 70 72 69 6e 74 28 22 76 61 6c 75 65     #print("value
5b70: 20 72 65 67 65 78 20 6d 61 74 63 68 69 6e 67 3a   regex matching:
5b80: 20 22 2c 20 73 52 65 67 65 78 29 0a 20 20 20 20   ", sRegex).    
5b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ba0: 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f  yield dGraph[dNo
5bb0: 64 65 5b 22 3c 72 65 5f 76 61 6c 75 65 3e 22 5d  de["<re_value>"]
5bc0: 5b 73 52 65 67 65 78 5d 5d 0a 20 20 20 20 20 20  [sRegex]].      
5bd0: 20 20 23 20 72 65 67 65 78 20 6d 6f 72 70 68 20    # regex morph 
5be0: 61 72 63 73 0a 20 20 20 20 20 20 20 20 69 66 20  arcs.        if 
5bf0: 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 20 69 6e 20  "<re_morph>" in 
5c00: 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20  dNode:.         
5c10: 20 20 20 66 6f 72 20 73 52 65 67 65 78 20 69 6e     for sRegex in
5c20: 20 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70   dNode["<re_morp
5c30: 68 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20  h>"]:.          
5c40: 20 20 20 20 20 20 69 66 20 22 c2 ac 22 20 6e 6f        if ".." no
5c50: 74 20 69 6e 20 73 52 65 67 65 78 3a 0a 20 20 20  t in sRegex:.   
5c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c70: 20 23 20 6e 6f 20 61 6e 74 69 2d 70 61 74 74 65   # no anti-patte
5c80: 72 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  rn.             
5c90: 20 20 20 20 20 20 20 69 66 20 61 6e 79 28 72 65         if any(re
5ca0: 2e 73 65 61 72 63 68 28 73 52 65 67 65 78 2c 20  .search(sRegex, 
5cb0: 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f  sMorph)  for sMo
5cc0: 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68  rph in _oSpellCh
5cd0: 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64  ecker.getMorph(d
5ce0: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29  Token["sValue"])
5cf0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
5d00: 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64             yield
5d10: 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c   dGraph[dNode["<
5d20: 72 65 5f 6d 6f 72 70 68 3e 22 5d 5b 73 52 65 67  re_morph>"][sReg
5d30: 65 78 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20  ex]].           
5d40: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
5d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
5d60: 20 74 68 65 72 65 20 69 73 20 61 6e 20 61 6e 74   there is an ant
5d70: 69 2d 70 61 74 74 65 72 6e 0a 20 20 20 20 20 20  i-pattern.      
5d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 50                sP
5d90: 61 74 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74  attern, sNegPatt
5da0: 65 72 6e 20 3d 20 73 52 65 67 65 78 2e 73 70 6c  ern = sRegex.spl
5db0: 69 74 28 22 c2 ac 22 2c 20 31 29 0a 20 20 20 20  it("..", 1).    
5dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5dd0: 69 66 20 73 4e 65 67 50 61 74 74 65 72 6e 20 3d  if sNegPattern =
5de0: 3d 20 22 2a 22 3a 0a 20 20 20 20 20 20 20 20 20  = "*":.         
5df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
5e00: 20 61 6c 6c 20 6d 6f 72 70 68 6f 6c 6f 67 69 65   all morphologie
5e10: 73 20 6d 75 73 74 20 6d 61 74 63 68 20 77 69 74  s must match wit
5e20: 68 20 3c 73 50 61 74 74 65 72 6e 3e 0a 20 20 20  h <sPattern>.   
5e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e40: 20 20 20 20 20 69 66 20 61 6c 6c 28 72 65 2e 73       if all(re.s
5e50: 65 61 72 63 68 28 73 50 61 74 74 65 72 6e 2c 20  earch(sPattern, 
5e60: 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f  sMorph)  for sMo
5e70: 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68  rph in _oSpellCh
5e80: 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64  ecker.getMorph(d
5e90: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29  Token["sValue"])
5ea0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
5eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 79                 y
5ec0: 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64  ield dGraph[dNod
5ed0: 65 5b 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 5d 5b  e["<re_morph>"][
5ee0: 73 52 65 67 65 78 5d 5d 0a 20 20 20 20 20 20 20  sRegex]].       
5ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73               els
5f00: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
5f10: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4e             if sN
5f20: 65 67 50 61 74 74 65 72 6e 20 61 6e 64 20 61 6e  egPattern and an
5f30: 79 28 72 65 2e 73 65 61 72 63 68 28 73 4e 65 67  y(re.search(sNeg
5f40: 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29  Pattern, sMorph)
5f50: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
5f60: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
5f70: 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22  etMorph(dToken["
5f80: 73 56 61 6c 75 65 22 5d 29 29 3a 0a 20 20 20 20  sValue"])):.    
5f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5fa0: 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65          continue
5fb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5fc0: 20 20 20 20 20 20 20 20 20 69 66 20 61 6e 79 28           if any(
5fd0: 72 65 2e 73 65 61 72 63 68 28 73 50 61 74 74 65  re.search(sPatte
5fe0: 72 6e 2c 20 73 4d 6f 72 70 68 29 20 20 66 6f 72  rn, sMorph)  for
5ff0: 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65   sMorph in _oSpe
6000: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
6010: 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ph(dToken["sValu
6020: 65 22 5d 29 29 3a 0a 20 20 20 20 20 20 20 20 20  e"])):.         
6030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6040: 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b     yield dGraph[
6050: 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70 68  dNode["<re_morph
6060: 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 0a 0a 20  >"][sRegex]]... 
6070: 20 20 20 64 65 66 20 70 61 72 73 65 20 28 73 65     def parse (se
6080: 6c 66 2c 20 64 50 72 69 6f 72 69 74 79 2c 20 73  lf, dPriority, s
6090: 43 6f 75 6e 74 72 79 3d 22 24 7b 63 6f 75 6e 74  Country="${count
60a0: 72 79 5f 64 65 66 61 75 6c 74 7d 22 2c 20 64 4f  ry_default}", dO
60b0: 70 74 69 6f 6e 73 3d 4e 6f 6e 65 2c 20 62 53 68  ptions=None, bSh
60c0: 6f 77 52 75 6c 65 49 64 3d 46 61 6c 73 65 2c 20  owRuleId=False, 
60d0: 62 44 65 62 75 67 3d 46 61 6c 73 65 2c 20 62 43  bDebug=False, bC
60e0: 6f 6e 74 65 78 74 3d 46 61 6c 73 65 29 3a 0a 20  ontext=False):. 
60f0: 20 20 20 20 20 20 20 64 45 72 72 20 3d 20 7b 7d         dErr = {}
6100: 0a 20 20 20 20 20 20 20 20 64 50 72 69 6f 72 69  .        dPriori
6110: 74 79 20 3d 20 7b 7d 20 20 23 20 4b 65 79 20 3d  ty = {}  # Key =
6120: 20 70 6f 73 69 74 69 6f 6e 3b 20 76 61 6c 75 65   position; value
6130: 20 3d 20 70 72 69 6f 72 69 74 79 0a 20 20 20 20   = priority.    
6140: 20 20 20 20 64 4f 70 74 20 3d 20 5f 64 4f 70 74      dOpt = _dOpt
6150: 69 6f 6e 73 20 20 69 66 20 6e 6f 74 20 64 4f 70  ions  if not dOp
6160: 74 69 6f 6e 73 20 20 65 6c 73 65 20 64 4f 70 74  tions  else dOpt
6170: 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 6c 50 6f  ions.        lPo
6180: 69 6e 74 65 72 20 3d 20 5b 5d 0a 20 20 20 20 20  inter = [].     
6190: 20 20 20 62 43 68 61 6e 67 65 20 3d 20 46 61 6c     bChange = Fal
61a0: 73 65 0a 20 20 20 20 20 20 20 20 66 6f 72 20 64  se.        for d
61b0: 54 6f 6b 65 6e 20 69 6e 20 73 65 6c 66 2e 6c 54  Token in self.lT
61c0: 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20 20 20  oken:.          
61d0: 20 20 23 20 63 68 65 63 6b 20 61 72 63 73 20 66    # check arcs f
61e0: 6f 72 20 65 61 63 68 20 65 78 69 73 74 69 6e 67  or each existing
61f0: 20 70 6f 69 6e 74 65 72 0a 20 20 20 20 20 20 20   pointer.       
6200: 20 20 20 20 20 6c 4e 65 77 50 6f 69 6e 74 65 72       lNewPointer
6210: 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 20 20   = [].          
6220: 20 20 66 6f 72 20 69 2c 20 64 50 6f 69 6e 74 65    for i, dPointe
6230: 72 20 69 6e 20 65 6e 75 6d 65 72 61 74 65 28 6c  r in enumerate(l
6240: 50 6f 69 6e 74 65 72 29 3a 0a 20 20 20 20 20 20  Pointer):.      
6250: 20 20 20 20 20 20 20 20 20 20 62 56 61 6c 69 64            bValid
6260: 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20   = False.       
6270: 20 20 20 20 20 20 20 20 20 62 46 69 72 73 74 20           bFirst 
6280: 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20 20  = True.         
6290: 20 20 20 20 20 20 20 66 6f 72 20 64 4e 6f 64 65         for dNode
62a0: 20 69 6e 20 73 65 6c 66 2e 5f 67 65 74 4e 65 78   in self._getNex
62b0: 74 4d 61 74 63 68 69 6e 67 4e 6f 64 65 73 28 64  tMatchingNodes(d
62c0: 54 6f 6b 65 6e 2c 20 64 50 6f 69 6e 74 65 72 5b  Token, dPointer[
62d0: 22 64 4e 6f 64 65 22 5d 29 3a 0a 20 20 20 20 20  "dNode"]):.     
62e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
62f0: 66 20 62 46 69 72 73 74 3a 0a 20 20 20 20 20 20  f bFirst:.      
6300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6310: 20 20 64 50 6f 69 6e 74 65 72 5b 22 64 4e 6f 64    dPointer["dNod
6320: 65 22 5d 20 3d 20 64 4e 6f 64 65 0a 20 20 20 20  e"] = dNode.    
6330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6340: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
6350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e                lN
6360: 65 77 50 6f 69 6e 74 65 72 2e 61 70 70 65 6e 64  ewPointer.append
6370: 28 7b 22 6e 4f 66 66 73 65 74 22 3a 20 64 50 6f  ({"nOffset": dPo
6380: 69 6e 74 65 72 5b 22 6e 4f 66 66 73 65 74 22 5d  inter["nOffset"]
6390: 2c 20 22 64 4e 6f 64 65 22 3a 20 64 4e 6f 64 65  , "dNode": dNode
63a0: 7d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  }).             
63b0: 20 20 20 20 20 20 20 62 46 69 72 73 74 20 3d 20         bFirst = 
63c0: 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20  False.          
63d0: 20 20 20 20 20 20 20 20 20 20 62 56 61 6c 69 64            bValid
63e0: 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20   = True.        
63f0: 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 62          if not b
6400: 56 61 6c 69 64 3a 0a 20 20 20 20 20 20 20 20 20  Valid:.         
6410: 20 20 20 20 20 20 20 20 20 20 20 64 65 6c 20 6c             del l
6420: 50 6f 69 6e 74 65 72 5b 69 5d 0a 20 20 20 20 20  Pointer[i].     
6430: 20 20 20 20 20 20 20 6c 50 6f 69 6e 74 65 72 2e         lPointer.
6440: 65 78 74 65 6e 64 28 6c 4e 65 77 50 6f 69 6e 74  extend(lNewPoint
6450: 65 72 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  er).            
6460: 23 20 63 68 65 63 6b 20 61 72 63 73 20 6f 66 20  # check arcs of 
6470: 66 69 72 73 74 20 6e 6f 64 65 73 0a 20 20 20 20  first nodes.    
6480: 20 20 20 20 20 20 20 20 66 6f 72 20 64 4e 6f 64          for dNod
6490: 65 20 69 6e 20 73 65 6c 66 2e 5f 67 65 74 4e 65  e in self._getNe
64a0: 78 74 4d 61 74 63 68 69 6e 67 4e 6f 64 65 73 28  xtMatchingNodes(
64b0: 64 54 6f 6b 65 6e 2c 20 64 47 72 61 70 68 5b 30  dToken, dGraph[0
64c0: 5d 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ]):.            
64d0: 20 20 20 20 6c 50 6f 69 6e 74 65 72 2e 61 70 70      lPointer.app
64e0: 65 6e 64 28 7b 22 6e 4f 66 66 73 65 74 22 3a 20  end({"nOffset": 
64f0: 64 54 6f 6b 65 6e 5b 22 69 22 5d 2c 20 22 64 4e  dToken["i"], "dN
6500: 6f 64 65 22 3a 20 64 4e 6f 64 65 7d 29 0a 20 20  ode": dNode}).  
6510: 20 20 20 20 20 20 20 20 20 20 23 20 63 68 65 63            # chec
6520: 6b 20 69 66 20 74 68 65 72 65 20 69 73 20 72 75  k if there is ru
6530: 6c 65 73 20 74 6f 20 63 68 65 63 6b 20 66 6f 72  les to check for
6540: 20 65 61 63 68 20 70 6f 69 6e 74 65 72 0a 20 20   each pointer.  
6550: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 64 50            for dP
6560: 6f 69 6e 74 65 72 20 69 6e 20 6c 50 6f 69 6e 74  ointer in lPoint
6570: 65 72 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  er:.            
6580: 20 20 20 20 69 66 20 22 3c 72 75 6c 65 73 3e 22      if "<rules>"
6590: 20 69 6e 20 64 50 6f 69 6e 74 65 72 5b 22 64 4e   in dPointer["dN
65a0: 6f 64 65 22 5d 3a 0a 20 20 20 20 20 20 20 20 20  ode"]:.         
65b0: 20 20 20 20 20 20 20 20 20 20 20 62 48 61 73 43             bHasC
65c0: 68 61 6e 67 65 64 2c 20 65 72 72 73 20 3d 20 73  hanged, errs = s
65d0: 65 6c 66 2e 5f 65 78 65 63 75 74 65 41 63 74 69  elf._executeActi
65e0: 6f 6e 73 28 64 50 6f 69 6e 74 65 72 5b 22 64 4e  ons(dPointer["dN
65f0: 6f 64 65 22 5d 5b 22 3c 72 75 6c 65 73 3e 22 5d  ode"]["<rules>"]
6600: 2c 20 64 50 6f 69 6e 74 65 72 5b 22 6e 4f 66 66  , dPointer["nOff
6610: 73 65 74 22 5d 2d 31 2c 20 64 50 72 69 6f 72 69  set"]-1, dPriori
6620: 74 79 2c 20 64 4f 70 74 2c 20 73 43 6f 75 6e 74  ty, dOpt, sCount
6630: 72 79 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c  ry, bShowRuleId,
6640: 20 62 43 6f 6e 74 65 78 74 29 0a 20 20 20 20 20   bContext).     
6650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
6660: 45 72 72 2e 75 70 64 61 74 65 28 65 72 72 73 29  Err.update(errs)
6670: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6680: 20 20 20 20 20 69 66 20 62 48 61 73 43 68 61 6e       if bHasChan
6690: 67 65 64 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ged:.           
66a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 43 68               bCh
66b0: 61 6e 67 65 20 3d 20 54 72 75 65 0a 20 20 20 20  ange = True.    
66c0: 20 20 20 20 69 66 20 64 45 72 72 3a 0a 20 20 20      if dErr:.   
66d0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 64           print(d
66e0: 45 72 72 29 0a 20 20 20 20 20 20 20 20 72 65 74  Err).        ret
66f0: 75 72 6e 20 28 62 43 68 61 6e 67 65 2c 20 64 45  urn (bChange, dE
6700: 72 72 29 0a 0a 20 20 20 20 64 65 66 20 5f 65 78  rr)..    def _ex
6710: 65 63 75 74 65 41 63 74 69 6f 6e 73 20 28 73 65  ecuteActions (se
6720: 6c 66 2c 20 64 4e 6f 64 65 2c 20 6e 54 6f 6b 65  lf, dNode, nToke
6730: 6e 4f 66 66 73 65 74 2c 20 64 50 72 69 6f 72 69  nOffset, dPriori
6740: 74 79 2c 20 64 4f 70 74 2c 20 73 43 6f 75 6e 74  ty, dOpt, sCount
6750: 72 79 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c  ry, bShowRuleId,
6760: 20 62 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20   bContext):.    
6770: 20 20 20 20 23 70 72 69 6e 74 28 6c 6f 63 61 6c      #print(local
6780: 73 28 29 29 0a 20 20 20 20 20 20 20 20 64 45 72  s()).        dEr
6790: 72 73 20 3d 20 7b 7d 0a 20 20 20 20 20 20 20 20  rs = {}.        
67a0: 62 43 68 61 6e 67 65 20 3d 20 46 61 6c 73 65 0a  bChange = False.
67b0: 20 20 20 20 20 20 20 20 66 6f 72 20 73 4c 69 6e          for sLin
67c0: 65 49 64 2c 20 6e 65 78 74 4e 6f 64 65 4b 65 79  eId, nextNodeKey
67d0: 20 69 6e 20 64 4e 6f 64 65 2e 69 74 65 6d 73 28   in dNode.items(
67e0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  ):.            f
67f0: 6f 72 20 73 52 75 6c 65 49 64 20 69 6e 20 64 47  or sRuleId in dG
6800: 72 61 70 68 5b 6e 65 78 74 4e 6f 64 65 4b 65 79  raph[nextNodeKey
6810: 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]:.             
6820: 20 20 20 70 72 69 6e 74 28 73 52 75 6c 65 49 64     print(sRuleId
6830: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
6840: 20 20 62 43 6f 6e 64 4d 65 6d 6f 20 3d 20 4e 6f    bCondMemo = No
6850: 6e 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ne.             
6860: 20 20 20 73 46 75 6e 63 43 6f 6e 64 2c 20 63 41     sFuncCond, cA
6870: 63 74 69 6f 6e 54 79 70 65 2c 20 73 57 68 61 74  ctionType, sWhat
6880: 2c 20 2a 65 41 63 74 20 3d 20 64 52 75 6c 65 5b  , *eAct = dRule[
6890: 73 52 75 6c 65 49 64 5d 0a 20 20 20 20 20 20 20  sRuleId].       
68a0: 20 20 20 20 20 20 20 20 20 23 20 61 63 74 69 6f           # actio
68b0: 6e 20 69 6e 20 6c 41 63 74 69 6f 6e 73 3a 20 5b  n in lActions: [
68c0: 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 61 63 74 69   condition, acti
68d0: 6f 6e 20 74 79 70 65 2c 20 72 65 70 6c 61 63 65  on type, replace
68e0: 6d 65 6e 74 2f 73 75 67 67 65 73 74 69 6f 6e 2f  ment/suggestion/
68f0: 61 63 74 69 6f 6e 5b 2c 20 69 54 6f 6b 65 6e 53  action[, iTokenS
6900: 74 61 72 74 2c 20 69 54 6f 6b 65 6e 45 6e 64 5b  tart, iTokenEnd[
6910: 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 6d 65 73  , nPriority, mes
6920: 73 61 67 65 2c 20 55 52 4c 5d 5d 20 5d 0a 20 20  sage, URL]] ].  
6930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 72                tr
6940: 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  y:.             
6950: 20 20 20 20 20 20 20 62 43 6f 6e 64 4d 65 6d 6f         bCondMemo
6960: 20 3d 20 6e 6f 74 20 73 46 75 6e 63 43 6f 6e 64   = not sFuncCond
6970: 20 6f 72 20 67 6c 6f 62 61 6c 73 28 29 5b 73 46   or globals()[sF
6980: 75 6e 63 43 6f 6e 64 5d 28 73 65 6c 66 2e 6c 54  uncCond](self.lT
6990: 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73  oken, nTokenOffs
69a0: 65 74 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43  et, sCountry, bC
69b0: 6f 6e 64 4d 65 6d 6f 29 0a 20 20 20 20 20 20 20  ondMemo).       
69c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
69d0: 62 43 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20 20  bCondMemo:.     
69e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69f0: 20 20 20 69 66 20 63 41 63 74 69 6f 6e 54 79 70     if cActionTyp
6a00: 65 20 3d 3d 20 22 2d 22 3a 0a 20 20 20 20 20 20  e == "-":.      
6a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a20: 20 20 20 20 20 20 23 20 67 72 61 6d 6d 61 72 20        # grammar 
6a30: 65 72 72 6f 72 0a 20 20 20 20 20 20 20 20 20 20  error.          
6a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a50: 20 20 70 72 69 6e 74 28 22 2d 22 29 0a 20 20 20    print("-").   
6a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a70: 20 20 20 20 20 20 20 20 20 6e 54 6f 6b 65 6e 45           nTokenE
6a80: 72 72 6f 72 53 74 61 72 74 20 3d 20 6e 54 6f 6b  rrorStart = nTok
6a90: 65 6e 4f 66 66 73 65 74 20 2b 20 65 41 63 74 5b  enOffset + eAct[
6aa0: 30 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  0].             
6ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e                 n
6ac0: 54 6f 6b 65 6e 45 72 72 6f 72 45 6e 64 20 3d 20  TokenErrorEnd = 
6ad0: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65  nTokenOffset + e
6ae0: 41 63 74 5b 31 5d 0a 20 20 20 20 20 20 20 20 20  Act[1].         
6af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b00: 20 20 20 6e 45 72 72 6f 72 53 74 61 72 74 20 3d     nErrorStart =
6b10: 20 73 65 6c 66 2e 69 53 74 61 72 74 20 2b 20 73   self.iStart + s
6b20: 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65  elf.lToken[nToke
6b30: 6e 45 72 72 6f 72 53 74 61 72 74 5d 5b 22 6e 53  nErrorStart]["nS
6b40: 74 61 72 74 22 5d 0a 20 20 20 20 20 20 20 20 20  tart"].         
6b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b60: 20 20 20 6e 45 72 72 6f 72 45 6e 64 20 3d 20 73     nErrorEnd = s
6b70: 65 6c 66 2e 69 53 74 61 72 74 20 2b 20 73 65 6c  elf.iStart + sel
6b80: 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 45  f.lToken[nTokenE
6b90: 72 72 6f 72 45 6e 64 5d 5b 22 6e 45 6e 64 22 5d  rrorEnd]["nEnd"]
6ba0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
6bc0: 6e 45 72 72 6f 72 53 74 61 72 74 20 6e 6f 74 20  nErrorStart not 
6bd0: 69 6e 20 64 45 72 72 73 20 6f 72 20 65 41 63 74  in dErrs or eAct
6be0: 5b 32 5d 20 3e 20 64 50 72 69 6f 72 69 74 79 5b  [2] > dPriority[
6bf0: 6e 45 72 72 6f 72 53 74 61 72 74 5d 3a 0a 20 20  nErrorStart]:.  
6c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 45                dE
6c20: 72 72 73 5b 6e 45 72 72 6f 72 53 74 61 72 74 5d  rrs[nErrorStart]
6c30: 20 3d 20 5f 63 72 65 61 74 65 54 6f 6b 65 6e 45   = _createTokenE
6c40: 72 72 6f 72 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e  rror(self.lToken
6c50: 2c 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65  , self.sSentence
6c60: 2c 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65  , self.sSentence
6c70: 30 2c 20 73 57 68 61 74 2c 20 6e 54 6f 6b 65 6e  0, sWhat, nToken
6c80: 45 72 72 6f 72 53 74 61 72 74 2c 20 6e 45 72 72  ErrorStart, nErr
6c90: 6f 72 53 74 61 72 74 2c 20 6e 45 72 72 6f 72 45  orStart, nErrorE
6ca0: 6e 64 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75  nd, sLineId, sRu
6cb0: 6c 65 49 64 2c 20 54 72 75 65 2c 20 65 41 63 74  leId, True, eAct
6cc0: 5b 33 5d 2c 20 65 41 63 74 5b 34 5d 2c 20 62 53  [3], eAct[4], bS
6cd0: 68 6f 77 52 75 6c 65 49 64 2c 20 22 6e 6f 74 79  howRuleId, "noty
6ce0: 70 65 22 2c 20 62 43 6f 6e 74 65 78 74 29 0a 20  pe", bContext). 
6cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
6d10: 50 72 69 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53  Priority[nErrorS
6d20: 74 61 72 74 5d 20 3d 20 65 41 63 74 5b 32 5d 0a  tart] = eAct[2].
6d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d40: 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 41 63          elif cAc
6d50: 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 7e 22 3a  tionType == "~":
6d60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 74               # t
6d80: 65 78 74 20 70 72 6f 63 65 73 73 6f 72 0a 20 20  ext processor.  
6d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6da0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
6db0: 22 7e 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  "~").           
6dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dd0: 20 73 65 6c 66 2e 5f 72 65 77 72 69 74 65 28 73   self._rewrite(s
6de0: 57 68 61 74 2c 20 6e 45 72 72 6f 72 53 74 61 72  What, nErrorStar
6df0: 74 2c 20 6e 45 72 72 6f 72 45 6e 64 29 0a 20 20  t, nErrorEnd).  
6e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e10: 20 20 20 20 20 20 65 6c 69 66 20 63 41 63 74 69        elif cActi
6e20: 6f 6e 54 79 70 65 20 3d 3d 20 22 40 22 3a 0a 20  onType == "@":. 
6e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e40: 20 20 20 20 20 20 20 20 20 20 20 23 20 6a 75 6d             # jum
6e50: 70 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p.              
6e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
6e70: 69 6e 74 28 22 40 22 29 0a 20 20 20 20 20 20 20  int("@").       
6e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e90: 20 20 20 20 20 73 65 6c 66 2e 5f 6a 75 6d 70 28       self._jump(
6ea0: 73 57 68 61 74 29 0a 20 20 20 20 20 20 20 20 20  sWhat).         
6eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
6ec0: 6c 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20  lif cActionType 
6ed0: 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20  == "=":.        
6ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ef0: 20 20 20 20 23 20 64 69 73 61 6d 62 69 67 75 61      # disambigua
6f00: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tion.           
6f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f20: 20 70 72 69 6e 74 28 22 3d 22 29 0a 20 20 20 20   print("=").    
6f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f40: 20 20 20 20 20 20 20 20 67 6c 6f 62 61 6c 73 28          globals(
6f50: 29 5b 73 57 68 61 74 5d 28 73 65 6c 66 2e 6c 54  )[sWhat](self.lT
6f60: 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20 20 20 20  oken).          
6f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
6f80: 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d  if cActionType =
6f90: 3d 20 22 3e 22 3a 0a 20 20 20 20 20 20 20 20 20  = ">":.         
6fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6fb0: 20 20 20 23 20 77 65 20 64 6f 20 6e 6f 74 68 69     # we do nothi
6fc0: 6e 67 2c 20 74 68 69 73 20 74 65 73 74 20 69 73  ng, this test is
6fd0: 20 6a 75 73 74 20 61 20 63 6f 6e 64 69 74 69 6f   just a conditio
6fe0: 6e 20 74 6f 20 61 70 70 6c 79 20 61 6c 6c 20 66  n to apply all f
6ff0: 6f 6c 6c 6f 77 69 6e 67 20 61 63 74 69 6f 6e 73  ollowing actions
7000: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7010: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
7020: 6e 74 28 22 3e 22 29 0a 20 20 20 20 20 20 20 20  nt(">").        
7030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7040: 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 20 20      pass.       
7050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7060: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
7070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7080: 20 20 20 70 72 69 6e 74 28 22 23 20 65 72 72 6f     print("# erro
7090: 72 3a 20 75 6e 6b 6e 6f 77 6e 20 61 63 74 69 6f  r: unknown actio
70a0: 6e 20 61 74 20 22 20 2b 20 73 4c 69 6e 65 49 64  n at " + sLineId
70b0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
70c0: 20 20 20 20 20 20 65 6c 69 66 20 63 41 63 74 69        elif cActi
70d0: 6f 6e 54 79 70 65 20 3d 3d 20 22 3e 22 3a 0a 20  onType == ">":. 
70e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70f0: 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20 20         break.   
7100: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 78 63               exc
7110: 65 70 74 20 45 78 63 65 70 74 69 6f 6e 20 61 73  ept Exception as
7120: 20 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20   e:.            
7130: 20 20 20 20 20 20 20 20 72 61 69 73 65 20 45 78          raise Ex
7140: 63 65 70 74 69 6f 6e 28 73 74 72 28 65 29 2c 20  ception(str(e), 
7150: 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20  sLineId).       
7160: 20 72 65 74 75 72 6e 20 62 43 68 61 6e 67 65 2c   return bChange,
7170: 20 64 45 72 72 73 0a 0a 20 20 20 20 64 65 66 20   dErrs..    def 
7180: 5f 72 65 77 72 69 74 65 20 28 73 65 6c 66 2c 20  _rewrite (self, 
7190: 73 57 68 61 74 2c 20 6e 45 72 72 6f 72 53 74 61  sWhat, nErrorSta
71a0: 72 74 2c 20 6e 45 72 72 6f 72 45 6e 64 29 3a 0a  rt, nErrorEnd):.
71b0: 20 20 20 20 20 20 20 20 22 74 65 78 74 20 70 72          "text pr
71c0: 6f 63 65 73 73 6f 72 3a 20 72 65 77 72 69 74 65  ocessor: rewrite
71d0: 20 74 6f 6b 65 6e 73 20 62 65 74 77 65 65 6e 20   tokens between 
71e0: 3c 6e 45 72 72 6f 72 53 74 61 72 74 3e 20 61 6e  <nErrorStart> an
71f0: 64 20 3c 6e 45 72 72 6f 72 45 6e 64 3e 20 70 6f  d <nErrorEnd> po
7200: 73 69 74 69 6f 6e 22 0a 20 20 20 20 20 20 20 20  sition".        
7210: 6c 54 6f 6b 65 6e 56 61 6c 75 65 20 3d 20 73 57  lTokenValue = sW
7220: 68 61 74 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20  hat.split("|"). 
7230: 20 20 20 20 20 20 20 69 66 20 6c 65 6e 28 6c 54         if len(lT
7240: 6f 6b 65 6e 56 61 6c 75 65 29 20 21 3d 20 28 6e  okenValue) != (n
7250: 45 72 72 6f 72 45 6e 64 20 2d 20 6e 45 72 72 6f  ErrorEnd - nErro
7260: 72 53 74 61 72 74 20 2b 20 31 29 3a 0a 20 20 20  rStart + 1):.   
7270: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
7280: 45 72 72 6f 72 2e 20 54 65 78 74 20 70 72 6f 63  Error. Text proc
7290: 65 73 73 6f 72 3a 20 6e 75 6d 62 65 72 20 6f 66  essor: number of
72a0: 20 72 65 70 6c 61 63 65 6d 65 6e 74 73 20 21 3d   replacements !=
72b0: 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e   number of token
72c0: 73 2e 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  s.").           
72d0: 20 72 65 74 75 72 6e 0a 20 20 20 20 20 20 20 20   return.        
72e0: 66 6f 72 20 69 2c 20 73 56 61 6c 75 65 20 69 6e  for i, sValue in
72f0: 20 7a 69 70 28 72 61 6e 67 65 28 6e 45 72 72 6f   zip(range(nErro
7300: 72 53 74 61 72 74 2c 20 6e 45 72 72 6f 72 45 6e  rStart, nErrorEn
7310: 64 2b 31 29 2c 20 6c 54 6f 6b 65 6e 56 61 6c 75  d+1), lTokenValu
7320: 65 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  e):.            
7330: 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 5d 5b 22  self.lToken[i]["
7340: 73 56 61 6c 75 65 22 5d 20 3d 20 73 56 61 6c 75  sValue"] = sValu
7350: 65 0a 0a 20 20 20 20 64 65 66 20 5f 6a 75 6d 70  e..    def _jump
7360: 20 28 73 65 6c 66 2c 20 73 57 68 61 74 29 3a 0a   (self, sWhat):.
7370: 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20          try:.   
7380: 20 20 20 20 20 20 20 20 20 6e 46 72 6f 6d 2c 20           nFrom, 
7390: 6e 54 6f 20 3d 20 73 57 68 61 74 2e 73 70 6c 69  nTo = sWhat.spli
73a0: 74 28 22 3e 22 29 0a 20 20 20 20 20 20 20 20 20  t(">").         
73b0: 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69     self.lToken[i
73c0: 6e 74 28 6e 46 72 6f 6d 29 5d 5b 22 69 4a 75 6d  nt(nFrom)]["iJum
73d0: 70 22 5d 20 3d 20 69 6e 74 28 6e 54 6f 29 0a 20  p"] = int(nTo). 
73e0: 20 20 20 20 20 20 20 65 78 63 65 70 74 3a 0a 20         except:. 
73f0: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
7400: 28 22 23 20 45 72 72 6f 72 2e 20 4a 75 6d 70 20  ("# Error. Jump 
7410: 66 61 69 6c 65 64 3a 20 22 2c 20 73 57 68 61 74  failed: ", sWhat
7420: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 74 72  ).            tr
7430: 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78  aceback.print_ex
7440: 63 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  c().            
7450: 72 65 74 75 72 6e 0a 0a 0a 23 23 23 23 20 41 6e  return...#### An
7460: 61 6c 79 73 65 20 74 6f 6b 65 6e 73 0a 0a 64 65  alyse tokens..de
7470: 66 20 67 5f 6d 6f 72 70 68 20 28 64 54 6f 6b 65  f g_morph (dToke
7480: 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20 62 53 74  n, sPattern, bSt
7490: 72 69 63 74 3d 54 72 75 65 29 3a 0a 20 20 20 20  rict=True):.    
74a0: 22 61 6e 61 6c 79 73 65 20 61 20 74 6f 6b 65 6e  "analyse a token
74b0: 2c 20 72 65 74 75 72 6e 20 54 72 75 65 20 69 66  , return True if
74c0: 20 3c 73 50 61 74 74 65 72 6e 3e 20 69 6e 20 6d   <sPattern> in m
74d0: 6f 72 70 68 6f 6c 6f 67 69 65 73 22 0a 20 20 20  orphologies".   
74e0: 20 69 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20   if "lMorph" in 
74f0: 64 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20  dToken:.        
7500: 6c 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e 5b  lMorph = dToken[
7510: 22 6c 4d 6f 72 70 68 22 5d 0a 20 20 20 20 65 6c  "lMorph"].    el
7520: 73 65 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72  se:.        lMor
7530: 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63  ph = _oSpellChec
7540: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f  ker.getMorph(dTo
7550: 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20  ken["sValue"]). 
7560: 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d         if not lM
7570: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20  orph:.          
7580: 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 20    return False. 
7590: 20 20 20 7a 50 61 74 74 65 72 6e 20 3d 20 72 65     zPattern = re
75a0: 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72  .compile(sPatter
75b0: 6e 29 0a 20 20 20 20 69 66 20 62 53 74 72 69 63  n).    if bStric
75c0: 74 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  t:.        retur
75d0: 6e 20 61 6c 6c 28 7a 50 61 74 74 65 72 6e 2e 73  n all(zPattern.s
75e0: 65 61 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66  earch(sMorph)  f
75f0: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f  or sMorph in lMo
7600: 72 70 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20  rph).    return 
7610: 61 6e 79 28 7a 50 61 74 74 65 72 6e 2e 73 65 61  any(zPattern.sea
7620: 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72  rch(sMorph)  for
7630: 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70   sMorph in lMorp
7640: 68 29 0a 0a 64 65 66 20 67 5f 6d 6f 72 70 68 65  h)..def g_morphe
7650: 78 20 28 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74  x (dToken, sPatt
7660: 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65 72 6e  ern, sNegPattern
7670: 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20  ):.    "analyse 
7680: 61 20 74 6f 6b 65 6e 2c 20 72 65 74 75 72 6e 20  a token, return 
7690: 54 72 75 65 20 69 66 20 3c 73 4e 65 67 50 61 74  True if <sNegPat
76a0: 74 65 72 6e 3e 20 6e 6f 74 20 69 6e 20 6d 6f 72  tern> not in mor
76b0: 70 68 6f 6c 6f 67 69 65 73 20 61 6e 64 20 3c 73  phologies and <s
76c0: 50 61 74 74 65 72 6e 3e 20 69 6e 20 6d 6f 72 70  Pattern> in morp
76d0: 68 6f 6c 6f 67 69 65 73 22 0a 20 20 20 20 69 66  hologies".    if
76e0: 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f   "lMorph" in dTo
76f0: 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f  ken:.        lMo
7700: 72 70 68 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d  rph = dToken["lM
7710: 6f 72 70 68 22 5d 0a 20 20 20 20 65 6c 73 65 3a  orph"].    else:
7720: 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72 70 68 20  .        lMorph 
7730: 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  = _oSpellChecker
7740: 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e  .getMorph(dToken
7750: 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20  ["sValue"]).    
7760: 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70      if not lMorp
7770: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  h:.            r
7780: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
7790: 23 20 63 68 65 63 6b 20 6e 65 67 61 74 69 76 65  # check negative
77a0: 20 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 7a   condition.    z
77b0: 4e 65 67 50 61 74 74 65 72 6e 20 3d 20 72 65 2e  NegPattern = re.
77c0: 63 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61 74 74  compile(sNegPatt
77d0: 65 72 6e 29 0a 20 20 20 20 69 66 20 61 6e 79 28  ern).    if any(
77e0: 7a 4e 65 67 50 61 74 74 65 72 6e 2e 73 65 61 72  zNegPattern.sear
77f0: 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72 20  ch(sMorph)  for 
7800: 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68  sMorph in lMorph
7810: 29 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ):.        retur
7820: 6e 20 46 61 6c 73 65 0a 20 20 20 20 23 20 73 65  n False.    # se
7830: 61 72 63 68 20 73 50 61 74 74 65 72 6e 0a 20 20  arch sPattern.  
7840: 20 20 7a 50 61 74 74 65 72 6e 20 3d 20 72 65 2e    zPattern = re.
7850: 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e  compile(sPattern
7860: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79  ).    return any
7870: 28 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68  (zPattern.search
7880: 28 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d  (sMorph)  for sM
7890: 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 0a  orph in lMorph).
78a0: 0a 64 65 66 20 67 5f 61 6e 61 6c 79 73 65 20 28  .def g_analyse (
78b0: 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e  dToken, sPattern
78c0: 2c 20 62 53 74 72 69 63 74 3d 54 72 75 65 29 3a  , bStrict=True):
78d0: 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20  .    "analyse a 
78e0: 74 6f 6b 65 6e 2c 20 72 65 74 75 72 6e 20 54 72  token, return Tr
78f0: 75 65 20 69 66 20 3c 73 50 61 74 74 65 72 6e 3e  ue if <sPattern>
7900: 20 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73   in morphologies
7910: 20 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e   (disambiguation
7920: 20 6f 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70   off)".    lMorp
7930: 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b  h = _oSpellCheck
7940: 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b  er.getMorph(dTok
7950: 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20  en["sValue"]).  
7960: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a    if not lMorph:
7970: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
7980: 46 61 6c 73 65 0a 20 20 20 20 7a 50 61 74 74 65  False.    zPatte
7990: 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28  rn = re.compile(
79a0: 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66  sPattern).    if
79b0: 20 62 53 74 72 69 63 74 3a 0a 20 20 20 20 20 20   bStrict:.      
79c0: 20 20 72 65 74 75 72 6e 20 61 6c 6c 28 7a 50 61    return all(zPa
79d0: 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f  ttern.search(sMo
79e0: 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68  rph)  for sMorph
79f0: 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 20 20 20 20   in lMorph).    
7a00: 72 65 74 75 72 6e 20 61 6e 79 28 7a 50 61 74 74  return any(zPatt
7a10: 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70  ern.search(sMorp
7a20: 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69  h)  for sMorph i
7a30: 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 64 65 66 20  n lMorph)...def 
7a40: 67 5f 61 6e 61 6c 79 73 65 78 20 28 64 54 6f 6b  g_analysex (dTok
7a50: 65 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e  en, sPattern, sN
7a60: 65 67 50 61 74 74 65 72 6e 29 3a 0a 20 20 20 20  egPattern):.    
7a70: 22 61 6e 61 6c 79 73 65 20 61 20 74 6f 6b 65 6e  "analyse a token
7a80: 2c 20 72 65 74 75 72 6e 20 54 72 75 65 20 69 66  , return True if
7a90: 20 3c 73 4e 65 67 50 61 74 74 65 72 6e 3e 20 6e   <sNegPattern> n
7aa0: 6f 74 20 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69  ot in morphologi
7ab0: 65 73 20 61 6e 64 20 3c 73 50 61 74 74 65 72 6e  es and <sPattern
7ac0: 3e 20 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65  > in morphologie
7ad0: 73 20 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f  s (disambiguatio
7ae0: 6e 20 6f 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72  n off)".    lMor
7af0: 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63  ph = _oSpellChec
7b00: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f  ker.getMorph(dTo
7b10: 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20  ken["sValue"]). 
7b20: 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68     if not lMorph
7b30: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
7b40: 20 46 61 6c 73 65 0a 20 20 20 20 23 20 63 68 65   False.    # che
7b50: 63 6b 20 6e 65 67 61 74 69 76 65 20 63 6f 6e 64  ck negative cond
7b60: 69 74 69 6f 6e 0a 20 20 20 20 7a 4e 65 67 50 61  ition.    zNegPa
7b70: 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69  ttern = re.compi
7b80: 6c 65 28 73 4e 65 67 50 61 74 74 65 72 6e 29 0a  le(sNegPattern).
7b90: 20 20 20 20 69 66 20 61 6e 79 28 7a 4e 65 67 50      if any(zNegP
7ba0: 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73 4d  attern.search(sM
7bb0: 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70  orph)  for sMorp
7bc0: 68 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20  h in lMorph):.  
7bd0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c        return Fal
7be0: 73 65 0a 20 20 20 20 23 20 73 65 61 72 63 68 20  se.    # search 
7bf0: 73 50 61 74 74 65 72 6e 0a 20 20 20 20 7a 50 61  sPattern.    zPa
7c00: 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69  ttern = re.compi
7c10: 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20  le(sPattern).   
7c20: 20 72 65 74 75 72 6e 20 61 6e 79 28 7a 50 61 74   return any(zPat
7c30: 74 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72  tern.search(sMor
7c40: 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20  ph)  for sMorph 
7c50: 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 0a 23 23  in lMorph)....##
7c60: 23 23 20 44 69 73 61 6d 62 69 67 75 61 74 6f 72  ## Disambiguator
7c70: 0a 0a 64 65 66 20 67 5f 73 65 6c 65 63 74 20 28  ..def g_select (
7c80: 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e  dToken, sPattern
7c90: 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f 6e 65 29  , lDefault=None)
7ca0: 3a 0a 20 20 20 20 22 73 65 6c 65 63 74 20 6d 6f  :.    "select mo
7cb0: 72 70 68 6f 6c 6f 67 69 65 73 20 66 6f 72 20 3c  rphologies for <
7cc0: 64 54 6f 6b 65 6e 3e 20 61 63 63 6f 72 64 69 6e  dToken> accordin
7cd0: 67 20 74 6f 20 3c 73 50 61 74 74 65 72 6e 3e 2c  g to <sPattern>,
7ce0: 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e 20 54   always return T
7cf0: 72 75 65 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20  rue".    lMorph 
7d00: 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68  = dToken["lMorph
7d10: 22 5d 20 20 69 66 20 22 6c 4d 6f 72 70 68 22 20  "]  if "lMorph" 
7d20: 69 6e 20 64 54 6f 6b 65 6e 20 20 65 6c 73 65 20  in dToken  else 
7d30: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
7d40: 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22  etMorph(dToken["
7d50: 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 69 66  sValue"]).    if
7d60: 20 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c   not lMorph or l
7d70: 65 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a  en(lMorph) == 1:
7d80: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
7d90: 54 72 75 65 0a 20 20 20 20 6c 53 65 6c 65 63 74  True.    lSelect
7da0: 20 3d 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72   = [ sMorph  for
7db0: 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70   sMorph in lMorp
7dc0: 68 20 20 69 66 20 72 65 2e 73 65 61 72 63 68 28  h  if re.search(
7dd0: 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68  sPattern, sMorph
7de0: 29 20 5d 0a 20 20 20 20 69 66 20 6c 53 65 6c 65  ) ].    if lSele
7df0: 63 74 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c  ct:.        if l
7e00: 65 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c  en(lSelect) != l
7e10: 65 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20  en(lMorph):.    
7e20: 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22          dToken["
7e30: 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 53 65 6c 65  lMorph"] = lSele
7e40: 63 74 0a 20 20 20 20 65 6c 69 66 20 6c 44 65 66  ct.    elif lDef
7e50: 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 64 54  ault:.        dT
7e60: 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d  oken["lMorph"] =
7e70: 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20 72 65   lDefault.    re
7e80: 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20  turn True...def 
7e90: 67 5f 65 78 63 6c 75 64 65 20 28 64 54 6f 6b 65  g_exclude (dToke
7ea0: 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20 6c 44 65  n, sPattern, lDe
7eb0: 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20  fault=None):.   
7ec0: 20 22 73 65 6c 65 63 74 20 6d 6f 72 70 68 6f 6c   "select morphol
7ed0: 6f 67 69 65 73 20 66 6f 72 20 3c 64 54 6f 6b 65  ogies for <dToke
7ee0: 6e 3e 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20  n> according to 
7ef0: 3c 73 50 61 74 74 65 72 6e 3e 2c 20 61 6c 77 61  <sPattern>, alwa
7f00: 79 73 20 72 65 74 75 72 6e 20 54 72 75 65 22 0a  ys return True".
7f10: 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 64 54 6f      lMorph = dTo
7f20: 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 20 69  ken["lMorph"]  i
7f30: 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54  f "lMorph" in dT
7f40: 6f 6b 65 6e 20 20 65 6c 73 65 20 5f 6f 53 70 65  oken  else _oSpe
7f50: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
7f60: 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ph(dToken["sValu
7f70: 65 22 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  e"]).    if not 
7f80: 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e 28 6c 4d  lMorph or len(lM
7f90: 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20 20 20 20  orph) == 1:.    
7fa0: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
7fb0: 20 20 20 20 6c 53 65 6c 65 63 74 20 3d 20 5b 20      lSelect = [ 
7fc0: 73 4d 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72  sMorph  for sMor
7fd0: 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20 20 69 66  ph in lMorph  if
7fe0: 20 6e 6f 74 20 72 65 2e 73 65 61 72 63 68 28 73   not re.search(s
7ff0: 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29  Pattern, sMorph)
8000: 20 5d 0a 20 20 20 20 69 66 20 6c 53 65 6c 65 63   ].    if lSelec
8010: 74 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c 65  t:.        if le
8020: 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c 65  n(lSelect) != le
8030: 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20  n(lMorph):.     
8040: 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c         dToken["l
8050: 4d 6f 72 70 68 22 5d 20 3d 20 6c 53 65 6c 65 63  Morph"] = lSelec
8060: 74 0a 20 20 20 20 65 6c 69 66 20 6c 44 65 66 61  t.    elif lDefa
8070: 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 64 54 6f  ult:.        dTo
8080: 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20  ken["lMorph"] = 
8090: 6c 44 65 66 61 75 6c 74 0a 20 20 20 20 72 65 74  lDefault.    ret
80a0: 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20 67  urn True...def g
80b0: 5f 64 65 66 69 6e 65 20 28 64 54 6f 6b 65 6e 2c  _define (dToken,
80c0: 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 22 73   lMorph):.    "s
80d0: 65 74 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20  et morphologies 
80e0: 6f 66 20 3c 64 54 6f 6b 65 6e 3e 2c 20 61 6c 77  of <dToken>, alw
80f0: 61 79 73 20 72 65 74 75 72 6e 20 54 72 75 65 22  ays return True"
8100: 0a 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f  .    dToken["lMo
8110: 72 70 68 22 5d 20 3d 20 6c 4d 6f 72 70 68 0a 20  rph"] = lMorph. 
8120: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a     return True..
8130: 0a 23 23 23 23 20 43 41 4c 4c 41 42 4c 45 53 20  .#### CALLABLES 
8140: 28 67 65 6e 65 72 61 74 65 64 20 63 6f 64 65 29  (generated code)
8150: 0a 0a 24 7b 67 72 61 70 68 5f 63 61 6c 6c 61 62  ..${graph_callab
8160: 6c 65 73 7d 0a                                   les}.