Grammalecte  Hex Artifact Content

Artifact f48195d4395d88c9db6aa05bec1ae4f095524227ff8491c95842fb4d6d267f54:


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: 44 41 20 3d 20 7b 7d 20 20 20 20 20 20 20 20 23  DA = {}        #
0ca0: 20 44 69 73 61 6d 62 69 67 75 69 73 61 74 6f 72   Disambiguisator
0cb0: 2e 20 4b 65 79 20 3d 20 70 6f 73 69 74 69 6f 6e  . Key = position
0cc0: 3b 20 76 61 6c 75 65 20 3d 20 6c 69 73 74 20 6f  ; value = list o
0cd0: 66 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 0a 20  f morphologies. 
0ce0: 20 20 20 64 50 72 69 6f 72 69 74 79 20 3d 20 7b     dPriority = {
0cf0: 7d 20 20 23 20 4b 65 79 20 3d 20 70 6f 73 69 74  }  # Key = posit
0d00: 69 6f 6e 3b 20 76 61 6c 75 65 20 3d 20 70 72 69  ion; value = pri
0d10: 6f 72 69 74 79 0a 20 20 20 20 64 4f 70 74 20 3d  ority.    dOpt =
0d20: 20 5f 64 4f 70 74 69 6f 6e 73 20 20 69 66 20 6e   _dOptions  if n
0d30: 6f 74 20 64 4f 70 74 69 6f 6e 73 20 20 65 6c 73  ot dOptions  els
0d40: 65 20 64 4f 70 74 69 6f 6e 73 0a 20 20 20 20 62  e dOptions.    b
0d50: 53 68 6f 77 52 75 6c 65 49 64 20 3d 20 6f 70 74  ShowRuleId = opt
0d60: 69 6f 6e 28 27 69 64 72 75 6c 65 27 29 0a 0a 20  ion('idrule').. 
0d70: 20 20 20 23 20 70 61 72 73 65 20 70 61 72 61 67     # parse parag
0d80: 72 61 70 68 0a 20 20 20 20 74 72 79 3a 0a 20 20  raph.    try:.  
0d90: 20 20 20 20 20 20 73 4e 65 77 2c 20 61 45 72 72        sNew, aErr
0da0: 6f 72 73 20 3d 20 5f 70 72 6f 6f 66 72 65 61 64  ors = _proofread
0db0: 28 4e 6f 6e 65 2c 20 73 54 65 78 74 2c 20 73 52  (None, sText, sR
0dc0: 65 61 6c 54 65 78 74 2c 20 30 2c 20 54 72 75 65  ealText, 0, True
0dd0: 2c 20 64 44 41 2c 20 64 50 72 69 6f 72 69 74 79  , dDA, dPriority
0de0: 2c 20 73 43 6f 75 6e 74 72 79 2c 20 64 4f 70 74  , sCountry, dOpt
0df0: 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62  , bShowRuleId, b
0e00: 44 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74 29  Debug, bContext)
0e10: 0a 20 20 20 20 20 20 20 20 69 66 20 73 4e 65 77  .        if sNew
0e20: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 54  :.            sT
0e30: 65 78 74 20 3d 20 73 4e 65 77 0a 20 20 20 20 65  ext = sNew.    e
0e40: 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 72  xcept:.        r
0e50: 61 69 73 65 0a 0a 20 20 20 20 23 20 63 6c 65 61  aise..    # clea
0e60: 6e 75 70 0a 20 20 20 20 69 66 20 22 c2 a0 22 20  nup.    if ".." 
0e70: 69 6e 20 73 54 65 78 74 3a 0a 20 20 20 20 20 20  in sText:.      
0e80: 20 20 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e    sText = sText.
0e90: 72 65 70 6c 61 63 65 28 22 c2 a0 22 2c 20 27 20  replace("..", ' 
0ea0: 27 29 20 23 20 6e 62 73 70 0a 20 20 20 20 69 66  ') # nbsp.    if
0eb0: 20 22 e2 80 af 22 20 69 6e 20 73 54 65 78 74 3a   "..." in sText:
0ec0: 0a 20 20 20 20 20 20 20 20 73 54 65 78 74 20 3d  .        sText =
0ed0: 20 73 54 65 78 74 2e 72 65 70 6c 61 63 65 28 22   sText.replace("
0ee0: e2 80 af 22 2c 20 27 20 27 29 20 23 20 6e 6e 62  ...", ' ') # nnb
0ef0: 73 70 0a 20 20 20 20 69 66 20 22 27 22 20 69 6e  sp.    if "'" in
0f00: 20 73 54 65 78 74 3a 0a 20 20 20 20 20 20 20 20   sText:.        
0f10: 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e 72 65  sText = sText.re
0f20: 70 6c 61 63 65 28 22 27 22 2c 20 22 e2 80 99 22  place("'", "..."
0f30: 29 0a 20 20 20 20 69 66 20 22 e2 80 91 22 20 69  ).    if "..." i
0f40: 6e 20 73 54 65 78 74 3a 0a 20 20 20 20 20 20 20  n sText:.       
0f50: 20 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e 72   sText = sText.r
0f60: 65 70 6c 61 63 65 28 22 e2 80 91 22 2c 20 22 2d  eplace("...", "-
0f70: 22 29 20 23 20 6e 6f 62 72 65 61 6b 64 61 73 68  ") # nobreakdash
0f80: 0a 0a 20 20 20 20 23 20 70 61 72 73 65 20 73 65  ..    # parse se
0f90: 6e 74 65 6e 63 65 73 0a 20 20 20 20 66 6f 72 20  ntences.    for 
0fa0: 69 53 74 61 72 74 2c 20 69 45 6e 64 20 69 6e 20  iStart, iEnd in 
0fb0: 5f 67 65 74 53 65 6e 74 65 6e 63 65 42 6f 75 6e  _getSentenceBoun
0fc0: 64 61 72 69 65 73 28 73 54 65 78 74 29 3a 0a 20  daries(sText):. 
0fd0: 20 20 20 20 20 20 20 69 66 20 34 20 3c 20 28 69         if 4 < (i
0fe0: 45 6e 64 20 2d 20 69 53 74 61 72 74 29 20 3c 20  End - iStart) < 
0ff0: 32 30 30 30 3a 0a 20 20 20 20 20 20 20 20 20 20  2000:.          
1000: 20 20 64 44 41 2e 63 6c 65 61 72 28 29 0a 20 20    dDA.clear().  
1010: 20 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20            try:. 
1020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6f                 o
1030: 53 65 6e 74 65 6e 63 65 20 3d 20 54 6f 6b 65 6e  Sentence = Token
1040: 53 65 6e 74 65 6e 63 65 28 73 54 65 78 74 5b 69  Sentence(sText[i
1050: 53 74 61 72 74 3a 69 45 6e 64 5d 2c 20 73 52 65  Start:iEnd], sRe
1060: 61 6c 54 65 78 74 5b 69 53 74 61 72 74 3a 69 45  alText[iStart:iE
1070: 6e 64 5d 2c 20 69 53 74 61 72 74 29 0a 20 20 20  nd], iStart).   
1080: 20 20 20 20 20 20 20 20 20 20 20 20 20 5f 2c 20               _, 
1090: 65 72 72 73 20 3d 20 5f 70 72 6f 6f 66 72 65 61  errs = _proofrea
10a0: 64 28 6f 53 65 6e 74 65 6e 63 65 2c 20 73 54 65  d(oSentence, sTe
10b0: 78 74 5b 69 53 74 61 72 74 3a 69 45 6e 64 5d 2c  xt[iStart:iEnd],
10c0: 20 73 52 65 61 6c 54 65 78 74 5b 69 53 74 61 72   sRealText[iStar
10d0: 74 3a 69 45 6e 64 5d 2c 20 69 53 74 61 72 74 2c  t:iEnd], iStart,
10e0: 20 46 61 6c 73 65 2c 20 64 44 41 2c 20 64 50 72   False, dDA, dPr
10f0: 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e 74 72 79  iority, sCountry
1100: 2c 20 64 4f 70 74 2c 20 62 53 68 6f 77 52 75 6c  , dOpt, bShowRul
1110: 65 49 64 2c 20 62 44 65 62 75 67 2c 20 62 43 6f  eId, bDebug, bCo
1120: 6e 74 65 78 74 29 0a 20 20 20 20 20 20 20 20 20  ntext).         
1130: 20 20 20 20 20 20 20 61 45 72 72 6f 72 73 2e 75         aErrors.u
1140: 70 64 61 74 65 28 65 72 72 73 29 0a 20 20 20 20  pdate(errs).    
1150: 20 20 20 20 20 20 20 20 65 78 63 65 70 74 3a 0a          except:.
1160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1170: 72 61 69 73 65 0a 20 20 20 20 72 65 74 75 72 6e  raise.    return
1180: 20 61 45 72 72 6f 72 73 2e 76 61 6c 75 65 73 28   aErrors.values(
1190: 29 20 23 20 74 68 69 73 20 69 73 20 61 20 76 69  ) # this is a vi
11a0: 65 77 20 28 69 74 65 72 61 62 6c 65 29 0a 0a 0a  ew (iterable)...
11b0: 5f 7a 45 6e 64 4f 66 53 65 6e 74 65 6e 63 65 20  _zEndOfSentence 
11c0: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72 27 28  = re.compile(r'(
11d0: 5b 2e 3f 21 3a 3b e2 80 a6 5d 5b 20 2e 3f 21 e2  [.?!:;...][ .?!.
11e0: 80 a6 20 c2 bb e2 80 9d 22 29 5d 2a 7c 2e 24 29  .. .....")]*|.$)
11f0: 27 29 0a 5f 7a 42 65 67 69 6e 4f 66 50 61 72 61  ')._zBeginOfPara
1200: 67 72 61 70 68 20 3d 20 72 65 2e 63 6f 6d 70 69  graph = re.compi
1210: 6c 65 28 72 22 5e 5c 57 2a 22 29 0a 5f 7a 45 6e  le(r"^\W*")._zEn
1220: 64 4f 66 50 61 72 61 67 72 61 70 68 20 3d 20 72  dOfParagraph = r
1230: 65 2e 63 6f 6d 70 69 6c 65 28 72 22 5c 57 2a 24  e.compile(r"\W*$
1240: 22 29 0a 0a 64 65 66 20 5f 67 65 74 53 65 6e 74  ")..def _getSent
1250: 65 6e 63 65 42 6f 75 6e 64 61 72 69 65 73 20 28  enceBoundaries (
1260: 73 54 65 78 74 29 3a 0a 20 20 20 20 69 53 74 61  sText):.    iSta
1270: 72 74 20 3d 20 5f 7a 42 65 67 69 6e 4f 66 50 61  rt = _zBeginOfPa
1280: 72 61 67 72 61 70 68 2e 6d 61 74 63 68 28 73 54  ragraph.match(sT
1290: 65 78 74 29 2e 65 6e 64 28 29 0a 20 20 20 20 66  ext).end().    f
12a0: 6f 72 20 6d 20 69 6e 20 5f 7a 45 6e 64 4f 66 53  or m in _zEndOfS
12b0: 65 6e 74 65 6e 63 65 2e 66 69 6e 64 69 74 65 72  entence.finditer
12c0: 28 73 54 65 78 74 29 3a 0a 20 20 20 20 20 20 20  (sText):.       
12d0: 20 79 69 65 6c 64 20 28 69 53 74 61 72 74 2c 20   yield (iStart, 
12e0: 6d 2e 65 6e 64 28 29 29 0a 20 20 20 20 20 20 20  m.end()).       
12f0: 20 69 53 74 61 72 74 20 3d 20 6d 2e 65 6e 64 28   iStart = m.end(
1300: 29 0a 0a 0a 64 65 66 20 5f 70 72 6f 6f 66 72 65  )...def _proofre
1310: 61 64 20 28 6f 53 65 6e 74 65 6e 63 65 2c 20 73  ad (oSentence, s
1320: 2c 20 73 78 2c 20 6e 4f 66 66 73 65 74 2c 20 62  , sx, nOffset, b
1330: 50 61 72 61 67 72 61 70 68 2c 20 64 44 41 2c 20  Paragraph, dDA, 
1340: 64 50 72 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e  dPriority, sCoun
1350: 74 72 79 2c 20 64 4f 70 74 69 6f 6e 73 2c 20 62  try, dOptions, b
1360: 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 44 65 62  ShowRuleId, bDeb
1370: 75 67 2c 20 62 43 6f 6e 74 65 78 74 29 3a 0a 20  ug, bContext):. 
1380: 20 20 20 64 45 72 72 73 20 3d 20 7b 7d 0a 20 20     dErrs = {}.  
1390: 20 20 62 50 61 72 61 67 72 61 70 68 43 68 61 6e    bParagraphChan
13a0: 67 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 62  ge = False.    b
13b0: 53 65 6e 74 65 6e 63 65 43 68 61 6e 67 65 20 3d  SentenceChange =
13c0: 20 46 61 6c 73 65 0a 20 20 20 20 66 6f 72 20 73   False.    for s
13d0: 4f 70 74 69 6f 6e 2c 20 6c 52 75 6c 65 47 72 6f  Option, lRuleGro
13e0: 75 70 20 69 6e 20 5f 67 65 74 52 75 6c 65 73 28  up in _getRules(
13f0: 62 50 61 72 61 67 72 61 70 68 29 3a 0a 20 20 20  bParagraph):.   
1400: 20 20 20 20 20 69 66 20 73 4f 70 74 69 6f 6e 20       if sOption 
1410: 3d 3d 20 22 40 40 40 40 22 3a 0a 20 20 20 20 20  == "@@@@":.     
1420: 20 20 20 20 20 20 20 23 20 67 72 61 70 68 20 72         # graph r
1430: 75 6c 65 73 0a 20 20 20 20 20 20 20 20 20 20 20  ules.           
1440: 20 69 66 20 6e 6f 74 20 62 50 61 72 61 67 72 61   if not bParagra
1450: 70 68 20 61 6e 64 20 62 53 65 6e 74 65 6e 63 65  ph and bSentence
1460: 43 68 61 6e 67 65 3a 0a 20 20 20 20 20 20 20 20  Change:.        
1470: 20 20 20 20 20 20 20 20 6f 53 65 6e 74 65 6e 63          oSentenc
1480: 65 2e 75 70 64 61 74 65 28 73 29 0a 20 20 20 20  e.update(s).    
1490: 20 20 20 20 20 20 20 20 20 20 20 20 62 53 65 6e              bSen
14a0: 74 65 6e 63 65 43 68 61 6e 67 65 20 3d 20 46 61  tenceChange = Fa
14b0: 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  lse.            
14c0: 66 6f 72 20 73 47 72 61 70 68 4e 61 6d 65 2c 20  for sGraphName, 
14d0: 73 4c 69 6e 65 49 64 20 69 6e 20 6c 52 75 6c 65  sLineId in lRule
14e0: 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20  Group:.         
14f0: 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67         if bDebug
1500: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1510: 20 20 20 20 20 20 70 72 69 6e 74 28 73 47 72 61        print(sGra
1520: 70 68 4e 61 6d 65 2c 20 73 4c 69 6e 65 49 64 29  phName, sLineId)
1530: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1540: 20 62 50 61 72 61 67 72 61 70 68 43 68 61 6e 67   bParagraphChang
1550: 65 2c 20 65 72 72 73 20 3d 20 6f 53 65 6e 74 65  e, errs = oSente
1560: 6e 63 65 2e 70 61 72 73 65 28 64 41 6c 6c 47 72  nce.parse(dAllGr
1570: 61 70 68 5b 73 47 72 61 70 68 4e 61 6d 65 5d 2c  aph[sGraphName],
1580: 20 64 50 72 69 6f 72 69 74 79 2c 20 73 43 6f 75   dPriority, sCou
1590: 6e 74 72 79 2c 20 64 4f 70 74 69 6f 6e 73 2c 20  ntry, dOptions, 
15a0: 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 44 65  bShowRuleId, bDe
15b0: 62 75 67 2c 20 62 43 6f 6e 74 65 78 74 29 0a 20  bug, bContext). 
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
15d0: 45 72 72 73 2e 75 70 64 61 74 65 28 65 72 72 73  Errs.update(errs
15e0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
15f0: 20 20 69 66 20 62 50 61 72 61 67 72 61 70 68 43    if bParagraphC
1600: 68 61 6e 67 65 3a 0a 20 20 20 20 20 20 20 20 20  hange:.         
1610: 20 20 20 20 20 20 20 20 20 20 20 73 20 3d 20 6f             s = o
1620: 53 65 6e 74 65 6e 63 65 2e 72 65 77 72 69 74 65  Sentence.rewrite
1630: 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ().             
1640: 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67         if bDebug
1650: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1660: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
1670: 22 7e 22 2c 20 6f 53 65 6e 74 65 6e 63 65 2e 73  "~", oSentence.s
1680: 53 65 6e 74 65 6e 63 65 29 0a 20 20 20 20 20 20  Sentence).      
1690: 20 20 65 6c 69 66 20 6e 6f 74 20 73 4f 70 74 69    elif not sOpti
16a0: 6f 6e 20 6f 72 20 64 4f 70 74 69 6f 6e 73 2e 67  on or dOptions.g
16b0: 65 74 28 73 4f 70 74 69 6f 6e 2c 20 46 61 6c 73  et(sOption, Fals
16c0: 65 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  e):.            
16d0: 23 20 72 65 67 65 78 20 72 75 6c 65 73 0a 20 20  # regex rules.  
16e0: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 7a 52            for zR
16f0: 65 67 65 78 2c 20 62 55 70 70 65 72 63 61 73 65  egex, bUppercase
1700: 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65  , sLineId, sRule
1710: 49 64 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 6c  Id, nPriority, l
1720: 41 63 74 69 6f 6e 73 20 69 6e 20 6c 52 75 6c 65  Actions in lRule
1730: 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20  Group:.         
1740: 20 20 20 20 20 20 20 69 66 20 73 52 75 6c 65 49         if sRuleI
1750: 64 20 6e 6f 74 20 69 6e 20 5f 61 49 67 6e 6f 72  d not in _aIgnor
1760: 65 64 52 75 6c 65 73 3a 0a 20 20 20 20 20 20 20  edRules:.       
1770: 20 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72               for
1780: 20 6d 20 69 6e 20 7a 52 65 67 65 78 2e 66 69 6e   m in zRegex.fin
1790: 64 69 74 65 72 28 73 29 3a 0a 20 20 20 20 20 20  diter(s):.      
17a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17b0: 20 20 62 43 6f 6e 64 4d 65 6d 6f 20 3d 20 4e 6f    bCondMemo = No
17c0: 6e 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ne.             
17d0: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 73             for s
17e0: 46 75 6e 63 43 6f 6e 64 2c 20 63 41 63 74 69 6f  FuncCond, cActio
17f0: 6e 54 79 70 65 2c 20 73 57 68 61 74 2c 20 2a 65  nType, sWhat, *e
1800: 41 63 74 20 69 6e 20 6c 41 63 74 69 6f 6e 73 3a  Act in lActions:
1810: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1820: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61               # a
1830: 63 74 69 6f 6e 20 69 6e 20 6c 41 63 74 69 6f 6e  ction in lAction
1840: 73 3a 20 5b 20 63 6f 6e 64 69 74 69 6f 6e 2c 20  s: [ condition, 
1850: 61 63 74 69 6f 6e 20 74 79 70 65 2c 20 72 65 70  action type, rep
1860: 6c 61 63 65 6d 65 6e 74 2f 73 75 67 67 65 73 74  lacement/suggest
1870: 69 6f 6e 2f 61 63 74 69 6f 6e 5b 2c 20 69 47 72  ion/action[, iGr
1880: 6f 75 70 5b 2c 20 6d 65 73 73 61 67 65 2c 20 55  oup[, message, U
1890: 52 4c 5d 5d 20 5d 0a 20 20 20 20 20 20 20 20 20  RL]] ].         
18a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18b0: 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20     try:.        
18c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18d0: 20 20 20 20 20 20 20 20 62 43 6f 6e 64 4d 65 6d          bCondMem
18e0: 6f 20 3d 20 6e 6f 74 20 73 46 75 6e 63 43 6f 6e  o = not sFuncCon
18f0: 64 20 6f 72 20 67 6c 6f 62 61 6c 73 28 29 5b 73  d or globals()[s
1900: 46 75 6e 63 43 6f 6e 64 5d 28 73 2c 20 73 78 2c  FuncCond](s, sx,
1910: 20 6d 2c 20 64 44 41 2c 20 73 43 6f 75 6e 74 72   m, dDA, sCountr
1920: 79 2c 20 62 43 6f 6e 64 4d 65 6d 6f 29 0a 20 20  y, bCondMemo).  
1930: 20 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 69 66                if
1950: 20 62 43 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20   bCondMemo:.    
1960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1980: 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d  if cActionType =
1990: 3d 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 20  = "-":.         
19a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
19c0: 20 67 72 61 6d 6d 61 72 20 65 72 72 6f 72 0a 20   grammar error. 
19d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19f0: 20 20 20 20 20 20 20 6e 45 72 72 6f 72 53 74 61         nErrorSta
1a00: 72 74 20 3d 20 6e 4f 66 66 73 65 74 20 2b 20 6d  rt = nOffset + m
1a10: 2e 73 74 61 72 74 28 65 41 63 74 5b 30 5d 29 0a  .start(eAct[0]).
1a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a40: 20 20 20 20 20 20 20 20 69 66 20 6e 45 72 72 6f          if nErro
1a50: 72 53 74 61 72 74 20 6e 6f 74 20 69 6e 20 64 45  rStart not in dE
1a60: 72 72 73 20 6f 72 20 6e 50 72 69 6f 72 69 74 79  rrs or nPriority
1a70: 20 3e 20 64 50 72 69 6f 72 69 74 79 5b 6e 45 72   > dPriority[nEr
1a80: 72 6f 72 53 74 61 72 74 5d 3a 0a 20 20 20 20 20  rorStart]:.     
1a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ab0: 20 20 20 20 20 20 20 64 45 72 72 73 5b 6e 45 72         dErrs[nEr
1ac0: 72 6f 72 53 74 61 72 74 5d 20 3d 20 5f 63 72 65  rorStart] = _cre
1ad0: 61 74 65 52 65 67 65 78 45 72 72 6f 72 28 73 2c  ateRegexError(s,
1ae0: 20 73 78 2c 20 73 57 68 61 74 2c 20 6e 4f 66 66   sx, sWhat, nOff
1af0: 73 65 74 2c 20 6d 2c 20 65 41 63 74 5b 30 5d 2c  set, m, eAct[0],
1b00: 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49   sLineId, sRuleI
1b10: 64 2c 20 62 55 70 70 65 72 63 61 73 65 2c 20 65  d, bUppercase, e
1b20: 41 63 74 5b 31 5d 2c 20 65 41 63 74 5b 32 5d 2c  Act[1], eAct[2],
1b30: 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 73 4f   bShowRuleId, sO
1b40: 70 74 69 6f 6e 2c 20 62 43 6f 6e 74 65 78 74 29  ption, bContext)
1b50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 50 72               dPr
1b80: 69 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53 74 61  iority[nErrorSta
1b90: 72 74 5d 20 3d 20 6e 50 72 69 6f 72 69 74 79 0a  rt] = nPriority.
1ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bc0: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
1bd0: 54 79 70 65 20 3d 3d 20 22 7e 22 3a 0a 20 20 20  Type == "~":.   
1be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c00: 20 20 20 20 20 23 20 74 65 78 74 20 70 72 6f 63       # text proc
1c10: 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20 20 20  essor.          
1c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 20                s 
1c40: 3d 20 5f 72 65 77 72 69 74 65 28 73 2c 20 73 57  = _rewrite(s, sW
1c50: 68 61 74 2c 20 65 41 63 74 5b 30 5d 2c 20 6d 2c  hat, eAct[0], m,
1c60: 20 62 55 70 70 65 72 63 61 73 65 29 0a 20 20 20   bUppercase).   
1c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c90: 20 20 20 20 20 62 50 61 72 61 67 72 61 70 68 43       bParagraphC
1ca0: 68 61 6e 67 65 20 3d 20 54 72 75 65 0a 20 20 20  hange = True.   
1cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cd0: 20 20 20 20 20 62 53 65 6e 74 65 6e 63 65 43 68       bSentenceCh
1ce0: 61 6e 67 65 20 3d 20 54 72 75 65 0a 20 20 20 20  ange = True.    
1cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d10: 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20      if bDebug:. 
1d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d40: 20 20 20 20 20 20 20 20 20 20 20 65 63 68 6f 28             echo(
1d50: 22 7e 20 22 20 2b 20 73 20 2b 20 22 20 20 2d 2d  "~ " + s + "  --
1d60: 20 22 20 2b 20 6d 2e 67 72 6f 75 70 28 65 41 63   " + m.group(eAc
1d70: 74 5b 30 5d 29 20 2b 20 22 20 20 23 20 22 20 2b  t[0]) + "  # " +
1d80: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
1db0: 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d  if cActionType =
1dc0: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20  = "=":.         
1dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
1df0: 20 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 0a   disambiguation.
1e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
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 67 6c 6f 62 61 6c 73 28          globals(
1e30: 29 5b 73 57 68 61 74 5d 28 73 2c 20 6d 2c 20 64  )[sWhat](s, m, d
1e40: 44 41 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  DA).            
1e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e60: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
1e70: 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20  Debug:.         
1e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ea0: 20 20 20 65 63 68 6f 28 22 3d 20 22 20 2b 20 6d     echo("= " + m
1eb0: 2e 67 72 6f 75 70 28 30 29 20 2b 20 22 20 20 23  .group(0) + "  #
1ec0: 20 22 20 2b 20 73 4c 69 6e 65 49 64 20 2b 20 22   " + sLineId + "
1ed0: 5c 6e 44 41 3a 20 22 20 2b 20 73 74 72 28 64 44  \nDA: " + str(dD
1ee0: 41 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  A)).            
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 65 6c 69 66 20 63 41 63          elif cAc
1f10: 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 3e 22 3a  tionType == ">":
1f20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
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 23 20 77 65 20 64 6f           # we do
1f50: 20 6e 6f 74 68 69 6e 67 2c 20 74 68 69 73 20 74   nothing, this t
1f60: 65 73 74 20 69 73 20 6a 75 73 74 20 61 20 63 6f  est is just a co
1f70: 6e 64 69 74 69 6f 6e 20 74 6f 20 61 70 70 6c 79  ndition to apply
1f80: 20 61 6c 6c 20 66 6f 6c 6c 6f 77 69 6e 67 20 61   all following a
1f90: 63 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 20  ctions.         
1fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
1fc0: 61 73 73 0a 20 20 20 20 20 20 20 20 20 20 20 20  ass.            
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 65 6c 73 65 3a 0a 20 20          else:.  
1ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2010: 20 20 20 20 20 20 65 63 68 6f 28 22 23 20 65 72        echo("# er
2020: 72 6f 72 3a 20 75 6e 6b 6e 6f 77 6e 20 61 63 74  ror: unknown act
2030: 69 6f 6e 20 61 74 20 22 20 2b 20 73 4c 69 6e 65  ion at " + sLine
2040: 49 64 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  Id).            
2050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2060: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
2070: 54 79 70 65 20 3d 3d 20 22 3e 22 3a 0a 20 20 20  Type == ">":.   
2080: 20 20 20 20 20 20 20 20 20 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 62 72 65 61 6b 0a 20 20 20 20 20 20 20 20 20   break.         
20b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20c0: 20 20 20 65 78 63 65 70 74 20 45 78 63 65 70 74     except Except
20d0: 69 6f 6e 20 61 73 20 65 3a 0a 20 20 20 20 20 20  ion as e:.      
20e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20f0: 20 20 20 20 20 20 20 20 20 20 72 61 69 73 65 20            raise 
2100: 45 78 63 65 70 74 69 6f 6e 28 73 74 72 28 65 29  Exception(str(e)
2110: 2c 20 22 23 20 22 20 2b 20 73 4c 69 6e 65 49 64  , "# " + sLineId
2120: 20 2b 20 22 20 23 20 22 20 2b 20 73 52 75 6c 65   + " # " + sRule
2130: 49 64 29 0a 20 20 20 20 69 66 20 62 50 61 72 61  Id).    if bPara
2140: 67 72 61 70 68 43 68 61 6e 67 65 3a 0a 20 20 20  graphChange:.   
2150: 20 20 20 20 20 72 65 74 75 72 6e 20 28 73 2c 20       return (s, 
2160: 64 45 72 72 73 29 0a 20 20 20 20 72 65 74 75 72  dErrs).    retur
2170: 6e 20 28 46 61 6c 73 65 2c 20 64 45 72 72 73 29  n (False, dErrs)
2180: 0a 0a 0a 64 65 66 20 5f 63 72 65 61 74 65 52 65  ...def _createRe
2190: 67 65 78 57 72 69 74 65 72 45 72 72 6f 72 20 28  gexWriterError (
21a0: 73 2c 20 73 78 2c 20 73 52 65 70 6c 2c 20 6e 4f  s, sx, sRepl, nO
21b0: 66 66 73 65 74 2c 20 6d 2c 20 69 47 72 6f 75 70  ffset, m, iGroup
21c0: 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65  , sLineId, sRule
21d0: 49 64 2c 20 62 55 70 70 65 72 63 61 73 65 2c 20  Id, bUppercase, 
21e0: 73 4d 73 67 2c 20 73 55 52 4c 2c 20 62 53 68 6f  sMsg, sURL, bSho
21f0: 77 52 75 6c 65 49 64 2c 20 73 4f 70 74 69 6f 6e  wRuleId, sOption
2200: 2c 20 62 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20  , bContext):.   
2210: 20 22 65 72 72 6f 72 20 66 6f 72 20 57 72 69 74   "error for Writ
2220: 65 72 20 28 4c 4f 2f 4f 4f 29 22 0a 20 20 20 20  er (LO/OO)".    
2230: 78 45 72 72 20 3d 20 53 69 6e 67 6c 65 50 72 6f  xErr = SinglePro
2240: 6f 66 72 65 61 64 69 6e 67 45 72 72 6f 72 28 29  ofreadingError()
2250: 0a 20 20 20 20 23 78 45 72 72 20 3d 20 75 6e 6f  .    #xErr = uno
2260: 2e 63 72 65 61 74 65 55 6e 6f 53 74 72 75 63 74  .createUnoStruct
2270: 28 20 22 63 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e  ( "com.sun.star.
2280: 6c 69 6e 67 75 69 73 74 69 63 32 2e 53 69 6e 67  linguistic2.Sing
2290: 6c 65 50 72 6f 6f 66 72 65 61 64 69 6e 67 45 72  leProofreadingEr
22a0: 72 6f 72 22 20 29 0a 20 20 20 20 78 45 72 72 2e  ror" ).    xErr.
22b0: 6e 45 72 72 6f 72 53 74 61 72 74 20 3d 20 6e 4f  nErrorStart = nO
22c0: 66 66 73 65 74 20 2b 20 6d 2e 73 74 61 72 74 28  ffset + m.start(
22d0: 69 47 72 6f 75 70 29 0a 20 20 20 20 78 45 72 72  iGroup).    xErr
22e0: 2e 6e 45 72 72 6f 72 4c 65 6e 67 74 68 20 3d 20  .nErrorLength = 
22f0: 6d 2e 65 6e 64 28 69 47 72 6f 75 70 29 20 2d 20  m.end(iGroup) - 
2300: 6d 2e 73 74 61 72 74 28 69 47 72 6f 75 70 29 0a  m.start(iGroup).
2310: 20 20 20 20 78 45 72 72 2e 6e 45 72 72 6f 72 54      xErr.nErrorT
2320: 79 70 65 20 3d 20 50 52 4f 4f 46 52 45 41 44 49  ype = PROOFREADI
2330: 4e 47 0a 20 20 20 20 78 45 72 72 2e 61 52 75 6c  NG.    xErr.aRul
2340: 65 49 64 65 6e 74 69 66 69 65 72 20 3d 20 73 52  eIdentifier = sR
2350: 75 6c 65 49 64 0a 20 20 20 20 23 20 73 75 67 67  uleId.    # sugg
2360: 65 73 74 69 6f 6e 73 0a 20 20 20 20 69 66 20 73  estions.    if s
2370: 52 65 70 6c 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22  Repl[0:1] == "="
2380: 3a 0a 20 20 20 20 20 20 20 20 73 75 67 67 20 3d  :.        sugg =
2390: 20 67 6c 6f 62 61 6c 73 28 29 5b 73 52 65 70 6c   globals()[sRepl
23a0: 5b 31 3a 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20  [1:]](s, m).    
23b0: 20 20 20 20 69 66 20 73 75 67 67 3a 0a 20 20 20      if sugg:.   
23c0: 20 20 20 20 20 20 20 20 20 69 66 20 62 55 70 70           if bUpp
23d0: 65 72 63 61 73 65 20 61 6e 64 20 6d 2e 67 72 6f  ercase and m.gro
23e0: 75 70 28 69 47 72 6f 75 70 29 5b 30 3a 31 5d 2e  up(iGroup)[0:1].
23f0: 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20 20 20  isupper():.     
2400: 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72 2e             xErr.
2410: 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74  aSuggestions = t
2420: 75 70 6c 65 28 6d 61 70 28 73 74 72 2e 63 61 70  uple(map(str.cap
2430: 69 74 61 6c 69 7a 65 2c 20 73 75 67 67 2e 73 70  italize, sugg.sp
2440: 6c 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20  lit("|"))).     
2450: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2460: 20 20 20 20 20 20 20 20 20 20 20 20 20 78 45 72               xEr
2470: 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d  r.aSuggestions =
2480: 20 74 75 70 6c 65 28 73 75 67 67 2e 73 70 6c 69   tuple(sugg.spli
2490: 74 28 22 7c 22 29 29 0a 20 20 20 20 20 20 20 20  t("|")).        
24a0: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
24b0: 20 20 78 45 72 72 2e 61 53 75 67 67 65 73 74 69    xErr.aSuggesti
24c0: 6f 6e 73 20 3d 20 28 29 0a 20 20 20 20 65 6c 69  ons = ().    eli
24d0: 66 20 73 52 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a  f sRepl == "_":.
24e0: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 75          xErr.aSu
24f0: 67 67 65 73 74 69 6f 6e 73 20 3d 20 28 29 0a 20  ggestions = (). 
2500: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
2510: 20 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61   if bUppercase a
2520: 6e 64 20 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75  nd m.group(iGrou
2530: 70 29 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28  p)[0:1].isupper(
2540: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 78  ):.            x
2550: 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73  Err.aSuggestions
2560: 20 3d 20 74 75 70 6c 65 28 6d 61 70 28 73 74 72   = tuple(map(str
2570: 2e 63 61 70 69 74 61 6c 69 7a 65 2c 20 6d 2e 65  .capitalize, m.e
2580: 78 70 61 6e 64 28 73 52 65 70 6c 29 2e 73 70 6c  xpand(sRepl).spl
2590: 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20  it("|"))).      
25a0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
25b0: 20 20 20 20 78 45 72 72 2e 61 53 75 67 67 65 73      xErr.aSugges
25c0: 74 69 6f 6e 73 20 3d 20 74 75 70 6c 65 28 6d 2e  tions = tuple(m.
25d0: 65 78 70 61 6e 64 28 73 52 65 70 6c 29 2e 73 70  expand(sRepl).sp
25e0: 6c 69 74 28 22 7c 22 29 29 0a 20 20 20 20 23 20  lit("|")).    # 
25f0: 4d 65 73 73 61 67 65 0a 20 20 20 20 73 4d 65 73  Message.    sMes
2600: 73 61 67 65 20 3d 20 67 6c 6f 62 61 6c 73 28 29  sage = globals()
2610: 5b 73 4d 73 67 5b 31 3a 5d 5d 28 73 2c 20 6d 29  [sMsg[1:]](s, m)
2620: 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20 3d    if sMsg[0:1] =
2630: 3d 20 22 3d 22 20 20 65 6c 73 65 20 20 6d 2e 65  = "="  else  m.e
2640: 78 70 61 6e 64 28 73 4d 73 67 29 0a 20 20 20 20  xpand(sMsg).    
2650: 78 45 72 72 2e 61 53 68 6f 72 74 43 6f 6d 6d 65  xErr.aShortComme
2660: 6e 74 20 3d 20 73 4d 65 73 73 61 67 65 20 20 20  nt = sMessage   
2670: 23 20 73 4d 65 73 73 61 67 65 2e 73 70 6c 69 74  # sMessage.split
2680: 28 22 7c 22 29 5b 30 5d 20 20 20 20 20 23 20 69  ("|")[0]     # i
2690: 6e 20 63 6f 6e 74 65 78 74 20 6d 65 6e 75 0a 20  n context menu. 
26a0: 20 20 20 78 45 72 72 2e 61 46 75 6c 6c 43 6f 6d     xErr.aFullCom
26b0: 6d 65 6e 74 20 3d 20 73 4d 65 73 73 61 67 65 20  ment = sMessage 
26c0: 20 20 23 20 73 4d 65 73 73 61 67 65 2e 73 70 6c    # sMessage.spl
26d0: 69 74 28 22 7c 22 29 5b 2d 31 5d 20 20 20 20 23  it("|")[-1]    #
26e0: 20 69 6e 20 64 69 61 6c 6f 67 0a 20 20 20 20 69   in dialog.    i
26f0: 66 20 62 53 68 6f 77 52 75 6c 65 49 64 3a 0a 20  f bShowRuleId:. 
2700: 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 68 6f         xErr.aSho
2710: 72 74 43 6f 6d 6d 65 6e 74 20 2b 3d 20 22 20 20  rtComment += "  
2720: 23 20 22 20 2b 20 73 4c 69 6e 65 49 64 20 2b 20  # " + sLineId + 
2730: 22 20 23 20 22 20 2b 20 73 52 75 6c 65 49 64 0a  " # " + sRuleId.
2740: 20 20 20 20 23 20 55 52 4c 0a 20 20 20 20 69 66      # URL.    if
2750: 20 73 55 52 4c 3a 0a 20 20 20 20 20 20 20 20 70   sURL:.        p
2760: 20 3d 20 50 72 6f 70 65 72 74 79 56 61 6c 75 65   = PropertyValue
2770: 28 29 0a 20 20 20 20 20 20 20 20 70 2e 4e 61 6d  ().        p.Nam
2780: 65 20 3d 20 22 46 75 6c 6c 43 6f 6d 6d 65 6e 74  e = "FullComment
2790: 55 52 4c 22 0a 20 20 20 20 20 20 20 20 70 2e 56  URL".        p.V
27a0: 61 6c 75 65 20 3d 20 73 55 52 4c 0a 20 20 20 20  alue = sURL.    
27b0: 20 20 20 20 78 45 72 72 2e 61 50 72 6f 70 65 72      xErr.aProper
27c0: 74 69 65 73 20 3d 20 28 70 2c 29 0a 20 20 20 20  ties = (p,).    
27d0: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 78 45  else:.        xE
27e0: 72 72 2e 61 50 72 6f 70 65 72 74 69 65 73 20 3d  rr.aProperties =
27f0: 20 28 29 0a 20 20 20 20 72 65 74 75 72 6e 20 78   ().    return x
2800: 45 72 72 0a 0a 0a 64 65 66 20 5f 63 72 65 61 74  Err...def _creat
2810: 65 52 65 67 65 78 44 69 63 74 45 72 72 6f 72 20  eRegexDictError 
2820: 28 73 2c 20 73 78 2c 20 73 52 65 70 6c 2c 20 6e  (s, sx, sRepl, n
2830: 4f 66 66 73 65 74 2c 20 6d 2c 20 69 47 72 6f 75  Offset, m, iGrou
2840: 70 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c  p, sLineId, sRul
2850: 65 49 64 2c 20 62 55 70 70 65 72 63 61 73 65 2c  eId, bUppercase,
2860: 20 73 4d 73 67 2c 20 73 55 52 4c 2c 20 62 53 68   sMsg, sURL, bSh
2870: 6f 77 52 75 6c 65 49 64 2c 20 73 4f 70 74 69 6f  owRuleId, sOptio
2880: 6e 2c 20 62 43 6f 6e 74 65 78 74 29 3a 0a 20 20  n, bContext):.  
2890: 20 20 22 65 72 72 6f 72 20 61 73 20 61 20 64 69    "error as a di
28a0: 63 74 69 6f 6e 61 72 79 22 0a 20 20 20 20 64 45  ctionary".    dE
28b0: 72 72 20 3d 20 7b 7d 0a 20 20 20 20 64 45 72 72  rr = {}.    dErr
28c0: 5b 22 6e 53 74 61 72 74 22 5d 20 3d 20 6e 4f 66  ["nStart"] = nOf
28d0: 66 73 65 74 20 2b 20 6d 2e 73 74 61 72 74 28 69  fset + m.start(i
28e0: 47 72 6f 75 70 29 0a 20 20 20 20 64 45 72 72 5b  Group).    dErr[
28f0: 22 6e 45 6e 64 22 5d 20 3d 20 6e 4f 66 66 73 65  "nEnd"] = nOffse
2900: 74 20 2b 20 6d 2e 65 6e 64 28 69 47 72 6f 75 70  t + m.end(iGroup
2910: 29 0a 20 20 20 20 64 45 72 72 5b 22 73 4c 69 6e  ).    dErr["sLin
2920: 65 49 64 22 5d 20 3d 20 73 4c 69 6e 65 49 64 0a  eId"] = sLineId.
2930: 20 20 20 20 64 45 72 72 5b 22 73 52 75 6c 65 49      dErr["sRuleI
2940: 64 22 5d 20 3d 20 73 52 75 6c 65 49 64 0a 20 20  d"] = sRuleId.  
2950: 20 20 64 45 72 72 5b 22 73 54 79 70 65 22 5d 20    dErr["sType"] 
2960: 3d 20 73 4f 70 74 69 6f 6e 20 20 69 66 20 73 4f  = sOption  if sO
2970: 70 74 69 6f 6e 20 20 65 6c 73 65 20 22 6e 6f 74  ption  else "not
2980: 79 70 65 22 0a 20 20 20 20 23 20 73 75 67 67 65  ype".    # sugge
2990: 73 74 69 6f 6e 73 0a 20 20 20 20 69 66 20 73 52  stions.    if sR
29a0: 65 70 6c 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a  epl[0:1] == "=":
29b0: 0a 20 20 20 20 20 20 20 20 73 75 67 67 20 3d 20  .        sugg = 
29c0: 67 6c 6f 62 61 6c 73 28 29 5b 73 52 65 70 6c 5b  globals()[sRepl[
29d0: 31 3a 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20 20  1:]](s, m).     
29e0: 20 20 20 69 66 20 73 75 67 67 3a 0a 20 20 20 20     if sugg:.    
29f0: 20 20 20 20 20 20 20 20 69 66 20 62 55 70 70 65          if bUppe
2a00: 72 63 61 73 65 20 61 6e 64 20 6d 2e 67 72 6f 75  rcase and m.grou
2a10: 70 28 69 47 72 6f 75 70 29 5b 30 3a 31 5d 2e 69  p(iGroup)[0:1].i
2a20: 73 75 70 70 65 72 28 29 3a 0a 20 20 20 20 20 20  supper():.      
2a30: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
2a40: 61 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d  aSuggestions"] =
2a50: 20 6c 69 73 74 28 6d 61 70 28 73 74 72 2e 63 61   list(map(str.ca
2a60: 70 69 74 61 6c 69 7a 65 2c 20 73 75 67 67 2e 73  pitalize, sugg.s
2a70: 70 6c 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20  plit("|"))).    
2a80: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
2a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 45                dE
2aa0: 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e 73  rr["aSuggestions
2ab0: 22 5d 20 3d 20 73 75 67 67 2e 73 70 6c 69 74 28  "] = sugg.split(
2ac0: 22 7c 22 29 0a 20 20 20 20 20 20 20 20 65 6c 73  "|").        els
2ad0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64  e:.            d
2ae0: 45 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e  Err["aSuggestion
2af0: 73 22 5d 20 3d 20 5b 5d 0a 20 20 20 20 65 6c 69  s"] = [].    eli
2b00: 66 20 73 52 65 70 6c 20 3d 3d 20 22 5f 22 3a 0a  f sRepl == "_":.
2b10: 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61 53          dErr["aS
2b20: 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20 5b  uggestions"] = [
2b30: 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20  ].    else:.    
2b40: 20 20 20 20 69 66 20 62 55 70 70 65 72 63 61 73      if bUppercas
2b50: 65 20 61 6e 64 20 6d 2e 67 72 6f 75 70 28 69 47  e and m.group(iG
2b60: 72 6f 75 70 29 5b 30 3a 31 5d 2e 69 73 75 70 70  roup)[0:1].isupp
2b70: 65 72 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20  er():.          
2b80: 20 20 64 45 72 72 5b 22 61 53 75 67 67 65 73 74    dErr["aSuggest
2b90: 69 6f 6e 73 22 5d 20 3d 20 6c 69 73 74 28 6d 61  ions"] = list(ma
2ba0: 70 28 73 74 72 2e 63 61 70 69 74 61 6c 69 7a 65  p(str.capitalize
2bb0: 2c 20 6d 2e 65 78 70 61 6e 64 28 73 52 65 70 6c  , m.expand(sRepl
2bc0: 29 2e 73 70 6c 69 74 28 22 7c 22 29 29 29 0a 20  ).split("|"))). 
2bd0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2be0: 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61           dErr["a
2bf0: 53 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20  Suggestions"] = 
2c00: 6d 2e 65 78 70 61 6e 64 28 73 52 65 70 6c 29 2e  m.expand(sRepl).
2c10: 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20 20 23  split("|").    #
2c20: 20 4d 65 73 73 61 67 65 0a 20 20 20 20 64 45 72   Message.    dEr
2c30: 72 5b 22 73 4d 65 73 73 61 67 65 22 5d 20 3d 20  r["sMessage"] = 
2c40: 67 6c 6f 62 61 6c 73 28 29 5b 73 4d 73 67 5b 31  globals()[sMsg[1
2c50: 3a 5d 5d 28 73 2c 20 6d 29 20 20 69 66 20 73 4d  :]](s, m)  if sM
2c60: 73 67 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 20 20  sg[0:1] == "="  
2c70: 65 6c 73 65 20 20 6d 2e 65 78 70 61 6e 64 28 73  else  m.expand(s
2c80: 4d 73 67 29 0a 20 20 20 20 69 66 20 62 53 68 6f  Msg).    if bSho
2c90: 77 52 75 6c 65 49 64 3a 0a 20 20 20 20 20 20 20  wRuleId:.       
2ca0: 20 64 45 72 72 5b 22 73 4d 65 73 73 61 67 65 22   dErr["sMessage"
2cb0: 5d 20 2b 3d 20 22 20 20 23 20 22 20 2b 20 73 4c  ] += "  # " + sL
2cc0: 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20 2b 20  ineId + " # " + 
2cd0: 73 52 75 6c 65 49 64 0a 20 20 20 20 23 20 55 52  sRuleId.    # UR
2ce0: 4c 0a 20 20 20 20 64 45 72 72 5b 22 55 52 4c 22  L.    dErr["URL"
2cf0: 5d 20 3d 20 73 55 52 4c 20 20 69 66 20 73 55 52  ] = sURL  if sUR
2d00: 4c 20 20 65 6c 73 65 20 22 22 0a 20 20 20 20 23  L  else "".    #
2d10: 20 43 6f 6e 74 65 78 74 0a 20 20 20 20 69 66 20   Context.    if 
2d20: 62 43 6f 6e 74 65 78 74 3a 0a 20 20 20 20 20 20  bContext:.      
2d30: 20 20 64 45 72 72 5b 27 73 55 6e 64 65 72 6c 69    dErr['sUnderli
2d40: 6e 65 64 27 5d 20 3d 20 73 78 5b 6d 2e 73 74 61  ned'] = sx[m.sta
2d50: 72 74 28 69 47 72 6f 75 70 29 3a 6d 2e 65 6e 64  rt(iGroup):m.end
2d60: 28 69 47 72 6f 75 70 29 5d 0a 20 20 20 20 20 20  (iGroup)].      
2d70: 20 20 64 45 72 72 5b 27 73 42 65 66 6f 72 65 27    dErr['sBefore'
2d80: 5d 20 3d 20 73 78 5b 6d 61 78 28 30 2c 6d 2e 73  ] = sx[max(0,m.s
2d90: 74 61 72 74 28 69 47 72 6f 75 70 29 2d 38 30 29  tart(iGroup)-80)
2da0: 3a 6d 2e 73 74 61 72 74 28 69 47 72 6f 75 70 29  :m.start(iGroup)
2db0: 5d 0a 20 20 20 20 20 20 20 20 64 45 72 72 5b 27  ].        dErr['
2dc0: 73 41 66 74 65 72 27 5d 20 3d 20 73 78 5b 6d 2e  sAfter'] = sx[m.
2dd0: 65 6e 64 28 69 47 72 6f 75 70 29 3a 6d 2e 65 6e  end(iGroup):m.en
2de0: 64 28 69 47 72 6f 75 70 29 2b 38 30 5d 0a 20 20  d(iGroup)+80].  
2df0: 20 20 72 65 74 75 72 6e 20 64 45 72 72 0a 0a 0a    return dErr...
2e00: 64 65 66 20 5f 72 65 77 72 69 74 65 20 28 73 53  def _rewrite (sS
2e10: 65 6e 74 65 6e 63 65 2c 20 73 52 65 70 6c 2c 20  entence, sRepl, 
2e20: 69 47 72 6f 75 70 2c 20 6d 2c 20 62 55 70 70 65  iGroup, m, bUppe
2e30: 72 63 61 73 65 29 3a 0a 20 20 20 20 22 74 65 78  rcase):.    "tex
2e40: 74 20 70 72 6f 63 65 73 73 6f 72 3a 20 77 72 69  t processor: wri
2e50: 74 65 20 3c 73 52 65 70 6c 3e 20 69 6e 20 3c 73  te <sRepl> in <s
2e60: 53 65 6e 74 65 6e 63 65 3e 20 61 74 20 3c 69 47  Sentence> at <iG
2e70: 72 6f 75 70 3e 20 70 6f 73 69 74 69 6f 6e 22 0a  roup> position".
2e80: 20 20 20 20 6e 4c 65 6e 20 3d 20 6d 2e 65 6e 64      nLen = m.end
2e90: 28 69 47 72 6f 75 70 29 20 2d 20 6d 2e 73 74 61  (iGroup) - m.sta
2ea0: 72 74 28 69 47 72 6f 75 70 29 0a 20 20 20 20 69  rt(iGroup).    i
2eb0: 66 20 73 52 65 70 6c 20 3d 3d 20 22 2a 22 3a 0a  f sRepl == "*":.
2ec0: 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20 22          sNew = "
2ed0: 20 22 20 2a 20 6e 4c 65 6e 0a 20 20 20 20 65 6c   " * nLen.    el
2ee0: 69 66 20 73 52 65 70 6c 20 3d 3d 20 22 5f 22 3a  if sRepl == "_":
2ef0: 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20  .        sNew = 
2f00: 73 52 65 70 6c 20 2b 20 22 20 22 20 2a 20 28 6e  sRepl + " " * (n
2f10: 4c 65 6e 2d 31 29 0a 20 20 20 20 65 6c 69 66 20  Len-1).    elif 
2f20: 73 52 65 70 6c 5b 30 3a 31 5d 20 3d 3d 20 22 3d  sRepl[0:1] == "=
2f30: 22 3a 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20  ":.        sNew 
2f40: 3d 20 67 6c 6f 62 61 6c 73 28 29 5b 73 52 65 70  = globals()[sRep
2f50: 6c 5b 31 3a 5d 5d 28 73 53 65 6e 74 65 6e 63 65  l[1:]](sSentence
2f60: 2c 20 6d 29 0a 20 20 20 20 20 20 20 20 73 4e 65  , m).        sNe
2f70: 77 20 3d 20 73 4e 65 77 20 2b 20 22 20 22 20 2a  w = sNew + " " *
2f80: 20 28 6e 4c 65 6e 2d 6c 65 6e 28 73 4e 65 77 29   (nLen-len(sNew)
2f90: 29 0a 20 20 20 20 20 20 20 20 69 66 20 62 55 70  ).        if bUp
2fa0: 70 65 72 63 61 73 65 20 61 6e 64 20 6d 2e 67 72  percase and m.gr
2fb0: 6f 75 70 28 69 47 72 6f 75 70 29 5b 30 3a 31 5d  oup(iGroup)[0:1]
2fc0: 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20 20  .isupper():.    
2fd0: 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20 73          sNew = s
2fe0: 4e 65 77 2e 63 61 70 69 74 61 6c 69 7a 65 28 29  New.capitalize()
2ff0: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
3000: 20 20 20 73 4e 65 77 20 3d 20 6d 2e 65 78 70 61     sNew = m.expa
3010: 6e 64 28 73 52 65 70 6c 29 0a 20 20 20 20 20 20  nd(sRepl).      
3020: 20 20 73 4e 65 77 20 3d 20 73 4e 65 77 20 2b 20    sNew = sNew + 
3030: 22 20 22 20 2a 20 28 6e 4c 65 6e 2d 6c 65 6e 28  " " * (nLen-len(
3040: 73 4e 65 77 29 29 0a 20 20 20 20 72 65 74 75 72  sNew)).    retur
3050: 6e 20 73 53 65 6e 74 65 6e 63 65 5b 30 3a 6d 2e  n sSentence[0:m.
3060: 73 74 61 72 74 28 69 47 72 6f 75 70 29 5d 20 2b  start(iGroup)] +
3070: 20 73 4e 65 77 20 2b 20 73 53 65 6e 74 65 6e 63   sNew + sSentenc
3080: 65 5b 6d 2e 65 6e 64 28 69 47 72 6f 75 70 29 3a  e[m.end(iGroup):
3090: 5d 0a 0a 0a 64 65 66 20 69 67 6e 6f 72 65 52 75  ]...def ignoreRu
30a0: 6c 65 20 28 73 52 75 6c 65 49 64 29 3a 0a 20 20  le (sRuleId):.  
30b0: 20 20 5f 61 49 67 6e 6f 72 65 64 52 75 6c 65 73    _aIgnoredRules
30c0: 2e 61 64 64 28 73 52 75 6c 65 49 64 29 0a 0a 0a  .add(sRuleId)...
30d0: 64 65 66 20 72 65 73 65 74 49 67 6e 6f 72 65 52  def resetIgnoreR
30e0: 75 6c 65 73 20 28 29 3a 0a 20 20 20 20 5f 61 49  ules ():.    _aI
30f0: 67 6e 6f 72 65 64 52 75 6c 65 73 2e 63 6c 65 61  gnoredRules.clea
3100: 72 28 29 0a 0a 0a 64 65 66 20 72 65 61 63 74 69  r()...def reacti
3110: 76 61 74 65 52 75 6c 65 20 28 73 52 75 6c 65 49  vateRule (sRuleI
3120: 64 29 3a 0a 20 20 20 20 5f 61 49 67 6e 6f 72 65  d):.    _aIgnore
3130: 64 52 75 6c 65 73 2e 64 69 73 63 61 72 64 28 73  dRules.discard(s
3140: 52 75 6c 65 49 64 29 0a 0a 0a 64 65 66 20 6c 69  RuleId)...def li
3150: 73 74 52 75 6c 65 73 20 28 73 46 69 6c 74 65 72  stRules (sFilter
3160: 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 67 65 6e  =None):.    "gen
3170: 65 72 61 74 6f 72 3a 20 72 65 74 75 72 6e 73 20  erator: returns 
3180: 74 79 70 6c 65 20 28 73 4f 70 74 69 6f 6e 2c 20  typle (sOption, 
3190: 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64  sLineId, sRuleId
31a0: 29 22 0a 20 20 20 20 69 66 20 73 46 69 6c 74 65  )".    if sFilte
31b0: 72 3a 0a 20 20 20 20 20 20 20 20 74 72 79 3a 0a  r:.        try:.
31c0: 20 20 20 20 20 20 20 20 20 20 20 20 7a 46 69 6c              zFil
31d0: 74 65 72 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ter = re.compile
31e0: 28 73 46 69 6c 74 65 72 29 0a 20 20 20 20 20 20  (sFilter).      
31f0: 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20    except:.      
3200: 20 20 20 20 20 20 65 63 68 6f 28 22 23 20 45 72        echo("# Er
3210: 72 6f 72 2e 20 4c 69 73 74 20 72 75 6c 65 73 3a  ror. List rules:
3220: 20 77 72 6f 6e 67 20 72 65 67 65 78 2e 22 29 0a   wrong regex.").
3230: 20 20 20 20 20 20 20 20 20 20 20 20 73 46 69 6c              sFil
3240: 74 65 72 20 3d 20 4e 6f 6e 65 0a 20 20 20 20 66  ter = None.    f
3250: 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 6c 52 75 6c  or sOption, lRul
3260: 65 47 72 6f 75 70 20 69 6e 20 63 68 61 69 6e 28  eGroup in chain(
3270: 5f 67 65 74 52 75 6c 65 73 28 54 72 75 65 29 2c  _getRules(True),
3280: 20 5f 67 65 74 52 75 6c 65 73 28 46 61 6c 73 65   _getRules(False
3290: 29 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  )):.        if s
32a0: 4f 70 74 69 6f 6e 20 21 3d 20 22 40 40 40 40 22  Option != "@@@@"
32b0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  :.            fo
32c0: 72 20 5f 2c 20 5f 2c 20 73 4c 69 6e 65 49 64 2c  r _, _, sLineId,
32d0: 20 73 52 75 6c 65 49 64 2c 20 5f 2c 20 5f 20 69   sRuleId, _, _ i
32e0: 6e 20 6c 52 75 6c 65 47 72 6f 75 70 3a 0a 20 20  n lRuleGroup:.  
32f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
3300: 20 6e 6f 74 20 73 46 69 6c 74 65 72 20 6f 72 20   not sFilter or 
3310: 7a 46 69 6c 74 65 72 2e 73 65 61 72 63 68 28 73  zFilter.search(s
3320: 52 75 6c 65 49 64 29 3a 0a 20 20 20 20 20 20 20  RuleId):.       
3330: 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65               yie
3340: 6c 64 20 28 73 4f 70 74 69 6f 6e 2c 20 73 4c 69  ld (sOption, sLi
3350: 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 29 0a 0a  neId, sRuleId)..
3360: 0a 64 65 66 20 64 69 73 70 6c 61 79 52 75 6c 65  .def displayRule
3370: 73 20 28 73 46 69 6c 74 65 72 3d 4e 6f 6e 65 29  s (sFilter=None)
3380: 3a 0a 20 20 20 20 65 63 68 6f 28 22 4c 69 73 74  :.    echo("List
3390: 20 6f 66 20 72 75 6c 65 73 2e 20 46 69 6c 74 65   of rules. Filte
33a0: 72 3a 20 3c 3c 20 22 20 2b 20 73 74 72 28 73 46  r: << " + str(sF
33b0: 69 6c 74 65 72 29 20 2b 20 22 20 3e 3e 22 29 0a  ilter) + " >>").
33c0: 20 20 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c      for sOption,
33d0: 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49   sLineId, sRuleI
33e0: 64 20 69 6e 20 6c 69 73 74 52 75 6c 65 73 28 73  d in listRules(s
33f0: 46 69 6c 74 65 72 29 3a 0a 20 20 20 20 20 20 20  Filter):.       
3400: 20 65 63 68 6f 28 22 7b 3a 3c 31 30 7d 20 7b 3a   echo("{:<10} {:
3410: 3c 31 30 7d 20 7b 7d 22 2e 66 6f 72 6d 61 74 28  <10} {}".format(
3420: 73 4f 70 74 69 6f 6e 2c 20 73 4c 69 6e 65 49 64  sOption, sLineId
3430: 2c 20 73 52 75 6c 65 49 64 29 29 0a 0a 0a 64 65  , sRuleId))...de
3440: 66 20 73 65 74 4f 70 74 69 6f 6e 20 28 73 4f 70  f setOption (sOp
3450: 74 2c 20 62 56 61 6c 29 3a 0a 20 20 20 20 69 66  t, bVal):.    if
3460: 20 73 4f 70 74 20 69 6e 20 5f 64 4f 70 74 69 6f   sOpt in _dOptio
3470: 6e 73 3a 0a 20 20 20 20 20 20 20 20 5f 64 4f 70  ns:.        _dOp
3480: 74 69 6f 6e 73 5b 73 4f 70 74 5d 20 3d 20 62 56  tions[sOpt] = bV
3490: 61 6c 0a 0a 0a 64 65 66 20 73 65 74 4f 70 74 69  al...def setOpti
34a0: 6f 6e 73 20 28 64 4f 70 74 29 3a 0a 20 20 20 20  ons (dOpt):.    
34b0: 66 6f 72 20 73 4b 65 79 2c 20 62 56 61 6c 20 69  for sKey, bVal i
34c0: 6e 20 64 4f 70 74 2e 69 74 65 6d 73 28 29 3a 0a  n dOpt.items():.
34d0: 20 20 20 20 20 20 20 20 69 66 20 73 4b 65 79 20          if sKey 
34e0: 69 6e 20 5f 64 4f 70 74 69 6f 6e 73 3a 0a 20 20  in _dOptions:.  
34f0: 20 20 20 20 20 20 20 20 20 20 5f 64 4f 70 74 69            _dOpti
3500: 6f 6e 73 5b 73 4b 65 79 5d 20 3d 20 62 56 61 6c  ons[sKey] = bVal
3510: 0a 0a 0a 64 65 66 20 67 65 74 4f 70 74 69 6f 6e  ...def getOption
3520: 73 20 28 29 3a 0a 20 20 20 20 72 65 74 75 72 6e  s ():.    return
3530: 20 5f 64 4f 70 74 69 6f 6e 73 0a 0a 0a 64 65 66   _dOptions...def
3540: 20 67 65 74 44 65 66 61 75 6c 74 4f 70 74 69 6f   getDefaultOptio
3550: 6e 73 20 28 29 3a 0a 20 20 20 20 72 65 74 75 72  ns ():.    retur
3560: 6e 20 64 69 63 74 28 67 63 5f 6f 70 74 69 6f 6e  n dict(gc_option
3570: 73 2e 67 65 74 4f 70 74 69 6f 6e 73 28 5f 73 41  s.getOptions(_sA
3580: 70 70 43 6f 6e 74 65 78 74 29 29 0a 0a 0a 64 65  ppContext))...de
3590: 66 20 67 65 74 4f 70 74 69 6f 6e 73 4c 61 62 65  f getOptionsLabe
35a0: 6c 73 20 28 73 4c 61 6e 67 29 3a 0a 20 20 20 20  ls (sLang):.    
35b0: 72 65 74 75 72 6e 20 67 63 5f 6f 70 74 69 6f 6e  return gc_option
35c0: 73 2e 67 65 74 55 49 28 73 4c 61 6e 67 29 0a 0a  s.getUI(sLang)..
35d0: 0a 64 65 66 20 64 69 73 70 6c 61 79 4f 70 74 69  .def displayOpti
35e0: 6f 6e 73 20 28 73 4c 61 6e 67 29 3a 0a 20 20 20  ons (sLang):.   
35f0: 20 65 63 68 6f 28 22 4c 69 73 74 20 6f 66 20 6f   echo("List of o
3600: 70 74 69 6f 6e 73 22 29 0a 20 20 20 20 65 63 68  ptions").    ech
3610: 6f 28 22 5c 6e 22 2e 6a 6f 69 6e 28 20 5b 20 6b  o("\n".join( [ k
3620: 2b 22 3a 5c 74 22 2b 73 74 72 28 76 29 2b 22 5c  +":\t"+str(v)+"\
3630: 74 22 2b 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  t"+gc_options.ge
3640: 74 55 49 28 73 4c 61 6e 67 29 2e 67 65 74 28 6b  tUI(sLang).get(k
3650: 2c 20 28 22 3f 22 2c 20 22 22 29 29 5b 30 5d 20  , ("?", ""))[0] 
3660: 20 66 6f 72 20 6b 2c 20 76 20 20 69 6e 20 73 6f   for k, v  in so
3670: 72 74 65 64 28 5f 64 4f 70 74 69 6f 6e 73 2e 69  rted(_dOptions.i
3680: 74 65 6d 73 28 29 29 20 5d 20 29 29 0a 20 20 20  tems()) ] )).   
3690: 20 65 63 68 6f 28 22 22 29 0a 0a 0a 64 65 66 20   echo("")...def 
36a0: 72 65 73 65 74 4f 70 74 69 6f 6e 73 20 28 29 3a  resetOptions ():
36b0: 0a 20 20 20 20 67 6c 6f 62 61 6c 20 5f 64 4f 70  .    global _dOp
36c0: 74 69 6f 6e 73 0a 20 20 20 20 5f 64 4f 70 74 69  tions.    _dOpti
36d0: 6f 6e 73 20 3d 20 64 69 63 74 28 67 63 5f 6f 70  ons = dict(gc_op
36e0: 74 69 6f 6e 73 2e 67 65 74 4f 70 74 69 6f 6e 73  tions.getOptions
36f0: 28 5f 73 41 70 70 43 6f 6e 74 65 78 74 29 29 0a  (_sAppContext)).
3700: 0a 0a 64 65 66 20 67 65 74 53 70 65 6c 6c 43 68  ..def getSpellCh
3710: 65 63 6b 65 72 20 28 29 3a 0a 20 20 20 20 72 65  ecker ():.    re
3720: 74 75 72 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63  turn _oSpellChec
3730: 6b 65 72 0a 0a 0a 64 65 66 20 5f 67 65 74 50 61  ker...def _getPa
3740: 74 68 20 28 29 3a 0a 20 20 20 20 72 65 74 75 72  th ():.    retur
3750: 6e 20 6f 73 2e 70 61 74 68 2e 6a 6f 69 6e 28 6f  n os.path.join(o
3760: 73 2e 70 61 74 68 2e 64 69 72 6e 61 6d 65 28 73  s.path.dirname(s
3770: 79 73 2e 6d 6f 64 75 6c 65 73 5b 5f 5f 6e 61 6d  ys.modules[__nam
3780: 65 5f 5f 5d 2e 5f 5f 66 69 6c 65 5f 5f 29 2c 20  e__].__file__), 
3790: 5f 5f 6e 61 6d 65 5f 5f 20 2b 20 22 2e 70 79 22  __name__ + ".py"
37a0: 29 0a 0a 0a 0a 23 23 23 23 20 63 6f 6d 6d 6f 6e  )....#### common
37b0: 20 66 75 6e 63 74 69 6f 6e 73 0a 0a 64 65 66 20   functions..def 
37c0: 6f 70 74 69 6f 6e 20 28 73 4f 70 74 29 3a 0a 20  option (sOpt):. 
37d0: 20 20 20 22 72 65 74 75 72 6e 20 54 72 75 65 20     "return True 
37e0: 69 66 20 6f 70 74 69 6f 6e 20 73 4f 70 74 20 69  if option sOpt i
37f0: 73 20 61 63 74 69 76 65 22 0a 20 20 20 20 72 65  s active".    re
3800: 74 75 72 6e 20 5f 64 4f 70 74 69 6f 6e 73 2e 67  turn _dOptions.g
3810: 65 74 28 73 4f 70 74 2c 20 46 61 6c 73 65 29 0a  et(sOpt, False).
3820: 0a 0a 64 65 66 20 64 69 73 70 6c 61 79 49 6e 66  ..def displayInf
3830: 6f 20 28 64 44 41 2c 20 74 57 6f 72 64 29 3a 0a  o (dDA, tWord):.
3840: 20 20 20 20 22 66 6f 72 20 64 65 62 75 67 67 69      "for debuggi
3850: 6e 67 3a 20 72 65 74 72 69 65 76 65 20 69 6e 66  ng: retrieve inf
3860: 6f 20 6f 66 20 77 6f 72 64 22 0a 20 20 20 20 69  o of word".    i
3870: 66 20 6e 6f 74 20 74 57 6f 72 64 3a 0a 20 20 20  f not tWord:.   
3880: 20 20 20 20 20 65 63 68 6f 28 22 3e 20 6e 6f 74       echo("> not
3890: 68 69 6e 67 20 74 6f 20 66 69 6e 64 22 29 0a 20  hing to find"). 
38a0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
38b0: 75 65 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20  ue.    lMorph = 
38c0: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
38d0: 65 74 4d 6f 72 70 68 28 74 57 6f 72 64 5b 31 5d  etMorph(tWord[1]
38e0: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f  ).    if not lMo
38f0: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 65 63 68  rph:.        ech
3900: 6f 28 22 3e 20 6e 6f 74 20 69 6e 20 64 69 63 74  o("> not in dict
3910: 69 6f 6e 61 72 79 22 29 0a 20 20 20 20 20 20 20  ionary").       
3920: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20   return True.   
3930: 20 69 66 20 74 57 6f 72 64 5b 30 5d 20 69 6e 20   if tWord[0] in 
3940: 64 44 41 3a 0a 20 20 20 20 20 20 20 20 65 63 68  dDA:.        ech
3950: 6f 28 22 44 41 3a 20 22 20 2b 20 73 74 72 28 64  o("DA: " + str(d
3960: 44 41 5b 74 57 6f 72 64 5b 30 5d 5d 29 29 0a 20  DA[tWord[0]])). 
3970: 20 20 20 65 63 68 6f 28 22 46 53 41 3a 20 22 20     echo("FSA: " 
3980: 2b 20 73 74 72 28 6c 4d 6f 72 70 68 29 29 0a 20  + str(lMorph)). 
3990: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a     return True..
39a0: 0a 64 65 66 20 6d 6f 72 70 68 20 28 64 44 41 2c  .def morph (dDA,
39b0: 20 74 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e   tWord, sPattern
39c0: 2c 20 62 53 74 72 69 63 74 3d 54 72 75 65 2c 20  , bStrict=True, 
39d0: 62 4e 6f 57 6f 72 64 3d 46 61 6c 73 65 29 3a 0a  bNoWord=False):.
39e0: 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 74      "analyse a t
39f0: 75 70 6c 65 20 28 70 6f 73 69 74 69 6f 6e 2c 20  uple (position, 
3a00: 77 6f 72 64 29 2c 20 72 65 74 75 72 6e 20 54 72  word), return Tr
3a10: 75 65 20 69 66 20 73 50 61 74 74 65 72 6e 20 69  ue if sPattern i
3a20: 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28  n morphologies (
3a30: 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f  disambiguation o
3a40: 6e 29 22 0a 20 20 20 20 69 66 20 6e 6f 74 20 74  n)".    if not t
3a50: 57 6f 72 64 3a 0a 20 20 20 20 20 20 20 20 72 65  Word:.        re
3a60: 74 75 72 6e 20 62 4e 6f 57 6f 72 64 0a 20 20 20  turn bNoWord.   
3a70: 20 6c 4d 6f 72 70 68 20 3d 20 64 44 41 5b 74 57   lMorph = dDA[tW
3a80: 6f 72 64 5b 30 5d 5d 20 20 69 66 20 74 57 6f 72  ord[0]]  if tWor
3a90: 64 5b 30 5d 20 69 6e 20 64 44 41 20 20 65 6c 73  d[0] in dDA  els
3aa0: 65 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  e _oSpellChecker
3ab0: 2e 67 65 74 4d 6f 72 70 68 28 74 57 6f 72 64 5b  .getMorph(tWord[
3ac0: 31 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c  1]).    if not l
3ad0: 4d 6f 72 70 68 3a 0a 20 20 20 20 20 20 20 20 72  Morph:.        r
3ae0: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
3af0: 70 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73  p = re.compile(s
3b00: 50 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66 20  Pattern).    if 
3b10: 62 53 74 72 69 63 74 3a 0a 20 20 20 20 20 20 20  bStrict:.       
3b20: 20 72 65 74 75 72 6e 20 61 6c 6c 28 70 2e 73 65   return all(p.se
3b30: 61 72 63 68 28 73 29 20 20 66 6f 72 20 73 20 69  arch(s)  for s i
3b40: 6e 20 6c 4d 6f 72 70 68 29 0a 20 20 20 20 72 65  n lMorph).    re
3b50: 74 75 72 6e 20 61 6e 79 28 70 2e 73 65 61 72 63  turn any(p.searc
3b60: 68 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c  h(s)  for s in l
3b70: 4d 6f 72 70 68 29 0a 0a 0a 64 65 66 20 6d 6f 72  Morph)...def mor
3b80: 70 68 65 78 20 28 64 44 41 2c 20 74 57 6f 72 64  phex (dDA, tWord
3b90: 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e 65 67  , sPattern, sNeg
3ba0: 50 61 74 74 65 72 6e 2c 20 62 4e 6f 57 6f 72 64  Pattern, bNoWord
3bb0: 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 22 61 6e  =False):.    "an
3bc0: 61 6c 79 73 65 20 61 20 74 75 70 6c 65 20 28 70  alyse a tuple (p
3bd0: 6f 73 69 74 69 6f 6e 2c 20 77 6f 72 64 29 2c 20  osition, word), 
3be0: 72 65 74 75 72 6e 73 20 54 72 75 65 20 69 66 20  returns True if 
3bf0: 6e 6f 74 20 73 4e 65 67 50 61 74 74 65 72 6e 20  not sNegPattern 
3c00: 69 6e 20 77 6f 72 64 20 6d 6f 72 70 68 6f 6c 6f  in word morpholo
3c10: 67 69 65 73 20 61 6e 64 20 73 50 61 74 74 65 72  gies and sPatter
3c20: 6e 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70 68 6f  n in word morpho
3c30: 6c 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69 67  logies (disambig
3c40: 75 61 74 69 6f 6e 20 6f 6e 29 22 0a 20 20 20 20  uation on)".    
3c50: 69 66 20 6e 6f 74 20 74 57 6f 72 64 3a 0a 20 20  if not tWord:.  
3c60: 20 20 20 20 20 20 72 65 74 75 72 6e 20 62 4e 6f        return bNo
3c70: 57 6f 72 64 0a 20 20 20 20 6c 4d 6f 72 70 68 20  Word.    lMorph 
3c80: 3d 20 64 44 41 5b 74 57 6f 72 64 5b 30 5d 5d 20  = dDA[tWord[0]] 
3c90: 20 69 66 20 74 57 6f 72 64 5b 30 5d 20 69 6e 20   if tWord[0] in 
3ca0: 64 44 41 20 20 65 6c 73 65 20 5f 6f 53 70 65 6c  dDA  else _oSpel
3cb0: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70  lChecker.getMorp
3cc0: 68 28 74 57 6f 72 64 5b 31 5d 29 0a 20 20 20 20  h(tWord[1]).    
3cd0: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20  if not lMorph:. 
3ce0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
3cf0: 6c 73 65 0a 20 20 20 20 23 20 63 68 65 63 6b 20  lse.    # check 
3d00: 6e 65 67 61 74 69 76 65 20 63 6f 6e 64 69 74 69  negative conditi
3d10: 6f 6e 0a 20 20 20 20 6e 70 20 3d 20 72 65 2e 63  on.    np = re.c
3d20: 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61 74 74 65  ompile(sNegPatte
3d30: 72 6e 29 0a 20 20 20 20 69 66 20 61 6e 79 28 6e  rn).    if any(n
3d40: 70 2e 73 65 61 72 63 68 28 73 29 20 20 66 6f 72  p.search(s)  for
3d50: 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20   s in lMorph):. 
3d60: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
3d70: 6c 73 65 0a 20 20 20 20 23 20 73 65 61 72 63 68  lse.    # search
3d80: 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20 70 20   sPattern.    p 
3d90: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61  = re.compile(sPa
3da0: 74 74 65 72 6e 29 0a 20 20 20 20 72 65 74 75 72  ttern).    retur
3db0: 6e 20 61 6e 79 28 70 2e 73 65 61 72 63 68 28 73  n any(p.search(s
3dc0: 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72  )  for s in lMor
3dd0: 70 68 29 0a 0a 0a 64 65 66 20 61 6e 61 6c 79 73  ph)...def analys
3de0: 65 20 28 73 57 6f 72 64 2c 20 73 50 61 74 74 65  e (sWord, sPatte
3df0: 72 6e 2c 20 62 53 74 72 69 63 74 3d 54 72 75 65  rn, bStrict=True
3e00: 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20  ):.    "analyse 
3e10: 61 20 77 6f 72 64 2c 20 72 65 74 75 72 6e 20 54  a word, return T
3e20: 72 75 65 20 69 66 20 73 50 61 74 74 65 72 6e 20  rue if sPattern 
3e30: 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20  in morphologies 
3e40: 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20  (disambiguation 
3e50: 6f 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70 68  off)".    lMorph
3e60: 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65   = _oSpellChecke
3e70: 72 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64  r.getMorph(sWord
3e80: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f  ).    if not lMo
3e90: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65 74  rph:.        ret
3ea0: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 70 20  urn False.    p 
3eb0: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61  = re.compile(sPa
3ec0: 74 74 65 72 6e 29 0a 20 20 20 20 69 66 20 62 53  ttern).    if bS
3ed0: 74 72 69 63 74 3a 0a 20 20 20 20 20 20 20 20 72  trict:.        r
3ee0: 65 74 75 72 6e 20 61 6c 6c 28 70 2e 73 65 61 72  eturn all(p.sear
3ef0: 63 68 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20  ch(s)  for s in 
3f00: 6c 4d 6f 72 70 68 29 0a 20 20 20 20 72 65 74 75  lMorph).    retu
3f10: 72 6e 20 61 6e 79 28 70 2e 73 65 61 72 63 68 28  rn any(p.search(
3f20: 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f  s)  for s in lMo
3f30: 72 70 68 29 0a 0a 0a 64 65 66 20 61 6e 61 6c 79  rph)...def analy
3f40: 73 65 78 20 28 73 57 6f 72 64 2c 20 73 50 61 74  sex (sWord, sPat
3f50: 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65 72  tern, sNegPatter
3f60: 6e 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65  n):.    "analyse
3f70: 20 61 20 77 6f 72 64 2c 20 72 65 74 75 72 6e 73   a word, returns
3f80: 20 54 72 75 65 20 69 66 20 6e 6f 74 20 73 4e 65   True if not sNe
3f90: 67 50 61 74 74 65 72 6e 20 69 6e 20 77 6f 72 64  gPattern in word
3fa0: 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 61 6e   morphologies an
3fb0: 64 20 73 50 61 74 74 65 72 6e 20 69 6e 20 77 6f  d sPattern in wo
3fc0: 72 64 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20  rd morphologies 
3fd0: 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20  (disambiguation 
3fe0: 6f 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70 68  off)".    lMorph
3ff0: 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65   = _oSpellChecke
4000: 72 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64  r.getMorph(sWord
4010: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f  ).    if not lMo
4020: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65 74  rph:.        ret
4030: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 23 20  urn False.    # 
4040: 63 68 65 63 6b 20 6e 65 67 61 74 69 76 65 20 63  check negative c
4050: 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 6e 70 20  ondition.    np 
4060: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 4e 65  = re.compile(sNe
4070: 67 50 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66  gPattern).    if
4080: 20 61 6e 79 28 6e 70 2e 73 65 61 72 63 68 28 73   any(np.search(s
4090: 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72  )  for s in lMor
40a0: 70 68 29 3a 0a 20 20 20 20 20 20 20 20 72 65 74  ph):.        ret
40b0: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 23 20  urn False.    # 
40c0: 73 65 61 72 63 68 20 73 50 61 74 74 65 72 6e 0a  search sPattern.
40d0: 20 20 20 20 70 20 3d 20 72 65 2e 63 6f 6d 70 69      p = re.compi
40e0: 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20  le(sPattern).   
40f0: 20 72 65 74 75 72 6e 20 61 6e 79 28 70 2e 73 65   return any(p.se
4100: 61 72 63 68 28 73 29 20 20 66 6f 72 20 73 20 69  arch(s)  for s i
4110: 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 0a 23 23 20  n lMorph)....## 
4120: 66 75 6e 63 74 69 6f 6e 73 20 74 6f 20 67 65 74  functions to get
4130: 20 74 65 78 74 20 6f 75 74 73 69 64 65 20 70 61   text outside pa
4140: 74 74 65 72 6e 20 73 63 6f 70 65 0a 0a 23 20 77  ttern scope..# w
4150: 61 72 6e 69 6e 67 3a 20 63 68 65 63 6b 20 63 6f  arning: check co
4160: 6d 70 69 6c 65 5f 72 75 6c 65 73 2e 70 79 20 74  mpile_rules.py t
4170: 6f 20 75 6e 64 65 72 73 74 61 6e 64 20 68 6f 77  o understand how
4180: 20 69 74 20 77 6f 72 6b 73 0a 0a 5f 7a 4e 65 78   it works.._zNex
4190: 74 57 6f 72 64 20 3d 20 72 65 2e 63 6f 6d 70 69  tWord = re.compi
41a0: 6c 65 28 72 22 20 2b 28 5c 77 5b 5c 77 2d 5d 2a  le(r" +(\w[\w-]*
41b0: 29 22 29 0a 5f 7a 50 72 65 76 57 6f 72 64 20 3d  )")._zPrevWord =
41c0: 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72 22 28 5c   re.compile(r"(\
41d0: 77 5b 5c 77 2d 5d 2a 29 20 2b 24 22 29 0a 0a 64  w[\w-]*) +$")..d
41e0: 65 66 20 6e 65 78 74 77 6f 72 64 20 28 73 2c 20  ef nextword (s, 
41f0: 69 53 74 61 72 74 2c 20 6e 29 3a 0a 20 20 20 20  iStart, n):.    
4200: 22 67 65 74 20 74 68 65 20 6e 74 68 20 77 6f 72  "get the nth wor
4210: 64 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20 73  d of the input s
4220: 74 72 69 6e 67 20 6f 72 20 65 6d 70 74 79 20 73  tring or empty s
4230: 74 72 69 6e 67 22 0a 20 20 20 20 6d 20 3d 20 72  tring".    m = r
4240: 65 2e 6d 61 74 63 68 28 22 28 3f 3a 20 2b 5b 5c  e.match("(?: +[\
4250: 5c 77 25 2d 5d 2b 29 7b 22 20 2b 20 73 74 72 28  \w%-]+){" + str(
4260: 6e 2d 31 29 20 2b 20 22 7d 20 2b 28 5b 5c 5c 77  n-1) + "} +([\\w
4270: 25 2d 5d 2b 29 22 2c 20 73 5b 69 53 74 61 72 74  %-]+)", s[iStart
4280: 3a 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6d  :]).    if not m
4290: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
42a0: 20 4e 6f 6e 65 0a 20 20 20 20 72 65 74 75 72 6e   None.    return
42b0: 20 28 69 53 74 61 72 74 2b 6d 2e 73 74 61 72 74   (iStart+m.start
42c0: 28 31 29 2c 20 6d 2e 67 72 6f 75 70 28 31 29 29  (1), m.group(1))
42d0: 0a 0a 0a 64 65 66 20 70 72 65 76 77 6f 72 64 20  ...def prevword 
42e0: 28 73 2c 20 69 45 6e 64 2c 20 6e 29 3a 0a 20 20  (s, iEnd, n):.  
42f0: 20 20 22 67 65 74 20 74 68 65 20 28 2d 29 6e 74    "get the (-)nt
4300: 68 20 77 6f 72 64 20 6f 66 20 74 68 65 20 69 6e  h word of the in
4310: 70 75 74 20 73 74 72 69 6e 67 20 6f 72 20 65 6d  put string or em
4320: 70 74 79 20 73 74 72 69 6e 67 22 0a 20 20 20 20  pty string".    
4330: 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28 22 28  m = re.search("(
4340: 5b 5c 5c 77 25 2d 5d 2b 29 20 2b 28 3f 3a 5b 5c  [\\w%-]+) +(?:[\
4350: 5c 77 25 2d 5d 2b 20 2b 29 7b 22 20 2b 20 73 74  \w%-]+ +){" + st
4360: 72 28 6e 2d 31 29 20 2b 20 22 7d 24 22 2c 20 73  r(n-1) + "}$", s
4370: 5b 3a 69 45 6e 64 5d 29 0a 20 20 20 20 69 66 20  [:iEnd]).    if 
4380: 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 72  not m:.        r
4390: 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20 72  eturn None.    r
43a0: 65 74 75 72 6e 20 28 6d 2e 73 74 61 72 74 28 31  eturn (m.start(1
43b0: 29 2c 20 6d 2e 67 72 6f 75 70 28 31 29 29 0a 0a  ), m.group(1))..
43c0: 0a 64 65 66 20 6e 65 78 74 77 6f 72 64 31 20 28  .def nextword1 (
43d0: 73 2c 20 69 53 74 61 72 74 29 3a 0a 20 20 20 20  s, iStart):.    
43e0: 22 67 65 74 20 6e 65 78 74 20 77 6f 72 64 20 28  "get next word (
43f0: 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 29 22 0a 20  optimization)". 
4400: 20 20 20 6d 20 3d 20 5f 7a 4e 65 78 74 57 6f 72     m = _zNextWor
4410: 64 2e 6d 61 74 63 68 28 73 5b 69 53 74 61 72 74  d.match(s[iStart
4420: 3a 5d 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6d  :]).    if not m
4430: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
4440: 20 4e 6f 6e 65 0a 20 20 20 20 72 65 74 75 72 6e   None.    return
4450: 20 28 69 53 74 61 72 74 2b 6d 2e 73 74 61 72 74   (iStart+m.start
4460: 28 31 29 2c 20 6d 2e 67 72 6f 75 70 28 31 29 29  (1), m.group(1))
4470: 0a 0a 0a 64 65 66 20 70 72 65 76 77 6f 72 64 31  ...def prevword1
4480: 20 28 73 2c 20 69 45 6e 64 29 3a 0a 20 20 20 20   (s, iEnd):.    
4490: 22 67 65 74 20 70 72 65 76 69 6f 75 73 20 77 6f  "get previous wo
44a0: 72 64 20 28 6f 70 74 69 6d 69 7a 61 74 69 6f 6e  rd (optimization
44b0: 29 22 0a 20 20 20 20 6d 20 3d 20 5f 7a 50 72 65  )".    m = _zPre
44c0: 76 57 6f 72 64 2e 73 65 61 72 63 68 28 73 5b 3a  vWord.search(s[:
44d0: 69 45 6e 64 5d 29 0a 20 20 20 20 69 66 20 6e 6f  iEnd]).    if no
44e0: 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 72 65 74  t m:.        ret
44f0: 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20 72 65 74  urn None.    ret
4500: 75 72 6e 20 28 6d 2e 73 74 61 72 74 28 31 29 2c  urn (m.start(1),
4510: 20 6d 2e 67 72 6f 75 70 28 31 29 29 0a 0a 0a 64   m.group(1))...d
4520: 65 66 20 6c 6f 6f 6b 20 28 73 2c 20 73 50 61 74  ef look (s, sPat
4530: 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65 72  tern, sNegPatter
4540: 6e 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 73 65  n=None):.    "se
4550: 65 6b 20 73 50 61 74 74 65 72 6e 20 69 6e 20 73  ek sPattern in s
4560: 20 28 62 65 66 6f 72 65 2f 61 66 74 65 72 2f 66   (before/after/f
4570: 75 6c 6c 74 65 78 74 29 2c 20 69 66 20 73 4e 65  ulltext), if sNe
4580: 67 50 61 74 74 65 72 6e 20 6e 6f 74 20 69 6e 20  gPattern not in 
4590: 73 22 0a 20 20 20 20 69 66 20 73 4e 65 67 50 61  s".    if sNegPa
45a0: 74 74 65 72 6e 20 61 6e 64 20 72 65 2e 73 65 61  ttern and re.sea
45b0: 72 63 68 28 73 4e 65 67 50 61 74 74 65 72 6e 2c  rch(sNegPattern,
45c0: 20 73 29 3a 0a 20 20 20 20 20 20 20 20 72 65 74   s):.        ret
45d0: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 69 66  urn False.    if
45e0: 20 72 65 2e 73 65 61 72 63 68 28 73 50 61 74 74   re.search(sPatt
45f0: 65 72 6e 2c 20 73 29 3a 0a 20 20 20 20 20 20 20  ern, s):.       
4600: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20   return True.   
4610: 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 0a 0a   return False...
4620: 64 65 66 20 6c 6f 6f 6b 5f 63 68 6b 31 20 28 64  def look_chk1 (d
4630: 44 41 2c 20 73 2c 20 6e 4f 66 66 73 65 74 2c 20  DA, s, nOffset, 
4640: 73 50 61 74 74 65 72 6e 2c 20 73 50 61 74 74 65  sPattern, sPatte
4650: 72 6e 47 72 6f 75 70 31 2c 20 73 4e 65 67 50 61  rnGroup1, sNegPa
4660: 74 74 65 72 6e 47 72 6f 75 70 31 3d 4e 6f 6e 65  tternGroup1=None
4670: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20  ):.    "returns 
4680: 54 72 75 65 20 69 66 20 73 20 68 61 73 20 70 61  True if s has pa
4690: 74 74 65 72 6e 20 73 50 61 74 74 65 72 6e 20 61  ttern sPattern a
46a0: 6e 64 20 6d 2e 67 72 6f 75 70 28 31 29 20 68 61  nd m.group(1) ha
46b0: 73 20 70 61 74 74 65 72 6e 20 73 50 61 74 74 65  s pattern sPatte
46c0: 72 6e 47 72 6f 75 70 31 22 0a 20 20 20 20 6d 20  rnGroup1".    m 
46d0: 3d 20 72 65 2e 73 65 61 72 63 68 28 73 50 61 74  = re.search(sPat
46e0: 74 65 72 6e 2c 20 73 29 0a 20 20 20 20 69 66 20  tern, s).    if 
46f0: 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 72  not m:.        r
4700: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
4710: 74 72 79 3a 0a 20 20 20 20 20 20 20 20 73 57 6f  try:.        sWo
4720: 72 64 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29 0a  rd = m.group(1).
4730: 20 20 20 20 20 20 20 20 6e 50 6f 73 20 3d 20 6d          nPos = m
4740: 2e 73 74 61 72 74 28 31 29 20 2b 20 6e 4f 66 66  .start(1) + nOff
4750: 73 65 74 0a 20 20 20 20 65 78 63 65 70 74 3a 0a  set.    except:.
4760: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46          return F
4770: 61 6c 73 65 0a 20 20 20 20 69 66 20 73 4e 65 67  alse.    if sNeg
4780: 50 61 74 74 65 72 6e 47 72 6f 75 70 31 3a 0a 20  PatternGroup1:. 
4790: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 6d 6f         return mo
47a0: 72 70 68 65 78 28 64 44 41 2c 20 28 6e 50 6f 73  rphex(dDA, (nPos
47b0: 2c 20 73 57 6f 72 64 29 2c 20 73 50 61 74 74 65  , sWord), sPatte
47c0: 72 6e 47 72 6f 75 70 31 2c 20 73 4e 65 67 50 61  rnGroup1, sNegPa
47d0: 74 74 65 72 6e 47 72 6f 75 70 31 29 0a 20 20 20  tternGroup1).   
47e0: 20 72 65 74 75 72 6e 20 6d 6f 72 70 68 28 64 44   return morph(dD
47f0: 41 2c 20 28 6e 50 6f 73 2c 20 73 57 6f 72 64 29  A, (nPos, sWord)
4800: 2c 20 73 50 61 74 74 65 72 6e 47 72 6f 75 70 31  , sPatternGroup1
4810: 2c 20 46 61 6c 73 65 29 0a 0a 0a 23 23 23 23 20  , False)...#### 
4820: 44 69 73 61 6d 62 69 67 75 61 74 6f 72 0a 0a 64  Disambiguator..d
4830: 65 66 20 73 65 6c 65 63 74 20 28 64 44 41 2c 20  ef select (dDA, 
4840: 6e 50 6f 73 2c 20 73 57 6f 72 64 2c 20 73 50 61  nPos, sWord, sPa
4850: 74 74 65 72 6e 2c 20 6c 44 65 66 61 75 6c 74 3d  ttern, lDefault=
4860: 4e 6f 6e 65 29 3a 0a 20 20 20 20 69 66 20 6e 6f  None):.    if no
4870: 74 20 73 57 6f 72 64 3a 0a 20 20 20 20 20 20 20  t sWord:.       
4880: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20   return True.   
4890: 20 69 66 20 6e 50 6f 73 20 69 6e 20 64 44 41 3a   if nPos in dDA:
48a0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
48b0: 54 72 75 65 0a 20 20 20 20 6c 4d 6f 72 70 68 20  True.    lMorph 
48c0: 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  = _oSpellChecker
48d0: 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64 29  .getMorph(sWord)
48e0: 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72  .    if not lMor
48f0: 70 68 20 6f 72 20 6c 65 6e 28 6c 4d 6f 72 70 68  ph or len(lMorph
4900: 29 20 3d 3d 20 31 3a 0a 20 20 20 20 20 20 20 20  ) == 1:.        
4910: 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20  return True.    
4920: 6c 53 65 6c 65 63 74 20 3d 20 5b 20 73 4d 6f 72  lSelect = [ sMor
4930: 70 68 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69  ph  for sMorph i
4940: 6e 20 6c 4d 6f 72 70 68 20 20 69 66 20 72 65 2e  n lMorph  if re.
4950: 73 65 61 72 63 68 28 73 50 61 74 74 65 72 6e 2c  search(sPattern,
4960: 20 73 4d 6f 72 70 68 29 20 5d 0a 20 20 20 20 69   sMorph) ].    i
4970: 66 20 6c 53 65 6c 65 63 74 3a 0a 20 20 20 20 20  f lSelect:.     
4980: 20 20 20 69 66 20 6c 65 6e 28 6c 53 65 6c 65 63     if len(lSelec
4990: 74 29 20 21 3d 20 6c 65 6e 28 6c 4d 6f 72 70 68  t) != len(lMorph
49a0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64  ):.            d
49b0: 44 41 5b 6e 50 6f 73 5d 20 3d 20 6c 53 65 6c 65  DA[nPos] = lSele
49c0: 63 74 0a 20 20 20 20 65 6c 69 66 20 6c 44 65 66  ct.    elif lDef
49d0: 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 64 44  ault:.        dD
49e0: 41 5b 6e 50 6f 73 5d 20 3d 20 6c 44 65 66 61 75  A[nPos] = lDefau
49f0: 6c 74 0a 20 20 20 20 72 65 74 75 72 6e 20 54 72  lt.    return Tr
4a00: 75 65 0a 0a 0a 64 65 66 20 65 78 63 6c 75 64 65  ue...def exclude
4a10: 20 28 64 44 41 2c 20 6e 50 6f 73 2c 20 73 57 6f   (dDA, nPos, sWo
4a20: 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 6c 44  rd, sPattern, lD
4a30: 65 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20  efault=None):.  
4a40: 20 20 69 66 20 6e 6f 74 20 73 57 6f 72 64 3a 0a    if not sWord:.
4a50: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
4a60: 72 75 65 0a 20 20 20 20 69 66 20 6e 50 6f 73 20  rue.    if nPos 
4a70: 69 6e 20 64 44 41 3a 0a 20 20 20 20 20 20 20 20  in dDA:.        
4a80: 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20  return True.    
4a90: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
4aa0: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
4ab0: 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66 20 6e  (sWord).    if n
4ac0: 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e  ot lMorph or len
4ad0: 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20  (lMorph) == 1:. 
4ae0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
4af0: 75 65 0a 20 20 20 20 6c 53 65 6c 65 63 74 20 3d  ue.    lSelect =
4b00: 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72 20 73   [ sMorph  for s
4b10: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20  Morph in lMorph 
4b20: 20 69 66 20 6e 6f 74 20 72 65 2e 73 65 61 72 63   if not re.searc
4b30: 68 28 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72  h(sPattern, sMor
4b40: 70 68 29 20 5d 0a 20 20 20 20 69 66 20 6c 53 65  ph) ].    if lSe
4b50: 6c 65 63 74 3a 0a 20 20 20 20 20 20 20 20 69 66  lect:.        if
4b60: 20 6c 65 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d   len(lSelect) !=
4b70: 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20   len(lMorph):.  
4b80: 20 20 20 20 20 20 20 20 20 20 64 44 41 5b 6e 50            dDA[nP
4b90: 6f 73 5d 20 3d 20 6c 53 65 6c 65 63 74 0a 20 20  os] = lSelect.  
4ba0: 20 20 65 6c 69 66 20 6c 44 65 66 61 75 6c 74 3a    elif lDefault:
4bb0: 0a 20 20 20 20 20 20 20 20 64 44 41 5b 6e 50 6f  .        dDA[nPo
4bc0: 73 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20  s] = lDefault.  
4bd0: 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a    return True...
4be0: 64 65 66 20 64 65 66 69 6e 65 20 28 64 44 41 2c  def define (dDA,
4bf0: 20 6e 50 6f 73 2c 20 6c 4d 6f 72 70 68 29 3a 0a   nPos, lMorph):.
4c00: 20 20 20 20 64 44 41 5b 6e 50 6f 73 5d 20 3d 20      dDA[nPos] = 
4c10: 6c 4d 6f 72 70 68 0a 20 20 20 20 72 65 74 75 72  lMorph.    retur
4c20: 6e 20 54 72 75 65 0a 0a 0a 23 23 23 23 20 47 52  n True...#### GR
4c30: 41 4d 4d 41 52 20 43 48 45 43 4b 45 52 20 50 4c  AMMAR CHECKER PL
4c40: 55 47 49 4e 53 0a 0a 24 7b 70 6c 75 67 69 6e 73  UGINS..${plugins
4c50: 7d 0a 0a 0a 0a 23 23 23 23 20 54 4f 4b 45 4e 20  }....#### TOKEN 
4c60: 53 45 4e 54 45 4e 43 45 20 43 48 45 43 4b 45 52  SENTENCE CHECKER
4c70: 0a 0a 63 6c 61 73 73 20 54 6f 6b 65 6e 53 65 6e  ..class TokenSen
4c80: 74 65 6e 63 65 3a 0a 0a 20 20 20 20 64 65 66 20  tence:..    def 
4c90: 5f 5f 69 6e 69 74 5f 5f 20 28 73 65 6c 66 2c 20  __init__ (self, 
4ca0: 73 53 65 6e 74 65 6e 63 65 2c 20 73 53 65 6e 74  sSentence, sSent
4cb0: 65 6e 63 65 30 2c 20 6e 4f 66 66 73 65 74 29 3a  ence0, nOffset):
4cc0: 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 73 53  .        self.sS
4cd0: 65 6e 74 65 6e 63 65 20 3d 20 73 53 65 6e 74 65  entence = sSente
4ce0: 6e 63 65 0a 20 20 20 20 20 20 20 20 73 65 6c 66  nce.        self
4cf0: 2e 73 53 65 6e 74 65 6e 63 65 30 20 3d 20 73 53  .sSentence0 = sS
4d00: 65 6e 74 65 6e 63 65 30 0a 20 20 20 20 20 20 20  entence0.       
4d10: 20 73 65 6c 66 2e 6e 4f 66 66 73 65 74 20 3d 20   self.nOffset = 
4d20: 6e 4f 66 66 73 65 74 0a 20 20 20 20 20 20 20 20  nOffset.        
4d30: 73 65 6c 66 2e 6c 54 6f 6b 65 6e 20 3d 20 6c 69  self.lToken = li
4d40: 73 74 28 5f 6f 54 6f 6b 65 6e 69 7a 65 72 2e 67  st(_oTokenizer.g
4d50: 65 6e 54 6f 6b 65 6e 73 28 73 53 65 6e 74 65 6e  enTokens(sSenten
4d60: 63 65 2c 20 54 72 75 65 29 29 0a 20 20 20 20 20  ce, True)).     
4d70: 20 20 20 73 65 6c 66 2e 64 54 6f 6b 65 6e 50 6f     self.dTokenPo
4d80: 73 20 3d 20 7b 20 64 54 6f 6b 65 6e 5b 22 6e 53  s = { dToken["nS
4d90: 74 61 72 74 22 5d 3a 20 64 54 6f 6b 65 6e 20 20  tart"]: dToken  
4da0: 66 6f 72 20 64 54 6f 6b 65 6e 20 69 6e 20 73 65  for dToken in se
4db0: 6c 66 2e 6c 54 6f 6b 65 6e 20 7d 0a 20 20 20 20  lf.lToken }.    
4dc0: 20 20 20 20 73 65 6c 66 2e 63 72 65 61 74 65 45      self.createE
4dd0: 72 72 6f 72 20 3d 20 73 65 6c 66 2e 5f 63 72 65  rror = self._cre
4de0: 61 74 65 57 72 69 74 65 72 45 72 72 6f 72 20 20  ateWriterError  
4df0: 69 66 20 5f 62 57 72 69 74 65 72 45 72 72 6f 72  if _bWriterError
4e00: 20 20 65 6c 73 65 20 73 65 6c 66 2e 5f 63 72 65    else self._cre
4e10: 61 74 65 44 69 63 74 45 72 72 6f 72 0a 0a 20 20  ateDictError..  
4e20: 20 20 64 65 66 20 75 70 64 61 74 65 20 28 73 65    def update (se
4e30: 6c 66 2c 20 73 53 65 6e 74 65 6e 63 65 29 3a 0a  lf, sSentence):.
4e40: 20 20 20 20 20 20 20 20 73 65 6c 66 2e 73 53 65          self.sSe
4e50: 6e 74 65 6e 63 65 20 3d 20 73 53 65 6e 74 65 6e  ntence = sSenten
4e60: 63 65 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e  ce.        self.
4e70: 6c 54 6f 6b 65 6e 20 3d 20 6c 69 73 74 28 5f 6f  lToken = list(_o
4e80: 54 6f 6b 65 6e 69 7a 65 72 2e 67 65 6e 54 6f 6b  Tokenizer.genTok
4e90: 65 6e 73 28 73 53 65 6e 74 65 6e 63 65 2c 20 54  ens(sSentence, T
4ea0: 72 75 65 29 29 0a 0a 20 20 20 20 64 65 66 20 5f  rue))..    def _
4eb0: 67 65 74 4e 65 78 74 4d 61 74 63 68 69 6e 67 4e  getNextMatchingN
4ec0: 6f 64 65 73 20 28 73 65 6c 66 2c 20 64 54 6f 6b  odes (self, dTok
4ed0: 65 6e 2c 20 64 47 72 61 70 68 2c 20 64 4e 6f 64  en, dGraph, dNod
4ee0: 65 29 3a 0a 20 20 20 20 20 20 20 20 22 67 65 6e  e):.        "gen
4ef0: 65 72 61 74 6f 72 3a 20 72 65 74 75 72 6e 20 6e  erator: return n
4f00: 6f 64 65 73 20 77 68 65 72 65 20 3c 64 54 6f 6b  odes where <dTok
4f10: 65 6e 3e 20 e2 80 9c 76 61 6c 75 65 73 e2 80 9d  en> ...values...
4f20: 20 6d 61 74 63 68 20 3c 64 4e 6f 64 65 3e 20 61   match <dNode> a
4f30: 72 63 73 22 0a 20 20 20 20 20 20 20 20 23 20 74  rcs".        # t
4f40: 6f 6b 65 6e 20 76 61 6c 75 65 0a 20 20 20 20 20  oken value.     
4f50: 20 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73 56     if dToken["sV
4f60: 61 6c 75 65 22 5d 20 69 6e 20 64 4e 6f 64 65 3a  alue"] in dNode:
4f70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 70 72  .            #pr
4f80: 69 6e 74 28 22 76 61 6c 75 65 20 66 6f 75 6e 64  int("value found
4f90: 3a 20 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61  : ", dToken["sVa
4fa0: 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20 20 20  lue"]).         
4fb0: 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b     yield dGraph[
4fc0: 64 4e 6f 64 65 5b 64 54 6f 6b 65 6e 5b 22 73 56  dNode[dToken["sV
4fd0: 61 6c 75 65 22 5d 5d 5d 0a 20 20 20 20 20 20 20  alue"]]].       
4fe0: 20 23 20 74 6f 6b 65 6e 20 6c 65 6d 6d 61 73 0a   # token lemmas.
4ff0: 20 20 20 20 20 20 20 20 69 66 20 22 3c 6c 65 6d          if "<lem
5000: 6d 61 73 3e 22 20 69 6e 20 64 4e 6f 64 65 3a 0a  mas>" in dNode:.
5010: 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20              for 
5020: 73 4c 65 6d 6d 61 20 69 6e 20 5f 6f 53 70 65 6c  sLemma in _oSpel
5030: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d  lChecker.getLemm
5040: 61 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65  a(dToken["sValue
5050: 22 5d 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "]):.           
5060: 20 20 20 20 20 69 66 20 73 4c 65 6d 6d 61 20 69       if sLemma i
5070: 6e 20 64 4e 6f 64 65 5b 22 3c 6c 65 6d 6d 61 73  n dNode["<lemmas
5080: 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20  >"]:.           
5090: 20 20 20 20 20 20 20 20 20 23 70 72 69 6e 74 28           #print(
50a0: 22 6c 65 6d 6d 61 20 66 6f 75 6e 64 3a 20 22 2c  "lemma found: ",
50b0: 20 73 4c 65 6d 6d 61 29 0a 20 20 20 20 20 20 20   sLemma).       
50c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65               yie
50d0: 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b  ld dGraph[dNode[
50e0: 22 3c 6c 65 6d 6d 61 73 3e 22 5d 5b 73 4c 65 6d  "<lemmas>"][sLem
50f0: 6d 61 5d 5d 0a 20 20 20 20 20 20 20 20 23 20 75  ma]].        # u
5100: 6e 69 76 65 72 73 61 6c 20 61 72 63 0a 20 20 20  niversal arc.   
5110: 20 20 20 20 20 69 66 20 22 2a 22 20 69 6e 20 64       if "*" in d
5120: 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20 20  Node:.          
5130: 20 20 23 70 72 69 6e 74 28 22 67 65 6e 65 72 69    #print("generi
5140: 63 20 61 72 63 22 29 0a 20 20 20 20 20 20 20 20  c arc").        
5150: 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68      yield dGraph
5160: 5b 64 4e 6f 64 65 5b 22 2a 22 5d 5d 0a 20 20 20  [dNode["*"]].   
5170: 20 20 20 20 20 23 20 72 65 67 65 78 20 76 61 6c       # regex val
5180: 75 65 20 61 72 63 73 0a 20 20 20 20 20 20 20 20  ue arcs.        
5190: 69 66 20 22 3c 72 65 5f 76 61 6c 75 65 3e 22 20  if "<re_value>" 
51a0: 69 6e 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20  in dNode:.      
51b0: 20 20 20 20 20 20 66 6f 72 20 73 52 65 67 65 78        for sRegex
51c0: 20 69 6e 20 64 4e 6f 64 65 5b 22 3c 72 65 5f 76   in dNode["<re_v
51d0: 61 6c 75 65 3e 22 5d 3a 0a 20 20 20 20 20 20 20  alue>"]:.       
51e0: 20 20 20 20 20 20 20 20 20 69 66 20 72 65 2e 73           if re.s
51f0: 65 61 72 63 68 28 73 52 65 67 65 78 2c 20 64 54  earch(sRegex, dT
5200: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 3a  oken["sValue"]):
5210: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5220: 20 20 20 20 20 23 70 72 69 6e 74 28 22 76 61 6c       #print("val
5230: 75 65 20 72 65 67 65 78 20 6d 61 74 63 68 69 6e  ue regex matchin
5240: 67 3a 20 22 2c 20 73 52 65 67 65 78 29 0a 20 20  g: ", sRegex).  
5250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5260: 20 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64    yield dGraph[d
5270: 4e 6f 64 65 5b 22 3c 72 65 5f 76 61 6c 75 65 3e  Node["<re_value>
5280: 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 20 20 20 20  "][sRegex]].    
5290: 20 20 20 20 23 20 72 65 67 65 78 20 6d 6f 72 70      # regex morp
52a0: 68 20 61 72 63 73 0a 20 20 20 20 20 20 20 20 69  h arcs.        i
52b0: 66 20 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 20 69  f "<re_morph>" i
52c0: 6e 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20  n dNode:.       
52d0: 20 20 20 20 20 66 6f 72 20 73 52 65 67 65 78 20       for sRegex 
52e0: 69 6e 20 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f  in dNode["<re_mo
52f0: 72 70 68 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20  rph>"]:.        
5300: 20 20 20 20 20 20 20 20 69 66 20 22 c2 ac 22 20          if ".." 
5310: 6e 6f 74 20 69 6e 20 73 52 65 67 65 78 3a 0a 20  not in sRegex:. 
5320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5330: 20 20 20 23 20 6e 6f 20 61 6e 74 69 2d 70 61 74     # no anti-pat
5340: 74 65 72 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tern.           
5350: 20 20 20 20 20 20 20 20 20 69 66 20 61 6e 79 28           if any(
5360: 72 65 2e 73 65 61 72 63 68 28 73 52 65 67 65 78  re.search(sRegex
5370: 2c 20 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73  , sMorph)  for s
5380: 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c  Morph in _oSpell
5390: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
53a0: 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22  (dToken["sValue"
53b0: 5d 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ])):.           
53c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65               yie
53d0: 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b  ld dGraph[dNode[
53e0: 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 5d 5b 73 52  "<re_morph>"][sR
53f0: 65 67 65 78 5d 5d 0a 20 20 20 20 20 20 20 20 20  egex]].         
5400: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
5410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5420: 20 23 20 74 68 65 72 65 20 69 73 20 61 6e 20 61   # there is an a
5430: 6e 74 69 2d 70 61 74 74 65 72 6e 0a 20 20 20 20  nti-pattern.    
5440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5450: 73 50 61 74 74 65 72 6e 2c 20 73 4e 65 67 50 61  sPattern, sNegPa
5460: 74 74 65 72 6e 20 3d 20 73 52 65 67 65 78 2e 73  ttern = sRegex.s
5470: 70 6c 69 74 28 22 c2 ac 22 2c 20 31 29 0a 20 20  plit("..", 1).  
5480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5490: 20 20 69 66 20 73 4e 65 67 50 61 74 74 65 72 6e    if sNegPattern
54a0: 20 3d 3d 20 22 2a 22 3a 0a 20 20 20 20 20 20 20   == "*":.       
54b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54c0: 20 23 20 61 6c 6c 20 6d 6f 72 70 68 6f 6c 6f 67   # all morpholog
54d0: 69 65 73 20 6d 75 73 74 20 6d 61 74 63 68 20 77  ies must match w
54e0: 69 74 68 20 3c 73 50 61 74 74 65 72 6e 3e 0a 20  ith <sPattern>. 
54f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5500: 20 20 20 20 20 20 20 69 66 20 61 6c 6c 28 72 65         if all(re
5510: 2e 73 65 61 72 63 68 28 73 50 61 74 74 65 72 6e  .search(sPattern
5520: 2c 20 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73  , sMorph)  for s
5530: 4d 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c  Morph in _oSpell
5540: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
5550: 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22  (dToken["sValue"
5560: 5d 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ])):.           
5570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5580: 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e   yield dGraph[dN
5590: 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70 68 3e 22  ode["<re_morph>"
55a0: 5d 5b 73 52 65 67 65 78 5d 5d 0a 20 20 20 20 20  ][sRegex]].     
55b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
55c0: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
55d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
55e0: 73 4e 65 67 50 61 74 74 65 72 6e 20 61 6e 64 20  sNegPattern and 
55f0: 61 6e 79 28 72 65 2e 73 65 61 72 63 68 28 73 4e  any(re.search(sN
5600: 65 67 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70  egPattern, sMorp
5610: 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69  h)  for sMorph i
5620: 6e 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  n _oSpellChecker
5630: 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e  .getMorph(dToken
5640: 5b 22 73 56 61 6c 75 65 22 5d 29 29 3a 0a 20 20  ["sValue"])):.  
5650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5660: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e            contin
5670: 75 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ue.             
5680: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 61 6e             if an
5690: 79 28 72 65 2e 73 65 61 72 63 68 28 73 50 61 74  y(re.search(sPat
56a0: 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20 20 66  tern, sMorph)  f
56b0: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
56c0: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
56d0: 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61  orph(dToken["sVa
56e0: 6c 75 65 22 5d 29 29 3a 0a 20 20 20 20 20 20 20  lue"])):.       
56f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5700: 20 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70       yield dGrap
5710: 68 5b 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72  h[dNode["<re_mor
5720: 70 68 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 0a  ph>"][sRegex]]..
5730: 20 20 20 20 64 65 66 20 70 61 72 73 65 20 28 73      def parse (s
5740: 65 6c 66 2c 20 64 47 72 61 70 68 2c 20 64 50 72  elf, dGraph, dPr
5750: 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e 74 72 79  iority, sCountry
5760: 3d 22 24 7b 63 6f 75 6e 74 72 79 5f 64 65 66 61  ="${country_defa
5770: 75 6c 74 7d 22 2c 20 64 4f 70 74 69 6f 6e 73 3d  ult}", dOptions=
5780: 4e 6f 6e 65 2c 20 62 53 68 6f 77 52 75 6c 65 49  None, bShowRuleI
5790: 64 3d 46 61 6c 73 65 2c 20 62 44 65 62 75 67 3d  d=False, bDebug=
57a0: 46 61 6c 73 65 2c 20 62 43 6f 6e 74 65 78 74 3d  False, bContext=
57b0: 46 61 6c 73 65 29 3a 0a 20 20 20 20 20 20 20 20  False):.        
57c0: 64 45 72 72 20 3d 20 7b 7d 0a 20 20 20 20 20 20  dErr = {}.      
57d0: 20 20 64 50 72 69 6f 72 69 74 79 20 3d 20 7b 7d    dPriority = {}
57e0: 20 20 23 20 4b 65 79 20 3d 20 70 6f 73 69 74 69    # Key = positi
57f0: 6f 6e 3b 20 76 61 6c 75 65 20 3d 20 70 72 69 6f  on; value = prio
5800: 72 69 74 79 0a 20 20 20 20 20 20 20 20 64 4f 70  rity.        dOp
5810: 74 20 3d 20 5f 64 4f 70 74 69 6f 6e 73 20 20 69  t = _dOptions  i
5820: 66 20 6e 6f 74 20 64 4f 70 74 69 6f 6e 73 20 20  f not dOptions  
5830: 65 6c 73 65 20 64 4f 70 74 69 6f 6e 73 0a 20 20  else dOptions.  
5840: 20 20 20 20 20 20 6c 50 6f 69 6e 74 65 72 20 3d        lPointer =
5850: 20 5b 5d 0a 20 20 20 20 20 20 20 20 62 43 68 61   [].        bCha
5860: 6e 67 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20  nge = False.    
5870: 20 20 20 20 66 6f 72 20 64 54 6f 6b 65 6e 20 69      for dToken i
5880: 6e 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 3a 0a 20  n self.lToken:. 
5890: 20 20 20 20 20 20 20 20 20 20 20 23 20 63 68 65             # che
58a0: 63 6b 20 61 72 63 73 20 66 6f 72 20 65 61 63 68  ck arcs for each
58b0: 20 65 78 69 73 74 69 6e 67 20 70 6f 69 6e 74 65   existing pointe
58c0: 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 4e  r.            lN
58d0: 65 78 74 50 6f 69 6e 74 65 72 20 3d 20 5b 5d 0a  extPointer = [].
58e0: 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20              for 
58f0: 64 50 6f 69 6e 74 65 72 20 69 6e 20 6c 50 6f 69  dPointer in lPoi
5900: 6e 74 65 72 3a 0a 20 20 20 20 20 20 20 20 20 20  nter:.          
5910: 20 20 20 20 20 20 66 6f 72 20 64 4e 6f 64 65 20        for dNode 
5920: 69 6e 20 73 65 6c 66 2e 5f 67 65 74 4e 65 78 74  in self._getNext
5930: 4d 61 74 63 68 69 6e 67 4e 6f 64 65 73 28 64 54  MatchingNodes(dT
5940: 6f 6b 65 6e 2c 20 64 47 72 61 70 68 2c 20 64 50  oken, dGraph, dP
5950: 6f 69 6e 74 65 72 5b 22 64 4e 6f 64 65 22 5d 29  ointer["dNode"])
5960: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5970: 20 20 20 20 20 20 6c 4e 65 78 74 50 6f 69 6e 74        lNextPoint
5980: 65 72 2e 61 70 70 65 6e 64 28 7b 22 69 54 6f 6b  er.append({"iTok
5990: 65 6e 22 3a 20 64 50 6f 69 6e 74 65 72 5b 22 69  en": dPointer["i
59a0: 54 6f 6b 65 6e 22 5d 2c 20 22 64 4e 6f 64 65 22  Token"], "dNode"
59b0: 3a 20 64 4e 6f 64 65 7d 29 0a 20 20 20 20 20 20  : dNode}).      
59c0: 20 20 20 20 20 20 6c 50 6f 69 6e 74 65 72 20 3d        lPointer =
59d0: 20 6c 4e 65 78 74 50 6f 69 6e 74 65 72 0a 20 20   lNextPointer.  
59e0: 20 20 20 20 20 20 20 20 20 20 23 20 63 68 65 63            # chec
59f0: 6b 20 61 72 63 73 20 6f 66 20 66 69 72 73 74 20  k arcs of first 
5a00: 6e 6f 64 65 73 0a 20 20 20 20 20 20 20 20 20 20  nodes.          
5a10: 20 20 66 6f 72 20 64 4e 6f 64 65 20 69 6e 20 73    for dNode in s
5a20: 65 6c 66 2e 5f 67 65 74 4e 65 78 74 4d 61 74 63  elf._getNextMatc
5a30: 68 69 6e 67 4e 6f 64 65 73 28 64 54 6f 6b 65 6e  hingNodes(dToken
5a40: 2c 20 64 47 72 61 70 68 2c 20 64 47 72 61 70 68  , dGraph, dGraph
5a50: 5b 30 5d 29 3a 0a 20 20 20 20 20 20 20 20 20 20  [0]):.          
5a60: 20 20 20 20 20 20 6c 50 6f 69 6e 74 65 72 2e 61        lPointer.a
5a70: 70 70 65 6e 64 28 7b 22 69 54 6f 6b 65 6e 22 3a  ppend({"iToken":
5a80: 20 64 54 6f 6b 65 6e 5b 22 69 22 5d 2c 20 22 64   dToken["i"], "d
5a90: 4e 6f 64 65 22 3a 20 64 4e 6f 64 65 7d 29 0a 20  Node": dNode}). 
5aa0: 20 20 20 20 20 20 20 20 20 20 20 23 20 63 68 65             # che
5ab0: 63 6b 20 69 66 20 74 68 65 72 65 20 69 73 20 72  ck if there is r
5ac0: 75 6c 65 73 20 74 6f 20 63 68 65 63 6b 20 66 6f  ules to check fo
5ad0: 72 20 65 61 63 68 20 70 6f 69 6e 74 65 72 0a 20  r each pointer. 
5ae0: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 64             for d
5af0: 50 6f 69 6e 74 65 72 20 69 6e 20 6c 50 6f 69 6e  Pointer in lPoin
5b00: 74 65 72 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ter:.           
5b10: 20 20 20 20 20 69 66 20 22 3c 72 75 6c 65 73 3e       if "<rules>
5b20: 22 20 69 6e 20 64 50 6f 69 6e 74 65 72 5b 22 64  " in dPointer["d
5b30: 4e 6f 64 65 22 5d 3a 0a 20 20 20 20 20 20 20 20  Node"]:.        
5b40: 20 20 20 20 20 20 20 20 20 20 20 20 62 48 61 73              bHas
5b50: 43 68 61 6e 67 65 64 2c 20 65 72 72 73 20 3d 20  Changed, errs = 
5b60: 73 65 6c 66 2e 5f 65 78 65 63 75 74 65 41 63 74  self._executeAct
5b70: 69 6f 6e 73 28 64 47 72 61 70 68 2c 20 64 50 6f  ions(dGraph, dPo
5b80: 69 6e 74 65 72 5b 22 64 4e 6f 64 65 22 5d 5b 22  inter["dNode"]["
5b90: 3c 72 75 6c 65 73 3e 22 5d 2c 20 64 50 6f 69 6e  <rules>"], dPoin
5ba0: 74 65 72 5b 22 69 54 6f 6b 65 6e 22 5d 2d 31 2c  ter["iToken"]-1,
5bb0: 20 64 50 72 69 6f 72 69 74 79 2c 20 64 4f 70 74   dPriority, dOpt
5bc0: 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 53 68 6f  , sCountry, bSho
5bd0: 77 52 75 6c 65 49 64 2c 20 62 44 65 62 75 67 2c  wRuleId, bDebug,
5be0: 20 62 43 6f 6e 74 65 78 74 29 0a 20 20 20 20 20   bContext).     
5bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
5c00: 45 72 72 2e 75 70 64 61 74 65 28 65 72 72 73 29  Err.update(errs)
5c10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5c20: 20 20 20 20 20 69 66 20 62 48 61 73 43 68 61 6e       if bHasChan
5c30: 67 65 64 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ged:.           
5c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 43 68               bCh
5c50: 61 6e 67 65 20 3d 20 54 72 75 65 0a 20 20 20 20  ange = True.    
5c60: 20 20 20 20 72 65 74 75 72 6e 20 28 62 43 68 61      return (bCha
5c70: 6e 67 65 2c 20 64 45 72 72 29 0a 0a 20 20 20 20  nge, dErr)..    
5c80: 64 65 66 20 5f 65 78 65 63 75 74 65 41 63 74 69  def _executeActi
5c90: 6f 6e 73 20 28 73 65 6c 66 2c 20 64 47 72 61 70  ons (self, dGrap
5ca0: 68 2c 20 64 4e 6f 64 65 2c 20 6e 54 6f 6b 65 6e  h, dNode, nToken
5cb0: 4f 66 66 73 65 74 2c 20 64 50 72 69 6f 72 69 74  Offset, dPriorit
5cc0: 79 2c 20 64 4f 70 74 69 6f 6e 73 2c 20 73 43 6f  y, dOptions, sCo
5cd0: 75 6e 74 72 79 2c 20 62 53 68 6f 77 52 75 6c 65  untry, bShowRule
5ce0: 49 64 2c 20 62 44 65 62 75 67 2c 20 62 43 6f 6e  Id, bDebug, bCon
5cf0: 74 65 78 74 29 3a 0a 20 20 20 20 20 20 20 20 22  text):.        "
5d00: 65 78 65 63 75 74 65 20 61 63 74 69 6f 6e 73 20  execute actions 
5d10: 66 6f 75 6e 64 20 69 6e 20 74 68 65 20 44 41 52  found in the DAR
5d20: 47 22 0a 20 20 20 20 20 20 20 20 64 45 72 72 73  G".        dErrs
5d30: 20 3d 20 7b 7d 0a 20 20 20 20 20 20 20 20 62 43   = {}.        bC
5d40: 68 61 6e 67 65 20 3d 20 46 61 6c 73 65 0a 20 20  hange = False.  
5d50: 20 20 20 20 20 20 66 6f 72 20 73 4c 69 6e 65 49        for sLineI
5d60: 64 2c 20 6e 65 78 74 4e 6f 64 65 4b 65 79 20 69  d, nextNodeKey i
5d70: 6e 20 64 4e 6f 64 65 2e 69 74 65 6d 73 28 29 3a  n dNode.items():
5d80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
5d90: 20 73 52 75 6c 65 49 64 20 69 6e 20 64 47 72 61   sRuleId in dGra
5da0: 70 68 5b 6e 65 78 74 4e 6f 64 65 4b 65 79 5d 3a  ph[nextNodeKey]:
5db0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5dc0: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 20 20   try:.          
5dd0: 20 20 20 20 20 20 20 20 20 20 62 43 6f 6e 64 4d            bCondM
5de0: 65 6d 6f 20 3d 20 4e 6f 6e 65 0a 20 20 20 20 20  emo = None.     
5df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
5e00: 4f 70 74 69 6f 6e 2c 20 73 46 75 6e 63 43 6f 6e  Option, sFuncCon
5e10: 64 2c 20 63 41 63 74 69 6f 6e 54 79 70 65 2c 20  d, cActionType, 
5e20: 73 57 68 61 74 2c 20 2a 65 41 63 74 20 3d 20 64  sWhat, *eAct = d
5e30: 52 75 6c 65 5b 73 52 75 6c 65 49 64 5d 0a 20 20  Rule[sRuleId].  
5e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e50: 20 20 23 20 61 63 74 69 6f 6e 20 69 6e 20 6c 41    # action in lA
5e60: 63 74 69 6f 6e 73 3a 20 5b 20 63 6f 6e 64 69 74  ctions: [ condit
5e70: 69 6f 6e 2c 20 61 63 74 69 6f 6e 20 74 79 70 65  ion, action type
5e80: 2c 20 72 65 70 6c 61 63 65 6d 65 6e 74 2f 73 75  , replacement/su
5e90: 67 67 65 73 74 69 6f 6e 2f 61 63 74 69 6f 6e 5b  ggestion/action[
5ea0: 2c 20 69 54 6f 6b 65 6e 53 74 61 72 74 2c 20 69  , iTokenStart, i
5eb0: 54 6f 6b 65 6e 45 6e 64 5b 2c 20 6e 50 72 69 6f  TokenEnd[, nPrio
5ec0: 72 69 74 79 2c 20 6d 65 73 73 61 67 65 2c 20 55  rity, message, U
5ed0: 52 4c 5d 5d 20 5d 0a 20 20 20 20 20 20 20 20 20  RL]] ].         
5ee0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 6f             if no
5ef0: 74 20 73 4f 70 74 69 6f 6e 20 6f 72 20 64 4f 70  t sOption or dOp
5f00: 74 69 6f 6e 73 2e 67 65 74 28 73 4f 70 74 69 6f  tions.get(sOptio
5f10: 6e 2c 20 46 61 6c 73 65 29 3a 0a 20 20 20 20 20  n, False):.     
5f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f30: 20 20 20 62 43 6f 6e 64 4d 65 6d 6f 20 3d 20 6e     bCondMemo = n
5f40: 6f 74 20 73 46 75 6e 63 43 6f 6e 64 20 6f 72 20  ot sFuncCond or 
5f50: 67 6c 6f 62 61 6c 73 28 29 5b 73 46 75 6e 63 43  globals()[sFuncC
5f60: 6f 6e 64 5d 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e  ond](self.lToken
5f70: 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2c 20  , nTokenOffset, 
5f80: 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f 6e 64 4d  sCountry, bCondM
5f90: 65 6d 6f 29 0a 20 20 20 20 20 20 20 20 20 20 20  emo).           
5fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
5fb0: 62 43 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20 20  bCondMemo:.     
5fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5fd0: 20 20 20 20 20 20 20 69 66 20 63 41 63 74 69 6f         if cActio
5fe0: 6e 54 79 70 65 20 3d 3d 20 22 2d 22 3a 0a 20 20  nType == "-":.  
5ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
6010: 67 72 61 6d 6d 61 72 20 65 72 72 6f 72 0a 20 20  grammar error.  
6020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 54                nT
6040: 6f 6b 65 6e 45 72 72 6f 72 53 74 61 72 74 20 3d  okenErrorStart =
6050: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20   nTokenOffset + 
6060: 65 41 63 74 5b 30 5d 0a 20 20 20 20 20 20 20 20  eAct[0].        
6070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6080: 20 20 20 20 20 20 20 20 6e 54 6f 6b 65 6e 45 72          nTokenEr
6090: 72 6f 72 45 6e 64 20 3d 20 6e 54 6f 6b 65 6e 4f  rorEnd = nTokenO
60a0: 66 66 73 65 74 20 2b 20 65 41 63 74 5b 31 5d 0a  ffset + eAct[1].
60b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60d0: 6e 45 72 72 6f 72 53 74 61 72 74 20 3d 20 73 65  nErrorStart = se
60e0: 6c 66 2e 6e 4f 66 66 73 65 74 20 2b 20 73 65 6c  lf.nOffset + sel
60f0: 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 45  f.lToken[nTokenE
6100: 72 72 6f 72 53 74 61 72 74 5d 5b 22 6e 53 74 61  rrorStart]["nSta
6110: 72 74 22 5d 0a 20 20 20 20 20 20 20 20 20 20 20  rt"].           
6120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6130: 20 20 20 20 20 6e 45 72 72 6f 72 45 6e 64 20 3d       nErrorEnd =
6140: 20 73 65 6c 66 2e 6e 4f 66 66 73 65 74 20 2b 20   self.nOffset + 
6150: 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b  self.lToken[nTok
6160: 65 6e 45 72 72 6f 72 45 6e 64 5d 5b 22 6e 45 6e  enErrorEnd]["nEn
6170: 64 22 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  d"].            
6180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6190: 20 20 20 20 69 66 20 6e 45 72 72 6f 72 53 74 61      if nErrorSta
61a0: 72 74 20 6e 6f 74 20 69 6e 20 64 45 72 72 73 20  rt not in dErrs 
61b0: 6f 72 20 65 41 63 74 5b 32 5d 20 3e 20 64 50 72  or eAct[2] > dPr
61c0: 69 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53 74 61  iority[nErrorSta
61d0: 72 74 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rt]:.           
61e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61f0: 20 20 20 20 20 20 20 20 20 64 45 72 72 73 5b 6e           dErrs[n
6200: 45 72 72 6f 72 53 74 61 72 74 5d 20 3d 20 73 65  ErrorStart] = se
6210: 6c 66 2e 63 72 65 61 74 65 45 72 72 6f 72 28 73  lf.createError(s
6220: 57 68 61 74 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73  What, nTokenOffs
6230: 65 74 2c 20 6e 54 6f 6b 65 6e 45 72 72 6f 72 53  et, nTokenErrorS
6240: 74 61 72 74 2c 20 6e 45 72 72 6f 72 53 74 61 72  tart, nErrorStar
6250: 74 2c 20 6e 45 72 72 6f 72 45 6e 64 2c 20 73 4c  t, nErrorEnd, sL
6260: 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20  ineId, sRuleId, 
6270: 54 72 75 65 2c 20 65 41 63 74 5b 33 5d 2c 20 65  True, eAct[3], e
6280: 41 63 74 5b 34 5d 2c 20 62 53 68 6f 77 52 75 6c  Act[4], bShowRul
6290: 65 49 64 2c 20 22 6e 6f 74 79 70 65 22 2c 20 62  eId, "notype", b
62a0: 43 6f 6e 74 65 78 74 29 0a 20 20 20 20 20 20 20  Context).       
62b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
62c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 50 72               dPr
62d0: 69 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53 74 61  iority[nErrorSta
62e0: 72 74 5d 20 3d 20 65 41 63 74 5b 32 5d 0a 20 20  rt] = eAct[2].  
62f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6310: 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20    if bDebug:.   
6320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6340: 20 20 20 20 20 70 72 69 6e 74 28 22 2d 22 2c 20       print("-", 
6350: 73 52 75 6c 65 49 64 2c 20 64 45 72 72 73 5b 6e  sRuleId, dErrs[n
6360: 45 72 72 6f 72 53 74 61 72 74 5d 29 0a 20 20 20  ErrorStart]).   
6370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6380: 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 41           elif cA
6390: 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 7e 22  ctionType == "~"
63a0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
63b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63c0: 20 20 23 20 74 65 78 74 20 70 72 6f 63 65 73 73    # text process
63d0: 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  or.             
63e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63f0: 20 20 20 73 65 6c 66 2e 5f 74 61 67 41 6e 64 50     self._tagAndP
6400: 72 65 70 61 72 65 54 6f 6b 65 6e 46 6f 72 52 65  repareTokenForRe
6410: 77 72 69 74 69 6e 67 28 73 57 68 61 74 2c 20 6e  writing(sWhat, n
6420: 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65 41  TokenOffset + eA
6430: 63 74 5b 30 5d 2c 20 6e 54 6f 6b 65 6e 4f 66 66  ct[0], nTokenOff
6440: 73 65 74 20 2b 20 65 41 63 74 5b 31 5d 29 0a 20  set + eAct[1]). 
6450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
6470: 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20  f bDebug:.      
6480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
64a0: 69 6e 74 28 22 7e 22 2c 20 73 52 75 6c 65 49 64  int("~", sRuleId
64b0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
64c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
64d0: 20 20 62 43 68 61 6e 67 65 20 3d 20 54 72 75 65    bChange = True
64e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
64f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69               eli
6500: 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d  f cActionType ==
6510: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "=":.          
6520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6530: 20 20 20 20 20 20 23 20 64 69 73 61 6d 62 69 67        # disambig
6540: 75 61 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20  uation.         
6550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6560: 20 20 20 20 20 20 20 67 6c 6f 62 61 6c 73 28 29         globals()
6570: 5b 73 57 68 61 74 5d 28 73 65 6c 66 2e 6c 54 6f  [sWhat](self.lTo
6580: 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65  ken, nTokenOffse
6590: 74 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  t).             
65a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65b0: 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20     if bDebug:.  
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 20 20 20 20 20 20 20 20                  
65e0: 20 20 70 72 69 6e 74 28 22 3d 22 2c 20 73 52 75    print("=", sRu
65f0: 6c 65 49 64 29 0a 20 20 20 20 20 20 20 20 20 20  leId).          
6600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6610: 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54 79    elif cActionTy
6620: 70 65 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20 20  pe == ">":.     
6630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6640: 20 20 20 20 20 20 20 20 20 20 20 23 20 77 65 20             # we 
6650: 64 6f 20 6e 6f 74 68 69 6e 67 2c 20 74 68 69 73  do nothing, this
6660: 20 74 65 73 74 20 69 73 20 6a 75 73 74 20 61 20   test is just a 
6670: 63 6f 6e 64 69 74 69 6f 6e 20 74 6f 20 61 70 70  condition to app
6680: 6c 79 20 61 6c 6c 20 66 6f 6c 6c 6f 77 69 6e 67  ly all following
6690: 20 61 63 74 69 6f 6e 73 0a 20 20 20 20 20 20 20   actions.       
66a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66b0: 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62           if bDeb
66c0: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
66d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66e0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 3e          print(">
66f0: 22 2c 20 73 52 75 6c 65 49 64 29 0a 20 20 20 20  ", sRuleId).    
6700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6710: 20 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73              pass
6720: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6730: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73               els
6740: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
6750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6760: 20 20 20 70 72 69 6e 74 28 22 23 20 65 72 72 6f     print("# erro
6770: 72 3a 20 75 6e 6b 6e 6f 77 6e 20 61 63 74 69 6f  r: unknown actio
6780: 6e 20 61 74 20 22 20 2b 20 73 4c 69 6e 65 49 64  n at " + sLineId
6790: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
67a0: 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63            elif c
67b0: 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 3e  ActionType == ">
67c0: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
67d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
67e0: 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20  f bDebug:.      
67f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6800: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
6810: 22 3e 21 22 2c 20 73 52 75 6c 65 49 64 29 0a 20  ">!", sRuleId). 
6820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6830: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b             break
6840: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6850: 20 65 78 63 65 70 74 20 45 78 63 65 70 74 69 6f   except Exceptio
6860: 6e 20 61 73 20 65 3a 0a 20 20 20 20 20 20 20 20  n as e:.        
6870: 20 20 20 20 20 20 20 20 20 20 20 20 72 61 69 73              rais
6880: 65 20 45 78 63 65 70 74 69 6f 6e 28 73 74 72 28  e Exception(str(
6890: 65 29 2c 20 73 4c 69 6e 65 49 64 29 0a 20 20 20  e), sLineId).   
68a0: 20 20 20 20 20 72 65 74 75 72 6e 20 62 43 68 61       return bCha
68b0: 6e 67 65 2c 20 64 45 72 72 73 0a 0a 20 20 20 20  nge, dErrs..    
68c0: 64 65 66 20 5f 63 72 65 61 74 65 57 72 69 74 65  def _createWrite
68d0: 72 45 72 72 6f 72 20 28 73 65 6c 66 2c 20 73 53  rError (self, sS
68e0: 75 67 67 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65  ugg, nTokenOffse
68f0: 74 2c 20 69 46 69 72 73 74 54 6f 6b 65 6e 2c 20  t, iFirstToken, 
6900: 6e 53 74 61 72 74 2c 20 6e 45 6e 64 2c 20 73 4c  nStart, nEnd, sL
6910: 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20  ineId, sRuleId, 
6920: 62 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73 67  bUppercase, sMsg
6930: 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75 6c  , sURL, bShowRul
6940: 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62 43  eId, sOption, bC
6950: 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20 20 20 20  ontext):.       
6960: 20 22 65 72 72 6f 72 20 66 6f 72 20 57 72 69 74   "error for Writ
6970: 65 72 20 28 4c 4f 2f 4f 4f 29 22 0a 20 20 20 20  er (LO/OO)".    
6980: 20 20 20 20 78 45 72 72 20 3d 20 53 69 6e 67 6c      xErr = Singl
6990: 65 50 72 6f 6f 66 72 65 61 64 69 6e 67 45 72 72  eProofreadingErr
69a0: 6f 72 28 29 0a 20 20 20 20 20 20 20 20 23 78 45  or().        #xE
69b0: 72 72 20 3d 20 75 6e 6f 2e 63 72 65 61 74 65 55  rr = uno.createU
69c0: 6e 6f 53 74 72 75 63 74 28 20 22 63 6f 6d 2e 73  noStruct( "com.s
69d0: 75 6e 2e 73 74 61 72 2e 6c 69 6e 67 75 69 73 74  un.star.linguist
69e0: 69 63 32 2e 53 69 6e 67 6c 65 50 72 6f 6f 66 72  ic2.SingleProofr
69f0: 65 61 64 69 6e 67 45 72 72 6f 72 22 20 29 0a 20  eadingError" ). 
6a00: 20 20 20 20 20 20 20 78 45 72 72 2e 6e 45 72 72         xErr.nErr
6a10: 6f 72 53 74 61 72 74 20 3d 20 6e 53 74 61 72 74  orStart = nStart
6a20: 0a 20 20 20 20 20 20 20 20 78 45 72 72 2e 6e 45  .        xErr.nE
6a30: 72 72 6f 72 4c 65 6e 67 74 68 20 3d 20 6e 45 6e  rrorLength = nEn
6a40: 64 20 2d 20 6e 53 74 61 72 74 0a 20 20 20 20 20  d - nStart.     
6a50: 20 20 20 78 45 72 72 2e 6e 45 72 72 6f 72 54 79     xErr.nErrorTy
6a60: 70 65 20 3d 20 50 52 4f 4f 46 52 45 41 44 49 4e  pe = PROOFREADIN
6a70: 47 0a 20 20 20 20 20 20 20 20 78 45 72 72 2e 61  G.        xErr.a
6a80: 52 75 6c 65 49 64 65 6e 74 69 66 69 65 72 20 3d  RuleIdentifier =
6a90: 20 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20 20   sRuleId.       
6aa0: 20 23 20 73 75 67 67 65 73 74 69 6f 6e 73 0a 20   # suggestions. 
6ab0: 20 20 20 20 20 20 20 69 66 20 73 53 75 67 67 5b         if sSugg[
6ac0: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
6ad0: 20 20 20 20 20 20 20 20 20 73 53 75 67 67 20 3d           sSugg =
6ae0: 20 67 6c 6f 62 61 6c 73 28 29 5b 73 53 75 67 67   globals()[sSugg
6af0: 5b 31 3a 5d 5d 28 73 65 6c 66 2e 6c 54 6f 6b 65  [1:]](self.lToke
6b00: 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29  n, nTokenOffset)
6b10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
6b20: 73 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20 20  sSugg:.         
6b30: 20 20 20 20 20 20 20 69 66 20 62 55 70 70 65 72         if bUpper
6b40: 63 61 73 65 20 61 6e 64 20 73 65 6c 66 2e 6c 54  case and self.lT
6b50: 6f 6b 65 6e 5b 69 46 69 72 73 74 54 6f 6b 65 6e  oken[iFirstToken
6b60: 5d 5b 22 73 56 61 6c 75 65 22 5d 5b 30 3a 31 5d  ]["sValue"][0:1]
6b70: 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20 20  .isupper():.    
6b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b90: 78 45 72 72 2e 61 53 75 67 67 65 73 74 69 6f 6e  xErr.aSuggestion
6ba0: 73 20 3d 20 74 75 70 6c 65 28 6d 61 70 28 73 74  s = tuple(map(st
6bb0: 72 2e 63 61 70 69 74 61 6c 69 7a 65 2c 20 73 53  r.capitalize, sS
6bc0: 75 67 67 2e 73 70 6c 69 74 28 22 7c 22 29 29 29  ugg.split("|")))
6bd0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6be0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
6bf0: 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72 2e             xErr.
6c00: 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74  aSuggestions = t
6c10: 75 70 6c 65 28 73 53 75 67 67 2e 73 70 6c 69 74  uple(sSugg.split
6c20: 28 22 7c 22 29 29 0a 20 20 20 20 20 20 20 20 20  ("|")).         
6c30: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
6c40: 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53           xErr.aS
6c50: 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 28 29 0a  uggestions = ().
6c60: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 53 75          elif sSu
6c70: 67 67 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20 20  gg == "_":.     
6c80: 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 75 67         xErr.aSug
6c90: 67 65 73 74 69 6f 6e 73 20 3d 20 28 29 0a 20 20  gestions = ().  
6ca0: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
6cb0: 20 20 20 20 20 20 20 20 69 66 20 62 55 70 70 65          if bUppe
6cc0: 72 63 61 73 65 20 61 6e 64 20 73 65 6c 66 2e 6c  rcase and self.l
6cd0: 54 6f 6b 65 6e 5b 69 46 69 72 73 74 54 6f 6b 65  Token[iFirstToke
6ce0: 6e 5d 5b 22 73 56 61 6c 75 65 22 5d 5b 30 3a 31  n]["sValue"][0:1
6cf0: 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20  ].isupper():.   
6d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 78 45 72               xEr
6d10: 72 2e 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d  r.aSuggestions =
6d20: 20 74 75 70 6c 65 28 6d 61 70 28 73 74 72 2e 63   tuple(map(str.c
6d30: 61 70 69 74 61 6c 69 7a 65 2c 20 73 65 6c 66 2e  apitalize, self.
6d40: 5f 65 78 70 61 6e 64 28 73 53 75 67 67 2c 20 6e  _expand(sSugg, n
6d50: 54 6f 6b 65 6e 4f 66 66 73 65 74 29 2e 73 70 6c  TokenOffset).spl
6d60: 69 74 28 22 7c 22 29 29 29 0a 20 20 20 20 20 20  it("|"))).      
6d70: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
6d80: 20 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72              xErr
6d90: 2e 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20  .aSuggestions = 
6da0: 74 75 70 6c 65 28 73 65 6c 66 2e 5f 65 78 70 61  tuple(self._expa
6db0: 6e 64 28 73 53 75 67 67 2c 20 6e 54 6f 6b 65 6e  nd(sSugg, nToken
6dc0: 4f 66 66 73 65 74 29 2e 73 70 6c 69 74 28 22 7c  Offset).split("|
6dd0: 22 29 29 0a 20 20 20 20 20 20 20 20 23 20 4d 65  ")).        # Me
6de0: 73 73 61 67 65 0a 20 20 20 20 20 20 20 20 73 4d  ssage.        sM
6df0: 65 73 73 61 67 65 20 3d 20 67 6c 6f 62 61 6c 73  essage = globals
6e00: 28 29 5b 73 4d 73 67 5b 31 3a 5d 5d 28 73 65 6c  ()[sMsg[1:]](sel
6e10: 66 2e 6c 54 6f 6b 65 6e 29 20 20 69 66 20 73 4d  f.lToken)  if sM
6e20: 73 67 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 20 20  sg[0:1] == "="  
6e30: 65 6c 73 65 20 73 65 6c 66 2e 5f 65 78 70 61 6e  else self._expan
6e40: 64 28 73 4d 73 67 2c 20 6e 54 6f 6b 65 6e 4f 66  d(sMsg, nTokenOf
6e50: 66 73 65 74 29 0a 20 20 20 20 20 20 20 20 78 45  fset).        xE
6e60: 72 72 2e 61 53 68 6f 72 74 43 6f 6d 6d 65 6e 74  rr.aShortComment
6e70: 20 3d 20 73 4d 65 73 73 61 67 65 20 20 20 23 20   = sMessage   # 
6e80: 73 4d 65 73 73 61 67 65 2e 73 70 6c 69 74 28 22  sMessage.split("
6e90: 7c 22 29 5b 30 5d 20 20 20 20 20 23 20 69 6e 20  |")[0]     # in 
6ea0: 63 6f 6e 74 65 78 74 20 6d 65 6e 75 0a 20 20 20  context menu.   
6eb0: 20 20 20 20 20 78 45 72 72 2e 61 46 75 6c 6c 43       xErr.aFullC
6ec0: 6f 6d 6d 65 6e 74 20 3d 20 73 4d 65 73 73 61 67  omment = sMessag
6ed0: 65 20 20 20 23 20 73 4d 65 73 73 61 67 65 2e 73  e   # sMessage.s
6ee0: 70 6c 69 74 28 22 7c 22 29 5b 2d 31 5d 20 20 20  plit("|")[-1]   
6ef0: 20 23 20 69 6e 20 64 69 61 6c 6f 67 0a 20 20 20   # in dialog.   
6f00: 20 20 20 20 20 69 66 20 62 53 68 6f 77 52 75 6c       if bShowRul
6f10: 65 49 64 3a 0a 20 20 20 20 20 20 20 20 20 20 20  eId:.           
6f20: 20 78 45 72 72 2e 61 53 68 6f 72 74 43 6f 6d 6d   xErr.aShortComm
6f30: 65 6e 74 20 2b 3d 20 22 20 20 22 20 2b 20 73 4c  ent += "  " + sL
6f40: 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20 2b 20  ineId + " # " + 
6f50: 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20 20 20  sRuleId.        
6f60: 23 20 55 52 4c 0a 20 20 20 20 20 20 20 20 69 66  # URL.        if
6f70: 20 73 55 52 4c 3a 0a 20 20 20 20 20 20 20 20 20   sURL:.         
6f80: 20 20 20 70 20 3d 20 50 72 6f 70 65 72 74 79 56     p = PropertyV
6f90: 61 6c 75 65 28 29 0a 20 20 20 20 20 20 20 20 20  alue().         
6fa0: 20 20 20 70 2e 4e 61 6d 65 20 3d 20 22 46 75 6c     p.Name = "Ful
6fb0: 6c 43 6f 6d 6d 65 6e 74 55 52 4c 22 0a 20 20 20  lCommentURL".   
6fc0: 20 20 20 20 20 20 20 20 20 70 2e 56 61 6c 75 65           p.Value
6fd0: 20 3d 20 73 55 52 4c 0a 20 20 20 20 20 20 20 20   = sURL.        
6fe0: 20 20 20 20 78 45 72 72 2e 61 50 72 6f 70 65 72      xErr.aProper
6ff0: 74 69 65 73 20 3d 20 28 70 2c 29 0a 20 20 20 20  ties = (p,).    
7000: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
7010: 20 20 20 20 20 20 78 45 72 72 2e 61 50 72 6f 70        xErr.aProp
7020: 65 72 74 69 65 73 20 3d 20 28 29 0a 20 20 20 20  erties = ().    
7030: 20 20 20 20 72 65 74 75 72 6e 20 78 45 72 72 0a      return xErr.
7040: 0a 20 20 20 20 64 65 66 20 5f 63 72 65 61 74 65  .    def _create
7050: 44 69 63 74 45 72 72 6f 72 20 28 73 65 6c 66 2c  DictError (self,
7060: 20 73 53 75 67 67 2c 20 6e 54 6f 6b 65 6e 4f 66   sSugg, nTokenOf
7070: 66 73 65 74 2c 20 69 46 69 72 73 74 54 6f 6b 65  fset, iFirstToke
7080: 6e 2c 20 6e 53 74 61 72 74 2c 20 6e 45 6e 64 2c  n, nStart, nEnd,
7090: 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49   sLineId, sRuleI
70a0: 64 2c 20 62 55 70 70 65 72 63 61 73 65 2c 20 73  d, bUppercase, s
70b0: 4d 73 67 2c 20 73 55 52 4c 2c 20 62 53 68 6f 77  Msg, sURL, bShow
70c0: 52 75 6c 65 49 64 2c 20 73 4f 70 74 69 6f 6e 2c  RuleId, sOption,
70d0: 20 62 43 6f 6e 74 65 78 74 29 3a 0a 20 20 20 20   bContext):.    
70e0: 20 20 20 20 22 65 72 72 6f 72 20 61 73 20 61 20      "error as a 
70f0: 64 69 63 74 69 6f 6e 61 72 79 22 0a 20 20 20 20  dictionary".    
7100: 20 20 20 20 64 45 72 72 20 3d 20 7b 7d 0a 20 20      dErr = {}.  
7110: 20 20 20 20 20 20 64 45 72 72 5b 22 6e 53 74 61        dErr["nSta
7120: 72 74 22 5d 20 3d 20 6e 53 74 61 72 74 0a 20 20  rt"] = nStart.  
7130: 20 20 20 20 20 20 64 45 72 72 5b 22 6e 45 6e 64        dErr["nEnd
7140: 22 5d 20 3d 20 6e 45 6e 64 0a 20 20 20 20 20 20  "] = nEnd.      
7150: 20 20 64 45 72 72 5b 22 73 4c 69 6e 65 49 64 22    dErr["sLineId"
7160: 5d 20 3d 20 73 4c 69 6e 65 49 64 0a 20 20 20 20  ] = sLineId.    
7170: 20 20 20 20 64 45 72 72 5b 22 73 52 75 6c 65 49      dErr["sRuleI
7180: 64 22 5d 20 3d 20 73 52 75 6c 65 49 64 0a 20 20  d"] = sRuleId.  
7190: 20 20 20 20 20 20 64 45 72 72 5b 22 73 54 79 70        dErr["sTyp
71a0: 65 22 5d 20 3d 20 73 4f 70 74 69 6f 6e 20 20 69  e"] = sOption  i
71b0: 66 20 73 4f 70 74 69 6f 6e 20 20 65 6c 73 65 20  f sOption  else 
71c0: 22 6e 6f 74 79 70 65 22 0a 20 20 20 20 20 20 20  "notype".       
71d0: 20 23 20 73 75 67 67 65 73 74 69 6f 6e 73 0a 20   # suggestions. 
71e0: 20 20 20 20 20 20 20 69 66 20 73 53 75 67 67 5b         if sSugg[
71f0: 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20  0:1] == "=":.   
7200: 20 20 20 20 20 20 20 20 20 73 53 75 67 67 20 3d           sSugg =
7210: 20 67 6c 6f 62 61 6c 73 28 29 5b 73 53 75 67 67   globals()[sSugg
7220: 5b 31 3a 5d 5d 28 73 65 6c 66 2e 6c 54 6f 6b 65  [1:]](self.lToke
7230: 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29  n, nTokenOffset)
7240: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
7250: 73 53 75 67 67 3a 0a 20 20 20 20 20 20 20 20 20  sSugg:.         
7260: 20 20 20 20 20 20 20 69 66 20 62 55 70 70 65 72         if bUpper
7270: 63 61 73 65 20 61 6e 64 20 73 65 6c 66 2e 6c 54  case and self.lT
7280: 6f 6b 65 6e 5b 69 46 69 72 73 74 54 6f 6b 65 6e  oken[iFirstToken
7290: 5d 5b 22 73 56 61 6c 75 65 22 5d 5b 30 3a 31 5d  ]["sValue"][0:1]
72a0: 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20 20  .isupper():.    
72b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72c0: 64 45 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f  dErr["aSuggestio
72d0: 6e 73 22 5d 20 3d 20 6c 69 73 74 28 6d 61 70 28  ns"] = list(map(
72e0: 73 74 72 2e 63 61 70 69 74 61 6c 69 7a 65 2c 20  str.capitalize, 
72f0: 73 53 75 67 67 2e 73 70 6c 69 74 28 22 7c 22 29  sSugg.split("|")
7300: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  )).             
7310: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
7320: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72               dEr
7330: 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e 73 22  r["aSuggestions"
7340: 5d 20 3d 20 73 53 75 67 67 2e 73 70 6c 69 74 28  ] = sSugg.split(
7350: 22 7c 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  "|").           
7360: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
7370: 20 20 20 20 20 20 20 64 45 72 72 5b 22 61 53 75         dErr["aSu
7380: 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20 5b 5d  ggestions"] = []
7390: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 53  .        elif sS
73a0: 75 67 67 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20  ugg == "_":.    
73b0: 20 20 20 20 20 20 20 20 64 45 72 72 5b 22 61 53          dErr["aS
73c0: 75 67 67 65 73 74 69 6f 6e 73 22 5d 20 3d 20 5b  uggestions"] = [
73d0: 5d 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a  ].        else:.
73e0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
73f0: 55 70 70 65 72 63 61 73 65 20 61 6e 64 20 73 65  Uppercase and se
7400: 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 46 69 72 73 74  lf.lToken[iFirst
7410: 54 6f 6b 65 6e 5d 5b 22 73 56 61 6c 75 65 22 5d  Token]["sValue"]
7420: 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 3a  [0:1].isupper():
7430: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7440: 20 64 45 72 72 5b 22 61 53 75 67 67 65 73 74 69   dErr["aSuggesti
7450: 6f 6e 73 22 5d 20 3d 20 6c 69 73 74 28 6d 61 70  ons"] = list(map
7460: 28 73 74 72 2e 63 61 70 69 74 61 6c 69 7a 65 2c  (str.capitalize,
7470: 20 73 65 6c 66 2e 5f 65 78 70 61 6e 64 28 73 53   self._expand(sS
7480: 75 67 67 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65  ugg, nTokenOffse
7490: 74 29 2e 73 70 6c 69 74 28 22 7c 22 29 29 29 0a  t).split("|"))).
74a0: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
74b0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
74c0: 20 20 64 45 72 72 5b 22 61 53 75 67 67 65 73 74    dErr["aSuggest
74d0: 69 6f 6e 73 22 5d 20 3d 20 73 65 6c 66 2e 5f 65  ions"] = self._e
74e0: 78 70 61 6e 64 28 73 53 75 67 67 2c 20 6e 54 6f  xpand(sSugg, nTo
74f0: 6b 65 6e 4f 66 66 73 65 74 29 2e 73 70 6c 69 74  kenOffset).split
7500: 28 22 7c 22 29 0a 20 20 20 20 20 20 20 20 23 20  ("|").        # 
7510: 4d 65 73 73 61 67 65 0a 20 20 20 20 20 20 20 20  Message.        
7520: 64 45 72 72 5b 22 73 4d 65 73 73 61 67 65 22 5d  dErr["sMessage"]
7530: 20 3d 20 67 6c 6f 62 61 6c 73 28 29 5b 73 4d 73   = globals()[sMs
7540: 67 5b 31 3a 5d 5d 28 73 65 6c 66 2e 6c 54 6f 6b  g[1:]](self.lTok
7550: 65 6e 29 20 20 69 66 20 73 4d 73 67 5b 30 3a 31  en)  if sMsg[0:1
7560: 5d 20 3d 3d 20 22 3d 22 20 20 65 6c 73 65 20 73  ] == "="  else s
7570: 65 6c 66 2e 5f 65 78 70 61 6e 64 28 73 4d 73 67  elf._expand(sMsg
7580: 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29 0a  , nTokenOffset).
7590: 20 20 20 20 20 20 20 20 69 66 20 62 53 68 6f 77          if bShow
75a0: 52 75 6c 65 49 64 3a 0a 20 20 20 20 20 20 20 20  RuleId:.        
75b0: 20 20 20 20 64 45 72 72 5b 22 73 4d 65 73 73 61      dErr["sMessa
75c0: 67 65 22 5d 20 2b 3d 20 22 20 20 22 20 2b 20 73  ge"] += "  " + s
75d0: 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20 2b  LineId + " # " +
75e0: 20 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20 20   sRuleId.       
75f0: 20 23 20 55 52 4c 0a 20 20 20 20 20 20 20 20 64   # URL.        d
7600: 45 72 72 5b 22 55 52 4c 22 5d 20 3d 20 73 55 52  Err["URL"] = sUR
7610: 4c 20 20 69 66 20 73 55 52 4c 20 20 65 6c 73 65  L  if sURL  else
7620: 20 22 22 0a 20 20 20 20 20 20 20 20 23 20 43 6f   "".        # Co
7630: 6e 74 65 78 74 0a 20 20 20 20 20 20 20 20 69 66  ntext.        if
7640: 20 62 43 6f 6e 74 65 78 74 3a 0a 20 20 20 20 20   bContext:.     
7650: 20 20 20 20 20 20 20 64 45 72 72 5b 27 73 55 6e         dErr['sUn
7660: 64 65 72 6c 69 6e 65 64 27 5d 20 3d 20 73 65 6c  derlined'] = sel
7670: 66 2e 73 53 65 6e 74 65 6e 63 65 30 5b 64 45 72  f.sSentence0[dEr
7680: 72 5b 22 6e 53 74 61 72 74 22 5d 3a 64 45 72 72  r["nStart"]:dErr
7690: 5b 22 6e 45 6e 64 22 5d 5d 0a 20 20 20 20 20 20  ["nEnd"]].      
76a0: 20 20 20 20 20 20 64 45 72 72 5b 27 73 42 65 66        dErr['sBef
76b0: 6f 72 65 27 5d 20 3d 20 73 65 6c 66 2e 73 53 65  ore'] = self.sSe
76c0: 6e 74 65 6e 63 65 30 5b 6d 61 78 28 30 2c 64 45  ntence0[max(0,dE
76d0: 72 72 5b 22 6e 53 74 61 72 74 22 5d 2d 38 30 29  rr["nStart"]-80)
76e0: 3a 64 45 72 72 5b 22 6e 53 74 61 72 74 22 5d 5d  :dErr["nStart"]]
76f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72  .            dEr
7700: 72 5b 27 73 41 66 74 65 72 27 5d 20 3d 20 73 65  r['sAfter'] = se
7710: 6c 66 2e 73 53 65 6e 74 65 6e 63 65 30 5b 64 45  lf.sSentence0[dE
7720: 72 72 5b 22 6e 45 6e 64 22 5d 3a 64 45 72 72 5b  rr["nEnd"]:dErr[
7730: 22 6e 45 6e 64 22 5d 2b 38 30 5d 0a 20 20 20 20  "nEnd"]+80].    
7740: 20 20 20 20 72 65 74 75 72 6e 20 64 45 72 72 0a      return dErr.
7750: 0a 20 20 20 20 64 65 66 20 5f 65 78 70 61 6e 64  .    def _expand
7760: 20 28 73 65 6c 66 2c 20 73 4d 73 67 2c 20 6e 54   (self, sMsg, nT
7770: 6f 6b 65 6e 4f 66 66 73 65 74 29 3a 0a 20 20 20  okenOffset):.   
7780: 20 20 20 20 20 23 70 72 69 6e 74 28 22 2a 22 2c       #print("*",
7790: 20 73 4d 73 67 29 0a 20 20 20 20 20 20 20 20 66   sMsg).        f
77a0: 6f 72 20 6d 20 69 6e 20 72 65 2e 66 69 6e 64 69  or m in re.findi
77b0: 74 65 72 28 72 22 5c 5c 28 5b 30 2d 39 5d 2b 29  ter(r"\\([0-9]+)
77c0: 22 2c 20 73 4d 73 67 29 3a 0a 20 20 20 20 20 20  ", sMsg):.      
77d0: 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73 4d 73        sMsg = sMs
77e0: 67 2e 72 65 70 6c 61 63 65 28 6d 2e 67 72 6f 75  g.replace(m.grou
77f0: 70 28 30 29 2c 20 73 65 6c 66 2e 6c 54 6f 6b 65  p(0), self.lToke
7800: 6e 5b 69 6e 74 28 6d 2e 67 72 6f 75 70 28 31 29  n[int(m.group(1)
7810: 29 2b 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 5b  )+nTokenOffset][
7820: 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20  "sValue"]).     
7830: 20 20 20 23 70 72 69 6e 74 28 22 3e 22 2c 20 73     #print(">", s
7840: 4d 73 67 29 0a 20 20 20 20 20 20 20 20 72 65 74  Msg).        ret
7850: 75 72 6e 20 73 4d 73 67 0a 0a 20 20 20 20 64 65  urn sMsg..    de
7860: 66 20 5f 74 61 67 41 6e 64 50 72 65 70 61 72 65  f _tagAndPrepare
7870: 54 6f 6b 65 6e 46 6f 72 52 65 77 72 69 74 69 6e  TokenForRewritin
7880: 67 20 28 73 65 6c 66 2c 20 73 57 68 61 74 2c 20  g (self, sWhat, 
7890: 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61  nTokenRewriteSta
78a0: 72 74 2c 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74  rt, nTokenRewrit
78b0: 65 45 6e 64 2c 20 62 55 70 70 65 72 63 61 73 65  eEnd, bUppercase
78c0: 3d 54 72 75 65 29 3a 0a 20 20 20 20 20 20 20 20  =True):.        
78d0: 22 74 65 78 74 20 70 72 6f 63 65 73 73 6f 72 3a  "text processor:
78e0: 20 72 65 77 72 69 74 65 20 74 6f 6b 65 6e 73 20   rewrite tokens 
78f0: 62 65 74 77 65 65 6e 20 3c 6e 54 6f 6b 65 6e 52  between <nTokenR
7900: 65 77 72 69 74 65 53 74 61 72 74 3e 20 61 6e 64  ewriteStart> and
7910: 20 3c 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 45   <nTokenRewriteE
7920: 6e 64 3e 20 70 6f 73 69 74 69 6f 6e 22 0a 20 20  nd> position".  
7930: 20 20 20 20 20 20 69 66 20 73 57 68 61 74 20 3d        if sWhat =
7940: 3d 20 22 2a 22 3a 0a 20 20 20 20 20 20 20 20 20  = "*":.         
7950: 20 20 20 23 20 70 75 72 67 65 20 74 65 78 74 0a     # purge text.
7960: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e              if n
7970: 54 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e 64 20  TokenRewriteEnd 
7980: 2d 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53  - nTokenRewriteS
7990: 74 61 72 74 20 3d 3d 20 30 3a 0a 20 20 20 20 20  tart == 0:.     
79a0: 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e             self.
79b0: 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 52 65 77  lToken[nTokenRew
79c0: 72 69 74 65 53 74 61 72 74 5d 5b 22 62 54 6f 52  riteStart]["bToR
79d0: 65 6d 6f 76 65 22 5d 20 3d 20 54 72 75 65 0a 20  emove"] = True. 
79e0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
79f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7a00: 20 66 6f 72 20 69 20 69 6e 20 72 61 6e 67 65 28   for i in range(
7a10: 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61  nTokenRewriteSta
7a20: 72 74 2c 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74  rt, nTokenRewrit
7a30: 65 45 6e 64 2b 31 29 3a 0a 20 20 20 20 20 20 20  eEnd+1):.       
7a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c               sel
7a50: 66 2e 6c 54 6f 6b 65 6e 5b 69 5d 5b 22 62 54 6f  f.lToken[i]["bTo
7a60: 52 65 6d 6f 76 65 22 5d 20 3d 20 54 72 75 65 0a  Remove"] = True.
7a70: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
7a80: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 57 68            if sWh
7a90: 61 74 2e 73 74 61 72 74 73 77 69 74 68 28 22 3d  at.startswith("=
7aa0: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
7ab0: 20 20 20 20 73 57 68 61 74 20 3d 20 67 6c 6f 62      sWhat = glob
7ac0: 61 6c 73 28 29 5b 73 57 68 61 74 5b 31 3a 5d 5d  als()[sWhat[1:]]
7ad0: 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e 29 0a 20 20  (self.lToken).  
7ae0: 20 20 20 20 20 20 20 20 20 20 62 55 70 70 65 72            bUpper
7af0: 63 61 73 65 20 3d 20 62 55 70 70 65 72 63 61 73  case = bUppercas
7b00: 65 20 61 6e 64 20 73 65 6c 66 2e 6c 54 6f 6b 65  e and self.lToke
7b10: 6e 5b 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53  n[nTokenRewriteS
7b20: 74 61 72 74 5d 5b 22 73 56 61 6c 75 65 22 5d 5b  tart]["sValue"][
7b30: 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29 0a 20  0:1].isupper(). 
7b40: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e 54             if nT
7b50: 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e 64 20 2d  okenRewriteEnd -
7b60: 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74   nTokenRewriteSt
7b70: 61 72 74 20 3d 3d 20 30 3a 0a 20 20 20 20 20 20  art == 0:.      
7b80: 20 20 20 20 20 20 20 20 20 20 73 57 68 61 74 20            sWhat 
7b90: 3d 20 73 57 68 61 74 20 2b 20 22 20 22 20 2a 20  = sWhat + " " * 
7ba0: 28 6c 65 6e 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e  (len(self.lToken
7bb0: 5b 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74  [nTokenRewriteSt
7bc0: 61 72 74 5d 5b 22 73 56 61 6c 75 65 22 5d 29 2d  art]["sValue"])-
7bd0: 6c 65 6e 28 73 57 68 61 74 29 29 0a 20 20 20 20  len(sWhat)).    
7be0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
7bf0: 55 70 70 65 72 63 61 73 65 3a 0a 20 20 20 20 20  Uppercase:.     
7c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
7c10: 57 68 61 74 20 3d 20 73 57 68 61 74 5b 30 3a 31  What = sWhat[0:1
7c20: 5d 2e 75 70 70 65 72 28 29 20 2b 20 73 57 68 61  ].upper() + sWha
7c30: 74 5b 31 3a 5d 0a 20 20 20 20 20 20 20 20 20 20  t[1:].          
7c40: 20 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65        self.lToke
7c50: 6e 5b 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53  n[nTokenRewriteS
7c60: 74 61 72 74 5d 5b 22 73 4e 65 77 56 61 6c 75 65  tart]["sNewValue
7c70: 22 5d 20 3d 20 73 57 68 61 74 0a 20 20 20 20 20  "] = sWhat.     
7c80: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
7c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f               lTo
7ca0: 6b 65 6e 56 61 6c 75 65 20 3d 20 73 57 68 61 74  kenValue = sWhat
7cb0: 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20 20  .split("|").    
7cc0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6c              if l
7cd0: 65 6e 28 6c 54 6f 6b 65 6e 56 61 6c 75 65 29 20  en(lTokenValue) 
7ce0: 21 3d 20 28 6e 54 6f 6b 65 6e 52 65 77 72 69 74  != (nTokenRewrit
7cf0: 65 45 6e 64 20 2d 20 6e 54 6f 6b 65 6e 52 65 77  eEnd - nTokenRew
7d00: 72 69 74 65 53 74 61 72 74 20 2b 20 31 29 3a 0a  riteStart + 1):.
7d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d20: 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72      print("Error
7d30: 2e 20 54 65 78 74 20 70 72 6f 63 65 73 73 6f 72  . Text processor
7d40: 3a 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 70 6c  : number of repl
7d50: 61 63 65 6d 65 6e 74 73 20 21 3d 20 6e 75 6d 62  acements != numb
7d60: 65 72 20 6f 66 20 74 6f 6b 65 6e 73 2e 22 29 0a  er of tokens.").
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d80: 20 20 20 20 72 65 74 75 72 6e 0a 20 20 20 20 20      return.     
7d90: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 69             for i
7da0: 2c 20 73 56 61 6c 75 65 20 69 6e 20 7a 69 70 28  , sValue in zip(
7db0: 72 61 6e 67 65 28 6e 54 6f 6b 65 6e 52 65 77 72  range(nTokenRewr
7dc0: 69 74 65 53 74 61 72 74 2c 20 6e 54 6f 6b 65 6e  iteStart, nToken
7dd0: 52 65 77 72 69 74 65 45 6e 64 2b 31 29 2c 20 6c  RewriteEnd+1), l
7de0: 54 6f 6b 65 6e 56 61 6c 75 65 29 3a 0a 20 20 20  TokenValue):.   
7df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e00: 20 69 66 20 62 55 70 70 65 72 63 61 73 65 3a 0a   if bUppercase:.
7e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e20: 20 20 20 20 20 20 20 20 73 56 61 6c 75 65 20 3d          sValue =
7e30: 20 73 56 61 6c 75 65 5b 30 3a 31 5d 2e 75 70 70   sValue[0:1].upp
7e40: 65 72 28 29 20 2b 20 73 56 61 6c 75 65 5b 31 3a  er() + sValue[1:
7e50: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ].              
7e60: 20 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65        self.lToke
7e70: 6e 5b 69 5d 5b 22 73 4e 65 77 56 61 6c 75 65 22  n[i]["sNewValue"
7e80: 5d 20 3d 20 73 56 61 6c 75 65 0a 0a 20 20 20 20  ] = sValue..    
7e90: 64 65 66 20 72 65 77 72 69 74 65 20 28 73 65 6c  def rewrite (sel
7ea0: 66 29 3a 0a 20 20 20 20 20 20 20 20 22 72 65 77  f):.        "rew
7eb0: 72 69 74 65 20 74 68 65 20 73 65 6e 74 65 6e 63  rite the sentenc
7ec0: 65 2c 20 6d 6f 64 69 66 79 20 74 6f 6b 65 6e 73  e, modify tokens
7ed0: 2c 20 70 75 72 67 65 20 74 68 65 20 74 6f 6b 65  , purge the toke
7ee0: 6e 20 6c 69 73 74 22 0a 20 20 20 20 20 20 20 20  n list".        
7ef0: 6c 4e 65 77 54 6f 6b 65 6e 20 3d 20 5b 5d 0a 20  lNewToken = []. 
7f00: 20 20 20 20 20 20 20 66 6f 72 20 69 2c 20 64 54         for i, dT
7f10: 6f 6b 65 6e 20 69 6e 20 65 6e 75 6d 65 72 61 74  oken in enumerat
7f20: 65 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e 29 3a 0a  e(self.lToken):.
7f30: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22              if "
7f40: 62 54 6f 52 65 6d 6f 76 65 22 20 69 6e 20 64 54  bToRemove" in dT
7f50: 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20 20 20  oken:.          
7f60: 20 20 20 20 20 20 23 20 72 65 6d 6f 76 65 20 75        # remove u
7f70: 73 65 6c 65 73 73 20 74 6f 6b 65 6e 0a 20 20 20  seless token.   
7f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c               sel
7f90: 66 2e 73 53 65 6e 74 65 6e 63 65 20 3d 20 73 65  f.sSentence = se
7fa0: 6c 66 2e 73 53 65 6e 74 65 6e 63 65 5b 3a 73 65  lf.sSentence[:se
7fb0: 6c 66 2e 6e 4f 66 66 73 65 74 2b 64 54 6f 6b 65  lf.nOffset+dToke
7fc0: 6e 5b 22 6e 53 74 61 72 74 22 5d 5d 20 2b 20 22  n["nStart"]] + "
7fd0: 20 22 20 2a 20 28 64 54 6f 6b 65 6e 5b 22 6e 45   " * (dToken["nE
7fe0: 6e 64 22 5d 20 2d 20 64 54 6f 6b 65 6e 5b 22 6e  nd"] - dToken["n
7ff0: 53 74 61 72 74 22 5d 29 20 2b 20 73 65 6c 66 2e  Start"]) + self.
8000: 73 53 65 6e 74 65 6e 63 65 5b 73 65 6c 66 2e 6e  sSentence[self.n
8010: 4f 66 66 73 65 74 2b 64 54 6f 6b 65 6e 5b 22 6e  Offset+dToken["n
8020: 45 6e 64 22 5d 3a 5d 0a 20 20 20 20 20 20 20 20  End"]:].        
8030: 20 20 20 20 20 20 20 20 23 70 72 69 6e 74 28 22          #print("
8040: 72 65 6d 6f 76 65 64 3a 22 2c 20 64 54 6f 6b 65  removed:", dToke
8050: 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20  n["sValue"]).   
8060: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
8080: 4e 65 77 54 6f 6b 65 6e 2e 61 70 70 65 6e 64 28  NewToken.append(
8090: 64 54 6f 6b 65 6e 29 0a 20 20 20 20 20 20 20 20  dToken).        
80a0: 20 20 20 20 20 20 20 20 69 66 20 22 73 4e 65 77          if "sNew
80b0: 56 61 6c 75 65 22 20 69 6e 20 64 54 6f 6b 65 6e  Value" in dToken
80c0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
80d0: 20 20 20 20 20 20 23 20 72 65 77 72 69 74 65 20        # rewrite 
80e0: 74 6f 6b 65 6e 20 61 6e 64 20 73 65 6e 74 65 6e  token and senten
80f0: 63 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ce.             
8100: 20 20 20 20 20 20 20 23 70 72 69 6e 74 28 64 54         #print(dT
8110: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 2c 20  oken["sValue"], 
8120: 22 2d 3e 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 4e  "->", dToken["sN
8130: 65 77 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20  ewValue"]).     
8140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
8150: 54 6f 6b 65 6e 5b 22 73 52 65 61 6c 56 61 6c 75  Token["sRealValu
8160: 65 22 5d 20 3d 20 64 54 6f 6b 65 6e 5b 22 73 56  e"] = dToken["sV
8170: 61 6c 75 65 22 5d 0a 20 20 20 20 20 20 20 20 20  alue"].         
8180: 20 20 20 20 20 20 20 20 20 20 20 64 54 6f 6b 65             dToke
8190: 6e 5b 22 73 56 61 6c 75 65 22 5d 20 3d 20 64 54  n["sValue"] = dT
81a0: 6f 6b 65 6e 5b 22 73 4e 65 77 56 61 6c 75 65 22  oken["sNewValue"
81b0: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ].              
81c0: 20 20 20 20 20 20 6e 44 69 66 66 4c 65 6e 20 3d        nDiffLen =
81d0: 20 6c 65 6e 28 64 54 6f 6b 65 6e 5b 22 73 52 65   len(dToken["sRe
81e0: 61 6c 56 61 6c 75 65 22 5d 29 20 2d 20 6c 65 6e  alValue"]) - len
81f0: 28 64 54 6f 6b 65 6e 5b 22 73 4e 65 77 56 61 6c  (dToken["sNewVal
8200: 75 65 22 5d 29 0a 20 20 20 20 20 20 20 20 20 20  ue"]).          
8210: 20 20 20 20 20 20 20 20 20 20 73 4e 65 77 52 65            sNewRe
8220: 70 6c 20 3d 20 28 64 54 6f 6b 65 6e 5b 22 73 4e  pl = (dToken["sN
8230: 65 77 56 61 6c 75 65 22 5d 20 2b 20 22 20 22 20  ewValue"] + " " 
8240: 2a 20 6e 44 69 66 66 4c 65 6e 29 20 20 69 66 20  * nDiffLen)  if 
8250: 6e 44 69 66 66 4c 65 6e 20 3e 3d 20 30 20 20 65  nDiffLen >= 0  e
8260: 6c 73 65 20 64 54 6f 6b 65 6e 5b 22 73 4e 65 77  lse dToken["sNew
8270: 56 61 6c 75 65 22 5d 5b 3a 6c 65 6e 28 64 54 6f  Value"][:len(dTo
8280: 6b 65 6e 5b 22 73 52 65 61 6c 56 61 6c 75 65 22  ken["sRealValue"
8290: 5d 29 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ])].            
82a0: 20 20 20 20 20 20 20 20 73 65 6c 66 2e 73 53 65          self.sSe
82b0: 6e 74 65 6e 63 65 20 3d 20 73 65 6c 66 2e 73 53  ntence = self.sS
82c0: 65 6e 74 65 6e 63 65 5b 3a 73 65 6c 66 2e 6e 4f  entence[:self.nO
82d0: 66 66 73 65 74 2b 64 54 6f 6b 65 6e 5b 22 6e 53  ffset+dToken["nS
82e0: 74 61 72 74 22 5d 5d 20 2b 20 73 4e 65 77 52 65  tart"]] + sNewRe
82f0: 70 6c 20 2b 20 73 65 6c 66 2e 73 53 65 6e 74 65  pl + self.sSente
8300: 6e 63 65 5b 73 65 6c 66 2e 6e 4f 66 66 73 65 74  nce[self.nOffset
8310: 2b 64 54 6f 6b 65 6e 5b 22 6e 45 6e 64 22 5d 3a  +dToken["nEnd"]:
8320: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ].              
8330: 20 20 20 20 20 20 64 65 6c 20 64 54 6f 6b 65 6e        del dToken
8340: 5b 22 73 4e 65 77 56 61 6c 75 65 22 5d 0a 20 20  ["sNewValue"].  
8350: 20 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65        self.lToke
8360: 6e 2e 63 6c 65 61 72 28 29 0a 20 20 20 20 20 20  n.clear().      
8370: 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 20 3d 20    self.lToken = 
8380: 6c 4e 65 77 54 6f 6b 65 6e 0a 20 20 20 20 20 20  lNewToken.      
8390: 20 20 72 65 74 75 72 6e 20 73 65 6c 66 2e 73 53    return self.sS
83a0: 65 6e 74 65 6e 63 65 0a 0a 0a 0a 23 23 23 23 20  entence....#### 
83b0: 41 6e 61 6c 79 73 65 20 74 6f 6b 65 6e 73 0a 0a  Analyse tokens..
83c0: 64 65 66 20 67 5f 6d 6f 72 70 68 20 28 64 54 6f  def g_morph (dTo
83d0: 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20 73  ken, sPattern, s
83e0: 4e 65 67 50 61 74 74 65 72 6e 3d 22 22 29 3a 0a  NegPattern=""):.
83f0: 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 74      "analyse a t
8400: 6f 6b 65 6e 2c 20 72 65 74 75 72 6e 20 54 72 75  oken, return Tru
8410: 65 20 69 66 20 3c 73 4e 65 67 50 61 74 74 65 72  e if <sNegPatter
8420: 6e 3e 20 6e 6f 74 20 69 6e 20 6d 6f 72 70 68 6f  n> not in morpho
8430: 6c 6f 67 69 65 73 20 61 6e 64 20 3c 73 50 61 74  logies and <sPat
8440: 74 65 72 6e 3e 20 69 6e 20 6d 6f 72 70 68 6f 6c  tern> in morphol
8450: 6f 67 69 65 73 22 0a 20 20 20 20 69 66 20 22 6c  ogies".    if "l
8460: 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b 65 6e  Morph" in dToken
8470: 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72 70 68  :.        lMorph
8480: 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70   = dToken["lMorp
8490: 68 22 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  h"].    else:.  
84a0: 20 20 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f        lMorph = _
84b0: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65  oSpellChecker.ge
84c0: 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73  tMorph(dToken["s
84d0: 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20  Value"]).       
84e0: 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a   if not lMorph:.
84f0: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
8500: 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 23 20 63  rn False.    # c
8510: 68 65 63 6b 20 6e 65 67 61 74 69 76 65 20 63 6f  heck negative co
8520: 6e 64 69 74 69 6f 6e 0a 20 20 20 20 69 66 20 73  ndition.    if s
8530: 4e 65 67 50 61 74 74 65 72 6e 3a 0a 20 20 20 20  NegPattern:.    
8540: 20 20 20 20 69 66 20 73 4e 65 67 50 61 74 74 65      if sNegPatte
8550: 72 6e 20 3d 3d 20 22 2a 22 3a 0a 20 20 20 20 20  rn == "*":.     
8560: 20 20 20 20 20 20 20 23 20 61 6c 6c 20 6d 6f 72         # all mor
8570: 70 68 20 6d 75 73 74 20 6d 61 74 63 68 20 73 50  ph must match sP
8580: 61 74 74 65 72 6e 0a 20 20 20 20 20 20 20 20 20  attern.         
8590: 20 20 20 7a 50 61 74 74 65 72 6e 20 3d 20 72 65     zPattern = re
85a0: 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72  .compile(sPatter
85b0: 6e 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  n).            r
85c0: 65 74 75 72 6e 20 61 6c 6c 28 7a 50 61 74 74 65  eturn all(zPatte
85d0: 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70 68  rn.search(sMorph
85e0: 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  )  for sMorph in
85f0: 20 6c 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20   lMorph).       
8600: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
8610: 20 20 20 7a 4e 65 67 50 61 74 74 65 72 6e 20 3d     zNegPattern =
8620: 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 4e 65 67   re.compile(sNeg
8630: 50 61 74 74 65 72 6e 29 0a 20 20 20 20 20 20 20  Pattern).       
8640: 20 20 20 20 20 69 66 20 61 6e 79 28 7a 4e 65 67       if any(zNeg
8650: 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73  Pattern.search(s
8660: 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72  Morph)  for sMor
8670: 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20  ph in lMorph):. 
8680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
8690: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
86a0: 23 20 73 65 61 72 63 68 20 73 50 61 74 74 65 72  # search sPatter
86b0: 6e 0a 20 20 20 20 7a 50 61 74 74 65 72 6e 20 3d  n.    zPattern =
86c0: 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74   re.compile(sPat
86d0: 74 65 72 6e 29 0a 20 20 20 20 72 65 74 75 72 6e  tern).    return
86e0: 20 61 6e 79 28 7a 50 61 74 74 65 72 6e 2e 73 65   any(zPattern.se
86f0: 61 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f  arch(sMorph)  fo
8700: 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72  r sMorph in lMor
8710: 70 68 29 0a 0a 0a 64 65 66 20 67 5f 61 6e 61 6c  ph)...def g_anal
8720: 79 73 65 20 28 64 54 6f 6b 65 6e 2c 20 73 50 61  yse (dToken, sPa
8730: 74 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65  ttern, sNegPatte
8740: 72 6e 3d 22 22 29 3a 0a 20 20 20 20 22 61 6e 61  rn=""):.    "ana
8750: 6c 79 73 65 20 61 20 74 6f 6b 65 6e 2c 20 72 65  lyse a token, re
8760: 74 75 72 6e 20 54 72 75 65 20 69 66 20 3c 73 4e  turn True if <sN
8770: 65 67 50 61 74 74 65 72 6e 3e 20 6e 6f 74 20 69  egPattern> not i
8780: 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 61  n morphologies a
8790: 6e 64 20 3c 73 50 61 74 74 65 72 6e 3e 20 69 6e  nd <sPattern> in
87a0: 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28 64   morphologies (d
87b0: 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f 66  isambiguation of
87c0: 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d  f)".    lMorph =
87d0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
87e0: 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b  getMorph(dToken[
87f0: 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 69  "sValue"]).    i
8800: 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20 20  f not lMorph:.  
8810: 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c        return Fal
8820: 73 65 0a 20 20 20 20 23 20 63 68 65 63 6b 20 6e  se.    # check n
8830: 65 67 61 74 69 76 65 20 63 6f 6e 64 69 74 69 6f  egative conditio
8840: 6e 0a 20 20 20 20 69 66 20 73 4e 65 67 50 61 74  n.    if sNegPat
8850: 74 65 72 6e 3a 0a 20 20 20 20 20 20 20 20 69 66  tern:.        if
8860: 20 73 4e 65 67 50 61 74 74 65 72 6e 20 3d 3d 20   sNegPattern == 
8870: 22 2a 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "*":.           
8880: 20 7a 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63   zPattern = re.c
8890: 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29  ompile(sPattern)
88a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
88b0: 75 72 6e 20 61 6c 6c 28 7a 50 61 74 74 65 72 6e  urn all(zPattern
88c0: 2e 73 65 61 72 63 68 28 73 4d 6f 72 70 68 29 20  .search(sMorph) 
88d0: 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c   for sMorph in l
88e0: 4d 6f 72 70 68 29 0a 20 20 20 20 20 20 20 20 65  Morph).        e
88f0: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
8900: 20 7a 4e 65 67 50 61 74 74 65 72 6e 20 3d 20 72   zNegPattern = r
8910: 65 2e 63 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61  e.compile(sNegPa
8920: 74 74 65 72 6e 29 0a 20 20 20 20 20 20 20 20 20  ttern).         
8930: 20 20 20 69 66 20 61 6e 79 28 7a 4e 65 67 50 61     if any(zNegPa
8940: 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f  ttern.search(sMo
8950: 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68  rph)  for sMorph
8960: 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20   in lMorph):.   
8970: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74               ret
8980: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 23 20  urn False.    # 
8990: 73 65 61 72 63 68 20 73 50 61 74 74 65 72 6e 0a  search sPattern.
89a0: 20 20 20 20 7a 50 61 74 74 65 72 6e 20 3d 20 72      zPattern = r
89b0: 65 2e 63 6f 6d 70 69 6c 65 28 73 50 61 74 74 65  e.compile(sPatte
89c0: 72 6e 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61  rn).    return a
89d0: 6e 79 28 7a 50 61 74 74 65 72 6e 2e 73 65 61 72  ny(zPattern.sear
89e0: 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72 20  ch(sMorph)  for 
89f0: 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68  sMorph in lMorph
8a00: 29 0a 0a 0a 0a 23 23 23 23 20 44 69 73 61 6d 62  )....#### Disamb
8a10: 69 67 75 61 74 6f 72 0a 0a 64 65 66 20 67 5f 73  iguator..def g_s
8a20: 65 6c 65 63 74 20 28 64 54 6f 6b 65 6e 2c 20 73  elect (dToken, s
8a30: 50 61 74 74 65 72 6e 2c 20 6c 44 65 66 61 75 6c  Pattern, lDefaul
8a40: 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22 73 65  t=None):.    "se
8a50: 6c 65 63 74 20 6d 6f 72 70 68 6f 6c 6f 67 69 65  lect morphologie
8a60: 73 20 66 6f 72 20 3c 64 54 6f 6b 65 6e 3e 20 61  s for <dToken> a
8a70: 63 63 6f 72 64 69 6e 67 20 74 6f 20 3c 73 50 61  ccording to <sPa
8a80: 74 74 65 72 6e 3e 2c 20 61 6c 77 61 79 73 20 72  ttern>, always r
8a90: 65 74 75 72 6e 20 54 72 75 65 22 0a 20 20 20 20  eturn True".    
8aa0: 6c 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e 5b  lMorph = dToken[
8ab0: 22 6c 4d 6f 72 70 68 22 5d 20 20 69 66 20 22 6c  "lMorph"]  if "l
8ac0: 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b 65 6e  Morph" in dToken
8ad0: 20 20 65 6c 73 65 20 5f 6f 53 70 65 6c 6c 43 68    else _oSpellCh
8ae0: 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64  ecker.getMorph(d
8af0: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29  Token["sValue"])
8b00: 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72  .    if not lMor
8b10: 70 68 20 6f 72 20 6c 65 6e 28 6c 4d 6f 72 70 68  ph or len(lMorph
8b20: 29 20 3d 3d 20 31 3a 0a 20 20 20 20 20 20 20 20  ) == 1:.        
8b30: 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a 20 20 20  if lDefault:.   
8b40: 20 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 5b           dToken[
8b50: 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 44 65 66  "lMorph"] = lDef
8b60: 61 75 6c 74 0a 20 20 20 20 20 20 20 20 20 20 20  ault.           
8b70: 20 23 70 72 69 6e 74 28 22 44 41 3a 22 2c 20 64   #print("DA:", d
8b80: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 2c  Token["sValue"],
8b90: 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22   dToken["lMorph"
8ba0: 5d 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ]).        retur
8bb0: 6e 20 54 72 75 65 0a 20 20 20 20 6c 53 65 6c 65  n True.    lSele
8bc0: 63 74 20 3d 20 5b 20 73 4d 6f 72 70 68 20 20 66  ct = [ sMorph  f
8bd0: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f  or sMorph in lMo
8be0: 72 70 68 20 20 69 66 20 72 65 2e 73 65 61 72 63  rph  if re.searc
8bf0: 68 28 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72  h(sPattern, sMor
8c00: 70 68 29 20 5d 0a 20 20 20 20 69 66 20 6c 53 65  ph) ].    if lSe
8c10: 6c 65 63 74 3a 0a 20 20 20 20 20 20 20 20 69 66  lect:.        if
8c20: 20 6c 65 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d   len(lSelect) !=
8c30: 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20   len(lMorph):.  
8c40: 20 20 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e            dToken
8c50: 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 53 65  ["lMorph"] = lSe
8c60: 6c 65 63 74 0a 20 20 20 20 65 6c 69 66 20 6c 44  lect.    elif lD
8c70: 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20  efault:.        
8c80: 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d  dToken["lMorph"]
8c90: 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20   = lDefault.    
8ca0: 23 70 72 69 6e 74 28 22 44 41 3a 22 2c 20 64 54  #print("DA:", dT
8cb0: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 2c 20  oken["sValue"], 
8cc0: 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d  dToken["lMorph"]
8cd0: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 54 72 75  ).    return Tru
8ce0: 65 0a 0a 0a 64 65 66 20 67 5f 65 78 63 6c 75 64  e...def g_exclud
8cf0: 65 20 28 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74  e (dToken, sPatt
8d00: 65 72 6e 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f  ern, lDefault=No
8d10: 6e 65 29 3a 0a 20 20 20 20 22 73 65 6c 65 63 74  ne):.    "select
8d20: 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 66 6f   morphologies fo
8d30: 72 20 3c 64 54 6f 6b 65 6e 3e 20 61 63 63 6f 72  r <dToken> accor
8d40: 64 69 6e 67 20 74 6f 20 3c 73 50 61 74 74 65 72  ding to <sPatter
8d50: 6e 3e 2c 20 61 6c 77 61 79 73 20 72 65 74 75 72  n>, always retur
8d60: 6e 20 54 72 75 65 22 0a 20 20 20 20 6c 4d 6f 72  n True".    lMor
8d70: 70 68 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f  ph = dToken["lMo
8d80: 72 70 68 22 5d 20 20 69 66 20 22 6c 4d 6f 72 70  rph"]  if "lMorp
8d90: 68 22 20 69 6e 20 64 54 6f 6b 65 6e 20 20 65 6c  h" in dToken  el
8da0: 73 65 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65  se _oSpellChecke
8db0: 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65  r.getMorph(dToke
8dc0: 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20  n["sValue"]).   
8dd0: 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f   if not lMorph o
8de0: 72 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d  r len(lMorph) ==
8df0: 20 31 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c   1:.        if l
8e00: 44 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20  Default:.       
8e10: 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f       dToken["lMo
8e20: 72 70 68 22 5d 20 3d 20 6c 44 65 66 61 75 6c 74  rph"] = lDefault
8e30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 70 72  .            #pr
8e40: 69 6e 74 28 22 44 41 3a 22 2c 20 64 54 6f 6b 65  int("DA:", dToke
8e50: 6e 5b 22 73 56 61 6c 75 65 22 5d 2c 20 64 54 6f  n["sValue"], dTo
8e60: 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 29 0a 20  ken["lMorph"]). 
8e70: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
8e80: 75 65 0a 20 20 20 20 6c 53 65 6c 65 63 74 20 3d  ue.    lSelect =
8e90: 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72 20 73   [ sMorph  for s
8ea0: 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20  Morph in lMorph 
8eb0: 20 69 66 20 6e 6f 74 20 72 65 2e 73 65 61 72 63   if not re.searc
8ec0: 68 28 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72  h(sPattern, sMor
8ed0: 70 68 29 20 5d 0a 20 20 20 20 69 66 20 6c 53 65  ph) ].    if lSe
8ee0: 6c 65 63 74 3a 0a 20 20 20 20 20 20 20 20 69 66  lect:.        if
8ef0: 20 6c 65 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d   len(lSelect) !=
8f00: 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20   len(lMorph):.  
8f10: 20 20 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e            dToken
8f20: 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 53 65  ["lMorph"] = lSe
8f30: 6c 65 63 74 0a 20 20 20 20 65 6c 69 66 20 6c 44  lect.    elif lD
8f40: 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20  efault:.        
8f50: 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d  dToken["lMorph"]
8f60: 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20   = lDefault.    
8f70: 23 70 72 69 6e 74 28 22 44 41 3a 22 2c 20 64 54  #print("DA:", dT
8f80: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 2c 20  oken["sValue"], 
8f90: 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d  dToken["lMorph"]
8fa0: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 54 72 75  ).    return Tru
8fb0: 65 0a 0a 0a 64 65 66 20 67 5f 64 65 66 69 6e 65  e...def g_define
8fc0: 20 28 64 54 6f 6b 65 6e 2c 20 6c 4d 6f 72 70 68   (dToken, lMorph
8fd0: 29 3a 0a 20 20 20 20 22 73 65 74 20 6d 6f 72 70  ):.    "set morp
8fe0: 68 6f 6c 6f 67 69 65 73 20 6f 66 20 3c 64 54 6f  hologies of <dTo
8ff0: 6b 65 6e 3e 2c 20 61 6c 77 61 79 73 20 72 65 74  ken>, always ret
9000: 75 72 6e 20 54 72 75 65 22 0a 20 20 20 20 64 54  urn True".    dT
9010: 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d  oken["lMorph"] =
9020: 20 6c 4d 6f 72 70 68 0a 20 20 20 20 23 70 72 69   lMorph.    #pri
9030: 6e 74 28 22 44 41 3a 22 2c 20 64 54 6f 6b 65 6e  nt("DA:", dToken
9040: 5b 22 73 56 61 6c 75 65 22 5d 2c 20 6c 4d 6f 72  ["sValue"], lMor
9050: 70 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ph).    return T
9060: 72 75 65 0a 0a 0a 23 23 23 23 20 43 41 4c 4c 41  rue...#### CALLA
9070: 42 4c 45 53 20 46 4f 52 20 52 45 47 45 58 20 52  BLES FOR REGEX R
9080: 55 4c 45 53 20 28 67 65 6e 65 72 61 74 65 64 20  ULES (generated 
9090: 63 6f 64 65 29 0a 0a 24 7b 63 61 6c 6c 61 62 6c  code)..${callabl
90a0: 65 73 7d 0a 0a 0a 23 23 23 23 20 43 41 4c 4c 41  es}...#### CALLA
90b0: 42 4c 45 53 20 46 4f 52 20 47 52 41 50 48 20 52  BLES FOR GRAPH R
90c0: 55 4c 45 53 20 28 67 65 6e 65 72 61 74 65 64 20  ULES (generated 
90d0: 63 6f 64 65 29 0a 0a 24 7b 67 72 61 70 68 5f 63  code)..${graph_c
90e0: 61 6c 6c 61 62 6c 65 73 7d 0a                    allables}.