Grammalecte  Hex Artifact Content

Artifact e9a038bb637cef327ca25504a631323fcb1aad6b8ac85a3f79a2c9d8604c2e16:


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 41 6c 6c 47 72 61 70 68 2c 20 64 52 75  t dAllGraph, dRu
0150: 6c 65 0a 0a 74 72 79 3a 0a 20 20 20 20 23 20 4c  le..try:.    # L
0160: 69 62 72 65 4f 66 66 69 63 65 20 2f 20 4f 70 65  ibreOffice / Ope
0170: 6e 4f 66 66 69 63 65 0a 20 20 20 20 66 72 6f 6d  nOffice.    from
0180: 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 6c 69   com.sun.star.li
0190: 6e 67 75 69 73 74 69 63 32 20 69 6d 70 6f 72 74  nguistic2 import
01a0: 20 53 69 6e 67 6c 65 50 72 6f 6f 66 72 65 61 64   SingleProofread
01b0: 69 6e 67 45 72 72 6f 72 0a 20 20 20 20 66 72 6f  ingError.    fro
01c0: 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 74  m com.sun.star.t
01d0: 65 78 74 2e 54 65 78 74 4d 61 72 6b 75 70 54 79  ext.TextMarkupTy
01e0: 70 65 20 69 6d 70 6f 72 74 20 50 52 4f 4f 46 52  pe import PROOFR
01f0: 45 41 44 49 4e 47 0a 20 20 20 20 66 72 6f 6d 20  EADING.    from 
0200: 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 62 65 61  com.sun.star.bea
0210: 6e 73 20 69 6d 70 6f 72 74 20 50 72 6f 70 65 72  ns import Proper
0220: 74 79 56 61 6c 75 65 0a 20 20 20 20 23 69 6d 70  tyValue.    #imp
0230: 6f 72 74 20 6c 69 67 68 74 70 72 6f 6f 66 5f 68  ort lightproof_h
0240: 61 6e 64 6c 65 72 5f 24 7b 69 6d 70 6c 6e 61 6d  andler_${implnam
0250: 65 7d 20 61 73 20 6f 70 74 0a 20 20 20 20 5f 62  e} as opt.    _b
0260: 57 72 69 74 65 72 45 72 72 6f 72 20 3d 20 54 72  WriterError = Tr
0270: 75 65 0a 65 78 63 65 70 74 20 49 6d 70 6f 72 74  ue.except Import
0280: 45 72 72 6f 72 3a 0a 20 20 20 20 5f 62 57 72 69  Error:.    _bWri
0290: 74 65 72 45 72 72 6f 72 20 3d 20 46 61 6c 73 65  terError = False
02a0: 0a 0a 0a 5f 5f 61 6c 6c 5f 5f 20 3d 20 5b 20 22  ...__all__ = [ "
02b0: 6c 61 6e 67 22 2c 20 22 6c 6f 63 61 6c 65 73 22  lang", "locales"
02c0: 2c 20 22 70 6b 67 22 2c 20 22 6e 61 6d 65 22 2c  , "pkg", "name",
02d0: 20 22 76 65 72 73 69 6f 6e 22 2c 20 22 61 75 74   "version", "aut
02e0: 68 6f 72 22 2c 20 5c 0a 20 20 20 20 20 20 20 20  hor", \.        
02f0: 20 20 20 20 22 6c 6f 61 64 22 2c 20 22 70 61 72      "load", "par
0300: 73 65 22 2c 20 22 67 65 74 53 70 65 6c 6c 43 68  se", "getSpellCh
0310: 65 63 6b 65 72 22 2c 20 5c 0a 20 20 20 20 20 20  ecker", \.      
0320: 20 20 20 20 20 20 22 73 65 74 4f 70 74 69 6f 6e        "setOption
0330: 22 2c 20 22 73 65 74 4f 70 74 69 6f 6e 73 22 2c  ", "setOptions",
0340: 20 22 67 65 74 4f 70 74 69 6f 6e 73 22 2c 20 22   "getOptions", "
0350: 67 65 74 44 65 66 61 75 6c 74 4f 70 74 69 6f 6e  getDefaultOption
0360: 73 22 2c 20 22 67 65 74 4f 70 74 69 6f 6e 73 4c  s", "getOptionsL
0370: 61 62 65 6c 73 22 2c 20 22 72 65 73 65 74 4f 70  abels", "resetOp
0380: 74 69 6f 6e 73 22 2c 20 22 64 69 73 70 6c 61 79  tions", "display
0390: 4f 70 74 69 6f 6e 73 22 2c 20 5c 0a 20 20 20 20  Options", \.    
03a0: 20 20 20 20 20 20 20 20 22 69 67 6e 6f 72 65 52          "ignoreR
03b0: 75 6c 65 22 2c 20 22 72 65 73 65 74 49 67 6e 6f  ule", "resetIgno
03c0: 72 65 52 75 6c 65 73 22 2c 20 22 72 65 61 63 74  reRules", "react
03d0: 69 76 61 74 65 52 75 6c 65 22 2c 20 22 6c 69 73  ivateRule", "lis
03e0: 74 52 75 6c 65 73 22 2c 20 22 64 69 73 70 6c 61  tRules", "displa
03f0: 79 52 75 6c 65 73 22 20 5d 0a 0a 5f 5f 76 65 72  yRules" ]..__ver
0400: 73 69 6f 6e 5f 5f 20 3d 20 22 24 7b 76 65 72 73  sion__ = "${vers
0410: 69 6f 6e 7d 22 0a 0a 0a 6c 61 6e 67 20 3d 20 22  ion}"...lang = "
0420: 24 7b 6c 61 6e 67 7d 22 0a 6c 6f 63 61 6c 65 73  ${lang}".locales
0430: 20 3d 20 24 7b 6c 6f 63 7d 0a 70 6b 67 20 3d 20   = ${loc}.pkg = 
0440: 22 24 7b 69 6d 70 6c 6e 61 6d 65 7d 22 0a 6e 61  "${implname}".na
0450: 6d 65 20 3d 20 22 24 7b 6e 61 6d 65 7d 22 0a 76  me = "${name}".v
0460: 65 72 73 69 6f 6e 20 3d 20 22 24 7b 76 65 72 73  ersion = "${vers
0470: 69 6f 6e 7d 22 0a 61 75 74 68 6f 72 20 3d 20 22  ion}".author = "
0480: 24 7b 61 75 74 68 6f 72 7d 22 0a 0a 5f 72 75 6c  ${author}".._rul
0490: 65 73 20 3d 20 4e 6f 6e 65 20 20 20 20 20 20 20  es = None       
04a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04b0: 20 20 20 20 20 20 20 20 23 20 6d 6f 64 75 6c 65          # module
04c0: 20 67 63 5f 72 75 6c 65 73 0a 0a 23 20 64 61 74   gc_rules..# dat
04d0: 61 0a 5f 73 41 70 70 43 6f 6e 74 65 78 74 20 3d  a._sAppContext =
04e0: 20 22 22 20 20 20 20 20 20 20 20 20 20 20 20 20   ""             
04f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0500: 77 68 61 74 20 73 6f 66 74 77 61 72 65 20 69 73  what software is
0510: 20 72 75 6e 6e 69 6e 67 0a 5f 64 4f 70 74 69 6f   running._dOptio
0520: 6e 73 20 3d 20 4e 6f 6e 65 0a 5f 6f 53 70 65 6c  ns = None._oSpel
0530: 6c 43 68 65 63 6b 65 72 20 3d 20 4e 6f 6e 65 0a  lChecker = None.
0540: 5f 6f 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 4e 6f  _oTokenizer = No
0550: 6e 65 0a 5f 61 49 67 6e 6f 72 65 64 52 75 6c 65  ne._aIgnoredRule
0560: 73 20 3d 20 73 65 74 28 29 0a 0a 23 20 66 75 6e  s = set()..# fun
0570: 63 74 69 6f 6e 73 0a 5f 63 72 65 61 74 65 52 65  ctions._createRe
0580: 67 65 78 45 72 72 6f 72 20 3d 20 4e 6f 6e 65 0a  gexError = None.
0590: 0a 0a 23 23 23 23 20 49 6e 69 74 69 61 6c 69 7a  ..#### Initializ
05a0: 61 74 69 6f 6e 0a 0a 64 65 66 20 6c 6f 61 64 20  ation..def load 
05b0: 28 73 43 6f 6e 74 65 78 74 3d 22 50 79 74 68 6f  (sContext="Pytho
05c0: 6e 22 29 3a 0a 20 20 20 20 67 6c 6f 62 61 6c 20  n"):.    global 
05d0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 0a 20  _oSpellChecker. 
05e0: 20 20 20 67 6c 6f 62 61 6c 20 5f 73 41 70 70 43     global _sAppC
05f0: 6f 6e 74 65 78 74 0a 20 20 20 20 67 6c 6f 62 61  ontext.    globa
0600: 6c 20 5f 64 4f 70 74 69 6f 6e 73 0a 20 20 20 20  l _dOptions.    
0610: 67 6c 6f 62 61 6c 20 5f 6f 54 6f 6b 65 6e 69 7a  global _oTokeniz
0620: 65 72 0a 20 20 20 20 67 6c 6f 62 61 6c 20 5f 63  er.    global _c
0630: 72 65 61 74 65 52 65 67 65 78 45 72 72 6f 72 0a  reateRegexError.
0640: 20 20 20 20 67 6c 6f 62 61 6c 20 5f 63 72 65 61      global _crea
0650: 74 65 54 6f 6b 65 6e 45 72 72 6f 72 0a 20 20 20  teTokenError.   
0660: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 5f 6f   try:.        _o
0670: 53 70 65 6c 6c 43 68 65 63 6b 65 72 20 3d 20 53  SpellChecker = S
0680: 70 65 6c 6c 43 68 65 63 6b 65 72 28 22 24 7b 6c  pellChecker("${l
0690: 61 6e 67 7d 22 2c 20 22 24 7b 64 69 63 5f 6d 61  ang}", "${dic_ma
06a0: 69 6e 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22  in_filename_py}"
06b0: 2c 20 22 24 7b 64 69 63 5f 65 78 74 65 6e 64 65  , "${dic_extende
06c0: 64 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 2c  d_filename_py}",
06d0: 20 22 24 7b 64 69 63 5f 63 6f 6d 6d 75 6e 69 74   "${dic_communit
06e0: 79 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 2c  y_filename_py}",
06f0: 20 22 24 7b 64 69 63 5f 70 65 72 73 6f 6e 61 6c   "${dic_personal
0700: 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 29 0a  _filename_py}").
0710: 20 20 20 20 20 20 20 20 5f 73 41 70 70 43 6f 6e          _sAppCon
0720: 74 65 78 74 20 3d 20 73 43 6f 6e 74 65 78 74 0a  text = sContext.
0730: 20 20 20 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e          _dOption
0740: 73 20 3d 20 64 69 63 74 28 67 63 5f 6f 70 74 69  s = dict(gc_opti
0750: 6f 6e 73 2e 67 65 74 4f 70 74 69 6f 6e 73 28 73  ons.getOptions(s
0760: 43 6f 6e 74 65 78 74 29 29 20 20 20 23 20 64 75  Context))   # du
0770: 70 6c 69 63 61 74 69 6f 6e 20 6e 65 63 65 73 73  plication necess
0780: 61 72 79 2c 20 74 6f 20 62 65 20 61 62 6c 65 20  ary, to be able 
0790: 74 6f 20 72 65 73 65 74 20 74 6f 20 64 65 66 61  to reset to defa
07a0: 75 6c 74 0a 20 20 20 20 20 20 20 20 5f 6f 54 6f  ult.        _oTo
07b0: 6b 65 6e 69 7a 65 72 20 3d 20 5f 6f 53 70 65 6c  kenizer = _oSpel
07c0: 6c 43 68 65 63 6b 65 72 2e 67 65 74 54 6f 6b 65  lChecker.getToke
07d0: 6e 69 7a 65 72 28 29 0a 20 20 20 20 20 20 20 20  nizer().        
07e0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 61  _oSpellChecker.a
07f0: 63 74 69 76 61 74 65 53 74 6f 72 61 67 65 28 29  ctivateStorage()
0800: 0a 20 20 20 20 20 20 20 20 5f 63 72 65 61 74 65  .        _create
0810: 52 65 67 65 78 45 72 72 6f 72 20 3d 20 5f 63 72  RegexError = _cr
0820: 65 61 74 65 52 65 67 65 78 57 72 69 74 65 72 45  eateRegexWriterE
0830: 72 72 6f 72 20 20 69 66 20 5f 62 57 72 69 74 65  rror  if _bWrite
0840: 72 45 72 72 6f 72 20 20 65 6c 73 65 20 5f 63 72  rError  else _cr
0850: 65 61 74 65 52 65 67 65 78 44 69 63 74 45 72 72  eateRegexDictErr
0860: 6f 72 0a 20 20 20 20 65 78 63 65 70 74 3a 0a 20  or.    except:. 
0870: 20 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b         traceback
0880: 2e 70 72 69 6e 74 5f 65 78 63 28 29 0a 0a 0a 64  .print_exc()...d
0890: 65 66 20 5f 67 65 74 52 75 6c 65 73 20 28 62 50  ef _getRules (bP
08a0: 61 72 61 67 72 61 70 68 29 3a 0a 20 20 20 20 74  aragraph):.    t
08b0: 72 79 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e  ry:.        if n
08c0: 6f 74 20 62 50 61 72 61 67 72 61 70 68 3a 0a 20  ot bParagraph:. 
08d0: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
08e0: 6e 20 5f 72 75 6c 65 73 2e 6c 53 65 6e 74 65 6e  n _rules.lSenten
08f0: 63 65 52 75 6c 65 73 0a 20 20 20 20 20 20 20 20  ceRules.        
0900: 72 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 50  return _rules.lP
0910: 61 72 61 67 72 61 70 68 52 75 6c 65 73 0a 20 20  aragraphRules.  
0920: 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20    except:.      
0930: 20 20 5f 6c 6f 61 64 52 75 6c 65 73 28 29 0a 20    _loadRules(). 
0940: 20 20 20 69 66 20 6e 6f 74 20 62 50 61 72 61 67     if not bParag
0950: 72 61 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65  raph:.        re
0960: 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 53 65 6e  turn _rules.lSen
0970: 74 65 6e 63 65 52 75 6c 65 73 0a 20 20 20 20 72  tenceRules.    r
0980: 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 50 61  eturn _rules.lPa
0990: 72 61 67 72 61 70 68 52 75 6c 65 73 0a 0a 0a 64  ragraphRules...d
09a0: 65 66 20 5f 6c 6f 61 64 52 75 6c 65 73 20 28 29  ef _loadRules ()
09b0: 3a 0a 20 20 20 20 66 72 6f 6d 20 2e 20 69 6d 70  :.    from . imp
09c0: 6f 72 74 20 67 63 5f 72 75 6c 65 73 0a 20 20 20  ort gc_rules.   
09d0: 20 67 6c 6f 62 61 6c 20 5f 72 75 6c 65 73 0a 20   global _rules. 
09e0: 20 20 20 5f 72 75 6c 65 73 20 3d 20 67 63 5f 72     _rules = gc_r
09f0: 75 6c 65 73 0a 20 20 20 20 23 20 63 6f 6d 70 69  ules.    # compi
0a00: 6c 65 20 72 75 6c 65 73 20 72 65 67 65 78 0a 20  le rules regex. 
0a10: 20 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20     for sOption, 
0a20: 6c 52 75 6c 65 47 72 6f 75 70 20 69 6e 20 63 68  lRuleGroup in ch
0a30: 61 69 6e 28 5f 72 75 6c 65 73 2e 6c 50 61 72 61  ain(_rules.lPara
0a40: 67 72 61 70 68 52 75 6c 65 73 2c 20 5f 72 75 6c  graphRules, _rul
0a50: 65 73 2e 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65  es.lSentenceRule
0a60: 73 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  s):.        if s
0a70: 4f 70 74 69 6f 6e 20 21 3d 20 22 40 40 40 40 22  Option != "@@@@"
0a80: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  :.            fo
0a90: 72 20 61 52 75 6c 65 20 69 6e 20 6c 52 75 6c 65  r aRule in lRule
0aa0: 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20  Group:.         
0ab0: 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20         try:.    
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ad0: 61 52 75 6c 65 5b 30 5d 20 3d 20 72 65 2e 63 6f  aRule[0] = re.co
0ae0: 6d 70 69 6c 65 28 61 52 75 6c 65 5b 30 5d 29 0a  mpile(aRule[0]).
0af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b00: 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20  except:.        
0b10: 20 20 20 20 20 20 20 20 20 20 20 20 65 63 68 6f              echo
0b20: 28 22 42 61 64 20 72 65 67 75 6c 61 72 20 65 78  ("Bad regular ex
0b30: 70 72 65 73 73 69 6f 6e 20 69 6e 20 23 20 22 20  pression in # " 
0b40: 2b 20 73 74 72 28 61 52 75 6c 65 5b 32 5d 29 29  + str(aRule[2]))
0b50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0b60: 20 20 20 20 20 61 52 75 6c 65 5b 30 5d 20 3d 20       aRule[0] = 
0b70: 22 28 3f 69 29 3c 47 72 61 6d 6d 61 6c 65 63 74  "(?i)<Grammalect
0b80: 65 3e 22 0a 0a 0a 23 23 23 23 20 50 61 72 73 69  e>"...#### Parsi
0b90: 6e 67 0a 0a 64 65 66 20 70 61 72 73 65 20 28 73  ng..def parse (s
0ba0: 54 65 78 74 2c 20 73 43 6f 75 6e 74 72 79 3d 22  Text, sCountry="
0bb0: 24 7b 63 6f 75 6e 74 72 79 5f 64 65 66 61 75 6c  ${country_defaul
0bc0: 74 7d 22 2c 20 62 44 65 62 75 67 3d 46 61 6c 73  t}", bDebug=Fals
0bd0: 65 2c 20 64 4f 70 74 69 6f 6e 73 3d 4e 6f 6e 65  e, dOptions=None
0be0: 2c 20 62 43 6f 6e 74 65 78 74 3d 46 61 6c 73 65  , bContext=False
0bf0: 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 73  ):.    "analyses
0c00: 20 74 68 65 20 70 61 72 61 67 72 61 70 68 20 73   the paragraph s
0c10: 54 65 78 74 20 61 6e 64 20 72 65 74 75 72 6e 73  Text and returns
0c20: 20 6c 69 73 74 20 6f 66 20 65 72 72 6f 72 73 22   list of errors"
0c30: 0a 20 20 20 20 23 73 54 65 78 74 20 3d 20 75 6e  .    #sText = un
0c40: 69 63 6f 64 65 64 61 74 61 2e 6e 6f 72 6d 61 6c  icodedata.normal
0c50: 69 7a 65 28 22 4e 46 43 22 2c 20 73 54 65 78 74  ize("NFC", sText
0c60: 29 0a 20 20 20 20 61 45 72 72 6f 72 73 20 3d 20  ).    aErrors = 
0c70: 4e 6f 6e 65 0a 20 20 20 20 73 52 65 61 6c 54 65  None.    sRealTe
0c80: 78 74 20 3d 20 73 54 65 78 74 0a 20 20 20 20 64  xt = sText.    d
0c90: 50 72 69 6f 72 69 74 79 20 3d 20 7b 7d 20 20 23  Priority = {}  #
0ca0: 20 4b 65 79 20 3d 20 70 6f 73 69 74 69 6f 6e 3b   Key = position;
0cb0: 20 76 61 6c 75 65 20 3d 20 70 72 69 6f 72 69 74   value = priorit
0cc0: 79 0a 20 20 20 20 64 4f 70 74 20 3d 20 5f 64 4f  y.    dOpt = _dO
0cd0: 70 74 69 6f 6e 73 20 20 69 66 20 6e 6f 74 20 64  ptions  if not d
0ce0: 4f 70 74 69 6f 6e 73 20 20 65 6c 73 65 20 64 4f  Options  else dO
0cf0: 70 74 69 6f 6e 73 0a 20 20 20 20 62 53 68 6f 77  ptions.    bShow
0d00: 52 75 6c 65 49 64 20 3d 20 6f 70 74 69 6f 6e 28  RuleId = option(
0d10: 27 69 64 72 75 6c 65 27 29 0a 0a 20 20 20 20 23  'idrule')..    #
0d20: 20 70 61 72 73 65 20 70 61 72 61 67 72 61 70 68   parse paragraph
0d30: 0a 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20  .    try:.      
0d40: 20 20 73 4e 65 77 2c 20 61 45 72 72 6f 72 73 20    sNew, aErrors 
0d50: 3d 20 5f 70 72 6f 6f 66 72 65 61 64 28 4e 6f 6e  = _proofread(Non
0d60: 65 2c 20 73 54 65 78 74 2c 20 73 52 65 61 6c 54  e, sText, sRealT
0d70: 65 78 74 2c 20 30 2c 20 54 72 75 65 2c 20 64 50  ext, 0, True, dP
0d80: 72 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e 74 72  riority, sCountr
0d90: 79 2c 20 64 4f 70 74 2c 20 62 53 68 6f 77 52 75  y, dOpt, bShowRu
0da0: 6c 65 49 64 2c 20 62 44 65 62 75 67 2c 20 62 43  leId, bDebug, bC
0db0: 6f 6e 74 65 78 74 29 0a 20 20 20 20 20 20 20 20  ontext).        
0dc0: 69 66 20 73 4e 65 77 3a 0a 20 20 20 20 20 20 20  if sNew:.       
0dd0: 20 20 20 20 20 73 54 65 78 74 20 3d 20 73 4e 65       sText = sNe
0de0: 77 0a 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20  w.    except:.  
0df0: 20 20 20 20 20 20 72 61 69 73 65 0a 0a 20 20 20        raise..   
0e00: 20 23 20 63 6c 65 61 6e 75 70 0a 20 20 20 20 69   # cleanup.    i
0e10: 66 20 22 c2 a0 22 20 69 6e 20 73 54 65 78 74 3a  f ".." in sText:
0e20: 0a 20 20 20 20 20 20 20 20 73 54 65 78 74 20 3d  .        sText =
0e30: 20 73 54 65 78 74 2e 72 65 70 6c 61 63 65 28 22   sText.replace("
0e40: c2 a0 22 2c 20 27 20 27 29 20 23 20 6e 62 73 70  ..", ' ') # nbsp
0e50: 0a 20 20 20 20 69 66 20 22 e2 80 af 22 20 69 6e  .    if "..." in
0e60: 20 73 54 65 78 74 3a 0a 20 20 20 20 20 20 20 20   sText:.        
0e70: 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e 72 65  sText = sText.re
0e80: 70 6c 61 63 65 28 22 e2 80 af 22 2c 20 27 20 27  place("...", ' '
0e90: 29 20 23 20 6e 6e 62 73 70 0a 20 20 20 20 69 66  ) # nnbsp.    if
0ea0: 20 22 27 22 20 69 6e 20 73 54 65 78 74 3a 0a 20   "'" in sText:. 
0eb0: 20 20 20 20 20 20 20 73 54 65 78 74 20 3d 20 73         sText = s
0ec0: 54 65 78 74 2e 72 65 70 6c 61 63 65 28 22 27 22  Text.replace("'"
0ed0: 2c 20 22 e2 80 99 22 29 0a 20 20 20 20 69 66 20  , "...").    if 
0ee0: 22 e2 80 91 22 20 69 6e 20 73 54 65 78 74 3a 0a  "..." in sText:.
0ef0: 20 20 20 20 20 20 20 20 73 54 65 78 74 20 3d 20          sText = 
0f00: 73 54 65 78 74 2e 72 65 70 6c 61 63 65 28 22 e2  sText.replace(".
0f10: 80 91 22 2c 20 22 2d 22 29 20 23 20 6e 6f 62 72  ..", "-") # nobr
0f20: 65 61 6b 64 61 73 68 0a 0a 20 20 20 20 23 20 70  eakdash..    # p
0f30: 61 72 73 65 20 73 65 6e 74 65 6e 63 65 73 0a 20  arse sentences. 
0f40: 20 20 20 66 6f 72 20 69 53 74 61 72 74 2c 20 69     for iStart, i
0f50: 45 6e 64 20 69 6e 20 5f 67 65 74 53 65 6e 74 65  End in _getSente
0f60: 6e 63 65 42 6f 75 6e 64 61 72 69 65 73 28 73 54  nceBoundaries(sT
0f70: 65 78 74 29 3a 0a 20 20 20 20 20 20 20 20 69 66  ext):.        if
0f80: 20 34 20 3c 20 28 69 45 6e 64 20 2d 20 69 53 74   4 < (iEnd - iSt
0f90: 61 72 74 29 20 3c 20 32 30 30 30 3a 0a 20 20 20  art) < 2000:.   
0fa0: 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20           try:.  
0fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6f 53                oS
0fc0: 65 6e 74 65 6e 63 65 20 3d 20 54 6f 6b 65 6e 53  entence = TokenS
0fd0: 65 6e 74 65 6e 63 65 28 73 54 65 78 74 5b 69 53  entence(sText[iS
0fe0: 74 61 72 74 3a 69 45 6e 64 5d 2c 20 73 52 65 61  tart:iEnd], sRea
0ff0: 6c 54 65 78 74 5b 69 53 74 61 72 74 3a 69 45 6e  lText[iStart:iEn
1000: 64 5d 2c 20 69 53 74 61 72 74 29 0a 20 20 20 20  d], iStart).    
1010: 20 20 20 20 20 20 20 20 20 20 20 20 5f 2c 20 65              _, e
1020: 72 72 73 20 3d 20 5f 70 72 6f 6f 66 72 65 61 64  rrs = _proofread
1030: 28 6f 53 65 6e 74 65 6e 63 65 2c 20 73 54 65 78  (oSentence, sTex
1040: 74 5b 69 53 74 61 72 74 3a 69 45 6e 64 5d 2c 20  t[iStart:iEnd], 
1050: 73 52 65 61 6c 54 65 78 74 5b 69 53 74 61 72 74  sRealText[iStart
1060: 3a 69 45 6e 64 5d 2c 20 69 53 74 61 72 74 2c 20  :iEnd], iStart, 
1070: 46 61 6c 73 65 2c 20 64 50 72 69 6f 72 69 74 79  False, dPriority
1080: 2c 20 73 43 6f 75 6e 74 72 79 2c 20 64 4f 70 74  , sCountry, dOpt
1090: 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62  , bShowRuleId, b
10a0: 44 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74 29  Debug, bContext)
10b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
10c0: 20 61 45 72 72 6f 72 73 2e 75 70 64 61 74 65 28   aErrors.update(
10d0: 65 72 72 73 29 0a 20 20 20 20 20 20 20 20 20 20  errs).          
10e0: 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20    except:.      
10f0: 20 20 20 20 20 20 20 20 20 20 72 61 69 73 65 0a            raise.
1100: 20 20 20 20 72 65 74 75 72 6e 20 61 45 72 72 6f      return aErro
1110: 72 73 2e 76 61 6c 75 65 73 28 29 20 23 20 74 68  rs.values() # th
1120: 69 73 20 69 73 20 61 20 76 69 65 77 20 28 69 74  is is a view (it
1130: 65 72 61 62 6c 65 29 0a 0a 0a 5f 7a 45 6e 64 4f  erable)..._zEndO
1140: 66 53 65 6e 74 65 6e 63 65 20 3d 20 72 65 2e 63  fSentence = re.c
1150: 6f 6d 70 69 6c 65 28 72 27 28 5b 2e 3f 21 3a 3b  ompile(r'([.?!:;
1160: e2 80 a6 5d 5b 20 2e 3f 21 e2 80 a6 20 c2 bb e2  ...][ .?!... ...
1170: 80 9d 22 29 5d 2a 7c 2e 24 29 27 29 0a 5f 7a 42  ..")]*|.$)')._zB
1180: 65 67 69 6e 4f 66 50 61 72 61 67 72 61 70 68 20  eginOfParagraph 
1190: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72 22 5e  = re.compile(r"^
11a0: 5c 57 2a 22 29 0a 5f 7a 45 6e 64 4f 66 50 61 72  \W*")._zEndOfPar
11b0: 61 67 72 61 70 68 20 3d 20 72 65 2e 63 6f 6d 70  agraph = re.comp
11c0: 69 6c 65 28 72 22 5c 57 2a 24 22 29 0a 0a 64 65  ile(r"\W*$")..de
11d0: 66 20 5f 67 65 74 53 65 6e 74 65 6e 63 65 42 6f  f _getSentenceBo
11e0: 75 6e 64 61 72 69 65 73 20 28 73 54 65 78 74 29  undaries (sText)
11f0: 3a 0a 20 20 20 20 69 53 74 61 72 74 20 3d 20 5f  :.    iStart = _
1200: 7a 42 65 67 69 6e 4f 66 50 61 72 61 67 72 61 70  zBeginOfParagrap
1210: 68 2e 6d 61 74 63 68 28 73 54 65 78 74 29 2e 65  h.match(sText).e
1220: 6e 64 28 29 0a 20 20 20 20 66 6f 72 20 6d 20 69  nd().    for m i
1230: 6e 20 5f 7a 45 6e 64 4f 66 53 65 6e 74 65 6e 63  n _zEndOfSentenc
1240: 65 2e 66 69 6e 64 69 74 65 72 28 73 54 65 78 74  e.finditer(sText
1250: 29 3a 0a 20 20 20 20 20 20 20 20 79 69 65 6c 64  ):.        yield
1260: 20 28 69 53 74 61 72 74 2c 20 6d 2e 65 6e 64 28   (iStart, m.end(
1270: 29 29 0a 20 20 20 20 20 20 20 20 69 53 74 61 72  )).        iStar
1280: 74 20 3d 20 6d 2e 65 6e 64 28 29 0a 0a 0a 64 65  t = m.end()...de
1290: 66 20 5f 70 72 6f 6f 66 72 65 61 64 20 28 6f 53  f _proofread (oS
12a0: 65 6e 74 65 6e 63 65 2c 20 73 2c 20 73 78 2c 20  entence, s, sx, 
12b0: 6e 4f 66 66 73 65 74 2c 20 62 50 61 72 61 67 72  nOffset, bParagr
12c0: 61 70 68 2c 20 64 50 72 69 6f 72 69 74 79 2c 20  aph, dPriority, 
12d0: 73 43 6f 75 6e 74 72 79 2c 20 64 4f 70 74 69 6f  sCountry, dOptio
12e0: 6e 73 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c  ns, bShowRuleId,
12f0: 20 62 44 65 62 75 67 2c 20 62 43 6f 6e 74 65 78   bDebug, bContex
1300: 74 29 3a 0a 20 20 20 20 64 45 72 72 73 20 3d 20  t):.    dErrs = 
1310: 7b 7d 0a 20 20 20 20 62 50 61 72 61 67 72 61 70  {}.    bParagrap
1320: 68 43 68 61 6e 67 65 20 3d 20 46 61 6c 73 65 0a  hChange = False.
1330: 20 20 20 20 62 53 65 6e 74 65 6e 63 65 43 68 61      bSentenceCha
1340: 6e 67 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20  nge = False.    
1350: 64 54 6f 6b 65 6e 50 6f 73 20 3d 20 6f 53 65 6e  dTokenPos = oSen
1360: 74 65 6e 63 65 2e 64 54 6f 6b 65 6e 50 6f 73 20  tence.dTokenPos 
1370: 69 66 20 6f 53 65 6e 74 65 6e 63 65 20 65 6c 73  if oSentence els
1380: 65 20 7b 7d 0a 20 20 20 20 66 6f 72 20 73 4f 70  e {}.    for sOp
1390: 74 69 6f 6e 2c 20 6c 52 75 6c 65 47 72 6f 75 70  tion, lRuleGroup
13a0: 20 69 6e 20 5f 67 65 74 52 75 6c 65 73 28 62 50   in _getRules(bP
13b0: 61 72 61 67 72 61 70 68 29 3a 0a 20 20 20 20 20  aragraph):.     
13c0: 20 20 20 69 66 20 73 4f 70 74 69 6f 6e 20 3d 3d     if sOption ==
13d0: 20 22 40 40 40 40 22 3a 0a 20 20 20 20 20 20 20   "@@@@":.       
13e0: 20 20 20 20 20 23 20 67 72 61 70 68 20 72 75 6c       # graph rul
13f0: 65 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  es.            i
1400: 66 20 6e 6f 74 20 62 50 61 72 61 67 72 61 70 68  f not bParagraph
1410: 20 61 6e 64 20 62 53 65 6e 74 65 6e 63 65 43 68   and bSentenceCh
1420: 61 6e 67 65 3a 0a 20 20 20 20 20 20 20 20 20 20  ange:.          
1430: 20 20 20 20 20 20 6f 53 65 6e 74 65 6e 63 65 2e        oSentence.
1440: 75 70 64 61 74 65 28 73 29 0a 20 20 20 20 20 20  update(s).      
1450: 20 20 20 20 20 20 20 20 20 20 62 53 65 6e 74 65            bSente
1460: 6e 63 65 43 68 61 6e 67 65 20 3d 20 46 61 6c 73  nceChange = Fals
1470: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  e.            fo
1480: 72 20 73 47 72 61 70 68 4e 61 6d 65 2c 20 73 4c  r sGraphName, sL
1490: 69 6e 65 49 64 20 69 6e 20 6c 52 75 6c 65 47 72  ineId in lRuleGr
14a0: 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20  oup:.           
14b0: 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a       if bDebug:.
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14d0: 20 20 20 20 70 72 69 6e 74 28 22 5c 6e 3e 3e 3e      print("\n>>>
14e0: 3e 20 47 52 41 50 48 3a 22 2c 20 73 47 72 61 70  > GRAPH:", sGrap
14f0: 68 4e 61 6d 65 2c 20 73 4c 69 6e 65 49 64 29 0a  hName, sLineId).
1500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1510: 62 50 61 72 61 67 72 61 70 68 43 68 61 6e 67 65  bParagraphChange
1520: 2c 20 65 72 72 73 20 3d 20 6f 53 65 6e 74 65 6e  , errs = oSenten
1530: 63 65 2e 70 61 72 73 65 28 64 41 6c 6c 47 72 61  ce.parse(dAllGra
1540: 70 68 5b 73 47 72 61 70 68 4e 61 6d 65 5d 2c 20  ph[sGraphName], 
1550: 64 50 72 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e  dPriority, sCoun
1560: 74 72 79 2c 20 64 4f 70 74 69 6f 6e 73 2c 20 62  try, dOptions, b
1570: 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 44 65 62  ShowRuleId, bDeb
1580: 75 67 2c 20 62 43 6f 6e 74 65 78 74 29 0a 20 20  ug, bContext).  
1590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 45                dE
15a0: 72 72 73 2e 75 70 64 61 74 65 28 65 72 72 73 29  rrs.update(errs)
15b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
15c0: 20 69 66 20 62 50 61 72 61 67 72 61 70 68 43 68   if bParagraphCh
15d0: 61 6e 67 65 3a 0a 20 20 20 20 20 20 20 20 20 20  ange:.          
15e0: 20 20 20 20 20 20 20 20 20 20 73 20 3d 20 6f 53            s = oS
15f0: 65 6e 74 65 6e 63 65 2e 72 65 77 72 69 74 65 28  entence.rewrite(
1600: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1610: 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a        if bDebug:
1620: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1630: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
1640: 7e 22 2c 20 6f 53 65 6e 74 65 6e 63 65 2e 73 53  ~", oSentence.sS
1650: 65 6e 74 65 6e 63 65 29 0a 20 20 20 20 20 20 20  entence).       
1660: 20 65 6c 69 66 20 6e 6f 74 20 73 4f 70 74 69 6f   elif not sOptio
1670: 6e 20 6f 72 20 64 4f 70 74 69 6f 6e 73 2e 67 65  n or dOptions.ge
1680: 74 28 73 4f 70 74 69 6f 6e 2c 20 46 61 6c 73 65  t(sOption, False
1690: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ):.            #
16a0: 20 72 65 67 65 78 20 72 75 6c 65 73 0a 20 20 20   regex rules.   
16b0: 20 20 20 20 20 20 20 20 20 66 6f 72 20 7a 52 65           for zRe
16c0: 67 65 78 2c 20 62 55 70 70 65 72 63 61 73 65 2c  gex, bUppercase,
16d0: 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49   sLineId, sRuleI
16e0: 64 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 6c 41  d, nPriority, lA
16f0: 63 74 69 6f 6e 73 20 69 6e 20 6c 52 75 6c 65 47  ctions in lRuleG
1700: 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20  roup:.          
1710: 20 20 20 20 20 20 69 66 20 73 52 75 6c 65 49 64        if sRuleId
1720: 20 6e 6f 74 20 69 6e 20 5f 61 49 67 6e 6f 72 65   not in _aIgnore
1730: 64 52 75 6c 65 73 3a 0a 20 20 20 20 20 20 20 20  dRules:.        
1740: 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20              for 
1750: 6d 20 69 6e 20 7a 52 65 67 65 78 2e 66 69 6e 64  m in zRegex.find
1760: 69 74 65 72 28 73 29 3a 0a 20 20 20 20 20 20 20  iter(s):.       
1770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1780: 20 62 43 6f 6e 64 4d 65 6d 6f 20 3d 20 4e 6f 6e   bCondMemo = Non
1790: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
17a0: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 46            for sF
17b0: 75 6e 63 43 6f 6e 64 2c 20 63 41 63 74 69 6f 6e  uncCond, cAction
17c0: 54 79 70 65 2c 20 73 57 68 61 74 2c 20 2a 65 41  Type, sWhat, *eA
17d0: 63 74 20 69 6e 20 6c 41 63 74 69 6f 6e 73 3a 0a  ct in lActions:.
17e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17f0: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61 63              # ac
1800: 74 69 6f 6e 20 69 6e 20 6c 41 63 74 69 6f 6e 73  tion in lActions
1810: 3a 20 5b 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 61  : [ condition, a
1820: 63 74 69 6f 6e 20 74 79 70 65 2c 20 72 65 70 6c  ction type, repl
1830: 61 63 65 6d 65 6e 74 2f 73 75 67 67 65 73 74 69  acement/suggesti
1840: 6f 6e 2f 61 63 74 69 6f 6e 5b 2c 20 69 47 72 6f  on/action[, iGro
1850: 75 70 5b 2c 20 6d 65 73 73 61 67 65 2c 20 55 52  up[, message, UR
1860: 4c 5d 5d 20 5d 0a 20 20 20 20 20 20 20 20 20 20  L]] ].          
1870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1880: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20    try:.         
1890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18a0: 20 20 20 20 20 20 20 62 43 6f 6e 64 4d 65 6d 6f         bCondMemo
18b0: 20 3d 20 6e 6f 74 20 73 46 75 6e 63 43 6f 6e 64   = not sFuncCond
18c0: 20 6f 72 20 67 6c 6f 62 61 6c 73 28 29 5b 73 46   or globals()[sF
18d0: 75 6e 63 43 6f 6e 64 5d 28 73 2c 20 73 78 2c 20  uncCond](s, sx, 
18e0: 6d 2c 20 64 54 6f 6b 65 6e 50 6f 73 2c 20 73 43  m, dTokenPos, sC
18f0: 6f 75 6e 74 72 79 2c 20 62 43 6f 6e 64 4d 65 6d  ountry, bCondMem
1900: 6f 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  o).             
1910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1920: 20 20 20 69 66 20 62 43 6f 6e 64 4d 65 6d 6f 3a     if bCondMemo:
1930: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1950: 20 20 20 20 20 69 66 20 63 41 63 74 69 6f 6e 54       if cActionT
1960: 79 70 65 20 3d 3d 20 22 2d 22 3a 0a 20 20 20 20  ype == "-":.    
1970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1990: 20 20 20 20 23 20 67 72 61 6d 6d 61 72 20 65 72      # grammar er
19a0: 72 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20  ror.            
19b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 45 72 72              nErr
19d0: 6f 72 53 74 61 72 74 20 3d 20 6e 4f 66 66 73 65  orStart = nOffse
19e0: 74 20 2b 20 6d 2e 73 74 61 72 74 28 65 41 63 74  t + m.start(eAct
19f0: 5b 30 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20  [0]).           
1a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
1a20: 6e 45 72 72 6f 72 53 74 61 72 74 20 6e 6f 74 20  nErrorStart not 
1a30: 69 6e 20 64 45 72 72 73 20 6f 72 20 6e 50 72 69  in dErrs or nPri
1a40: 6f 72 69 74 79 20 3e 20 64 50 72 69 6f 72 69 74  ority > dPriorit
1a50: 79 5b 6e 45 72 72 6f 72 53 74 61 72 74 5d 3a 0a  y[nErrorStart]:.
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a80: 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72              dErr
1a90: 73 5b 6e 45 72 72 6f 72 53 74 61 72 74 5d 20 3d  s[nErrorStart] =
1aa0: 20 5f 63 72 65 61 74 65 52 65 67 65 78 45 72 72   _createRegexErr
1ab0: 6f 72 28 73 2c 20 73 78 2c 20 73 57 68 61 74 2c  or(s, sx, sWhat,
1ac0: 20 6e 4f 66 66 73 65 74 2c 20 6d 2c 20 65 41 63   nOffset, m, eAc
1ad0: 74 5b 30 5d 2c 20 73 4c 69 6e 65 49 64 2c 20 73  t[0], sLineId, s
1ae0: 52 75 6c 65 49 64 2c 20 62 55 70 70 65 72 63 61  RuleId, bUpperca
1af0: 73 65 2c 20 65 41 63 74 5b 31 5d 2c 20 65 41 63  se, eAct[1], eAc
1b00: 74 5b 32 5d 2c 20 62 53 68 6f 77 52 75 6c 65 49  t[2], bShowRuleI
1b10: 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62 43 6f 6e  d, sOption, bCon
1b20: 74 65 78 74 29 0a 20 20 20 20 20 20 20 20 20 20  text).          
1b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b50: 20 20 64 50 72 69 6f 72 69 74 79 5b 6e 45 72 72    dPriority[nErr
1b60: 6f 72 53 74 61 72 74 5d 20 3d 20 6e 50 72 69 6f  orStart] = nPrio
1b70: 72 69 74 79 0a 20 20 20 20 20 20 20 20 20 20 20  rity.           
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b90: 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 41           elif cA
1ba0: 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 7e 22  ctionType == "~"
1bb0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bd0: 20 20 20 20 20 20 20 20 20 20 23 20 74 65 78 74            # text
1be0: 20 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20 20   processor.     
1bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c10: 20 20 20 73 20 3d 20 5f 72 65 77 72 69 74 65 28     s = _rewrite(
1c20: 73 2c 20 73 57 68 61 74 2c 20 65 41 63 74 5b 30  s, sWhat, eAct[0
1c30: 5d 2c 20 6d 2c 20 62 55 70 70 65 72 63 61 73 65  ], m, bUppercase
1c40: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c60: 20 20 20 20 20 20 20 20 20 20 62 50 61 72 61 67            bParag
1c70: 72 61 70 68 43 68 61 6e 67 65 20 3d 20 54 72 75  raphChange = Tru
1c80: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
1c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ca0: 20 20 20 20 20 20 20 20 20 20 62 53 65 6e 74 65            bSente
1cb0: 6e 63 65 43 68 61 6e 67 65 20 3d 20 54 72 75 65  nceChange = True
1cc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ce0: 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62           if bDeb
1cf0: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
1d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d20: 65 63 68 6f 28 22 7e 20 22 20 2b 20 73 20 2b 20  echo("~ " + s + 
1d30: 22 20 20 2d 2d 20 22 20 2b 20 6d 2e 67 72 6f 75  "  -- " + m.grou
1d40: 70 28 65 41 63 74 5b 30 5d 29 20 2b 20 22 20 20  p(eAct[0]) + "  
1d50: 23 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 20  # " + sLineId). 
1d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d80: 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54     elif cActionT
1d90: 79 70 65 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20  ype == "=":.    
1da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dc0: 20 20 20 20 23 20 64 69 73 61 6d 62 69 67 75 61      # disambigua
1dd0: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tion.           
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
1e00: 6e 6f 74 20 62 50 61 72 61 67 72 61 70 68 3a 0a  not bParagraph:.
1e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e30: 20 20 20 20 20 20 20 20 20 20 20 20 67 6c 6f 62              glob
1e40: 61 6c 73 28 29 5b 73 57 68 61 74 5d 28 73 2c 20  als()[sWhat](s, 
1e50: 6d 2c 20 64 54 6f 6b 65 6e 50 6f 73 29 0a 20 20  m, dTokenPos).  
1e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e80: 20 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65            if bDe
1e90: 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20  bug:.           
1ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ec0: 20 20 20 20 20 65 63 68 6f 28 22 3d 20 22 20 2b       echo("= " +
1ed0: 20 6d 2e 67 72 6f 75 70 28 30 29 20 2b 20 22 20   m.group(0) + " 
1ee0: 20 23 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a   # " + sLineId).
1ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f10: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
1f20: 54 79 70 65 20 3d 3d 20 22 3e 22 3a 0a 20 20 20  Type == ">":.   
1f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f50: 20 20 20 20 20 23 20 77 65 20 64 6f 20 6e 6f 74       # we do not
1f60: 68 69 6e 67 2c 20 74 68 69 73 20 74 65 73 74 20  hing, this test 
1f70: 69 73 20 6a 75 73 74 20 61 20 63 6f 6e 64 69 74  is just a condit
1f80: 69 6f 6e 20 74 6f 20 61 70 70 6c 79 20 61 6c 6c  ion to apply all
1f90: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 63 74 69 6f   following actio
1fa0: 6e 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ns.             
1fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fc0: 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73 0a             pass.
1fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ff0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2020: 20 20 65 63 68 6f 28 22 23 20 65 72 72 6f 72 3a    echo("# error:
2030: 20 75 6e 6b 6e 6f 77 6e 20 61 63 74 69 6f 6e 20   unknown action 
2040: 61 74 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a  at " + sLineId).
2050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2070: 65 6c 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65  elif cActionType
2080: 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20 20 20 20   == ">":.       
2090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65               bre
20b0: 61 6b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ak.             
20c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
20d0: 78 63 65 70 74 20 45 78 63 65 70 74 69 6f 6e 20  xcept Exception 
20e0: 61 73 20 65 3a 0a 20 20 20 20 20 20 20 20 20 20  as e:.          
20f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2100: 20 20 20 20 20 20 72 61 69 73 65 20 45 78 63 65        raise Exce
2110: 70 74 69 6f 6e 28 73 74 72 28 65 29 2c 20 22 23  ption(str(e), "#
2120: 20 22 20 2b 20 73 4c 69 6e 65 49 64 20 2b 20 22   " + sLineId + "
2130: 20 23 20 22 20 2b 20 73 52 75 6c 65 49 64 29 0a   # " + sRuleId).
2140: 20 20 20 20 69 66 20 62 50 61 72 61 67 72 61 70      if bParagrap
2150: 68 43 68 61 6e 67 65 3a 0a 20 20 20 20 20 20 20  hChange:.       
2160: 20 72 65 74 75 72 6e 20 28 73 2c 20 64 45 72 72   return (s, dErr
2170: 73 29 0a 20 20 20 20 72 65 74 75 72 6e 20 28 46  s).    return (F
2180: 61 6c 73 65 2c 20 64 45 72 72 73 29 0a 0a 0a 64  alse, dErrs)...d
2190: 65 66 20 5f 63 72 65 61 74 65 52 65 67 65 78 57  ef _createRegexW
21a0: 72 69 74 65 72 45 72 72 6f 72 20 28 73 2c 20 73  riterError (s, s
21b0: 78 2c 20 73 52 65 70 6c 2c 20 6e 4f 66 66 73 65  x, sRepl, nOffse
21c0: 74 2c 20 6d 2c 20 69 47 72 6f 75 70 2c 20 73 4c  t, m, iGroup, sL
21d0: 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20  ineId, sRuleId, 
21e0: 62 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73 67  bUppercase, sMsg
21f0: 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75 6c  , sURL, bShowRul
2200: 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62 43  eId, sOption, bC
2210: 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 22 65 72  ontext):.    "er
2220: 72 6f 72 20 66 6f 72 20 57 72 69 74 65 72 20 28  ror for Writer (
2230: 4c 4f 2f 4f 4f 29 22 0a 20 20 20 20 78 45 72 72  LO/OO)".    xErr
2240: 20 3d 20 53 69 6e 67 6c 65 50 72 6f 6f 66 72 65   = SingleProofre
2250: 61 64 69 6e 67 45 72 72 6f 72 28 29 0a 20 20 20  adingError().   
2260: 20 23 78 45 72 72 20 3d 20 75 6e 6f 2e 63 72 65   #xErr = uno.cre
2270: 61 74 65 55 6e 6f 53 74 72 75 63 74 28 20 22 63  ateUnoStruct( "c
2280: 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 6c 69 6e 67  om.sun.star.ling
2290: 75 69 73 74 69 63 32 2e 53 69 6e 67 6c 65 50 72  uistic2.SinglePr
22a0: 6f 6f 66 72 65 61 64 69 6e 67 45 72 72 6f 72 22  oofreadingError"
22b0: 20 29 0a 20 20 20 20 78 45 72 72 2e 6e 45 72 72   ).    xErr.nErr
22c0: 6f 72 53 74 61 72 74 20 3d 20 6e 4f 66 66 73 65  orStart = nOffse
22d0: 74 20 2b 20 6d 2e 73 74 61 72 74 28 69 47 72 6f  t + m.start(iGro
22e0: 75 70 29 0a 20 20 20 20 78 45 72 72 2e 6e 45 72  up).    xErr.nEr
22f0: 72 6f 72 4c 65 6e 67 74 68 20 3d 20 6d 2e 65 6e  rorLength = m.en
2300: 64 28 69 47 72 6f 75 70 29 20 2d 20 6d 2e 73 74  d(iGroup) - m.st
2310: 61 72 74 28 69 47 72 6f 75 70 29 0a 20 20 20 20  art(iGroup).    
2320: 78 45 72 72 2e 6e 45 72 72 6f 72 54 79 70 65 20  xErr.nErrorType 
2330: 3d 20 50 52 4f 4f 46 52 45 41 44 49 4e 47 0a 20  = PROOFREADING. 
2340: 20 20 20 78 45 72 72 2e 61 52 75 6c 65 49 64 65     xErr.aRuleIde
2350: 6e 74 69 66 69 65 72 20 3d 20 73 52 75 6c 65 49  ntifier = sRuleI
2360: 64 0a 20 20 20 20 23 20 73 75 67 67 65 73 74 69  d.    # suggesti
2370: 6f 6e 73 0a 20 20 20 20 69 66 20 73 52 65 70 6c  ons.    if sRepl
2380: 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20  [0:1] == "=":.  
2390: 20 20 20 20 20 20 73 75 67 67 20 3d 20 67 6c 6f        sugg = glo
23a0: 62 61 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a 5d  bals()[sRepl[1:]
23b0: 5d 28 73 2c 20 6d 29 0a 20 20 20 20 20 20 20 20  ](s, m).        
23c0: 69 66 20 73 75 67 67 3a 0a 20 20 20 20 20 20 20  if sugg:.       
23d0: 20 20 20 20 20 69 66 20 62 55 70 70 65 72 63 61       if bUpperca
23e0: 73 65 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 69  se and m.group(i
23f0: 47 72 6f 75 70 29 5b 30 3a 31 5d 2e 69 73 75 70  Group)[0:1].isup
2400: 70 65 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20  per():.         
2410: 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 75 67         xErr.aSug
2420: 67 65 73 74 69 6f 6e 73 20 3d 20 74 75 70 6c 65  gestions = tuple
2430: 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61 6c  (map(str.capital
2440: 69 7a 65 2c 20 73 75 67 67 2e 73 70 6c 69 74 28  ize, sugg.split(
2450: 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20 20  "|"))).         
2460: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
2470: 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53           xErr.aS
2480: 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74 75 70  uggestions = tup
2490: 6c 65 28 73 75 67 67 2e 73 70 6c 69 74 28 22 7c  le(sugg.split("|
24a0: 22 29 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  ")).        else
24b0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 78 45  :.            xE
24c0: 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73 20  rr.aSuggestions 
24d0: 3d 20 28 29 0a 20 20 20 20 65 6c 69 66 20 73 52  = ().    elif sR
24e0: 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20  epl == "_":.    
24f0: 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65 73      xErr.aSugges
2500: 74 69 6f 6e 73 20 3d 20 28 29 0a 20 20 20 20 65  tions = ().    e
2510: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 69 66 20  lse:.        if 
2520: 62 55 70 70 65 72 63 61 73 65 20 61 6e 64 20 6d  bUppercase and m
2530: 2e 67 72 6f 75 70 28 69 47 72 6f 75 70 29 5b 30  .group(iGroup)[0
2540: 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a 20  :1].isupper():. 
2550: 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72 2e             xErr.
2560: 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74  aSuggestions = t
2570: 75 70 6c 65 28 6d 61 70 28 73 74 72 2e 63 61 70  uple(map(str.cap
2580: 69 74 61 6c 69 7a 65 2c 20 6d 2e 65 78 70 61 6e  italize, m.expan
2590: 64 28 73 52 65 70 6c 29 2e 73 70 6c 69 74 28 22  d(sRepl).split("
25a0: 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20 65 6c  |"))).        el
25b0: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
25c0: 78 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e  xErr.aSuggestion
25d0: 73 20 3d 20 74 75 70 6c 65 28 6d 2e 65 78 70 61  s = tuple(m.expa
25e0: 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c 69 74 28  nd(sRepl).split(
25f0: 22 7c 22 29 29 0a 20 20 20 20 23 20 4d 65 73 73  "|")).    # Mess
2600: 61 67 65 0a 20 20 20 20 73 4d 65 73 73 61 67 65  age.    sMessage
2610: 20 3d 20 67 6c 6f 62 61 6c 73 28 29 5b 73 4d 73   = globals()[sMs
2620: 67 5b 31 3a 5d 5d 28 73 2c 20 6d 29 20 20 69 66  g[1:]](s, m)  if
2630: 20 73 4d 73 67 5b 30 3a 31 5d 20 3d 3d 20 22 3d   sMsg[0:1] == "=
2640: 22 20 20 65 6c 73 65 20 20 6d 2e 65 78 70 61 6e  "  else  m.expan
2650: 64 28 73 4d 73 67 29 0a 20 20 20 20 78 45 72 72  d(sMsg).    xErr
2660: 2e 61 53 68 6f 72 74 43 6f 6d 6d 65 6e 74 20 3d  .aShortComment =
2670: 20 73 4d 65 73 73 61 67 65 20 20 20 23 20 73 4d   sMessage   # sM
2680: 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22 7c 22  essage.split("|"
2690: 29 5b 30 5d 20 20 20 20 20 23 20 69 6e 20 63 6f  )[0]     # in co
26a0: 6e 74 65 78 74 20 6d 65 6e 75 0a 20 20 20 20 78  ntext menu.    x
26b0: 45 72 72 2e 61 46 75 6c 6c 43 6f 6d 6d 65 6e 74  Err.aFullComment
26c0: 20 3d 20 73 4d 65 73 73 61 67 65 20 20 20 23 20   = sMessage   # 
26d0: 73 4d 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22  sMessage.split("
26e0: 7c 22 29 5b 2d 31 5d 20 20 20 20 23 20 69 6e 20  |")[-1]    # in 
26f0: 64 69 61 6c 6f 67 0a 20 20 20 20 69 66 20 62 53  dialog.    if bS
2700: 68 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20 20 20  howRuleId:.     
2710: 20 20 20 78 45 72 72 2e 61 53 68 6f 72 74 43 6f     xErr.aShortCo
2720: 6d 6d 65 6e 74 20 2b 3d 20 22 20 20 23 20 22 20  mment += "  # " 
2730: 2b 20 73 4c 69 6e 65 49 64 20 2b 20 22 20 23 20  + sLineId + " # 
2740: 22 20 2b 20 73 52 75 6c 65 49 64 0a 20 20 20 20  " + sRuleId.    
2750: 23 20 55 52 4c 0a 20 20 20 20 69 66 20 73 55 52  # URL.    if sUR
2760: 4c 3a 0a 20 20 20 20 20 20 20 20 70 20 3d 20 50  L:.        p = P
2770: 72 6f 70 65 72 74 79 56 61 6c 75 65 28 29 0a 20  ropertyValue(). 
2780: 20 20 20 20 20 20 20 70 2e 4e 61 6d 65 20 3d 20         p.Name = 
2790: 22 46 75 6c 6c 43 6f 6d 6d 65 6e 74 55 52 4c 22  "FullCommentURL"
27a0: 0a 20 20 20 20 20 20 20 20 70 2e 56 61 6c 75 65  .        p.Value
27b0: 20 3d 20 73 55 52 4c 0a 20 20 20 20 20 20 20 20   = sURL.        
27c0: 78 45 72 72 2e 61 50 72 6f 70 65 72 74 69 65 73  xErr.aProperties
27d0: 20 3d 20 28 70 2c 29 0a 20 20 20 20 65 6c 73 65   = (p,).    else
27e0: 3a 0a 20 20 20 20 20 20 20 20 78 45 72 72 2e 61  :.        xErr.a
27f0: 50 72 6f 70 65 72 74 69 65 73 20 3d 20 28 29 0a  Properties = ().
2800: 20 20 20 20 72 65 74 75 72 6e 20 78 45 72 72 0a      return xErr.
2810: 0a 0a 64 65 66 20 5f 63 72 65 61 74 65 52 65 67  ..def _createReg
2820: 65 78 44 69 63 74 45 72 72 6f 72 20 28 73 2c 20  exDictError (s, 
2830: 73 78 2c 20 73 52 65 70 6c 2c 20 6e 4f 66 66 73  sx, sRepl, nOffs
2840: 65 74 2c 20 6d 2c 20 69 47 72 6f 75 70 2c 20 73  et, m, iGroup, s
2850: 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c  LineId, sRuleId,
2860: 20 62 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73   bUppercase, sMs
2870: 67 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75  g, sURL, bShowRu
2880: 6c 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62  leId, sOption, b
2890: 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 22 65  Context):.    "e
28a0: 72 72 6f 72 20 61 73 20 61 20 64 69 63 74 69 6f  rror as a dictio
28b0: 6e 61 72 79 22 0a 20 20 20 20 64 45 72 72 20 3d  nary".    dErr =
28c0: 20 7b 7d 0a 20 20 20 20 64 45 72 72 5b 22 6e 53   {}.    dErr["nS
28d0: 74 61 72 74 22 5d 20 3d 20 6e 4f 66 66 73 65 74  tart"] = nOffset
28e0: 20 2b 20 6d 2e 73 74 61 72 74 28 69 47 72 6f 75   + m.start(iGrou
28f0: 70 29 0a 20 20 20 20 64 45 72 72 5b 22 6e 45 6e  p).    dErr["nEn
2900: 64 22 5d 20 3d 20 6e 4f 66 66 73 65 74 20 2b 20  d"] = nOffset + 
2910: 6d 2e 65 6e 64 28 69 47 72 6f 75 70 29 0a 20 20  m.end(iGroup).  
2920: 20 20 64 45 72 72 5b 22 73 4c 69 6e 65 49 64 22    dErr["sLineId"
2930: 5d 20 3d 20 73 4c 69 6e 65 49 64 0a 20 20 20 20  ] = sLineId.    
2940: 64 45 72 72 5b 22 73 52 75 6c 65 49 64 22 5d 20  dErr["sRuleId"] 
2950: 3d 20 73 52 75 6c 65 49 64 0a 20 20 20 20 64 45  = sRuleId.    dE
2960: 72 72 5b 22 73 54 79 70 65 22 5d 20 3d 20 73 4f  rr["sType"] = sO
2970: 70 74 69 6f 6e 20 20 69 66 20 73 4f 70 74 69 6f  ption  if sOptio
2980: 6e 20 20 65 6c 73 65 20 22 6e 6f 74 79 70 65 22  n  else "notype"
2990: 0a 20 20 20 20 23 20 73 75 67 67 65 73 74 69 6f  .    # suggestio
29a0: 6e 73 0a 20 20 20 20 69 66 20 73 52 65 70 6c 5b  ns.    if sRepl[
29b0: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
29c0: 20 20 20 20 20 73 75 67 67 20 3d 20 67 6c 6f 62       sugg = glob
29d0: 61 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a 5d 5d  als()[sRepl[1:]]
29e0: 28 73 2c 20 6d 29 0a 20 20 20 20 20 20 20 20 69  (s, m).        i
29f0: 66 20 73 75 67 67 3a 0a 20 20 20 20 20 20 20 20  f sugg:.        
2a00: 20 20 20 20 69 66 20 62 55 70 70 65 72 63 61 73      if bUppercas
2a10: 65 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 69 47  e and m.group(iG
2a20: 72 6f 75 70 29 5b 30 3a 31 5d 2e 69 73 75 70 70  roup)[0:1].isupp
2a30: 65 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20  er():.          
2a40: 20 20 20 20 20 20 64 45 72 72 5b 22 61 53 75 67        dErr["aSug
2a50: 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20 6c 69 73  gestions"] = lis
2a60: 74 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61  t(map(str.capita
2a70: 6c 69 7a 65 2c 20 73 75 67 67 2e 73 70 6c 69 74  lize, sugg.split
2a80: 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20  ("|"))).        
2a90: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
2aa0: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
2ab0: 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d  aSuggestions"] =
2ac0: 20 73 75 67 67 2e 73 70 6c 69 74 28 22 7c 22 29   sugg.split("|")
2ad0: 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20  .        else:. 
2ae0: 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b             dErr[
2af0: 22 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20  "aSuggestions"] 
2b00: 3d 20 5b 5d 0a 20 20 20 20 65 6c 69 66 20 73 52  = [].    elif sR
2b10: 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20  epl == "_":.    
2b20: 20 20 20 20 64 45 72 72 5b 22 61 53 75 67 67 65      dErr["aSugge
2b30: 73 74 69 6f 6e 73 22 5d 20 3d 20 5b 5d 0a 20 20  stions"] = [].  
2b40: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2b50: 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e  if bUppercase an
2b60: 64 20 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75 70  d m.group(iGroup
2b70: 29 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29  )[0:1].isupper()
2b80: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 45  :.            dE
2b90: 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e 73  rr["aSuggestions
2ba0: 22 5d 20 3d 20 6c 69 73 74 28 6d 61 70 28 73 74  "] = list(map(st
2bb0: 72 2e 63 61 70 69 74 61 6c 69 7a 65 2c 20 6d 2e  r.capitalize, m.
2bc0: 65 78 70 61 6e 64 28 73 52 65 70 6c 29 2e 73 70  expand(sRepl).sp
2bd0: 6c 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20  lit("|"))).     
2be0: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
2bf0: 20 20 20 20 20 64 45 72 72 5b 22 61 53 75 67 67       dErr["aSugg
2c00: 65 73 74 69 6f 6e 73 22 5d 20 3d 20 6d 2e 65 78  estions"] = m.ex
2c10: 70 61 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c 69  pand(sRepl).spli
2c20: 74 28 22 7c 22 29 0a 20 20 20 20 23 20 4d 65 73  t("|").    # Mes
2c30: 73 61 67 65 0a 20 20 20 20 64 45 72 72 5b 22 73  sage.    dErr["s
2c40: 4d 65 73 73 61 67 65 22 5d 20 3d 20 67 6c 6f 62  Message"] = glob
2c50: 61 6c 73 28 29 5b 73 4d 73 67 5b 31 3a 5d 5d 28  als()[sMsg[1:]](
2c60: 73 2c 20 6d 29 20 20 69 66 20 73 4d 73 67 5b 30  s, m)  if sMsg[0
2c70: 3a 31 5d 20 3d 3d 20 22 3d 22 20 20 65 6c 73 65  :1] == "="  else
2c80: 20 20 6d 2e 65 78 70 61 6e 64 28 73 4d 73 67 29    m.expand(sMsg)
2c90: 0a 20 20 20 20 69 66 20 62 53 68 6f 77 52 75 6c  .    if bShowRul
2ca0: 65 49 64 3a 0a 20 20 20 20 20 20 20 20 64 45 72  eId:.        dEr
2cb0: 72 5b 22 73 4d 65 73 73 61 67 65 22 5d 20 2b 3d  r["sMessage"] +=
2cc0: 20 22 20 20 23 20 22 20 2b 20 73 4c 69 6e 65 49   "  # " + sLineI
2cd0: 64 20 2b 20 22 20 23 20 22 20 2b 20 73 52 75 6c  d + " # " + sRul
2ce0: 65 49 64 0a 20 20 20 20 23 20 55 52 4c 0a 20 20  eId.    # URL.  
2cf0: 20 20 64 45 72 72 5b 22 55 52 4c 22 5d 20 3d 20    dErr["URL"] = 
2d00: 73 55 52 4c 20 20 69 66 20 73 55 52 4c 20 20 65  sURL  if sURL  e
2d10: 6c 73 65 20 22 22 0a 20 20 20 20 23 20 43 6f 6e  lse "".    # Con
2d20: 74 65 78 74 0a 20 20 20 20 69 66 20 62 43 6f 6e  text.    if bCon
2d30: 74 65 78 74 3a 0a 20 20 20 20 20 20 20 20 64 45  text:.        dE
2d40: 72 72 5b 27 73 55 6e 64 65 72 6c 69 6e 65 64 27  rr['sUnderlined'
2d50: 5d 20 3d 20 73 78 5b 6d 2e 73 74 61 72 74 28 69  ] = sx[m.start(i
2d60: 47 72 6f 75 70 29 3a 6d 2e 65 6e 64 28 69 47 72  Group):m.end(iGr
2d70: 6f 75 70 29 5d 0a 20 20 20 20 20 20 20 20 64 45  oup)].        dE
2d80: 72 72 5b 27 73 42 65 66 6f 72 65 27 5d 20 3d 20  rr['sBefore'] = 
2d90: 73 78 5b 6d 61 78 28 30 2c 6d 2e 73 74 61 72 74  sx[max(0,m.start
2da0: 28 69 47 72 6f 75 70 29 2d 38 30 29 3a 6d 2e 73  (iGroup)-80):m.s
2db0: 74 61 72 74 28 69 47 72 6f 75 70 29 5d 0a 20 20  tart(iGroup)].  
2dc0: 20 20 20 20 20 20 64 45 72 72 5b 27 73 41 66 74        dErr['sAft
2dd0: 65 72 27 5d 20 3d 20 73 78 5b 6d 2e 65 6e 64 28  er'] = sx[m.end(
2de0: 69 47 72 6f 75 70 29 3a 6d 2e 65 6e 64 28 69 47  iGroup):m.end(iG
2df0: 72 6f 75 70 29 2b 38 30 5d 0a 20 20 20 20 72 65  roup)+80].    re
2e00: 74 75 72 6e 20 64 45 72 72 0a 0a 0a 64 65 66 20  turn dErr...def 
2e10: 5f 72 65 77 72 69 74 65 20 28 73 53 65 6e 74 65  _rewrite (sSente
2e20: 6e 63 65 2c 20 73 52 65 70 6c 2c 20 69 47 72 6f  nce, sRepl, iGro
2e30: 75 70 2c 20 6d 2c 20 62 55 70 70 65 72 63 61 73  up, m, bUppercas
2e40: 65 29 3a 0a 20 20 20 20 22 74 65 78 74 20 70 72  e):.    "text pr
2e50: 6f 63 65 73 73 6f 72 3a 20 77 72 69 74 65 20 3c  ocessor: write <
2e60: 73 52 65 70 6c 3e 20 69 6e 20 3c 73 53 65 6e 74  sRepl> in <sSent
2e70: 65 6e 63 65 3e 20 61 74 20 3c 69 47 72 6f 75 70  ence> at <iGroup
2e80: 3e 20 70 6f 73 69 74 69 6f 6e 22 0a 20 20 20 20  > position".    
2e90: 6e 4c 65 6e 20 3d 20 6d 2e 65 6e 64 28 69 47 72  nLen = m.end(iGr
2ea0: 6f 75 70 29 20 2d 20 6d 2e 73 74 61 72 74 28 69  oup) - m.start(i
2eb0: 47 72 6f 75 70 29 0a 20 20 20 20 69 66 20 73 52  Group).    if sR
2ec0: 65 70 6c 20 3d 3d 20 22 2a 22 3a 0a 20 20 20 20  epl == "*":.    
2ed0: 20 20 20 20 73 4e 65 77 20 3d 20 22 20 22 20 2a      sNew = " " *
2ee0: 20 6e 4c 65 6e 0a 20 20 20 20 65 6c 69 66 20 73   nLen.    elif s
2ef0: 52 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a 20 20 20  Repl == "_":.   
2f00: 20 20 20 20 20 73 4e 65 77 20 3d 20 73 52 65 70       sNew = sRep
2f10: 6c 20 2b 20 22 20 22 20 2a 20 28 6e 4c 65 6e 2d  l + " " * (nLen-
2f20: 31 29 0a 20 20 20 20 65 6c 69 66 20 73 52 65 70  1).    elif sRep
2f30: 6c 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20  l[0:1] == "=":. 
2f40: 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20 67 6c         sNew = gl
2f50: 6f 62 61 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a  obals()[sRepl[1:
2f60: 5d 5d 28 73 53 65 6e 74 65 6e 63 65 2c 20 6d 29  ]](sSentence, m)
2f70: 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20  .        sNew = 
2f80: 73 4e 65 77 20 2b 20 22 20 22 20 2a 20 28 6e 4c  sNew + " " * (nL
2f90: 65 6e 2d 6c 65 6e 28 73 4e 65 77 29 29 0a 20 20  en-len(sNew)).  
2fa0: 20 20 20 20 20 20 69 66 20 62 55 70 70 65 72 63        if bUpperc
2fb0: 61 73 65 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28  ase and m.group(
2fc0: 69 47 72 6f 75 70 29 5b 30 3a 31 5d 2e 69 73 75  iGroup)[0:1].isu
2fd0: 70 70 65 72 28 29 3a 0a 20 20 20 20 20 20 20 20  pper():.        
2fe0: 20 20 20 20 73 4e 65 77 20 3d 20 73 4e 65 77 2e      sNew = sNew.
2ff0: 63 61 70 69 74 61 6c 69 7a 65 28 29 0a 20 20 20  capitalize().   
3000: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 73   else:.        s
3010: 4e 65 77 20 3d 20 6d 2e 65 78 70 61 6e 64 28 73  New = m.expand(s
3020: 52 65 70 6c 29 0a 20 20 20 20 20 20 20 20 73 4e  Repl).        sN
3030: 65 77 20 3d 20 73 4e 65 77 20 2b 20 22 20 22 20  ew = sNew + " " 
3040: 2a 20 28 6e 4c 65 6e 2d 6c 65 6e 28 73 4e 65 77  * (nLen-len(sNew
3050: 29 29 0a 20 20 20 20 72 65 74 75 72 6e 20 73 53  )).    return sS
3060: 65 6e 74 65 6e 63 65 5b 30 3a 6d 2e 73 74 61 72  entence[0:m.star
3070: 74 28 69 47 72 6f 75 70 29 5d 20 2b 20 73 4e 65  t(iGroup)] + sNe
3080: 77 20 2b 20 73 53 65 6e 74 65 6e 63 65 5b 6d 2e  w + sSentence[m.
3090: 65 6e 64 28 69 47 72 6f 75 70 29 3a 5d 0a 0a 0a  end(iGroup):]...
30a0: 64 65 66 20 69 67 6e 6f 72 65 52 75 6c 65 20 28  def ignoreRule (
30b0: 73 52 75 6c 65 49 64 29 3a 0a 20 20 20 20 5f 61  sRuleId):.    _a
30c0: 49 67 6e 6f 72 65 64 52 75 6c 65 73 2e 61 64 64  IgnoredRules.add
30d0: 28 73 52 75 6c 65 49 64 29 0a 0a 0a 64 65 66 20  (sRuleId)...def 
30e0: 72 65 73 65 74 49 67 6e 6f 72 65 52 75 6c 65 73  resetIgnoreRules
30f0: 20 28 29 3a 0a 20 20 20 20 5f 61 49 67 6e 6f 72   ():.    _aIgnor
3100: 65 64 52 75 6c 65 73 2e 63 6c 65 61 72 28 29 0a  edRules.clear().
3110: 0a 0a 64 65 66 20 72 65 61 63 74 69 76 61 74 65  ..def reactivate
3120: 52 75 6c 65 20 28 73 52 75 6c 65 49 64 29 3a 0a  Rule (sRuleId):.
3130: 20 20 20 20 5f 61 49 67 6e 6f 72 65 64 52 75 6c      _aIgnoredRul
3140: 65 73 2e 64 69 73 63 61 72 64 28 73 52 75 6c 65  es.discard(sRule
3150: 49 64 29 0a 0a 0a 64 65 66 20 6c 69 73 74 52 75  Id)...def listRu
3160: 6c 65 73 20 28 73 46 69 6c 74 65 72 3d 4e 6f 6e  les (sFilter=Non
3170: 65 29 3a 0a 20 20 20 20 22 67 65 6e 65 72 61 74  e):.    "generat
3180: 6f 72 3a 20 72 65 74 75 72 6e 73 20 74 79 70 6c  or: returns typl
3190: 65 20 28 73 4f 70 74 69 6f 6e 2c 20 73 4c 69 6e  e (sOption, sLin
31a0: 65 49 64 2c 20 73 52 75 6c 65 49 64 29 22 0a 20  eId, sRuleId)". 
31b0: 20 20 20 69 66 20 73 46 69 6c 74 65 72 3a 0a 20     if sFilter:. 
31c0: 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20         try:.    
31d0: 20 20 20 20 20 20 20 20 7a 46 69 6c 74 65 72 20          zFilter 
31e0: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 46 69  = re.compile(sFi
31f0: 6c 74 65 72 29 0a 20 20 20 20 20 20 20 20 65 78  lter).        ex
3200: 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 20 20  cept:.          
3210: 20 20 65 63 68 6f 28 22 23 20 45 72 72 6f 72 2e    echo("# Error.
3220: 20 4c 69 73 74 20 72 75 6c 65 73 3a 20 77 72 6f   List rules: wro
3230: 6e 67 20 72 65 67 65 78 2e 22 29 0a 20 20 20 20  ng regex.").    
3240: 20 20 20 20 20 20 20 20 73 46 69 6c 74 65 72 20          sFilter 
3250: 3d 20 4e 6f 6e 65 0a 20 20 20 20 66 6f 72 20 73  = None.    for s
3260: 4f 70 74 69 6f 6e 2c 20 6c 52 75 6c 65 47 72 6f  Option, lRuleGro
3270: 75 70 20 69 6e 20 63 68 61 69 6e 28 5f 67 65 74  up in chain(_get
3280: 52 75 6c 65 73 28 54 72 75 65 29 2c 20 5f 67 65  Rules(True), _ge
3290: 74 52 75 6c 65 73 28 46 61 6c 73 65 29 29 3a 0a  tRules(False)):.
32a0: 20 20 20 20 20 20 20 20 69 66 20 73 4f 70 74 69          if sOpti
32b0: 6f 6e 20 21 3d 20 22 40 40 40 40 22 3a 0a 20 20  on != "@@@@":.  
32c0: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 5f 2c            for _,
32d0: 20 5f 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75   _, sLineId, sRu
32e0: 6c 65 49 64 2c 20 5f 2c 20 5f 20 69 6e 20 6c 52  leId, _, _ in lR
32f0: 75 6c 65 47 72 6f 75 70 3a 0a 20 20 20 20 20 20  uleGroup:.      
3300: 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74            if not
3310: 20 73 46 69 6c 74 65 72 20 6f 72 20 7a 46 69 6c   sFilter or zFil
3320: 74 65 72 2e 73 65 61 72 63 68 28 73 52 75 6c 65  ter.search(sRule
3330: 49 64 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  Id):.           
3340: 20 20 20 20 20 20 20 20 20 79 69 65 6c 64 20 28           yield (
3350: 73 4f 70 74 69 6f 6e 2c 20 73 4c 69 6e 65 49 64  sOption, sLineId
3360: 2c 20 73 52 75 6c 65 49 64 29 0a 0a 0a 64 65 66  , sRuleId)...def
3370: 20 64 69 73 70 6c 61 79 52 75 6c 65 73 20 28 73   displayRules (s
3380: 46 69 6c 74 65 72 3d 4e 6f 6e 65 29 3a 0a 20 20  Filter=None):.  
3390: 20 20 65 63 68 6f 28 22 4c 69 73 74 20 6f 66 20    echo("List of 
33a0: 72 75 6c 65 73 2e 20 46 69 6c 74 65 72 3a 20 3c  rules. Filter: <
33b0: 3c 20 22 20 2b 20 73 74 72 28 73 46 69 6c 74 65  < " + str(sFilte
33c0: 72 29 20 2b 20 22 20 3e 3e 22 29 0a 20 20 20 20  r) + " >>").    
33d0: 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 73 4c 69  for sOption, sLi
33e0: 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 20 69 6e  neId, sRuleId in
33f0: 20 6c 69 73 74 52 75 6c 65 73 28 73 46 69 6c 74   listRules(sFilt
3400: 65 72 29 3a 0a 20 20 20 20 20 20 20 20 65 63 68  er):.        ech
3410: 6f 28 22 7b 3a 3c 31 30 7d 20 7b 3a 3c 31 30 7d  o("{:<10} {:<10}
3420: 20 7b 7d 22 2e 66 6f 72 6d 61 74 28 73 4f 70 74   {}".format(sOpt
3430: 69 6f 6e 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52  ion, sLineId, sR
3440: 75 6c 65 49 64 29 29 0a 0a 0a 64 65 66 20 73 65  uleId))...def se
3450: 74 4f 70 74 69 6f 6e 20 28 73 4f 70 74 2c 20 62  tOption (sOpt, b
3460: 56 61 6c 29 3a 0a 20 20 20 20 69 66 20 73 4f 70  Val):.    if sOp
3470: 74 20 69 6e 20 5f 64 4f 70 74 69 6f 6e 73 3a 0a  t in _dOptions:.
3480: 20 20 20 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e          _dOption
3490: 73 5b 73 4f 70 74 5d 20 3d 20 62 56 61 6c 0a 0a  s[sOpt] = bVal..
34a0: 0a 64 65 66 20 73 65 74 4f 70 74 69 6f 6e 73 20  .def setOptions 
34b0: 28 64 4f 70 74 29 3a 0a 20 20 20 20 66 6f 72 20  (dOpt):.    for 
34c0: 73 4b 65 79 2c 20 62 56 61 6c 20 69 6e 20 64 4f  sKey, bVal in dO
34d0: 70 74 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20 20  pt.items():.    
34e0: 20 20 20 20 69 66 20 73 4b 65 79 20 69 6e 20 5f      if sKey in _
34f0: 64 4f 70 74 69 6f 6e 73 3a 0a 20 20 20 20 20 20  dOptions:.      
3500: 20 20 20 20 20 20 5f 64 4f 70 74 69 6f 6e 73 5b        _dOptions[
3510: 73 4b 65 79 5d 20 3d 20 62 56 61 6c 0a 0a 0a 64  sKey] = bVal...d
3520: 65 66 20 67 65 74 4f 70 74 69 6f 6e 73 20 28 29  ef getOptions ()
3530: 3a 0a 20 20 20 20 72 65 74 75 72 6e 20 5f 64 4f  :.    return _dO
3540: 70 74 69 6f 6e 73 0a 0a 0a 64 65 66 20 67 65 74  ptions...def get
3550: 44 65 66 61 75 6c 74 4f 70 74 69 6f 6e 73 20 28  DefaultOptions (
3560: 29 3a 0a 20 20 20 20 72 65 74 75 72 6e 20 64 69  ):.    return di
3570: 63 74 28 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  ct(gc_options.ge
3580: 74 4f 70 74 69 6f 6e 73 28 5f 73 41 70 70 43 6f  tOptions(_sAppCo
3590: 6e 74 65 78 74 29 29 0a 0a 0a 64 65 66 20 67 65  ntext))...def ge
35a0: 74 4f 70 74 69 6f 6e 73 4c 61 62 65 6c 73 20 28  tOptionsLabels (
35b0: 73 4c 61 6e 67 29 3a 0a 20 20 20 20 72 65 74 75  sLang):.    retu
35c0: 72 6e 20 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  rn gc_options.ge
35d0: 74 55 49 28 73 4c 61 6e 67 29 0a 0a 0a 64 65 66  tUI(sLang)...def
35e0: 20 64 69 73 70 6c 61 79 4f 70 74 69 6f 6e 73 20   displayOptions 
35f0: 28 73 4c 61 6e 67 29 3a 0a 20 20 20 20 65 63 68  (sLang):.    ech
3600: 6f 28 22 4c 69 73 74 20 6f 66 20 6f 70 74 69 6f  o("List of optio
3610: 6e 73 22 29 0a 20 20 20 20 65 63 68 6f 28 22 5c  ns").    echo("\
3620: 6e 22 2e 6a 6f 69 6e 28 20 5b 20 6b 2b 22 3a 5c  n".join( [ k+":\
3630: 74 22 2b 73 74 72 28 76 29 2b 22 5c 74 22 2b 67  t"+str(v)+"\t"+g
3640: 63 5f 6f 70 74 69 6f 6e 73 2e 67 65 74 55 49 28  c_options.getUI(
3650: 73 4c 61 6e 67 29 2e 67 65 74 28 6b 2c 20 28 22  sLang).get(k, ("
3660: 3f 22 2c 20 22 22 29 29 5b 30 5d 20 20 66 6f 72  ?", ""))[0]  for
3670: 20 6b 2c 20 76 20 20 69 6e 20 73 6f 72 74 65 64   k, v  in sorted
3680: 28 5f 64 4f 70 74 69 6f 6e 73 2e 69 74 65 6d 73  (_dOptions.items
3690: 28 29 29 20 5d 20 29 29 0a 20 20 20 20 65 63 68  ()) ] )).    ech
36a0: 6f 28 22 22 29 0a 0a 0a 64 65 66 20 72 65 73 65  o("")...def rese
36b0: 74 4f 70 74 69 6f 6e 73 20 28 29 3a 0a 20 20 20  tOptions ():.   
36c0: 20 67 6c 6f 62 61 6c 20 5f 64 4f 70 74 69 6f 6e   global _dOption
36d0: 73 0a 20 20 20 20 5f 64 4f 70 74 69 6f 6e 73 20  s.    _dOptions 
36e0: 3d 20 64 69 63 74 28 67 63 5f 6f 70 74 69 6f 6e  = dict(gc_option
36f0: 73 2e 67 65 74 4f 70 74 69 6f 6e 73 28 5f 73 41  s.getOptions(_sA
3700: 70 70 43 6f 6e 74 65 78 74 29 29 0a 0a 0a 64 65  ppContext))...de
3710: 66 20 67 65 74 53 70 65 6c 6c 43 68 65 63 6b 65  f getSpellChecke
3720: 72 20 28 29 3a 0a 20 20 20 20 72 65 74 75 72 6e  r ():.    return
3730: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 0a   _oSpellChecker.
3740: 0a 0a 64 65 66 20 5f 67 65 74 50 61 74 68 20 28  ..def _getPath (
3750: 29 3a 0a 20 20 20 20 72 65 74 75 72 6e 20 6f 73  ):.    return os
3760: 2e 70 61 74 68 2e 6a 6f 69 6e 28 6f 73 2e 70 61  .path.join(os.pa
3770: 74 68 2e 64 69 72 6e 61 6d 65 28 73 79 73 2e 6d  th.dirname(sys.m
3780: 6f 64 75 6c 65 73 5b 5f 5f 6e 61 6d 65 5f 5f 5d  odules[__name__]
3790: 2e 5f 5f 66 69 6c 65 5f 5f 29 2c 20 5f 5f 6e 61  .__file__), __na
37a0: 6d 65 5f 5f 20 2b 20 22 2e 70 79 22 29 0a 0a 0a  me__ + ".py")...
37b0: 0a 23 23 23 23 20 63 6f 6d 6d 6f 6e 20 66 75 6e  .#### common fun
37c0: 63 74 69 6f 6e 73 0a 0a 64 65 66 20 6f 70 74 69  ctions..def opti
37d0: 6f 6e 20 28 73 4f 70 74 29 3a 0a 20 20 20 20 22  on (sOpt):.    "
37e0: 72 65 74 75 72 6e 20 54 72 75 65 20 69 66 20 6f  return True if o
37f0: 70 74 69 6f 6e 20 73 4f 70 74 20 69 73 20 61 63  ption sOpt is ac
3800: 74 69 76 65 22 0a 20 20 20 20 72 65 74 75 72 6e  tive".    return
3810: 20 5f 64 4f 70 74 69 6f 6e 73 2e 67 65 74 28 73   _dOptions.get(s
3820: 4f 70 74 2c 20 46 61 6c 73 65 29 0a 0a 0a 64 65  Opt, False)...de
3830: 66 20 64 69 73 70 6c 61 79 49 6e 66 6f 20 28 64  f displayInfo (d
3840: 54 6f 6b 65 6e 50 6f 73 2c 20 74 57 6f 72 64 29  TokenPos, tWord)
3850: 3a 0a 20 20 20 20 22 66 6f 72 20 64 65 62 75 67  :.    "for debug
3860: 67 69 6e 67 3a 20 72 65 74 72 69 65 76 65 20 69  ging: retrieve i
3870: 6e 66 6f 20 6f 66 20 77 6f 72 64 22 0a 20 20 20  nfo of word".   
3880: 20 69 66 20 6e 6f 74 20 74 57 6f 72 64 3a 0a 20   if not tWord:. 
3890: 20 20 20 20 20 20 20 65 63 68 6f 28 22 3e 20 6e         echo("> n
38a0: 6f 74 68 69 6e 67 20 74 6f 20 66 69 6e 64 22 29  othing to find")
38b0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
38c0: 54 72 75 65 0a 20 20 20 20 6c 4d 6f 72 70 68 20  True.    lMorph 
38d0: 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  = _oSpellChecker
38e0: 2e 67 65 74 4d 6f 72 70 68 28 74 57 6f 72 64 5b  .getMorph(tWord[
38f0: 31 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c  1]).    if not l
3900: 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 65  Morph:.        e
3910: 63 68 6f 28 22 3e 20 6e 6f 74 20 69 6e 20 64 69  cho("> not in di
3920: 63 74 69 6f 6e 61 72 79 22 29 0a 20 20 20 20 20  ctionary").     
3930: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20     return True. 
3940: 20 20 20 69 66 20 74 57 6f 72 64 5b 30 5d 20 69     if tWord[0] i
3950: 6e 20 64 54 6f 6b 65 6e 50 6f 73 20 61 6e 64 20  n dTokenPos and 
3960: 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b  "lMorph" in dTok
3970: 65 6e 50 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 3a  enPos[tWord[0]]:
3980: 0a 20 20 20 20 20 20 20 20 65 63 68 6f 28 22 44  .        echo("D
3990: 41 3a 20 22 20 2b 20 73 74 72 28 64 54 6f 6b 65  A: " + str(dToke
39a0: 6e 50 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 5b 22  nPos[tWord[0]]["
39b0: 6c 4d 6f 72 70 68 22 5d 29 29 0a 20 20 20 20 65  lMorph"])).    e
39c0: 63 68 6f 28 22 46 53 41 3a 20 22 20 2b 20 73 74  cho("FSA: " + st
39d0: 72 28 6c 4d 6f 72 70 68 29 29 0a 20 20 20 20 72  r(lMorph)).    r
39e0: 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66  eturn True...def
39f0: 20 6d 6f 72 70 68 20 28 64 54 6f 6b 65 6e 50 6f   morph (dTokenPo
3a00: 73 2c 20 74 57 6f 72 64 2c 20 73 50 61 74 74 65  s, tWord, sPatte
3a10: 72 6e 2c 20 62 53 74 72 69 63 74 3d 54 72 75 65  rn, bStrict=True
3a20: 2c 20 62 4e 6f 57 6f 72 64 3d 46 61 6c 73 65 29  , bNoWord=False)
3a30: 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61  :.    "analyse a
3a40: 20 74 75 70 6c 65 20 28 70 6f 73 69 74 69 6f 6e   tuple (position
3a50: 2c 20 77 6f 72 64 29 2c 20 72 65 74 75 72 6e 20  , word), return 
3a60: 54 72 75 65 20 69 66 20 73 50 61 74 74 65 72 6e  True if sPattern
3a70: 20 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73   in morphologies
3a80: 20 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e   (disambiguation
3a90: 20 6f 6e 29 22 0a 20 20 20 20 69 66 20 6e 6f 74   on)".    if not
3aa0: 20 74 57 6f 72 64 3a 0a 20 20 20 20 20 20 20 20   tWord:.        
3ab0: 72 65 74 75 72 6e 20 62 4e 6f 57 6f 72 64 0a 20  return bNoWord. 
3ac0: 20 20 20 6c 4d 6f 72 70 68 20 3d 20 64 54 6f 6b     lMorph = dTok
3ad0: 65 6e 50 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 5b  enPos[tWord[0]][
3ae0: 22 6c 4d 6f 72 70 68 22 5d 20 20 69 66 20 74 57  "lMorph"]  if tW
3af0: 6f 72 64 5b 30 5d 20 69 6e 20 64 54 6f 6b 65 6e  ord[0] in dToken
3b00: 50 6f 73 20 61 6e 64 20 22 6c 4d 6f 72 70 68 22  Pos and "lMorph"
3b10: 20 69 6e 20 64 54 6f 6b 65 6e 50 6f 73 5b 74 57   in dTokenPos[tW
3b20: 6f 72 64 5b 30 5d 5d 20 20 65 6c 73 65 20 5f 6f  ord[0]]  else _o
3b30: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74  SpellChecker.get
3b40: 4d 6f 72 70 68 28 74 57 6f 72 64 5b 31 5d 29 0a  Morph(tWord[1]).
3b50: 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70      if not lMorp
3b60: 68 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  h:.        retur
3b70: 6e 20 46 61 6c 73 65 0a 20 20 20 20 70 20 3d 20  n False.    p = 
3b80: 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74  re.compile(sPatt
3b90: 65 72 6e 29 0a 20 20 20 20 69 66 20 62 53 74 72  ern).    if bStr
3ba0: 69 63 74 3a 0a 20 20 20 20 20 20 20 20 72 65 74  ict:.        ret
3bb0: 75 72 6e 20 61 6c 6c 28 70 2e 73 65 61 72 63 68  urn all(p.search
3bc0: 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d  (s)  for s in lM
3bd0: 6f 72 70 68 29 0a 20 20 20 20 72 65 74 75 72 6e  orph).    return
3be0: 20 61 6e 79 28 70 2e 73 65 61 72 63 68 28 73 29   any(p.search(s)
3bf0: 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70    for s in lMorp
3c00: 68 29 0a 0a 0a 64 65 66 20 6d 6f 72 70 68 65 78  h)...def morphex
3c10: 20 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 74 57 6f   (dTokenPos, tWo
3c20: 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e  rd, sPattern, sN
3c30: 65 67 50 61 74 74 65 72 6e 2c 20 62 4e 6f 57 6f  egPattern, bNoWo
3c40: 72 64 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22  rd=False):.    "
3c50: 61 6e 61 6c 79 73 65 20 61 20 74 75 70 6c 65 20  analyse a tuple 
3c60: 28 70 6f 73 69 74 69 6f 6e 2c 20 77 6f 72 64 29  (position, word)
3c70: 2c 20 72 65 74 75 72 6e 73 20 54 72 75 65 20 69  , returns True i
3c80: 66 20 6e 6f 74 20 73 4e 65 67 50 61 74 74 65 72  f not sNegPatter
3c90: 6e 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70 68 6f  n in word morpho
3ca0: 6c 6f 67 69 65 73 20 61 6e 64 20 73 50 61 74 74  logies and sPatt
3cb0: 65 72 6e 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70  ern in word morp
3cc0: 68 6f 6c 6f 67 69 65 73 20 28 64 69 73 61 6d 62  hologies (disamb
3cd0: 69 67 75 61 74 69 6f 6e 20 6f 6e 29 22 0a 20 20  iguation on)".  
3ce0: 20 20 69 66 20 6e 6f 74 20 74 57 6f 72 64 3a 0a    if not tWord:.
3cf0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 62          return b
3d00: 4e 6f 57 6f 72 64 0a 20 20 20 20 6c 4d 6f 72 70  NoWord.    lMorp
3d10: 68 20 3d 20 64 54 6f 6b 65 6e 50 6f 73 5b 74 57  h = dTokenPos[tW
3d20: 6f 72 64 5b 30 5d 5d 5b 22 6c 4d 6f 72 70 68 22  ord[0]]["lMorph"
3d30: 5d 20 20 69 66 20 74 57 6f 72 64 5b 30 5d 20 69  ]  if tWord[0] i
3d40: 6e 20 64 54 6f 6b 65 6e 50 6f 73 20 61 6e 64 20  n dTokenPos and 
3d50: 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b  "lMorph" in dTok
3d60: 65 6e 50 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 20  enPos[tWord[0]] 
3d70: 20 65 6c 73 65 20 5f 6f 53 70 65 6c 6c 43 68 65   else _oSpellChe
3d80: 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 74 57  cker.getMorph(tW
3d90: 6f 72 64 5b 31 5d 29 0a 20 20 20 20 69 66 20 6e  ord[1]).    if n
3da0: 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20 20 20 20 20  ot lMorph:.     
3db0: 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a     return False.
3dc0: 20 20 20 20 23 20 63 68 65 63 6b 20 6e 65 67 61      # check nega
3dd0: 74 69 76 65 20 63 6f 6e 64 69 74 69 6f 6e 0a 20  tive condition. 
3de0: 20 20 20 6e 70 20 3d 20 72 65 2e 63 6f 6d 70 69     np = re.compi
3df0: 6c 65 28 73 4e 65 67 50 61 74 74 65 72 6e 29 0a  le(sNegPattern).
3e00: 20 20 20 20 69 66 20 61 6e 79 28 6e 70 2e 73 65      if any(np.se
3e10: 61 72 63 68 28 73 29 20 20 66 6f 72 20 73 20 69  arch(s)  for s i
3e20: 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20  n lMorph):.     
3e30: 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a     return False.
3e40: 20 20 20 20 23 20 73 65 61 72 63 68 20 73 50 61      # search sPa
3e50: 74 74 65 72 6e 0a 20 20 20 20 70 20 3d 20 72 65  ttern.    p = re
3e60: 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72  .compile(sPatter
3e70: 6e 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e  n).    return an
3e80: 79 28 70 2e 73 65 61 72 63 68 28 73 29 20 20 66  y(p.search(s)  f
3e90: 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a  or s in lMorph).
3ea0: 0a 0a 64 65 66 20 61 6e 61 6c 79 73 65 20 28 73  ..def analyse (s
3eb0: 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20  Word, sPattern, 
3ec0: 62 53 74 72 69 63 74 3d 54 72 75 65 29 3a 0a 20  bStrict=True):. 
3ed0: 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 77 6f     "analyse a wo
3ee0: 72 64 2c 20 72 65 74 75 72 6e 20 54 72 75 65 20  rd, return True 
3ef0: 69 66 20 73 50 61 74 74 65 72 6e 20 69 6e 20 6d  if sPattern in m
3f00: 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28 64 69 73  orphologies (dis
3f10: 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f 66 66 29  ambiguation off)
3f20: 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f  ".    lMorph = _
3f30: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
3f40: 74 4d 6f 72 70 68 28 73 57 6f 72 64 29 0a 20 20  tMorph(sWord).  
3f50: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a    if not lMorph:
3f60: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3f70: 46 61 6c 73 65 0a 20 20 20 20 70 20 3d 20 72 65  False.    p = re
3f80: 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72  .compile(sPatter
3f90: 6e 29 0a 20 20 20 20 69 66 20 62 53 74 72 69 63  n).    if bStric
3fa0: 74 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  t:.        retur
3fb0: 6e 20 61 6c 6c 28 70 2e 73 65 61 72 63 68 28 73  n all(p.search(s
3fc0: 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72  )  for s in lMor
3fd0: 70 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61  ph).    return a
3fe0: 6e 79 28 70 2e 73 65 61 72 63 68 28 73 29 20 20  ny(p.search(s)  
3ff0: 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29  for s in lMorph)
4000: 0a 0a 0a 64 65 66 20 61 6e 61 6c 79 73 65 78 20  ...def analysex 
4010: 28 73 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e  (sWord, sPattern
4020: 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 29 3a 0a  , sNegPattern):.
4030: 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 77      "analyse a w
4040: 6f 72 64 2c 20 72 65 74 75 72 6e 73 20 54 72 75  ord, returns Tru
4050: 65 20 69 66 20 6e 6f 74 20 73 4e 65 67 50 61 74  e if not sNegPat
4060: 74 65 72 6e 20 69 6e 20 77 6f 72 64 20 6d 6f 72  tern in word mor
4070: 70 68 6f 6c 6f 67 69 65 73 20 61 6e 64 20 73 50  phologies and sP
4080: 61 74 74 65 72 6e 20 69 6e 20 77 6f 72 64 20 6d  attern in word m
4090: 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28 64 69 73  orphologies (dis
40a0: 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f 66 66 29  ambiguation off)
40b0: 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f  ".    lMorph = _
40c0: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
40d0: 74 4d 6f 72 70 68 28 73 57 6f 72 64 29 0a 20 20  tMorph(sWord).  
40e0: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a    if not lMorph:
40f0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
4100: 46 61 6c 73 65 0a 20 20 20 20 23 20 63 68 65 63  False.    # chec
4110: 6b 20 6e 65 67 61 74 69 76 65 20 63 6f 6e 64 69  k negative condi
4120: 74 69 6f 6e 0a 20 20 20 20 6e 70 20 3d 20 72 65  tion.    np = re
4130: 2e 63 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61 74  .compile(sNegPat
4140: 74 65 72 6e 29 0a 20 20 20 20 69 66 20 61 6e 79  tern).    if any
4150: 28 6e 70 2e 73 65 61 72 63 68 28 73 29 20 20 66  (np.search(s)  f
4160: 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 3a  or s in lMorph):
4170: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
4180: 46 61 6c 73 65 0a 20 20 20 20 23 20 73 65 61 72  False.    # sear
4190: 63 68 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20  ch sPattern.    
41a0: 70 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73  p = re.compile(s
41b0: 50 61 74 74 65 72 6e 29 0a 20 20 20 20 72 65 74  Pattern).    ret
41c0: 75 72 6e 20 61 6e 79 28 70 2e 73 65 61 72 63 68  urn any(p.search
41d0: 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d  (s)  for s in lM
41e0: 6f 72 70 68 29 0a 0a 0a 0a 23 23 20 66 75 6e 63  orph)....## func
41f0: 74 69 6f 6e 73 20 74 6f 20 67 65 74 20 74 65 78  tions to get tex
4200: 74 20 6f 75 74 73 69 64 65 20 70 61 74 74 65 72  t outside patter
4210: 6e 20 73 63 6f 70 65 0a 0a 23 20 77 61 72 6e 69  n scope..# warni
4220: 6e 67 3a 20 63 68 65 63 6b 20 63 6f 6d 70 69 6c  ng: check compil
4230: 65 5f 72 75 6c 65 73 2e 70 79 20 74 6f 20 75 6e  e_rules.py to un
4240: 64 65 72 73 74 61 6e 64 20 68 6f 77 20 69 74 20  derstand how it 
4250: 77 6f 72 6b 73 0a 0a 5f 7a 4e 65 78 74 57 6f 72  works.._zNextWor
4260: 64 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72  d = re.compile(r
4270: 22 20 2b 28 5c 77 5b 5c 77 2d 5d 2a 29 22 29 0a  " +(\w[\w-]*)").
4280: 5f 7a 50 72 65 76 57 6f 72 64 20 3d 20 72 65 2e  _zPrevWord = re.
4290: 63 6f 6d 70 69 6c 65 28 72 22 28 5c 77 5b 5c 77  compile(r"(\w[\w
42a0: 2d 5d 2a 29 20 2b 24 22 29 0a 0a 64 65 66 20 6e  -]*) +$")..def n
42b0: 65 78 74 77 6f 72 64 20 28 73 2c 20 69 53 74 61  extword (s, iSta
42c0: 72 74 2c 20 6e 29 3a 0a 20 20 20 20 22 67 65 74  rt, n):.    "get
42d0: 20 74 68 65 20 6e 74 68 20 77 6f 72 64 20 6f 66   the nth word of
42e0: 20 74 68 65 20 69 6e 70 75 74 20 73 74 72 69 6e   the input strin
42f0: 67 20 6f 72 20 65 6d 70 74 79 20 73 74 72 69 6e  g or empty strin
4300: 67 22 0a 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61  g".    m = re.ma
4310: 74 63 68 28 22 28 3f 3a 20 2b 5b 5c 5c 77 25 2d  tch("(?: +[\\w%-
4320: 5d 2b 29 7b 22 20 2b 20 73 74 72 28 6e 2d 31 29  ]+){" + str(n-1)
4330: 20 2b 20 22 7d 20 2b 28 5b 5c 5c 77 25 2d 5d 2b   + "} +([\\w%-]+
4340: 29 22 2c 20 73 5b 69 53 74 61 72 74 3a 5d 29 0a  )", s[iStart:]).
4350: 20 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20      if not m:.  
4360: 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e        return Non
4370: 65 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 53  e.    return (iS
4380: 74 61 72 74 2b 6d 2e 73 74 61 72 74 28 31 29 2c  tart+m.start(1),
4390: 20 6d 2e 67 72 6f 75 70 28 31 29 29 0a 0a 0a 64   m.group(1))...d
43a0: 65 66 20 70 72 65 76 77 6f 72 64 20 28 73 2c 20  ef prevword (s, 
43b0: 69 45 6e 64 2c 20 6e 29 3a 0a 20 20 20 20 22 67  iEnd, n):.    "g
43c0: 65 74 20 74 68 65 20 28 2d 29 6e 74 68 20 77 6f  et the (-)nth wo
43d0: 72 64 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20  rd of the input 
43e0: 73 74 72 69 6e 67 20 6f 72 20 65 6d 70 74 79 20  string or empty 
43f0: 73 74 72 69 6e 67 22 0a 20 20 20 20 6d 20 3d 20  string".    m = 
4400: 72 65 2e 73 65 61 72 63 68 28 22 28 5b 5c 5c 77  re.search("([\\w
4410: 25 2d 5d 2b 29 20 2b 28 3f 3a 5b 5c 5c 77 25 2d  %-]+) +(?:[\\w%-
4420: 5d 2b 20 2b 29 7b 22 20 2b 20 73 74 72 28 6e 2d  ]+ +){" + str(n-
4430: 31 29 20 2b 20 22 7d 24 22 2c 20 73 5b 3a 69 45  1) + "}$", s[:iE
4440: 6e 64 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  nd]).    if not 
4450: 6d 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  m:.        retur
4460: 6e 20 4e 6f 6e 65 0a 20 20 20 20 72 65 74 75 72  n None.    retur
4470: 6e 20 28 6d 2e 73 74 61 72 74 28 31 29 2c 20 6d  n (m.start(1), m
4480: 2e 67 72 6f 75 70 28 31 29 29 0a 0a 0a 64 65 66  .group(1))...def
4490: 20 6e 65 78 74 77 6f 72 64 31 20 28 73 2c 20 69   nextword1 (s, i
44a0: 53 74 61 72 74 29 3a 0a 20 20 20 20 22 67 65 74  Start):.    "get
44b0: 20 6e 65 78 74 20 77 6f 72 64 20 28 6f 70 74 69   next word (opti
44c0: 6d 69 7a 61 74 69 6f 6e 29 22 0a 20 20 20 20 6d  mization)".    m
44d0: 20 3d 20 5f 7a 4e 65 78 74 57 6f 72 64 2e 6d 61   = _zNextWord.ma
44e0: 74 63 68 28 73 5b 69 53 74 61 72 74 3a 5d 29 0a  tch(s[iStart:]).
44f0: 20 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20      if not m:.  
4500: 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e        return Non
4510: 65 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 53  e.    return (iS
4520: 74 61 72 74 2b 6d 2e 73 74 61 72 74 28 31 29 2c  tart+m.start(1),
4530: 20 6d 2e 67 72 6f 75 70 28 31 29 29 0a 0a 0a 64   m.group(1))...d
4540: 65 66 20 70 72 65 76 77 6f 72 64 31 20 28 73 2c  ef prevword1 (s,
4550: 20 69 45 6e 64 29 3a 0a 20 20 20 20 22 67 65 74   iEnd):.    "get
4560: 20 70 72 65 76 69 6f 75 73 20 77 6f 72 64 20 28   previous word (
4570: 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 29 22 0a 20  optimization)". 
4580: 20 20 20 6d 20 3d 20 5f 7a 50 72 65 76 57 6f 72     m = _zPrevWor
4590: 64 2e 73 65 61 72 63 68 28 73 5b 3a 69 45 6e 64  d.search(s[:iEnd
45a0: 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6d 3a  ]).    if not m:
45b0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
45c0: 4e 6f 6e 65 0a 20 20 20 20 72 65 74 75 72 6e 20  None.    return 
45d0: 28 6d 2e 73 74 61 72 74 28 31 29 2c 20 6d 2e 67  (m.start(1), m.g
45e0: 72 6f 75 70 28 31 29 29 0a 0a 0a 64 65 66 20 6c  roup(1))...def l
45f0: 6f 6f 6b 20 28 73 2c 20 73 50 61 74 74 65 72 6e  ook (s, sPattern
4600: 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 3d 4e 6f  , sNegPattern=No
4610: 6e 65 29 3a 0a 20 20 20 20 22 73 65 65 6b 20 73  ne):.    "seek s
4620: 50 61 74 74 65 72 6e 20 69 6e 20 73 20 28 62 65  Pattern in s (be
4630: 66 6f 72 65 2f 61 66 74 65 72 2f 66 75 6c 6c 74  fore/after/fullt
4640: 65 78 74 29 2c 20 69 66 20 73 4e 65 67 50 61 74  ext), if sNegPat
4650: 74 65 72 6e 20 6e 6f 74 20 69 6e 20 73 22 0a 20  tern not in s". 
4660: 20 20 20 69 66 20 73 4e 65 67 50 61 74 74 65 72     if sNegPatter
4670: 6e 20 61 6e 64 20 72 65 2e 73 65 61 72 63 68 28  n and re.search(
4680: 73 4e 65 67 50 61 74 74 65 72 6e 2c 20 73 29 3a  sNegPattern, s):
4690: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
46a0: 46 61 6c 73 65 0a 20 20 20 20 69 66 20 72 65 2e  False.    if re.
46b0: 73 65 61 72 63 68 28 73 50 61 74 74 65 72 6e 2c  search(sPattern,
46c0: 20 73 29 3a 0a 20 20 20 20 20 20 20 20 72 65 74   s):.        ret
46d0: 75 72 6e 20 54 72 75 65 0a 20 20 20 20 72 65 74  urn True.    ret
46e0: 75 72 6e 20 46 61 6c 73 65 0a 0a 0a 64 65 66 20  urn False...def 
46f0: 6c 6f 6f 6b 5f 63 68 6b 31 20 28 64 54 6f 6b 65  look_chk1 (dToke
4700: 6e 50 6f 73 2c 20 73 2c 20 6e 4f 66 66 73 65 74  nPos, s, nOffset
4710: 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 50 61 74  , sPattern, sPat
4720: 74 65 72 6e 47 72 6f 75 70 31 2c 20 73 4e 65 67  ternGroup1, sNeg
4730: 50 61 74 74 65 72 6e 47 72 6f 75 70 31 3d 4e 6f  PatternGroup1=No
4740: 6e 65 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e  ne):.    "return
4750: 73 20 54 72 75 65 20 69 66 20 73 20 68 61 73 20  s True if s has 
4760: 70 61 74 74 65 72 6e 20 73 50 61 74 74 65 72 6e  pattern sPattern
4770: 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 31 29 20   and m.group(1) 
4780: 68 61 73 20 70 61 74 74 65 72 6e 20 73 50 61 74  has pattern sPat
4790: 74 65 72 6e 47 72 6f 75 70 31 22 0a 20 20 20 20  ternGroup1".    
47a0: 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28 73 50  m = re.search(sP
47b0: 61 74 74 65 72 6e 2c 20 73 29 0a 20 20 20 20 69  attern, s).    i
47c0: 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20  f not m:.       
47d0: 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20   return False.  
47e0: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 73    try:.        s
47f0: 57 6f 72 64 20 3d 20 6d 2e 67 72 6f 75 70 28 31  Word = m.group(1
4800: 29 0a 20 20 20 20 20 20 20 20 6e 50 6f 73 20 3d  ).        nPos =
4810: 20 6d 2e 73 74 61 72 74 28 31 29 20 2b 20 6e 4f   m.start(1) + nO
4820: 66 66 73 65 74 0a 20 20 20 20 65 78 63 65 70 74  ffset.    except
4830: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
4840: 20 46 61 6c 73 65 0a 20 20 20 20 69 66 20 73 4e   False.    if sN
4850: 65 67 50 61 74 74 65 72 6e 47 72 6f 75 70 31 3a  egPatternGroup1:
4860: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
4870: 6d 6f 72 70 68 65 78 28 64 54 6f 6b 65 6e 50 6f  morphex(dTokenPo
4880: 73 2c 20 28 6e 50 6f 73 2c 20 73 57 6f 72 64 29  s, (nPos, sWord)
4890: 2c 20 73 50 61 74 74 65 72 6e 47 72 6f 75 70 31  , sPatternGroup1
48a0: 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 47 72 6f  , sNegPatternGro
48b0: 75 70 31 29 0a 20 20 20 20 72 65 74 75 72 6e 20  up1).    return 
48c0: 6d 6f 72 70 68 28 64 54 6f 6b 65 6e 50 6f 73 2c  morph(dTokenPos,
48d0: 20 28 6e 50 6f 73 2c 20 73 57 6f 72 64 29 2c 20   (nPos, sWord), 
48e0: 73 50 61 74 74 65 72 6e 47 72 6f 75 70 31 2c 20  sPatternGroup1, 
48f0: 46 61 6c 73 65 29 0a 0a 0a 23 23 23 23 20 44 69  False)...#### Di
4900: 73 61 6d 62 69 67 75 61 74 6f 72 0a 0a 64 65 66  sambiguator..def
4910: 20 73 65 6c 65 63 74 20 28 64 54 6f 6b 65 6e 50   select (dTokenP
4920: 6f 73 2c 20 6e 50 6f 73 2c 20 73 57 6f 72 64 2c  os, nPos, sWord,
4930: 20 73 50 61 74 74 65 72 6e 2c 20 6c 44 65 66 61   sPattern, lDefa
4940: 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 69  ult=None):.    i
4950: 66 20 6e 6f 74 20 73 57 6f 72 64 3a 0a 20 20 20  f not sWord:.   
4960: 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65       return True
4970: 0a 20 20 20 20 69 66 20 6e 50 6f 73 20 6e 6f 74  .    if nPos not
4980: 20 69 6e 20 64 54 6f 6b 65 6e 50 6f 73 3a 0a 20   in dTokenPos:. 
4990: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72         print("Er
49a0: 72 6f 72 2e 20 54 68 65 72 65 20 73 68 6f 75 6c  ror. There shoul
49b0: 64 20 62 65 20 61 20 74 6f 6b 65 6e 20 61 74 20  d be a token at 
49c0: 74 68 69 73 20 70 6f 73 69 74 69 6f 6e 3a 20 22  this position: "
49d0: 2c 20 6e 50 6f 73 29 0a 20 20 20 20 20 20 20 20  , nPos).        
49e0: 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20  return True.    
49f0: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
4a00: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
4a10: 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66 20 6e  (sWord).    if n
4a20: 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e  ot lMorph or len
4a30: 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20  (lMorph) == 1:. 
4a40: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
4a50: 75 65 0a 20 20 20 20 6c 53 65 6c 65 63 74 20 3d  ue.    lSelect =
4a60: 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72 20 73   [ sMorph  for s
4a70: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20  Morph in lMorph 
4a80: 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 73 50   if re.search(sP
4a90: 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20  attern, sMorph) 
4aa0: 5d 0a 20 20 20 20 69 66 20 6c 53 65 6c 65 63 74  ].    if lSelect
4ab0: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c 65 6e  :.        if len
4ac0: 28 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c 65 6e  (lSelect) != len
4ad0: 28 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20  (lMorph):.      
4ae0: 20 20 20 20 20 20 64 54 6f 6b 65 6e 50 6f 73 5b        dTokenPos[
4af0: 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68 22 5d 20  nPos]["lMorph"] 
4b00: 3d 20 6c 53 65 6c 65 63 74 0a 20 20 20 20 65 6c  = lSelect.    el
4b10: 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a 20 20 20  if lDefault:.   
4b20: 20 20 20 20 20 64 54 6f 6b 65 6e 50 6f 73 5b 6e       dTokenPos[n
4b30: 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d  Pos]["lMorph"] =
4b40: 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20 72 65   lDefault.    re
4b50: 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20  turn True...def 
4b60: 65 78 63 6c 75 64 65 20 28 64 54 6f 6b 65 6e 50  exclude (dTokenP
4b70: 6f 73 2c 20 6e 50 6f 73 2c 20 73 57 6f 72 64 2c  os, nPos, sWord,
4b80: 20 73 50 61 74 74 65 72 6e 2c 20 6c 44 65 66 61   sPattern, lDefa
4b90: 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 69  ult=None):.    i
4ba0: 66 20 6e 6f 74 20 73 57 6f 72 64 3a 0a 20 20 20  f not sWord:.   
4bb0: 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65       return True
4bc0: 0a 20 20 20 20 69 66 20 6e 50 6f 73 20 6e 6f 74  .    if nPos not
4bd0: 20 69 6e 20 64 54 6f 6b 65 6e 50 6f 73 3a 0a 20   in dTokenPos:. 
4be0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72         print("Er
4bf0: 72 6f 72 2e 20 54 68 65 72 65 20 73 68 6f 75 6c  ror. There shoul
4c00: 64 20 62 65 20 61 20 74 6f 6b 65 6e 20 61 74 20  d be a token at 
4c10: 74 68 69 73 20 70 6f 73 69 74 69 6f 6e 3a 20 22  this position: "
4c20: 2c 20 6e 50 6f 73 29 0a 20 20 20 20 20 20 20 20  , nPos).        
4c30: 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20  return True.    
4c40: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
4c50: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
4c60: 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66 20 6e  (sWord).    if n
4c70: 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e  ot lMorph or len
4c80: 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20  (lMorph) == 1:. 
4c90: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
4ca0: 75 65 0a 20 20 20 20 6c 53 65 6c 65 63 74 20 3d  ue.    lSelect =
4cb0: 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72 20 73   [ sMorph  for s
4cc0: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20  Morph in lMorph 
4cd0: 20 69 66 20 6e 6f 74 20 72 65 2e 73 65 61 72 63   if not re.searc
4ce0: 68 28 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72  h(sPattern, sMor
4cf0: 70 68 29 20 5d 0a 20 20 20 20 69 66 20 6c 53 65  ph) ].    if lSe
4d00: 6c 65 63 74 3a 0a 20 20 20 20 20 20 20 20 69 66  lect:.        if
4d10: 20 6c 65 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d   len(lSelect) !=
4d20: 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20   len(lMorph):.  
4d30: 20 20 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e            dToken
4d40: 50 6f 73 5b 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70  Pos[nPos]["lMorp
4d50: 68 22 5d 20 3d 20 6c 53 65 6c 65 63 74 0a 20 20  h"] = lSelect.  
4d60: 20 20 65 6c 69 66 20 6c 44 65 66 61 75 6c 74 3a    elif lDefault:
4d70: 0a 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 50  .        dTokenP
4d80: 6f 73 5b 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68  os[nPos]["lMorph
4d90: 22 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20  "] = lDefault.  
4da0: 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a    return True...
4db0: 64 65 66 20 64 65 66 69 6e 65 20 28 64 54 6f 6b  def define (dTok
4dc0: 65 6e 50 6f 73 2c 20 6e 50 6f 73 2c 20 6c 4d 6f  enPos, nPos, lMo
4dd0: 72 70 68 29 3a 0a 20 20 20 20 69 66 20 6e 50 6f  rph):.    if nPo
4de0: 73 20 6e 6f 74 20 69 6e 20 64 54 6f 6b 65 6e 50  s not in dTokenP
4df0: 6f 73 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e  os:.        prin
4e00: 74 28 22 45 72 72 6f 72 2e 20 54 68 65 72 65 20  t("Error. There 
4e10: 73 68 6f 75 6c 64 20 62 65 20 61 20 74 6f 6b 65  should be a toke
4e20: 6e 20 61 74 20 74 68 69 73 20 70 6f 73 69 74 69  n at this positi
4e30: 6f 6e 3a 20 22 2c 20 6e 50 6f 73 29 0a 20 20 20  on: ", nPos).   
4e40: 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65       return True
4e50: 0a 20 20 20 20 64 54 6f 6b 65 6e 50 6f 73 5b 6e  .    dTokenPos[n
4e60: 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d  Pos]["lMorph"] =
4e70: 20 6c 4d 6f 72 70 68 0a 20 20 20 20 72 65 74 75   lMorph.    retu
4e80: 72 6e 20 54 72 75 65 0a 0a 0a 23 23 23 23 20 47  rn True...#### G
4e90: 52 41 4d 4d 41 52 20 43 48 45 43 4b 45 52 20 50  RAMMAR CHECKER P
4ea0: 4c 55 47 49 4e 53 0a 0a 24 7b 70 6c 75 67 69 6e  LUGINS..${plugin
4eb0: 73 7d 0a 0a 0a 0a 23 23 23 23 20 54 4f 4b 45 4e  s}....#### TOKEN
4ec0: 20 53 45 4e 54 45 4e 43 45 20 43 48 45 43 4b 45   SENTENCE CHECKE
4ed0: 52 0a 0a 63 6c 61 73 73 20 54 6f 6b 65 6e 53 65  R..class TokenSe
4ee0: 6e 74 65 6e 63 65 3a 0a 0a 20 20 20 20 64 65 66  ntence:..    def
4ef0: 20 5f 5f 69 6e 69 74 5f 5f 20 28 73 65 6c 66 2c   __init__ (self,
4f00: 20 73 53 65 6e 74 65 6e 63 65 2c 20 73 53 65 6e   sSentence, sSen
4f10: 74 65 6e 63 65 30 2c 20 6e 4f 66 66 73 65 74 29  tence0, nOffset)
4f20: 3a 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 73  :.        self.s
4f30: 53 65 6e 74 65 6e 63 65 20 3d 20 73 53 65 6e 74  Sentence = sSent
4f40: 65 6e 63 65 0a 20 20 20 20 20 20 20 20 73 65 6c  ence.        sel
4f50: 66 2e 73 53 65 6e 74 65 6e 63 65 30 20 3d 20 73  f.sSentence0 = s
4f60: 53 65 6e 74 65 6e 63 65 30 0a 20 20 20 20 20 20  Sentence0.      
4f70: 20 20 73 65 6c 66 2e 6e 4f 66 66 73 65 74 20 3d    self.nOffset =
4f80: 20 6e 4f 66 66 73 65 74 0a 20 20 20 20 20 20 20   nOffset.       
4f90: 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 20 3d 20 6c   self.lToken = l
4fa0: 69 73 74 28 5f 6f 54 6f 6b 65 6e 69 7a 65 72 2e  ist(_oTokenizer.
4fb0: 67 65 6e 54 6f 6b 65 6e 73 28 73 53 65 6e 74 65  genTokens(sSente
4fc0: 6e 63 65 2c 20 54 72 75 65 29 29 0a 20 20 20 20  nce, True)).    
4fd0: 20 20 20 20 73 65 6c 66 2e 64 54 6f 6b 65 6e 50      self.dTokenP
4fe0: 6f 73 20 3d 20 7b 20 64 54 6f 6b 65 6e 5b 22 6e  os = { dToken["n
4ff0: 53 74 61 72 74 22 5d 3a 20 64 54 6f 6b 65 6e 20  Start"]: dToken 
5000: 20 66 6f 72 20 64 54 6f 6b 65 6e 20 69 6e 20 73   for dToken in s
5010: 65 6c 66 2e 6c 54 6f 6b 65 6e 20 7d 0a 20 20 20  elf.lToken }.   
5020: 20 20 20 20 20 73 65 6c 66 2e 63 72 65 61 74 65       self.create
5030: 45 72 72 6f 72 20 3d 20 73 65 6c 66 2e 5f 63 72  Error = self._cr
5040: 65 61 74 65 57 72 69 74 65 72 45 72 72 6f 72 20  eateWriterError 
5050: 20 69 66 20 5f 62 57 72 69 74 65 72 45 72 72 6f   if _bWriterErro
5060: 72 20 20 65 6c 73 65 20 73 65 6c 66 2e 5f 63 72  r  else self._cr
5070: 65 61 74 65 44 69 63 74 45 72 72 6f 72 0a 0a 20  eateDictError.. 
5080: 20 20 20 64 65 66 20 75 70 64 61 74 65 20 28 73     def update (s
5090: 65 6c 66 2c 20 73 53 65 6e 74 65 6e 63 65 29 3a  elf, sSentence):
50a0: 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 73 53  .        self.sS
50b0: 65 6e 74 65 6e 63 65 20 3d 20 73 53 65 6e 74 65  entence = sSente
50c0: 6e 63 65 0a 20 20 20 20 20 20 20 20 73 65 6c 66  nce.        self
50d0: 2e 6c 54 6f 6b 65 6e 20 3d 20 6c 69 73 74 28 5f  .lToken = list(_
50e0: 6f 54 6f 6b 65 6e 69 7a 65 72 2e 67 65 6e 54 6f  oTokenizer.genTo
50f0: 6b 65 6e 73 28 73 53 65 6e 74 65 6e 63 65 2c 20  kens(sSentence, 
5100: 54 72 75 65 29 29 0a 0a 20 20 20 20 64 65 66 20  True))..    def 
5110: 5f 67 65 74 4e 65 78 74 4d 61 74 63 68 69 6e 67  _getNextMatching
5120: 4e 6f 64 65 73 20 28 73 65 6c 66 2c 20 64 54 6f  Nodes (self, dTo
5130: 6b 65 6e 2c 20 64 47 72 61 70 68 2c 20 64 4e 6f  ken, dGraph, dNo
5140: 64 65 2c 20 62 44 65 62 75 67 3d 46 61 6c 73 65  de, bDebug=False
5150: 29 3a 0a 20 20 20 20 20 20 20 20 22 67 65 6e 65  ):.        "gene
5160: 72 61 74 6f 72 3a 20 72 65 74 75 72 6e 20 6e 6f  rator: return no
5170: 64 65 73 20 77 68 65 72 65 20 3c 64 54 6f 6b 65  des where <dToke
5180: 6e 3e 20 e2 80 9c 76 61 6c 75 65 73 e2 80 9d 20  n> ...values... 
5190: 6d 61 74 63 68 20 3c 64 4e 6f 64 65 3e 20 61 72  match <dNode> ar
51a0: 63 73 22 0a 20 20 20 20 20 20 20 20 23 20 74 6f  cs".        # to
51b0: 6b 65 6e 20 76 61 6c 75 65 0a 20 20 20 20 20 20  ken value.      
51c0: 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73 56 61    if dToken["sVa
51d0: 6c 75 65 22 5d 20 69 6e 20 64 4e 6f 64 65 3a 0a  lue"] in dNode:.
51e0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
51f0: 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20  Debug:.         
5200: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 4d 41         print("MA
5210: 54 43 48 3a 22 2c 20 64 54 6f 6b 65 6e 5b 22 73  TCH:", dToken["s
5220: 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20  Value"]).       
5230: 20 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70       yield dGrap
5240: 68 5b 64 4e 6f 64 65 5b 64 54 6f 6b 65 6e 5b 22  h[dNode[dToken["
5250: 73 56 61 6c 75 65 22 5d 5d 5d 0a 20 20 20 20 20  sValue"]]].     
5260: 20 20 20 23 20 74 6f 6b 65 6e 20 6c 65 6d 6d 61     # token lemma
5270: 73 0a 20 20 20 20 20 20 20 20 69 66 20 22 3c 6c  s.        if "<l
5280: 65 6d 6d 61 73 3e 22 20 69 6e 20 64 4e 6f 64 65  emmas>" in dNode
5290: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  :.            fo
52a0: 72 20 73 4c 65 6d 6d 61 20 69 6e 20 5f 6f 53 70  r sLemma in _oSp
52b0: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65  ellChecker.getLe
52c0: 6d 6d 61 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c  mma(dToken["sVal
52d0: 75 65 22 5d 29 3a 0a 20 20 20 20 20 20 20 20 20  ue"]):.         
52e0: 20 20 20 20 20 20 20 69 66 20 73 4c 65 6d 6d 61         if sLemma
52f0: 20 69 6e 20 64 4e 6f 64 65 5b 22 3c 6c 65 6d 6d   in dNode["<lemm
5300: 61 73 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20  as>"]:.         
5310: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 44             if bD
5320: 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20  ebug:.          
5330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
5340: 69 6e 74 28 22 4d 41 54 43 48 3a 20 3e 22 20 2b  int("MATCH: >" +
5350: 20 73 4c 65 6d 6d 61 29 0a 20 20 20 20 20 20 20   sLemma).       
5360: 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65               yie
5370: 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b  ld dGraph[dNode[
5380: 22 3c 6c 65 6d 6d 61 73 3e 22 5d 5b 73 4c 65 6d  "<lemmas>"][sLem
5390: 6d 61 5d 5d 0a 20 20 20 20 20 20 20 20 23 20 75  ma]].        # u
53a0: 6e 69 76 65 72 73 61 6c 20 61 72 63 0a 20 20 20  niversal arc.   
53b0: 20 20 20 20 20 69 66 20 22 2a 22 20 69 6e 20 64       if "*" in d
53c0: 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20 20  Node:.          
53d0: 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20    if bDebug:.   
53e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
53f0: 6e 74 28 22 4d 41 54 43 48 3a 20 2a 22 29 0a 20  nt("MATCH: *"). 
5400: 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64             yield
5410: 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 2a   dGraph[dNode["*
5420: 22 5d 5d 0a 20 20 20 20 20 20 20 20 23 20 72 65  "]].        # re
5430: 67 65 78 20 76 61 6c 75 65 20 61 72 63 73 0a 20  gex value arcs. 
5440: 20 20 20 20 20 20 20 69 66 20 22 3c 72 65 5f 76         if "<re_v
5450: 61 6c 75 65 3e 22 20 69 6e 20 64 4e 6f 64 65 3a  alue>" in dNode:
5460: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
5470: 20 73 52 65 67 65 78 20 69 6e 20 64 4e 6f 64 65   sRegex in dNode
5480: 5b 22 3c 72 65 5f 76 61 6c 75 65 3e 22 5d 3a 0a  ["<re_value>"]:.
5490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54a0: 69 66 20 72 65 2e 73 65 61 72 63 68 28 73 52 65  if re.search(sRe
54b0: 67 65 78 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61  gex, dToken["sVa
54c0: 6c 75 65 22 5d 29 3a 0a 20 20 20 20 20 20 20 20  lue"]):.        
54d0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
54e0: 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20  Debug:.         
54f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
5500: 72 69 6e 74 28 22 4d 41 54 43 48 3a 20 7e 22 20  rint("MATCH: ~" 
5510: 2b 20 73 52 65 67 65 78 29 0a 20 20 20 20 20 20  + sRegex).      
5520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69                yi
5530: 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65  eld dGraph[dNode
5540: 5b 22 3c 72 65 5f 76 61 6c 75 65 3e 22 5d 5b 73  ["<re_value>"][s
5550: 52 65 67 65 78 5d 5d 0a 20 20 20 20 20 20 20 20  Regex]].        
5560: 23 20 72 65 67 65 78 20 6d 6f 72 70 68 20 61 72  # regex morph ar
5570: 63 73 0a 20 20 20 20 20 20 20 20 69 66 20 22 3c  cs.        if "<
5580: 72 65 5f 6d 6f 72 70 68 3e 22 20 69 6e 20 64 4e  re_morph>" in dN
5590: 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ode:.           
55a0: 20 66 6f 72 20 73 52 65 67 65 78 20 69 6e 20 64   for sRegex in d
55b0: 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70 68 3e  Node["<re_morph>
55c0: 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "]:.            
55d0: 20 20 20 20 69 66 20 22 c2 ac 22 20 6e 6f 74 20      if ".." not 
55e0: 69 6e 20 73 52 65 67 65 78 3a 0a 20 20 20 20 20  in sRegex:.     
55f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
5600: 20 6e 6f 20 61 6e 74 69 2d 70 61 74 74 65 72 6e   no anti-pattern
5610: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5620: 20 20 20 20 20 69 66 20 61 6e 79 28 72 65 2e 73       if any(re.s
5630: 65 61 72 63 68 28 73 52 65 67 65 78 2c 20 73 4d  earch(sRegex, sM
5640: 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70  orph)  for sMorp
5650: 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  h in _oSpellChec
5660: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f  ker.getMorph(dTo
5670: 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 29 3a  ken["sValue"])):
5680: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5690: 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62           if bDeb
56a0: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
56b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56c0: 70 72 69 6e 74 28 22 4d 41 54 43 48 3a 20 40 22  print("MATCH: @"
56d0: 20 2b 20 73 52 65 67 65 78 29 0a 20 20 20 20 20   + sRegex).     
56e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56f0: 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b     yield dGraph[
5700: 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70 68  dNode["<re_morph
5710: 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 20 20 20  >"][sRegex]].   
5720: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73               els
5730: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
5740: 20 20 20 20 20 20 20 23 20 74 68 65 72 65 20 69         # there i
5750: 73 20 61 6e 20 61 6e 74 69 2d 70 61 74 74 65 72  s an anti-patter
5760: 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n.              
5770: 20 20 20 20 20 20 73 50 61 74 74 65 72 6e 2c 20        sPattern, 
5780: 73 4e 65 67 50 61 74 74 65 72 6e 20 3d 20 73 52  sNegPattern = sR
5790: 65 67 65 78 2e 73 70 6c 69 74 28 22 c2 ac 22 2c  egex.split("..",
57a0: 20 31 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   1).            
57b0: 20 20 20 20 20 20 20 20 69 66 20 73 4e 65 67 50          if sNegP
57c0: 61 74 74 65 72 6e 20 3d 3d 20 22 2a 22 3a 0a 20  attern == "*":. 
57d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57e0: 20 20 20 20 20 20 20 23 20 61 6c 6c 20 6d 6f 72         # all mor
57f0: 70 68 6f 6c 6f 67 69 65 73 20 6d 75 73 74 20 6d  phologies must m
5800: 61 74 63 68 20 77 69 74 68 20 3c 73 50 61 74 74  atch with <sPatt
5810: 65 72 6e 3e 0a 20 20 20 20 20 20 20 20 20 20 20  ern>.           
5820: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
5830: 61 6c 6c 28 72 65 2e 73 65 61 72 63 68 28 73 50  all(re.search(sP
5840: 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20  attern, sMorph) 
5850: 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f   for sMorph in _
5860: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
5870: 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73  tMorph(dToken["s
5880: 56 61 6c 75 65 22 5d 29 29 3a 0a 20 20 20 20 20  Value"])):.     
5890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58a0: 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67         if bDebug
58b0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
58c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58d0: 20 20 70 72 69 6e 74 28 22 4d 41 54 43 48 3a 20    print("MATCH: 
58e0: 40 22 20 2b 20 73 52 65 67 65 78 29 0a 20 20 20  @" + sRegex).   
58f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5900: 20 20 20 20 20 20 20 20 20 79 69 65 6c 64 20 64           yield d
5910: 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c 72 65  Graph[dNode["<re
5920: 5f 6d 6f 72 70 68 3e 22 5d 5b 73 52 65 67 65 78  _morph>"][sRegex
5930: 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]].             
5940: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
5950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5960: 20 20 20 20 20 69 66 20 73 4e 65 67 50 61 74 74       if sNegPatt
5970: 65 72 6e 20 61 6e 64 20 61 6e 79 28 72 65 2e 73  ern and any(re.s
5980: 65 61 72 63 68 28 73 4e 65 67 50 61 74 74 65 72  earch(sNegPatter
5990: 6e 2c 20 73 4d 6f 72 70 68 29 20 20 66 6f 72 20  n, sMorph)  for 
59a0: 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c  sMorph in _oSpel
59b0: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70  lChecker.getMorp
59c0: 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65  h(dToken["sValue
59d0: 22 5d 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20  "])):.          
59e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59f0: 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20    continue.     
5a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a10: 20 20 20 69 66 20 61 6e 79 28 72 65 2e 73 65 61     if any(re.sea
5a20: 72 63 68 28 73 50 61 74 74 65 72 6e 2c 20 73 4d  rch(sPattern, sM
5a30: 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70  orph)  for sMorp
5a40: 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  h in _oSpellChec
5a50: 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f  ker.getMorph(dTo
5a60: 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 29 3a  ken["sValue"])):
5a70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
5a90: 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20  bDebug:.        
5aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ab0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 4d          print("M
5ac0: 41 54 43 48 3a 20 40 22 20 2b 20 73 52 65 67 65  ATCH: @" + sRege
5ad0: 78 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  x).             
5ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 79                 y
5af0: 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64  ield dGraph[dNod
5b00: 65 5b 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 5d 5b  e["<re_morph>"][
5b10: 73 52 65 67 65 78 5d 5d 0a 0a 20 20 20 20 64 65  sRegex]]..    de
5b20: 66 20 70 61 72 73 65 20 28 73 65 6c 66 2c 20 64  f parse (self, d
5b30: 47 72 61 70 68 2c 20 64 50 72 69 6f 72 69 74 79  Graph, dPriority
5b40: 2c 20 73 43 6f 75 6e 74 72 79 3d 22 24 7b 63 6f  , sCountry="${co
5b50: 75 6e 74 72 79 5f 64 65 66 61 75 6c 74 7d 22 2c  untry_default}",
5b60: 20 64 4f 70 74 69 6f 6e 73 3d 4e 6f 6e 65 2c 20   dOptions=None, 
5b70: 62 53 68 6f 77 52 75 6c 65 49 64 3d 46 61 6c 73  bShowRuleId=Fals
5b80: 65 2c 20 62 44 65 62 75 67 3d 46 61 6c 73 65 2c  e, bDebug=False,
5b90: 20 62 43 6f 6e 74 65 78 74 3d 46 61 6c 73 65 29   bContext=False)
5ba0: 3a 0a 20 20 20 20 20 20 20 20 64 45 72 72 20 3d  :.        dErr =
5bb0: 20 7b 7d 0a 20 20 20 20 20 20 20 20 64 50 72 69   {}.        dPri
5bc0: 6f 72 69 74 79 20 3d 20 7b 7d 20 20 23 20 4b 65  ority = {}  # Ke
5bd0: 79 20 3d 20 70 6f 73 69 74 69 6f 6e 3b 20 76 61  y = position; va
5be0: 6c 75 65 20 3d 20 70 72 69 6f 72 69 74 79 0a 20  lue = priority. 
5bf0: 20 20 20 20 20 20 20 64 4f 70 74 20 3d 20 5f 64         dOpt = _d
5c00: 4f 70 74 69 6f 6e 73 20 20 69 66 20 6e 6f 74 20  Options  if not 
5c10: 64 4f 70 74 69 6f 6e 73 20 20 65 6c 73 65 20 64  dOptions  else d
5c20: 4f 70 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20  Options.        
5c30: 6c 50 6f 69 6e 74 65 72 20 3d 20 5b 5d 0a 20 20  lPointer = [].  
5c40: 20 20 20 20 20 20 62 43 68 61 6e 67 65 20 3d 20        bChange = 
5c50: 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 66 6f  False.        fo
5c60: 72 20 64 54 6f 6b 65 6e 20 69 6e 20 73 65 6c 66  r dToken in self
5c70: 2e 6c 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20  .lToken:.       
5c80: 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a       if bDebug:.
5c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ca0: 70 72 69 6e 74 28 22 54 4f 4b 45 4e 3a 22 2c 20  print("TOKEN:", 
5cb0: 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d  dToken["sValue"]
5cc0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  ).            # 
5cd0: 63 68 65 63 6b 20 61 72 63 73 20 66 6f 72 20 65  check arcs for e
5ce0: 61 63 68 20 65 78 69 73 74 69 6e 67 20 70 6f 69  ach existing poi
5cf0: 6e 74 65 72 0a 20 20 20 20 20 20 20 20 20 20 20  nter.           
5d00: 20 6c 4e 65 78 74 50 6f 69 6e 74 65 72 20 3d 20   lNextPointer = 
5d10: 5b 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  [].            f
5d20: 6f 72 20 64 50 6f 69 6e 74 65 72 20 69 6e 20 6c  or dPointer in l
5d30: 50 6f 69 6e 74 65 72 3a 0a 20 20 20 20 20 20 20  Pointer:.       
5d40: 20 20 20 20 20 20 20 20 20 66 6f 72 20 64 4e 6f           for dNo
5d50: 64 65 20 69 6e 20 73 65 6c 66 2e 5f 67 65 74 4e  de in self._getN
5d60: 65 78 74 4d 61 74 63 68 69 6e 67 4e 6f 64 65 73  extMatchingNodes
5d70: 28 64 54 6f 6b 65 6e 2c 20 64 47 72 61 70 68 2c  (dToken, dGraph,
5d80: 20 64 50 6f 69 6e 74 65 72 5b 22 64 4e 6f 64 65   dPointer["dNode
5d90: 22 5d 2c 20 62 44 65 62 75 67 29 3a 0a 20 20 20  "], bDebug):.   
5da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5db0: 20 6c 4e 65 78 74 50 6f 69 6e 74 65 72 2e 61 70   lNextPointer.ap
5dc0: 70 65 6e 64 28 7b 22 69 54 6f 6b 65 6e 22 3a 20  pend({"iToken": 
5dd0: 64 50 6f 69 6e 74 65 72 5b 22 69 54 6f 6b 65 6e  dPointer["iToken
5de0: 22 5d 2c 20 22 64 4e 6f 64 65 22 3a 20 64 4e 6f  "], "dNode": dNo
5df0: 64 65 7d 29 0a 20 20 20 20 20 20 20 20 20 20 20  de}).           
5e00: 20 6c 50 6f 69 6e 74 65 72 20 3d 20 6c 4e 65 78   lPointer = lNex
5e10: 74 50 6f 69 6e 74 65 72 0a 20 20 20 20 20 20 20  tPointer.       
5e20: 20 20 20 20 20 23 20 63 68 65 63 6b 20 61 72 63       # check arc
5e30: 73 20 6f 66 20 66 69 72 73 74 20 6e 6f 64 65 73  s of first nodes
5e40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
5e50: 20 64 4e 6f 64 65 20 69 6e 20 73 65 6c 66 2e 5f   dNode in self._
5e60: 67 65 74 4e 65 78 74 4d 61 74 63 68 69 6e 67 4e  getNextMatchingN
5e70: 6f 64 65 73 28 64 54 6f 6b 65 6e 2c 20 64 47 72  odes(dToken, dGr
5e80: 61 70 68 2c 20 64 47 72 61 70 68 5b 30 5d 2c 20  aph, dGraph[0], 
5e90: 62 44 65 62 75 67 29 3a 0a 20 20 20 20 20 20 20  bDebug):.       
5ea0: 20 20 20 20 20 20 20 20 20 6c 50 6f 69 6e 74 65           lPointe
5eb0: 72 2e 61 70 70 65 6e 64 28 7b 22 69 54 6f 6b 65  r.append({"iToke
5ec0: 6e 22 3a 20 64 54 6f 6b 65 6e 5b 22 69 22 5d 2c  n": dToken["i"],
5ed0: 20 22 64 4e 6f 64 65 22 3a 20 64 4e 6f 64 65 7d   "dNode": dNode}
5ee0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  ).            # 
5ef0: 63 68 65 63 6b 20 69 66 20 74 68 65 72 65 20 69  check if there i
5f00: 73 20 72 75 6c 65 73 20 74 6f 20 63 68 65 63 6b  s rules to check
5f10: 20 66 6f 72 20 65 61 63 68 20 70 6f 69 6e 74 65   for each pointe
5f20: 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  r.            fo
5f30: 72 20 64 50 6f 69 6e 74 65 72 20 69 6e 20 6c 50  r dPointer in lP
5f40: 6f 69 6e 74 65 72 3a 0a 20 20 20 20 20 20 20 20  ointer:.        
5f50: 20 20 20 20 20 20 20 20 23 69 66 20 62 44 65 62          #if bDeb
5f60: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
5f70: 20 20 20 20 23 20 20 20 20 70 72 69 6e 74 28 22      #    print("
5f80: 2b 22 2c 20 64 50 6f 69 6e 74 65 72 29 0a 20 20  +", dPointer).  
5f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
5fa0: 20 22 3c 72 75 6c 65 73 3e 22 20 69 6e 20 64 50   "<rules>" in dP
5fb0: 6f 69 6e 74 65 72 5b 22 64 4e 6f 64 65 22 5d 3a  ointer["dNode"]:
5fc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5fd0: 20 20 20 20 20 62 48 61 73 43 68 61 6e 67 65 64       bHasChanged
5fe0: 2c 20 65 72 72 73 20 3d 20 73 65 6c 66 2e 5f 65  , errs = self._e
5ff0: 78 65 63 75 74 65 41 63 74 69 6f 6e 73 28 64 47  xecuteActions(dG
6000: 72 61 70 68 2c 20 64 50 6f 69 6e 74 65 72 5b 22  raph, dPointer["
6010: 64 4e 6f 64 65 22 5d 5b 22 3c 72 75 6c 65 73 3e  dNode"]["<rules>
6020: 22 5d 2c 20 64 50 6f 69 6e 74 65 72 5b 22 69 54  "], dPointer["iT
6030: 6f 6b 65 6e 22 5d 2d 31 2c 20 64 50 72 69 6f 72  oken"]-1, dPrior
6040: 69 74 79 2c 20 64 4f 70 74 2c 20 73 43 6f 75 6e  ity, dOpt, sCoun
6050: 74 72 79 2c 20 62 53 68 6f 77 52 75 6c 65 49 64  try, bShowRuleId
6060: 2c 20 62 44 65 62 75 67 2c 20 62 43 6f 6e 74 65  , bDebug, bConte
6070: 78 74 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  xt).            
6080: 20 20 20 20 20 20 20 20 64 45 72 72 2e 75 70 64          dErr.upd
6090: 61 74 65 28 65 72 72 73 29 0a 20 20 20 20 20 20  ate(errs).      
60a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
60b0: 20 62 48 61 73 43 68 61 6e 67 65 64 3a 0a 20 20   bHasChanged:.  
60c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60d0: 20 20 20 20 20 20 62 43 68 61 6e 67 65 20 3d 20        bChange = 
60e0: 54 72 75 65 0a 20 20 20 20 20 20 20 20 72 65 74  True.        ret
60f0: 75 72 6e 20 28 62 43 68 61 6e 67 65 2c 20 64 45  urn (bChange, dE
6100: 72 72 29 0a 0a 20 20 20 20 64 65 66 20 5f 65 78  rr)..    def _ex
6110: 65 63 75 74 65 41 63 74 69 6f 6e 73 20 28 73 65  ecuteActions (se
6120: 6c 66 2c 20 64 47 72 61 70 68 2c 20 64 4e 6f 64  lf, dGraph, dNod
6130: 65 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2c  e, nTokenOffset,
6140: 20 64 50 72 69 6f 72 69 74 79 2c 20 64 4f 70 74   dPriority, dOpt
6150: 69 6f 6e 73 2c 20 73 43 6f 75 6e 74 72 79 2c 20  ions, sCountry, 
6160: 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 44 65  bShowRuleId, bDe
6170: 62 75 67 2c 20 62 43 6f 6e 74 65 78 74 29 3a 0a  bug, bContext):.
6180: 20 20 20 20 20 20 20 20 22 65 78 65 63 75 74 65          "execute
6190: 20 61 63 74 69 6f 6e 73 20 66 6f 75 6e 64 20 69   actions found i
61a0: 6e 20 74 68 65 20 44 41 52 47 22 0a 20 20 20 20  n the DARG".    
61b0: 20 20 20 20 64 45 72 72 73 20 3d 20 7b 7d 0a 20      dErrs = {}. 
61c0: 20 20 20 20 20 20 20 62 43 68 61 6e 67 65 20 3d         bChange =
61d0: 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 66   False.        f
61e0: 6f 72 20 73 4c 69 6e 65 49 64 2c 20 6e 65 78 74  or sLineId, next
61f0: 4e 6f 64 65 4b 65 79 20 69 6e 20 64 4e 6f 64 65  NodeKey in dNode
6200: 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20 20 20 20  .items():.      
6210: 20 20 20 20 20 20 66 6f 72 20 73 52 75 6c 65 49        for sRuleI
6220: 64 20 69 6e 20 64 47 72 61 70 68 5b 6e 65 78 74  d in dGraph[next
6230: 4e 6f 64 65 4b 65 79 5d 3a 0a 20 20 20 20 20 20  NodeKey]:.      
6240: 20 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20            try:. 
6250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6260: 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20     if bDebug:.  
6270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6280: 20 20 20 20 20 20 70 72 69 6e 74 28 22 41 43 54        print("ACT
6290: 49 4f 4e 3a 22 2c 20 73 52 75 6c 65 49 64 29 0a  ION:", sRuleId).
62a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
62b0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 64 52          print(dR
62c0: 75 6c 65 5b 73 52 75 6c 65 49 64 5d 29 0a 20 20  ule[sRuleId]).  
62d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
62e0: 20 20 62 43 6f 6e 64 4d 65 6d 6f 20 3d 20 4e 6f    bCondMemo = No
62f0: 6e 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ne.             
6300: 20 20 20 20 20 20 20 73 4f 70 74 69 6f 6e 2c 20         sOption, 
6310: 73 46 75 6e 63 43 6f 6e 64 2c 20 63 41 63 74 69  sFuncCond, cActi
6320: 6f 6e 54 79 70 65 2c 20 73 57 68 61 74 2c 20 2a  onType, sWhat, *
6330: 65 41 63 74 20 3d 20 64 52 75 6c 65 5b 73 52 75  eAct = dRule[sRu
6340: 6c 65 49 64 5d 0a 20 20 20 20 20 20 20 20 20 20  leId].          
6350: 20 20 20 20 20 20 20 20 20 20 23 20 61 63 74 69            # acti
6360: 6f 6e 20 69 6e 20 6c 41 63 74 69 6f 6e 73 3a 20  on in lActions: 
6370: 5b 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 61 63 74  [ condition, act
6380: 69 6f 6e 20 74 79 70 65 2c 20 72 65 70 6c 61 63  ion type, replac
6390: 65 6d 65 6e 74 2f 73 75 67 67 65 73 74 69 6f 6e  ement/suggestion
63a0: 2f 61 63 74 69 6f 6e 5b 2c 20 69 54 6f 6b 65 6e  /action[, iToken
63b0: 53 74 61 72 74 2c 20 69 54 6f 6b 65 6e 45 6e 64  Start, iTokenEnd
63c0: 5b 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 6d 65  [, nPriority, me
63d0: 73 73 61 67 65 2c 20 55 52 4c 5d 5d 20 5d 0a 20  ssage, URL]] ]. 
63e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63f0: 20 20 20 69 66 20 6e 6f 74 20 73 4f 70 74 69 6f     if not sOptio
6400: 6e 20 6f 72 20 64 4f 70 74 69 6f 6e 73 2e 67 65  n or dOptions.ge
6410: 74 28 73 4f 70 74 69 6f 6e 2c 20 46 61 6c 73 65  t(sOption, False
6420: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
6430: 20 20 20 20 20 20 20 20 20 20 20 62 43 6f 6e 64             bCond
6440: 4d 65 6d 6f 20 3d 20 6e 6f 74 20 73 46 75 6e 63  Memo = not sFunc
6450: 43 6f 6e 64 20 6f 72 20 67 6c 6f 62 61 6c 73 28  Cond or globals(
6460: 29 5b 73 46 75 6e 63 43 6f 6e 64 5d 28 73 65 6c  )[sFuncCond](sel
6470: 66 2e 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e  f.lToken, nToken
6480: 4f 66 66 73 65 74 2c 20 73 43 6f 75 6e 74 72 79  Offset, sCountry
6490: 2c 20 62 43 6f 6e 64 4d 65 6d 6f 29 0a 20 20 20  , bCondMemo).   
64a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
64b0: 20 20 20 20 20 69 66 20 62 43 6f 6e 64 4d 65 6d       if bCondMem
64c0: 6f 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  o:.             
64d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
64e0: 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d  f cActionType ==
64f0: 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "-":.          
6500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6510: 20 20 20 20 20 20 23 20 67 72 61 6d 6d 61 72 20        # grammar 
6520: 65 72 72 6f 72 0a 20 20 20 20 20 20 20 20 20 20  error.          
6530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6540: 20 20 20 20 20 20 6e 54 6f 6b 65 6e 45 72 72 6f        nTokenErro
6550: 72 53 74 61 72 74 20 3d 20 6e 54 6f 6b 65 6e 4f  rStart = nTokenO
6560: 66 66 73 65 74 20 2b 20 65 41 63 74 5b 30 5d 0a  ffset + eAct[0].
6570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6590: 6e 54 6f 6b 65 6e 45 72 72 6f 72 45 6e 64 20 3d  nTokenErrorEnd =
65a0: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20   nTokenOffset + 
65b0: 65 41 63 74 5b 31 5d 0a 20 20 20 20 20 20 20 20  eAct[1].        
65c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65d0: 20 20 20 20 20 20 20 20 6e 45 72 72 6f 72 53 74          nErrorSt
65e0: 61 72 74 20 3d 20 73 65 6c 66 2e 6e 4f 66 66 73  art = self.nOffs
65f0: 65 74 20 2b 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e  et + self.lToken
6600: 5b 6e 54 6f 6b 65 6e 45 72 72 6f 72 53 74 61 72  [nTokenErrorStar
6610: 74 5d 5b 22 6e 53 74 61 72 74 22 5d 0a 20 20 20  t]["nStart"].   
6620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6630: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 45 72               nEr
6640: 72 6f 72 45 6e 64 20 3d 20 73 65 6c 66 2e 6e 4f  rorEnd = self.nO
6650: 66 66 73 65 74 20 2b 20 73 65 6c 66 2e 6c 54 6f  ffset + self.lTo
6660: 6b 65 6e 5b 6e 54 6f 6b 65 6e 45 72 72 6f 72 45  ken[nTokenErrorE
6670: 6e 64 5d 5b 22 6e 45 6e 64 22 5d 0a 20 20 20 20  nd]["nEnd"].    
6680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6690: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e              if n
66a0: 45 72 72 6f 72 53 74 61 72 74 20 6e 6f 74 20 69  ErrorStart not i
66b0: 6e 20 64 45 72 72 73 20 6f 72 20 65 41 63 74 5b  n dErrs or eAct[
66c0: 32 5d 20 3e 20 64 50 72 69 6f 72 69 74 79 5b 6e  2] > dPriority[n
66d0: 45 72 72 6f 72 53 74 61 72 74 5d 3a 0a 20 20 20  ErrorStart]:.   
66e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6700: 20 64 45 72 72 73 5b 6e 45 72 72 6f 72 53 74 61   dErrs[nErrorSta
6710: 72 74 5d 20 3d 20 73 65 6c 66 2e 63 72 65 61 74  rt] = self.creat
6720: 65 45 72 72 6f 72 28 73 57 68 61 74 2c 20 6e 54  eError(sWhat, nT
6730: 6f 6b 65 6e 4f 66 66 73 65 74 2c 20 6e 54 6f 6b  okenOffset, nTok
6740: 65 6e 45 72 72 6f 72 53 74 61 72 74 2c 20 6e 45  enErrorStart, nE
6750: 72 72 6f 72 53 74 61 72 74 2c 20 6e 45 72 72 6f  rrorStart, nErro
6760: 72 45 6e 64 2c 20 73 4c 69 6e 65 49 64 2c 20 73  rEnd, sLineId, s
6770: 52 75 6c 65 49 64 2c 20 54 72 75 65 2c 20 65 41  RuleId, True, eA
6780: 63 74 5b 33 5d 2c 20 65 41 63 74 5b 34 5d 2c 20  ct[3], eAct[4], 
6790: 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 22 6e 6f  bShowRuleId, "no
67a0: 74 79 70 65 22 2c 20 62 43 6f 6e 74 65 78 74 29  type", bContext)
67b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
67c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
67d0: 20 20 20 20 20 64 50 72 69 6f 72 69 74 79 5b 6e       dPriority[n
67e0: 45 72 72 6f 72 53 74 61 72 74 5d 20 3d 20 65 41  ErrorStart] = eA
67f0: 63 74 5b 32 5d 0a 20 20 20 20 20 20 20 20 20 20  ct[2].          
6800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6810: 20 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65            if bDe
6820: 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20  bug:.           
6830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6840: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
6850: 6e 74 28 22 2d 22 2c 20 73 52 75 6c 65 49 64 2c  nt("-", sRuleId,
6860: 20 64 45 72 72 73 5b 6e 45 72 72 6f 72 53 74 61   dErrs[nErrorSta
6870: 72 74 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20  rt]).           
6880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6890: 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54 79 70   elif cActionTyp
68a0: 65 20 3d 3d 20 22 7e 22 3a 0a 20 20 20 20 20 20  e == "~":.      
68b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
68c0: 20 20 20 20 20 20 20 20 20 20 23 20 74 65 78 74            # text
68d0: 20 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20 20   processor.     
68e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
68f0: 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e             self.
6900: 5f 74 61 67 41 6e 64 50 72 65 70 61 72 65 54 6f  _tagAndPrepareTo
6910: 6b 65 6e 46 6f 72 52 65 77 72 69 74 69 6e 67 28  kenForRewriting(
6920: 73 57 68 61 74 2c 20 6e 54 6f 6b 65 6e 4f 66 66  sWhat, nTokenOff
6930: 73 65 74 20 2b 20 65 41 63 74 5b 30 5d 2c 20 6e  set + eAct[0], n
6940: 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65 41  TokenOffset + eA
6950: 63 74 5b 31 5d 29 0a 20 20 20 20 20 20 20 20 20  ct[1]).         
6960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6970: 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67         if bDebug
6980: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
6990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69a0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 7e 22 2c        print("~",
69b0: 20 73 52 75 6c 65 49 64 29 0a 20 20 20 20 20 20   sRuleId).      
69c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69d0: 20 20 20 20 20 20 20 20 20 20 62 43 68 61 6e 67            bChang
69e0: 65 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20  e = True.       
69f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a00: 20 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f       elif cActio
6a10: 6e 54 79 70 65 20 3d 3d 20 22 3d 22 3a 0a 20 20  nType == "=":.  
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 20 20 20 23 20                # 
6a40: 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 0a 20  disambiguation. 
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 20 20 20 20 20 20 20 67                 g
6a70: 6c 6f 62 61 6c 73 28 29 5b 73 57 68 61 74 5d 28  lobals()[sWhat](
6a80: 73 65 6c 66 2e 6c 54 6f 6b 65 6e 2c 20 6e 54 6f  self.lToken, nTo
6a90: 6b 65 6e 4f 66 66 73 65 74 29 0a 20 20 20 20 20  kenOffset).     
6aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ab0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 44             if bD
6ac0: 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20  ebug:.          
6ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ae0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
6af0: 22 3d 22 2c 20 73 52 75 6c 65 49 64 29 0a 20 20  "=", sRuleId).  
6b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b10: 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63            elif c
6b20: 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 3e  ActionType == ">
6b30: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
6b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b50: 20 20 20 23 20 77 65 20 64 6f 20 6e 6f 74 68 69     # we do nothi
6b60: 6e 67 2c 20 74 68 69 73 20 74 65 73 74 20 69 73  ng, this test is
6b70: 20 6a 75 73 74 20 61 20 63 6f 6e 64 69 74 69 6f   just a conditio
6b80: 6e 20 74 6f 20 61 70 70 6c 79 20 61 6c 6c 20 66  n to apply all f
6b90: 6f 6c 6c 6f 77 69 6e 67 20 61 63 74 69 6f 6e 73  ollowing actions
6ba0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6bc0: 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20   if bDebug:.    
6bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6bf0: 70 72 69 6e 74 28 22 3e 22 2c 20 73 52 75 6c 65  print(">", sRule
6c00: 49 64 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  Id).            
6c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c20: 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 20 20      pass.       
6c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c40: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
6c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6c60: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
6c70: 28 22 23 20 65 72 72 6f 72 3a 20 75 6e 6b 6e 6f  ("# error: unkno
6c80: 77 6e 20 61 63 74 69 6f 6e 20 61 74 20 22 20 2b  wn action at " +
6c90: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
6ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6cb0: 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54 79    elif cActionTy
6cc0: 70 65 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20 20  pe == ">":.     
6cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ce0: 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67         if bDebug
6cf0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
6d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d10: 20 20 70 72 69 6e 74 28 22 3e 21 22 2c 20 73 52    print(">!", sR
6d20: 75 6c 65 49 64 29 0a 20 20 20 20 20 20 20 20 20  uleId).         
6d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d40: 20 20 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20     break.       
6d50: 20 20 20 20 20 20 20 20 20 65 78 63 65 70 74 20           except 
6d60: 45 78 63 65 70 74 69 6f 6e 20 61 73 20 65 3a 0a  Exception as e:.
6d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d80: 20 20 20 20 72 61 69 73 65 20 45 78 63 65 70 74      raise Except
6d90: 69 6f 6e 28 73 74 72 28 65 29 2c 20 73 4c 69 6e  ion(str(e), sLin
6da0: 65 49 64 29 0a 20 20 20 20 20 20 20 20 72 65 74  eId).        ret
6db0: 75 72 6e 20 62 43 68 61 6e 67 65 2c 20 64 45 72  urn bChange, dEr
6dc0: 72 73 0a 0a 20 20 20 20 64 65 66 20 5f 63 72 65  rs..    def _cre
6dd0: 61 74 65 57 72 69 74 65 72 45 72 72 6f 72 20 28  ateWriterError (
6de0: 73 65 6c 66 2c 20 73 53 75 67 67 2c 20 6e 54 6f  self, sSugg, nTo
6df0: 6b 65 6e 4f 66 66 73 65 74 2c 20 69 46 69 72 73  kenOffset, iFirs
6e00: 74 54 6f 6b 65 6e 2c 20 6e 53 74 61 72 74 2c 20  tToken, nStart, 
6e10: 6e 45 6e 64 2c 20 73 4c 69 6e 65 49 64 2c 20 73  nEnd, sLineId, s
6e20: 52 75 6c 65 49 64 2c 20 62 55 70 70 65 72 63 61  RuleId, bUpperca
6e30: 73 65 2c 20 73 4d 73 67 2c 20 73 55 52 4c 2c 20  se, sMsg, sURL, 
6e40: 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 73 4f 70  bShowRuleId, sOp
6e50: 74 69 6f 6e 2c 20 62 43 6f 6e 74 65 78 74 29 3a  tion, bContext):
6e60: 0a 20 20 20 20 20 20 20 20 22 65 72 72 6f 72 20  .        "error 
6e70: 66 6f 72 20 57 72 69 74 65 72 20 28 4c 4f 2f 4f  for Writer (LO/O
6e80: 4f 29 22 0a 20 20 20 20 20 20 20 20 78 45 72 72  O)".        xErr
6e90: 20 3d 20 53 69 6e 67 6c 65 50 72 6f 6f 66 72 65   = SingleProofre
6ea0: 61 64 69 6e 67 45 72 72 6f 72 28 29 0a 20 20 20  adingError().   
6eb0: 20 20 20 20 20 23 78 45 72 72 20 3d 20 75 6e 6f       #xErr = uno
6ec0: 2e 63 72 65 61 74 65 55 6e 6f 53 74 72 75 63 74  .createUnoStruct
6ed0: 28 20 22 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e  ( "com.sun.star.
6ee0: 6c 69 6e 67 75 69 73 74 69 63 32 2e 53 69 6e 67  linguistic2.Sing
6ef0: 6c 65 50 72 6f 6f 66 72 65 61 64 69 6e 67 45 72  leProofreadingEr
6f00: 72 6f 72 22 20 29 0a 20 20 20 20 20 20 20 20 78  ror" ).        x
6f10: 45 72 72 2e 6e 45 72 72 6f 72 53 74 61 72 74 20  Err.nErrorStart 
6f20: 3d 20 6e 53 74 61 72 74 0a 20 20 20 20 20 20 20  = nStart.       
6f30: 20 78 45 72 72 2e 6e 45 72 72 6f 72 4c 65 6e 67   xErr.nErrorLeng
6f40: 74 68 20 3d 20 6e 45 6e 64 20 2d 20 6e 53 74 61  th = nEnd - nSta
6f50: 72 74 0a 20 20 20 20 20 20 20 20 78 45 72 72 2e  rt.        xErr.
6f60: 6e 45 72 72 6f 72 54 79 70 65 20 3d 20 50 52 4f  nErrorType = PRO
6f70: 4f 46 52 45 41 44 49 4e 47 0a 20 20 20 20 20 20  OFREADING.      
6f80: 20 20 78 45 72 72 2e 61 52 75 6c 65 49 64 65 6e    xErr.aRuleIden
6f90: 74 69 66 69 65 72 20 3d 20 73 52 75 6c 65 49 64  tifier = sRuleId
6fa0: 0a 20 20 20 20 20 20 20 20 23 20 73 75 67 67 65  .        # sugge
6fb0: 73 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 69  stions.        i
6fc0: 66 20 73 53 75 67 67 5b 30 3a 31 5d 20 3d 3d 20  f sSugg[0:1] == 
6fd0: 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "=":.           
6fe0: 20 73 53 75 67 67 20 3d 20 67 6c 6f 62 61 6c 73   sSugg = globals
6ff0: 28 29 5b 73 53 75 67 67 5b 31 3a 5d 5d 28 73 65  ()[sSugg[1:]](se
7000: 6c 66 2e 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  lf.lToken, nToke
7010: 6e 4f 66 66 73 65 74 29 0a 20 20 20 20 20 20 20  nOffset).       
7020: 20 20 20 20 20 69 66 20 73 53 75 67 67 3a 0a 20       if sSugg:. 
7030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
7040: 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e 64  f bUppercase and
7050: 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 46 69   self.lToken[iFi
7060: 72 73 74 54 6f 6b 65 6e 5d 5b 22 73 56 61 6c 75  rstToken]["sValu
7070: 65 22 5d 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72  e"][0:1].isupper
7080: 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ():.            
7090: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 75          xErr.aSu
70a0: 67 67 65 73 74 69 6f 6e 73 20 3d 20 74 75 70 6c  ggestions = tupl
70b0: 65 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61  e(map(str.capita
70c0: 6c 69 7a 65 2c 20 73 53 75 67 67 2e 73 70 6c 69  lize, sSugg.spli
70d0: 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20  t("|"))).       
70e0: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
70f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7100: 20 20 20 78 45 72 72 2e 61 53 75 67 67 65 73 74     xErr.aSuggest
7110: 69 6f 6e 73 20 3d 20 74 75 70 6c 65 28 73 53 75  ions = tuple(sSu
7120: 67 67 2e 73 70 6c 69 74 28 22 7c 22 29 29 0a 20  gg.split("|")). 
7130: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
7140: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7150: 20 78 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f   xErr.aSuggestio
7160: 6e 73 20 3d 20 28 29 0a 20 20 20 20 20 20 20 20  ns = ().        
7170: 65 6c 69 66 20 73 53 75 67 67 20 3d 3d 20 22 5f  elif sSugg == "_
7180: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 78  ":.            x
7190: 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73  Err.aSuggestions
71a0: 20 3d 20 28 29 0a 20 20 20 20 20 20 20 20 65 6c   = ().        el
71b0: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
71c0: 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e  if bUppercase an
71d0: 64 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 46  d self.lToken[iF
71e0: 69 72 73 74 54 6f 6b 65 6e 5d 5b 22 73 56 61 6c  irstToken]["sVal
71f0: 75 65 22 5d 5b 30 3a 31 5d 2e 69 73 75 70 70 65  ue"][0:1].isuppe
7200: 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  r():.           
7210: 20 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65       xErr.aSugge
7220: 73 74 69 6f 6e 73 20 3d 20 74 75 70 6c 65 28 6d  stions = tuple(m
7230: 61 70 28 73 74 72 2e 63 61 70 69 74 61 6c 69 7a  ap(str.capitaliz
7240: 65 2c 20 73 65 6c 66 2e 5f 65 78 70 61 6e 64 28  e, self._expand(
7250: 73 53 75 67 67 2c 20 6e 54 6f 6b 65 6e 4f 66 66  sSugg, nTokenOff
7260: 73 65 74 29 2e 73 70 6c 69 74 28 22 7c 22 29 29  set).split("|"))
7270: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  ).            el
7280: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
7290: 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65 73      xErr.aSugges
72a0: 74 69 6f 6e 73 20 3d 20 74 75 70 6c 65 28 73 65  tions = tuple(se
72b0: 6c 66 2e 5f 65 78 70 61 6e 64 28 73 53 75 67 67  lf._expand(sSugg
72c0: 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29 2e  , nTokenOffset).
72d0: 73 70 6c 69 74 28 22 7c 22 29 29 0a 20 20 20 20  split("|")).    
72e0: 20 20 20 20 23 20 4d 65 73 73 61 67 65 0a 20 20      # Message.  
72f0: 20 20 20 20 20 20 73 4d 65 73 73 61 67 65 20 3d        sMessage =
7300: 20 67 6c 6f 62 61 6c 73 28 29 5b 73 4d 73 67 5b   globals()[sMsg[
7310: 31 3a 5d 5d 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e  1:]](self.lToken
7320: 29 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20  )  if sMsg[0:1] 
7330: 3d 3d 20 22 3d 22 20 20 65 6c 73 65 20 73 65 6c  == "="  else sel
7340: 66 2e 5f 65 78 70 61 6e 64 28 73 4d 73 67 2c 20  f._expand(sMsg, 
7350: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29 0a 20 20  nTokenOffset).  
7360: 20 20 20 20 20 20 78 45 72 72 2e 61 53 68 6f 72        xErr.aShor
7370: 74 43 6f 6d 6d 65 6e 74 20 3d 20 73 4d 65 73 73  tComment = sMess
7380: 61 67 65 20 20 20 23 20 73 4d 65 73 73 61 67 65  age   # sMessage
7390: 2e 73 70 6c 69 74 28 22 7c 22 29 5b 30 5d 20 20  .split("|")[0]  
73a0: 20 20 20 23 20 69 6e 20 63 6f 6e 74 65 78 74 20     # in context 
73b0: 6d 65 6e 75 0a 20 20 20 20 20 20 20 20 78 45 72  menu.        xEr
73c0: 72 2e 61 46 75 6c 6c 43 6f 6d 6d 65 6e 74 20 3d  r.aFullComment =
73d0: 20 73 4d 65 73 73 61 67 65 20 20 20 23 20 73 4d   sMessage   # sM
73e0: 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22 7c 22  essage.split("|"
73f0: 29 5b 2d 31 5d 20 20 20 20 23 20 69 6e 20 64 69  )[-1]    # in di
7400: 61 6c 6f 67 0a 20 20 20 20 20 20 20 20 69 66 20  alog.        if 
7410: 62 53 68 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20  bShowRuleId:.   
7420: 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53           xErr.aS
7430: 68 6f 72 74 43 6f 6d 6d 65 6e 74 20 2b 3d 20 22  hortComment += "
7440: 20 20 22 20 2b 20 73 4c 69 6e 65 49 64 20 2b 20    " + sLineId + 
7450: 22 20 23 20 22 20 2b 20 73 52 75 6c 65 49 64 0a  " # " + sRuleId.
7460: 20 20 20 20 20 20 20 20 23 20 55 52 4c 0a 20 20          # URL.  
7470: 20 20 20 20 20 20 69 66 20 73 55 52 4c 3a 0a 20        if sURL:. 
7480: 20 20 20 20 20 20 20 20 20 20 20 70 20 3d 20 50             p = P
7490: 72 6f 70 65 72 74 79 56 61 6c 75 65 28 29 0a 20  ropertyValue(). 
74a0: 20 20 20 20 20 20 20 20 20 20 20 70 2e 4e 61 6d             p.Nam
74b0: 65 20 3d 20 22 46 75 6c 6c 43 6f 6d 6d 65 6e 74  e = "FullComment
74c0: 55 52 4c 22 0a 20 20 20 20 20 20 20 20 20 20 20  URL".           
74d0: 20 70 2e 56 61 6c 75 65 20 3d 20 73 55 52 4c 0a   p.Value = sURL.
74e0: 20 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72              xErr
74f0: 2e 61 50 72 6f 70 65 72 74 69 65 73 20 3d 20 28  .aProperties = (
7500: 70 2c 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  p,).        else
7510: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 78 45  :.            xE
7520: 72 72 2e 61 50 72 6f 70 65 72 74 69 65 73 20 3d  rr.aProperties =
7530: 20 28 29 0a 20 20 20 20 20 20 20 20 72 65 74 75   ().        retu
7540: 72 6e 20 78 45 72 72 0a 0a 20 20 20 20 64 65 66  rn xErr..    def
7550: 20 5f 63 72 65 61 74 65 44 69 63 74 45 72 72 6f   _createDictErro
7560: 72 20 28 73 65 6c 66 2c 20 73 53 75 67 67 2c 20  r (self, sSugg, 
7570: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2c 20 69 46  nTokenOffset, iF
7580: 69 72 73 74 54 6f 6b 65 6e 2c 20 6e 53 74 61 72  irstToken, nStar
7590: 74 2c 20 6e 45 6e 64 2c 20 73 4c 69 6e 65 49 64  t, nEnd, sLineId
75a0: 2c 20 73 52 75 6c 65 49 64 2c 20 62 55 70 70 65  , sRuleId, bUppe
75b0: 72 63 61 73 65 2c 20 73 4d 73 67 2c 20 73 55 52  rcase, sMsg, sUR
75c0: 4c 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20  L, bShowRuleId, 
75d0: 73 4f 70 74 69 6f 6e 2c 20 62 43 6f 6e 74 65 78  sOption, bContex
75e0: 74 29 3a 0a 20 20 20 20 20 20 20 20 22 65 72 72  t):.        "err
75f0: 6f 72 20 61 73 20 61 20 64 69 63 74 69 6f 6e 61  or as a dictiona
7600: 72 79 22 0a 20 20 20 20 20 20 20 20 64 45 72 72  ry".        dErr
7610: 20 3d 20 7b 7d 0a 20 20 20 20 20 20 20 20 64 45   = {}.        dE
7620: 72 72 5b 22 6e 53 74 61 72 74 22 5d 20 3d 20 6e  rr["nStart"] = n
7630: 53 74 61 72 74 0a 20 20 20 20 20 20 20 20 64 45  Start.        dE
7640: 72 72 5b 22 6e 45 6e 64 22 5d 20 3d 20 6e 45 6e  rr["nEnd"] = nEn
7650: 64 0a 20 20 20 20 20 20 20 20 64 45 72 72 5b 22  d.        dErr["
7660: 73 4c 69 6e 65 49 64 22 5d 20 3d 20 73 4c 69 6e  sLineId"] = sLin
7670: 65 49 64 0a 20 20 20 20 20 20 20 20 64 45 72 72  eId.        dErr
7680: 5b 22 73 52 75 6c 65 49 64 22 5d 20 3d 20 73 52  ["sRuleId"] = sR
7690: 75 6c 65 49 64 0a 20 20 20 20 20 20 20 20 64 45  uleId.        dE
76a0: 72 72 5b 22 73 54 79 70 65 22 5d 20 3d 20 73 4f  rr["sType"] = sO
76b0: 70 74 69 6f 6e 20 20 69 66 20 73 4f 70 74 69 6f  ption  if sOptio
76c0: 6e 20 20 65 6c 73 65 20 22 6e 6f 74 79 70 65 22  n  else "notype"
76d0: 0a 20 20 20 20 20 20 20 20 23 20 73 75 67 67 65  .        # sugge
76e0: 73 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 69  stions.        i
76f0: 66 20 73 53 75 67 67 5b 30 3a 31 5d 20 3d 3d 20  f sSugg[0:1] == 
7700: 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "=":.           
7710: 20 73 53 75 67 67 20 3d 20 67 6c 6f 62 61 6c 73   sSugg = globals
7720: 28 29 5b 73 53 75 67 67 5b 31 3a 5d 5d 28 73 65  ()[sSugg[1:]](se
7730: 6c 66 2e 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65  lf.lToken, nToke
7740: 6e 4f 66 66 73 65 74 29 0a 20 20 20 20 20 20 20  nOffset).       
7750: 20 20 20 20 20 69 66 20 73 53 75 67 67 3a 0a 20       if sSugg:. 
7760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
7770: 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e 64  f bUppercase and
7780: 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 46 69   self.lToken[iFi
7790: 72 73 74 54 6f 6b 65 6e 5d 5b 22 73 56 61 6c 75  rstToken]["sValu
77a0: 65 22 5d 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72  e"][0:1].isupper
77b0: 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ():.            
77c0: 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61 53          dErr["aS
77d0: 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20 6c  uggestions"] = l
77e0: 69 73 74 28 6d 61 70 28 73 74 72 2e 63 61 70 69  ist(map(str.capi
77f0: 74 61 6c 69 7a 65 2c 20 73 53 75 67 67 2e 73 70  talize, sSugg.sp
7800: 6c 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20  lit("|"))).     
7810: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
7820: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7830: 20 20 20 20 20 64 45 72 72 5b 22 61 53 75 67 67       dErr["aSugg
7840: 65 73 74 69 6f 6e 73 22 5d 20 3d 20 73 53 75 67  estions"] = sSug
7850: 67 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20  g.split("|").   
7860: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
7870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
7880: 45 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e  Err["aSuggestion
7890: 73 22 5d 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20  s"] = [].       
78a0: 20 65 6c 69 66 20 73 53 75 67 67 20 3d 3d 20 22   elif sSugg == "
78b0: 5f 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  _":.            
78c0: 64 45 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f  dErr["aSuggestio
78d0: 6e 73 22 5d 20 3d 20 5b 5d 0a 20 20 20 20 20 20  ns"] = [].      
78e0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
78f0: 20 20 20 20 69 66 20 62 55 70 70 65 72 63 61 73      if bUppercas
7900: 65 20 61 6e 64 20 73 65 6c 66 2e 6c 54 6f 6b 65  e and self.lToke
7910: 6e 5b 69 46 69 72 73 74 54 6f 6b 65 6e 5d 5b 22  n[iFirstToken]["
7920: 73 56 61 6c 75 65 22 5d 5b 30 3a 31 5d 2e 69 73  sValue"][0:1].is
7930: 75 70 70 65 72 28 29 3a 0a 20 20 20 20 20 20 20  upper():.       
7940: 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61           dErr["a
7950: 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20  Suggestions"] = 
7960: 6c 69 73 74 28 6d 61 70 28 73 74 72 2e 63 61 70  list(map(str.cap
7970: 69 74 61 6c 69 7a 65 2c 20 73 65 6c 66 2e 5f 65  italize, self._e
7980: 78 70 61 6e 64 28 73 53 75 67 67 2c 20 6e 54 6f  xpand(sSugg, nTo
7990: 6b 65 6e 4f 66 66 73 65 74 29 2e 73 70 6c 69 74  kenOffset).split
79a0: 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20 20 20  ("|"))).        
79b0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
79c0: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
79d0: 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d  aSuggestions"] =
79e0: 20 73 65 6c 66 2e 5f 65 78 70 61 6e 64 28 73 53   self._expand(sS
79f0: 75 67 67 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65  ugg, nTokenOffse
7a00: 74 29 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20  t).split("|").  
7a10: 20 20 20 20 20 20 23 20 4d 65 73 73 61 67 65 0a        # Message.
7a20: 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 73 4d          dErr["sM
7a30: 65 73 73 61 67 65 22 5d 20 3d 20 67 6c 6f 62 61  essage"] = globa
7a40: 6c 73 28 29 5b 73 4d 73 67 5b 31 3a 5d 5d 28 73  ls()[sMsg[1:]](s
7a50: 65 6c 66 2e 6c 54 6f 6b 65 6e 29 20 20 69 66 20  elf.lToken)  if 
7a60: 73 4d 73 67 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22  sMsg[0:1] == "="
7a70: 20 20 65 6c 73 65 20 73 65 6c 66 2e 5f 65 78 70    else self._exp
7a80: 61 6e 64 28 73 4d 73 67 2c 20 6e 54 6f 6b 65 6e  and(sMsg, nToken
7a90: 4f 66 66 73 65 74 29 0a 20 20 20 20 20 20 20 20  Offset).        
7aa0: 69 66 20 62 53 68 6f 77 52 75 6c 65 49 64 3a 0a  if bShowRuleId:.
7ab0: 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72              dErr
7ac0: 5b 22 73 4d 65 73 73 61 67 65 22 5d 20 2b 3d 20  ["sMessage"] += 
7ad0: 22 20 20 22 20 2b 20 73 4c 69 6e 65 49 64 20 2b  "  " + sLineId +
7ae0: 20 22 20 23 20 22 20 2b 20 73 52 75 6c 65 49 64   " # " + sRuleId
7af0: 0a 20 20 20 20 20 20 20 20 23 20 55 52 4c 0a 20  .        # URL. 
7b00: 20 20 20 20 20 20 20 64 45 72 72 5b 22 55 52 4c         dErr["URL
7b10: 22 5d 20 3d 20 73 55 52 4c 20 20 69 66 20 73 55  "] = sURL  if sU
7b20: 52 4c 20 20 65 6c 73 65 20 22 22 0a 20 20 20 20  RL  else "".    
7b30: 20 20 20 20 23 20 43 6f 6e 74 65 78 74 0a 20 20      # Context.  
7b40: 20 20 20 20 20 20 69 66 20 62 43 6f 6e 74 65 78        if bContex
7b50: 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64  t:.            d
7b60: 45 72 72 5b 27 73 55 6e 64 65 72 6c 69 6e 65 64  Err['sUnderlined
7b70: 27 5d 20 3d 20 73 65 6c 66 2e 73 53 65 6e 74 65  '] = self.sSente
7b80: 6e 63 65 30 5b 64 45 72 72 5b 22 6e 53 74 61 72  nce0[dErr["nStar
7b90: 74 22 5d 3a 64 45 72 72 5b 22 6e 45 6e 64 22 5d  t"]:dErr["nEnd"]
7ba0: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 45  ].            dE
7bb0: 72 72 5b 27 73 42 65 66 6f 72 65 27 5d 20 3d 20  rr['sBefore'] = 
7bc0: 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 30 5b  self.sSentence0[
7bd0: 6d 61 78 28 30 2c 64 45 72 72 5b 22 6e 53 74 61  max(0,dErr["nSta
7be0: 72 74 22 5d 2d 38 30 29 3a 64 45 72 72 5b 22 6e  rt"]-80):dErr["n
7bf0: 53 74 61 72 74 22 5d 5d 0a 20 20 20 20 20 20 20  Start"]].       
7c00: 20 20 20 20 20 64 45 72 72 5b 27 73 41 66 74 65       dErr['sAfte
7c10: 72 27 5d 20 3d 20 73 65 6c 66 2e 73 53 65 6e 74  r'] = self.sSent
7c20: 65 6e 63 65 30 5b 64 45 72 72 5b 22 6e 45 6e 64  ence0[dErr["nEnd
7c30: 22 5d 3a 64 45 72 72 5b 22 6e 45 6e 64 22 5d 2b  "]:dErr["nEnd"]+
7c40: 38 30 5d 0a 20 20 20 20 20 20 20 20 72 65 74 75  80].        retu
7c50: 72 6e 20 64 45 72 72 0a 0a 20 20 20 20 64 65 66  rn dErr..    def
7c60: 20 5f 65 78 70 61 6e 64 20 28 73 65 6c 66 2c 20   _expand (self, 
7c70: 73 4d 73 67 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73  sMsg, nTokenOffs
7c80: 65 74 29 3a 0a 20 20 20 20 20 20 20 20 23 70 72  et):.        #pr
7c90: 69 6e 74 28 22 2a 22 2c 20 73 4d 73 67 29 0a 20  int("*", sMsg). 
7ca0: 20 20 20 20 20 20 20 66 6f 72 20 6d 20 69 6e 20         for m in 
7cb0: 72 65 2e 66 69 6e 64 69 74 65 72 28 72 22 5c 5c  re.finditer(r"\\
7cc0: 28 5b 30 2d 39 5d 2b 29 22 2c 20 73 4d 73 67 29  ([0-9]+)", sMsg)
7cd0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4d  :.            sM
7ce0: 73 67 20 3d 20 73 4d 73 67 2e 72 65 70 6c 61 63  sg = sMsg.replac
7cf0: 65 28 6d 2e 67 72 6f 75 70 28 30 29 2c 20 73 65  e(m.group(0), se
7d00: 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 6e 74 28 6d 2e  lf.lToken[int(m.
7d10: 67 72 6f 75 70 28 31 29 29 2b 6e 54 6f 6b 65 6e  group(1))+nToken
7d20: 4f 66 66 73 65 74 5d 5b 22 73 56 61 6c 75 65 22  Offset]["sValue"
7d30: 5d 29 0a 20 20 20 20 20 20 20 20 23 70 72 69 6e  ]).        #prin
7d40: 74 28 22 3e 22 2c 20 73 4d 73 67 29 0a 20 20 20  t(">", sMsg).   
7d50: 20 20 20 20 20 72 65 74 75 72 6e 20 73 4d 73 67       return sMsg
7d60: 0a 0a 20 20 20 20 64 65 66 20 5f 74 61 67 41 6e  ..    def _tagAn
7d70: 64 50 72 65 70 61 72 65 54 6f 6b 65 6e 46 6f 72  dPrepareTokenFor
7d80: 52 65 77 72 69 74 69 6e 67 20 28 73 65 6c 66 2c  Rewriting (self,
7d90: 20 73 57 68 61 74 2c 20 6e 54 6f 6b 65 6e 52 65   sWhat, nTokenRe
7da0: 77 72 69 74 65 53 74 61 72 74 2c 20 6e 54 6f 6b  writeStart, nTok
7db0: 65 6e 52 65 77 72 69 74 65 45 6e 64 2c 20 62 55  enRewriteEnd, bU
7dc0: 70 70 65 72 63 61 73 65 3d 54 72 75 65 29 3a 0a  ppercase=True):.
7dd0: 20 20 20 20 20 20 20 20 22 74 65 78 74 20 70 72          "text pr
7de0: 6f 63 65 73 73 6f 72 3a 20 72 65 77 72 69 74 65  ocessor: rewrite
7df0: 20 74 6f 6b 65 6e 73 20 62 65 74 77 65 65 6e 20   tokens between 
7e00: 3c 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74  <nTokenRewriteSt
7e10: 61 72 74 3e 20 61 6e 64 20 3c 6e 54 6f 6b 65 6e  art> and <nToken
7e20: 52 65 77 72 69 74 65 45 6e 64 3e 20 70 6f 73 69  RewriteEnd> posi
7e30: 74 69 6f 6e 22 0a 20 20 20 20 20 20 20 20 69 66  tion".        if
7e40: 20 73 57 68 61 74 20 3d 3d 20 22 2a 22 3a 0a 20   sWhat == "*":. 
7e50: 20 20 20 20 20 20 20 20 20 20 20 23 20 70 75 72             # pur
7e60: 67 65 20 74 65 78 74 0a 20 20 20 20 20 20 20 20  ge text.        
7e70: 20 20 20 20 69 66 20 6e 54 6f 6b 65 6e 52 65 77      if nTokenRew
7e80: 72 69 74 65 45 6e 64 20 2d 20 6e 54 6f 6b 65 6e  riteEnd - nToken
7e90: 52 65 77 72 69 74 65 53 74 61 72 74 20 3d 3d 20  RewriteStart == 
7ea0: 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  0:.             
7eb0: 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e     self.lToken[n
7ec0: 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61 72  TokenRewriteStar
7ed0: 74 5d 5b 22 62 54 6f 52 65 6d 6f 76 65 22 5d 20  t]["bToRemove"] 
7ee0: 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20 20  = True.         
7ef0: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
7f00: 20 20 20 20 20 20 20 20 20 66 6f 72 20 69 20 69           for i i
7f10: 6e 20 72 61 6e 67 65 28 6e 54 6f 6b 65 6e 52 65  n range(nTokenRe
7f20: 77 72 69 74 65 53 74 61 72 74 2c 20 6e 54 6f 6b  writeStart, nTok
7f30: 65 6e 52 65 77 72 69 74 65 45 6e 64 2b 31 29 3a  enRewriteEnd+1):
7f40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7f50: 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e       self.lToken
7f60: 5b 69 5d 5b 22 62 54 6f 52 65 6d 6f 76 65 22 5d  [i]["bToRemove"]
7f70: 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20   = True.        
7f80: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
7f90: 20 20 69 66 20 73 57 68 61 74 2e 73 74 61 72 74    if sWhat.start
7fa0: 73 77 69 74 68 28 22 3d 22 29 3a 0a 20 20 20 20  swith("="):.    
7fb0: 20 20 20 20 20 20 20 20 20 20 20 20 73 57 68 61              sWha
7fc0: 74 20 3d 20 67 6c 6f 62 61 6c 73 28 29 5b 73 57  t = globals()[sW
7fd0: 68 61 74 5b 31 3a 5d 5d 28 73 65 6c 66 2e 6c 54  hat[1:]](self.lT
7fe0: 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20 20 20 20  oken).          
7ff0: 20 20 62 55 70 70 65 72 63 61 73 65 20 3d 20 62    bUppercase = b
8000: 55 70 70 65 72 63 61 73 65 20 61 6e 64 20 73 65  Uppercase and se
8010: 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e  lf.lToken[nToken
8020: 52 65 77 72 69 74 65 53 74 61 72 74 5d 5b 22 73  RewriteStart]["s
8030: 56 61 6c 75 65 22 5d 5b 30 3a 31 5d 2e 69 73 75  Value"][0:1].isu
8040: 70 70 65 72 28 29 0a 20 20 20 20 20 20 20 20 20  pper().         
8050: 20 20 20 69 66 20 6e 54 6f 6b 65 6e 52 65 77 72     if nTokenRewr
8060: 69 74 65 45 6e 64 20 2d 20 6e 54 6f 6b 65 6e 52  iteEnd - nTokenR
8070: 65 77 72 69 74 65 53 74 61 72 74 20 3d 3d 20 30  ewriteStart == 0
8080: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
8090: 20 20 73 57 68 61 74 20 3d 20 73 57 68 61 74 20    sWhat = sWhat 
80a0: 2b 20 22 20 22 20 2a 20 28 6c 65 6e 28 73 65 6c  + " " * (len(sel
80b0: 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 52  f.lToken[nTokenR
80c0: 65 77 72 69 74 65 53 74 61 72 74 5d 5b 22 73 56  ewriteStart]["sV
80d0: 61 6c 75 65 22 5d 29 2d 6c 65 6e 28 73 57 68 61  alue"])-len(sWha
80e0: 74 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  t)).            
80f0: 20 20 20 20 69 66 20 62 55 70 70 65 72 63 61 73      if bUppercas
8100: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
8110: 20 20 20 20 20 20 20 73 57 68 61 74 20 3d 20 73         sWhat = s
8120: 57 68 61 74 5b 30 3a 31 5d 2e 75 70 70 65 72 28  What[0:1].upper(
8130: 29 20 2b 20 73 57 68 61 74 5b 31 3a 5d 0a 20 20  ) + sWhat[1:].  
8140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65                se
8150: 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e  lf.lToken[nToken
8160: 52 65 77 72 69 74 65 53 74 61 72 74 5d 5b 22 73  RewriteStart]["s
8170: 4e 65 77 56 61 6c 75 65 22 5d 20 3d 20 73 57 68  NewValue"] = sWh
8180: 61 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 65  at.            e
8190: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
81a0: 20 20 20 20 20 6c 54 6f 6b 65 6e 56 61 6c 75 65       lTokenValue
81b0: 20 3d 20 73 57 68 61 74 2e 73 70 6c 69 74 28 22   = sWhat.split("
81c0: 7c 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  |").            
81d0: 20 20 20 20 69 66 20 6c 65 6e 28 6c 54 6f 6b 65      if len(lToke
81e0: 6e 56 61 6c 75 65 29 20 21 3d 20 28 6e 54 6f 6b  nValue) != (nTok
81f0: 65 6e 52 65 77 72 69 74 65 45 6e 64 20 2d 20 6e  enRewriteEnd - n
8200: 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61 72  TokenRewriteStar
8210: 74 20 2b 20 31 29 3a 0a 20 20 20 20 20 20 20 20  t + 1):.        
8220: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
8230: 74 28 22 45 72 72 6f 72 2e 20 54 65 78 74 20 70  t("Error. Text p
8240: 72 6f 63 65 73 73 6f 72 3a 20 6e 75 6d 62 65 72  rocessor: number
8250: 20 6f 66 20 72 65 70 6c 61 63 65 6d 65 6e 74 73   of replacements
8260: 20 21 3d 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f   != number of to
8270: 6b 65 6e 73 2e 22 29 0a 20 20 20 20 20 20 20 20  kens.").        
8280: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
8290: 72 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  rn.             
82a0: 20 20 20 66 6f 72 20 69 2c 20 73 56 61 6c 75 65     for i, sValue
82b0: 20 69 6e 20 7a 69 70 28 72 61 6e 67 65 28 6e 54   in zip(range(nT
82c0: 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61 72 74  okenRewriteStart
82d0: 2c 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 45  , nTokenRewriteE
82e0: 6e 64 2b 31 29 2c 20 6c 54 6f 6b 65 6e 56 61 6c  nd+1), lTokenVal
82f0: 75 65 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ue):.           
8300: 20 20 20 20 20 20 20 20 20 69 66 20 62 55 70 70           if bUpp
8310: 65 72 63 61 73 65 3a 0a 20 20 20 20 20 20 20 20  ercase:.        
8320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8330: 73 56 61 6c 75 65 20 3d 20 73 56 61 6c 75 65 5b  sValue = sValue[
8340: 30 3a 31 5d 2e 75 70 70 65 72 28 29 20 2b 20 73  0:1].upper() + s
8350: 56 61 6c 75 65 5b 31 3a 5d 0a 20 20 20 20 20 20  Value[1:].      
8360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65                se
8370: 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 5d 5b 22 73 4e  lf.lToken[i]["sN
8380: 65 77 56 61 6c 75 65 22 5d 20 3d 20 73 56 61 6c  ewValue"] = sVal
8390: 75 65 0a 0a 20 20 20 20 64 65 66 20 72 65 77 72  ue..    def rewr
83a0: 69 74 65 20 28 73 65 6c 66 29 3a 0a 20 20 20 20  ite (self):.    
83b0: 20 20 20 20 22 72 65 77 72 69 74 65 20 74 68 65      "rewrite the
83c0: 20 73 65 6e 74 65 6e 63 65 2c 20 6d 6f 64 69 66   sentence, modif
83d0: 79 20 74 6f 6b 65 6e 73 2c 20 70 75 72 67 65 20  y tokens, purge 
83e0: 74 68 65 20 74 6f 6b 65 6e 20 6c 69 73 74 22 0a  the token list".
83f0: 20 20 20 20 20 20 20 20 6c 4e 65 77 54 6f 6b 65          lNewToke
8400: 6e 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 66  n = [].        f
8410: 6f 72 20 69 2c 20 64 54 6f 6b 65 6e 20 69 6e 20  or i, dToken in 
8420: 65 6e 75 6d 65 72 61 74 65 28 73 65 6c 66 2e 6c  enumerate(self.l
8430: 54 6f 6b 65 6e 29 3a 0a 20 20 20 20 20 20 20 20  Token):.        
8440: 20 20 20 20 69 66 20 22 62 54 6f 52 65 6d 6f 76      if "bToRemov
8450: 65 22 20 69 6e 20 64 54 6f 6b 65 6e 3a 0a 20 20  e" in dToken:.  
8460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
8470: 72 65 6d 6f 76 65 20 75 73 65 6c 65 73 73 20 74  remove useless t
8480: 6f 6b 65 6e 0a 20 20 20 20 20 20 20 20 20 20 20  oken.           
8490: 20 20 20 20 20 73 65 6c 66 2e 73 53 65 6e 74 65       self.sSente
84a0: 6e 63 65 20 3d 20 73 65 6c 66 2e 73 53 65 6e 74  nce = self.sSent
84b0: 65 6e 63 65 5b 3a 73 65 6c 66 2e 6e 4f 66 66 73  ence[:self.nOffs
84c0: 65 74 2b 64 54 6f 6b 65 6e 5b 22 6e 53 74 61 72  et+dToken["nStar
84d0: 74 22 5d 5d 20 2b 20 22 20 22 20 2a 20 28 64 54  t"]] + " " * (dT
84e0: 6f 6b 65 6e 5b 22 6e 45 6e 64 22 5d 20 2d 20 64  oken["nEnd"] - d
84f0: 54 6f 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 29  Token["nStart"])
8500: 20 2b 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63   + self.sSentenc
8510: 65 5b 73 65 6c 66 2e 6e 4f 66 66 73 65 74 2b 64  e[self.nOffset+d
8520: 54 6f 6b 65 6e 5b 22 6e 45 6e 64 22 5d 3a 5d 0a  Token["nEnd"]:].
8530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8540: 23 70 72 69 6e 74 28 22 72 65 6d 6f 76 65 64 3a  #print("removed:
8550: 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ", dToken["sValu
8560: 65 22 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20  e"]).           
8570: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
8580: 20 20 20 20 20 20 20 6c 4e 65 77 54 6f 6b 65 6e         lNewToken
8590: 2e 61 70 70 65 6e 64 28 64 54 6f 6b 65 6e 29 0a  .append(dToken).
85a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
85b0: 69 66 20 22 73 4e 65 77 56 61 6c 75 65 22 20 69  if "sNewValue" i
85c0: 6e 20 64 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20  n dToken:.      
85d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
85e0: 72 65 77 72 69 74 65 20 74 6f 6b 65 6e 20 61 6e  rewrite token an
85f0: 64 20 73 65 6e 74 65 6e 63 65 0a 20 20 20 20 20  d sentence.     
8600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
8610: 70 72 69 6e 74 28 64 54 6f 6b 65 6e 5b 22 73 56  print(dToken["sV
8620: 61 6c 75 65 22 5d 2c 20 22 2d 3e 22 2c 20 64 54  alue"], "->", dT
8630: 6f 6b 65 6e 5b 22 73 4e 65 77 56 61 6c 75 65 22  oken["sNewValue"
8640: 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]).             
8650: 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22 73         dToken["s
8660: 52 65 61 6c 56 61 6c 75 65 22 5d 20 3d 20 64 54  RealValue"] = dT
8670: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 0a 20  oken["sValue"]. 
8680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8690: 20 20 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75     dToken["sValu
86a0: 65 22 5d 20 3d 20 64 54 6f 6b 65 6e 5b 22 73 4e  e"] = dToken["sN
86b0: 65 77 56 61 6c 75 65 22 5d 0a 20 20 20 20 20 20  ewValue"].      
86c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 44                nD
86d0: 69 66 66 4c 65 6e 20 3d 20 6c 65 6e 28 64 54 6f  iffLen = len(dTo
86e0: 6b 65 6e 5b 22 73 52 65 61 6c 56 61 6c 75 65 22  ken["sRealValue"
86f0: 5d 29 20 2d 20 6c 65 6e 28 64 54 6f 6b 65 6e 5b  ]) - len(dToken[
8700: 22 73 4e 65 77 56 61 6c 75 65 22 5d 29 0a 20 20  "sNewValue"]).  
8710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8720: 20 20 73 4e 65 77 52 65 70 6c 20 3d 20 28 64 54    sNewRepl = (dT
8730: 6f 6b 65 6e 5b 22 73 4e 65 77 56 61 6c 75 65 22  oken["sNewValue"
8740: 5d 20 2b 20 22 20 22 20 2a 20 6e 44 69 66 66 4c  ] + " " * nDiffL
8750: 65 6e 29 20 20 69 66 20 6e 44 69 66 66 4c 65 6e  en)  if nDiffLen
8760: 20 3e 3d 20 30 20 20 65 6c 73 65 20 64 54 6f 6b   >= 0  else dTok
8770: 65 6e 5b 22 73 4e 65 77 56 61 6c 75 65 22 5d 5b  en["sNewValue"][
8780: 3a 6c 65 6e 28 64 54 6f 6b 65 6e 5b 22 73 52 65  :len(dToken["sRe
8790: 61 6c 56 61 6c 75 65 22 5d 29 5d 0a 20 20 20 20  alValue"])].    
87a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
87b0: 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 20 3d  self.sSentence =
87c0: 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 5b   self.sSentence[
87d0: 3a 73 65 6c 66 2e 6e 4f 66 66 73 65 74 2b 64 54  :self.nOffset+dT
87e0: 6f 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 5d 20  oken["nStart"]] 
87f0: 2b 20 73 4e 65 77 52 65 70 6c 20 2b 20 73 65 6c  + sNewRepl + sel
8800: 66 2e 73 53 65 6e 74 65 6e 63 65 5b 73 65 6c 66  f.sSentence[self
8810: 2e 6e 4f 66 66 73 65 74 2b 64 54 6f 6b 65 6e 5b  .nOffset+dToken[
8820: 22 6e 45 6e 64 22 5d 3a 5d 0a 20 20 20 20 20 20  "nEnd"]:].      
8830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 65                de
8840: 6c 20 64 54 6f 6b 65 6e 5b 22 73 4e 65 77 56 61  l dToken["sNewVa
8850: 6c 75 65 22 5d 0a 20 20 20 20 20 20 20 20 73 65  lue"].        se
8860: 6c 66 2e 6c 54 6f 6b 65 6e 2e 63 6c 65 61 72 28  lf.lToken.clear(
8870: 29 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6c  ).        self.l
8880: 54 6f 6b 65 6e 20 3d 20 6c 4e 65 77 54 6f 6b 65  Token = lNewToke
8890: 6e 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  n.        return
88a0: 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 0a   self.sSentence.
88b0: 0a 0a 0a 23 23 23 23 20 41 6e 61 6c 79 73 65 20  ...#### Analyse 
88c0: 74 6f 6b 65 6e 73 0a 0a 64 65 66 20 67 5f 6d 6f  tokens..def g_mo
88d0: 72 70 68 20 28 64 54 6f 6b 65 6e 2c 20 73 50 61  rph (dToken, sPa
88e0: 74 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65  ttern, sNegPatte
88f0: 72 6e 3d 22 22 29 3a 0a 20 20 20 20 22 61 6e 61  rn=""):.    "ana
8900: 6c 79 73 65 20 61 20 74 6f 6b 65 6e 2c 20 72 65  lyse a token, re
8910: 74 75 72 6e 20 54 72 75 65 20 69 66 20 3c 73 4e  turn True if <sN
8920: 65 67 50 61 74 74 65 72 6e 3e 20 6e 6f 74 20 69  egPattern> not i
8930: 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 61  n morphologies a
8940: 6e 64 20 3c 73 50 61 74 74 65 72 6e 3e 20 69 6e  nd <sPattern> in
8950: 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 22 0a 20   morphologies". 
8960: 20 20 20 69 66 20 22 6c 4d 6f 72 70 68 22 20 69     if "lMorph" i
8970: 6e 20 64 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20  n dToken:.      
8980: 20 20 6c 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65    lMorph = dToke
8990: 6e 5b 22 6c 4d 6f 72 70 68 22 5d 0a 20 20 20 20  n["lMorph"].    
89a0: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 6c 4d  else:.        lM
89b0: 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68  orph = _oSpellCh
89c0: 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64  ecker.getMorph(d
89d0: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29  Token["sValue"])
89e0: 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20  .        if not 
89f0: 6c 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20  lMorph:.        
8a00: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
8a10: 0a 20 20 20 20 23 20 63 68 65 63 6b 20 6e 65 67  .    # check neg
8a20: 61 74 69 76 65 20 63 6f 6e 64 69 74 69 6f 6e 0a  ative condition.
8a30: 20 20 20 20 69 66 20 73 4e 65 67 50 61 74 74 65      if sNegPatte
8a40: 72 6e 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  rn:.        if s
8a50: 4e 65 67 50 61 74 74 65 72 6e 20 3d 3d 20 22 2a  NegPattern == "*
8a60: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ":.            #
8a70: 20 61 6c 6c 20 6d 6f 72 70 68 20 6d 75 73 74 20   all morph must 
8a80: 6d 61 74 63 68 20 73 50 61 74 74 65 72 6e 0a 20  match sPattern. 
8a90: 20 20 20 20 20 20 20 20 20 20 20 7a 50 61 74 74             zPatt
8aa0: 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ern = re.compile
8ab0: 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20 20  (sPattern).     
8ac0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 61 6c         return al
8ad0: 6c 28 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63  l(zPattern.searc
8ae0: 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73  h(sMorph)  for s
8af0: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29  Morph in lMorph)
8b00: 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20  .        else:. 
8b10: 20 20 20 20 20 20 20 20 20 20 20 7a 4e 65 67 50             zNegP
8b20: 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70  attern = re.comp
8b30: 69 6c 65 28 73 4e 65 67 50 61 74 74 65 72 6e 29  ile(sNegPattern)
8b40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
8b50: 61 6e 79 28 7a 4e 65 67 50 61 74 74 65 72 6e 2e  any(zNegPattern.
8b60: 73 65 61 72 63 68 28 73 4d 6f 72 70 68 29 20 20  search(sMorph)  
8b70: 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d  for sMorph in lM
8b80: 6f 72 70 68 29 3a 0a 20 20 20 20 20 20 20 20 20  orph):.         
8b90: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
8ba0: 6c 73 65 0a 20 20 20 20 23 20 73 65 61 72 63 68  lse.    # search
8bb0: 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20 7a 50   sPattern.    zP
8bc0: 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70  attern = re.comp
8bd0: 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20  ile(sPattern).  
8be0: 20 20 72 65 74 75 72 6e 20 61 6e 79 28 7a 50 61    return any(zPa
8bf0: 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f  ttern.search(sMo
8c00: 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68  rph)  for sMorph
8c10: 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 64 65   in lMorph)...de
8c20: 66 20 67 5f 61 6e 61 6c 79 73 65 20 28 64 54 6f  f g_analyse (dTo
8c30: 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20 73  ken, sPattern, s
8c40: 4e 65 67 50 61 74 74 65 72 6e 3d 22 22 29 3a 0a  NegPattern=""):.
8c50: 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 74      "analyse a t
8c60: 6f 6b 65 6e 2c 20 72 65 74 75 72 6e 20 54 72 75  oken, return Tru
8c70: 65 20 69 66 20 3c 73 4e 65 67 50 61 74 74 65 72  e if <sNegPatter
8c80: 6e 3e 20 6e 6f 74 20 69 6e 20 6d 6f 72 70 68 6f  n> not in morpho
8c90: 6c 6f 67 69 65 73 20 61 6e 64 20 3c 73 50 61 74  logies and <sPat
8ca0: 74 65 72 6e 3e 20 69 6e 20 6d 6f 72 70 68 6f 6c  tern> in morphol
8cb0: 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69 67 75  ogies (disambigu
8cc0: 61 74 69 6f 6e 20 6f 66 66 29 22 0a 20 20 20 20  ation off)".    
8cd0: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
8ce0: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
8cf0: 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22  (dToken["sValue"
8d00: 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d  ]).    if not lM
8d10: 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65  orph:.        re
8d20: 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 23  turn False.    #
8d30: 20 63 68 65 63 6b 20 6e 65 67 61 74 69 76 65 20   check negative 
8d40: 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 69 66  condition.    if
8d50: 20 73 4e 65 67 50 61 74 74 65 72 6e 3a 0a 20 20   sNegPattern:.  
8d60: 20 20 20 20 20 20 69 66 20 73 4e 65 67 50 61 74        if sNegPat
8d70: 74 65 72 6e 20 3d 3d 20 22 2a 22 3a 0a 20 20 20  tern == "*":.   
8d80: 20 20 20 20 20 20 20 20 20 7a 50 61 74 74 65 72           zPatter
8d90: 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73  n = re.compile(s
8da0: 50 61 74 74 65 72 6e 29 0a 20 20 20 20 20 20 20  Pattern).       
8db0: 20 20 20 20 20 72 65 74 75 72 6e 20 61 6c 6c 28       return all(
8dc0: 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28  zPattern.search(
8dd0: 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f  sMorph)  for sMo
8de0: 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 20  rph in lMorph). 
8df0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
8e00: 20 20 20 20 20 20 20 20 20 7a 4e 65 67 50 61 74           zNegPat
8e10: 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  tern = re.compil
8e20: 65 28 73 4e 65 67 50 61 74 74 65 72 6e 29 0a 20  e(sNegPattern). 
8e30: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 61 6e             if an
8e40: 79 28 7a 4e 65 67 50 61 74 74 65 72 6e 2e 73 65  y(zNegPattern.se
8e50: 61 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f  arch(sMorph)  fo
8e60: 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72  r sMorph in lMor
8e70: 70 68 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ph):.           
8e80: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
8e90: 65 0a 20 20 20 20 23 20 73 65 61 72 63 68 20 73  e.    # search s
8ea0: 50 61 74 74 65 72 6e 0a 20 20 20 20 7a 50 61 74  Pattern.    zPat
8eb0: 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  tern = re.compil
8ec0: 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20  e(sPattern).    
8ed0: 72 65 74 75 72 6e 20 61 6e 79 28 7a 50 61 74 74  return any(zPatt
8ee0: 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70  ern.search(sMorp
8ef0: 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69  h)  for sMorph i
8f00: 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 0a 23 23 23  n lMorph)....###
8f10: 23 20 44 69 73 61 6d 62 69 67 75 61 74 6f 72 0a  # Disambiguator.
8f20: 0a 64 65 66 20 67 5f 73 65 6c 65 63 74 20 28 64  .def g_select (d
8f30: 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e 2c  Token, sPattern,
8f40: 20 6c 44 65 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a   lDefault=None):
8f50: 0a 20 20 20 20 22 73 65 6c 65 63 74 20 6d 6f 72  .    "select mor
8f60: 70 68 6f 6c 6f 67 69 65 73 20 66 6f 72 20 3c 64  phologies for <d
8f70: 54 6f 6b 65 6e 3e 20 61 63 63 6f 72 64 69 6e 67  Token> according
8f80: 20 74 6f 20 3c 73 50 61 74 74 65 72 6e 3e 2c 20   to <sPattern>, 
8f90: 61 6c 77 61 79 73 20 72 65 74 75 72 6e 20 54 72  always return Tr
8fa0: 75 65 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d  ue".    lMorph =
8fb0: 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22   dToken["lMorph"
8fc0: 5d 20 20 69 66 20 22 6c 4d 6f 72 70 68 22 20 69  ]  if "lMorph" i
8fd0: 6e 20 64 54 6f 6b 65 6e 20 20 65 6c 73 65 20 5f  n dToken  else _
8fe0: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
8ff0: 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73  tMorph(dToken["s
9000: 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 69 66 20  Value"]).    if 
9010: 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c 65  not lMorph or le
9020: 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a 0a  n(lMorph) == 1:.
9030: 20 20 20 20 20 20 20 20 69 66 20 6c 44 65 66 61          if lDefa
9040: 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ult:.           
9050: 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22   dToken["lMorph"
9060: 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20 20  ] = lDefault.   
9070: 20 20 20 20 20 20 20 20 20 23 70 72 69 6e 74 28           #print(
9080: 22 44 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b 22 73  "DA:", dToken["s
9090: 56 61 6c 75 65 22 5d 2c 20 64 54 6f 6b 65 6e 5b  Value"], dToken[
90a0: 22 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20 20 20  "lMorph"]).     
90b0: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20     return True. 
90c0: 20 20 20 6c 53 65 6c 65 63 74 20 3d 20 5b 20 73     lSelect = [ s
90d0: 4d 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72 70  Morph  for sMorp
90e0: 68 20 69 6e 20 6c 4d 6f 72 70 68 20 20 69 66 20  h in lMorph  if 
90f0: 72 65 2e 73 65 61 72 63 68 28 73 50 61 74 74 65  re.search(sPatte
9100: 72 6e 2c 20 73 4d 6f 72 70 68 29 20 5d 0a 20 20  rn, sMorph) ].  
9110: 20 20 69 66 20 6c 53 65 6c 65 63 74 3a 0a 20 20    if lSelect:.  
9120: 20 20 20 20 20 20 69 66 20 6c 65 6e 28 6c 53 65        if len(lSe
9130: 6c 65 63 74 29 20 21 3d 20 6c 65 6e 28 6c 4d 6f  lect) != len(lMo
9140: 72 70 68 29 3a 0a 20 20 20 20 20 20 20 20 20 20  rph):.          
9150: 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68    dToken["lMorph
9160: 22 5d 20 3d 20 6c 53 65 6c 65 63 74 0a 20 20 20  "] = lSelect.   
9170: 20 65 6c 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a   elif lDefault:.
9180: 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22          dToken["
9190: 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 44 65 66 61  lMorph"] = lDefa
91a0: 75 6c 74 0a 20 20 20 20 23 70 72 69 6e 74 28 22  ult.    #print("
91b0: 44 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56  DA:", dToken["sV
91c0: 61 6c 75 65 22 5d 2c 20 64 54 6f 6b 65 6e 5b 22  alue"], dToken["
91d0: 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20 20 72 65  lMorph"]).    re
91e0: 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20  turn True...def 
91f0: 67 5f 65 78 63 6c 75 64 65 20 28 64 54 6f 6b 65  g_exclude (dToke
9200: 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20 6c 44 65  n, sPattern, lDe
9210: 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20  fault=None):.   
9220: 20 22 73 65 6c 65 63 74 20 6d 6f 72 70 68 6f 6c   "select morphol
9230: 6f 67 69 65 73 20 66 6f 72 20 3c 64 54 6f 6b 65  ogies for <dToke
9240: 6e 3e 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20  n> according to 
9250: 3c 73 50 61 74 74 65 72 6e 3e 2c 20 61 6c 77 61  <sPattern>, alwa
9260: 79 73 20 72 65 74 75 72 6e 20 54 72 75 65 22 0a  ys return True".
9270: 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 64 54 6f      lMorph = dTo
9280: 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 20 69  ken["lMorph"]  i
9290: 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64 54  f "lMorph" in dT
92a0: 6f 6b 65 6e 20 20 65 6c 73 65 20 5f 6f 53 70 65  oken  else _oSpe
92b0: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72  llChecker.getMor
92c0: 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ph(dToken["sValu
92d0: 65 22 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  e"]).    if not 
92e0: 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e 28 6c 4d  lMorph or len(lM
92f0: 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20 20 20 20  orph) == 1:.    
9300: 20 20 20 20 69 66 20 6c 44 65 66 61 75 6c 74 3a      if lDefault:
9310: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 54 6f  .            dTo
9320: 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20  ken["lMorph"] = 
9330: 6c 44 65 66 61 75 6c 74 0a 20 20 20 20 20 20 20  lDefault.       
9340: 20 20 20 20 20 23 70 72 69 6e 74 28 22 44 41 3a       #print("DA:
9350: 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  ", dToken["sValu
9360: 65 22 5d 2c 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f  e"], dToken["lMo
9370: 72 70 68 22 5d 29 0a 20 20 20 20 20 20 20 20 72  rph"]).        r
9380: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 6c  eturn True.    l
9390: 53 65 6c 65 63 74 20 3d 20 5b 20 73 4d 6f 72 70  Select = [ sMorp
93a0: 68 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  h  for sMorph in
93b0: 20 6c 4d 6f 72 70 68 20 20 69 66 20 6e 6f 74 20   lMorph  if not 
93c0: 72 65 2e 73 65 61 72 63 68 28 73 50 61 74 74 65  re.search(sPatte
93d0: 72 6e 2c 20 73 4d 6f 72 70 68 29 20 5d 0a 20 20  rn, sMorph) ].  
93e0: 20 20 69 66 20 6c 53 65 6c 65 63 74 3a 0a 20 20    if lSelect:.  
93f0: 20 20 20 20 20 20 69 66 20 6c 65 6e 28 6c 53 65        if len(lSe
9400: 6c 65 63 74 29 20 21 3d 20 6c 65 6e 28 6c 4d 6f  lect) != len(lMo
9410: 72 70 68 29 3a 0a 20 20 20 20 20 20 20 20 20 20  rph):.          
9420: 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68    dToken["lMorph
9430: 22 5d 20 3d 20 6c 53 65 6c 65 63 74 0a 20 20 20  "] = lSelect.   
9440: 20 65 6c 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a   elif lDefault:.
9450: 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22          dToken["
9460: 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 44 65 66 61  lMorph"] = lDefa
9470: 75 6c 74 0a 20 20 20 20 23 70 72 69 6e 74 28 22  ult.    #print("
9480: 44 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56  DA:", dToken["sV
9490: 61 6c 75 65 22 5d 2c 20 64 54 6f 6b 65 6e 5b 22  alue"], dToken["
94a0: 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20 20 72 65  lMorph"]).    re
94b0: 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20  turn True...def 
94c0: 67 5f 64 65 66 69 6e 65 20 28 64 54 6f 6b 65 6e  g_define (dToken
94d0: 2c 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 22  , lMorph):.    "
94e0: 73 65 74 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73  set morphologies
94f0: 20 6f 66 20 3c 64 54 6f 6b 65 6e 3e 2c 20 61 6c   of <dToken>, al
9500: 77 61 79 73 20 72 65 74 75 72 6e 20 54 72 75 65  ways return True
9510: 22 0a 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d  ".    dToken["lM
9520: 6f 72 70 68 22 5d 20 3d 20 6c 4d 6f 72 70 68 0a  orph"] = lMorph.
9530: 20 20 20 20 23 70 72 69 6e 74 28 22 44 41 3a 22      #print("DA:"
9540: 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65  , dToken["sValue
9550: 22 5d 2c 20 6c 4d 6f 72 70 68 29 0a 20 20 20 20  "], lMorph).    
9560: 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 23 23  return True...##
9570: 23 23 20 43 41 4c 4c 41 42 4c 45 53 20 46 4f 52  ## CALLABLES FOR
9580: 20 52 45 47 45 58 20 52 55 4c 45 53 20 28 67 65   REGEX RULES (ge
9590: 6e 65 72 61 74 65 64 20 63 6f 64 65 29 0a 0a 24  nerated code)..$
95a0: 7b 63 61 6c 6c 61 62 6c 65 73 7d 0a 0a 0a 23 23  {callables}...##
95b0: 23 23 20 43 41 4c 4c 41 42 4c 45 53 20 46 4f 52  ## CALLABLES FOR
95c0: 20 47 52 41 50 48 20 52 55 4c 45 53 20 28 67 65   GRAPH RULES (ge
95d0: 6e 65 72 61 74 65 64 20 63 6f 64 65 29 0a 0a 24  nerated code)..$
95e0: 7b 67 72 61 70 68 5f 63 61 6c 6c 61 62 6c 65 73  {graph_callables
95f0: 7d 0a                                            }.