Grammalecte  Hex Artifact Content

Artifact d669c0fe4f0449756e3523f8e002332720e89593133d28c090ca22cc80fe278e:


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 2c 20 73 52 65 70 6c 2c 20 69 47 72 6f   (s, sRepl, iGro
3110: 75 70 2c 20 6d 2c 20 62 55 70 70 65 72 63 61 73  up, m, bUppercas
3120: 65 29 3a 0a 20 20 20 20 22 74 65 78 74 20 70 72  e):.    "text pr
3130: 6f 63 65 73 73 6f 72 3a 20 77 72 69 74 65 20 73  ocessor: write s
3140: 52 65 70 6c 20 69 6e 20 73 20 61 74 20 69 47 72  Repl in s at iGr
3150: 6f 75 70 20 70 6f 73 69 74 69 6f 6e 22 0a 20 20  oup position".  
3160: 20 20 6e 4c 65 6e 20 3d 20 6d 2e 65 6e 64 28 69    nLen = m.end(i
3170: 47 72 6f 75 70 29 20 2d 20 6d 2e 73 74 61 72 74  Group) - m.start
3180: 28 69 47 72 6f 75 70 29 0a 20 20 20 20 69 66 20  (iGroup).    if 
3190: 73 52 65 70 6c 20 3d 3d 20 22 2a 22 3a 0a 20 20  sRepl == "*":.  
31a0: 20 20 20 20 20 20 73 4e 65 77 20 3d 20 22 20 22        sNew = " "
31b0: 20 2a 20 6e 4c 65 6e 0a 20 20 20 20 65 6c 69 66   * nLen.    elif
31c0: 20 73 52 65 70 6c 20 3d 3d 20 22 3e 22 20 6f 72   sRepl == ">" or
31d0: 20 73 52 65 70 6c 20 3d 3d 20 22 5f 22 20 6f 72   sRepl == "_" or
31e0: 20 73 52 65 70 6c 20 3d 3d 20 22 7e 22 3a 0a 20   sRepl == "~":. 
31f0: 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20 73 52         sNew = sR
3200: 65 70 6c 20 2b 20 22 20 22 20 2a 20 28 6e 4c 65  epl + " " * (nLe
3210: 6e 2d 31 29 0a 20 20 20 20 65 6c 69 66 20 73 52  n-1).    elif sR
3220: 65 70 6c 20 3d 3d 20 22 40 22 3a 0a 20 20 20 20  epl == "@":.    
3230: 20 20 20 20 73 4e 65 77 20 3d 20 22 40 22 20 2a      sNew = "@" *
3240: 20 6e 4c 65 6e 0a 20 20 20 20 65 6c 69 66 20 73   nLen.    elif s
3250: 52 65 70 6c 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22  Repl[0:1] == "="
3260: 3a 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d  :.        sNew =
3270: 20 67 6c 6f 62 61 6c 73 28 29 5b 73 52 65 70 6c   globals()[sRepl
3280: 5b 31 3a 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20  [1:]](s, m).    
3290: 20 20 20 20 73 4e 65 77 20 3d 20 73 4e 65 77 20      sNew = sNew 
32a0: 2b 20 22 20 22 20 2a 20 28 6e 4c 65 6e 2d 6c 65  + " " * (nLen-le
32b0: 6e 28 73 4e 65 77 29 29 0a 20 20 20 20 20 20 20  n(sNew)).       
32c0: 20 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61   if bUppercase a
32d0: 6e 64 20 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75  nd m.group(iGrou
32e0: 70 29 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28  p)[0:1].isupper(
32f0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ):.            s
3300: 4e 65 77 20 3d 20 73 4e 65 77 2e 63 61 70 69 74  New = sNew.capit
3310: 61 6c 69 7a 65 28 29 0a 20 20 20 20 65 6c 73 65  alize().    else
3320: 3a 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d  :.        sNew =
3330: 20 6d 2e 65 78 70 61 6e 64 28 73 52 65 70 6c 29   m.expand(sRepl)
3340: 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20  .        sNew = 
3350: 73 4e 65 77 20 2b 20 22 20 22 20 2a 20 28 6e 4c  sNew + " " * (nL
3360: 65 6e 2d 6c 65 6e 28 73 4e 65 77 29 29 0a 20 20  en-len(sNew)).  
3370: 20 20 72 65 74 75 72 6e 20 73 5b 30 3a 6d 2e 73    return s[0:m.s
3380: 74 61 72 74 28 69 47 72 6f 75 70 29 5d 20 2b 20  tart(iGroup)] + 
3390: 73 4e 65 77 20 2b 20 73 5b 6d 2e 65 6e 64 28 69  sNew + s[m.end(i
33a0: 47 72 6f 75 70 29 3a 5d 0a 0a 0a 64 65 66 20 69  Group):]...def i
33b0: 67 6e 6f 72 65 52 75 6c 65 20 28 73 52 75 6c 65  gnoreRule (sRule
33c0: 49 64 29 3a 0a 20 20 20 20 5f 61 49 67 6e 6f 72  Id):.    _aIgnor
33d0: 65 64 52 75 6c 65 73 2e 61 64 64 28 73 52 75 6c  edRules.add(sRul
33e0: 65 49 64 29 0a 0a 0a 64 65 66 20 72 65 73 65 74  eId)...def reset
33f0: 49 67 6e 6f 72 65 52 75 6c 65 73 20 28 29 3a 0a  IgnoreRules ():.
3400: 20 20 20 20 5f 61 49 67 6e 6f 72 65 64 52 75 6c      _aIgnoredRul
3410: 65 73 2e 63 6c 65 61 72 28 29 0a 0a 0a 64 65 66  es.clear()...def
3420: 20 72 65 61 63 74 69 76 61 74 65 52 75 6c 65 20   reactivateRule 
3430: 28 73 52 75 6c 65 49 64 29 3a 0a 20 20 20 20 5f  (sRuleId):.    _
3440: 61 49 67 6e 6f 72 65 64 52 75 6c 65 73 2e 64 69  aIgnoredRules.di
3450: 73 63 61 72 64 28 73 52 75 6c 65 49 64 29 0a 0a  scard(sRuleId)..
3460: 0a 64 65 66 20 6c 69 73 74 52 75 6c 65 73 20 28  .def listRules (
3470: 73 46 69 6c 74 65 72 3d 4e 6f 6e 65 29 3a 0a 20  sFilter=None):. 
3480: 20 20 20 22 67 65 6e 65 72 61 74 6f 72 3a 20 72     "generator: r
3490: 65 74 75 72 6e 73 20 74 79 70 6c 65 20 28 73 4f  eturns typle (sO
34a0: 70 74 69 6f 6e 2c 20 73 4c 69 6e 65 49 64 2c 20  ption, sLineId, 
34b0: 73 52 75 6c 65 49 64 29 22 0a 20 20 20 20 69 66  sRuleId)".    if
34c0: 20 73 46 69 6c 74 65 72 3a 0a 20 20 20 20 20 20   sFilter:.      
34d0: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20    try:.         
34e0: 20 20 20 7a 46 69 6c 74 65 72 20 3d 20 72 65 2e     zFilter = re.
34f0: 63 6f 6d 70 69 6c 65 28 73 46 69 6c 74 65 72 29  compile(sFilter)
3500: 0a 20 20 20 20 20 20 20 20 65 78 63 65 70 74 3a  .        except:
3510: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 63 68  .            ech
3520: 6f 28 22 23 20 45 72 72 6f 72 2e 20 4c 69 73 74  o("# Error. List
3530: 20 72 75 6c 65 73 3a 20 77 72 6f 6e 67 20 72 65   rules: wrong re
3540: 67 65 78 2e 22 29 0a 20 20 20 20 20 20 20 20 20  gex.").         
3550: 20 20 20 73 46 69 6c 74 65 72 20 3d 20 4e 6f 6e     sFilter = Non
3560: 65 0a 20 20 20 20 66 6f 72 20 73 4f 70 74 69 6f  e.    for sOptio
3570: 6e 2c 20 6c 52 75 6c 65 47 72 6f 75 70 20 69 6e  n, lRuleGroup in
3580: 20 63 68 61 69 6e 28 5f 67 65 74 52 75 6c 65 73   chain(_getRules
3590: 28 54 72 75 65 29 2c 20 5f 67 65 74 52 75 6c 65  (True), _getRule
35a0: 73 28 46 61 6c 73 65 29 29 3a 0a 20 20 20 20 20  s(False)):.     
35b0: 20 20 20 66 6f 72 20 5f 2c 20 5f 2c 20 73 4c 69     for _, _, sLi
35c0: 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 5f  neId, sRuleId, _
35d0: 2c 20 5f 20 69 6e 20 6c 52 75 6c 65 47 72 6f 75  , _ in lRuleGrou
35e0: 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  p:.            i
35f0: 66 20 6e 6f 74 20 73 46 69 6c 74 65 72 20 6f 72  f not sFilter or
3600: 20 7a 46 69 6c 74 65 72 2e 73 65 61 72 63 68 28   zFilter.search(
3610: 73 52 75 6c 65 49 64 29 3a 0a 20 20 20 20 20 20  sRuleId):.      
3620: 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64 20            yield 
3630: 28 73 4f 70 74 69 6f 6e 2c 20 73 4c 69 6e 65 49  (sOption, sLineI
3640: 64 2c 20 73 52 75 6c 65 49 64 29 0a 0a 0a 64 65  d, sRuleId)...de
3650: 66 20 64 69 73 70 6c 61 79 52 75 6c 65 73 20 28  f displayRules (
3660: 73 46 69 6c 74 65 72 3d 4e 6f 6e 65 29 3a 0a 20  sFilter=None):. 
3670: 20 20 20 65 63 68 6f 28 22 4c 69 73 74 20 6f 66     echo("List of
3680: 20 72 75 6c 65 73 2e 20 46 69 6c 74 65 72 3a 20   rules. Filter: 
3690: 3c 3c 20 22 20 2b 20 73 74 72 28 73 46 69 6c 74  << " + str(sFilt
36a0: 65 72 29 20 2b 20 22 20 3e 3e 22 29 0a 20 20 20  er) + " >>").   
36b0: 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 73 4c   for sOption, sL
36c0: 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 20 69  ineId, sRuleId i
36d0: 6e 20 6c 69 73 74 52 75 6c 65 73 28 73 46 69 6c  n listRules(sFil
36e0: 74 65 72 29 3a 0a 20 20 20 20 20 20 20 20 65 63  ter):.        ec
36f0: 68 6f 28 22 7b 3a 3c 31 30 7d 20 7b 3a 3c 31 30  ho("{:<10} {:<10
3700: 7d 20 7b 7d 22 2e 66 6f 72 6d 61 74 28 73 4f 70  } {}".format(sOp
3710: 74 69 6f 6e 2c 20 73 4c 69 6e 65 49 64 2c 20 73  tion, sLineId, s
3720: 52 75 6c 65 49 64 29 29 0a 0a 0a 23 23 23 23 20  RuleId))...#### 
3730: 69 6e 69 74 0a 0a 74 72 79 3a 0a 20 20 20 20 23  init..try:.    #
3740: 20 4c 69 62 72 65 4f 66 66 69 63 65 20 2f 20 4f   LibreOffice / O
3750: 70 65 6e 4f 66 66 69 63 65 0a 20 20 20 20 66 72  penOffice.    fr
3760: 6f 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e  om com.sun.star.
3770: 6c 69 6e 67 75 69 73 74 69 63 32 20 69 6d 70 6f  linguistic2 impo
3780: 72 74 20 53 69 6e 67 6c 65 50 72 6f 6f 66 72 65  rt SingleProofre
3790: 61 64 69 6e 67 45 72 72 6f 72 0a 20 20 20 20 66  adingError.    f
37a0: 72 6f 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72  rom com.sun.star
37b0: 2e 74 65 78 74 2e 54 65 78 74 4d 61 72 6b 75 70  .text.TextMarkup
37c0: 54 79 70 65 20 69 6d 70 6f 72 74 20 50 52 4f 4f  Type import PROO
37d0: 46 52 45 41 44 49 4e 47 0a 20 20 20 20 66 72 6f  FREADING.    fro
37e0: 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 62  m com.sun.star.b
37f0: 65 61 6e 73 20 69 6d 70 6f 72 74 20 50 72 6f 70  eans import Prop
3800: 65 72 74 79 56 61 6c 75 65 0a 20 20 20 20 23 69  ertyValue.    #i
3810: 6d 70 6f 72 74 20 6c 69 67 68 74 70 72 6f 6f 66  mport lightproof
3820: 5f 68 61 6e 64 6c 65 72 5f 24 7b 69 6d 70 6c 6e  _handler_${impln
3830: 61 6d 65 7d 20 61 73 20 6f 70 74 0a 20 20 20 20  ame} as opt.    
3840: 5f 63 72 65 61 74 65 52 65 67 65 78 45 72 72 6f  _createRegexErro
3850: 72 20 3d 20 5f 63 72 65 61 74 65 52 65 67 65 78  r = _createRegex
3860: 57 72 69 74 65 72 45 72 72 6f 72 0a 20 20 20 20  WriterError.    
3870: 5f 63 72 65 61 74 65 54 6f 6b 65 6e 45 72 72 6f  _createTokenErro
3880: 72 20 3d 20 5f 63 72 65 61 74 65 54 6f 6b 65 6e  r = _createToken
3890: 57 72 69 74 65 72 45 72 72 6f 72 0a 65 78 63 65  WriterError.exce
38a0: 70 74 20 49 6d 70 6f 72 74 45 72 72 6f 72 3a 0a  pt ImportError:.
38b0: 20 20 20 20 5f 63 72 65 61 74 65 52 65 67 65 78      _createRegex
38c0: 45 72 72 6f 72 20 3d 20 5f 63 72 65 61 74 65 52  Error = _createR
38d0: 65 67 65 78 44 69 63 74 45 72 72 6f 72 0a 20 20  egexDictError.  
38e0: 20 20 5f 63 72 65 61 74 65 54 6f 6b 65 6e 45 72    _createTokenEr
38f0: 72 6f 72 20 3d 20 5f 63 72 65 61 74 65 54 6f 6b  ror = _createTok
3900: 65 6e 44 69 63 74 45 72 72 6f 72 0a 0a 0a 64 65  enDictError...de
3910: 66 20 6c 6f 61 64 20 28 73 43 6f 6e 74 65 78 74  f load (sContext
3920: 3d 22 50 79 74 68 6f 6e 22 29 3a 0a 20 20 20 20  ="Python"):.    
3930: 67 6c 6f 62 61 6c 20 5f 6f 53 70 65 6c 6c 43 68  global _oSpellCh
3940: 65 63 6b 65 72 0a 20 20 20 20 67 6c 6f 62 61 6c  ecker.    global
3950: 20 5f 73 41 70 70 43 6f 6e 74 65 78 74 0a 20 20   _sAppContext.  
3960: 20 20 67 6c 6f 62 61 6c 20 5f 64 4f 70 74 69 6f    global _dOptio
3970: 6e 73 0a 20 20 20 20 67 6c 6f 62 61 6c 20 5f 6f  ns.    global _o
3980: 54 6f 6b 65 6e 69 7a 65 72 0a 20 20 20 20 74 72  Tokenizer.    tr
3990: 79 3a 0a 20 20 20 20 20 20 20 20 5f 6f 53 70 65  y:.        _oSpe
39a0: 6c 6c 43 68 65 63 6b 65 72 20 3d 20 53 70 65 6c  llChecker = Spel
39b0: 6c 43 68 65 63 6b 65 72 28 22 24 7b 6c 61 6e 67  lChecker("${lang
39c0: 7d 22 2c 20 22 24 7b 64 69 63 5f 6d 61 69 6e 5f  }", "${dic_main_
39d0: 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 2c 20 22  filename_py}", "
39e0: 24 7b 64 69 63 5f 65 78 74 65 6e 64 65 64 5f 66  ${dic_extended_f
39f0: 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 2c 20 22 24  ilename_py}", "$
3a00: 7b 64 69 63 5f 63 6f 6d 6d 75 6e 69 74 79 5f 66  {dic_community_f
3a10: 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 2c 20 22 24  ilename_py}", "$
3a20: 7b 64 69 63 5f 70 65 72 73 6f 6e 61 6c 5f 66 69  {dic_personal_fi
3a30: 6c 65 6e 61 6d 65 5f 70 79 7d 22 29 0a 20 20 20  lename_py}").   
3a40: 20 20 20 20 20 5f 73 41 70 70 43 6f 6e 74 65 78       _sAppContex
3a50: 74 20 3d 20 73 43 6f 6e 74 65 78 74 0a 20 20 20  t = sContext.   
3a60: 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e 73 20 3d       _dOptions =
3a70: 20 64 69 63 74 28 67 63 5f 6f 70 74 69 6f 6e 73   dict(gc_options
3a80: 2e 67 65 74 4f 70 74 69 6f 6e 73 28 73 43 6f 6e  .getOptions(sCon
3a90: 74 65 78 74 29 29 20 20 20 23 20 64 75 70 6c 69  text))   # dupli
3aa0: 63 61 74 69 6f 6e 20 6e 65 63 65 73 73 61 72 79  cation necessary
3ab0: 2c 20 74 6f 20 62 65 20 61 62 6c 65 20 74 6f 20  , to be able to 
3ac0: 72 65 73 65 74 20 74 6f 20 64 65 66 61 75 6c 74  reset to default
3ad0: 0a 20 20 20 20 20 20 20 20 5f 6f 54 6f 6b 65 6e  .        _oToken
3ae0: 69 7a 65 72 20 3d 20 5f 6f 53 70 65 6c 6c 43 68  izer = _oSpellCh
3af0: 65 63 6b 65 72 2e 67 65 74 54 6f 6b 65 6e 69 7a  ecker.getTokeniz
3b00: 65 72 28 29 0a 20 20 20 20 20 20 20 20 5f 6f 53  er().        _oS
3b10: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 61 63 74 69  pellChecker.acti
3b20: 76 61 74 65 53 74 6f 72 61 67 65 28 29 0a 20 20  vateStorage().  
3b30: 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20    except:.      
3b40: 20 20 74 72 61 63 65 62 61 63 6b 2e 70 72 69 6e    traceback.prin
3b50: 74 5f 65 78 63 28 29 0a 0a 0a 64 65 66 20 73 65  t_exc()...def se
3b60: 74 4f 70 74 69 6f 6e 20 28 73 4f 70 74 2c 20 62  tOption (sOpt, b
3b70: 56 61 6c 29 3a 0a 20 20 20 20 69 66 20 73 4f 70  Val):.    if sOp
3b80: 74 20 69 6e 20 5f 64 4f 70 74 69 6f 6e 73 3a 0a  t in _dOptions:.
3b90: 20 20 20 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e          _dOption
3ba0: 73 5b 73 4f 70 74 5d 20 3d 20 62 56 61 6c 0a 0a  s[sOpt] = bVal..
3bb0: 0a 64 65 66 20 73 65 74 4f 70 74 69 6f 6e 73 20  .def setOptions 
3bc0: 28 64 4f 70 74 29 3a 0a 20 20 20 20 66 6f 72 20  (dOpt):.    for 
3bd0: 73 4b 65 79 2c 20 62 56 61 6c 20 69 6e 20 64 4f  sKey, bVal in dO
3be0: 70 74 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20 20  pt.items():.    
3bf0: 20 20 20 20 69 66 20 73 4b 65 79 20 69 6e 20 5f      if sKey in _
3c00: 64 4f 70 74 69 6f 6e 73 3a 0a 20 20 20 20 20 20  dOptions:.      
3c10: 20 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e 73 5b        _dOptions[
3c20: 73 4b 65 79 5d 20 3d 20 62 56 61 6c 0a 0a 0a 64  sKey] = bVal...d
3c30: 65 66 20 67 65 74 4f 70 74 69 6f 6e 73 20 28 29  ef getOptions ()
3c40: 3a 0a 20 20 20 20 72 65 74 75 72 6e 20 5f 64 4f  :.    return _dO
3c50: 70 74 69 6f 6e 73 0a 0a 0a 64 65 66 20 67 65 74  ptions...def get
3c60: 44 65 66 61 75 6c 74 4f 70 74 69 6f 6e 73 20 28  DefaultOptions (
3c70: 29 3a 0a 20 20 20 20 72 65 74 75 72 6e 20 64 69  ):.    return di
3c80: 63 74 28 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  ct(gc_options.ge
3c90: 74 4f 70 74 69 6f 6e 73 28 5f 73 41 70 70 43 6f  tOptions(_sAppCo
3ca0: 6e 74 65 78 74 29 29 0a 0a 0a 64 65 66 20 67 65  ntext))...def ge
3cb0: 74 4f 70 74 69 6f 6e 73 4c 61 62 65 6c 73 20 28  tOptionsLabels (
3cc0: 73 4c 61 6e 67 29 3a 0a 20 20 20 20 72 65 74 75  sLang):.    retu
3cd0: 72 6e 20 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  rn gc_options.ge
3ce0: 74 55 49 28 73 4c 61 6e 67 29 0a 0a 0a 64 65 66  tUI(sLang)...def
3cf0: 20 64 69 73 70 6c 61 79 4f 70 74 69 6f 6e 73 20   displayOptions 
3d00: 28 73 4c 61 6e 67 29 3a 0a 20 20 20 20 65 63 68  (sLang):.    ech
3d10: 6f 28 22 4c 69 73 74 20 6f 66 20 6f 70 74 69 6f  o("List of optio
3d20: 6e 73 22 29 0a 20 20 20 20 65 63 68 6f 28 22 5c  ns").    echo("\
3d30: 6e 22 2e 6a 6f 69 6e 28 20 5b 20 6b 2b 22 3a 5c  n".join( [ k+":\
3d40: 74 22 2b 73 74 72 28 76 29 2b 22 5c 74 22 2b 67  t"+str(v)+"\t"+g
3d50: 63 5f 6f 70 74 69 6f 6e 73 2e 67 65 74 55 49 28  c_options.getUI(
3d60: 73 4c 61 6e 67 29 2e 67 65 74 28 6b 2c 20 28 22  sLang).get(k, ("
3d70: 3f 22 2c 20 22 22 29 29 5b 30 5d 20 20 66 6f 72  ?", ""))[0]  for
3d80: 20 6b 2c 20 76 20 20 69 6e 20 73 6f 72 74 65 64   k, v  in sorted
3d90: 28 5f 64 4f 70 74 69 6f 6e 73 2e 69 74 65 6d 73  (_dOptions.items
3da0: 28 29 29 20 5d 20 29 29 0a 20 20 20 20 65 63 68  ()) ] )).    ech
3db0: 6f 28 22 22 29 0a 0a 0a 64 65 66 20 72 65 73 65  o("")...def rese
3dc0: 74 4f 70 74 69 6f 6e 73 20 28 29 3a 0a 20 20 20  tOptions ():.   
3dd0: 20 67 6c 6f 62 61 6c 20 5f 64 4f 70 74 69 6f 6e   global _dOption
3de0: 73 0a 20 20 20 20 5f 64 4f 70 74 69 6f 6e 73 20  s.    _dOptions 
3df0: 3d 20 64 69 63 74 28 67 63 5f 6f 70 74 69 6f 6e  = dict(gc_option
3e00: 73 2e 67 65 74 4f 70 74 69 6f 6e 73 28 5f 73 41  s.getOptions(_sA
3e10: 70 70 43 6f 6e 74 65 78 74 29 29 0a 0a 0a 64 65  ppContext))...de
3e20: 66 20 67 65 74 53 70 65 6c 6c 43 68 65 63 6b 65  f getSpellChecke
3e30: 72 20 28 29 3a 0a 20 20 20 20 72 65 74 75 72 6e  r ():.    return
3e40: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 0a   _oSpellChecker.
3e50: 0a 0a 64 65 66 20 5f 67 65 74 52 75 6c 65 73 20  ..def _getRules 
3e60: 28 62 50 61 72 61 67 72 61 70 68 29 3a 0a 20 20  (bParagraph):.  
3e70: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 69    try:.        i
3e80: 66 20 6e 6f 74 20 62 50 61 72 61 67 72 61 70 68  f not bParagraph
3e90: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  :.            re
3ea0: 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 53 65 6e  turn _rules.lSen
3eb0: 74 65 6e 63 65 52 75 6c 65 73 0a 20 20 20 20 20  tenceRules.     
3ec0: 20 20 20 72 65 74 75 72 6e 20 5f 72 75 6c 65 73     return _rules
3ed0: 2e 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65 73  .lParagraphRules
3ee0: 0a 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20  .    except:.   
3ef0: 20 20 20 20 20 5f 6c 6f 61 64 52 75 6c 65 73 28       _loadRules(
3f00: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 62 50 61  ).    if not bPa
3f10: 72 61 67 72 61 70 68 3a 0a 20 20 20 20 20 20 20  ragraph:.       
3f20: 20 72 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c   return _rules.l
3f30: 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 0a 20 20  SentenceRules.  
3f40: 20 20 72 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e    return _rules.
3f50: 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 0a  lParagraphRules.
3f60: 0a 0a 64 65 66 20 5f 6c 6f 61 64 52 75 6c 65 73  ..def _loadRules
3f70: 20 28 29 3a 0a 20 20 20 20 66 72 6f 6d 20 2e 20   ():.    from . 
3f80: 69 6d 70 6f 72 74 20 67 63 5f 72 75 6c 65 73 0a  import gc_rules.
3f90: 20 20 20 20 67 6c 6f 62 61 6c 20 5f 72 75 6c 65      global _rule
3fa0: 73 0a 20 20 20 20 5f 72 75 6c 65 73 20 3d 20 67  s.    _rules = g
3fb0: 63 5f 72 75 6c 65 73 0a 20 20 20 20 23 20 63 6f  c_rules.    # co
3fc0: 6d 70 69 6c 65 20 72 75 6c 65 73 20 72 65 67 65  mpile rules rege
3fd0: 78 0a 20 20 20 20 66 6f 72 20 6c 52 75 6c 65 47  x.    for lRuleG
3fe0: 72 6f 75 70 20 69 6e 20 63 68 61 69 6e 28 5f 72  roup in chain(_r
3ff0: 75 6c 65 73 2e 6c 50 61 72 61 67 72 61 70 68 52  ules.lParagraphR
4000: 75 6c 65 73 2c 20 5f 72 75 6c 65 73 2e 6c 53 65  ules, _rules.lSe
4010: 6e 74 65 6e 63 65 52 75 6c 65 73 29 3a 0a 20 20  ntenceRules):.  
4020: 20 20 20 20 20 20 66 6f 72 20 72 75 6c 65 20 69        for rule i
4030: 6e 20 6c 52 75 6c 65 47 72 6f 75 70 5b 31 5d 3a  n lRuleGroup[1]:
4040: 0a 20 20 20 20 20 20 20 20 20 20 20 20 74 72 79  .            try
4050: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
4060: 20 20 72 75 6c 65 5b 30 5d 20 3d 20 72 65 2e 63    rule[0] = re.c
4070: 6f 6d 70 69 6c 65 28 72 75 6c 65 5b 30 5d 29 0a  ompile(rule[0]).
4080: 20 20 20 20 20 20 20 20 20 20 20 20 65 78 63 65              exce
4090: 70 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  pt:.            
40a0: 20 20 20 20 65 63 68 6f 28 22 42 61 64 20 72 65      echo("Bad re
40b0: 67 75 6c 61 72 20 65 78 70 72 65 73 73 69 6f 6e  gular expression
40c0: 20 69 6e 20 23 20 22 20 2b 20 73 74 72 28 72 75   in # " + str(ru
40d0: 6c 65 5b 32 5d 29 29 0a 20 20 20 20 20 20 20 20  le[2])).        
40e0: 20 20 20 20 20 20 20 20 72 75 6c 65 5b 30 5d 20          rule[0] 
40f0: 3d 20 22 28 3f 69 29 3c 47 72 61 6d 6d 61 6c 65  = "(?i)<Grammale
4100: 63 74 65 3e 22 0a 0a 0a 64 65 66 20 5f 67 65 74  cte>"...def _get
4110: 50 61 74 68 20 28 29 3a 0a 20 20 20 20 72 65 74  Path ():.    ret
4120: 75 72 6e 20 6f 73 2e 70 61 74 68 2e 6a 6f 69 6e  urn os.path.join
4130: 28 6f 73 2e 70 61 74 68 2e 64 69 72 6e 61 6d 65  (os.path.dirname
4140: 28 73 79 73 2e 6d 6f 64 75 6c 65 73 5b 5f 5f 6e  (sys.modules[__n
4150: 61 6d 65 5f 5f 5d 2e 5f 5f 66 69 6c 65 5f 5f 29  ame__].__file__)
4160: 2c 20 5f 5f 6e 61 6d 65 5f 5f 20 2b 20 22 2e 70  , __name__ + ".p
4170: 79 22 29 0a 0a 0a 0a 23 23 23 23 20 63 6f 6d 6d  y")....#### comm
4180: 6f 6e 20 66 75 6e 63 74 69 6f 6e 73 0a 0a 23 20  on functions..# 
4190: 63 6f 6d 6d 6f 6e 20 72 65 67 65 78 65 73 0a 5f  common regexes._
41a0: 7a 45 6e 64 4f 66 53 65 6e 74 65 6e 63 65 20 3d  zEndOfSentence =
41b0: 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72 27 28 5b   re.compile(r'([
41c0: 2e 3f 21 3a 3b e2 80 a6 5d 5b 20 2e 3f 21 e2 80  .?!:;...][ .?!..
41d0: a6 20 c2 bb e2 80 9d 22 29 5d 2a 7c 2e 24 29 27  . .....")]*|.$)'
41e0: 29 0a 5f 7a 42 65 67 69 6e 4f 66 50 61 72 61 67  )._zBeginOfParag
41f0: 72 61 70 68 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  raph = re.compil
4200: 65 28 72 22 5e 5c 57 2a 22 29 0a 5f 7a 45 6e 64  e(r"^\W*")._zEnd
4210: 4f 66 50 61 72 61 67 72 61 70 68 20 3d 20 72 65  OfParagraph = re
4220: 2e 63 6f 6d 70 69 6c 65 28 72 22 5c 57 2a 24 22  .compile(r"\W*$"
4230: 29 0a 5f 7a 4e 65 78 74 57 6f 72 64 20 3d 20 72  )._zNextWord = r
4240: 65 2e 63 6f 6d 70 69 6c 65 28 72 22 20 2b 28 5c  e.compile(r" +(\
4250: 77 5b 5c 77 2d 5d 2a 29 22 29 0a 5f 7a 50 72 65  w[\w-]*)")._zPre
4260: 76 57 6f 72 64 20 3d 20 72 65 2e 63 6f 6d 70 69  vWord = re.compi
4270: 6c 65 28 72 22 28 5c 77 5b 5c 77 2d 5d 2a 29 20  le(r"(\w[\w-]*) 
4280: 2b 24 22 29 0a 0a 0a 64 65 66 20 6f 70 74 69 6f  +$")...def optio
4290: 6e 20 28 73 4f 70 74 29 3a 0a 20 20 20 20 22 72  n (sOpt):.    "r
42a0: 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 6f 70  eturn True if op
42b0: 74 69 6f 6e 20 73 4f 70 74 20 69 73 20 61 63 74  tion sOpt is act
42c0: 69 76 65 22 0a 20 20 20 20 72 65 74 75 72 6e 20  ive".    return 
42d0: 5f 64 4f 70 74 69 6f 6e 73 2e 67 65 74 28 73 4f  _dOptions.get(sO
42e0: 70 74 2c 20 46 61 6c 73 65 29 0a 0a 0a 64 65 66  pt, False)...def
42f0: 20 64 69 73 70 6c 61 79 49 6e 66 6f 20 28 64 44   displayInfo (dD
4300: 41 2c 20 74 57 6f 72 64 29 3a 0a 20 20 20 20 22  A, tWord):.    "
4310: 66 6f 72 20 64 65 62 75 67 67 69 6e 67 3a 20 72  for debugging: r
4320: 65 74 72 69 65 76 65 20 69 6e 66 6f 20 6f 66 20  etrieve info of 
4330: 77 6f 72 64 22 0a 20 20 20 20 69 66 20 6e 6f 74  word".    if not
4340: 20 74 57 6f 72 64 3a 0a 20 20 20 20 20 20 20 20   tWord:.        
4350: 65 63 68 6f 28 22 3e 20 6e 6f 74 68 69 6e 67 20  echo("> nothing 
4360: 74 6f 20 66 69 6e 64 22 29 0a 20 20 20 20 20 20  to find").      
4370: 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20    return True.  
4380: 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65    lMorph = _oSpe
4390: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
43a0: 70 68 28 74 57 6f 72 64 5b 31 5d 29 0a 20 20 20  ph(tWord[1]).   
43b0: 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a   if not lMorph:.
43c0: 20 20 20 20 20 20 20 20 65 63 68 6f 28 22 3e 20          echo("> 
43d0: 6e 6f 74 20 69 6e 20 64 69 63 74 69 6f 6e 61 72  not in dictionar
43e0: 79 22 29 0a 20 20 20 20 20 20 20 20 72 65 74 75  y").        retu
43f0: 72 6e 20 54 72 75 65 0a 20 20 20 20 69 66 20 74  rn True.    if t
4400: 57 6f 72 64 5b 30 5d 20 69 6e 20 64 44 41 3a 0a  Word[0] in dDA:.
4410: 20 20 20 20 20 20 20 20 65 63 68 6f 28 22 44 41          echo("DA
4420: 3a 20 22 20 2b 20 73 74 72 28 64 44 41 5b 74 57  : " + str(dDA[tW
4430: 6f 72 64 5b 30 5d 5d 29 29 0a 20 20 20 20 65 63  ord[0]])).    ec
4440: 68 6f 28 22 46 53 41 3a 20 22 20 2b 20 73 74 72  ho("FSA: " + str
4450: 28 6c 4d 6f 72 70 68 29 29 0a 20 20 20 20 72 65  (lMorph)).    re
4460: 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20  turn True...def 
4470: 6d 6f 72 70 68 20 28 64 44 41 2c 20 74 57 6f 72  morph (dDA, tWor
4480: 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 62 53 74  d, sPattern, bSt
4490: 72 69 63 74 3d 54 72 75 65 2c 20 62 4e 6f 57 6f  rict=True, bNoWo
44a0: 72 64 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22  rd=False):.    "
44b0: 61 6e 61 6c 79 73 65 20 61 20 74 75 70 6c 65 20  analyse a tuple 
44c0: 28 70 6f 73 69 74 69 6f 6e 2c 20 77 6f 72 64 29  (position, word)
44d0: 2c 20 72 65 74 75 72 6e 20 54 72 75 65 20 69 66  , return True if
44e0: 20 73 50 61 74 74 65 72 6e 20 69 6e 20 6d 6f 72   sPattern in mor
44f0: 70 68 6f 6c 6f 67 69 65 73 20 28 64 69 73 61 6d  phologies (disam
4500: 62 69 67 75 61 74 69 6f 6e 20 6f 6e 29 22 0a 20  biguation on)". 
4510: 20 20 20 69 66 20 6e 6f 74 20 74 57 6f 72 64 3a     if not tWord:
4520: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
4530: 62 4e 6f 57 6f 72 64 0a 20 20 20 20 6c 4d 6f 72  bNoWord.    lMor
4540: 70 68 20 3d 20 64 44 41 5b 74 57 6f 72 64 5b 30  ph = dDA[tWord[0
4550: 5d 5d 20 20 69 66 20 74 57 6f 72 64 5b 30 5d 20  ]]  if tWord[0] 
4560: 69 6e 20 64 44 41 20 20 65 6c 73 65 20 5f 6f 53  in dDA  else _oS
4570: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
4580: 6f 72 70 68 28 74 57 6f 72 64 5b 31 5d 29 0a 20  orph(tWord[1]). 
4590: 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68     if not lMorph
45a0: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
45b0: 20 46 61 6c 73 65 0a 20 20 20 20 70 20 3d 20 72   False.    p = r
45c0: 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65  e.compile(sPatte
45d0: 72 6e 29 0a 20 20 20 20 69 66 20 62 53 74 72 69  rn).    if bStri
45e0: 63 74 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  ct:.        retu
45f0: 72 6e 20 61 6c 6c 28 70 2e 73 65 61 72 63 68 28  rn all(p.search(
4600: 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f  s)  for s in lMo
4610: 72 70 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20  rph).    return 
4620: 61 6e 79 28 70 2e 73 65 61 72 63 68 28 73 29 20  any(p.search(s) 
4630: 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68   for s in lMorph
4640: 29 0a 0a 0a 64 65 66 20 6d 6f 72 70 68 65 78 20  )...def morphex 
4650: 28 64 44 41 2c 20 74 57 6f 72 64 2c 20 73 50 61  (dDA, tWord, sPa
4660: 74 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65  ttern, sNegPatte
4670: 72 6e 2c 20 62 4e 6f 57 6f 72 64 3d 46 61 6c 73  rn, bNoWord=Fals
4680: 65 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65  e):.    "analyse
4690: 20 61 20 74 75 70 6c 65 20 28 70 6f 73 69 74 69   a tuple (positi
46a0: 6f 6e 2c 20 77 6f 72 64 29 2c 20 72 65 74 75 72  on, word), retur
46b0: 6e 73 20 54 72 75 65 20 69 66 20 6e 6f 74 20 73  ns True if not s
46c0: 4e 65 67 50 61 74 74 65 72 6e 20 69 6e 20 77 6f  NegPattern in wo
46d0: 72 64 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20  rd morphologies 
46e0: 61 6e 64 20 73 50 61 74 74 65 72 6e 20 69 6e 20  and sPattern in 
46f0: 77 6f 72 64 20 6d 6f 72 70 68 6f 6c 6f 67 69 65  word morphologie
4700: 73 20 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f  s (disambiguatio
4710: 6e 20 6f 6e 29 22 0a 20 20 20 20 69 66 20 6e 6f  n on)".    if no
4720: 74 20 74 57 6f 72 64 3a 0a 20 20 20 20 20 20 20  t tWord:.       
4730: 20 72 65 74 75 72 6e 20 62 4e 6f 57 6f 72 64 0a   return bNoWord.
4740: 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 64 44 41      lMorph = dDA
4750: 5b 74 57 6f 72 64 5b 30 5d 5d 20 20 69 66 20 74  [tWord[0]]  if t
4760: 57 6f 72 64 5b 30 5d 20 69 6e 20 64 44 41 20 20  Word[0] in dDA  
4770: 65 6c 73 65 20 5f 6f 53 70 65 6c 6c 43 68 65 63  else _oSpellChec
4780: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 74 57 6f  ker.getMorph(tWo
4790: 72 64 5b 31 5d 29 0a 20 20 20 20 69 66 20 6e 6f  rd[1]).    if no
47a0: 74 20 6c 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20  t lMorph:.      
47b0: 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 20    return False. 
47c0: 20 20 20 23 20 63 68 65 63 6b 20 6e 65 67 61 74     # check negat
47d0: 69 76 65 20 63 6f 6e 64 69 74 69 6f 6e 0a 20 20  ive condition.  
47e0: 20 20 6e 70 20 3d 20 72 65 2e 63 6f 6d 70 69 6c    np = re.compil
47f0: 65 28 73 4e 65 67 50 61 74 74 65 72 6e 29 0a 20  e(sNegPattern). 
4800: 20 20 20 69 66 20 61 6e 79 28 6e 70 2e 73 65 61     if any(np.sea
4810: 72 63 68 28 73 29 20 20 66 6f 72 20 73 20 69 6e  rch(s)  for s in
4820: 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20   lMorph):.      
4830: 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 20    return False. 
4840: 20 20 20 23 20 73 65 61 72 63 68 20 73 50 61 74     # search sPat
4850: 74 65 72 6e 0a 20 20 20 20 70 20 3d 20 72 65 2e  tern.    p = re.
4860: 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e  compile(sPattern
4870: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79  ).    return any
4880: 28 70 2e 73 65 61 72 63 68 28 73 29 20 20 66 6f  (p.search(s)  fo
4890: 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a  r s in lMorph)..
48a0: 0a 64 65 66 20 61 6e 61 6c 79 73 65 20 28 73 57  .def analyse (sW
48b0: 6f 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 62  ord, sPattern, b
48c0: 53 74 72 69 63 74 3d 54 72 75 65 29 3a 0a 20 20  Strict=True):.  
48d0: 20 20 22 61 6e 61 6c 79 73 65 20 61 20 77 6f 72    "analyse a wor
48e0: 64 2c 20 72 65 74 75 72 6e 20 54 72 75 65 20 69  d, return True i
48f0: 66 20 73 50 61 74 74 65 72 6e 20 69 6e 20 6d 6f  f sPattern in mo
4900: 72 70 68 6f 6c 6f 67 69 65 73 20 28 64 69 73 61  rphologies (disa
4910: 6d 62 69 67 75 61 74 69 6f 6e 20 6f 66 66 29 22  mbiguation off)"
4920: 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f  .    lMorph = _o
4930: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74  SpellChecker.get
4940: 4d 6f 72 70 68 28 73 57 6f 72 64 29 0a 20 20 20  Morph(sWord).   
4950: 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a   if not lMorph:.
4960: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46          return F
4970: 61 6c 73 65 0a 20 20 20 20 70 20 3d 20 72 65 2e  alse.    p = re.
4980: 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e  compile(sPattern
4990: 29 0a 20 20 20 20 69 66 20 62 53 74 72 69 63 74  ).    if bStrict
49a0: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
49b0: 20 61 6c 6c 28 70 2e 73 65 61 72 63 68 28 73 29   all(p.search(s)
49c0: 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70    for s in lMorp
49d0: 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e  h).    return an
49e0: 79 28 70 2e 73 65 61 72 63 68 28 73 29 20 20 66  y(p.search(s)  f
49f0: 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a  or s in lMorph).
4a00: 0a 0a 64 65 66 20 61 6e 61 6c 79 73 65 78 20 28  ..def analysex (
4a10: 73 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e 2c  sWord, sPattern,
4a20: 20 73 4e 65 67 50 61 74 74 65 72 6e 29 3a 0a 20   sNegPattern):. 
4a30: 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 77 6f     "analyse a wo
4a40: 72 64 2c 20 72 65 74 75 72 6e 73 20 54 72 75 65  rd, returns True
4a50: 20 69 66 20 6e 6f 74 20 73 4e 65 67 50 61 74 74   if not sNegPatt
4a60: 65 72 6e 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70  ern in word morp
4a70: 68 6f 6c 6f 67 69 65 73 20 61 6e 64 20 73 50 61  hologies and sPa
4a80: 74 74 65 72 6e 20 69 6e 20 77 6f 72 64 20 6d 6f  ttern in word mo
4a90: 72 70 68 6f 6c 6f 67 69 65 73 20 28 64 69 73 61  rphologies (disa
4aa0: 6d 62 69 67 75 61 74 69 6f 6e 20 6f 66 66 29 22  mbiguation off)"
4ab0: 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f  .    lMorph = _o
4ac0: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74  SpellChecker.get
4ad0: 4d 6f 72 70 68 28 73 57 6f 72 64 29 0a 20 20 20  Morph(sWord).   
4ae0: 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a   if not lMorph:.
4af0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46          return F
4b00: 61 6c 73 65 0a 20 20 20 20 23 20 63 68 65 63 6b  alse.    # check
4b10: 20 6e 65 67 61 74 69 76 65 20 63 6f 6e 64 69 74   negative condit
4b20: 69 6f 6e 0a 20 20 20 20 6e 70 20 3d 20 72 65 2e  ion.    np = re.
4b30: 63 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61 74 74  compile(sNegPatt
4b40: 65 72 6e 29 0a 20 20 20 20 69 66 20 61 6e 79 28  ern).    if any(
4b50: 6e 70 2e 73 65 61 72 63 68 28 73 29 20 20 66 6f  np.search(s)  fo
4b60: 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a  r s in lMorph):.
4b70: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46          return F
4b80: 61 6c 73 65 0a 20 20 20 20 23 20 73 65 61 72 63  alse.    # searc
4b90: 68 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20 70  h sPattern.    p
4ba0: 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50   = re.compile(sP
4bb0: 61 74 74 65 72 6e 29 0a 20 20 20 20 72 65 74 75  attern).    retu
4bc0: 72 6e 20 61 6e 79 28 70 2e 73 65 61 72 63 68 28  rn any(p.search(
4bd0: 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f  s)  for s in lMo
4be0: 72 70 68 29 0a 0a 0a 0a 23 23 20 66 75 6e 63 74  rph)....## funct
4bf0: 69 6f 6e 73 20 74 6f 20 67 65 74 20 74 65 78 74  ions to get text
4c00: 20 6f 75 74 73 69 64 65 20 70 61 74 74 65 72 6e   outside pattern
4c10: 20 73 63 6f 70 65 0a 0a 23 20 77 61 72 6e 69 6e   scope..# warnin
4c20: 67 3a 20 63 68 65 63 6b 20 63 6f 6d 70 69 6c 65  g: check compile
4c30: 5f 72 75 6c 65 73 2e 70 79 20 74 6f 20 75 6e 64  _rules.py to und
4c40: 65 72 73 74 61 6e 64 20 68 6f 77 20 69 74 20 77  erstand how it w
4c50: 6f 72 6b 73 0a 0a 64 65 66 20 6e 65 78 74 77 6f  orks..def nextwo
4c60: 72 64 20 28 73 2c 20 69 53 74 61 72 74 2c 20 6e  rd (s, iStart, n
4c70: 29 3a 0a 20 20 20 20 22 67 65 74 20 74 68 65 20  ):.    "get the 
4c80: 6e 74 68 20 77 6f 72 64 20 6f 66 20 74 68 65 20  nth word of the 
4c90: 69 6e 70 75 74 20 73 74 72 69 6e 67 20 6f 72 20  input string or 
4ca0: 65 6d 70 74 79 20 73 74 72 69 6e 67 22 0a 20 20  empty string".  
4cb0: 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22    m = re.match("
4cc0: 28 3f 3a 20 2b 5b 5c 5c 77 25 2d 5d 2b 29 7b 22  (?: +[\\w%-]+){"
4cd0: 20 2b 20 73 74 72 28 6e 2d 31 29 20 2b 20 22 7d   + str(n-1) + "}
4ce0: 20 2b 28 5b 5c 5c 77 25 2d 5d 2b 29 22 2c 20 73   +([\\w%-]+)", s
4cf0: 5b 69 53 74 61 72 74 3a 5d 29 0a 20 20 20 20 69  [iStart:]).    i
4d00: 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20  f not m:.       
4d10: 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20   return None.   
4d20: 20 72 65 74 75 72 6e 20 28 69 53 74 61 72 74 2b   return (iStart+
4d30: 6d 2e 73 74 61 72 74 28 31 29 2c 20 6d 2e 67 72  m.start(1), m.gr
4d40: 6f 75 70 28 31 29 29 0a 0a 0a 64 65 66 20 70 72  oup(1))...def pr
4d50: 65 76 77 6f 72 64 20 28 73 2c 20 69 45 6e 64 2c  evword (s, iEnd,
4d60: 20 6e 29 3a 0a 20 20 20 20 22 67 65 74 20 74 68   n):.    "get th
4d70: 65 20 28 2d 29 6e 74 68 20 77 6f 72 64 20 6f 66  e (-)nth word of
4d80: 20 74 68 65 20 69 6e 70 75 74 20 73 74 72 69 6e   the input strin
4d90: 67 20 6f 72 20 65 6d 70 74 79 20 73 74 72 69 6e  g or empty strin
4da0: 67 22 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65  g".    m = re.se
4db0: 61 72 63 68 28 22 28 5b 5c 5c 77 25 2d 5d 2b 29  arch("([\\w%-]+)
4dc0: 20 2b 28 3f 3a 5b 5c 5c 77 25 2d 5d 2b 20 2b 29   +(?:[\\w%-]+ +)
4dd0: 7b 22 20 2b 20 73 74 72 28 6e 2d 31 29 20 2b 20  {" + str(n-1) + 
4de0: 22 7d 24 22 2c 20 73 5b 3a 69 45 6e 64 5d 29 0a  "}$", s[:iEnd]).
4df0: 20 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20      if not m:.  
4e00: 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e        return Non
4e10: 65 0a 20 20 20 20 72 65 74 75 72 6e 20 28 6d 2e  e.    return (m.
4e20: 73 74 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75  start(1), m.grou
4e30: 70 28 31 29 29 0a 0a 0a 64 65 66 20 6e 65 78 74  p(1))...def next
4e40: 77 6f 72 64 31 20 28 73 2c 20 69 53 74 61 72 74  word1 (s, iStart
4e50: 29 3a 0a 20 20 20 20 22 67 65 74 20 6e 65 78 74  ):.    "get next
4e60: 20 77 6f 72 64 20 28 6f 70 74 69 6d 69 7a 61 74   word (optimizat
4e70: 69 6f 6e 29 22 0a 20 20 20 20 6d 20 3d 20 5f 7a  ion)".    m = _z
4e80: 4e 65 78 74 57 6f 72 64 2e 6d 61 74 63 68 28 73  NextWord.match(s
4e90: 5b 69 53 74 61 72 74 3a 5d 29 0a 20 20 20 20 69  [iStart:]).    i
4ea0: 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20  f not m:.       
4eb0: 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20   return None.   
4ec0: 20 72 65 74 75 72 6e 20 28 69 53 74 61 72 74 2b   return (iStart+
4ed0: 6d 2e 73 74 61 72 74 28 31 29 2c 20 6d 2e 67 72  m.start(1), m.gr
4ee0: 6f 75 70 28 31 29 29 0a 0a 0a 64 65 66 20 70 72  oup(1))...def pr
4ef0: 65 76 77 6f 72 64 31 20 28 73 2c 20 69 45 6e 64  evword1 (s, iEnd
4f00: 29 3a 0a 20 20 20 20 22 67 65 74 20 70 72 65 76  ):.    "get prev
4f10: 69 6f 75 73 20 77 6f 72 64 20 28 6f 70 74 69 6d  ious word (optim
4f20: 69 7a 61 74 69 6f 6e 29 22 0a 20 20 20 20 6d 20  ization)".    m 
4f30: 3d 20 5f 7a 50 72 65 76 57 6f 72 64 2e 73 65 61  = _zPrevWord.sea
4f40: 72 63 68 28 73 5b 3a 69 45 6e 64 5d 29 0a 20 20  rch(s[:iEnd]).  
4f50: 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20    if not m:.    
4f60: 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a      return None.
4f70: 20 20 20 20 72 65 74 75 72 6e 20 28 6d 2e 73 74      return (m.st
4f80: 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75 70 28  art(1), m.group(
4f90: 31 29 29 0a 0a 0a 64 65 66 20 6c 6f 6f 6b 20 28  1))...def look (
4fa0: 73 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e 65  s, sPattern, sNe
4fb0: 67 50 61 74 74 65 72 6e 3d 4e 6f 6e 65 29 3a 0a  gPattern=None):.
4fc0: 20 20 20 20 22 73 65 65 6b 20 73 50 61 74 74 65      "seek sPatte
4fd0: 72 6e 20 69 6e 20 73 20 28 62 65 66 6f 72 65 2f  rn in s (before/
4fe0: 61 66 74 65 72 2f 66 75 6c 6c 74 65 78 74 29 2c  after/fulltext),
4ff0: 20 69 66 20 73 4e 65 67 50 61 74 74 65 72 6e 20   if sNegPattern 
5000: 6e 6f 74 20 69 6e 20 73 22 0a 20 20 20 20 69 66  not in s".    if
5010: 20 73 4e 65 67 50 61 74 74 65 72 6e 20 61 6e 64   sNegPattern and
5020: 20 72 65 2e 73 65 61 72 63 68 28 73 4e 65 67 50   re.search(sNegP
5030: 61 74 74 65 72 6e 2c 20 73 29 3a 0a 20 20 20 20  attern, s):.    
5040: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
5050: 0a 20 20 20 20 69 66 20 72 65 2e 73 65 61 72 63  .    if re.searc
5060: 68 28 73 50 61 74 74 65 72 6e 2c 20 73 29 3a 0a  h(sPattern, s):.
5070: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
5080: 72 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20 46  rue.    return F
5090: 61 6c 73 65 0a 0a 0a 64 65 66 20 6c 6f 6f 6b 5f  alse...def look_
50a0: 63 68 6b 31 20 28 64 44 41 2c 20 73 2c 20 6e 4f  chk1 (dDA, s, nO
50b0: 66 66 73 65 74 2c 20 73 50 61 74 74 65 72 6e 2c  ffset, sPattern,
50c0: 20 73 50 61 74 74 65 72 6e 47 72 6f 75 70 31 2c   sPatternGroup1,
50d0: 20 73 4e 65 67 50 61 74 74 65 72 6e 47 72 6f 75   sNegPatternGrou
50e0: 70 31 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 72  p1=None):.    "r
50f0: 65 74 75 72 6e 73 20 54 72 75 65 20 69 66 20 73  eturns True if s
5100: 20 68 61 73 20 70 61 74 74 65 72 6e 20 73 50 61   has pattern sPa
5110: 74 74 65 72 6e 20 61 6e 64 20 6d 2e 67 72 6f 75  ttern and m.grou
5120: 70 28 31 29 20 68 61 73 20 70 61 74 74 65 72 6e  p(1) has pattern
5130: 20 73 50 61 74 74 65 72 6e 47 72 6f 75 70 31 22   sPatternGroup1"
5140: 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61 72  .    m = re.sear
5150: 63 68 28 73 50 61 74 74 65 72 6e 2c 20 73 29 0a  ch(sPattern, s).
5160: 20 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20      if not m:.  
5170: 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c        return Fal
5180: 73 65 0a 20 20 20 20 74 72 79 3a 0a 20 20 20 20  se.    try:.    
5190: 20 20 20 20 73 57 6f 72 64 20 3d 20 6d 2e 67 72      sWord = m.gr
51a0: 6f 75 70 28 31 29 0a 20 20 20 20 20 20 20 20 6e  oup(1).        n
51b0: 50 6f 73 20 3d 20 6d 2e 73 74 61 72 74 28 31 29  Pos = m.start(1)
51c0: 20 2b 20 6e 4f 66 66 73 65 74 0a 20 20 20 20 65   + nOffset.    e
51d0: 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 72  xcept:.        r
51e0: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
51f0: 69 66 20 73 4e 65 67 50 61 74 74 65 72 6e 47 72  if sNegPatternGr
5200: 6f 75 70 31 3a 0a 20 20 20 20 20 20 20 20 72 65  oup1:.        re
5210: 74 75 72 6e 20 6d 6f 72 70 68 65 78 28 64 44 41  turn morphex(dDA
5220: 2c 20 28 6e 50 6f 73 2c 20 73 57 6f 72 64 29 2c  , (nPos, sWord),
5230: 20 73 50 61 74 74 65 72 6e 47 72 6f 75 70 31 2c   sPatternGroup1,
5240: 20 73 4e 65 67 50 61 74 74 65 72 6e 47 72 6f 75   sNegPatternGrou
5250: 70 31 29 0a 20 20 20 20 72 65 74 75 72 6e 20 6d  p1).    return m
5260: 6f 72 70 68 28 64 44 41 2c 20 28 6e 50 6f 73 2c  orph(dDA, (nPos,
5270: 20 73 57 6f 72 64 29 2c 20 73 50 61 74 74 65 72   sWord), sPatter
5280: 6e 47 72 6f 75 70 31 2c 20 46 61 6c 73 65 29 0a  nGroup1, False).
5290: 0a 0a 23 23 23 23 20 44 69 73 61 6d 62 69 67 75  ..#### Disambigu
52a0: 61 74 6f 72 0a 0a 64 65 66 20 73 65 6c 65 63 74  ator..def select
52b0: 20 28 64 44 41 2c 20 6e 50 6f 73 2c 20 73 57 6f   (dDA, nPos, sWo
52c0: 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 6c 44  rd, sPattern, lD
52d0: 65 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20  efault=None):.  
52e0: 20 20 69 66 20 6e 6f 74 20 73 57 6f 72 64 3a 0a    if not sWord:.
52f0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
5300: 72 75 65 0a 20 20 20 20 69 66 20 6e 50 6f 73 20  rue.    if nPos 
5310: 69 6e 20 64 44 41 3a 0a 20 20 20 20 20 20 20 20  in dDA:.        
5320: 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20  return True.    
5330: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
5340: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
5350: 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66 20 6e  (sWord).    if n
5360: 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e  ot lMorph or len
5370: 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20  (lMorph) == 1:. 
5380: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
5390: 75 65 0a 20 20 20 20 6c 53 65 6c 65 63 74 20 3d  ue.    lSelect =
53a0: 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72 20 73   [ sMorph  for s
53b0: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20  Morph in lMorph 
53c0: 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 73 50   if re.search(sP
53d0: 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20  attern, sMorph) 
53e0: 5d 0a 20 20 20 20 69 66 20 6c 53 65 6c 65 63 74  ].    if lSelect
53f0: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c 65 6e  :.        if len
5400: 28 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c 65 6e  (lSelect) != len
5410: 28 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20  (lMorph):.      
5420: 20 20 20 20 20 20 64 44 41 5b 6e 50 6f 73 5d 20        dDA[nPos] 
5430: 3d 20 6c 53 65 6c 65 63 74 0a 20 20 20 20 65 6c  = lSelect.    el
5440: 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a 20 20 20  if lDefault:.   
5450: 20 20 20 20 20 64 44 41 5b 6e 50 6f 73 5d 20 3d       dDA[nPos] =
5460: 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20 72 65   lDefault.    re
5470: 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20  turn True...def 
5480: 65 78 63 6c 75 64 65 20 28 64 44 41 2c 20 6e 50  exclude (dDA, nP
5490: 6f 73 2c 20 73 57 6f 72 64 2c 20 73 50 61 74 74  os, sWord, sPatt
54a0: 65 72 6e 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f  ern, lDefault=No
54b0: 6e 65 29 3a 0a 20 20 20 20 69 66 20 6e 6f 74 20  ne):.    if not 
54c0: 73 57 6f 72 64 3a 0a 20 20 20 20 20 20 20 20 72  sWord:.        r
54d0: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 69  eturn True.    i
54e0: 66 20 6e 50 6f 73 20 69 6e 20 64 44 41 3a 0a 20  f nPos in dDA:. 
54f0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
5500: 75 65 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20  ue.    lMorph = 
5510: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
5520: 65 74 4d 6f 72 70 68 28 73 57 6f 72 64 29 0a 20  etMorph(sWord). 
5530: 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68     if not lMorph
5540: 20 6f 72 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 20   or len(lMorph) 
5550: 3d 3d 20 31 3a 0a 20 20 20 20 20 20 20 20 72 65  == 1:.        re
5560: 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 6c 53  turn True.    lS
5570: 65 6c 65 63 74 20 3d 20 5b 20 73 4d 6f 72 70 68  elect = [ sMorph
5580: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
5590: 6c 4d 6f 72 70 68 20 20 69 66 20 6e 6f 74 20 72  lMorph  if not r
55a0: 65 2e 73 65 61 72 63 68 28 73 50 61 74 74 65 72  e.search(sPatter
55b0: 6e 2c 20 73 4d 6f 72 70 68 29 20 5d 0a 20 20 20  n, sMorph) ].   
55c0: 20 69 66 20 6c 53 65 6c 65 63 74 3a 0a 20 20 20   if lSelect:.   
55d0: 20 20 20 20 20 69 66 20 6c 65 6e 28 6c 53 65 6c       if len(lSel
55e0: 65 63 74 29 20 21 3d 20 6c 65 6e 28 6c 4d 6f 72  ect) != len(lMor
55f0: 70 68 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ph):.           
5600: 20 64 44 41 5b 6e 50 6f 73 5d 20 3d 20 6c 53 65   dDA[nPos] = lSe
5610: 6c 65 63 74 0a 20 20 20 20 65 6c 69 66 20 6c 44  lect.    elif lD
5620: 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20  efault:.        
5630: 64 44 41 5b 6e 50 6f 73 5d 20 3d 20 6c 44 65 66  dDA[nPos] = lDef
5640: 61 75 6c 74 0a 20 20 20 20 72 65 74 75 72 6e 20  ault.    return 
5650: 54 72 75 65 0a 0a 0a 64 65 66 20 64 65 66 69 6e  True...def defin
5660: 65 20 28 64 44 41 2c 20 6e 50 6f 73 2c 20 6c 4d  e (dDA, nPos, lM
5670: 6f 72 70 68 29 3a 0a 20 20 20 20 64 44 41 5b 6e  orph):.    dDA[n
5680: 50 6f 73 5d 20 3d 20 6c 4d 6f 72 70 68 0a 20 20  Pos] = lMorph.  
5690: 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a    return True...
56a0: 23 23 23 23 20 47 52 41 4d 4d 41 52 20 43 48 45  #### GRAMMAR CHE
56b0: 43 4b 45 52 20 50 4c 55 47 49 4e 53 0a 0a 24 7b  CKER PLUGINS..${
56c0: 70 6c 75 67 69 6e 73 7d 0a 0a 0a 23 23 23 23 20  plugins}...#### 
56d0: 43 41 4c 4c 41 42 4c 45 53 20 28 67 65 6e 65 72  CALLABLES (gener
56e0: 61 74 65 64 20 63 6f 64 65 29 0a 0a 24 7b 63 61  ated code)..${ca
56f0: 6c 6c 61 62 6c 65 73 7d 0a 0a 0a 0a 23 23 23 23  llables}....####
5700: 20 54 4f 4b 45 4e 20 53 45 4e 54 45 4e 43 45 20   TOKEN SENTENCE 
5710: 43 48 45 43 4b 45 52 0a 0a 63 6c 61 73 73 20 54  CHECKER..class T
5720: 6f 6b 65 6e 53 65 6e 74 65 6e 63 65 3a 0a 0a 20  okenSentence:.. 
5730: 20 20 20 64 65 66 20 5f 5f 69 6e 69 74 5f 5f 20     def __init__ 
5740: 28 73 65 6c 66 2c 20 73 53 65 6e 74 65 6e 63 65  (self, sSentence
5750: 2c 20 73 53 65 6e 74 65 6e 63 65 30 2c 20 69 53  , sSentence0, iS
5760: 74 61 72 74 29 3a 0a 20 20 20 20 20 20 20 20 73  tart):.        s
5770: 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 20 3d 20  elf.sSentence = 
5780: 73 53 65 6e 74 65 6e 63 65 0a 20 20 20 20 20 20  sSentence.      
5790: 20 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65    self.sSentence
57a0: 30 20 3d 20 73 53 65 6e 74 65 6e 63 65 30 0a 20  0 = sSentence0. 
57b0: 20 20 20 20 20 20 20 73 65 6c 66 2e 69 53 74 61         self.iSta
57c0: 72 74 20 3d 20 69 53 74 61 72 74 0a 20 20 20 20  rt = iStart.    
57d0: 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 20      self.lToken 
57e0: 3d 20 6c 69 73 74 28 5f 6f 54 6f 6b 65 6e 69 7a  = list(_oTokeniz
57f0: 65 72 2e 67 65 6e 54 6f 6b 65 6e 73 28 73 53 65  er.genTokens(sSe
5800: 6e 74 65 6e 63 65 2c 20 54 72 75 65 29 29 0a 0a  ntence, True))..
5810: 20 20 20 20 64 65 66 20 5f 67 65 74 4e 65 78 74      def _getNext
5820: 4d 61 74 63 68 69 6e 67 4e 6f 64 65 73 20 28 73  MatchingNodes (s
5830: 65 6c 66 2c 20 64 54 6f 6b 65 6e 2c 20 64 4e 6f  elf, dToken, dNo
5840: 64 65 29 3a 0a 20 20 20 20 20 20 20 20 22 67 65  de):.        "ge
5850: 6e 65 72 61 74 6f 72 3a 20 72 65 74 75 72 6e 20  nerator: return 
5860: 6e 6f 64 65 73 20 77 68 65 72 65 20 3c 64 54 6f  nodes where <dTo
5870: 6b 65 6e 3e 20 e2 80 9c 76 61 6c 75 65 73 e2 80  ken> ...values..
5880: 9d 20 6d 61 74 63 68 20 3c 64 4e 6f 64 65 3e 20  . match <dNode> 
5890: 61 72 63 73 22 0a 20 20 20 20 20 20 20 20 23 20  arcs".        # 
58a0: 74 6f 6b 65 6e 20 76 61 6c 75 65 0a 20 20 20 20  token value.    
58b0: 20 20 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73      if dToken["s
58c0: 56 61 6c 75 65 22 5d 20 69 6e 20 64 4e 6f 64 65  Value"] in dNode
58d0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 70  :.            #p
58e0: 72 69 6e 74 28 22 76 61 6c 75 65 20 66 6f 75 6e  rint("value foun
58f0: 64 3a 20 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56  d: ", dToken["sV
5900: 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20 20  alue"]).        
5910: 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68      yield dGraph
5920: 5b 64 4e 6f 64 65 5b 64 54 6f 6b 65 6e 5b 22 73  [dNode[dToken["s
5930: 56 61 6c 75 65 22 5d 5d 5d 0a 20 20 20 20 20 20  Value"]]].      
5940: 20 20 23 20 74 6f 6b 65 6e 20 6c 65 6d 6d 61 73    # token lemmas
5950: 0a 20 20 20 20 20 20 20 20 69 66 20 22 3c 6c 65  .        if "<le
5960: 6d 6d 61 73 3e 22 20 69 6e 20 64 4e 6f 64 65 3a  mmas>" in dNode:
5970: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
5980: 20 73 4c 65 6d 6d 61 20 69 6e 20 5f 6f 53 70 65   sLemma in _oSpe
5990: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d  llChecker.getLem
59a0: 6d 61 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ma(dToken["sValu
59b0: 65 22 5d 29 3a 0a 20 20 20 20 20 20 20 20 20 20  e"]):.          
59c0: 20 20 20 20 20 20 69 66 20 73 4c 65 6d 6d 61 20        if sLemma 
59d0: 69 6e 20 64 4e 6f 64 65 5b 22 3c 6c 65 6d 6d 61  in dNode["<lemma
59e0: 73 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20  s>"]:.          
59f0: 20 20 20 20 20 20 20 20 20 20 23 70 72 69 6e 74            #print
5a00: 28 22 6c 65 6d 6d 61 20 66 6f 75 6e 64 3a 20 22  ("lemma found: "
5a10: 2c 20 73 4c 65 6d 6d 61 29 0a 20 20 20 20 20 20  , sLemma).      
5a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69                yi
5a30: 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65  eld dGraph[dNode
5a40: 5b 22 3c 6c 65 6d 6d 61 73 3e 22 5d 5b 73 4c 65  ["<lemmas>"][sLe
5a50: 6d 6d 61 5d 5d 0a 20 20 20 20 20 20 20 20 23 20  mma]].        # 
5a60: 75 6e 69 76 65 72 73 61 6c 20 61 72 63 0a 20 20  universal arc.  
5a70: 20 20 20 20 20 20 69 66 20 22 2a 22 20 69 6e 20        if "*" in 
5a80: 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20  dNode:.         
5a90: 20 20 20 23 70 72 69 6e 74 28 22 67 65 6e 65 72     #print("gener
5aa0: 69 63 20 61 72 63 22 29 0a 20 20 20 20 20 20 20  ic arc").       
5ab0: 20 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70       yield dGrap
5ac0: 68 5b 64 4e 6f 64 65 5b 22 2a 22 5d 5d 0a 20 20  h[dNode["*"]].  
5ad0: 20 20 20 20 20 20 23 20 72 65 67 65 78 20 76 61        # regex va
5ae0: 6c 75 65 20 61 72 63 73 0a 20 20 20 20 20 20 20  lue arcs.       
5af0: 20 69 66 20 22 3c 72 65 5f 76 61 6c 75 65 3e 22   if "<re_value>"
5b00: 20 69 6e 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20   in dNode:.     
5b10: 20 20 20 20 20 20 20 66 6f 72 20 73 52 65 67 65         for sRege
5b20: 78 20 69 6e 20 64 4e 6f 64 65 5b 22 3c 72 65 5f  x in dNode["<re_
5b30: 76 61 6c 75 65 3e 22 5d 3a 0a 20 20 20 20 20 20  value>"]:.      
5b40: 20 20 20 20 20 20 20 20 20 20 69 66 20 72 65 2e            if re.
5b50: 73 65 61 72 63 68 28 73 52 65 67 65 78 2c 20 64  search(sRegex, d
5b60: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29  Token["sValue"])
5b70: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5b80: 20 20 20 20 20 20 23 70 72 69 6e 74 28 22 76 61        #print("va
5b90: 6c 75 65 20 72 65 67 65 78 20 6d 61 74 63 68 69  lue regex matchi
5ba0: 6e 67 3a 20 22 2c 20 73 52 65 67 65 78 29 0a 20  ng: ", sRegex). 
5bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5bc0: 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b     yield dGraph[
5bd0: 64 4e 6f 64 65 5b 22 3c 72 65 5f 76 61 6c 75 65  dNode["<re_value
5be0: 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 20 20 20  >"][sRegex]].   
5bf0: 20 20 20 20 20 23 20 72 65 67 65 78 20 6d 6f 72       # regex mor
5c00: 70 68 20 61 72 63 73 0a 20 20 20 20 20 20 20 20  ph arcs.        
5c10: 69 66 20 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 20  if "<re_morph>" 
5c20: 69 6e 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20  in dNode:.      
5c30: 20 20 20 20 20 20 66 6f 72 20 73 52 65 67 65 78        for sRegex
5c40: 20 69 6e 20 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d   in dNode["<re_m
5c50: 6f 72 70 68 3e 22 5d 3a 0a 20 20 20 20 20 20 20  orph>"]:.       
5c60: 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 4d 6f           for sMo
5c70: 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68  rph in _oSpellCh
5c80: 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64  ecker.getMorph(d
5c90: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29  Token["sValue"])
5ca0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5cb0: 20 20 20 20 20 20 69 66 20 72 65 2e 73 65 61 72        if re.sear
5cc0: 63 68 28 73 52 65 67 65 78 2c 20 73 4d 6f 72 70  ch(sRegex, sMorp
5cd0: 68 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  h):.            
5ce0: 20 20 20 20 20 20 20 20 20 20 20 20 23 70 72 69              #pri
5cf0: 6e 74 28 22 6d 6f 72 70 68 20 72 65 67 65 78 20  nt("morph regex 
5d00: 6d 61 74 63 68 69 6e 67 3a 20 22 2c 20 73 52 65  matching: ", sRe
5d10: 67 65 78 29 0a 20 20 20 20 20 20 20 20 20 20 20  gex).           
5d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65               yie
5d30: 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b  ld dGraph[dNode[
5d40: 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 5d 5b 73 52  "<re_morph>"][sR
5d50: 65 67 65 78 5d 5d 0a 0a 20 20 20 20 64 65 66 20  egex]]..    def 
5d60: 70 61 72 73 65 20 28 73 65 6c 66 2c 20 64 50 72  parse (self, dPr
5d70: 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e 74 72 79  iority, sCountry
5d80: 3d 22 24 7b 63 6f 75 6e 74 72 79 5f 64 65 66 61  ="${country_defa
5d90: 75 6c 74 7d 22 2c 20 64 4f 70 74 69 6f 6e 73 3d  ult}", dOptions=
5da0: 4e 6f 6e 65 2c 20 62 53 68 6f 77 52 75 6c 65 49  None, bShowRuleI
5db0: 64 3d 46 61 6c 73 65 2c 20 62 44 65 62 75 67 3d  d=False, bDebug=
5dc0: 46 61 6c 73 65 2c 20 62 43 6f 6e 74 65 78 74 3d  False, bContext=
5dd0: 46 61 6c 73 65 29 3a 0a 20 20 20 20 20 20 20 20  False):.        
5de0: 64 45 72 72 20 3d 20 7b 7d 0a 20 20 20 20 20 20  dErr = {}.      
5df0: 20 20 64 50 72 69 6f 72 69 74 79 20 3d 20 7b 7d    dPriority = {}
5e00: 20 20 23 20 4b 65 79 20 3d 20 70 6f 73 69 74 69    # Key = positi
5e10: 6f 6e 3b 20 76 61 6c 75 65 20 3d 20 70 72 69 6f  on; value = prio
5e20: 72 69 74 79 0a 20 20 20 20 20 20 20 20 64 4f 70  rity.        dOp
5e30: 74 20 3d 20 5f 64 4f 70 74 69 6f 6e 73 20 20 69  t = _dOptions  i
5e40: 66 20 6e 6f 74 20 64 4f 70 74 69 6f 6e 73 20 20  f not dOptions  
5e50: 65 6c 73 65 20 64 4f 70 74 69 6f 6e 73 0a 20 20  else dOptions.  
5e60: 20 20 20 20 20 20 6c 50 6f 69 6e 74 65 72 20 3d        lPointer =
5e70: 20 5b 5d 0a 20 20 20 20 20 20 20 20 62 43 68 61   [].        bCha
5e80: 6e 67 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20  nge = False.    
5e90: 20 20 20 20 66 6f 72 20 64 54 6f 6b 65 6e 20 69      for dToken i
5ea0: 6e 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 3a 0a 20  n self.lToken:. 
5eb0: 20 20 20 20 20 20 20 20 20 20 20 23 20 63 68 65             # che
5ec0: 63 6b 20 61 72 63 73 20 66 6f 72 20 65 61 63 68  ck arcs for each
5ed0: 20 65 78 69 73 74 69 6e 67 20 70 6f 69 6e 74 65   existing pointe
5ee0: 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e  r.            lN
5ef0: 65 77 50 6f 69 6e 74 65 72 20 3d 20 5b 5d 0a 20  ewPointer = []. 
5f00: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 69             for i
5f10: 2c 20 64 50 6f 69 6e 74 65 72 20 69 6e 20 65 6e  , dPointer in en
5f20: 75 6d 65 72 61 74 65 28 6c 50 6f 69 6e 74 65 72  umerate(lPointer
5f30: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
5f40: 20 20 20 62 56 61 6c 69 64 20 3d 20 46 61 6c 73     bValid = Fals
5f50: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
5f60: 20 20 62 46 69 72 73 74 20 3d 20 54 72 75 65 0a    bFirst = True.
5f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f80: 66 6f 72 20 64 4e 6f 64 65 20 69 6e 20 73 65 6c  for dNode in sel
5f90: 66 2e 5f 67 65 74 4e 65 78 74 4d 61 74 63 68 69  f._getNextMatchi
5fa0: 6e 67 4e 6f 64 65 73 28 64 54 6f 6b 65 6e 2c 20  ngNodes(dToken, 
5fb0: 64 50 6f 69 6e 74 65 72 5b 22 64 4e 6f 64 65 22  dPointer["dNode"
5fc0: 5d 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ]):.            
5fd0: 20 20 20 20 20 20 20 20 69 66 20 62 46 69 72 73          if bFirs
5fe0: 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  t:.             
5ff0: 20 20 20 20 20 20 20 20 20 20 20 64 50 6f 69 6e             dPoin
6000: 74 65 72 5b 22 64 4e 6f 64 65 22 5d 20 3d 20 64  ter["dNode"] = d
6010: 4e 6f 64 65 0a 20 20 20 20 20 20 20 20 20 20 20  Node.           
6020: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
6030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6040: 20 20 20 20 20 20 20 6c 4e 65 77 50 6f 69 6e 74         lNewPoint
6050: 65 72 2e 61 70 70 65 6e 64 28 7b 22 6e 4f 66 66  er.append({"nOff
6060: 73 65 74 22 3a 20 64 50 6f 69 6e 74 65 72 5b 22  set": dPointer["
6070: 6e 4f 66 66 73 65 74 22 5d 2c 20 22 64 4e 6f 64  nOffset"], "dNod
6080: 65 22 3a 20 64 4e 6f 64 65 7d 29 0a 20 20 20 20  e": dNode}).    
6090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60a0: 62 46 69 72 73 74 20 3d 20 46 61 6c 73 65 0a 20  bFirst = False. 
60b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60c0: 20 20 20 62 56 61 6c 69 64 20 3d 20 54 72 75 65     bValid = True
60d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
60e0: 20 69 66 20 6e 6f 74 20 62 56 61 6c 69 64 3a 0a   if not bValid:.
60f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6100: 20 20 20 20 64 65 6c 20 6c 50 6f 69 6e 74 65 72      del lPointer
6110: 5b 69 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  [i].            
6120: 6c 50 6f 69 6e 74 65 72 2e 65 78 74 65 6e 64 28  lPointer.extend(
6130: 6c 4e 65 77 50 6f 69 6e 74 65 72 29 0a 20 20 20  lNewPointer).   
6140: 20 20 20 20 20 20 20 20 20 23 20 63 68 65 63 6b           # check
6150: 20 61 72 63 73 20 6f 66 20 66 69 72 73 74 20 6e   arcs of first n
6160: 6f 64 65 73 0a 20 20 20 20 20 20 20 20 20 20 20  odes.           
6170: 20 66 6f 72 20 64 4e 6f 64 65 20 69 6e 20 73 65   for dNode in se
6180: 6c 66 2e 5f 67 65 74 4e 65 78 74 4d 61 74 63 68  lf._getNextMatch
6190: 69 6e 67 4e 6f 64 65 73 28 64 54 6f 6b 65 6e 2c  ingNodes(dToken,
61a0: 20 64 47 72 61 70 68 5b 30 5d 29 3a 0a 20 20 20   dGraph[0]):.   
61b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 50 6f               lPo
61c0: 69 6e 74 65 72 2e 61 70 70 65 6e 64 28 7b 22 6e  inter.append({"n
61d0: 4f 66 66 73 65 74 22 3a 20 64 54 6f 6b 65 6e 5b  Offset": dToken[
61e0: 22 69 22 5d 2c 20 22 64 4e 6f 64 65 22 3a 20 64  "i"], "dNode": d
61f0: 4e 6f 64 65 7d 29 0a 20 20 20 20 20 20 20 20 20  Node}).         
6200: 20 20 20 23 20 63 68 65 63 6b 20 69 66 20 74 68     # check if th
6210: 65 72 65 20 69 73 20 72 75 6c 65 73 20 74 6f 20  ere is rules to 
6220: 63 68 65 63 6b 20 66 6f 72 20 65 61 63 68 20 70  check for each p
6230: 6f 69 6e 74 65 72 0a 20 20 20 20 20 20 20 20 20  ointer.         
6240: 20 20 20 66 6f 72 20 64 50 6f 69 6e 74 65 72 20     for dPointer 
6250: 69 6e 20 6c 50 6f 69 6e 74 65 72 3a 0a 20 20 20  in lPointer:.   
6260: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
6270: 22 3c 72 75 6c 65 73 3e 22 20 69 6e 20 64 50 6f  "<rules>" in dPo
6280: 69 6e 74 65 72 5b 22 64 4e 6f 64 65 22 5d 3a 0a  inter["dNode"]:.
6290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
62a0: 20 20 20 20 62 48 61 73 43 68 61 6e 67 65 64 2c      bHasChanged,
62b0: 20 65 72 72 73 20 3d 20 73 65 6c 66 2e 5f 65 78   errs = self._ex
62c0: 65 63 75 74 65 41 63 74 69 6f 6e 73 28 64 50 6f  ecuteActions(dPo
62d0: 69 6e 74 65 72 5b 22 64 4e 6f 64 65 22 5d 5b 22  inter["dNode"]["
62e0: 3c 72 75 6c 65 73 3e 22 5d 2c 20 64 50 6f 69 6e  <rules>"], dPoin
62f0: 74 65 72 5b 22 6e 4f 66 66 73 65 74 22 5d 2c 20  ter["nOffset"], 
6300: 64 50 72 69 6f 72 69 74 79 2c 20 64 4f 70 74 2c  dPriority, dOpt,
6310: 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 43   bShowRuleId, bC
6320: 6f 6e 74 65 78 74 29 0a 20 20 20 20 20 20 20 20  ontext).        
6330: 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72              dErr
6340: 2e 75 70 64 61 74 65 28 65 72 72 73 29 0a 20 20  .update(errs).  
6350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6360: 20 20 69 66 20 62 48 61 73 43 68 61 6e 67 65 64    if bHasChanged
6370: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
6380: 20 20 20 20 20 20 20 20 20 20 62 43 68 61 6e 67            bChang
6390: 65 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20  e = True.       
63a0: 20 69 66 20 64 45 72 72 3a 0a 20 20 20 20 20 20   if dErr:.      
63b0: 20 20 20 20 20 20 70 72 69 6e 74 28 64 45 72 72        print(dErr
63c0: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
63d0: 20 28 62 43 68 61 6e 67 65 2c 20 64 45 72 72 29   (bChange, dErr)
63e0: 0a 0a 20 20 20 20 64 65 66 20 5f 65 78 65 63 75  ..    def _execu
63f0: 74 65 41 63 74 69 6f 6e 73 20 28 73 65 6c 66 2c  teActions (self,
6400: 20 64 4e 6f 64 65 2c 20 6e 54 6f 6b 65 6e 4f 66   dNode, nTokenOf
6410: 66 73 65 74 2c 20 64 50 72 69 6f 72 69 74 79 2c  fset, dPriority,
6420: 20 64 4f 70 74 2c 20 62 53 68 6f 77 52 75 6c 65   dOpt, bShowRule
6430: 49 64 2c 20 62 43 6f 6e 74 65 78 74 29 3a 0a 20  Id, bContext):. 
6440: 20 20 20 20 20 20 20 23 70 72 69 6e 74 28 6c 6f         #print(lo
6450: 63 61 6c 73 28 29 29 0a 20 20 20 20 20 20 20 20  cals()).        
6460: 64 45 72 72 73 20 3d 20 7b 7d 0a 20 20 20 20 20  dErrs = {}.     
6470: 20 20 20 62 43 68 61 6e 67 65 20 3d 20 46 61 6c     bChange = Fal
6480: 73 65 0a 20 20 20 20 20 20 20 20 66 6f 72 20 73  se.        for s
6490: 4c 69 6e 65 49 64 2c 20 6e 65 78 74 4e 6f 64 65  LineId, nextNode
64a0: 4b 65 79 20 69 6e 20 64 4e 6f 64 65 2e 69 74 65  Key in dNode.ite
64b0: 6d 73 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ms():.          
64c0: 20 20 66 6f 72 20 73 52 75 6c 65 49 64 20 69 6e    for sRuleId in
64d0: 20 64 47 72 61 70 68 5b 6e 65 78 74 4e 6f 64 65   dGraph[nextNode
64e0: 4b 65 79 5d 3a 0a 20 20 20 20 20 20 20 20 20 20  Key]:.          
64f0: 20 20 20 20 20 20 70 72 69 6e 74 28 73 52 75 6c        print(sRul
6500: 65 49 64 29 0a 20 20 20 20 20 20 20 20 20 20 20  eId).           
6510: 20 20 20 20 20 62 43 6f 6e 64 4d 65 6d 6f 20 3d       bCondMemo =
6520: 20 4e 6f 6e 65 0a 20 20 20 20 20 20 20 20 20 20   None.          
6530: 20 20 20 20 20 20 73 46 75 6e 63 43 6f 6e 64 2c        sFuncCond,
6540: 20 63 41 63 74 69 6f 6e 54 79 70 65 2c 20 73 57   cActionType, sW
6550: 68 61 74 2c 20 2a 65 41 63 74 20 3d 20 64 52 75  hat, *eAct = dRu
6560: 6c 65 5b 73 52 75 6c 65 49 64 5d 0a 20 20 20 20  le[sRuleId].    
6570: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61 63              # ac
6580: 74 69 6f 6e 20 69 6e 20 6c 41 63 74 69 6f 6e 73  tion in lActions
6590: 3a 20 5b 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 61  : [ condition, a
65a0: 63 74 69 6f 6e 20 74 79 70 65 2c 20 72 65 70 6c  ction type, repl
65b0: 61 63 65 6d 65 6e 74 2f 73 75 67 67 65 73 74 69  acement/suggesti
65c0: 6f 6e 2f 61 63 74 69 6f 6e 5b 2c 20 69 54 6f 6b  on/action[, iTok
65d0: 65 6e 53 74 61 72 74 2c 20 69 54 6f 6b 65 6e 45  enStart, iTokenE
65e0: 6e 64 5b 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20  nd[, nPriority, 
65f0: 6d 65 73 73 61 67 65 2c 20 55 52 4c 5d 5d 20 5d  message, URL]] ]
6600: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6610: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20   try:.          
6620: 20 20 20 20 20 20 20 20 20 20 62 43 6f 6e 64 4d            bCondM
6630: 65 6d 6f 20 3d 20 6e 6f 74 20 73 46 75 6e 63 43  emo = not sFuncC
6640: 6f 6e 64 20 6f 72 20 67 6c 6f 62 61 6c 73 28 29  ond or globals()
6650: 5b 73 46 75 6e 63 43 6f 6e 64 5d 28 73 65 6c 66  [sFuncCond](self
6660: 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f 6e  , sCountry, bCon
6670: 64 4d 65 6d 6f 29 0a 20 20 20 20 20 20 20 20 20  dMemo).         
6680: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 43             if bC
6690: 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20 20 20 20  ondMemo:.       
66a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66b0: 20 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20   if cActionType 
66c0: 3d 3d 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20  == "-":.        
66d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66e0: 20 20 20 20 23 20 67 72 61 6d 6d 61 72 20 65 72      # grammar er
66f0: 72 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20  ror.            
6700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6710: 70 72 69 6e 74 28 22 2d 22 29 0a 20 20 20 20 20  print("-").     
6720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6730: 20 20 20 20 20 20 20 6e 54 6f 6b 65 6e 45 72 72         nTokenErr
6740: 6f 72 53 74 61 72 74 20 3d 20 6e 54 6f 6b 65 6e  orStart = nToken
6750: 4f 66 66 73 65 74 20 2b 20 65 41 63 74 5b 30 5d  Offset + eAct[0]
6760: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6770: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 54 6f               nTo
6780: 6b 65 6e 45 72 72 6f 72 45 6e 64 20 3d 20 6e 54  kenErrorEnd = nT
6790: 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65 41 63  okenOffset + eAc
67a0: 74 5b 31 5d 0a 20 20 20 20 20 20 20 20 20 20 20  t[1].           
67b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
67c0: 20 6e 45 72 72 6f 72 53 74 61 72 74 20 3d 20 73   nErrorStart = s
67d0: 65 6c 66 2e 69 53 74 61 72 74 20 2b 20 73 65 6c  elf.iStart + sel
67e0: 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 45  f.lToken[nTokenE
67f0: 72 72 6f 72 53 74 61 72 74 5d 5b 22 6e 53 74 61  rrorStart]["nSta
6800: 72 74 22 5d 0a 20 20 20 20 20 20 20 20 20 20 20  rt"].           
6810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6820: 20 6e 45 72 72 6f 72 45 6e 64 20 3d 20 73 65 6c   nErrorEnd = sel
6830: 66 2e 69 53 74 61 72 74 20 2b 20 73 65 6c 66 2e  f.iStart + self.
6840: 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 45 72 72  lToken[nTokenErr
6850: 6f 72 45 6e 64 5d 5b 22 6e 45 6e 64 22 5d 0a 20  orEnd]["nEnd"]. 
6860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6870: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 45             if nE
6880: 72 72 6f 72 53 74 61 72 74 20 6e 6f 74 20 69 6e  rrorStart not in
6890: 20 64 45 72 72 73 20 6f 72 20 65 41 63 74 5b 32   dErrs or eAct[2
68a0: 5d 20 3e 20 64 50 72 69 6f 72 69 74 79 5b 6e 45  ] > dPriority[nE
68b0: 72 72 6f 72 53 74 61 72 74 5d 3a 0a 20 20 20 20  rrorStart]:.    
68c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
68d0: 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72              dErr
68e0: 73 5b 6e 45 72 72 6f 72 53 74 61 72 74 5d 20 3d  s[nErrorStart] =
68f0: 20 5f 63 72 65 61 74 65 54 6f 6b 65 6e 45 72 72   _createTokenErr
6900: 6f 72 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e 2c 20  or(self.lToken, 
6910: 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 2c 20  self.sSentence, 
6920: 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 30 2c  self.sSentence0,
6930: 20 73 57 68 61 74 2c 20 6e 54 6f 6b 65 6e 45 72   sWhat, nTokenEr
6940: 72 6f 72 53 74 61 72 74 2c 20 6e 45 72 72 6f 72  rorStart, nError
6950: 53 74 61 72 74 2c 20 6e 45 72 72 6f 72 45 6e 64  Start, nErrorEnd
6960: 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65  , sLineId, sRule
6970: 49 64 2c 20 54 72 75 65 2c 20 65 41 63 74 5b 33  Id, True, eAct[3
6980: 5d 2c 20 65 41 63 74 5b 34 5d 2c 20 62 53 68 6f  ], eAct[4], bSho
6990: 77 52 75 6c 65 49 64 2c 20 22 6e 6f 74 79 70 65  wRuleId, "notype
69a0: 22 2c 20 62 43 6f 6e 74 65 78 74 29 0a 20 20 20  ", bContext).   
69b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 50 72               dPr
69d0: 69 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53 74 61  iority[nErrorSta
69e0: 72 74 5d 20 3d 20 65 41 63 74 5b 32 5d 0a 20 20  rt] = eAct[2].  
69f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a00: 20 20 20 20 20 20 65 6c 69 66 20 63 41 63 74 69        elif cActi
6a10: 6f 6e 54 79 70 65 20 3d 3d 20 22 7e 22 3a 0a 20  onType == "~":. 
6a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a30: 20 20 20 20 20 20 20 20 20 20 20 23 20 74 65 78             # tex
6a40: 74 20 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20  t processor.    
6a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a60: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 7e          print("~
6a70: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ").             
6a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
6a90: 65 6c 66 2e 5f 72 65 77 72 69 74 65 28 73 57 68  elf._rewrite(sWh
6aa0: 61 74 2c 20 6e 45 72 72 6f 72 53 74 61 72 74 2c  at, nErrorStart,
6ab0: 20 6e 45 72 72 6f 72 45 6e 64 29 0a 20 20 20 20   nErrorEnd).    
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ad0: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
6ae0: 54 79 70 65 20 3d 3d 20 22 40 22 3a 0a 20 20 20  Type == "@":.   
6af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b00: 20 20 20 20 20 20 20 20 20 23 20 6a 75 6d 70 0a           # jump.
6b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b20: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
6b30: 74 28 22 40 22 29 0a 20 20 20 20 20 20 20 20 20  t("@").         
6b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b50: 20 20 20 73 65 6c 66 2e 5f 6a 75 6d 70 28 73 57     self._jump(sW
6b60: 68 61 74 29 0a 20 20 20 20 20 20 20 20 20 20 20  hat).           
6b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69               eli
6b80: 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d  f cActionType ==
6b90: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "=":.          
6ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6bb0: 20 20 23 20 64 69 73 61 6d 62 69 67 75 61 74 69    # disambiguati
6bc0: 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  on.             
6bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
6be0: 72 69 6e 74 28 22 3d 22 29 0a 20 20 20 20 20 20  rint("=").      
6bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c00: 20 20 20 20 20 20 67 6c 6f 62 61 6c 73 28 29 5b        globals()[
6c10: 73 57 68 61 74 5d 28 73 65 6c 66 2e 6c 54 6f 6b  sWhat](self.lTok
6c20: 65 6e 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  en).            
6c30: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66              elif
6c40: 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20   cActionType == 
6c50: 22 3e 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ">":.           
6c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c70: 20 23 20 77 65 20 64 6f 20 6e 6f 74 68 69 6e 67   # we do nothing
6c80: 2c 20 74 68 69 73 20 74 65 73 74 20 69 73 20 6a  , this test is j
6c90: 75 73 74 20 61 20 63 6f 6e 64 69 74 69 6f 6e 20  ust a condition 
6ca0: 74 6f 20 61 70 70 6c 79 20 61 6c 6c 20 66 6f 6c  to apply all fol
6cb0: 6c 6f 77 69 6e 67 20 61 63 74 69 6f 6e 73 0a 20  lowing actions. 
6cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6cd0: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
6ce0: 28 22 3e 22 29 0a 20 20 20 20 20 20 20 20 20 20  (">").          
6cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d00: 20 20 70 61 73 73 0a 20 20 20 20 20 20 20 20 20    pass.         
6d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
6d20: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
6d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d40: 20 70 72 69 6e 74 28 22 23 20 65 72 72 6f 72 3a   print("# error:
6d50: 20 75 6e 6b 6e 6f 77 6e 20 61 63 74 69 6f 6e 20   unknown action 
6d60: 61 74 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a  at " + sLineId).
6d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d80: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
6d90: 54 79 70 65 20 3d 3d 20 22 3e 22 3a 0a 20 20 20  Type == ">":.   
6da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6db0: 20 20 20 20 20 62 72 65 61 6b 0a 20 20 20 20 20       break.     
6dc0: 20 20 20 20 20 20 20 20 20 20 20 65 78 63 65 70             excep
6dd0: 74 20 45 78 63 65 70 74 69 6f 6e 20 61 73 20 65  t Exception as e
6de0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
6df0: 20 20 20 20 20 20 72 61 69 73 65 20 45 78 63 65        raise Exce
6e00: 70 74 69 6f 6e 28 73 74 72 28 65 29 2c 20 73 4c  ption(str(e), sL
6e10: 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20 72  ineId).        r
6e20: 65 74 75 72 6e 20 62 43 68 61 6e 67 65 2c 20 64  eturn bChange, d
6e30: 45 72 72 73 0a 0a 20 20 20 20 64 65 66 20 5f 72  Errs..    def _r
6e40: 65 77 72 69 74 65 20 28 73 65 6c 66 2c 20 73 57  ewrite (self, sW
6e50: 68 61 74 2c 20 6e 45 72 72 6f 72 53 74 61 72 74  hat, nErrorStart
6e60: 2c 20 6e 45 72 72 6f 72 45 6e 64 29 3a 0a 20 20  , nErrorEnd):.  
6e70: 20 20 20 20 20 20 22 74 65 78 74 20 70 72 6f 63        "text proc
6e80: 65 73 73 6f 72 3a 20 72 65 77 72 69 74 65 20 74  essor: rewrite t
6e90: 6f 6b 65 6e 73 20 62 65 74 77 65 65 6e 20 3c 6e  okens between <n
6ea0: 45 72 72 6f 72 53 74 61 72 74 3e 20 61 6e 64 20  ErrorStart> and 
6eb0: 3c 6e 45 72 72 6f 72 45 6e 64 3e 20 70 6f 73 69  <nErrorEnd> posi
6ec0: 74 69 6f 6e 22 0a 20 20 20 20 20 20 20 20 6c 54  tion".        lT
6ed0: 6f 6b 65 6e 56 61 6c 75 65 20 3d 20 73 57 68 61  okenValue = sWha
6ee0: 74 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20  t.split("|").   
6ef0: 20 20 20 20 20 69 66 20 6c 65 6e 28 6c 54 6f 6b       if len(lTok
6f00: 65 6e 56 61 6c 75 65 29 20 21 3d 20 28 6e 45 72  enValue) != (nEr
6f10: 72 6f 72 45 6e 64 20 2d 20 6e 45 72 72 6f 72 53  rorEnd - nErrorS
6f20: 74 61 72 74 20 2b 20 31 29 3a 0a 20 20 20 20 20  tart + 1):.     
6f30: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72         print("Er
6f40: 72 6f 72 2e 20 54 65 78 74 20 70 72 6f 63 65 73  ror. Text proces
6f50: 73 6f 72 3a 20 6e 75 6d 62 65 72 20 6f 66 20 72  sor: number of r
6f60: 65 70 6c 61 63 65 6d 65 6e 74 73 20 21 3d 20 6e  eplacements != n
6f70: 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 2e  umber of tokens.
6f80: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  ").            r
6f90: 65 74 75 72 6e 0a 20 20 20 20 20 20 20 20 66 6f  eturn.        fo
6fa0: 72 20 69 2c 20 73 56 61 6c 75 65 20 69 6e 20 7a  r i, sValue in z
6fb0: 69 70 28 72 61 6e 67 65 28 6e 45 72 72 6f 72 53  ip(range(nErrorS
6fc0: 74 61 72 74 2c 20 6e 45 72 72 6f 72 45 6e 64 2b  tart, nErrorEnd+
6fd0: 31 29 2c 20 6c 54 6f 6b 65 6e 56 61 6c 75 65 29  1), lTokenValue)
6fe0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65  :.            se
6ff0: 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 5d 5b 22 73 56  lf.lToken[i]["sV
7000: 61 6c 75 65 22 5d 20 3d 20 73 56 61 6c 75 65 0a  alue"] = sValue.
7010: 0a 20 20 20 20 64 65 66 20 5f 6a 75 6d 70 20 28  .    def _jump (
7020: 73 65 6c 66 2c 20 73 57 68 61 74 29 3a 0a 20 20  self, sWhat):.  
7030: 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20        try:.     
7040: 20 20 20 20 20 20 20 6e 46 72 6f 6d 2c 20 6e 54         nFrom, nT
7050: 6f 20 3d 20 73 57 68 61 74 2e 73 70 6c 69 74 28  o = sWhat.split(
7060: 22 3e 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  ">").           
7070: 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 6e 74   self.lToken[int
7080: 28 6e 46 72 6f 6d 29 5d 5b 22 69 4a 75 6d 70 22  (nFrom)]["iJump"
7090: 5d 20 3d 20 69 6e 74 28 6e 54 6f 29 0a 20 20 20  ] = int(nTo).   
70a0: 20 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20       except:.   
70b0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
70c0: 23 20 45 72 72 6f 72 2e 20 4a 75 6d 70 20 66 61  # Error. Jump fa
70d0: 69 6c 65 64 3a 20 22 2c 20 73 57 68 61 74 29 0a  iled: ", sWhat).
70e0: 20 20 20 20 20 20 20 20 20 20 20 20 74 72 61 63              trac
70f0: 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63 28  eback.print_exc(
7100: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  ).            re
7110: 74 75 72 6e 0a 0a 0a 23 23 23 23 20 41 6e 61 6c  turn...#### Anal
7120: 79 73 65 20 74 6f 6b 65 6e 73 0a 0a 64 65 66 20  yse tokens..def 
7130: 67 5f 6d 6f 72 70 68 20 28 64 54 6f 6b 65 6e 2c  g_morph (dToken,
7140: 20 73 50 61 74 74 65 72 6e 2c 20 62 53 74 72 69   sPattern, bStri
7150: 63 74 3d 54 72 75 65 29 3a 0a 20 20 20 20 22 61  ct=True):.    "a
7160: 6e 61 6c 79 73 65 20 61 20 74 6f 6b 65 6e 2c 20  nalyse a token, 
7170: 72 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 3c  return True if <
7180: 73 50 61 74 74 65 72 6e 3e 20 69 6e 20 6d 6f 72  sPattern> in mor
7190: 70 68 6f 6c 6f 67 69 65 73 22 0a 20 20 20 20 69  phologies".    i
71a0: 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54  f "lMorph" in dT
71b0: 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20 6c 4d  oken:.        lM
71c0: 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c  orph = dToken["l
71d0: 4d 6f 72 70 68 22 5d 0a 20 20 20 20 65 6c 73 65  Morph"].    else
71e0: 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72 70 68  :.        lMorph
71f0: 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65   = _oSpellChecke
7200: 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65  r.getMorph(dToke
7210: 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20  n["sValue"]).   
7220: 20 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72       if not lMor
7230: 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ph:.            
7240: 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20  return False.   
7250: 20 7a 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63   zPattern = re.c
7260: 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29  ompile(sPattern)
7270: 0a 20 20 20 20 69 66 20 62 53 74 72 69 63 74 3a  .    if bStrict:
7280: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
7290: 61 6c 6c 28 7a 50 61 74 74 65 72 6e 2e 73 65 61  all(zPattern.sea
72a0: 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72  rch(sMorph)  for
72b0: 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70   sMorph in lMorp
72c0: 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e  h).    return an
72d0: 79 28 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63  y(zPattern.searc
72e0: 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73  h(sMorph)  for s
72f0: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29  Morph in lMorph)
7300: 0a 0a 64 65 66 20 67 5f 6d 6f 72 70 68 65 78 20  ..def g_morphex 
7310: 28 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72  (dToken, sPatter
7320: 6e 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 29 3a  n, sNegPattern):
7330: 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20  .    "analyse a 
7340: 74 6f 6b 65 6e 2c 20 72 65 74 75 72 6e 20 54 72  token, return Tr
7350: 75 65 20 69 66 20 3c 73 4e 65 67 50 61 74 74 65  ue if <sNegPatte
7360: 72 6e 3e 20 6e 6f 74 20 69 6e 20 6d 6f 72 70 68  rn> not in morph
7370: 6f 6c 6f 67 69 65 73 20 61 6e 64 20 3c 73 50 61  ologies and <sPa
7380: 74 74 65 72 6e 3e 20 69 6e 20 6d 6f 72 70 68 6f  ttern> in morpho
7390: 6c 6f 67 69 65 73 22 0a 20 20 20 20 69 66 20 22  logies".    if "
73a0: 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b 65  lMorph" in dToke
73b0: 6e 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72 70  n:.        lMorp
73c0: 68 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72  h = dToken["lMor
73d0: 70 68 22 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20  ph"].    else:. 
73e0: 20 20 20 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20         lMorph = 
73f0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
7400: 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22  etMorph(dToken["
7410: 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20  sValue"]).      
7420: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a    if not lMorph:
7430: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
7440: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 23 20  urn False.    # 
7450: 63 68 65 63 6b 20 6e 65 67 61 74 69 76 65 20 63  check negative c
7460: 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 7a 4e 65  ondition.    zNe
7470: 67 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f  gPattern = re.co
7480: 6d 70 69 6c 65 28 73 4e 65 67 50 61 74 74 65 72  mpile(sNegPatter
7490: 6e 29 0a 20 20 20 20 69 66 20 61 6e 79 28 7a 4e  n).    if any(zN
74a0: 65 67 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68  egPattern.search
74b0: 28 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d  (sMorph)  for sM
74c0: 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 3a  orph in lMorph):
74d0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
74e0: 46 61 6c 73 65 0a 20 20 20 20 23 20 73 65 61 72  False.    # sear
74f0: 63 68 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20  ch sPattern.    
7500: 7a 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f  zPattern = re.co
7510: 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a  mpile(sPattern).
7520: 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79 28 7a      return any(z
7530: 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73  Pattern.search(s
7540: 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72  Morph)  for sMor
7550: 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a 64  ph in lMorph)..d
7560: 65 66 20 67 5f 61 6e 61 6c 79 73 65 20 28 64 54  ef g_analyse (dT
7570: 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20  oken, sPattern, 
7580: 62 53 74 72 69 63 74 3d 54 72 75 65 29 3a 0a 20  bStrict=True):. 
7590: 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 74 6f     "analyse a to
75a0: 6b 65 6e 2c 20 72 65 74 75 72 6e 20 54 72 75 65  ken, return True
75b0: 20 69 66 20 3c 73 50 61 74 74 65 72 6e 3e 20 69   if <sPattern> i
75c0: 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28  n morphologies (
75d0: 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f  disambiguation o
75e0: 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20  ff)".    lMorph 
75f0: 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  = _oSpellChecker
7600: 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e  .getMorph(dToken
7610: 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20  ["sValue"]).    
7620: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20  if not lMorph:. 
7630: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
7640: 6c 73 65 0a 20 20 20 20 7a 50 61 74 74 65 72 6e  lse.    zPattern
7650: 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50   = re.compile(sP
7660: 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66 20 62  attern).    if b
7670: 53 74 72 69 63 74 3a 0a 20 20 20 20 20 20 20 20  Strict:.        
7680: 72 65 74 75 72 6e 20 61 6c 6c 28 7a 50 61 74 74  return all(zPatt
7690: 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70  ern.search(sMorp
76a0: 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69  h)  for sMorph i
76b0: 6e 20 6c 4d 6f 72 70 68 29 0a 20 20 20 20 72 65  n lMorph).    re
76c0: 74 75 72 6e 20 61 6e 79 28 7a 50 61 74 74 65 72  turn any(zPatter
76d0: 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70 68 29  n.search(sMorph)
76e0: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
76f0: 6c 4d 6f 72 70 68 29 0a 0a 0a 64 65 66 20 67 5f  lMorph)...def g_
7700: 61 6e 61 6c 79 73 65 78 20 28 64 54 6f 6b 65 6e  analysex (dToken
7710: 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e 65 67  , sPattern, sNeg
7720: 50 61 74 74 65 72 6e 29 3a 0a 20 20 20 20 22 61  Pattern):.    "a
7730: 6e 61 6c 79 73 65 20 61 20 74 6f 6b 65 6e 2c 20  nalyse a token, 
7740: 72 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 3c  return True if <
7750: 73 4e 65 67 50 61 74 74 65 72 6e 3e 20 6e 6f 74  sNegPattern> not
7760: 20 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73   in morphologies
7770: 20 61 6e 64 20 3c 73 50 61 74 74 65 72 6e 3e 20   and <sPattern> 
7780: 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20  in morphologies 
7790: 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20  (disambiguation 
77a0: 6f 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70 68  off)".    lMorph
77b0: 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65   = _oSpellChecke
77c0: 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65  r.getMorph(dToke
77d0: 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20  n["sValue"]).   
77e0: 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a   if not lMorph:.
77f0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46          return F
7800: 61 6c 73 65 0a 20 20 20 20 23 20 63 68 65 63 6b  alse.    # check
7810: 20 6e 65 67 61 74 69 76 65 20 63 6f 6e 64 69 74   negative condit
7820: 69 6f 6e 0a 20 20 20 20 7a 4e 65 67 50 61 74 74  ion.    zNegPatt
7830: 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ern = re.compile
7840: 28 73 4e 65 67 50 61 74 74 65 72 6e 29 0a 20 20  (sNegPattern).  
7850: 20 20 69 66 20 61 6e 79 28 7a 4e 65 67 50 61 74    if any(zNegPat
7860: 74 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72  tern.search(sMor
7870: 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20  ph)  for sMorph 
7880: 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20  in lMorph):.    
7890: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
78a0: 0a 20 20 20 20 23 20 73 65 61 72 63 68 20 73 50  .    # search sP
78b0: 61 74 74 65 72 6e 0a 20 20 20 20 7a 50 61 74 74  attern.    zPatt
78c0: 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ern = re.compile
78d0: 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20 72  (sPattern).    r
78e0: 65 74 75 72 6e 20 61 6e 79 28 7a 50 61 74 74 65  eturn any(zPatte
78f0: 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70 68  rn.search(sMorph
7900: 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  )  for sMorph in
7910: 20 6c 4d 6f 72 70 68 29 0a 0a 0a 23 23 23 23 20   lMorph)...#### 
7920: 47 6f 20 6f 75 74 73 69 64 65 20 74 68 65 20 72  Go outside the r
7930: 75 6c 65 20 73 63 6f 70 65 0a 0a 64 65 66 20 67  ule scope..def g
7940: 5f 6e 65 78 74 54 6f 6b 65 6e 20 28 69 29 3a 0a  _nextToken (i):.
7950: 20 20 20 20 70 61 73 73 0a 0a 64 65 66 20 67 5f      pass..def g_
7960: 70 72 65 76 54 6f 6b 65 6e 20 28 69 29 3a 0a 20  prevToken (i):. 
7970: 20 20 20 70 61 73 73 0a 0a 64 65 66 20 67 5f 6c     pass..def g_l
7980: 6f 6f 6b 20 28 29 3a 0a 20 20 20 20 70 61 73 73  ook ():.    pass
7990: 0a 0a 64 65 66 20 67 5f 6c 6f 6f 6b 41 6e 64 43  ..def g_lookAndC
79a0: 68 65 63 6b 20 28 29 3a 0a 20 20 20 20 70 61 73  heck ():.    pas
79b0: 73 0a 0a 0a 23 23 23 23 20 44 69 73 61 6d 62 69  s...#### Disambi
79c0: 67 75 61 74 6f 72 0a 0a 64 65 66 20 67 5f 73 65  guator..def g_se
79d0: 6c 65 63 74 20 28 64 54 6f 6b 65 6e 2c 20 73 50  lect (dToken, sP
79e0: 61 74 74 65 72 6e 2c 20 6c 44 65 66 61 75 6c 74  attern, lDefault
79f0: 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 73 65 6c  =None):.    "sel
7a00: 65 63 74 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73  ect morphologies
7a10: 20 66 6f 72 20 3c 64 54 6f 6b 65 6e 3e 20 61 63   for <dToken> ac
7a20: 63 6f 72 64 69 6e 67 20 74 6f 20 3c 73 50 61 74  cording to <sPat
7a30: 74 65 72 6e 3e 2c 20 61 6c 77 61 79 73 20 72 65  tern>, always re
7a40: 74 75 72 6e 20 54 72 75 65 22 0a 20 20 20 20 6c  turn True".    l
7a50: 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e 5b 22  Morph = dToken["
7a60: 6c 4d 6f 72 70 68 22 5d 20 20 69 66 20 22 6c 4d  lMorph"]  if "lM
7a70: 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b 65 6e 20  orph" in dToken 
7a80: 20 65 6c 73 65 20 5f 6f 53 70 65 6c 6c 43 68 65   else _oSpellChe
7a90: 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54  cker.getMorph(dT
7aa0: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a  oken["sValue"]).
7ab0: 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70      if not lMorp
7ac0: 68 20 6f 72 20 6c 65 6e 28 6c 4d 6f 72 70 68 29  h or len(lMorph)
7ad0: 20 3d 3d 20 31 3a 0a 20 20 20 20 20 20 20 20 72   == 1:.        r
7ae0: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 6c  eturn True.    l
7af0: 53 65 6c 65 63 74 20 3d 20 5b 20 73 4d 6f 72 70  Select = [ sMorp
7b00: 68 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  h  for sMorph in
7b10: 20 6c 4d 6f 72 70 68 20 20 69 66 20 72 65 2e 73   lMorph  if re.s
7b20: 65 61 72 63 68 28 73 50 61 74 74 65 72 6e 2c 20  earch(sPattern, 
7b30: 73 4d 6f 72 70 68 29 20 5d 0a 20 20 20 20 69 66  sMorph) ].    if
7b40: 20 6c 53 65 6c 65 63 74 3a 0a 20 20 20 20 20 20   lSelect:.      
7b50: 20 20 69 66 20 6c 65 6e 28 6c 53 65 6c 65 63 74    if len(lSelect
7b60: 29 20 21 3d 20 6c 65 6e 28 6c 4d 6f 72 70 68 29  ) != len(lMorph)
7b70: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 54  :.            dT
7b80: 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d  oken["lMorph"] =
7b90: 20 6c 53 65 6c 65 63 74 0a 20 20 20 20 65 6c 69   lSelect.    eli
7ba0: 66 20 6c 44 65 66 61 75 6c 74 3a 0a 20 20 20 20  f lDefault:.    
7bb0: 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72      dToken["lMor
7bc0: 70 68 22 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a  ph"] = lDefault.
7bd0: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
7be0: 0a 0a 64 65 66 20 67 5f 65 78 63 6c 75 64 65 20  ..def g_exclude 
7bf0: 28 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72  (dToken, sPatter
7c00: 6e 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f 6e 65  n, lDefault=None
7c10: 29 3a 0a 20 20 20 20 22 73 65 6c 65 63 74 20 6d  ):.    "select m
7c20: 6f 72 70 68 6f 6c 6f 67 69 65 73 20 66 6f 72 20  orphologies for 
7c30: 3c 64 54 6f 6b 65 6e 3e 20 61 63 63 6f 72 64 69  <dToken> accordi
7c40: 6e 67 20 74 6f 20 3c 73 50 61 74 74 65 72 6e 3e  ng to <sPattern>
7c50: 2c 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e 20  , always return 
7c60: 54 72 75 65 22 0a 20 20 20 20 6c 4d 6f 72 70 68  True".    lMorph
7c70: 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70   = dToken["lMorp
7c80: 68 22 5d 20 20 69 66 20 22 6c 4d 6f 72 70 68 22  h"]  if "lMorph"
7c90: 20 69 6e 20 64 54 6f 6b 65 6e 20 20 65 6c 73 65   in dToken  else
7ca0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
7cb0: 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b  getMorph(dToken[
7cc0: 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 69  "sValue"]).    i
7cd0: 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20  f not lMorph or 
7ce0: 6c 65 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31  len(lMorph) == 1
7cf0: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
7d00: 20 54 72 75 65 0a 20 20 20 20 6c 53 65 6c 65 63   True.    lSelec
7d10: 74 20 3d 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f  t = [ sMorph  fo
7d20: 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72  r sMorph in lMor
7d30: 70 68 20 20 69 66 20 6e 6f 74 20 72 65 2e 73 65  ph  if not re.se
7d40: 61 72 63 68 28 73 50 61 74 74 65 72 6e 2c 20 73  arch(sPattern, s
7d50: 4d 6f 72 70 68 29 20 5d 0a 20 20 20 20 69 66 20  Morph) ].    if 
7d60: 6c 53 65 6c 65 63 74 3a 0a 20 20 20 20 20 20 20  lSelect:.       
7d70: 20 69 66 20 6c 65 6e 28 6c 53 65 6c 65 63 74 29   if len(lSelect)
7d80: 20 21 3d 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 3a   != len(lMorph):
7d90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 54 6f  .            dTo
7da0: 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20  ken["lMorph"] = 
7db0: 6c 53 65 6c 65 63 74 0a 20 20 20 20 65 6c 69 66  lSelect.    elif
7dc0: 20 6c 44 65 66 61 75 6c 74 3a 0a 20 20 20 20 20   lDefault:.     
7dd0: 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70     dToken["lMorp
7de0: 68 22 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20  h"] = lDefault. 
7df0: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a     return True..
7e00: 0a 64 65 66 20 67 5f 64 65 66 69 6e 65 20 28 64  .def g_define (d
7e10: 54 6f 6b 65 6e 2c 20 6c 4d 6f 72 70 68 29 3a 0a  Token, lMorph):.
7e20: 20 20 20 20 22 73 65 74 20 6d 6f 72 70 68 6f 6c      "set morphol
7e30: 6f 67 69 65 73 20 6f 66 20 3c 64 54 6f 6b 65 6e  ogies of <dToken
7e40: 3e 2c 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e  >, always return
7e50: 20 54 72 75 65 22 0a 20 20 20 20 64 54 6f 6b 65   True".    dToke
7e60: 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 4d  n["lMorph"] = lM
7e70: 6f 72 70 68 0a 20 20 20 20 72 65 74 75 72 6e 20  orph.    return 
7e80: 54 72 75 65 0a 0a 0a 23 23 23 23 20 43 41 4c 4c  True...#### CALL
7e90: 41 42 4c 45 53 20 28 67 65 6e 65 72 61 74 65 64  ABLES (generated
7ea0: 20 63 6f 64 65 29 0a 0a 24 7b 67 72 61 70 68 5f   code)..${graph_
7eb0: 63 61 6c 6c 61 62 6c 65 73 7d 0a                 callables}.