Grammalecte  Hex Artifact Content

Artifact e53fccaf0231b99f61f19637b3bba08c04996f3e474fc4d8b2c826b52176a910:


0000: 22 22 22 0a 47 72 61 6d 6d 61 6c 65 63 74 65 0a  """.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 22 22 22 0a 0a 69 6d 70 6f  engine."""..impo
0030: 72 74 20 72 65 0a 69 6d 70 6f 72 74 20 73 79 73  rt re.import sys
0040: 0a 69 6d 70 6f 72 74 20 6f 73 0a 69 6d 70 6f 72  .import os.impor
0050: 74 20 74 72 61 63 65 62 61 63 6b 0a 23 69 6d 70  t traceback.#imp
0060: 6f 72 74 20 75 6e 69 63 6f 64 65 64 61 74 61 0a  ort unicodedata.
0070: 66 72 6f 6d 20 69 74 65 72 74 6f 6f 6c 73 20 69  from itertools i
0080: 6d 70 6f 72 74 20 63 68 61 69 6e 0a 0a 66 72 6f  mport chain..fro
0090: 6d 20 2e 2e 67 72 61 70 68 73 70 65 6c 6c 2e 73  m ..graphspell.s
00a0: 70 65 6c 6c 63 68 65 63 6b 65 72 20 69 6d 70 6f  pellchecker impo
00b0: 72 74 20 53 70 65 6c 6c 43 68 65 63 6b 65 72 0a  rt SpellChecker.
00c0: 66 72 6f 6d 20 2e 2e 67 72 61 70 68 73 70 65 6c  from ..graphspel
00d0: 6c 2e 65 63 68 6f 20 69 6d 70 6f 72 74 20 65 63  l.echo import ec
00e0: 68 6f 0a 66 72 6f 6d 20 2e 20 69 6d 70 6f 72 74  ho.from . import
00f0: 20 67 63 5f 6f 70 74 69 6f 6e 73 0a 0a 66 72 6f   gc_options..fro
0100: 6d 20 2e 2e 67 72 61 70 68 73 70 65 6c 6c 2e 74  m ..graphspell.t
0110: 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6f 72 74 20  okenizer import 
0120: 54 6f 6b 65 6e 69 7a 65 72 0a 66 72 6f 6d 20 2e  Tokenizer.from .
0130: 67 63 5f 72 75 6c 65 73 5f 67 72 61 70 68 20 69  gc_rules_graph i
0140: 6d 70 6f 72 74 20 64 41 6c 6c 47 72 61 70 68 2c  mport dAllGraph,
0150: 20 64 52 75 6c 65 0a 0a 74 72 79 3a 0a 20 20 20   dRule..try:.   
0160: 20 23 20 4c 69 62 72 65 4f 66 66 69 63 65 20 2f   # LibreOffice /
0170: 20 4f 70 65 6e 4f 66 66 69 63 65 0a 20 20 20 20   OpenOffice.    
0180: 66 72 6f 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74 61  from com.sun.sta
0190: 72 2e 6c 69 6e 67 75 69 73 74 69 63 32 20 69 6d  r.linguistic2 im
01a0: 70 6f 72 74 20 53 69 6e 67 6c 65 50 72 6f 6f 66  port SingleProof
01b0: 72 65 61 64 69 6e 67 45 72 72 6f 72 0a 20 20 20  readingError.   
01c0: 20 66 72 6f 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74   from com.sun.st
01d0: 61 72 2e 74 65 78 74 2e 54 65 78 74 4d 61 72 6b  ar.text.TextMark
01e0: 75 70 54 79 70 65 20 69 6d 70 6f 72 74 20 50 52  upType import PR
01f0: 4f 4f 46 52 45 41 44 49 4e 47 0a 20 20 20 20 66  OOFREADING.    f
0200: 72 6f 6d 20 63 6f 6d 2e 73 75 6e 2e 73 74 61 72  rom com.sun.star
0210: 2e 62 65 61 6e 73 20 69 6d 70 6f 72 74 20 50 72  .beans import Pr
0220: 6f 70 65 72 74 79 56 61 6c 75 65 0a 20 20 20 20  opertyValue.    
0230: 23 69 6d 70 6f 72 74 20 6c 69 67 68 74 70 72 6f  #import lightpro
0240: 6f 66 5f 68 61 6e 64 6c 65 72 5f 24 7b 69 6d 70  of_handler_${imp
0250: 6c 6e 61 6d 65 7d 20 61 73 20 6f 70 74 0a 20 20  lname} as opt.  
0260: 20 20 5f 62 57 72 69 74 65 72 45 72 72 6f 72 20    _bWriterError 
0270: 3d 20 54 72 75 65 0a 65 78 63 65 70 74 20 49 6d  = True.except Im
0280: 70 6f 72 74 45 72 72 6f 72 3a 0a 20 20 20 20 5f  portError:.    _
0290: 62 57 72 69 74 65 72 45 72 72 6f 72 20 3d 20 46  bWriterError = F
02a0: 61 6c 73 65 0a 0a 0a 5f 5f 61 6c 6c 5f 5f 20 3d  alse...__all__ =
02b0: 20 5b 20 22 6c 61 6e 67 22 2c 20 22 6c 6f 63 61   [ "lang", "loca
02c0: 6c 65 73 22 2c 20 22 70 6b 67 22 2c 20 22 6e 61  les", "pkg", "na
02d0: 6d 65 22 2c 20 22 76 65 72 73 69 6f 6e 22 2c 20  me", "version", 
02e0: 22 61 75 74 68 6f 72 22 2c 20 5c 0a 20 20 20 20  "author", \.    
02f0: 20 20 20 20 20 20 20 20 22 6c 6f 61 64 22 2c 20          "load", 
0300: 22 70 61 72 73 65 22 2c 20 22 67 65 74 53 70 65  "parse", "getSpe
0310: 6c 6c 43 68 65 63 6b 65 72 22 2c 20 5c 0a 20 20  llChecker", \.  
0320: 20 20 20 20 20 20 20 20 20 20 22 73 65 74 4f 70            "setOp
0330: 74 69 6f 6e 22 2c 20 22 73 65 74 4f 70 74 69 6f  tion", "setOptio
0340: 6e 73 22 2c 20 22 67 65 74 4f 70 74 69 6f 6e 73  ns", "getOptions
0350: 22 2c 20 22 67 65 74 44 65 66 61 75 6c 74 4f 70  ", "getDefaultOp
0360: 74 69 6f 6e 73 22 2c 20 22 67 65 74 4f 70 74 69  tions", "getOpti
0370: 6f 6e 73 4c 61 62 65 6c 73 22 2c 20 22 72 65 73  onsLabels", "res
0380: 65 74 4f 70 74 69 6f 6e 73 22 2c 20 22 64 69 73  etOptions", "dis
0390: 70 6c 61 79 4f 70 74 69 6f 6e 73 22 2c 20 5c 0a  playOptions", \.
03a0: 20 20 20 20 20 20 20 20 20 20 20 20 22 69 67 6e              "ign
03b0: 6f 72 65 52 75 6c 65 22 2c 20 22 72 65 73 65 74  oreRule", "reset
03c0: 49 67 6e 6f 72 65 52 75 6c 65 73 22 2c 20 22 72  IgnoreRules", "r
03d0: 65 61 63 74 69 76 61 74 65 52 75 6c 65 22 2c 20  eactivateRule", 
03e0: 22 6c 69 73 74 52 75 6c 65 73 22 2c 20 22 64 69  "listRules", "di
03f0: 73 70 6c 61 79 52 75 6c 65 73 22 20 5d 0a 0a 5f  splayRules" ].._
0400: 5f 76 65 72 73 69 6f 6e 5f 5f 20 3d 20 22 24 7b  _version__ = "${
0410: 76 65 72 73 69 6f 6e 7d 22 0a 0a 0a 6c 61 6e 67  version}"...lang
0420: 20 3d 20 22 24 7b 6c 61 6e 67 7d 22 0a 6c 6f 63   = "${lang}".loc
0430: 61 6c 65 73 20 3d 20 24 7b 6c 6f 63 7d 0a 70 6b  ales = ${loc}.pk
0440: 67 20 3d 20 22 24 7b 69 6d 70 6c 6e 61 6d 65 7d  g = "${implname}
0450: 22 0a 6e 61 6d 65 20 3d 20 22 24 7b 6e 61 6d 65  ".name = "${name
0460: 7d 22 0a 76 65 72 73 69 6f 6e 20 3d 20 22 24 7b  }".version = "${
0470: 76 65 72 73 69 6f 6e 7d 22 0a 61 75 74 68 6f 72  version}".author
0480: 20 3d 20 22 24 7b 61 75 74 68 6f 72 7d 22 0a 0a   = "${author}"..
0490: 5f 72 75 6c 65 73 20 3d 20 4e 6f 6e 65 20 20 20  _rules = 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 20 20 20 20 23 20 6d 6f              # mo
04c0: 64 75 6c 65 20 67 63 5f 72 75 6c 65 73 0a 0a 23  dule gc_rules..#
04d0: 20 64 61 74 61 0a 5f 73 41 70 70 43 6f 6e 74 65   data._sAppConte
04e0: 78 74 20 3d 20 22 22 20 20 20 20 20 20 20 20 20  xt = ""         
04f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0500: 20 20 23 20 77 68 61 74 20 73 6f 66 74 77 61 72    # what softwar
0510: 65 20 69 73 20 72 75 6e 6e 69 6e 67 0a 5f 64 4f  e is running._dO
0520: 70 74 69 6f 6e 73 20 3d 20 4e 6f 6e 65 0a 5f 6f  ptions = None._o
0530: 53 70 65 6c 6c 43 68 65 63 6b 65 72 20 3d 20 4e  SpellChecker = N
0540: 6f 6e 65 0a 5f 6f 54 6f 6b 65 6e 69 7a 65 72 20  one._oTokenizer 
0550: 3d 20 4e 6f 6e 65 0a 5f 61 49 67 6e 6f 72 65 64  = None._aIgnored
0560: 52 75 6c 65 73 20 3d 20 73 65 74 28 29 0a 0a 0a  Rules = set()...
0570: 0a 23 23 23 23 20 49 6e 69 74 69 61 6c 69 7a 61  .#### Initializa
0580: 74 69 6f 6e 0a 0a 64 65 66 20 6c 6f 61 64 20 28  tion..def load (
0590: 73 43 6f 6e 74 65 78 74 3d 22 50 79 74 68 6f 6e  sContext="Python
05a0: 22 29 3a 0a 20 20 20 20 22 69 6e 69 74 69 61 6c  "):.    "initial
05b0: 69 7a 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 67  ization of the g
05c0: 72 61 6d 6d 61 72 20 63 68 65 63 6b 65 72 22 0a  rammar checker".
05d0: 20 20 20 20 67 6c 6f 62 61 6c 20 5f 6f 53 70 65      global _oSpe
05e0: 6c 6c 43 68 65 63 6b 65 72 0a 20 20 20 20 67 6c  llChecker.    gl
05f0: 6f 62 61 6c 20 5f 73 41 70 70 43 6f 6e 74 65 78  obal _sAppContex
0600: 74 0a 20 20 20 20 67 6c 6f 62 61 6c 20 5f 64 4f  t.    global _dO
0610: 70 74 69 6f 6e 73 0a 20 20 20 20 67 6c 6f 62 61  ptions.    globa
0620: 6c 20 5f 6f 54 6f 6b 65 6e 69 7a 65 72 0a 20 20  l _oTokenizer.  
0630: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 5f    try:.        _
0640: 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 20 3d 20  oSpellChecker = 
0650: 53 70 65 6c 6c 43 68 65 63 6b 65 72 28 22 24 7b  SpellChecker("${
0660: 6c 61 6e 67 7d 22 2c 20 22 24 7b 64 69 63 5f 6d  lang}", "${dic_m
0670: 61 69 6e 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d  ain_filename_py}
0680: 22 2c 20 22 24 7b 64 69 63 5f 65 78 74 65 6e 64  ", "${dic_extend
0690: 65 64 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22  ed_filename_py}"
06a0: 2c 20 22 24 7b 64 69 63 5f 63 6f 6d 6d 75 6e 69  , "${dic_communi
06b0: 74 79 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22  ty_filename_py}"
06c0: 2c 20 22 24 7b 64 69 63 5f 70 65 72 73 6f 6e 61  , "${dic_persona
06d0: 6c 5f 66 69 6c 65 6e 61 6d 65 5f 70 79 7d 22 29  l_filename_py}")
06e0: 0a 20 20 20 20 20 20 20 20 5f 73 41 70 70 43 6f  .        _sAppCo
06f0: 6e 74 65 78 74 20 3d 20 73 43 6f 6e 74 65 78 74  ntext = sContext
0700: 0a 20 20 20 20 20 20 20 20 5f 64 4f 70 74 69 6f  .        _dOptio
0710: 6e 73 20 3d 20 64 69 63 74 28 67 63 5f 6f 70 74  ns = dict(gc_opt
0720: 69 6f 6e 73 2e 67 65 74 4f 70 74 69 6f 6e 73 28  ions.getOptions(
0730: 73 43 6f 6e 74 65 78 74 29 29 20 20 20 23 20 64  sContext))   # d
0740: 75 70 6c 69 63 61 74 69 6f 6e 20 6e 65 63 65 73  uplication neces
0750: 73 61 72 79 2c 20 74 6f 20 62 65 20 61 62 6c 65  sary, to be able
0760: 20 74 6f 20 72 65 73 65 74 20 74 6f 20 64 65 66   to reset to def
0770: 61 75 6c 74 0a 20 20 20 20 20 20 20 20 5f 6f 54  ault.        _oT
0780: 6f 6b 65 6e 69 7a 65 72 20 3d 20 5f 6f 53 70 65  okenizer = _oSpe
0790: 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 54 6f 6b  llChecker.getTok
07a0: 65 6e 69 7a 65 72 28 29 0a 20 20 20 20 20 20 20  enizer().       
07b0: 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e   _oSpellChecker.
07c0: 61 63 74 69 76 61 74 65 53 74 6f 72 61 67 65 28  activateStorage(
07d0: 29 0a 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20  ).    except:.  
07e0: 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b 2e        traceback.
07f0: 70 72 69 6e 74 5f 65 78 63 28 29 0a 0a 0a 64 65  print_exc()...de
0800: 66 20 5f 67 65 74 52 75 6c 65 73 20 28 62 50 61  f _getRules (bPa
0810: 72 61 67 72 61 70 68 29 3a 0a 20 20 20 20 74 72  ragraph):.    tr
0820: 79 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e 6f  y:.        if no
0830: 74 20 62 50 61 72 61 67 72 61 70 68 3a 0a 20 20  t bParagraph:.  
0840: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
0850: 20 5f 72 75 6c 65 73 2e 6c 53 65 6e 74 65 6e 63   _rules.lSentenc
0860: 65 52 75 6c 65 73 0a 20 20 20 20 20 20 20 20 72  eRules.        r
0870: 65 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 50 61  eturn _rules.lPa
0880: 72 61 67 72 61 70 68 52 75 6c 65 73 0a 20 20 20  ragraphRules.   
0890: 20 65 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20   except:.       
08a0: 20 5f 6c 6f 61 64 52 75 6c 65 73 28 29 0a 20 20   _loadRules().  
08b0: 20 20 69 66 20 6e 6f 74 20 62 50 61 72 61 67 72    if not bParagr
08c0: 61 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65 74  aph:.        ret
08d0: 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 53 65 6e 74  urn _rules.lSent
08e0: 65 6e 63 65 52 75 6c 65 73 0a 20 20 20 20 72 65  enceRules.    re
08f0: 74 75 72 6e 20 5f 72 75 6c 65 73 2e 6c 50 61 72  turn _rules.lPar
0900: 61 67 72 61 70 68 52 75 6c 65 73 0a 0a 0a 64 65  agraphRules...de
0910: 66 20 5f 6c 6f 61 64 52 75 6c 65 73 20 28 29 3a  f _loadRules ():
0920: 0a 20 20 20 20 66 72 6f 6d 20 2e 20 69 6d 70 6f  .    from . impo
0930: 72 74 20 67 63 5f 72 75 6c 65 73 0a 20 20 20 20  rt gc_rules.    
0940: 67 6c 6f 62 61 6c 20 5f 72 75 6c 65 73 0a 20 20  global _rules.  
0950: 20 20 5f 72 75 6c 65 73 20 3d 20 67 63 5f 72 75    _rules = gc_ru
0960: 6c 65 73 0a 20 20 20 20 23 20 63 6f 6d 70 69 6c  les.    # compil
0970: 65 20 72 75 6c 65 73 20 72 65 67 65 78 0a 20 20  e rules regex.  
0980: 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 6c    for sOption, l
0990: 52 75 6c 65 47 72 6f 75 70 20 69 6e 20 63 68 61  RuleGroup in cha
09a0: 69 6e 28 5f 72 75 6c 65 73 2e 6c 50 61 72 61 67  in(_rules.lParag
09b0: 72 61 70 68 52 75 6c 65 73 2c 20 5f 72 75 6c 65  raphRules, _rule
09c0: 73 2e 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73  s.lSentenceRules
09d0: 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 4f  ):.        if sO
09e0: 70 74 69 6f 6e 20 21 3d 20 22 40 40 40 40 22 3a  ption != "@@@@":
09f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
0a00: 20 61 52 75 6c 65 20 69 6e 20 6c 52 75 6c 65 47   aRule in lRuleG
0a10: 72 6f 75 70 3a 0a 20 20 20 20 20 20 20 20 20 20  roup:.          
0a20: 20 20 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20        try:.     
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
0a40: 52 75 6c 65 5b 30 5d 20 3d 20 72 65 2e 63 6f 6d  Rule[0] = re.com
0a50: 70 69 6c 65 28 61 52 75 6c 65 5b 30 5d 29 0a 20  pile(aRule[0]). 
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
0a70: 78 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 20  xcept:.         
0a80: 20 20 20 20 20 20 20 20 20 20 20 65 63 68 6f 28             echo(
0a90: 22 42 61 64 20 72 65 67 75 6c 61 72 20 65 78 70  "Bad regular exp
0aa0: 72 65 73 73 69 6f 6e 20 69 6e 20 23 20 22 20 2b  ression in # " +
0ab0: 20 73 74 72 28 61 52 75 6c 65 5b 32 5d 29 29 0a   str(aRule[2])).
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ad0: 20 20 20 20 61 52 75 6c 65 5b 30 5d 20 3d 20 22      aRule[0] = "
0ae0: 28 3f 69 29 3c 47 72 61 6d 6d 61 6c 65 63 74 65  (?i)<Grammalecte
0af0: 3e 22 0a 0a 0a 23 23 23 23 20 50 61 72 73 69 6e  >"...#### Parsin
0b00: 67 0a 0a 5f 7a 45 6e 64 4f 66 53 65 6e 74 65 6e  g.._zEndOfSenten
0b10: 63 65 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28  ce = re.compile(
0b20: 72 27 28 5b 2e 3f 21 3a 3b e2 80 a6 5d 5b 20 2e  r'([.?!:;...][ .
0b30: 3f 21 e2 80 a6 20 c2 bb e2 80 9d 22 29 5d 2a 7c  ?!... .....")]*|
0b40: 2e 24 29 27 29 0a 5f 7a 42 65 67 69 6e 4f 66 50  .$)')._zBeginOfP
0b50: 61 72 61 67 72 61 70 68 20 3d 20 72 65 2e 63 6f  aragraph = re.co
0b60: 6d 70 69 6c 65 28 72 22 5e 5c 57 2a 22 29 0a 5f  mpile(r"^\W*")._
0b70: 7a 45 6e 64 4f 66 50 61 72 61 67 72 61 70 68 20  zEndOfParagraph 
0b80: 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 72 22 5c  = re.compile(r"\
0b90: 57 2a 24 22 29 0a 0a 64 65 66 20 5f 67 65 74 53  W*$")..def _getS
0ba0: 65 6e 74 65 6e 63 65 42 6f 75 6e 64 61 72 69 65  entenceBoundarie
0bb0: 73 20 28 73 54 65 78 74 29 3a 0a 20 20 20 20 69  s (sText):.    i
0bc0: 53 74 61 72 74 20 3d 20 5f 7a 42 65 67 69 6e 4f  Start = _zBeginO
0bd0: 66 50 61 72 61 67 72 61 70 68 2e 6d 61 74 63 68  fParagraph.match
0be0: 28 73 54 65 78 74 29 2e 65 6e 64 28 29 0a 20 20  (sText).end().  
0bf0: 20 20 66 6f 72 20 6d 20 69 6e 20 5f 7a 45 6e 64    for m in _zEnd
0c00: 4f 66 53 65 6e 74 65 6e 63 65 2e 66 69 6e 64 69  OfSentence.findi
0c10: 74 65 72 28 73 54 65 78 74 29 3a 0a 20 20 20 20  ter(sText):.    
0c20: 20 20 20 20 79 69 65 6c 64 20 28 69 53 74 61 72      yield (iStar
0c30: 74 2c 20 6d 2e 65 6e 64 28 29 29 0a 20 20 20 20  t, m.end()).    
0c40: 20 20 20 20 69 53 74 61 72 74 20 3d 20 6d 2e 65      iStart = m.e
0c50: 6e 64 28 29 0a 0a 0a 64 65 66 20 70 61 72 73 65  nd()...def parse
0c60: 20 28 73 54 65 78 74 2c 20 73 43 6f 75 6e 74 72   (sText, sCountr
0c70: 79 3d 22 24 7b 63 6f 75 6e 74 72 79 5f 64 65 66  y="${country_def
0c80: 61 75 6c 74 7d 22 2c 20 62 44 65 62 75 67 3d 46  ault}", bDebug=F
0c90: 61 6c 73 65 2c 20 64 4f 70 74 69 6f 6e 73 3d 4e  alse, dOptions=N
0ca0: 6f 6e 65 2c 20 62 43 6f 6e 74 65 78 74 3d 46 61  one, bContext=Fa
0cb0: 6c 73 65 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79  lse):.    "analy
0cc0: 73 65 73 20 74 68 65 20 70 61 72 61 67 72 61 70  ses the paragrap
0cd0: 68 20 73 54 65 78 74 20 61 6e 64 20 72 65 74 75  h sText and retu
0ce0: 72 6e 73 20 6c 69 73 74 20 6f 66 20 65 72 72 6f  rns list of erro
0cf0: 72 73 22 0a 20 20 20 20 23 73 54 65 78 74 20 3d  rs".    #sText =
0d00: 20 75 6e 69 63 6f 64 65 64 61 74 61 2e 6e 6f 72   unicodedata.nor
0d10: 6d 61 6c 69 7a 65 28 22 4e 46 43 22 2c 20 73 54  malize("NFC", sT
0d20: 65 78 74 29 0a 20 20 20 20 61 45 72 72 6f 72 73  ext).    aErrors
0d30: 20 3d 20 4e 6f 6e 65 0a 20 20 20 20 73 52 65 61   = None.    sRea
0d40: 6c 54 65 78 74 20 3d 20 73 54 65 78 74 0a 20 20  lText = sText.  
0d50: 20 20 64 50 72 69 6f 72 69 74 79 20 3d 20 7b 7d    dPriority = {}
0d60: 20 20 23 20 4b 65 79 20 3d 20 70 6f 73 69 74 69    # Key = positi
0d70: 6f 6e 3b 20 76 61 6c 75 65 20 3d 20 70 72 69 6f  on; value = prio
0d80: 72 69 74 79 0a 20 20 20 20 64 4f 70 74 20 3d 20  rity.    dOpt = 
0d90: 5f 64 4f 70 74 69 6f 6e 73 20 20 69 66 20 6e 6f  _dOptions  if no
0da0: 74 20 64 4f 70 74 69 6f 6e 73 20 20 65 6c 73 65  t dOptions  else
0db0: 20 64 4f 70 74 69 6f 6e 73 0a 20 20 20 20 62 53   dOptions.    bS
0dc0: 68 6f 77 52 75 6c 65 49 64 20 3d 20 6f 70 74 69  howRuleId = opti
0dd0: 6f 6e 28 27 69 64 72 75 6c 65 27 29 0a 0a 20 20  on('idrule')..  
0de0: 20 20 23 20 70 61 72 73 65 20 70 61 72 61 67 72    # parse paragr
0df0: 61 70 68 0a 20 20 20 20 74 72 79 3a 0a 20 20 20  aph.    try:.   
0e00: 20 20 20 20 20 73 4e 65 77 2c 20 61 45 72 72 6f       sNew, aErro
0e10: 72 73 20 3d 20 5f 70 72 6f 6f 66 72 65 61 64 28  rs = _proofread(
0e20: 4e 6f 6e 65 2c 20 73 54 65 78 74 2c 20 73 52 65  None, sText, sRe
0e30: 61 6c 54 65 78 74 2c 20 30 2c 20 54 72 75 65 2c  alText, 0, True,
0e40: 20 64 50 72 69 6f 72 69 74 79 2c 20 73 43 6f 75   dPriority, sCou
0e50: 6e 74 72 79 2c 20 64 4f 70 74 2c 20 62 53 68 6f  ntry, dOpt, bSho
0e60: 77 52 75 6c 65 49 64 2c 20 62 44 65 62 75 67 2c  wRuleId, bDebug,
0e70: 20 62 43 6f 6e 74 65 78 74 29 0a 20 20 20 20 20   bContext).     
0e80: 20 20 20 69 66 20 73 4e 65 77 3a 0a 20 20 20 20     if sNew:.    
0e90: 20 20 20 20 20 20 20 20 73 54 65 78 74 20 3d 20          sText = 
0ea0: 73 4e 65 77 0a 20 20 20 20 65 78 63 65 70 74 3a  sNew.    except:
0eb0: 0a 20 20 20 20 20 20 20 20 72 61 69 73 65 0a 0a  .        raise..
0ec0: 20 20 20 20 23 20 63 6c 65 61 6e 75 70 0a 20 20      # cleanup.  
0ed0: 20 20 69 66 20 22 c2 a0 22 20 69 6e 20 73 54 65    if ".." in sTe
0ee0: 78 74 3a 0a 20 20 20 20 20 20 20 20 73 54 65 78  xt:.        sTex
0ef0: 74 20 3d 20 73 54 65 78 74 2e 72 65 70 6c 61 63  t = sText.replac
0f00: 65 28 22 c2 a0 22 2c 20 27 20 27 29 20 23 20 6e  e("..", ' ') # n
0f10: 62 73 70 0a 20 20 20 20 69 66 20 22 e2 80 af 22  bsp.    if "..."
0f20: 20 69 6e 20 73 54 65 78 74 3a 0a 20 20 20 20 20   in sText:.     
0f30: 20 20 20 73 54 65 78 74 20 3d 20 73 54 65 78 74     sText = sText
0f40: 2e 72 65 70 6c 61 63 65 28 22 e2 80 af 22 2c 20  .replace("...", 
0f50: 27 20 27 29 20 23 20 6e 6e 62 73 70 0a 20 20 20  ' ') # nnbsp.   
0f60: 20 69 66 20 22 27 22 20 69 6e 20 73 54 65 78 74   if "'" in sText
0f70: 3a 0a 20 20 20 20 20 20 20 20 73 54 65 78 74 20  :.        sText 
0f80: 3d 20 73 54 65 78 74 2e 72 65 70 6c 61 63 65 28  = sText.replace(
0f90: 22 27 22 2c 20 22 e2 80 99 22 29 0a 20 20 20 20  "'", "...").    
0fa0: 69 66 20 22 e2 80 91 22 20 69 6e 20 73 54 65 78  if "..." in sTex
0fb0: 74 3a 0a 20 20 20 20 20 20 20 20 73 54 65 78 74  t:.        sText
0fc0: 20 3d 20 73 54 65 78 74 2e 72 65 70 6c 61 63 65   = sText.replace
0fd0: 28 22 e2 80 91 22 2c 20 22 2d 22 29 20 23 20 6e  ("...", "-") # n
0fe0: 6f 62 72 65 61 6b 64 61 73 68 0a 0a 20 20 20 20  obreakdash..    
0ff0: 23 20 70 61 72 73 65 20 73 65 6e 74 65 6e 63 65  # parse sentence
1000: 73 0a 20 20 20 20 66 6f 72 20 69 53 74 61 72 74  s.    for iStart
1010: 2c 20 69 45 6e 64 20 69 6e 20 5f 67 65 74 53 65  , iEnd in _getSe
1020: 6e 74 65 6e 63 65 42 6f 75 6e 64 61 72 69 65 73  ntenceBoundaries
1030: 28 73 54 65 78 74 29 3a 0a 20 20 20 20 20 20 20  (sText):.       
1040: 20 69 66 20 34 20 3c 20 28 69 45 6e 64 20 2d 20   if 4 < (iEnd - 
1050: 69 53 74 61 72 74 29 20 3c 20 32 30 30 30 3a 0a  iStart) < 2000:.
1060: 20 20 20 20 20 20 20 20 20 20 20 20 74 72 79 3a              try:
1070: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1080: 20 6f 53 65 6e 74 65 6e 63 65 20 3d 20 54 6f 6b   oSentence = Tok
1090: 65 6e 53 65 6e 74 65 6e 63 65 28 73 54 65 78 74  enSentence(sText
10a0: 5b 69 53 74 61 72 74 3a 69 45 6e 64 5d 2c 20 73  [iStart:iEnd], s
10b0: 52 65 61 6c 54 65 78 74 5b 69 53 74 61 72 74 3a  RealText[iStart:
10c0: 69 45 6e 64 5d 2c 20 69 53 74 61 72 74 29 0a 20  iEnd], iStart). 
10d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5f                 _
10e0: 2c 20 65 72 72 73 20 3d 20 5f 70 72 6f 6f 66 72  , errs = _proofr
10f0: 65 61 64 28 6f 53 65 6e 74 65 6e 63 65 2c 20 73  ead(oSentence, s
1100: 54 65 78 74 5b 69 53 74 61 72 74 3a 69 45 6e 64  Text[iStart:iEnd
1110: 5d 2c 20 73 52 65 61 6c 54 65 78 74 5b 69 53 74  ], sRealText[iSt
1120: 61 72 74 3a 69 45 6e 64 5d 2c 20 69 53 74 61 72  art:iEnd], iStar
1130: 74 2c 20 46 61 6c 73 65 2c 20 64 50 72 69 6f 72  t, False, dPrior
1140: 69 74 79 2c 20 73 43 6f 75 6e 74 72 79 2c 20 64  ity, sCountry, d
1150: 4f 70 74 2c 20 62 53 68 6f 77 52 75 6c 65 49 64  Opt, bShowRuleId
1160: 2c 20 62 44 65 62 75 67 2c 20 62 43 6f 6e 74 65  , bDebug, bConte
1170: 78 74 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  xt).            
1180: 20 20 20 20 61 45 72 72 6f 72 73 2e 75 70 64 61      aErrors.upda
1190: 74 65 28 65 72 72 73 29 0a 20 20 20 20 20 20 20  te(errs).       
11a0: 20 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20       except:.   
11b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 61 69               rai
11c0: 73 65 0a 20 20 20 20 72 65 74 75 72 6e 20 61 45  se.    return aE
11d0: 72 72 6f 72 73 2e 76 61 6c 75 65 73 28 29 20 23  rrors.values() #
11e0: 20 74 68 69 73 20 69 73 20 61 20 76 69 65 77 20   this is a view 
11f0: 28 69 74 65 72 61 62 6c 65 29 0a 0a 0a 64 65 66  (iterable)...def
1200: 20 5f 70 72 6f 6f 66 72 65 61 64 20 28 6f 53 65   _proofread (oSe
1210: 6e 74 65 6e 63 65 2c 20 73 2c 20 73 78 2c 20 6e  ntence, s, sx, n
1220: 4f 66 66 73 65 74 2c 20 62 50 61 72 61 67 72 61  Offset, bParagra
1230: 70 68 2c 20 64 50 72 69 6f 72 69 74 79 2c 20 73  ph, dPriority, s
1240: 43 6f 75 6e 74 72 79 2c 20 64 4f 70 74 69 6f 6e  Country, dOption
1250: 73 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20  s, bShowRuleId, 
1260: 62 44 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74  bDebug, bContext
1270: 29 3a 0a 20 20 20 20 64 45 72 72 73 20 3d 20 7b  ):.    dErrs = {
1280: 7d 0a 20 20 20 20 62 50 61 72 61 67 72 61 70 68  }.    bParagraph
1290: 43 68 61 6e 67 65 20 3d 20 46 61 6c 73 65 0a 20  Change = False. 
12a0: 20 20 20 62 53 65 6e 74 65 6e 63 65 43 68 61 6e     bSentenceChan
12b0: 67 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 64  ge = False.    d
12c0: 54 6f 6b 65 6e 50 6f 73 20 3d 20 6f 53 65 6e 74  TokenPos = oSent
12d0: 65 6e 63 65 2e 64 54 6f 6b 65 6e 50 6f 73 20 69  ence.dTokenPos i
12e0: 66 20 6f 53 65 6e 74 65 6e 63 65 20 65 6c 73 65  f oSentence else
12f0: 20 7b 7d 0a 20 20 20 20 66 6f 72 20 73 4f 70 74   {}.    for sOpt
1300: 69 6f 6e 2c 20 6c 52 75 6c 65 47 72 6f 75 70 20  ion, lRuleGroup 
1310: 69 6e 20 5f 67 65 74 52 75 6c 65 73 28 62 50 61  in _getRules(bPa
1320: 72 61 67 72 61 70 68 29 3a 0a 20 20 20 20 20 20  ragraph):.      
1330: 20 20 69 66 20 73 4f 70 74 69 6f 6e 20 3d 3d 20    if sOption == 
1340: 22 40 40 40 40 22 3a 0a 20 20 20 20 20 20 20 20  "@@@@":.        
1350: 20 20 20 20 23 20 67 72 61 70 68 20 72 75 6c 65      # graph rule
1360: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  s.            if
1370: 20 6e 6f 74 20 62 50 61 72 61 67 72 61 70 68 20   not bParagraph 
1380: 61 6e 64 20 62 53 65 6e 74 65 6e 63 65 43 68 61  and bSentenceCha
1390: 6e 67 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  nge:.           
13a0: 20 20 20 20 20 6f 53 65 6e 74 65 6e 63 65 2e 75       oSentence.u
13b0: 70 64 61 74 65 28 73 2c 20 62 44 65 62 75 67 29  pdate(s, bDebug)
13c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
13d0: 20 62 53 65 6e 74 65 6e 63 65 43 68 61 6e 67 65   bSentenceChange
13e0: 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20   = False.       
13f0: 20 20 20 20 20 66 6f 72 20 73 47 72 61 70 68 4e       for sGraphN
1400: 61 6d 65 2c 20 73 4c 69 6e 65 49 64 20 69 6e 20  ame, sLineId in 
1410: 6c 52 75 6c 65 47 72 6f 75 70 3a 0a 20 20 20 20  lRuleGroup:.    
1420: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
1430: 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20  Debug:.         
1440: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
1450: 28 22 5c 6e 3e 3e 3e 3e 20 47 52 41 50 48 3a 22  ("\n>>>> GRAPH:"
1460: 2c 20 73 47 72 61 70 68 4e 61 6d 65 2c 20 73 4c  , sGraphName, sL
1470: 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20 20  ineId).         
1480: 20 20 20 20 20 20 20 62 50 61 72 61 67 72 61 70         bParagrap
1490: 68 43 68 61 6e 67 65 2c 20 73 20 3d 20 6f 53 65  hChange, s = oSe
14a0: 6e 74 65 6e 63 65 2e 70 61 72 73 65 28 64 41 6c  ntence.parse(dAl
14b0: 6c 47 72 61 70 68 5b 73 47 72 61 70 68 4e 61 6d  lGraph[sGraphNam
14c0: 65 5d 2c 20 64 50 72 69 6f 72 69 74 79 2c 20 73  e], dPriority, s
14d0: 43 6f 75 6e 74 72 79 2c 20 64 4f 70 74 69 6f 6e  Country, dOption
14e0: 73 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20  s, bShowRuleId, 
14f0: 62 44 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74  bDebug, bContext
1500: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
1510: 20 20 64 45 72 72 73 2e 75 70 64 61 74 65 28 6f    dErrs.update(o
1520: 53 65 6e 74 65 6e 63 65 2e 64 45 72 72 6f 72 29  Sentence.dError)
1530: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1540: 20 64 54 6f 6b 65 6e 50 6f 73 20 3d 20 6f 53 65   dTokenPos = oSe
1550: 6e 74 65 6e 63 65 2e 64 54 6f 6b 65 6e 50 6f 73  ntence.dTokenPos
1560: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 6e 6f  .        elif no
1570: 74 20 73 4f 70 74 69 6f 6e 20 6f 72 20 64 4f 70  t sOption or dOp
1580: 74 69 6f 6e 73 2e 67 65 74 28 73 4f 70 74 69 6f  tions.get(sOptio
1590: 6e 2c 20 46 61 6c 73 65 29 3a 0a 20 20 20 20 20  n, False):.     
15a0: 20 20 20 20 20 20 20 23 20 72 65 67 65 78 20 72         # regex r
15b0: 75 6c 65 73 0a 20 20 20 20 20 20 20 20 20 20 20  ules.           
15c0: 20 66 6f 72 20 7a 52 65 67 65 78 2c 20 62 55 70   for zRegex, bUp
15d0: 70 65 72 63 61 73 65 2c 20 73 4c 69 6e 65 49 64  percase, sLineId
15e0: 2c 20 73 52 75 6c 65 49 64 2c 20 6e 50 72 69 6f  , sRuleId, nPrio
15f0: 72 69 74 79 2c 20 6c 41 63 74 69 6f 6e 73 20 69  rity, lActions i
1600: 6e 20 6c 52 75 6c 65 47 72 6f 75 70 3a 0a 20 20  n lRuleGroup:.  
1610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
1620: 20 73 52 75 6c 65 49 64 20 6e 6f 74 20 69 6e 20   sRuleId not in 
1630: 5f 61 49 67 6e 6f 72 65 64 52 75 6c 65 73 3a 0a  _aIgnoredRules:.
1640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1650: 20 20 20 20 66 6f 72 20 6d 20 69 6e 20 7a 52 65      for m in zRe
1660: 67 65 78 2e 66 69 6e 64 69 74 65 72 28 73 29 3a  gex.finditer(s):
1670: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1680: 20 20 20 20 20 20 20 20 20 62 43 6f 6e 64 4d 65           bCondMe
1690: 6d 6f 20 3d 20 4e 6f 6e 65 0a 20 20 20 20 20 20  mo = None.      
16a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16b0: 20 20 66 6f 72 20 73 46 75 6e 63 43 6f 6e 64 2c    for sFuncCond,
16c0: 20 63 41 63 74 69 6f 6e 54 79 70 65 2c 20 73 57   cActionType, sW
16d0: 68 61 74 2c 20 2a 65 41 63 74 20 69 6e 20 6c 41  hat, *eAct in lA
16e0: 63 74 69 6f 6e 73 3a 0a 20 20 20 20 20 20 20 20  ctions:.        
16f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1700: 20 20 20 20 23 20 61 63 74 69 6f 6e 20 69 6e 20      # action in 
1710: 6c 41 63 74 69 6f 6e 73 3a 20 5b 20 63 6f 6e 64  lActions: [ cond
1720: 69 74 69 6f 6e 2c 20 61 63 74 69 6f 6e 20 74 79  ition, action ty
1730: 70 65 2c 20 72 65 70 6c 61 63 65 6d 65 6e 74 2f  pe, replacement/
1740: 73 75 67 67 65 73 74 69 6f 6e 2f 61 63 74 69 6f  suggestion/actio
1750: 6e 5b 2c 20 69 47 72 6f 75 70 5b 2c 20 6d 65 73  n[, iGroup[, mes
1760: 73 61 67 65 2c 20 55 52 4c 5d 5d 20 5d 0a 20 20  sage, URL]] ].  
1770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1780: 20 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20            try:. 
1790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62                 b
17b0: 43 6f 6e 64 4d 65 6d 6f 20 3d 20 6e 6f 74 20 73  CondMemo = not s
17c0: 46 75 6e 63 43 6f 6e 64 20 6f 72 20 67 6c 6f 62  FuncCond or glob
17d0: 61 6c 73 28 29 5b 73 46 75 6e 63 43 6f 6e 64 5d  als()[sFuncCond]
17e0: 28 73 2c 20 73 78 2c 20 6d 2c 20 64 54 6f 6b 65  (s, sx, m, dToke
17f0: 6e 50 6f 73 2c 20 73 43 6f 75 6e 74 72 79 2c 20  nPos, sCountry, 
1800: 62 43 6f 6e 64 4d 65 6d 6f 29 0a 20 20 20 20 20  bCondMemo).     
1810: 20 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 69 66 20 62 43             if bC
1830: 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20 20 20 20  ondMemo:.       
1840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1850: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
1860: 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20  bDebug:.        
1870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1890: 70 72 69 6e 74 28 22 52 55 4c 45 3a 22 2c 20 73  print("RULE:", s
18a0: 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20  LineId).        
18b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18c0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 63              if c
18d0: 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 2d  ActionType == "-
18e0: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
18f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1900: 20 20 20 20 20 20 20 20 20 20 20 23 20 67 72 61             # gra
1910: 6d 6d 61 72 20 65 72 72 6f 72 0a 20 20 20 20 20  mmar error.     
1920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1940: 20 20 20 6e 45 72 72 6f 72 53 74 61 72 74 20 3d     nErrorStart =
1950: 20 6e 4f 66 66 73 65 74 20 2b 20 6d 2e 73 74 61   nOffset + m.sta
1960: 72 74 28 65 41 63 74 5b 30 5d 29 0a 20 20 20 20  rt(eAct[0]).    
1970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1990: 20 20 20 20 69 66 20 6e 45 72 72 6f 72 53 74 61      if nErrorSta
19a0: 72 74 20 6e 6f 74 20 69 6e 20 64 45 72 72 73 20  rt not in dErrs 
19b0: 6f 72 20 6e 50 72 69 6f 72 69 74 79 20 3e 20 64  or nPriority > d
19c0: 50 72 69 6f 72 69 74 79 2e 67 65 74 28 6e 45 72  Priority.get(nEr
19d0: 72 6f 72 53 74 61 72 74 2c 20 2d 31 29 3a 0a 20  rorStart, -1):. 
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 20 20 20 20 20 20 20 20 20                  
1a00: 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72 73             dErrs
1a10: 5b 6e 45 72 72 6f 72 53 74 61 72 74 5d 20 3d 20  [nErrorStart] = 
1a20: 5f 63 72 65 61 74 65 45 72 72 6f 72 28 73 2c 20  _createError(s, 
1a30: 73 78 2c 20 73 57 68 61 74 2c 20 6e 4f 66 66 73  sx, sWhat, nOffs
1a40: 65 74 2c 20 6d 2c 20 65 41 63 74 5b 30 5d 2c 20  et, m, eAct[0], 
1a50: 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64  sLineId, sRuleId
1a60: 2c 20 62 55 70 70 65 72 63 61 73 65 2c 20 65 41  , bUppercase, eA
1a70: 63 74 5b 31 5d 2c 20 65 41 63 74 5b 32 5d 2c 20  ct[1], eAct[2], 
1a80: 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 73 4f 70  bShowRuleId, sOp
1a90: 74 69 6f 6e 2c 20 62 43 6f 6e 74 65 78 74 29 0a  tion, bContext).
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 20 20 20 20 20 20 20 20 20                  
1ac0: 20 20 20 20 20 20 20 20 20 20 20 20 64 50 72 69              dPri
1ad0: 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53 74 61 72  ority[nErrorStar
1ae0: 74 5d 20 3d 20 6e 50 72 69 6f 72 69 74 79 0a 20  t] = nPriority. 
1af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b10: 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54     elif cActionT
1b20: 79 70 65 20 3d 3d 20 22 7e 22 3a 0a 20 20 20 20  ype == "~":.    
1b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b50: 20 20 20 20 23 20 74 65 78 74 20 70 72 6f 63 65      # text proce
1b60: 73 73 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20  ssor.           
1b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 20 3d               s =
1b90: 20 5f 72 65 77 72 69 74 65 28 73 2c 20 73 57 68   _rewrite(s, sWh
1ba0: 61 74 2c 20 65 41 63 74 5b 30 5d 2c 20 6d 2c 20  at, eAct[0], m, 
1bb0: 62 55 70 70 65 72 63 61 73 65 29 0a 20 20 20 20  bUppercase).    
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1be0: 20 20 20 20 62 50 61 72 61 67 72 61 70 68 43 68      bParagraphCh
1bf0: 61 6e 67 65 20 3d 20 54 72 75 65 0a 20 20 20 20  ange = True.    
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c20: 20 20 20 20 62 53 65 6e 74 65 6e 63 65 43 68 61      bSentenceCha
1c30: 6e 67 65 20 3d 20 54 72 75 65 0a 20 20 20 20 20  nge = True.     
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c60: 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20     if bDebug:.  
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 20 20 20 20 20 65 63 68 6f 28 22            echo("
1ca0: 7e 20 22 20 2b 20 73 20 2b 20 22 20 20 2d 2d 20  ~ " + s + "  -- 
1cb0: 22 20 2b 20 6d 2e 67 72 6f 75 70 28 65 41 63 74  " + m.group(eAct
1cc0: 5b 30 5d 29 20 2b 20 22 20 20 23 20 22 20 2b 20  [0]) + "  # " + 
1cd0: 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20  sLineId).       
1ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 69               eli
1d00: 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d  f cActionType ==
1d10: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "=":.          
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 23 20                # 
1d40: 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 0a 20  disambiguation. 
1d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d70: 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 62 50         if not bP
1d80: 61 72 61 67 72 61 70 68 3a 0a 20 20 20 20 20 20  aragraph:.      
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 20 20                  
1db0: 20 20 20 20 20 20 67 6c 6f 62 61 6c 73 28 29 5b        globals()[
1dc0: 73 57 68 61 74 5d 28 73 2c 20 6d 2c 20 64 54 6f  sWhat](s, m, dTo
1dd0: 6b 65 6e 50 6f 73 29 0a 20 20 20 20 20 20 20 20  kenPos).        
1de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e00: 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20      if bDebug:. 
1e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
1e40: 63 68 6f 28 22 3d 20 22 20 2b 20 6d 2e 67 72 6f  cho("= " + m.gro
1e50: 75 70 28 30 29 20 2b 20 22 20 20 23 20 22 20 2b  up(0) + "  # " +
1e60: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
1e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
1e90: 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d  if cActionType =
1ea0: 3d 20 22 3e 22 3a 0a 20 20 20 20 20 20 20 20 20  = ">":.         
1eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
1ed0: 20 77 65 20 64 6f 20 6e 6f 74 68 69 6e 67 2c 20   we do nothing, 
1ee0: 74 68 69 73 20 74 65 73 74 20 69 73 20 6a 75 73  this test is jus
1ef0: 74 20 61 20 63 6f 6e 64 69 74 69 6f 6e 20 74 6f  t a condition to
1f00: 20 61 70 70 6c 79 20 61 6c 6c 20 66 6f 6c 6c 6f   apply all follo
1f10: 77 69 6e 67 20 61 63 74 69 6f 6e 73 0a 20 20 20  wing actions.   
1f20: 20 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 70 61 73 73 0a 20 20 20 20 20 20       pass.      
1f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
1f70: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f90: 20 20 20 20 20 20 20 20 20 20 20 20 65 63 68 6f              echo
1fa0: 28 22 23 20 65 72 72 6f 72 3a 20 75 6e 6b 6e 6f  ("# error: unkno
1fb0: 77 6e 20 61 63 74 69 6f 6e 20 61 74 20 22 20 2b  wn action at " +
1fc0: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
1fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fe0: 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63            elif c
1ff0: 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 3e  ActionType == ">
2000: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
2010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2020: 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20 20         break.   
2030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2040: 20 20 20 20 20 20 20 20 20 65 78 63 65 70 74 20           except 
2050: 45 78 63 65 70 74 69 6f 6e 20 61 73 20 65 3a 0a  Exception as e:.
2060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2080: 72 61 69 73 65 20 45 78 63 65 70 74 69 6f 6e 28  raise Exception(
2090: 73 74 72 28 65 29 2c 20 22 23 20 22 20 2b 20 73  str(e), "# " + s
20a0: 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20 2b  LineId + " # " +
20b0: 20 73 52 75 6c 65 49 64 29 0a 20 20 20 20 69 66   sRuleId).    if
20c0: 20 62 50 61 72 61 67 72 61 70 68 43 68 61 6e 67   bParagraphChang
20d0: 65 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  e:.        retur
20e0: 6e 20 28 73 2c 20 64 45 72 72 73 29 0a 20 20 20  n (s, dErrs).   
20f0: 20 72 65 74 75 72 6e 20 28 46 61 6c 73 65 2c 20   return (False, 
2100: 64 45 72 72 73 29 0a 0a 0a 64 65 66 20 5f 63 72  dErrs)...def _cr
2110: 65 61 74 65 45 72 72 6f 72 20 28 73 2c 20 73 78  eateError (s, sx
2120: 2c 20 73 52 65 70 6c 2c 20 6e 4f 66 66 73 65 74  , sRepl, nOffset
2130: 2c 20 6d 2c 20 69 47 72 6f 75 70 2c 20 73 4c 69  , m, iGroup, sLi
2140: 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 62  neId, sRuleId, b
2150: 55 70 70 65 72 63 61 73 65 2c 20 73 4d 73 67 2c  Uppercase, sMsg,
2160: 20 73 55 52 4c 2c 20 62 53 68 6f 77 52 75 6c 65   sURL, bShowRule
2170: 49 64 2c 20 73 4f 70 74 69 6f 6e 2c 20 62 43 6f  Id, sOption, bCo
2180: 6e 74 65 78 74 29 3a 0a 20 20 20 20 6e 53 74 61  ntext):.    nSta
2190: 72 74 20 3d 20 6e 4f 66 66 73 65 74 20 2b 20 6d  rt = nOffset + m
21a0: 2e 73 74 61 72 74 28 69 47 72 6f 75 70 29 0a 20  .start(iGroup). 
21b0: 20 20 20 6e 45 6e 64 20 3d 20 6e 4f 66 66 73 65     nEnd = nOffse
21c0: 74 20 2b 20 6d 2e 65 6e 64 28 69 47 72 6f 75 70  t + m.end(iGroup
21d0: 29 0a 20 20 20 20 23 20 73 75 67 67 65 73 74 69  ).    # suggesti
21e0: 6f 6e 73 0a 20 20 20 20 69 66 20 73 52 65 70 6c  ons.    if sRepl
21f0: 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20  [0:1] == "=":.  
2200: 20 20 20 20 20 20 73 53 75 67 67 20 3d 20 67 6c        sSugg = gl
2210: 6f 62 61 6c 73 28 29 5b 73 52 65 70 6c 5b 31 3a  obals()[sRepl[1:
2220: 5d 5d 28 73 2c 20 6d 29 0a 20 20 20 20 20 20 20  ]](s, m).       
2230: 20 6c 53 75 67 67 20 3d 20 73 53 75 67 67 2e 73   lSugg = sSugg.s
2240: 70 6c 69 74 28 22 7c 22 29 20 20 69 66 20 73 53  plit("|")  if sS
2250: 75 67 67 20 20 65 6c 73 65 20 5b 5d 0a 20 20 20  ugg  else [].   
2260: 20 65 6c 69 66 20 73 52 65 70 6c 20 3d 3d 20 22   elif sRepl == "
2270: 5f 22 3a 0a 20 20 20 20 20 20 20 20 6c 53 75 67  _":.        lSug
2280: 67 20 3d 20 5b 5d 0a 20 20 20 20 65 6c 73 65 3a  g = [].    else:
2290: 0a 20 20 20 20 20 20 20 20 6c 53 75 67 67 20 3d  .        lSugg =
22a0: 20 6d 2e 65 78 70 61 6e 64 28 73 52 65 70 6c 29   m.expand(sRepl)
22b0: 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20 20  .split("|").    
22c0: 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e  if bUppercase an
22d0: 64 20 6c 53 75 67 67 20 61 6e 64 20 6d 2e 67 72  d lSugg and m.gr
22e0: 6f 75 70 28 69 47 72 6f 75 70 29 5b 30 3a 31 5d  oup(iGroup)[0:1]
22f0: 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20 20  .isupper():.    
2300: 20 20 20 20 6c 53 75 67 67 20 3d 20 6c 69 73 74      lSugg = list
2310: 28 6d 61 70 28 73 74 72 2e 63 61 70 69 74 61 6c  (map(str.capital
2320: 69 7a 65 2c 20 6c 53 75 67 67 29 29 0a 20 20 20  ize, lSugg)).   
2330: 20 23 20 4d 65 73 73 61 67 65 0a 20 20 20 20 73   # Message.    s
2340: 4d 65 73 73 61 67 65 20 3d 20 67 6c 6f 62 61 6c  Message = global
2350: 73 28 29 5b 73 4d 73 67 5b 31 3a 5d 5d 28 73 2c  s()[sMsg[1:]](s,
2360: 20 6d 29 20 20 69 66 20 73 4d 73 67 5b 30 3a 31   m)  if sMsg[0:1
2370: 5d 20 3d 3d 20 22 3d 22 20 20 65 6c 73 65 20 20  ] == "="  else  
2380: 6d 2e 65 78 70 61 6e 64 28 73 4d 73 67 29 0a 20  m.expand(sMsg). 
2390: 20 20 20 69 66 20 62 53 68 6f 77 52 75 6c 65 49     if bShowRuleI
23a0: 64 3a 0a 20 20 20 20 20 20 20 20 73 4d 65 73 73  d:.        sMess
23b0: 61 67 65 20 2b 3d 20 22 20 20 23 20 22 20 2b 20  age += "  # " + 
23c0: 73 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20  sLineId + " # " 
23d0: 2b 20 73 52 75 6c 65 49 64 0a 20 20 20 20 23 0a  + sRuleId.    #.
23e0: 20 20 20 20 69 66 20 5f 62 57 72 69 74 65 72 45      if _bWriterE
23f0: 72 72 6f 72 3a 0a 20 20 20 20 20 20 20 20 78 45  rror:.        xE
2400: 72 72 20 3d 20 53 69 6e 67 6c 65 50 72 6f 6f 66  rr = SingleProof
2410: 72 65 61 64 69 6e 67 45 72 72 6f 72 28 29 20 20  readingError()  
2420: 20 20 23 20 75 6e 6f 2e 63 72 65 61 74 65 55 6e    # uno.createUn
2430: 6f 53 74 72 75 63 74 28 20 22 63 6f 6d 2e 73 75  oStruct( "com.su
2440: 6e 2e 73 74 61 72 2e 6c 69 6e 67 75 69 73 74 69  n.star.linguisti
2450: 63 32 2e 53 69 6e 67 6c 65 50 72 6f 6f 66 72 65  c2.SingleProofre
2460: 61 64 69 6e 67 45 72 72 6f 72 22 20 29 0a 20 20  adingError" ).  
2470: 20 20 20 20 20 20 78 45 72 72 2e 6e 45 72 72 6f        xErr.nErro
2480: 72 53 74 61 72 74 20 3d 20 6e 53 74 61 72 74 0a  rStart = nStart.
2490: 20 20 20 20 20 20 20 20 78 45 72 72 2e 6e 45 72          xErr.nEr
24a0: 72 6f 72 4c 65 6e 67 74 68 20 3d 20 6e 45 6e 64  rorLength = nEnd
24b0: 20 2d 20 6e 53 74 61 72 74 0a 20 20 20 20 20 20   - nStart.      
24c0: 20 20 78 45 72 72 2e 6e 45 72 72 6f 72 54 79 70    xErr.nErrorTyp
24d0: 65 20 3d 20 50 52 4f 4f 46 52 45 41 44 49 4e 47  e = PROOFREADING
24e0: 0a 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 52  .        xErr.aR
24f0: 75 6c 65 49 64 65 6e 74 69 66 69 65 72 20 3d 20  uleIdentifier = 
2500: 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20 20 20  sRuleId.        
2510: 78 45 72 72 2e 61 53 68 6f 72 74 43 6f 6d 6d 65  xErr.aShortComme
2520: 6e 74 20 3d 20 73 4d 65 73 73 61 67 65 20 20 20  nt = sMessage   
2530: 23 20 73 4d 65 73 73 61 67 65 2e 73 70 6c 69 74  # sMessage.split
2540: 28 22 7c 22 29 5b 30 5d 20 20 20 20 20 23 20 69  ("|")[0]     # i
2550: 6e 20 63 6f 6e 74 65 78 74 20 6d 65 6e 75 0a 20  n context menu. 
2560: 20 20 20 20 20 20 20 78 45 72 72 2e 61 46 75 6c         xErr.aFul
2570: 6c 43 6f 6d 6d 65 6e 74 20 3d 20 73 4d 65 73 73  lComment = sMess
2580: 61 67 65 20 20 20 23 20 73 4d 65 73 73 61 67 65  age   # sMessage
2590: 2e 73 70 6c 69 74 28 22 7c 22 29 5b 2d 31 5d 20  .split("|")[-1] 
25a0: 20 20 20 23 20 69 6e 20 64 69 61 6c 6f 67 0a 20     # in dialog. 
25b0: 20 20 20 20 20 20 20 69 66 20 62 53 68 6f 77 52         if bShowR
25c0: 75 6c 65 49 64 3a 0a 20 20 20 20 20 20 20 20 20  uleId:.         
25d0: 20 20 20 78 45 72 72 2e 61 53 68 6f 72 74 43 6f     xErr.aShortCo
25e0: 6d 6d 65 6e 74 20 2b 3d 20 22 20 20 22 20 2b 20  mment += "  " + 
25f0: 73 4c 69 6e 65 49 64 20 2b 20 22 20 23 20 22 20  sLineId + " # " 
2600: 2b 20 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20  + sRuleId.      
2610: 20 20 78 45 72 72 2e 61 53 75 67 67 65 73 74 69    xErr.aSuggesti
2620: 6f 6e 73 20 3d 20 74 75 70 6c 65 28 6c 53 75 67  ons = tuple(lSug
2630: 67 29 0a 20 20 20 20 20 20 20 20 69 66 20 73 55  g).        if sU
2640: 52 4c 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  RL:.            
2650: 78 50 72 6f 70 65 72 74 79 20 3d 20 50 72 6f 70  xProperty = Prop
2660: 65 72 74 79 56 61 6c 75 65 28 29 0a 20 20 20 20  ertyValue().    
2670: 20 20 20 20 20 20 20 20 78 50 72 6f 70 65 72 74          xPropert
2680: 79 2e 4e 61 6d 65 20 3d 20 22 46 75 6c 6c 43 6f  y.Name = "FullCo
2690: 6d 6d 65 6e 74 55 52 4c 22 0a 20 20 20 20 20 20  mmentURL".      
26a0: 20 20 20 20 20 20 78 50 72 6f 70 65 72 74 79 2e        xProperty.
26b0: 56 61 6c 75 65 20 3d 20 73 55 52 4c 0a 20 20 20  Value = sURL.   
26c0: 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 50           xErr.aP
26d0: 72 6f 70 65 72 74 69 65 73 20 3d 20 28 78 50 72  roperties = (xPr
26e0: 6f 70 65 72 74 79 2c 29 0a 20 20 20 20 20 20 20  operty,).       
26f0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
2700: 20 20 20 78 45 72 72 2e 61 50 72 6f 70 65 72 74     xErr.aPropert
2710: 69 65 73 20 3d 20 28 29 0a 20 20 20 20 20 20 20  ies = ().       
2720: 20 72 65 74 75 72 6e 20 78 45 72 72 0a 20 20 20   return xErr.   
2730: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 64   else:.        d
2740: 45 72 72 20 3d 20 7b 7d 0a 20 20 20 20 20 20 20  Err = {}.       
2750: 20 64 45 72 72 5b 22 6e 53 74 61 72 74 22 5d 20   dErr["nStart"] 
2760: 3d 20 6e 53 74 61 72 74 0a 20 20 20 20 20 20 20  = nStart.       
2770: 20 64 45 72 72 5b 22 6e 45 6e 64 22 5d 20 3d 20   dErr["nEnd"] = 
2780: 6e 45 6e 64 0a 20 20 20 20 20 20 20 20 64 45 72  nEnd.        dEr
2790: 72 5b 22 73 4c 69 6e 65 49 64 22 5d 20 3d 20 73  r["sLineId"] = s
27a0: 4c 69 6e 65 49 64 0a 20 20 20 20 20 20 20 20 64  LineId.        d
27b0: 45 72 72 5b 22 73 52 75 6c 65 49 64 22 5d 20 3d  Err["sRuleId"] =
27c0: 20 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20 20   sRuleId.       
27d0: 20 64 45 72 72 5b 22 73 54 79 70 65 22 5d 20 3d   dErr["sType"] =
27e0: 20 73 4f 70 74 69 6f 6e 20 20 69 66 20 73 4f 70   sOption  if sOp
27f0: 74 69 6f 6e 20 20 65 6c 73 65 20 22 6e 6f 74 79  tion  else "noty
2800: 70 65 22 0a 20 20 20 20 20 20 20 20 64 45 72 72  pe".        dErr
2810: 5b 22 73 4d 65 73 73 61 67 65 22 5d 20 3d 20 73  ["sMessage"] = s
2820: 4d 65 73 73 61 67 65 0a 20 20 20 20 20 20 20 20  Message.        
2830: 64 45 72 72 5b 22 61 53 75 67 67 65 73 74 69 6f  dErr["aSuggestio
2840: 6e 73 22 5d 20 3d 20 6c 53 75 67 67 0a 20 20 20  ns"] = lSugg.   
2850: 20 20 20 20 20 64 45 72 72 5b 22 55 52 4c 22 5d       dErr["URL"]
2860: 20 3d 20 73 55 52 4c 20 20 69 66 20 73 55 52 4c   = sURL  if sURL
2870: 20 20 65 6c 73 65 20 22 22 0a 20 20 20 20 20 20    else "".      
2880: 20 20 69 66 20 62 43 6f 6e 74 65 78 74 3a 0a 20    if bContext:. 
2890: 20 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b             dErr[
28a0: 27 73 55 6e 64 65 72 6c 69 6e 65 64 27 5d 20 3d  'sUnderlined'] =
28b0: 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 30   self.sSentence0
28c0: 5b 6e 53 74 61 72 74 3a 6e 45 6e 64 5d 0a 20 20  [nStart:nEnd].  
28d0: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 27            dErr['
28e0: 73 42 65 66 6f 72 65 27 5d 20 3d 20 73 65 6c 66  sBefore'] = self
28f0: 2e 73 53 65 6e 74 65 6e 63 65 30 5b 6d 61 78 28  .sSentence0[max(
2900: 30 2c 6e 53 74 61 72 74 2d 38 30 29 3a 6e 53 74  0,nStart-80):nSt
2910: 61 72 74 5d 0a 20 20 20 20 20 20 20 20 20 20 20  art].           
2920: 20 64 45 72 72 5b 27 73 41 66 74 65 72 27 5d 20   dErr['sAfter'] 
2930: 3d 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65  = self.sSentence
2940: 30 5b 6e 45 6e 64 3a 6e 45 6e 64 2b 38 30 5d 0a  0[nEnd:nEnd+80].
2950: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 64          return d
2960: 45 72 72 0a 0a 0a 64 65 66 20 5f 72 65 77 72 69  Err...def _rewri
2970: 74 65 20 28 73 53 65 6e 74 65 6e 63 65 2c 20 73  te (sSentence, s
2980: 52 65 70 6c 2c 20 69 47 72 6f 75 70 2c 20 6d 2c  Repl, iGroup, m,
2990: 20 62 55 70 70 65 72 63 61 73 65 29 3a 0a 20 20   bUppercase):.  
29a0: 20 20 22 74 65 78 74 20 70 72 6f 63 65 73 73 6f    "text processo
29b0: 72 3a 20 77 72 69 74 65 20 3c 73 52 65 70 6c 3e  r: write <sRepl>
29c0: 20 69 6e 20 3c 73 53 65 6e 74 65 6e 63 65 3e 20   in <sSentence> 
29d0: 61 74 20 3c 69 47 72 6f 75 70 3e 20 70 6f 73 69  at <iGroup> posi
29e0: 74 69 6f 6e 22 0a 20 20 20 20 6e 4c 65 6e 20 3d  tion".    nLen =
29f0: 20 6d 2e 65 6e 64 28 69 47 72 6f 75 70 29 20 2d   m.end(iGroup) -
2a00: 20 6d 2e 73 74 61 72 74 28 69 47 72 6f 75 70 29   m.start(iGroup)
2a10: 0a 20 20 20 20 69 66 20 73 52 65 70 6c 20 3d 3d  .    if sRepl ==
2a20: 20 22 2a 22 3a 0a 20 20 20 20 20 20 20 20 73 4e   "*":.        sN
2a30: 65 77 20 3d 20 22 20 22 20 2a 20 6e 4c 65 6e 0a  ew = " " * nLen.
2a40: 20 20 20 20 65 6c 69 66 20 73 52 65 70 6c 20 3d      elif sRepl =
2a50: 3d 20 22 5f 22 3a 0a 20 20 20 20 20 20 20 20 73  = "_":.        s
2a60: 4e 65 77 20 3d 20 73 52 65 70 6c 20 2b 20 22 20  New = sRepl + " 
2a70: 22 20 2a 20 28 6e 4c 65 6e 2d 31 29 0a 20 20 20  " * (nLen-1).   
2a80: 20 65 6c 69 66 20 73 52 65 70 6c 5b 30 3a 31 5d   elif sRepl[0:1]
2a90: 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20   == "=":.       
2aa0: 20 73 4e 65 77 20 3d 20 67 6c 6f 62 61 6c 73 28   sNew = globals(
2ab0: 29 5b 73 52 65 70 6c 5b 31 3a 5d 5d 28 73 53 65  )[sRepl[1:]](sSe
2ac0: 6e 74 65 6e 63 65 2c 20 6d 29 0a 20 20 20 20 20  ntence, m).     
2ad0: 20 20 20 73 4e 65 77 20 3d 20 73 4e 65 77 20 2b     sNew = sNew +
2ae0: 20 22 20 22 20 2a 20 28 6e 4c 65 6e 2d 6c 65 6e   " " * (nLen-len
2af0: 28 73 4e 65 77 29 29 0a 20 20 20 20 20 20 20 20  (sNew)).        
2b00: 69 66 20 62 55 70 70 65 72 63 61 73 65 20 61 6e  if bUppercase an
2b10: 64 20 6d 2e 67 72 6f 75 70 28 69 47 72 6f 75 70  d m.group(iGroup
2b20: 29 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28 29  )[0:1].isupper()
2b30: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4e  :.            sN
2b40: 65 77 20 3d 20 73 4e 65 77 2e 63 61 70 69 74 61  ew = sNew.capita
2b50: 6c 69 7a 65 28 29 0a 20 20 20 20 65 6c 73 65 3a  lize().    else:
2b60: 0a 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20  .        sNew = 
2b70: 6d 2e 65 78 70 61 6e 64 28 73 52 65 70 6c 29 0a  m.expand(sRepl).
2b80: 20 20 20 20 20 20 20 20 73 4e 65 77 20 3d 20 73          sNew = s
2b90: 4e 65 77 20 2b 20 22 20 22 20 2a 20 28 6e 4c 65  New + " " * (nLe
2ba0: 6e 2d 6c 65 6e 28 73 4e 65 77 29 29 0a 20 20 20  n-len(sNew)).   
2bb0: 20 72 65 74 75 72 6e 20 73 53 65 6e 74 65 6e 63   return sSentenc
2bc0: 65 5b 30 3a 6d 2e 73 74 61 72 74 28 69 47 72 6f  e[0:m.start(iGro
2bd0: 75 70 29 5d 20 2b 20 73 4e 65 77 20 2b 20 73 53  up)] + sNew + sS
2be0: 65 6e 74 65 6e 63 65 5b 6d 2e 65 6e 64 28 69 47  entence[m.end(iG
2bf0: 72 6f 75 70 29 3a 5d 0a 0a 0a 64 65 66 20 69 67  roup):]...def ig
2c00: 6e 6f 72 65 52 75 6c 65 20 28 73 52 75 6c 65 49  noreRule (sRuleI
2c10: 64 29 3a 0a 20 20 20 20 22 64 69 73 61 62 6c 65  d):.    "disable
2c20: 20 72 75 6c 65 20 3c 73 52 75 6c 65 49 64 3e 22   rule <sRuleId>"
2c30: 0a 20 20 20 20 5f 61 49 67 6e 6f 72 65 64 52 75  .    _aIgnoredRu
2c40: 6c 65 73 2e 61 64 64 28 73 52 75 6c 65 49 64 29  les.add(sRuleId)
2c50: 0a 0a 0a 64 65 66 20 72 65 73 65 74 49 67 6e 6f  ...def resetIgno
2c60: 72 65 52 75 6c 65 73 20 28 29 3a 0a 20 20 20 20  reRules ():.    
2c70: 22 63 6c 65 61 72 20 61 6c 6c 20 69 67 6e 6f 72  "clear all ignor
2c80: 65 64 20 72 75 6c 65 73 22 0a 20 20 20 20 5f 61  ed rules".    _a
2c90: 49 67 6e 6f 72 65 64 52 75 6c 65 73 2e 63 6c 65  IgnoredRules.cle
2ca0: 61 72 28 29 0a 0a 0a 64 65 66 20 72 65 61 63 74  ar()...def react
2cb0: 69 76 61 74 65 52 75 6c 65 20 28 73 52 75 6c 65  ivateRule (sRule
2cc0: 49 64 29 3a 0a 20 20 20 20 22 28 72 65 29 61 63  Id):.    "(re)ac
2cd0: 74 69 76 61 74 65 20 72 75 6c 65 20 3c 73 52 75  tivate rule <sRu
2ce0: 6c 65 49 64 3e 22 0a 20 20 20 20 5f 61 49 67 6e  leId>".    _aIgn
2cf0: 6f 72 65 64 52 75 6c 65 73 2e 64 69 73 63 61 72  oredRules.discar
2d00: 64 28 73 52 75 6c 65 49 64 29 0a 0a 0a 64 65 66  d(sRuleId)...def
2d10: 20 6c 69 73 74 52 75 6c 65 73 20 28 73 46 69 6c   listRules (sFil
2d20: 74 65 72 3d 4e 6f 6e 65 29 3a 0a 20 20 20 20 22  ter=None):.    "
2d30: 67 65 6e 65 72 61 74 6f 72 3a 20 72 65 74 75 72  generator: retur
2d40: 6e 73 20 74 79 70 6c 65 20 28 73 4f 70 74 69 6f  ns typle (sOptio
2d50: 6e 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c  n, sLineId, sRul
2d60: 65 49 64 29 22 0a 20 20 20 20 69 66 20 73 46 69  eId)".    if sFi
2d70: 6c 74 65 72 3a 0a 20 20 20 20 20 20 20 20 74 72  lter:.        tr
2d80: 79 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 7a  y:.            z
2d90: 46 69 6c 74 65 72 20 3d 20 72 65 2e 63 6f 6d 70  Filter = re.comp
2da0: 69 6c 65 28 73 46 69 6c 74 65 72 29 0a 20 20 20  ile(sFilter).   
2db0: 20 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20       except:.   
2dc0: 20 20 20 20 20 20 20 20 20 65 63 68 6f 28 22 23           echo("#
2dd0: 20 45 72 72 6f 72 2e 20 4c 69 73 74 20 72 75 6c   Error. List rul
2de0: 65 73 3a 20 77 72 6f 6e 67 20 72 65 67 65 78 2e  es: wrong regex.
2df0: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ").            s
2e00: 46 69 6c 74 65 72 20 3d 20 4e 6f 6e 65 0a 20 20  Filter = None.  
2e10: 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 6c    for sOption, l
2e20: 52 75 6c 65 47 72 6f 75 70 20 69 6e 20 63 68 61  RuleGroup in cha
2e30: 69 6e 28 5f 67 65 74 52 75 6c 65 73 28 54 72 75  in(_getRules(Tru
2e40: 65 29 2c 20 5f 67 65 74 52 75 6c 65 73 28 46 61  e), _getRules(Fa
2e50: 6c 73 65 29 29 3a 0a 20 20 20 20 20 20 20 20 69  lse)):.        i
2e60: 66 20 73 4f 70 74 69 6f 6e 20 21 3d 20 22 40 40  f sOption != "@@
2e70: 40 40 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  @@":.           
2e80: 20 66 6f 72 20 5f 2c 20 5f 2c 20 73 4c 69 6e 65   for _, _, sLine
2e90: 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 5f 2c 20  Id, sRuleId, _, 
2ea0: 5f 20 69 6e 20 6c 52 75 6c 65 47 72 6f 75 70 3a  _ in lRuleGroup:
2eb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2ec0: 20 69 66 20 6e 6f 74 20 73 46 69 6c 74 65 72 20   if not sFilter 
2ed0: 6f 72 20 7a 46 69 6c 74 65 72 2e 73 65 61 72 63  or zFilter.searc
2ee0: 68 28 73 52 75 6c 65 49 64 29 3a 0a 20 20 20 20  h(sRuleId):.    
2ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f00: 79 69 65 6c 64 20 28 73 4f 70 74 69 6f 6e 2c 20  yield (sOption, 
2f10: 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64  sLineId, sRuleId
2f20: 29 0a 0a 0a 64 65 66 20 64 69 73 70 6c 61 79 52  )...def displayR
2f30: 75 6c 65 73 20 28 73 46 69 6c 74 65 72 3d 4e 6f  ules (sFilter=No
2f40: 6e 65 29 3a 0a 20 20 20 20 22 64 69 73 70 6c 61  ne):.    "displa
2f50: 79 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 72 75  y the name of ru
2f60: 6c 65 73 2c 20 77 69 74 68 20 74 68 65 20 66 69  les, with the fi
2f70: 6c 74 65 72 20 3c 73 46 69 6c 74 65 72 3e 22 0a  lter <sFilter>".
2f80: 20 20 20 20 65 63 68 6f 28 22 4c 69 73 74 20 6f      echo("List o
2f90: 66 20 72 75 6c 65 73 2e 20 46 69 6c 74 65 72 3a  f rules. Filter:
2fa0: 20 3c 3c 20 22 20 2b 20 73 74 72 28 73 46 69 6c   << " + str(sFil
2fb0: 74 65 72 29 20 2b 20 22 20 3e 3e 22 29 0a 20 20  ter) + " >>").  
2fc0: 20 20 66 6f 72 20 73 4f 70 74 69 6f 6e 2c 20 73    for sOption, s
2fd0: 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65 49 64 20  LineId, sRuleId 
2fe0: 69 6e 20 6c 69 73 74 52 75 6c 65 73 28 73 46 69  in listRules(sFi
2ff0: 6c 74 65 72 29 3a 0a 20 20 20 20 20 20 20 20 65  lter):.        e
3000: 63 68 6f 28 22 7b 3a 3c 31 30 7d 20 7b 3a 3c 31  cho("{:<10} {:<1
3010: 30 7d 20 7b 7d 22 2e 66 6f 72 6d 61 74 28 73 4f  0} {}".format(sO
3020: 70 74 69 6f 6e 2c 20 73 4c 69 6e 65 49 64 2c 20  ption, sLineId, 
3030: 73 52 75 6c 65 49 64 29 29 0a 0a 0a 64 65 66 20  sRuleId))...def 
3040: 73 65 74 4f 70 74 69 6f 6e 20 28 73 4f 70 74 2c  setOption (sOpt,
3050: 20 62 56 61 6c 29 3a 0a 20 20 20 20 22 73 65 74   bVal):.    "set
3060: 20 6f 70 74 69 6f 6e 20 3c 73 4f 70 74 3e 20 77   option <sOpt> w
3070: 69 74 68 20 3c 62 56 61 6c 3e 20 69 66 20 69 74  ith <bVal> if it
3080: 20 65 78 69 73 74 73 22 0a 20 20 20 20 69 66 20   exists".    if 
3090: 73 4f 70 74 20 69 6e 20 5f 64 4f 70 74 69 6f 6e  sOpt in _dOption
30a0: 73 3a 0a 20 20 20 20 20 20 20 20 5f 64 4f 70 74  s:.        _dOpt
30b0: 69 6f 6e 73 5b 73 4f 70 74 5d 20 3d 20 62 56 61  ions[sOpt] = bVa
30c0: 6c 0a 0a 0a 64 65 66 20 73 65 74 4f 70 74 69 6f  l...def setOptio
30d0: 6e 73 20 28 64 4f 70 74 29 3a 0a 20 20 20 20 22  ns (dOpt):.    "
30e0: 75 70 64 61 74 65 20 74 68 65 20 64 69 63 74 69  update the dicti
30f0: 6f 6e 61 72 79 20 6f 66 20 6f 70 74 69 6f 6e 73  onary of options
3100: 20 77 69 74 68 20 3c 64 4f 70 74 3e 22 0a 20 20   with <dOpt>".  
3110: 20 20 66 6f 72 20 73 4b 65 79 2c 20 62 56 61 6c    for sKey, bVal
3120: 20 69 6e 20 64 4f 70 74 2e 69 74 65 6d 73 28 29   in dOpt.items()
3130: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73 4b 65  :.        if sKe
3140: 79 20 69 6e 20 5f 64 4f 70 74 69 6f 6e 73 3a 0a  y in _dOptions:.
3150: 20 20 20 20 20 20 20 20 20 20 20 20 5f 64 4f 70              _dOp
3160: 74 69 6f 6e 73 5b 73 4b 65 79 5d 20 3d 20 62 56  tions[sKey] = bV
3170: 61 6c 0a 0a 0a 64 65 66 20 67 65 74 4f 70 74 69  al...def getOpti
3180: 6f 6e 73 20 28 29 3a 0a 20 20 20 20 22 72 65 74  ons ():.    "ret
3190: 75 72 6e 20 74 68 65 20 64 69 63 74 69 6f 6e 61  urn the dictiona
31a0: 72 79 20 6f 66 20 63 75 72 72 65 6e 74 20 6f 70  ry of current op
31b0: 74 69 6f 6e 73 22 0a 20 20 20 20 72 65 74 75 72  tions".    retur
31c0: 6e 20 5f 64 4f 70 74 69 6f 6e 73 0a 0a 0a 64 65  n _dOptions...de
31d0: 66 20 67 65 74 44 65 66 61 75 6c 74 4f 70 74 69  f getDefaultOpti
31e0: 6f 6e 73 20 28 29 3a 0a 20 20 20 20 22 72 65 74  ons ():.    "ret
31f0: 75 72 6e 20 74 68 65 20 64 69 63 74 69 6f 6e 61  urn the dictiona
3200: 72 79 20 6f 66 20 64 65 66 61 75 6c 74 20 6f 70  ry of default op
3210: 74 69 6f 6e 73 22 0a 20 20 20 20 72 65 74 75 72  tions".    retur
3220: 6e 20 64 69 63 74 28 67 63 5f 6f 70 74 69 6f 6e  n dict(gc_option
3230: 73 2e 67 65 74 4f 70 74 69 6f 6e 73 28 5f 73 41  s.getOptions(_sA
3240: 70 70 43 6f 6e 74 65 78 74 29 29 0a 0a 0a 64 65  ppContext))...de
3250: 66 20 67 65 74 4f 70 74 69 6f 6e 73 4c 61 62 65  f getOptionsLabe
3260: 6c 73 20 28 73 4c 61 6e 67 29 3a 0a 20 20 20 20  ls (sLang):.    
3270: 22 72 65 74 75 72 6e 20 6f 70 74 69 6f 6e 73 20  "return options 
3280: 6c 61 62 65 6c 73 22 0a 20 20 20 20 72 65 74 75  labels".    retu
3290: 72 6e 20 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65  rn gc_options.ge
32a0: 74 55 49 28 73 4c 61 6e 67 29 0a 0a 0a 64 65 66  tUI(sLang)...def
32b0: 20 64 69 73 70 6c 61 79 4f 70 74 69 6f 6e 73 20   displayOptions 
32c0: 28 73 4c 61 6e 67 29 3a 0a 20 20 20 20 22 64 69  (sLang):.    "di
32d0: 73 70 6c 61 79 20 74 68 65 20 6c 69 73 74 20 6f  splay the list o
32e0: 66 20 67 72 61 6d 6d 61 72 20 63 68 65 63 6b 69  f grammar checki
32f0: 6e 67 20 6f 70 74 69 6f 6e 73 22 0a 20 20 20 20  ng options".    
3300: 65 63 68 6f 28 22 4c 69 73 74 20 6f 66 20 6f 70  echo("List of op
3310: 74 69 6f 6e 73 22 29 0a 20 20 20 20 65 63 68 6f  tions").    echo
3320: 28 22 5c 6e 22 2e 6a 6f 69 6e 28 20 5b 20 6b 2b  ("\n".join( [ k+
3330: 22 3a 5c 74 22 2b 73 74 72 28 76 29 2b 22 5c 74  ":\t"+str(v)+"\t
3340: 22 2b 67 63 5f 6f 70 74 69 6f 6e 73 2e 67 65 74  "+gc_options.get
3350: 55 49 28 73 4c 61 6e 67 29 2e 67 65 74 28 6b 2c  UI(sLang).get(k,
3360: 20 28 22 3f 22 2c 20 22 22 29 29 5b 30 5d 20 20   ("?", ""))[0]  
3370: 66 6f 72 20 6b 2c 20 76 20 20 69 6e 20 73 6f 72  for k, v  in sor
3380: 74 65 64 28 5f 64 4f 70 74 69 6f 6e 73 2e 69 74  ted(_dOptions.it
3390: 65 6d 73 28 29 29 20 5d 20 29 29 0a 20 20 20 20  ems()) ] )).    
33a0: 65 63 68 6f 28 22 22 29 0a 0a 0a 64 65 66 20 72  echo("")...def r
33b0: 65 73 65 74 4f 70 74 69 6f 6e 73 20 28 29 3a 0a  esetOptions ():.
33c0: 20 20 20 20 22 73 65 74 20 6f 70 74 69 6f 6e 73      "set options
33d0: 20 74 6f 20 64 65 66 61 75 6c 74 20 76 61 6c 75   to default valu
33e0: 65 73 22 0a 20 20 20 20 67 6c 6f 62 61 6c 20 5f  es".    global _
33f0: 64 4f 70 74 69 6f 6e 73 0a 20 20 20 20 5f 64 4f  dOptions.    _dO
3400: 70 74 69 6f 6e 73 20 3d 20 64 69 63 74 28 67 63  ptions = dict(gc
3410: 5f 6f 70 74 69 6f 6e 73 2e 67 65 74 4f 70 74 69  _options.getOpti
3420: 6f 6e 73 28 5f 73 41 70 70 43 6f 6e 74 65 78 74  ons(_sAppContext
3430: 29 29 0a 0a 0a 64 65 66 20 67 65 74 53 70 65 6c  ))...def getSpel
3440: 6c 43 68 65 63 6b 65 72 20 28 29 3a 0a 20 20 20  lChecker ():.   
3450: 20 22 72 65 74 75 72 6e 20 74 68 65 20 73 70 65   "return the spe
3460: 6c 6c 63 68 65 63 6b 65 72 20 6f 62 6a 65 63 74  llchecker object
3470: 22 0a 20 20 20 20 72 65 74 75 72 6e 20 5f 6f 53  ".    return _oS
3480: 70 65 6c 6c 43 68 65 63 6b 65 72 0a 0a 0a 64 65  pellChecker...de
3490: 66 20 5f 67 65 74 50 61 74 68 20 28 29 3a 0a 20  f _getPath ():. 
34a0: 20 20 20 72 65 74 75 72 6e 20 6f 73 2e 70 61 74     return os.pat
34b0: 68 2e 6a 6f 69 6e 28 6f 73 2e 70 61 74 68 2e 64  h.join(os.path.d
34c0: 69 72 6e 61 6d 65 28 73 79 73 2e 6d 6f 64 75 6c  irname(sys.modul
34d0: 65 73 5b 5f 5f 6e 61 6d 65 5f 5f 5d 2e 5f 5f 66  es[__name__].__f
34e0: 69 6c 65 5f 5f 29 2c 20 5f 5f 6e 61 6d 65 5f 5f  ile__), __name__
34f0: 20 2b 20 22 2e 70 79 22 29 0a 0a 0a 0a 23 23 23   + ".py")....###
3500: 23 20 63 6f 6d 6d 6f 6e 20 66 75 6e 63 74 69 6f  # common functio
3510: 6e 73 0a 0a 64 65 66 20 6f 70 74 69 6f 6e 20 28  ns..def option (
3520: 73 4f 70 74 29 3a 0a 20 20 20 20 22 72 65 74 75  sOpt):.    "retu
3530: 72 6e 20 54 72 75 65 20 69 66 20 6f 70 74 69 6f  rn True if optio
3540: 6e 20 3c 73 4f 70 74 3e 20 69 73 20 61 63 74 69  n <sOpt> is acti
3550: 76 65 22 0a 20 20 20 20 72 65 74 75 72 6e 20 5f  ve".    return _
3560: 64 4f 70 74 69 6f 6e 73 2e 67 65 74 28 73 4f 70  dOptions.get(sOp
3570: 74 2c 20 46 61 6c 73 65 29 0a 0a 0a 64 65 66 20  t, False)...def 
3580: 64 69 73 70 6c 61 79 49 6e 66 6f 20 28 64 54 6f  displayInfo (dTo
3590: 6b 65 6e 50 6f 73 2c 20 74 57 6f 72 64 29 3a 0a  kenPos, tWord):.
35a0: 20 20 20 20 22 66 6f 72 20 64 65 62 75 67 67 69      "for debuggi
35b0: 6e 67 3a 20 72 65 74 72 69 65 76 65 20 69 6e 66  ng: retrieve inf
35c0: 6f 20 6f 66 20 77 6f 72 64 22 0a 20 20 20 20 69  o of word".    i
35d0: 66 20 6e 6f 74 20 74 57 6f 72 64 3a 0a 20 20 20  f not tWord:.   
35e0: 20 20 20 20 20 65 63 68 6f 28 22 3e 20 6e 6f 74       echo("> not
35f0: 68 69 6e 67 20 74 6f 20 66 69 6e 64 22 29 0a 20  hing to find"). 
3600: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
3610: 75 65 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20  ue.    lMorph = 
3620: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
3630: 65 74 4d 6f 72 70 68 28 74 57 6f 72 64 5b 31 5d  etMorph(tWord[1]
3640: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f  ).    if not lMo
3650: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 65 63 68  rph:.        ech
3660: 6f 28 22 3e 20 6e 6f 74 20 69 6e 20 64 69 63 74  o("> not in dict
3670: 69 6f 6e 61 72 79 22 29 0a 20 20 20 20 20 20 20  ionary").       
3680: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20   return True.   
3690: 20 70 72 69 6e 74 28 22 54 4f 4b 45 4e 53 3a 22   print("TOKENS:"
36a0: 2c 20 64 54 6f 6b 65 6e 50 6f 73 29 0a 20 20 20  , dTokenPos).   
36b0: 20 69 66 20 74 57 6f 72 64 5b 30 5d 20 69 6e 20   if tWord[0] in 
36c0: 64 54 6f 6b 65 6e 50 6f 73 20 61 6e 64 20 22 6c  dTokenPos and "l
36d0: 4d 6f 72 70 68 22 20 69 6e 20 64 54 6f 6b 65 6e  Morph" in dToken
36e0: 50 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 3a 0a 20  Pos[tWord[0]]:. 
36f0: 20 20 20 20 20 20 20 65 63 68 6f 28 22 44 41 3a         echo("DA:
3700: 20 22 20 2b 20 73 74 72 28 64 54 6f 6b 65 6e 50   " + str(dTokenP
3710: 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 5b 22 6c 4d  os[tWord[0]]["lM
3720: 6f 72 70 68 22 5d 29 29 0a 20 20 20 20 65 63 68  orph"])).    ech
3730: 6f 28 22 46 53 41 3a 20 22 20 2b 20 73 74 72 28  o("FSA: " + str(
3740: 6c 4d 6f 72 70 68 29 29 0a 20 20 20 20 72 65 74  lMorph)).    ret
3750: 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66 20 6d  urn True...def m
3760: 6f 72 70 68 20 28 64 54 6f 6b 65 6e 50 6f 73 2c  orph (dTokenPos,
3770: 20 74 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e   tWord, sPattern
3780: 2c 20 62 53 74 72 69 63 74 3d 54 72 75 65 2c 20  , bStrict=True, 
3790: 62 4e 6f 57 6f 72 64 3d 46 61 6c 73 65 29 3a 0a  bNoWord=False):.
37a0: 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 74      "analyse a t
37b0: 75 70 6c 65 20 28 70 6f 73 69 74 69 6f 6e 2c 20  uple (position, 
37c0: 77 6f 72 64 29 2c 20 72 65 74 75 72 6e 20 54 72  word), return Tr
37d0: 75 65 20 69 66 20 73 50 61 74 74 65 72 6e 20 69  ue if sPattern i
37e0: 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28  n morphologies (
37f0: 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f  disambiguation o
3800: 6e 29 22 0a 20 20 20 20 69 66 20 6e 6f 74 20 74  n)".    if not t
3810: 57 6f 72 64 3a 0a 20 20 20 20 20 20 20 20 72 65  Word:.        re
3820: 74 75 72 6e 20 62 4e 6f 57 6f 72 64 0a 20 20 20  turn bNoWord.   
3830: 20 6c 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e   lMorph = dToken
3840: 50 6f 73 5b 74 57 6f 72 64 5b 30 5d 5d 5b 22 6c  Pos[tWord[0]]["l
3850: 4d 6f 72 70 68 22 5d 20 20 69 66 20 74 57 6f 72  Morph"]  if tWor
3860: 64 5b 30 5d 20 69 6e 20 64 54 6f 6b 65 6e 50 6f  d[0] in dTokenPo
3870: 73 20 61 6e 64 20 22 6c 4d 6f 72 70 68 22 20 69  s and "lMorph" i
3880: 6e 20 64 54 6f 6b 65 6e 50 6f 73 5b 74 57 6f 72  n dTokenPos[tWor
3890: 64 5b 30 5d 5d 20 20 65 6c 73 65 20 5f 6f 53 70  d[0]]  else _oSp
38a0: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f  ellChecker.getMo
38b0: 72 70 68 28 74 57 6f 72 64 5b 31 5d 29 0a 20 20  rph(tWord[1]).  
38c0: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a    if not lMorph:
38d0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
38e0: 46 61 6c 73 65 0a 20 20 20 20 7a 50 61 74 74 65  False.    zPatte
38f0: 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28  rn = re.compile(
3900: 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66  sPattern).    if
3910: 20 62 53 74 72 69 63 74 3a 0a 20 20 20 20 20 20   bStrict:.      
3920: 20 20 72 65 74 75 72 6e 20 62 6f 6f 6c 28 6c 4d    return bool(lM
3930: 6f 72 70 68 29 20 61 6e 64 20 61 6c 6c 28 7a 50  orph) and all(zP
3940: 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73 29  attern.search(s)
3950: 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70    for s in lMorp
3960: 68 29 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e  h).    return an
3970: 79 28 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63  y(zPattern.searc
3980: 68 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c  h(s)  for s in l
3990: 4d 6f 72 70 68 29 0a 0a 0a 64 65 66 20 6d 6f 72  Morph)...def mor
39a0: 70 68 65 78 20 28 64 54 6f 6b 65 6e 50 6f 73 2c  phex (dTokenPos,
39b0: 20 74 57 6f 72 64 2c 20 73 50 61 74 74 65 72 6e   tWord, sPattern
39c0: 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 2c 20 62  , sNegPattern, b
39d0: 4e 6f 57 6f 72 64 3d 46 61 6c 73 65 29 3a 0a 20  NoWord=False):. 
39e0: 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20 74 75     "analyse a tu
39f0: 70 6c 65 20 28 70 6f 73 69 74 69 6f 6e 2c 20 77  ple (position, w
3a00: 6f 72 64 29 2c 20 72 65 74 75 72 6e 73 20 54 72  ord), returns Tr
3a10: 75 65 20 69 66 20 6e 6f 74 20 73 4e 65 67 50 61  ue if not sNegPa
3a20: 74 74 65 72 6e 20 69 6e 20 77 6f 72 64 20 6d 6f  ttern in word mo
3a30: 72 70 68 6f 6c 6f 67 69 65 73 20 61 6e 64 20 73  rphologies and s
3a40: 50 61 74 74 65 72 6e 20 69 6e 20 77 6f 72 64 20  Pattern in word 
3a50: 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 28 64 69  morphologies (di
3a60: 73 61 6d 62 69 67 75 61 74 69 6f 6e 20 6f 6e 29  sambiguation on)
3a70: 22 0a 20 20 20 20 69 66 20 6e 6f 74 20 74 57 6f  ".    if not tWo
3a80: 72 64 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75  rd:.        retu
3a90: 72 6e 20 62 4e 6f 57 6f 72 64 0a 20 20 20 20 6c  rn bNoWord.    l
3aa0: 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e 50 6f  Morph = dTokenPo
3ab0: 73 5b 74 57 6f 72 64 5b 30 5d 5d 5b 22 6c 4d 6f  s[tWord[0]]["lMo
3ac0: 72 70 68 22 5d 20 20 69 66 20 74 57 6f 72 64 5b  rph"]  if tWord[
3ad0: 30 5d 20 69 6e 20 64 54 6f 6b 65 6e 50 6f 73 20  0] in dTokenPos 
3ae0: 61 6e 64 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20  and "lMorph" in 
3af0: 64 54 6f 6b 65 6e 50 6f 73 5b 74 57 6f 72 64 5b  dTokenPos[tWord[
3b00: 30 5d 5d 20 20 65 6c 73 65 20 5f 6f 53 70 65 6c  0]]  else _oSpel
3b10: 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70  lChecker.getMorp
3b20: 68 28 74 57 6f 72 64 5b 31 5d 29 0a 20 20 20 20  h(tWord[1]).    
3b30: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20  if not lMorph:. 
3b40: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
3b50: 6c 73 65 0a 20 20 20 20 23 20 63 68 65 63 6b 20  lse.    # check 
3b60: 6e 65 67 61 74 69 76 65 20 63 6f 6e 64 69 74 69  negative conditi
3b70: 6f 6e 0a 20 20 20 20 7a 4e 65 67 50 61 74 74 65  on.    zNegPatte
3b80: 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28  rn = re.compile(
3b90: 73 4e 65 67 50 61 74 74 65 72 6e 29 0a 20 20 20  sNegPattern).   
3ba0: 20 69 66 20 61 6e 79 28 7a 4e 65 67 50 61 74 74   if any(zNegPatt
3bb0: 65 72 6e 2e 73 65 61 72 63 68 28 73 29 20 20 66  ern.search(s)  f
3bc0: 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 3a  or s in lMorph):
3bd0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3be0: 46 61 6c 73 65 0a 20 20 20 20 23 20 73 65 61 72  False.    # sear
3bf0: 63 68 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20  ch sPattern.    
3c00: 7a 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f  zPattern = re.co
3c10: 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a  mpile(sPattern).
3c20: 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79 28 7a      return any(z
3c30: 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73  Pattern.search(s
3c40: 29 20 20 66 6f 72 20 73 20 69 6e 20 6c 4d 6f 72  )  for s in lMor
3c50: 70 68 29 0a 0a 0a 64 65 66 20 61 6e 61 6c 79 73  ph)...def analys
3c60: 65 20 28 73 57 6f 72 64 2c 20 73 50 61 74 74 65  e (sWord, sPatte
3c70: 72 6e 2c 20 62 53 74 72 69 63 74 3d 54 72 75 65  rn, bStrict=True
3c80: 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20  ):.    "analyse 
3c90: 61 20 77 6f 72 64 2c 20 72 65 74 75 72 6e 20 54  a word, return T
3ca0: 72 75 65 20 69 66 20 73 50 61 74 74 65 72 6e 20  rue if sPattern 
3cb0: 69 6e 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20  in morphologies 
3cc0: 28 64 69 73 61 6d 62 69 67 75 61 74 69 6f 6e 20  (disambiguation 
3cd0: 6f 66 66 29 22 0a 20 20 20 20 6c 4d 6f 72 70 68  off)".    lMorph
3ce0: 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65   = _oSpellChecke
3cf0: 72 2e 67 65 74 4d 6f 72 70 68 28 73 57 6f 72 64  r.getMorph(sWord
3d00: 29 0a 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f  ).    if not lMo
3d10: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 72 65 74  rph:.        ret
3d20: 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20 7a 50  urn False.    zP
3d30: 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70  attern = re.comp
3d40: 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20  ile(sPattern).  
3d50: 20 20 69 66 20 62 53 74 72 69 63 74 3a 0a 20 20    if bStrict:.  
3d60: 20 20 20 20 20 20 72 65 74 75 72 6e 20 62 6f 6f        return boo
3d70: 6c 28 6c 4d 6f 72 70 68 29 20 61 6e 64 20 61 6c  l(lMorph) and al
3d80: 6c 28 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63  l(zPattern.searc
3d90: 68 28 73 29 20 20 66 6f 72 20 73 20 69 6e 20 6c  h(s)  for s in l
3da0: 4d 6f 72 70 68 29 0a 20 20 20 20 72 65 74 75 72  Morph).    retur
3db0: 6e 20 61 6e 79 28 7a 50 61 74 74 65 72 6e 2e 73  n any(zPattern.s
3dc0: 65 61 72 63 68 28 73 29 20 20 66 6f 72 20 73 20  earch(s)  for s 
3dd0: 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a 0a 64 65 66  in lMorph)...def
3de0: 20 61 6e 61 6c 79 73 65 78 20 28 73 57 6f 72 64   analysex (sWord
3df0: 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e 65 67  , sPattern, sNeg
3e00: 50 61 74 74 65 72 6e 29 3a 0a 20 20 20 20 22 61  Pattern):.    "a
3e10: 6e 61 6c 79 73 65 20 61 20 77 6f 72 64 2c 20 72  nalyse a word, r
3e20: 65 74 75 72 6e 73 20 54 72 75 65 20 69 66 20 6e  eturns True if n
3e30: 6f 74 20 73 4e 65 67 50 61 74 74 65 72 6e 20 69  ot sNegPattern i
3e40: 6e 20 77 6f 72 64 20 6d 6f 72 70 68 6f 6c 6f 67  n word morpholog
3e50: 69 65 73 20 61 6e 64 20 73 50 61 74 74 65 72 6e  ies and sPattern
3e60: 20 69 6e 20 77 6f 72 64 20 6d 6f 72 70 68 6f 6c   in word morphol
3e70: 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69 67 75  ogies (disambigu
3e80: 61 74 69 6f 6e 20 6f 66 66 29 22 0a 20 20 20 20  ation off)".    
3e90: 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c  lMorph = _oSpell
3ea0: 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68  Checker.getMorph
3eb0: 28 73 57 6f 72 64 29 0a 20 20 20 20 69 66 20 6e  (sWord).    if n
3ec0: 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20 20 20 20 20  ot lMorph:.     
3ed0: 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a     return False.
3ee0: 20 20 20 20 23 20 63 68 65 63 6b 20 6e 65 67 61      # check nega
3ef0: 74 69 76 65 20 63 6f 6e 64 69 74 69 6f 6e 0a 20  tive condition. 
3f00: 20 20 20 7a 4e 65 67 50 61 74 74 65 72 6e 20 3d     zNegPattern =
3f10: 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 4e 65 67   re.compile(sNeg
3f20: 50 61 74 74 65 72 6e 29 0a 20 20 20 20 69 66 20  Pattern).    if 
3f30: 61 6e 79 28 7a 4e 65 67 50 61 74 74 65 72 6e 2e  any(zNegPattern.
3f40: 73 65 61 72 63 68 28 73 29 20 20 66 6f 72 20 73  search(s)  for s
3f50: 20 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20   in lMorph):.   
3f60: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
3f70: 65 0a 20 20 20 20 23 20 73 65 61 72 63 68 20 73  e.    # search s
3f80: 50 61 74 74 65 72 6e 0a 20 20 20 20 7a 50 61 74  Pattern.    zPat
3f90: 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  tern = re.compil
3fa0: 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20  e(sPattern).    
3fb0: 72 65 74 75 72 6e 20 61 6e 79 28 7a 50 61 74 74  return any(zPatt
3fc0: 65 72 6e 2e 73 65 61 72 63 68 28 73 29 20 20 66  ern.search(s)  f
3fd0: 6f 72 20 73 20 69 6e 20 6c 4d 6f 72 70 68 29 0a  or s in lMorph).
3fe0: 0a 0a 0a 23 23 20 66 75 6e 63 74 69 6f 6e 73 20  ...## functions 
3ff0: 74 6f 20 67 65 74 20 74 65 78 74 20 6f 75 74 73  to get text outs
4000: 69 64 65 20 70 61 74 74 65 72 6e 20 73 63 6f 70  ide pattern scop
4010: 65 0a 0a 23 20 77 61 72 6e 69 6e 67 3a 20 63 68  e..# warning: ch
4020: 65 63 6b 20 63 6f 6d 70 69 6c 65 5f 72 75 6c 65  eck compile_rule
4030: 73 2e 70 79 20 74 6f 20 75 6e 64 65 72 73 74 61  s.py to understa
4040: 6e 64 20 68 6f 77 20 69 74 20 77 6f 72 6b 73 0a  nd how it works.
4050: 0a 5f 7a 4e 65 78 74 57 6f 72 64 20 3d 20 72 65  ._zNextWord = re
4060: 2e 63 6f 6d 70 69 6c 65 28 72 22 20 2b 28 5c 77  .compile(r" +(\w
4070: 5b 5c 77 2d 5d 2a 29 22 29 0a 5f 7a 50 72 65 76  [\w-]*)")._zPrev
4080: 57 6f 72 64 20 3d 20 72 65 2e 63 6f 6d 70 69 6c  Word = re.compil
4090: 65 28 72 22 28 5c 77 5b 5c 77 2d 5d 2a 29 20 2b  e(r"(\w[\w-]*) +
40a0: 24 22 29 0a 0a 64 65 66 20 6e 65 78 74 77 6f 72  $")..def nextwor
40b0: 64 20 28 73 2c 20 69 53 74 61 72 74 2c 20 6e 29  d (s, iStart, n)
40c0: 3a 0a 20 20 20 20 22 67 65 74 20 74 68 65 20 6e  :.    "get the n
40d0: 74 68 20 77 6f 72 64 20 6f 66 20 74 68 65 20 69  th word of the i
40e0: 6e 70 75 74 20 73 74 72 69 6e 67 20 6f 72 20 65  nput string or e
40f0: 6d 70 74 79 20 73 74 72 69 6e 67 22 0a 20 20 20  mpty string".   
4100: 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 28   m = re.match("(
4110: 3f 3a 20 2b 5b 5c 5c 77 25 2d 5d 2b 29 7b 22 20  ?: +[\\w%-]+){" 
4120: 2b 20 73 74 72 28 6e 2d 31 29 20 2b 20 22 7d 20  + str(n-1) + "} 
4130: 2b 28 5b 5c 5c 77 25 2d 5d 2b 29 22 2c 20 73 5b  +([\\w%-]+)", s[
4140: 69 53 74 61 72 74 3a 5d 29 0a 20 20 20 20 69 66  iStart:]).    if
4150: 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20   not m:.        
4160: 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20  return None.    
4170: 72 65 74 75 72 6e 20 28 69 53 74 61 72 74 2b 6d  return (iStart+m
4180: 2e 73 74 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f  .start(1), m.gro
4190: 75 70 28 31 29 29 0a 0a 0a 64 65 66 20 70 72 65  up(1))...def pre
41a0: 76 77 6f 72 64 20 28 73 2c 20 69 45 6e 64 2c 20  vword (s, iEnd, 
41b0: 6e 29 3a 0a 20 20 20 20 22 67 65 74 20 74 68 65  n):.    "get the
41c0: 20 28 2d 29 6e 74 68 20 77 6f 72 64 20 6f 66 20   (-)nth word of 
41d0: 74 68 65 20 69 6e 70 75 74 20 73 74 72 69 6e 67  the input string
41e0: 20 6f 72 20 65 6d 70 74 79 20 73 74 72 69 6e 67   or empty string
41f0: 22 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61  ".    m = re.sea
4200: 72 63 68 28 22 28 5b 5c 5c 77 25 2d 5d 2b 29 20  rch("([\\w%-]+) 
4210: 2b 28 3f 3a 5b 5c 5c 77 25 2d 5d 2b 20 2b 29 7b  +(?:[\\w%-]+ +){
4220: 22 20 2b 20 73 74 72 28 6e 2d 31 29 20 2b 20 22  " + str(n-1) + "
4230: 7d 24 22 2c 20 73 5b 3a 69 45 6e 64 5d 29 0a 20  }$", s[:iEnd]). 
4240: 20 20 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20     if not m:.   
4250: 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65       return None
4260: 0a 20 20 20 20 72 65 74 75 72 6e 20 28 6d 2e 73  .    return (m.s
4270: 74 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75 70  tart(1), m.group
4280: 28 31 29 29 0a 0a 0a 64 65 66 20 6e 65 78 74 77  (1))...def nextw
4290: 6f 72 64 31 20 28 73 2c 20 69 53 74 61 72 74 29  ord1 (s, iStart)
42a0: 3a 0a 20 20 20 20 22 67 65 74 20 6e 65 78 74 20  :.    "get next 
42b0: 77 6f 72 64 20 28 6f 70 74 69 6d 69 7a 61 74 69  word (optimizati
42c0: 6f 6e 29 22 0a 20 20 20 20 6d 20 3d 20 5f 7a 4e  on)".    m = _zN
42d0: 65 78 74 57 6f 72 64 2e 6d 61 74 63 68 28 73 5b  extWord.match(s[
42e0: 69 53 74 61 72 74 3a 5d 29 0a 20 20 20 20 69 66  iStart:]).    if
42f0: 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20 20 20 20   not m:.        
4300: 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20  return None.    
4310: 72 65 74 75 72 6e 20 28 69 53 74 61 72 74 2b 6d  return (iStart+m
4320: 2e 73 74 61 72 74 28 31 29 2c 20 6d 2e 67 72 6f  .start(1), m.gro
4330: 75 70 28 31 29 29 0a 0a 0a 64 65 66 20 70 72 65  up(1))...def pre
4340: 76 77 6f 72 64 31 20 28 73 2c 20 69 45 6e 64 29  vword1 (s, iEnd)
4350: 3a 0a 20 20 20 20 22 67 65 74 20 70 72 65 76 69  :.    "get previ
4360: 6f 75 73 20 77 6f 72 64 20 28 6f 70 74 69 6d 69  ous word (optimi
4370: 7a 61 74 69 6f 6e 29 22 0a 20 20 20 20 6d 20 3d  zation)".    m =
4380: 20 5f 7a 50 72 65 76 57 6f 72 64 2e 73 65 61 72   _zPrevWord.sear
4390: 63 68 28 73 5b 3a 69 45 6e 64 5d 29 0a 20 20 20  ch(s[:iEnd]).   
43a0: 20 69 66 20 6e 6f 74 20 6d 3a 0a 20 20 20 20 20   if not m:.     
43b0: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20     return None. 
43c0: 20 20 20 72 65 74 75 72 6e 20 28 6d 2e 73 74 61     return (m.sta
43d0: 72 74 28 31 29 2c 20 6d 2e 67 72 6f 75 70 28 31  rt(1), m.group(1
43e0: 29 29 0a 0a 0a 64 65 66 20 6c 6f 6f 6b 20 28 73  ))...def look (s
43f0: 2c 20 73 50 61 74 74 65 72 6e 2c 20 73 4e 65 67  , sPattern, sNeg
4400: 50 61 74 74 65 72 6e 3d 4e 6f 6e 65 29 3a 0a 20  Pattern=None):. 
4410: 20 20 20 22 73 65 65 6b 20 73 50 61 74 74 65 72     "seek sPatter
4420: 6e 20 69 6e 20 73 20 28 62 65 66 6f 72 65 2f 61  n in s (before/a
4430: 66 74 65 72 2f 66 75 6c 6c 74 65 78 74 29 2c 20  fter/fulltext), 
4440: 69 66 20 73 4e 65 67 50 61 74 74 65 72 6e 20 6e  if sNegPattern n
4450: 6f 74 20 69 6e 20 73 22 0a 20 20 20 20 69 66 20  ot in s".    if 
4460: 73 4e 65 67 50 61 74 74 65 72 6e 20 61 6e 64 20  sNegPattern and 
4470: 72 65 2e 73 65 61 72 63 68 28 73 4e 65 67 50 61  re.search(sNegPa
4480: 74 74 65 72 6e 2c 20 73 29 3a 0a 20 20 20 20 20  ttern, s):.     
4490: 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a     return False.
44a0: 20 20 20 20 69 66 20 72 65 2e 73 65 61 72 63 68      if re.search
44b0: 28 73 50 61 74 74 65 72 6e 2c 20 73 29 3a 0a 20  (sPattern, s):. 
44c0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72         return Tr
44d0: 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20 46 61  ue.    return Fa
44e0: 6c 73 65 0a 0a 0a 64 65 66 20 6c 6f 6f 6b 5f 63  lse...def look_c
44f0: 68 6b 31 20 28 64 54 6f 6b 65 6e 50 6f 73 2c 20  hk1 (dTokenPos, 
4500: 73 2c 20 6e 4f 66 66 73 65 74 2c 20 73 50 61 74  s, nOffset, sPat
4510: 74 65 72 6e 2c 20 73 50 61 74 74 65 72 6e 47 72  tern, sPatternGr
4520: 6f 75 70 31 2c 20 73 4e 65 67 50 61 74 74 65 72  oup1, sNegPatter
4530: 6e 47 72 6f 75 70 31 3d 4e 6f 6e 65 29 3a 0a 20  nGroup1=None):. 
4540: 20 20 20 22 72 65 74 75 72 6e 73 20 54 72 75 65     "returns True
4550: 20 69 66 20 73 20 68 61 73 20 70 61 74 74 65 72   if s has patter
4560: 6e 20 73 50 61 74 74 65 72 6e 20 61 6e 64 20 6d  n sPattern and m
4570: 2e 67 72 6f 75 70 28 31 29 20 68 61 73 20 70 61  .group(1) has pa
4580: 74 74 65 72 6e 20 73 50 61 74 74 65 72 6e 47 72  ttern sPatternGr
4590: 6f 75 70 31 22 0a 20 20 20 20 6d 20 3d 20 72 65  oup1".    m = re
45a0: 2e 73 65 61 72 63 68 28 73 50 61 74 74 65 72 6e  .search(sPattern
45b0: 2c 20 73 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  , s).    if not 
45c0: 6d 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  m:.        retur
45d0: 6e 20 46 61 6c 73 65 0a 20 20 20 20 74 72 79 3a  n False.    try:
45e0: 0a 20 20 20 20 20 20 20 20 73 57 6f 72 64 20 3d  .        sWord =
45f0: 20 6d 2e 67 72 6f 75 70 28 31 29 0a 20 20 20 20   m.group(1).    
4600: 20 20 20 20 6e 50 6f 73 20 3d 20 6d 2e 73 74 61      nPos = m.sta
4610: 72 74 28 31 29 20 2b 20 6e 4f 66 66 73 65 74 0a  rt(1) + nOffset.
4620: 20 20 20 20 65 78 63 65 70 74 3a 0a 20 20 20 20      except:.    
4630: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
4640: 0a 20 20 20 20 69 66 20 73 4e 65 67 50 61 74 74  .    if sNegPatt
4650: 65 72 6e 47 72 6f 75 70 31 3a 0a 20 20 20 20 20  ernGroup1:.     
4660: 20 20 20 72 65 74 75 72 6e 20 6d 6f 72 70 68 65     return morphe
4670: 78 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 28 6e 50  x(dTokenPos, (nP
4680: 6f 73 2c 20 73 57 6f 72 64 29 2c 20 73 50 61 74  os, sWord), sPat
4690: 74 65 72 6e 47 72 6f 75 70 31 2c 20 73 4e 65 67  ternGroup1, sNeg
46a0: 50 61 74 74 65 72 6e 47 72 6f 75 70 31 29 0a 20  PatternGroup1). 
46b0: 20 20 20 72 65 74 75 72 6e 20 6d 6f 72 70 68 28     return morph(
46c0: 64 54 6f 6b 65 6e 50 6f 73 2c 20 28 6e 50 6f 73  dTokenPos, (nPos
46d0: 2c 20 73 57 6f 72 64 29 2c 20 73 50 61 74 74 65  , sWord), sPatte
46e0: 72 6e 47 72 6f 75 70 31 2c 20 46 61 6c 73 65 29  rnGroup1, False)
46f0: 0a 0a 0a 23 23 23 23 20 44 69 73 61 6d 62 69 67  ...#### Disambig
4700: 75 61 74 6f 72 0a 0a 64 65 66 20 73 65 6c 65 63  uator..def selec
4710: 74 20 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 6e 50  t (dTokenPos, nP
4720: 6f 73 2c 20 73 57 6f 72 64 2c 20 73 50 61 74 74  os, sWord, sPatt
4730: 65 72 6e 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f  ern, lDefault=No
4740: 6e 65 29 3a 0a 20 20 20 20 22 44 69 73 61 6d 62  ne):.    "Disamb
4750: 69 67 75 61 74 69 6f 6e 3a 20 73 65 6c 65 63 74  iguation: select
4760: 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 6f 66   morphologies of
4770: 20 3c 73 57 6f 72 64 3e 20 6d 61 74 63 68 69 6e   <sWord> matchin
4780: 67 20 3c 73 50 61 74 74 65 72 6e 3e 22 0a 20 20  g <sPattern>".  
4790: 20 20 69 66 20 6e 6f 74 20 73 57 6f 72 64 3a 0a    if not sWord:.
47a0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
47b0: 72 75 65 0a 20 20 20 20 69 66 20 6e 50 6f 73 20  rue.    if nPos 
47c0: 6e 6f 74 20 69 6e 20 64 54 6f 6b 65 6e 50 6f 73  not in dTokenPos
47d0: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
47e0: 22 45 72 72 6f 72 2e 20 54 68 65 72 65 20 73 68  "Error. There sh
47f0: 6f 75 6c 64 20 62 65 20 61 20 74 6f 6b 65 6e 20  ould be a token 
4800: 61 74 20 74 68 69 73 20 70 6f 73 69 74 69 6f 6e  at this position
4810: 3a 20 22 2c 20 6e 50 6f 73 29 0a 20 20 20 20 20  : ", nPos).     
4820: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20     return True. 
4830: 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70     lMorph = _oSp
4840: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f  ellChecker.getMo
4850: 72 70 68 28 73 57 6f 72 64 29 0a 20 20 20 20 69  rph(sWord).    i
4860: 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20  f not lMorph or 
4870: 6c 65 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31  len(lMorph) == 1
4880: 3a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  :.        return
4890: 20 54 72 75 65 0a 20 20 20 20 6c 53 65 6c 65 63   True.    lSelec
48a0: 74 20 3d 20 5b 20 73 4d 6f 72 70 68 20 20 66 6f  t = [ sMorph  fo
48b0: 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72  r sMorph in lMor
48c0: 70 68 20 20 69 66 20 72 65 2e 73 65 61 72 63 68  ph  if re.search
48d0: 28 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70  (sPattern, sMorp
48e0: 68 29 20 5d 0a 20 20 20 20 69 66 20 6c 53 65 6c  h) ].    if lSel
48f0: 65 63 74 3a 0a 20 20 20 20 20 20 20 20 69 66 20  ect:.        if 
4900: 6c 65 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d 20  len(lSelect) != 
4910: 6c 65 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20 20  len(lMorph):.   
4920: 20 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 50           dTokenP
4930: 6f 73 5b 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68  os[nPos]["lMorph
4940: 22 5d 20 3d 20 6c 53 65 6c 65 63 74 0a 20 20 20  "] = lSelect.   
4950: 20 65 6c 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a   elif lDefault:.
4960: 20 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 50 6f          dTokenPo
4970: 73 5b 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68 22  s[nPos]["lMorph"
4980: 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20 20  ] = lDefault.   
4990: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64   return True...d
49a0: 65 66 20 65 78 63 6c 75 64 65 20 28 64 54 6f 6b  ef exclude (dTok
49b0: 65 6e 50 6f 73 2c 20 6e 50 6f 73 2c 20 73 57 6f  enPos, nPos, sWo
49c0: 72 64 2c 20 73 50 61 74 74 65 72 6e 2c 20 6c 44  rd, sPattern, lD
49d0: 65 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a 0a 20 20  efault=None):.  
49e0: 20 20 22 44 69 73 61 6d 62 69 67 75 61 74 69 6f    "Disambiguatio
49f0: 6e 3a 20 65 78 63 6c 75 64 65 20 6d 6f 72 70 68  n: exclude morph
4a00: 6f 6c 6f 67 69 65 73 20 6f 66 20 3c 73 57 6f 72  ologies of <sWor
4a10: 64 3e 20 6d 61 74 63 68 69 6e 67 20 3c 73 50 61  d> matching <sPa
4a20: 74 74 65 72 6e 3e 22 0a 20 20 20 20 69 66 20 6e  ttern>".    if n
4a30: 6f 74 20 73 57 6f 72 64 3a 0a 20 20 20 20 20 20  ot sWord:.      
4a40: 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20    return True.  
4a50: 20 20 69 66 20 6e 50 6f 73 20 6e 6f 74 20 69 6e    if nPos not in
4a60: 20 64 54 6f 6b 65 6e 50 6f 73 3a 0a 20 20 20 20   dTokenPos:.    
4a70: 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72      print("Error
4a80: 2e 20 54 68 65 72 65 20 73 68 6f 75 6c 64 20 62  . There should b
4a90: 65 20 61 20 74 6f 6b 65 6e 20 61 74 20 74 68 69  e a token at thi
4aa0: 73 20 70 6f 73 69 74 69 6f 6e 3a 20 22 2c 20 6e  s position: ", n
4ab0: 50 6f 73 29 0a 20 20 20 20 20 20 20 20 72 65 74  Pos).        ret
4ac0: 75 72 6e 20 54 72 75 65 0a 20 20 20 20 6c 4d 6f  urn True.    lMo
4ad0: 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65  rph = _oSpellChe
4ae0: 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 73 57  cker.getMorph(sW
4af0: 6f 72 64 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  ord).    if not 
4b00: 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e 28 6c 4d  lMorph or len(lM
4b10: 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20 20 20 20  orph) == 1:.    
4b20: 20 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a      return True.
4b30: 20 20 20 20 6c 53 65 6c 65 63 74 20 3d 20 5b 20      lSelect = [ 
4b40: 73 4d 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72  sMorph  for sMor
4b50: 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20 20 69 66  ph in lMorph  if
4b60: 20 6e 6f 74 20 72 65 2e 73 65 61 72 63 68 28 73   not re.search(s
4b70: 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29  Pattern, sMorph)
4b80: 20 5d 0a 20 20 20 20 69 66 20 6c 53 65 6c 65 63   ].    if lSelec
4b90: 74 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c 65  t:.        if le
4ba0: 6e 28 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c 65  n(lSelect) != le
4bb0: 6e 28 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20  n(lMorph):.     
4bc0: 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 50 6f 73         dTokenPos
4bd0: 5b 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68 22 5d  [nPos]["lMorph"]
4be0: 20 3d 20 6c 53 65 6c 65 63 74 0a 20 20 20 20 65   = lSelect.    e
4bf0: 6c 69 66 20 6c 44 65 66 61 75 6c 74 3a 0a 20 20  lif lDefault:.  
4c00: 20 20 20 20 20 20 64 54 6f 6b 65 6e 50 6f 73 5b        dTokenPos[
4c10: 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70 68 22 5d 20  nPos]["lMorph"] 
4c20: 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20 72  = lDefault.    r
4c30: 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64 65 66  eturn True...def
4c40: 20 64 65 66 69 6e 65 20 28 64 54 6f 6b 65 6e 50   define (dTokenP
4c50: 6f 73 2c 20 6e 50 6f 73 2c 20 6c 4d 6f 72 70 68  os, nPos, lMorph
4c60: 29 3a 0a 20 20 20 20 22 44 69 73 61 6d 62 69 67  ):.    "Disambig
4c70: 75 61 74 69 6f 6e 3a 20 73 65 74 20 6d 6f 72 70  uation: set morp
4c80: 68 6f 6c 6f 67 69 65 73 20 6f 66 20 74 6f 6b 65  hologies of toke
4c90: 6e 20 61 74 20 3c 6e 50 6f 73 3e 20 77 69 74 68  n at <nPos> with
4ca0: 20 3c 6c 4d 6f 72 70 68 3e 22 0a 20 20 20 20 69   <lMorph>".    i
4cb0: 66 20 6e 50 6f 73 20 6e 6f 74 20 69 6e 20 64 54  f nPos not in dT
4cc0: 6f 6b 65 6e 50 6f 73 3a 0a 20 20 20 20 20 20 20  okenPos:.       
4cd0: 20 70 72 69 6e 74 28 22 45 72 72 6f 72 2e 20 54   print("Error. T
4ce0: 68 65 72 65 20 73 68 6f 75 6c 64 20 62 65 20 61  here should be a
4cf0: 20 74 6f 6b 65 6e 20 61 74 20 74 68 69 73 20 70   token at this p
4d00: 6f 73 69 74 69 6f 6e 3a 20 22 2c 20 6e 50 6f 73  osition: ", nPos
4d10: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
4d20: 20 54 72 75 65 0a 20 20 20 20 64 54 6f 6b 65 6e   True.    dToken
4d30: 50 6f 73 5b 6e 50 6f 73 5d 5b 22 6c 4d 6f 72 70  Pos[nPos]["lMorp
4d40: 68 22 5d 20 3d 20 6c 4d 6f 72 70 68 0a 20 20 20  h"] = lMorph.   
4d50: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 0a   return True....
4d60: 0a 23 23 23 23 20 54 4f 4b 45 4e 20 53 45 4e 54  .#### TOKEN SENT
4d70: 45 4e 43 45 20 43 48 45 43 4b 45 52 0a 0a 63 6c  ENCE CHECKER..cl
4d80: 61 73 73 20 54 6f 6b 65 6e 53 65 6e 74 65 6e 63  ass TokenSentenc
4d90: 65 3a 0a 20 20 20 20 22 54 65 78 74 20 70 61 72  e:.    "Text par
4da0: 73 65 72 22 0a 0a 20 20 20 20 64 65 66 20 5f 5f  ser"..    def __
4db0: 69 6e 69 74 5f 5f 20 28 73 65 6c 66 2c 20 73 53  init__ (self, sS
4dc0: 65 6e 74 65 6e 63 65 2c 20 73 53 65 6e 74 65 6e  entence, sSenten
4dd0: 63 65 30 2c 20 6e 4f 66 66 73 65 74 29 3a 0a 20  ce0, nOffset):. 
4de0: 20 20 20 20 20 20 20 73 65 6c 66 2e 73 53 65 6e         self.sSen
4df0: 74 65 6e 63 65 20 3d 20 73 53 65 6e 74 65 6e 63  tence = sSentenc
4e00: 65 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 73  e.        self.s
4e10: 53 65 6e 74 65 6e 63 65 30 20 3d 20 73 53 65 6e  Sentence0 = sSen
4e20: 74 65 6e 63 65 30 0a 20 20 20 20 20 20 20 20 73  tence0.        s
4e30: 65 6c 66 2e 6e 4f 66 66 73 65 74 57 69 74 68 69  elf.nOffsetWithi
4e40: 6e 50 61 72 61 67 72 61 70 68 20 3d 20 6e 4f 66  nParagraph = nOf
4e50: 66 73 65 74 0a 20 20 20 20 20 20 20 20 73 65 6c  fset.        sel
4e60: 66 2e 6c 54 6f 6b 65 6e 20 3d 20 6c 69 73 74 28  f.lToken = list(
4e70: 5f 6f 54 6f 6b 65 6e 69 7a 65 72 2e 67 65 6e 54  _oTokenizer.genT
4e80: 6f 6b 65 6e 73 28 73 53 65 6e 74 65 6e 63 65 2c  okens(sSentence,
4e90: 20 54 72 75 65 29 29 0a 20 20 20 20 20 20 20 20   True)).        
4ea0: 73 65 6c 66 2e 64 54 6f 6b 65 6e 50 6f 73 20 3d  self.dTokenPos =
4eb0: 20 7b 20 64 54 6f 6b 65 6e 5b 22 6e 53 74 61 72   { dToken["nStar
4ec0: 74 22 5d 3a 20 64 54 6f 6b 65 6e 20 20 66 6f 72  t"]: dToken  for
4ed0: 20 64 54 6f 6b 65 6e 20 69 6e 20 73 65 6c 66 2e   dToken in self.
4ee0: 6c 54 6f 6b 65 6e 20 20 69 66 20 64 54 6f 6b 65  lToken  if dToke
4ef0: 6e 5b 22 73 54 79 70 65 22 5d 20 21 3d 20 22 49  n["sType"] != "I
4f00: 4e 46 4f 22 20 7d 0a 20 20 20 20 20 20 20 20 73  NFO" }.        s
4f10: 65 6c 66 2e 64 54 61 67 73 20 3d 20 7b 7d 0a 20  elf.dTags = {}. 
4f20: 20 20 20 20 20 20 20 73 65 6c 66 2e 64 45 72 72         self.dErr
4f30: 6f 72 20 3d 20 7b 7d 0a 0a 20 20 20 20 64 65 66  or = {}..    def
4f40: 20 5f 5f 73 74 72 5f 5f 20 28 73 65 6c 66 29 3a   __str__ (self):
4f50: 0a 20 20 20 20 20 20 20 20 73 20 3d 20 22 73 65  .        s = "se
4f60: 6e 74 65 6e 63 65 3a 20 22 20 2b 20 73 65 6c 66  ntence: " + self
4f70: 2e 73 53 65 6e 74 65 6e 63 65 30 20 2b 20 22 5c  .sSentence0 + "\
4f80: 6e 22 0a 20 20 20 20 20 20 20 20 73 20 2b 3d 20  n".        s += 
4f90: 22 6e 6f 77 3a 20 20 20 20 20 20 22 20 2b 20 73  "now:      " + s
4fa0: 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 20 20 2b  elf.sSentence  +
4fb0: 20 22 5c 6e 22 0a 20 20 20 20 20 20 20 20 66 6f   "\n".        fo
4fc0: 72 20 64 54 6f 6b 65 6e 20 69 6e 20 73 65 6c 66  r dToken in self
4fd0: 2e 6c 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20  .lToken:.       
4fe0: 20 20 20 20 20 73 20 2b 3d 20 66 27 7b 64 54 6f       s += f'{dTo
4ff0: 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 7d 5c 74  ken["nStart"]}\t
5000: 7b 64 54 6f 6b 65 6e 5b 22 6e 45 6e 64 22 5d 7d  {dToken["nEnd"]}
5010: 5c 74 7b 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  \t{dToken["sValu
5020: 65 22 5d 7d 27 0a 20 20 20 20 20 20 20 20 20 20  e"]}'.          
5030: 20 20 69 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e    if "lMorph" in
5040: 20 64 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20   dToken:.       
5050: 20 20 20 20 20 20 20 20 20 73 20 2b 3d 20 22 5c           s += "\
5060: 74 22 20 2b 20 73 74 72 28 64 54 6f 6b 65 6e 5b  t" + str(dToken[
5070: 22 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20 20 20  "lMorph"]).     
5080: 20 20 20 20 20 20 20 73 20 2b 3d 20 22 5c 6e 22         s += "\n"
5090: 0a 20 20 20 20 20 20 20 20 66 6f 72 20 6e 50 6f  .        for nPo
50a0: 73 2c 20 64 54 6f 6b 65 6e 20 69 6e 20 73 65 6c  s, dToken in sel
50b0: 66 2e 64 54 6f 6b 65 6e 50 6f 73 2e 69 74 65 6d  f.dTokenPos.item
50c0: 73 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  s():.           
50d0: 20 73 20 2b 3d 20 66 22 7b 6e 50 6f 73 7d 5c 74   s += f"{nPos}\t
50e0: 7b 64 54 6f 6b 65 6e 7d 5c 6e 22 0a 20 20 20 20  {dToken}\n".    
50f0: 20 20 20 20 72 65 74 75 72 6e 20 73 0a 0a 20 20      return s..  
5100: 20 20 64 65 66 20 75 70 64 61 74 65 20 28 73 65    def update (se
5110: 6c 66 2c 20 73 53 65 6e 74 65 6e 63 65 2c 20 62  lf, sSentence, b
5120: 44 65 62 75 67 3d 46 61 6c 73 65 29 3a 0a 20 20  Debug=False):.  
5130: 20 20 20 20 20 20 22 75 70 64 61 74 65 20 3c 73        "update <s
5140: 53 65 6e 74 65 6e 63 65 3e 20 61 6e 64 20 72 65  Sentence> and re
5150: 74 6f 6b 65 6e 69 7a 65 22 0a 20 20 20 20 20 20  tokenize".      
5160: 20 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65    self.sSentence
5170: 20 3d 20 73 53 65 6e 74 65 6e 63 65 0a 20 20 20   = sSentence.   
5180: 20 20 20 20 20 6c 4e 65 77 54 6f 6b 65 6e 20 3d       lNewToken =
5190: 20 6c 69 73 74 28 5f 6f 54 6f 6b 65 6e 69 7a 65   list(_oTokenize
51a0: 72 2e 67 65 6e 54 6f 6b 65 6e 73 28 73 53 65 6e  r.genTokens(sSen
51b0: 74 65 6e 63 65 2c 20 54 72 75 65 29 29 0a 20 20  tence, True)).  
51c0: 20 20 20 20 20 20 66 6f 72 20 64 54 6f 6b 65 6e        for dToken
51d0: 20 69 6e 20 6c 4e 65 77 54 6f 6b 65 6e 3a 0a 20   in lNewToken:. 
51e0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 22 6c             if "l
51f0: 4d 6f 72 70 68 22 20 69 6e 20 73 65 6c 66 2e 64  Morph" in self.d
5200: 54 6f 6b 65 6e 50 6f 73 2e 67 65 74 28 64 54 6f  TokenPos.get(dTo
5210: 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 2c 20 7b  ken["nStart"], {
5220: 7d 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  }):.            
5230: 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72      dToken["lMor
5240: 70 68 22 5d 20 3d 20 73 65 6c 66 2e 64 54 6f 6b  ph"] = self.dTok
5250: 65 6e 50 6f 73 5b 64 54 6f 6b 65 6e 5b 22 6e 53  enPos[dToken["nS
5260: 74 61 72 74 22 5d 5d 5b 22 6c 4d 6f 72 70 68 22  tart"]]["lMorph"
5270: 5d 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6c  ].        self.l
5280: 54 6f 6b 65 6e 20 3d 20 6c 4e 65 77 54 6f 6b 65  Token = lNewToke
5290: 6e 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 64  n.        self.d
52a0: 54 6f 6b 65 6e 50 6f 73 20 3d 20 7b 20 64 54 6f  TokenPos = { dTo
52b0: 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 3a 20 64  ken["nStart"]: d
52c0: 54 6f 6b 65 6e 20 20 66 6f 72 20 64 54 6f 6b 65  Token  for dToke
52d0: 6e 20 69 6e 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e  n in self.lToken
52e0: 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73 54 79    if dToken["sTy
52f0: 70 65 22 5d 20 21 3d 20 22 49 4e 46 4f 22 20 7d  pe"] != "INFO" }
5300: 0a 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62  .        if bDeb
5310: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
5320: 70 72 69 6e 74 28 22 55 50 44 41 54 45 3a 22 29  print("UPDATE:")
5330: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
5340: 6e 74 28 73 65 6c 66 29 0a 0a 20 20 20 20 64 65  nt(self)..    de
5350: 66 20 5f 67 65 74 4e 65 78 74 4d 61 74 63 68 69  f _getNextMatchi
5360: 6e 67 4e 6f 64 65 73 20 28 73 65 6c 66 2c 20 64  ngNodes (self, d
5370: 54 6f 6b 65 6e 2c 20 64 47 72 61 70 68 2c 20 64  Token, dGraph, d
5380: 4e 6f 64 65 2c 20 62 44 65 62 75 67 3d 46 61 6c  Node, bDebug=Fal
5390: 73 65 29 3a 0a 20 20 20 20 20 20 20 20 22 67 65  se):.        "ge
53a0: 6e 65 72 61 74 6f 72 3a 20 72 65 74 75 72 6e 20  nerator: return 
53b0: 6e 6f 64 65 73 20 77 68 65 72 65 20 3c 64 54 6f  nodes where <dTo
53c0: 6b 65 6e 3e 20 e2 80 9c 76 61 6c 75 65 73 e2 80  ken> ...values..
53d0: 9d 20 6d 61 74 63 68 20 3c 64 4e 6f 64 65 3e 20  . match <dNode> 
53e0: 61 72 63 73 22 0a 20 20 20 20 20 20 20 20 23 20  arcs".        # 
53f0: 74 6f 6b 65 6e 20 76 61 6c 75 65 0a 20 20 20 20  token value.    
5400: 20 20 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73      if dToken["s
5410: 56 61 6c 75 65 22 5d 20 69 6e 20 64 4e 6f 64 65  Value"] in dNode
5420: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  :.            if
5430: 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20   bDebug:.       
5440: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
5450: 20 20 4d 41 54 43 48 3a 22 2c 20 64 54 6f 6b 65    MATCH:", dToke
5460: 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20  n["sValue"]).   
5470: 20 20 20 20 20 20 20 20 20 79 69 65 6c 64 20 64           yield d
5480: 47 72 61 70 68 5b 64 4e 6f 64 65 5b 64 54 6f 6b  Graph[dNode[dTok
5490: 65 6e 5b 22 73 56 61 6c 75 65 22 5d 5d 5d 0a 20  en["sValue"]]]. 
54a0: 20 20 20 20 20 20 20 69 66 20 64 54 6f 6b 65 6e         if dToken
54b0: 5b 22 73 56 61 6c 75 65 22 5d 5b 30 3a 32 5d 2e  ["sValue"][0:2].
54c0: 69 73 74 69 74 6c 65 28 29 3a 20 23 20 77 65 20  istitle(): # we 
54d0: 74 65 73 74 20 6f 6e 6c 79 20 32 20 66 69 72 73  test only 2 firs
54e0: 74 20 63 68 61 72 73 2c 20 74 6f 20 6d 61 6b 65  t chars, to make
54f0: 20 76 61 6c 69 64 20 77 6f 72 64 73 20 73 75 63   valid words suc
5500: 68 20 61 73 20 22 4c 61 69 73 73 65 7a 2d 6c 65  h as "Laissez-le
5510: 73 22 2c 20 22 50 61 73 73 65 2d 70 61 72 74 6f  s", "Passe-parto
5520: 75 74 22 2e 0a 20 20 20 20 20 20 20 20 20 20 20  ut"..           
5530: 20 73 56 61 6c 75 65 20 3d 20 64 54 6f 6b 65 6e   sValue = dToken
5540: 5b 22 73 56 61 6c 75 65 22 5d 2e 6c 6f 77 65 72  ["sValue"].lower
5550: 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ().            i
5560: 66 20 73 56 61 6c 75 65 20 69 6e 20 64 4e 6f 64  f sValue in dNod
5570: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
5580: 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20     if bDebug:.  
5590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
55a0: 20 20 70 72 69 6e 74 28 22 20 20 4d 41 54 43 48    print("  MATCH
55b0: 3a 22 2c 20 73 56 61 6c 75 65 29 0a 20 20 20 20  :", sValue).    
55c0: 20 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c              yiel
55d0: 64 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 73  d dGraph[dNode[s
55e0: 56 61 6c 75 65 5d 5d 0a 20 20 20 20 20 20 20 20  Value]].        
55f0: 65 6c 69 66 20 64 54 6f 6b 65 6e 5b 22 73 56 61  elif dToken["sVa
5600: 6c 75 65 22 5d 2e 69 73 75 70 70 65 72 28 29 3a  lue"].isupper():
5610: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 56 61  .            sVa
5620: 6c 75 65 20 3d 20 64 54 6f 6b 65 6e 5b 22 73 56  lue = dToken["sV
5630: 61 6c 75 65 22 5d 2e 6c 6f 77 65 72 28 29 0a 20  alue"].lower(). 
5640: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73 56             if sV
5650: 61 6c 75 65 20 69 6e 20 64 4e 6f 64 65 3a 0a 20  alue in dNode:. 
5660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
5670: 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20  f bDebug:.      
5680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
5690: 69 6e 74 28 22 20 20 4d 41 54 43 48 3a 22 2c 20  int("  MATCH:", 
56a0: 73 56 61 6c 75 65 29 0a 20 20 20 20 20 20 20 20  sValue).        
56b0: 20 20 20 20 20 20 20 20 79 69 65 6c 64 20 64 47          yield dG
56c0: 72 61 70 68 5b 64 4e 6f 64 65 5b 73 56 61 6c 75  raph[dNode[sValu
56d0: 65 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  e]].            
56e0: 73 56 61 6c 75 65 20 3d 20 64 54 6f 6b 65 6e 5b  sValue = dToken[
56f0: 22 73 56 61 6c 75 65 22 5d 2e 63 61 70 69 74 61  "sValue"].capita
5700: 6c 69 7a 65 28 29 0a 20 20 20 20 20 20 20 20 20  lize().         
5710: 20 20 20 69 66 20 73 56 61 6c 75 65 20 69 6e 20     if sValue in 
5720: 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20 20  dNode:.         
5730: 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67         if bDebug
5740: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5750: 20 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 4d        print("  M
5760: 41 54 43 48 3a 22 2c 20 73 56 61 6c 75 65 29 0a  ATCH:", sValue).
5770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5780: 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f  yield dGraph[dNo
5790: 64 65 5b 73 56 61 6c 75 65 5d 5d 0a 20 20 20 20  de[sValue]].    
57a0: 20 20 20 20 23 20 72 65 67 65 78 20 76 61 6c 75      # regex valu
57b0: 65 20 61 72 63 73 0a 20 20 20 20 20 20 20 20 69  e arcs.        i
57c0: 66 20 22 3c 72 65 5f 76 61 6c 75 65 3e 22 20 69  f "<re_value>" i
57d0: 6e 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20  n dNode:.       
57e0: 20 20 20 20 20 66 6f 72 20 73 52 65 67 65 78 20       for sRegex 
57f0: 69 6e 20 64 4e 6f 64 65 5b 22 3c 72 65 5f 76 61  in dNode["<re_va
5800: 6c 75 65 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20  lue>"]:.        
5810: 20 20 20 20 20 20 20 20 69 66 20 22 c2 ac 22 20          if ".." 
5820: 6e 6f 74 20 69 6e 20 73 52 65 67 65 78 3a 0a 20  not in sRegex:. 
5830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5840: 20 20 20 23 20 6e 6f 20 61 6e 74 69 2d 70 61 74     # no anti-pat
5850: 74 65 72 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tern.           
5860: 20 20 20 20 20 20 20 20 20 69 66 20 72 65 2e 73           if re.s
5870: 65 61 72 63 68 28 73 52 65 67 65 78 2c 20 64 54  earch(sRegex, dT
5880: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 3a  oken["sValue"]):
5890: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
58a0: 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62           if bDeb
58b0: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
58c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58d0: 70 72 69 6e 74 28 22 20 20 4d 41 54 43 48 3a 20  print("  MATCH: 
58e0: 7e 22 20 2b 20 73 52 65 67 65 78 29 0a 20 20 20  ~" + sRegex).   
58f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5900: 20 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70       yield dGrap
5910: 68 5b 64 4e 6f 64 65 5b 22 3c 72 65 5f 76 61 6c  h[dNode["<re_val
5920: 75 65 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 20  ue>"][sRegex]]. 
5930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65                 e
5940: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
5950: 20 20 20 20 20 20 20 20 20 23 20 74 68 65 72 65           # there
5960: 20 69 73 20 61 6e 20 61 6e 74 69 2d 70 61 74 74   is an anti-patt
5970: 65 72 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20  ern.            
5980: 20 20 20 20 20 20 20 20 73 50 61 74 74 65 72 6e          sPattern
5990: 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 20 3d 20  , sNegPattern = 
59a0: 73 52 65 67 65 78 2e 73 70 6c 69 74 28 22 c2 ac  sRegex.split("..
59b0: 22 2c 20 31 29 0a 20 20 20 20 20 20 20 20 20 20  ", 1).          
59c0: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4e 65            if sNe
59d0: 67 50 61 74 74 65 72 6e 20 61 6e 64 20 72 65 2e  gPattern and re.
59e0: 73 65 61 72 63 68 28 73 4e 65 67 50 61 74 74 65  search(sNegPatte
59f0: 72 6e 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c  rn, dToken["sVal
5a00: 75 65 22 5d 29 3a 0a 20 20 20 20 20 20 20 20 20  ue"]):.         
5a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
5a20: 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20 20 20  ontinue.        
5a30: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6e              if n
5a40: 6f 74 20 73 50 61 74 74 65 72 6e 20 6f 72 20 72  ot sPattern or r
5a50: 65 2e 73 65 61 72 63 68 28 73 50 61 74 74 65 72  e.search(sPatter
5a60: 6e 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75  n, dToken["sValu
5a70: 65 22 5d 29 3a 0a 20 20 20 20 20 20 20 20 20 20  e"]):.          
5a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
5a90: 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20   bDebug:.       
5aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ab0: 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 4d 41       print("  MA
5ac0: 54 43 48 3a 20 7e 22 20 2b 20 73 52 65 67 65 78  TCH: ~" + sRegex
5ad0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
5ae0: 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64 20            yield 
5af0: 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c 72  dGraph[dNode["<r
5b00: 65 5f 76 61 6c 75 65 3e 22 5d 5b 73 52 65 67 65  e_value>"][sRege
5b10: 78 5d 5d 0a 20 20 20 20 20 20 20 20 23 20 61 6e  x]].        # an
5b20: 61 6c 79 73 61 62 6c 65 20 74 6f 6b 65 6e 73 0a  alysable tokens.
5b30: 20 20 20 20 20 20 20 20 69 66 20 64 54 6f 6b 65          if dToke
5b40: 6e 5b 22 73 54 79 70 65 22 5d 5b 30 3a 34 5d 20  n["sType"][0:4] 
5b50: 3d 3d 20 22 57 4f 52 44 22 3a 0a 20 20 20 20 20  == "WORD":.     
5b60: 20 20 20 20 20 20 20 23 20 74 6f 6b 65 6e 20 6c         # token l
5b70: 65 6d 6d 61 73 0a 20 20 20 20 20 20 20 20 20 20  emmas.          
5b80: 20 20 69 66 20 22 3c 6c 65 6d 6d 61 73 3e 22 20    if "<lemmas>" 
5b90: 69 6e 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20  in dNode:.      
5ba0: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 73 4c            for sL
5bb0: 65 6d 6d 61 20 69 6e 20 5f 6f 53 70 65 6c 6c 43  emma in _oSpellC
5bc0: 68 65 63 6b 65 72 2e 67 65 74 4c 65 6d 6d 61 28  hecker.getLemma(
5bd0: 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d  dToken["sValue"]
5be0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
5bf0: 20 20 20 20 20 20 20 69 66 20 73 4c 65 6d 6d 61         if sLemma
5c00: 20 69 6e 20 64 4e 6f 64 65 5b 22 3c 6c 65 6d 6d   in dNode["<lemm
5c10: 61 73 3e 22 5d 3a 0a 20 20 20 20 20 20 20 20 20  as>"]:.         
5c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
5c30: 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20  f bDebug:.      
5c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c50: 20 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 4d        print("  M
5c60: 41 54 43 48 3a 20 3e 22 20 2b 20 73 4c 65 6d 6d  ATCH: >" + sLemm
5c70: 61 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  a).             
5c80: 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64             yield
5c90: 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c   dGraph[dNode["<
5ca0: 6c 65 6d 6d 61 73 3e 22 5d 5b 73 4c 65 6d 6d 61  lemmas>"][sLemma
5cb0: 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ]].            #
5cc0: 20 72 65 67 65 78 20 6d 6f 72 70 68 20 61 72 63   regex morph arc
5cd0: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  s.            if
5ce0: 20 22 3c 72 65 5f 6d 6f 72 70 68 3e 22 20 69 6e   "<re_morph>" in
5cf0: 20 64 4e 6f 64 65 3a 0a 20 20 20 20 20 20 20 20   dNode:.        
5d00: 20 20 20 20 20 20 20 20 66 6f 72 20 73 52 65 67          for sReg
5d10: 65 78 20 69 6e 20 64 4e 6f 64 65 5b 22 3c 72 65  ex in dNode["<re
5d20: 5f 6d 6f 72 70 68 3e 22 5d 3a 0a 20 20 20 20 20  _morph>"]:.     
5d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
5d40: 66 20 22 c2 ac 22 20 6e 6f 74 20 69 6e 20 73 52  f ".." not in sR
5d50: 65 67 65 78 3a 0a 20 20 20 20 20 20 20 20 20 20  egex:.          
5d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
5d70: 6e 6f 20 61 6e 74 69 2d 70 61 74 74 65 72 6e 0a  no anti-pattern.
5d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d90: 20 20 20 20 20 20 20 20 69 66 20 61 6e 79 28 72          if any(r
5da0: 65 2e 73 65 61 72 63 68 28 73 52 65 67 65 78 2c  e.search(sRegex,
5db0: 20 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d   sMorph)  for sM
5dc0: 6f 72 70 68 20 69 6e 20 5f 6f 53 70 65 6c 6c 43  orph in _oSpellC
5dd0: 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28  hecker.getMorph(
5de0: 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d  dToken["sValue"]
5df0: 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  )):.            
5e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e10: 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20  if bDebug:.     
5e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e30: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
5e40: 28 22 20 20 4d 41 54 43 48 3a 20 40 22 20 2b 20  ("  MATCH: @" + 
5e50: 73 52 65 67 65 78 29 0a 20 20 20 20 20 20 20 20  sRegex).        
5e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e70: 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68      yield dGraph
5e80: 5b 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70  [dNode["<re_morp
5e90: 68 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 20 20  h>"][sRegex]].  
5ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5eb0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
5ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ed0: 23 20 74 68 65 72 65 20 69 73 20 61 6e 20 61 6e  # there is an an
5ee0: 74 69 2d 70 61 74 74 65 72 6e 0a 20 20 20 20 20  ti-pattern.     
5ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f00: 20 20 20 73 50 61 74 74 65 72 6e 2c 20 73 4e 65     sPattern, sNe
5f10: 67 50 61 74 74 65 72 6e 20 3d 20 73 52 65 67 65  gPattern = sRege
5f20: 78 2e 73 70 6c 69 74 28 22 c2 ac 22 2c 20 31 29  x.split("..", 1)
5f30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5f40: 20 20 20 20 20 20 20 20 20 69 66 20 73 4e 65 67           if sNeg
5f50: 50 61 74 74 65 72 6e 20 3d 3d 20 22 2a 22 3a 0a  Pattern == "*":.
5f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f70: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61 6c              # al
5f80: 6c 20 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 6d  l morphologies m
5f90: 75 73 74 20 6d 61 74 63 68 20 77 69 74 68 20 3c  ust match with <
5fa0: 73 50 61 74 74 65 72 6e 3e 0a 20 20 20 20 20 20  sPattern>.      
5fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5fc0: 20 20 20 20 20 20 69 66 20 73 50 61 74 74 65 72        if sPatter
5fd0: 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  n:.             
5fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ff0: 20 20 20 6c 4d 6f 72 70 68 20 3d 20 5f 6f 53 70     lMorph = _oSp
6000: 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d 6f  ellChecker.getMo
6010: 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c  rph(dToken["sVal
6020: 75 65 22 5d 29 0a 20 20 20 20 20 20 20 20 20 20  ue"]).          
6030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6040: 20 20 20 20 20 20 69 66 20 6c 4d 6f 72 70 68 20        if lMorph 
6050: 61 6e 64 20 61 6c 6c 28 72 65 2e 73 65 61 72 63  and all(re.searc
6060: 68 28 73 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72  h(sPattern, sMor
6070: 70 68 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20  ph)  for sMorph 
6080: 69 6e 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20  in lMorph):.    
6090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60b0: 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20  if bDebug:.     
60c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60e0: 20 20 20 70 72 69 6e 74 28 22 20 20 4d 41 54 43     print("  MATC
60f0: 48 3a 20 40 22 20 2b 20 73 52 65 67 65 78 29 0a  H: @" + sRegex).
6100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6120: 20 20 20 20 79 69 65 6c 64 20 64 47 72 61 70 68      yield dGraph
6130: 5b 64 4e 6f 64 65 5b 22 3c 72 65 5f 6d 6f 72 70  [dNode["<re_morp
6140: 68 3e 22 5d 5b 73 52 65 67 65 78 5d 5d 0a 20 20  h>"][sRegex]].  
6150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6160: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
6170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6180: 20 20 20 20 20 20 20 20 69 66 20 73 4e 65 67 50          if sNegP
6190: 61 74 74 65 72 6e 20 61 6e 64 20 61 6e 79 28 72  attern and any(r
61a0: 65 2e 73 65 61 72 63 68 28 73 4e 65 67 50 61 74  e.search(sNegPat
61b0: 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20 20 66  tern, sMorph)  f
61c0: 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20 5f 6f 53  or sMorph in _oS
61d0: 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74 4d  pellChecker.getM
61e0: 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56 61  orph(dToken["sVa
61f0: 6c 75 65 22 5d 29 29 3a 0a 20 20 20 20 20 20 20  lue"])):.       
6200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6210: 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e 75           continu
6220: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
6230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
6240: 20 6e 6f 74 20 73 50 61 74 74 65 72 6e 20 6f 72   not sPattern or
6250: 20 61 6e 79 28 72 65 2e 73 65 61 72 63 68 28 73   any(re.search(s
6260: 50 61 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29  Pattern, sMorph)
6270: 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e 20    for sMorph in 
6280: 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67  _oSpellChecker.g
6290: 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22  etMorph(dToken["
62a0: 73 56 61 6c 75 65 22 5d 29 29 3a 0a 20 20 20 20  sValue"])):.    
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 69 66 20 62              if b
62d0: 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20 20  Debug:.         
62e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
62f0: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
6300: 28 22 20 20 4d 41 54 43 48 3a 20 40 22 20 2b 20  ("  MATCH: @" + 
6310: 73 52 65 67 65 78 29 0a 20 20 20 20 20 20 20 20  sRegex).        
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 79 69 65 6c 64 20 64 47          yield dG
6340: 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c 72 65 5f  raph[dNode["<re_
6350: 6d 6f 72 70 68 3e 22 5d 5b 73 52 65 67 65 78 5d  morph>"][sRegex]
6360: 5d 0a 20 20 20 20 20 20 20 20 23 20 6d 65 74 61  ].        # meta
6370: 20 61 72 63 20 28 66 6f 72 20 74 6f 6b 65 6e 20   arc (for token 
6380: 74 79 70 65 29 0a 20 20 20 20 20 20 20 20 69 66  type).        if
6390: 20 22 3c 6d 65 74 61 3e 22 20 69 6e 20 64 4e 6f   "<meta>" in dNo
63a0: 64 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  de:.            
63b0: 66 6f 72 20 73 4d 65 74 61 20 69 6e 20 64 4e 6f  for sMeta in dNo
63c0: 64 65 5b 22 3c 6d 65 74 61 3e 22 5d 3a 0a 20 20  de["<meta>"]:.  
63d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
63e0: 6e 6f 74 20 72 65 67 65 78 20 68 65 72 65 2c 20  not regex here, 
63f0: 77 65 20 6a 75 73 74 20 73 65 61 72 63 68 20 69  we just search i
6400: 66 20 3c 64 4e 6f 64 65 5b 22 73 54 79 70 65 22  f <dNode["sType"
6410: 5d 3e 20 65 78 69 73 74 73 20 77 69 74 68 69 6e  ]> exists within
6420: 20 3c 73 4d 65 74 61 3e 0a 20 20 20 20 20 20 20   <sMeta>.       
6430: 20 20 20 20 20 20 20 20 20 69 66 20 73 4d 65 74           if sMet
6440: 61 20 3d 3d 20 22 2a 22 3a 0a 20 20 20 20 20 20  a == "*":.      
6450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
6460: 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20   bDebug:.       
6470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6480: 20 70 72 69 6e 74 28 22 20 20 4d 41 54 43 48 3a   print("  MATCH:
6490: 20 2a 22 20 2b 20 73 4d 65 74 61 29 0a 20 20 20   *" + sMeta).   
64a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
64b0: 20 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e   yield dGraph[dN
64c0: 6f 64 65 5b 22 3c 6d 65 74 61 3e 22 5d 5b 22 2a  ode["<meta>"]["*
64d0: 22 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  "]].            
64e0: 20 20 20 20 65 6c 69 66 20 22 c2 ac 22 20 69 6e      elif ".." in
64f0: 20 73 4d 65 74 61 3a 0a 20 20 20 20 20 20 20 20   sMeta:.        
6500: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 64              if d
6510: 54 6f 6b 65 6e 5b 22 73 54 79 70 65 22 5d 20 6e  Token["sType"] n
6520: 6f 74 20 69 6e 20 73 4d 65 74 61 3a 0a 20 20 20  ot in sMeta:.   
6530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6540: 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a       if bDebug:.
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 20 20 20 20 20 70 72 69 6e              prin
6570: 74 28 22 20 20 4d 41 54 43 48 3a 20 2a 22 20 2b  t("  MATCH: *" +
6580: 20 73 4d 65 74 61 29 0a 20 20 20 20 20 20 20 20   sMeta).        
6590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65a0: 79 69 65 6c 64 20 64 47 72 61 70 68 5b 64 4e 6f  yield dGraph[dNo
65b0: 64 65 5b 22 3c 6d 65 74 61 3e 22 5d 5b 73 4d 65  de["<meta>"][sMe
65c0: 74 61 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20  ta]].           
65d0: 20 20 20 20 20 65 6c 69 66 20 64 54 6f 6b 65 6e       elif dToken
65e0: 5b 22 73 54 79 70 65 22 5d 20 69 6e 20 73 4d 65  ["sType"] in sMe
65f0: 74 61 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ta:.            
6600: 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75          if bDebu
6610: 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  g:.             
6620: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
6630: 28 22 20 20 4d 41 54 43 48 3a 20 2a 22 20 2b 20  ("  MATCH: *" + 
6640: 73 4d 65 74 61 29 0a 20 20 20 20 20 20 20 20 20  sMeta).         
6650: 20 20 20 20 20 20 20 20 20 20 20 79 69 65 6c 64             yield
6660: 20 64 47 72 61 70 68 5b 64 4e 6f 64 65 5b 22 3c   dGraph[dNode["<
6670: 6d 65 74 61 3e 22 5d 5b 73 4d 65 74 61 5d 5d 0a  meta>"][sMeta]].
6680: 0a 20 20 20 20 64 65 66 20 70 61 72 73 65 20 28  .    def parse (
6690: 73 65 6c 66 2c 20 64 47 72 61 70 68 2c 20 64 50  self, dGraph, dP
66a0: 72 69 6f 72 69 74 79 2c 20 73 43 6f 75 6e 74 72  riority, sCountr
66b0: 79 3d 22 24 7b 63 6f 75 6e 74 72 79 5f 64 65 66  y="${country_def
66c0: 61 75 6c 74 7d 22 2c 20 64 4f 70 74 69 6f 6e 73  ault}", dOptions
66d0: 3d 4e 6f 6e 65 2c 20 62 53 68 6f 77 52 75 6c 65  =None, bShowRule
66e0: 49 64 3d 46 61 6c 73 65 2c 20 62 44 65 62 75 67  Id=False, bDebug
66f0: 3d 46 61 6c 73 65 2c 20 62 43 6f 6e 74 65 78 74  =False, bContext
6700: 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 20 20 20  =False):.       
6710: 20 22 70 61 72 73 65 20 74 6f 6b 65 6e 73 20 66   "parse tokens f
6720: 72 6f 6d 20 74 68 65 20 74 65 78 74 20 61 6e 64  rom the text and
6730: 20 65 78 65 63 75 74 65 20 61 63 74 69 6f 6e 73   execute actions
6740: 20 65 6e 63 6f 75 6e 74 65 72 65 64 22 0a 20 20   encountered".  
6750: 20 20 20 20 20 20 73 65 6c 66 2e 64 45 72 72 6f        self.dErro
6760: 72 20 3d 20 7b 7d 0a 20 20 20 20 20 20 20 20 64  r = {}.        d
6770: 50 72 69 6f 72 69 74 79 20 3d 20 7b 7d 20 20 23  Priority = {}  #
6780: 20 4b 65 79 20 3d 20 70 6f 73 69 74 69 6f 6e 3b   Key = position;
6790: 20 76 61 6c 75 65 20 3d 20 70 72 69 6f 72 69 74   value = priorit
67a0: 79 0a 20 20 20 20 20 20 20 20 64 4f 70 74 20 3d  y.        dOpt =
67b0: 20 5f 64 4f 70 74 69 6f 6e 73 20 20 69 66 20 6e   _dOptions  if n
67c0: 6f 74 20 64 4f 70 74 69 6f 6e 73 20 20 65 6c 73  ot dOptions  els
67d0: 65 20 64 4f 70 74 69 6f 6e 73 0a 20 20 20 20 20  e dOptions.     
67e0: 20 20 20 6c 50 6f 69 6e 74 65 72 20 3d 20 5b 5d     lPointer = []
67f0: 0a 20 20 20 20 20 20 20 20 62 54 61 67 41 6e 64  .        bTagAnd
6800: 52 65 77 72 69 74 65 20 3d 20 46 61 6c 73 65 0a  Rewrite = False.
6810: 20 20 20 20 20 20 20 20 66 6f 72 20 64 54 6f 6b          for dTok
6820: 65 6e 20 69 6e 20 73 65 6c 66 2e 6c 54 6f 6b 65  en in self.lToke
6830: 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  n:.            i
6840: 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20  f bDebug:.      
6850: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
6860: 22 54 4f 4b 45 4e 3a 22 2c 20 64 54 6f 6b 65 6e  "TOKEN:", dToken
6870: 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20  ["sValue"]).    
6880: 20 20 20 20 20 20 20 20 23 20 63 68 65 63 6b 20          # check 
6890: 61 72 63 73 20 66 6f 72 20 65 61 63 68 20 65 78  arcs for each ex
68a0: 69 73 74 69 6e 67 20 70 6f 69 6e 74 65 72 0a 20  isting pointer. 
68b0: 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65 78 74             lNext
68c0: 50 6f 69 6e 74 65 72 20 3d 20 5b 5d 0a 20 20 20  Pointer = [].   
68d0: 20 20 20 20 20 20 20 20 20 66 6f 72 20 64 50 6f           for dPo
68e0: 69 6e 74 65 72 20 69 6e 20 6c 50 6f 69 6e 74 65  inter in lPointe
68f0: 72 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  r:.             
6900: 20 20 20 66 6f 72 20 64 4e 6f 64 65 20 69 6e 20     for dNode in 
6910: 73 65 6c 66 2e 5f 67 65 74 4e 65 78 74 4d 61 74  self._getNextMat
6920: 63 68 69 6e 67 4e 6f 64 65 73 28 64 54 6f 6b 65  chingNodes(dToke
6930: 6e 2c 20 64 47 72 61 70 68 2c 20 64 50 6f 69 6e  n, dGraph, dPoin
6940: 74 65 72 5b 22 64 4e 6f 64 65 22 5d 2c 20 62 44  ter["dNode"], bD
6950: 65 62 75 67 29 3a 0a 20 20 20 20 20 20 20 20 20  ebug):.         
6960: 20 20 20 20 20 20 20 20 20 20 20 6c 4e 65 78 74             lNext
6970: 50 6f 69 6e 74 65 72 2e 61 70 70 65 6e 64 28 7b  Pointer.append({
6980: 22 69 54 6f 6b 65 6e 22 3a 20 64 50 6f 69 6e 74  "iToken": dPoint
6990: 65 72 5b 22 69 54 6f 6b 65 6e 22 5d 2c 20 22 64  er["iToken"], "d
69a0: 4e 6f 64 65 22 3a 20 64 4e 6f 64 65 7d 29 0a 20  Node": dNode}). 
69b0: 20 20 20 20 20 20 20 20 20 20 20 6c 50 6f 69 6e             lPoin
69c0: 74 65 72 20 3d 20 6c 4e 65 78 74 50 6f 69 6e 74  ter = lNextPoint
69d0: 65 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  er.            #
69e0: 20 63 68 65 63 6b 20 61 72 63 73 20 6f 66 20 66   check arcs of f
69f0: 69 72 73 74 20 6e 6f 64 65 73 0a 20 20 20 20 20  irst nodes.     
6a00: 20 20 20 20 20 20 20 66 6f 72 20 64 4e 6f 64 65         for dNode
6a10: 20 69 6e 20 73 65 6c 66 2e 5f 67 65 74 4e 65 78   in self._getNex
6a20: 74 4d 61 74 63 68 69 6e 67 4e 6f 64 65 73 28 64  tMatchingNodes(d
6a30: 54 6f 6b 65 6e 2c 20 64 47 72 61 70 68 2c 20 64  Token, dGraph, d
6a40: 47 72 61 70 68 5b 30 5d 2c 20 62 44 65 62 75 67  Graph[0], bDebug
6a50: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
6a60: 20 20 20 6c 50 6f 69 6e 74 65 72 2e 61 70 70 65     lPointer.appe
6a70: 6e 64 28 7b 22 69 54 6f 6b 65 6e 22 3a 20 64 54  nd({"iToken": dT
6a80: 6f 6b 65 6e 5b 22 69 22 5d 2c 20 22 64 4e 6f 64  oken["i"], "dNod
6a90: 65 22 3a 20 64 4e 6f 64 65 7d 29 0a 20 20 20 20  e": dNode}).    
6aa0: 20 20 20 20 20 20 20 20 23 20 63 68 65 63 6b 20          # check 
6ab0: 69 66 20 74 68 65 72 65 20 69 73 20 72 75 6c 65  if there is rule
6ac0: 73 20 74 6f 20 63 68 65 63 6b 20 66 6f 72 20 65  s to check for e
6ad0: 61 63 68 20 70 6f 69 6e 74 65 72 0a 20 20 20 20  ach pointer.    
6ae0: 20 20 20 20 20 20 20 20 66 6f 72 20 64 50 6f 69          for dPoi
6af0: 6e 74 65 72 20 69 6e 20 6c 50 6f 69 6e 74 65 72  nter in lPointer
6b00: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
6b10: 20 20 23 69 66 20 62 44 65 62 75 67 3a 0a 20 20    #if bDebug:.  
6b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
6b30: 20 20 20 70 72 69 6e 74 28 22 2b 22 2c 20 64 50     print("+", dP
6b40: 6f 69 6e 74 65 72 29 0a 20 20 20 20 20 20 20 20  ointer).        
6b50: 20 20 20 20 20 20 20 20 69 66 20 22 3c 72 75 6c          if "<rul
6b60: 65 73 3e 22 20 69 6e 20 64 50 6f 69 6e 74 65 72  es>" in dPointer
6b70: 5b 22 64 4e 6f 64 65 22 5d 3a 0a 20 20 20 20 20  ["dNode"]:.     
6b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62                 b
6b90: 43 68 61 6e 67 65 2c 20 64 45 72 72 20 3d 20 73  Change, dErr = s
6ba0: 65 6c 66 2e 5f 65 78 65 63 75 74 65 41 63 74 69  elf._executeActi
6bb0: 6f 6e 73 28 64 47 72 61 70 68 2c 20 64 50 6f 69  ons(dGraph, dPoi
6bc0: 6e 74 65 72 5b 22 64 4e 6f 64 65 22 5d 5b 22 3c  nter["dNode"]["<
6bd0: 72 75 6c 65 73 3e 22 5d 2c 20 64 50 6f 69 6e 74  rules>"], dPoint
6be0: 65 72 5b 22 69 54 6f 6b 65 6e 22 5d 2d 31 2c 20  er["iToken"]-1, 
6bf0: 64 54 6f 6b 65 6e 5b 22 69 22 5d 2c 20 64 50 72  dToken["i"], dPr
6c00: 69 6f 72 69 74 79 2c 20 64 4f 70 74 2c 20 73 43  iority, dOpt, sC
6c10: 6f 75 6e 74 72 79 2c 20 62 53 68 6f 77 52 75 6c  ountry, bShowRul
6c20: 65 49 64 2c 20 62 44 65 62 75 67 2c 20 62 43 6f  eId, bDebug, bCo
6c30: 6e 74 65 78 74 29 0a 20 20 20 20 20 20 20 20 20  ntext).         
6c40: 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e             self.
6c50: 64 45 72 72 6f 72 2e 75 70 64 61 74 65 28 64 45  dError.update(dE
6c60: 72 72 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  rr).            
6c70: 20 20 20 20 20 20 20 20 69 66 20 62 43 68 61 6e          if bChan
6c80: 67 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ge:.            
6c90: 20 20 20 20 20 20 20 20 20 20 20 20 62 54 61 67              bTag
6ca0: 41 6e 64 52 65 77 72 69 74 65 20 3d 20 54 72 75  AndRewrite = Tru
6cb0: 65 0a 20 20 20 20 20 20 20 20 69 66 20 62 54 61  e.        if bTa
6cc0: 67 41 6e 64 52 65 77 72 69 74 65 3a 0a 20 20 20  gAndRewrite:.   
6cd0: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 72 65           self.re
6ce0: 77 72 69 74 65 28 62 44 65 62 75 67 29 0a 20 20  write(bDebug).  
6cf0: 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a        if bDebug:
6d00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
6d10: 6e 74 28 73 65 6c 66 29 0a 20 20 20 20 20 20 20  nt(self).       
6d20: 20 72 65 74 75 72 6e 20 28 62 54 61 67 41 6e 64   return (bTagAnd
6d30: 52 65 77 72 69 74 65 2c 20 73 65 6c 66 2e 73 53  Rewrite, self.sS
6d40: 65 6e 74 65 6e 63 65 29 0a 0a 20 20 20 20 64 65  entence)..    de
6d50: 66 20 5f 65 78 65 63 75 74 65 41 63 74 69 6f 6e  f _executeAction
6d60: 73 20 28 73 65 6c 66 2c 20 64 47 72 61 70 68 2c  s (self, dGraph,
6d70: 20 64 4e 6f 64 65 2c 20 6e 54 6f 6b 65 6e 4f 66   dNode, nTokenOf
6d80: 66 73 65 74 2c 20 6e 4c 61 73 74 54 6f 6b 65 6e  fset, nLastToken
6d90: 2c 20 64 50 72 69 6f 72 69 74 79 2c 20 64 4f 70  , dPriority, dOp
6da0: 74 69 6f 6e 73 2c 20 73 43 6f 75 6e 74 72 79 2c  tions, sCountry,
6db0: 20 62 53 68 6f 77 52 75 6c 65 49 64 2c 20 62 44   bShowRuleId, bD
6dc0: 65 62 75 67 2c 20 62 43 6f 6e 74 65 78 74 29 3a  ebug, bContext):
6dd0: 0a 20 20 20 20 20 20 20 20 22 65 78 65 63 75 74  .        "execut
6de0: 65 20 61 63 74 69 6f 6e 73 20 66 6f 75 6e 64 20  e actions found 
6df0: 69 6e 20 74 68 65 20 44 41 52 47 22 0a 20 20 20  in the DARG".   
6e00: 20 20 20 20 20 64 45 72 72 6f 72 20 3d 20 7b 7d       dError = {}
6e10: 0a 20 20 20 20 20 20 20 20 62 43 68 61 6e 67 65  .        bChange
6e20: 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20   = False.       
6e30: 20 66 6f 72 20 73 4c 69 6e 65 49 64 2c 20 6e 65   for sLineId, ne
6e40: 78 74 4e 6f 64 65 4b 65 79 20 69 6e 20 64 4e 6f  xtNodeKey in dNo
6e50: 64 65 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20 20  de.items():.    
6e60: 20 20 20 20 20 20 20 20 62 43 6f 6e 64 4d 65 6d          bCondMem
6e70: 6f 20 3d 20 4e 6f 6e 65 0a 20 20 20 20 20 20 20  o = None.       
6e80: 20 20 20 20 20 66 6f 72 20 73 52 75 6c 65 49 64       for sRuleId
6e90: 20 69 6e 20 64 47 72 61 70 68 5b 6e 65 78 74 4e   in dGraph[nextN
6ea0: 6f 64 65 4b 65 79 5d 3a 0a 20 20 20 20 20 20 20  odeKey]:.       
6eb0: 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20 20           try:.  
6ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ed0: 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20    if bDebug:.   
6ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ef0: 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 54 52       print("  TR
6f00: 59 3a 22 2c 20 73 52 75 6c 65 49 64 29 0a 20 20  Y:", sRuleId).  
6f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f20: 20 20 73 4f 70 74 69 6f 6e 2c 20 73 46 75 6e 63    sOption, sFunc
6f30: 43 6f 6e 64 2c 20 63 41 63 74 69 6f 6e 54 79 70  Cond, cActionTyp
6f40: 65 2c 20 73 57 68 61 74 2c 20 2a 65 41 63 74 20  e, sWhat, *eAct 
6f50: 3d 20 64 52 75 6c 65 5b 73 52 75 6c 65 49 64 5d  = dRule[sRuleId]
6f60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6f70: 20 20 20 20 20 23 20 53 75 67 67 65 73 74 69 6f       # Suggestio
6f80: 6e 20 20 20 20 5b 20 6f 70 74 69 6f 6e 2c 20 63  n    [ option, c
6f90: 6f 6e 64 69 74 69 6f 6e 2c 20 22 2d 22 2c 20 72  ondition, "-", r
6fa0: 65 70 6c 61 63 65 6d 65 6e 74 2f 73 75 67 67 65  eplacement/sugge
6fb0: 73 74 69 6f 6e 2f 61 63 74 69 6f 6e 2c 20 69 54  stion/action, iT
6fc0: 6f 6b 65 6e 53 74 61 72 74 2c 20 69 54 6f 6b 65  okenStart, iToke
6fd0: 6e 45 6e 64 2c 20 6e 50 72 69 6f 72 69 74 79 2c  nEnd, nPriority,
6fe0: 20 6d 65 73 73 61 67 65 2c 20 55 52 4c 20 5d 0a   message, URL ].
6ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7000: 20 20 20 20 23 20 54 65 78 74 50 72 6f 63 65 73      # TextProces
7010: 73 6f 72 20 5b 20 6f 70 74 69 6f 6e 2c 20 63 6f  sor [ option, co
7020: 6e 64 69 74 69 6f 6e 2c 20 22 7e 22 2c 20 72 65  ndition, "~", re
7030: 70 6c 61 63 65 6d 65 6e 74 2f 73 75 67 67 65 73  placement/sugges
7040: 74 69 6f 6e 2f 61 63 74 69 6f 6e 2c 20 69 54 6f  tion/action, iTo
7050: 6b 65 6e 53 74 61 72 74 2c 20 69 54 6f 6b 65 6e  kenStart, iToken
7060: 45 6e 64 20 5d 0a 20 20 20 20 20 20 20 20 20 20  End ].          
7070: 20 20 20 20 20 20 20 20 20 20 23 20 44 69 73 61            # Disa
7080: 6d 62 69 67 75 61 74 6f 72 20 5b 20 6f 70 74 69  mbiguator [ opti
7090: 6f 6e 2c 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 22  on, condition, "
70a0: 3d 22 2c 20 72 65 70 6c 61 63 65 6d 65 6e 74 2f  =", replacement/
70b0: 73 75 67 67 65 73 74 69 6f 6e 2f 61 63 74 69 6f  suggestion/actio
70c0: 6e 20 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  n ].            
70d0: 20 20 20 20 20 20 20 20 23 20 53 65 6e 74 65 6e          # Senten
70e0: 63 65 20 54 61 67 20 20 5b 20 6f 70 74 69 6f 6e  ce Tag  [ option
70f0: 2c 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 22 2f 22  , condition, "/"
7100: 2c 20 72 65 70 6c 61 63 65 6d 65 6e 74 2f 73 75  , replacement/su
7110: 67 67 65 73 74 69 6f 6e 2f 61 63 74 69 6f 6e 2c  ggestion/action,
7120: 20 69 54 6f 6b 65 6e 53 74 61 72 74 2c 20 69 54   iTokenStart, iT
7130: 6f 6b 65 6e 45 6e 64 20 5d 0a 20 20 20 20 20 20  okenEnd ].      
7140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
7150: 54 65 73 74 20 20 20 20 20 20 20 20 20 20 5b 20  Test          [ 
7160: 6f 70 74 69 6f 6e 2c 20 63 6f 6e 64 69 74 69 6f  option, conditio
7170: 6e 2c 20 22 3e 22 2c 20 22 22 20 5d 0a 20 20 20  n, ">", "" ].   
7180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7190: 20 69 66 20 6e 6f 74 20 73 4f 70 74 69 6f 6e 20   if not sOption 
71a0: 6f 72 20 64 4f 70 74 69 6f 6e 73 2e 67 65 74 28  or dOptions.get(
71b0: 73 4f 70 74 69 6f 6e 2c 20 46 61 6c 73 65 29 3a  sOption, False):
71c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
71d0: 20 20 20 20 20 20 20 20 20 62 43 6f 6e 64 4d 65           bCondMe
71e0: 6d 6f 20 3d 20 6e 6f 74 20 73 46 75 6e 63 43 6f  mo = not sFuncCo
71f0: 6e 64 20 6f 72 20 67 6c 6f 62 61 6c 73 28 29 5b  nd or globals()[
7200: 73 46 75 6e 63 43 6f 6e 64 5d 28 73 65 6c 66 2e  sFuncCond](self.
7210: 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66  lToken, nTokenOf
7220: 66 73 65 74 2c 20 6e 4c 61 73 74 54 6f 6b 65 6e  fset, nLastToken
7230: 2c 20 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f 6e  , sCountry, bCon
7240: 64 4d 65 6d 6f 2c 20 73 65 6c 66 2e 64 54 61 67  dMemo, self.dTag
7250: 73 2c 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63  s, self.sSentenc
7260: 65 2c 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63  e, self.sSentenc
7270: 65 30 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  e0).            
7280: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62              if b
7290: 43 6f 6e 64 4d 65 6d 6f 3a 0a 20 20 20 20 20 20  CondMemo:.      
72a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72b0: 20 20 20 20 20 20 69 66 20 63 41 63 74 69 6f 6e        if cAction
72c0: 54 79 70 65 20 3d 3d 20 22 2d 22 3a 0a 20 20 20  Type == "-":.   
72d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 67               # g
72f0: 72 61 6d 6d 61 72 20 65 72 72 6f 72 0a 20 20 20  rammar error.   
7300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7310: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 54 6f               nTo
7320: 6b 65 6e 45 72 72 6f 72 53 74 61 72 74 20 3d 20  kenErrorStart = 
7330: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65  nTokenOffset + e
7340: 41 63 74 5b 30 5d 0a 20 20 20 20 20 20 20 20 20  Act[0].         
7350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7360: 20 20 20 20 20 20 20 69 66 20 22 62 49 6d 6d 75         if "bImmu
7370: 6e 65 22 20 6e 6f 74 20 69 6e 20 73 65 6c 66 2e  ne" not in self.
7380: 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 45 72 72  lToken[nTokenErr
7390: 6f 72 53 74 61 72 74 5d 3a 0a 20 20 20 20 20 20  orStart]:.      
73a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
73b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 54                nT
73c0: 6f 6b 65 6e 45 72 72 6f 72 45 6e 64 20 3d 20 28  okenErrorEnd = (
73d0: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65  nTokenOffset + e
73e0: 41 63 74 5b 31 5d 29 20 20 69 66 20 65 41 63 74  Act[1])  if eAct
73f0: 5b 31 5d 20 20 65 6c 73 65 20 6e 4c 61 73 74 54  [1]  else nLastT
7400: 6f 6b 65 6e 0a 20 20 20 20 20 20 20 20 20 20 20  oken.           
7410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7420: 20 20 20 20 20 20 20 20 20 6e 45 72 72 6f 72 53           nErrorS
7430: 74 61 72 74 20 3d 20 73 65 6c 66 2e 6e 4f 66 66  tart = self.nOff
7440: 73 65 74 57 69 74 68 69 6e 50 61 72 61 67 72 61  setWithinParagra
7450: 70 68 20 2b 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e  ph + self.lToken
7460: 5b 6e 54 6f 6b 65 6e 45 72 72 6f 72 53 74 61 72  [nTokenErrorStar
7470: 74 5d 5b 22 6e 53 74 61 72 74 22 5d 0a 20 20 20  t]["nStart"].   
7480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
74a0: 20 6e 45 72 72 6f 72 45 6e 64 20 3d 20 73 65 6c   nErrorEnd = sel
74b0: 66 2e 6e 4f 66 66 73 65 74 57 69 74 68 69 6e 50  f.nOffsetWithinP
74c0: 61 72 61 67 72 61 70 68 20 2b 20 73 65 6c 66 2e  aragraph + self.
74d0: 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 45 72 72  lToken[nTokenErr
74e0: 6f 72 45 6e 64 5d 5b 22 6e 45 6e 64 22 5d 0a 20  orEnd]["nEnd"]. 
74f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7510: 20 20 20 69 66 20 6e 45 72 72 6f 72 53 74 61 72     if nErrorStar
7520: 74 20 6e 6f 74 20 69 6e 20 64 45 72 72 6f 72 20  t not in dError 
7530: 6f 72 20 65 41 63 74 5b 32 5d 20 3e 20 64 50 72  or eAct[2] > dPr
7540: 69 6f 72 69 74 79 2e 67 65 74 28 6e 45 72 72 6f  iority.get(nErro
7550: 72 53 74 61 72 74 2c 20 2d 31 29 3a 0a 20 20 20  rStart, -1):.   
7560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7580: 20 20 20 20 20 64 45 72 72 6f 72 5b 6e 45 72 72       dError[nErr
7590: 6f 72 53 74 61 72 74 5d 20 3d 20 73 65 6c 66 2e  orStart] = self.
75a0: 5f 63 72 65 61 74 65 45 72 72 6f 72 28 73 57 68  _createError(sWh
75b0: 61 74 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74  at, nTokenOffset
75c0: 2c 20 6e 54 6f 6b 65 6e 45 72 72 6f 72 53 74 61  , nTokenErrorSta
75d0: 72 74 2c 20 6e 45 72 72 6f 72 53 74 61 72 74 2c  rt, nErrorStart,
75e0: 20 6e 45 72 72 6f 72 45 6e 64 2c 20 73 4c 69 6e   nErrorEnd, sLin
75f0: 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 54 72  eId, sRuleId, Tr
7600: 75 65 2c 20 65 41 63 74 5b 33 5d 2c 20 65 41 63  ue, eAct[3], eAc
7610: 74 5b 34 5d 2c 20 62 53 68 6f 77 52 75 6c 65 49  t[4], bShowRuleI
7620: 64 2c 20 22 6e 6f 74 79 70 65 22 2c 20 62 43 6f  d, "notype", bCo
7630: 6e 74 65 78 74 29 0a 20 20 20 20 20 20 20 20 20  ntext).         
7640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
7660: 50 72 69 6f 72 69 74 79 5b 6e 45 72 72 6f 72 53  Priority[nErrorS
7670: 74 61 72 74 5d 20 3d 20 65 41 63 74 5b 32 5d 0a  tart] = eAct[2].
7680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
76a0: 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75          if bDebu
76b0: 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  g:.             
76c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
76d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
76e0: 72 69 6e 74 28 22 20 20 4e 45 57 5f 45 52 52 4f  rint("  NEW_ERRO
76f0: 52 3a 22 2c 20 64 45 72 72 6f 72 5b 6e 45 72 72  R:", dError[nErr
7700: 6f 72 53 74 61 72 74 5d 2c 20 22 5c 6e 20 20 22  orStart], "\n  "
7710: 2c 20 64 52 75 6c 65 5b 73 52 75 6c 65 49 64 5d  , dRule[sRuleId]
7720: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
7730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6c                el
7740: 69 66 20 63 41 63 74 69 6f 6e 54 79 70 65 20 3d  if cActionType =
7750: 3d 20 22 7e 22 3a 0a 20 20 20 20 20 20 20 20 20  = "~":.         
7760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7770: 20 20 20 20 20 20 20 23 20 74 65 78 74 20 70 72         # text pr
7780: 6f 63 65 73 73 6f 72 0a 20 20 20 20 20 20 20 20  ocessor.        
7790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
77a0: 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62 75          if bDebu
77b0: 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  g:.             
77c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
77d0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 20 20         print("  
77e0: 54 41 47 5f 50 52 45 50 41 52 45 3a 5c 6e 20 20  TAG_PREPARE:\n  
77f0: 22 2c 20 64 52 75 6c 65 5b 73 52 75 6c 65 49 64  ", dRule[sRuleId
7800: 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]).             
7810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7820: 20 20 20 6e 45 6e 64 54 6f 6b 65 6e 20 3d 20 28     nEndToken = (
7830: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20 65  nTokenOffset + e
7840: 41 63 74 5b 31 5d 29 20 20 69 66 20 65 41 63 74  Act[1])  if eAct
7850: 5b 31 5d 20 20 65 6c 73 65 20 6e 4c 61 73 74 54  [1]  else nLastT
7860: 6f 6b 65 6e 0a 20 20 20 20 20 20 20 20 20 20 20  oken.           
7870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7880: 20 20 20 20 20 73 65 6c 66 2e 5f 74 61 67 41 6e       self._tagAn
7890: 64 50 72 65 70 61 72 65 54 6f 6b 65 6e 46 6f 72  dPrepareTokenFor
78a0: 52 65 77 72 69 74 69 6e 67 28 73 57 68 61 74 2c  Rewriting(sWhat,
78b0: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 20 2b 20   nTokenOffset + 
78c0: 65 41 63 74 5b 30 5d 2c 20 6e 45 6e 64 54 6f 6b  eAct[0], nEndTok
78d0: 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74  en, nTokenOffset
78e0: 2c 20 54 72 75 65 2c 20 62 44 65 62 75 67 29 0a  , True, bDebug).
78f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7910: 62 43 68 61 6e 67 65 20 3d 20 54 72 75 65 0a 20  bChange = True. 
7920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7930: 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20             elif 
7940: 63 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22  cActionType == "
7950: 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  =":.            
7960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7970: 20 20 20 20 23 20 64 69 73 61 6d 62 69 67 75 61      # disambigua
7980: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tion.           
7990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
79a0: 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a       if bDebug:.
79b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
79c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
79d0: 20 20 20 20 70 72 69 6e 74 28 22 20 20 44 49 53      print("  DIS
79e0: 41 4d 42 49 47 55 41 54 4f 52 3a 5c 6e 20 20 22  AMBIGUATOR:\n  "
79f0: 2c 20 64 52 75 6c 65 5b 73 52 75 6c 65 49 64 5d  , dRule[sRuleId]
7a00: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
7a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7a20: 20 20 67 6c 6f 62 61 6c 73 28 29 5b 73 57 68 61    globals()[sWha
7a30: 74 5d 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e 2c 20  t](self.lToken, 
7a40: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29 0a 20 20  nTokenOffset).  
7a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7a60: 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20 63            elif c
7a70: 41 63 74 69 6f 6e 54 79 70 65 20 3d 3d 20 22 3e  ActionType == ">
7a80: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ":.             
7a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7aa0: 20 20 20 23 20 77 65 20 64 6f 20 6e 6f 74 68 69     # we do nothi
7ab0: 6e 67 2c 20 74 68 69 73 20 74 65 73 74 20 69 73  ng, this test is
7ac0: 20 6a 75 73 74 20 61 20 63 6f 6e 64 69 74 69 6f   just a conditio
7ad0: 6e 20 74 6f 20 61 70 70 6c 79 20 61 6c 6c 20 66  n to apply all f
7ae0: 6f 6c 6c 6f 77 69 6e 67 20 61 63 74 69 6f 6e 73  ollowing actions
7af0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b10: 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20 20   if bDebug:.    
7b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b40: 70 72 69 6e 74 28 22 20 20 43 4f 4e 44 5f 4f 4b  print("  COND_OK
7b50: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ").             
7b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b70: 20 20 20 70 61 73 73 0a 20 20 20 20 20 20 20 20     pass.        
7b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b90: 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f 6e      elif cAction
7ba0: 54 79 70 65 20 3d 3d 20 22 2f 22 3a 0a 20 20 20  Type == "/":.   
7bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 73               # s
7bd0: 65 6e 74 65 6e 63 65 20 74 61 67 73 0a 20 20 20  entence tags.   
7be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
7c00: 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20  bDebug:.        
7c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c20: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
7c30: 74 28 22 20 20 53 45 4e 54 45 4e 43 45 5f 54 41  t("  SENTENCE_TA
7c40: 47 3a 5c 6e 20 20 22 2c 20 64 52 75 6c 65 5b 73  G:\n  ", dRule[s
7c50: 52 75 6c 65 49 64 5d 29 0a 20 20 20 20 20 20 20  RuleId]).       
7c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c70: 20 20 20 20 20 20 20 20 20 6e 54 6f 6b 65 6e 54           nTokenT
7c80: 61 67 20 3d 20 6e 54 6f 6b 65 6e 4f 66 66 73 65  ag = nTokenOffse
7c90: 74 20 2b 20 65 41 63 74 5b 30 5d 0a 20 20 20 20  t + eAct[0].    
7ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cb0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73              if s
7cc0: 57 68 61 74 20 6e 6f 74 20 69 6e 20 73 65 6c 66  What not in self
7cd0: 2e 64 54 61 67 73 3a 0a 20 20 20 20 20 20 20 20  .dTags:.        
7ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cf0: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66              self
7d00: 2e 64 54 61 67 73 5b 73 57 68 61 74 5d 20 3d 20  .dTags[sWhat] = 
7d10: 28 6e 54 6f 6b 65 6e 54 61 67 2c 20 6e 54 6f 6b  (nTokenTag, nTok
7d20: 65 6e 54 61 67 29 0a 20 20 20 20 20 20 20 20 20  enTag).         
7d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d40: 20 20 20 20 20 20 20 65 6c 69 66 20 6e 54 6f 6b         elif nTok
7d50: 65 6e 54 61 67 20 3e 20 73 65 6c 66 2e 64 54 61  enTag > self.dTa
7d60: 67 73 5b 73 57 68 61 74 5d 5b 31 5d 3a 0a 20 20  gs[sWhat][1]:.  
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d90: 20 20 73 65 6c 66 2e 64 54 61 67 73 5b 73 57 68    self.dTags[sWh
7da0: 61 74 5d 20 3d 20 28 73 65 6c 66 2e 64 54 61 67  at] = (self.dTag
7db0: 73 5b 73 57 68 61 74 5d 5b 30 5d 2c 20 6e 54 6f  s[sWhat][0], nTo
7dc0: 6b 65 6e 54 61 67 29 0a 20 20 20 20 20 20 20 20  kenTag).        
7dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7de0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
7df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e00: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
7e10: 22 23 20 65 72 72 6f 72 3a 20 75 6e 6b 6e 6f 77  "# error: unknow
7e20: 6e 20 61 63 74 69 6f 6e 20 61 74 20 22 20 2b 20  n action at " + 
7e30: 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20  sLineId).       
7e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e50: 20 65 6c 69 66 20 63 41 63 74 69 6f 6e 54 79 70   elif cActionTyp
7e60: 65 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20 20 20  e == ">":.      
7e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e80: 20 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a        if bDebug:
7e90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7eb0: 20 70 72 69 6e 74 28 22 20 20 43 4f 4e 44 5f 42   print("  COND_B
7ec0: 52 45 41 4b 22 29 0a 20 20 20 20 20 20 20 20 20  REAK").         
7ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7ee0: 20 20 20 62 72 65 61 6b 0a 20 20 20 20 20 20 20     break.       
7ef0: 20 20 20 20 20 20 20 20 20 65 78 63 65 70 74 20           except 
7f00: 45 78 63 65 70 74 69 6f 6e 20 61 73 20 65 3a 0a  Exception as e:.
7f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f20: 20 20 20 20 72 61 69 73 65 20 45 78 63 65 70 74      raise Except
7f30: 69 6f 6e 28 73 74 72 28 65 29 2c 20 73 4c 69 6e  ion(str(e), sLin
7f40: 65 49 64 2c 20 73 52 75 6c 65 49 64 2c 20 73 65  eId, sRuleId, se
7f50: 6c 66 2e 73 53 65 6e 74 65 6e 63 65 29 0a 20 20  lf.sSentence).  
7f60: 20 20 20 20 20 20 72 65 74 75 72 6e 20 62 43 68        return bCh
7f70: 61 6e 67 65 2c 20 64 45 72 72 6f 72 0a 0a 20 20  ange, dError..  
7f80: 20 20 64 65 66 20 5f 63 72 65 61 74 65 45 72 72    def _createErr
7f90: 6f 72 20 28 73 65 6c 66 2c 20 73 53 75 67 67 2c  or (self, sSugg,
7fa0: 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 2c 20 69   nTokenOffset, i
7fb0: 46 69 72 73 74 54 6f 6b 65 6e 2c 20 6e 53 74 61  FirstToken, nSta
7fc0: 72 74 2c 20 6e 45 6e 64 2c 20 73 4c 69 6e 65 49  rt, nEnd, sLineI
7fd0: 64 2c 20 73 52 75 6c 65 49 64 2c 20 62 55 70 70  d, sRuleId, bUpp
7fe0: 65 72 63 61 73 65 2c 20 73 4d 73 67 2c 20 73 55  ercase, sMsg, sU
7ff0: 52 4c 2c 20 62 53 68 6f 77 52 75 6c 65 49 64 2c  RL, bShowRuleId,
8000: 20 73 4f 70 74 69 6f 6e 2c 20 62 43 6f 6e 74 65   sOption, bConte
8010: 78 74 29 3a 0a 20 20 20 20 20 20 20 20 23 20 73  xt):.        # s
8020: 75 67 67 65 73 74 69 6f 6e 73 0a 20 20 20 20 20  uggestions.     
8030: 20 20 20 69 66 20 73 53 75 67 67 5b 30 3a 31 5d     if sSugg[0:1]
8040: 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20   == "=":.       
8050: 20 20 20 20 20 73 53 75 67 67 20 3d 20 67 6c 6f       sSugg = glo
8060: 62 61 6c 73 28 29 5b 73 53 75 67 67 5b 31 3a 5d  bals()[sSugg[1:]
8070: 5d 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e 2c 20 6e  ](self.lToken, n
8080: 54 6f 6b 65 6e 4f 66 66 73 65 74 29 0a 20 20 20  TokenOffset).   
8090: 20 20 20 20 20 20 20 20 20 6c 53 75 67 67 20 3d           lSugg =
80a0: 20 73 53 75 67 67 2e 73 70 6c 69 74 28 22 7c 22   sSugg.split("|"
80b0: 29 20 20 69 66 20 73 53 75 67 67 20 20 65 6c 73  )  if sSugg  els
80c0: 65 20 5b 5d 0a 20 20 20 20 20 20 20 20 65 6c 69  e [].        eli
80d0: 66 20 73 53 75 67 67 20 3d 3d 20 22 5f 22 3a 0a  f sSugg == "_":.
80e0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 53 75 67              lSug
80f0: 67 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 65  g = [].        e
8100: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
8110: 20 6c 53 75 67 67 20 3d 20 73 65 6c 66 2e 5f 65   lSugg = self._e
8120: 78 70 61 6e 64 28 73 53 75 67 67 2c 20 6e 54 6f  xpand(sSugg, nTo
8130: 6b 65 6e 4f 66 66 73 65 74 29 2e 73 70 6c 69 74  kenOffset).split
8140: 28 22 7c 22 29 0a 20 20 20 20 20 20 20 20 69 66  ("|").        if
8150: 20 62 55 70 70 65 72 63 61 73 65 20 61 6e 64 20   bUppercase and 
8160: 6c 53 75 67 67 20 61 6e 64 20 73 65 6c 66 2e 6c  lSugg and self.l
8170: 54 6f 6b 65 6e 5b 69 46 69 72 73 74 54 6f 6b 65  Token[iFirstToke
8180: 6e 5d 5b 22 73 56 61 6c 75 65 22 5d 5b 30 3a 31  n]["sValue"][0:1
8190: 5d 2e 69 73 75 70 70 65 72 28 29 3a 0a 20 20 20  ].isupper():.   
81a0: 20 20 20 20 20 20 20 20 20 6c 53 75 67 67 20 3d           lSugg =
81b0: 20 6c 69 73 74 28 6d 61 70 28 73 74 72 2e 63 61   list(map(str.ca
81c0: 70 69 74 61 6c 69 7a 65 2c 20 6c 53 75 67 67 29  pitalize, lSugg)
81d0: 29 0a 20 20 20 20 20 20 20 20 23 20 4d 65 73 73  ).        # Mess
81e0: 61 67 65 0a 20 20 20 20 20 20 20 20 73 4d 65 73  age.        sMes
81f0: 73 61 67 65 20 3d 20 67 6c 6f 62 61 6c 73 28 29  sage = globals()
8200: 5b 73 4d 73 67 5b 31 3a 5d 5d 28 73 65 6c 66 2e  [sMsg[1:]](self.
8210: 6c 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66  lToken, nTokenOf
8220: 66 73 65 74 29 20 20 69 66 20 73 4d 73 67 5b 30  fset)  if sMsg[0
8230: 3a 31 5d 20 3d 3d 20 22 3d 22 20 20 65 6c 73 65  :1] == "="  else
8240: 20 73 65 6c 66 2e 5f 65 78 70 61 6e 64 28 73 4d   self._expand(sM
8250: 73 67 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74  sg, nTokenOffset
8260: 29 0a 20 20 20 20 20 20 20 20 69 66 20 62 53 68  ).        if bSh
8270: 6f 77 52 75 6c 65 49 64 3a 0a 20 20 20 20 20 20  owRuleId:.      
8280: 20 20 20 20 20 20 73 4d 65 73 73 61 67 65 20 2b        sMessage +
8290: 3d 20 22 20 20 22 20 2b 20 73 4c 69 6e 65 49 64  = "  " + sLineId
82a0: 20 2b 20 22 20 23 20 22 20 2b 20 73 52 75 6c 65   + " # " + sRule
82b0: 49 64 0a 20 20 20 20 20 20 20 20 23 0a 20 20 20  Id.        #.   
82c0: 20 20 20 20 20 69 66 20 5f 62 57 72 69 74 65 72       if _bWriter
82d0: 45 72 72 6f 72 3a 0a 20 20 20 20 20 20 20 20 20  Error:.         
82e0: 20 20 20 78 45 72 72 20 3d 20 53 69 6e 67 6c 65     xErr = Single
82f0: 50 72 6f 6f 66 72 65 61 64 69 6e 67 45 72 72 6f  ProofreadingErro
8300: 72 28 29 20 20 20 20 23 20 75 6e 6f 2e 63 72 65  r()    # uno.cre
8310: 61 74 65 55 6e 6f 53 74 72 75 63 74 28 20 22 63  ateUnoStruct( "c
8320: 6f 6d 2e 73 75 6e 2e 73 74 61 72 2e 6c 69 6e 67  om.sun.star.ling
8330: 75 69 73 74 69 63 32 2e 53 69 6e 67 6c 65 50 72  uistic2.SinglePr
8340: 6f 6f 66 72 65 61 64 69 6e 67 45 72 72 6f 72 22  oofreadingError"
8350: 20 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 78   ).            x
8360: 45 72 72 2e 6e 45 72 72 6f 72 53 74 61 72 74 20  Err.nErrorStart 
8370: 3d 20 6e 53 74 61 72 74 0a 20 20 20 20 20 20 20  = nStart.       
8380: 20 20 20 20 20 78 45 72 72 2e 6e 45 72 72 6f 72       xErr.nError
8390: 4c 65 6e 67 74 68 20 3d 20 6e 45 6e 64 20 2d 20  Length = nEnd - 
83a0: 6e 53 74 61 72 74 0a 20 20 20 20 20 20 20 20 20  nStart.         
83b0: 20 20 20 78 45 72 72 2e 6e 45 72 72 6f 72 54 79     xErr.nErrorTy
83c0: 70 65 20 3d 20 50 52 4f 4f 46 52 45 41 44 49 4e  pe = PROOFREADIN
83d0: 47 0a 20 20 20 20 20 20 20 20 20 20 20 20 78 45  G.            xE
83e0: 72 72 2e 61 52 75 6c 65 49 64 65 6e 74 69 66 69  rr.aRuleIdentifi
83f0: 65 72 20 3d 20 73 52 75 6c 65 49 64 0a 20 20 20  er = sRuleId.   
8400: 20 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53           xErr.aS
8410: 68 6f 72 74 43 6f 6d 6d 65 6e 74 20 3d 20 73 4d  hortComment = sM
8420: 65 73 73 61 67 65 20 20 20 23 20 73 4d 65 73 73  essage   # sMess
8430: 61 67 65 2e 73 70 6c 69 74 28 22 7c 22 29 5b 30  age.split("|")[0
8440: 5d 20 20 20 20 20 23 20 69 6e 20 63 6f 6e 74 65  ]     # in conte
8450: 78 74 20 6d 65 6e 75 0a 20 20 20 20 20 20 20 20  xt menu.        
8460: 20 20 20 20 78 45 72 72 2e 61 46 75 6c 6c 43 6f      xErr.aFullCo
8470: 6d 6d 65 6e 74 20 3d 20 73 4d 65 73 73 61 67 65  mment = sMessage
8480: 20 20 20 23 20 73 4d 65 73 73 61 67 65 2e 73 70     # sMessage.sp
8490: 6c 69 74 28 22 7c 22 29 5b 2d 31 5d 20 20 20 20  lit("|")[-1]    
84a0: 23 20 69 6e 20 64 69 61 6c 6f 67 0a 20 20 20 20  # in dialog.    
84b0: 20 20 20 20 20 20 20 20 69 66 20 62 53 68 6f 77          if bShow
84c0: 52 75 6c 65 49 64 3a 0a 20 20 20 20 20 20 20 20  RuleId:.        
84d0: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 53 68          xErr.aSh
84e0: 6f 72 74 43 6f 6d 6d 65 6e 74 20 2b 3d 20 22 20  ortComment += " 
84f0: 20 22 20 2b 20 73 4c 69 6e 65 49 64 20 2b 20 22   " + sLineId + "
8500: 20 23 20 22 20 2b 20 73 52 75 6c 65 49 64 0a 20   # " + sRuleId. 
8510: 20 20 20 20 20 20 20 20 20 20 20 78 45 72 72 2e             xErr.
8520: 61 53 75 67 67 65 73 74 69 6f 6e 73 20 3d 20 74  aSuggestions = t
8530: 75 70 6c 65 28 6c 53 75 67 67 29 0a 20 20 20 20  uple(lSugg).    
8540: 20 20 20 20 20 20 20 20 69 66 20 73 55 52 4c 3a          if sURL:
8550: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8560: 20 78 50 72 6f 70 65 72 74 79 20 3d 20 50 72 6f   xProperty = Pro
8570: 70 65 72 74 79 56 61 6c 75 65 28 29 0a 20 20 20  pertyValue().   
8580: 20 20 20 20 20 20 20 20 20 20 20 20 20 78 50 72               xPr
8590: 6f 70 65 72 74 79 2e 4e 61 6d 65 20 3d 20 22 46  operty.Name = "F
85a0: 75 6c 6c 43 6f 6d 6d 65 6e 74 55 52 4c 22 0a 20  ullCommentURL". 
85b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 78                 x
85c0: 50 72 6f 70 65 72 74 79 2e 56 61 6c 75 65 20 3d  Property.Value =
85d0: 20 73 55 52 4c 0a 20 20 20 20 20 20 20 20 20 20   sURL.          
85e0: 20 20 20 20 20 20 78 45 72 72 2e 61 50 72 6f 70        xErr.aProp
85f0: 65 72 74 69 65 73 20 3d 20 28 78 50 72 6f 70 65  erties = (xPrope
8600: 72 74 79 2c 29 0a 20 20 20 20 20 20 20 20 20 20  rty,).          
8610: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
8620: 20 20 20 20 20 20 20 20 78 45 72 72 2e 61 50 72          xErr.aPr
8630: 6f 70 65 72 74 69 65 73 20 3d 20 28 29 0a 20 20  operties = ().  
8640: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
8650: 20 78 45 72 72 0a 20 20 20 20 20 20 20 20 65 6c   xErr.        el
8660: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
8670: 64 45 72 72 20 3d 20 7b 7d 0a 20 20 20 20 20 20  dErr = {}.      
8680: 20 20 20 20 20 20 64 45 72 72 5b 22 6e 53 74 61        dErr["nSta
8690: 72 74 22 5d 20 3d 20 6e 53 74 61 72 74 0a 20 20  rt"] = nStart.  
86a0: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
86b0: 6e 45 6e 64 22 5d 20 3d 20 6e 45 6e 64 0a 20 20  nEnd"] = nEnd.  
86c0: 20 20 20 20 20 20 20 20 20 20 64 45 72 72 5b 22            dErr["
86d0: 73 4c 69 6e 65 49 64 22 5d 20 3d 20 73 4c 69 6e  sLineId"] = sLin
86e0: 65 49 64 0a 20 20 20 20 20 20 20 20 20 20 20 20  eId.            
86f0: 64 45 72 72 5b 22 73 52 75 6c 65 49 64 22 5d 20  dErr["sRuleId"] 
8700: 3d 20 73 52 75 6c 65 49 64 0a 20 20 20 20 20 20  = sRuleId.      
8710: 20 20 20 20 20 20 64 45 72 72 5b 22 73 54 79 70        dErr["sTyp
8720: 65 22 5d 20 3d 20 73 4f 70 74 69 6f 6e 20 20 69  e"] = sOption  i
8730: 66 20 73 4f 70 74 69 6f 6e 20 20 65 6c 73 65 20  f sOption  else 
8740: 22 6e 6f 74 79 70 65 22 0a 20 20 20 20 20 20 20  "notype".       
8750: 20 20 20 20 20 64 45 72 72 5b 22 73 4d 65 73 73       dErr["sMess
8760: 61 67 65 22 5d 20 3d 20 73 4d 65 73 73 61 67 65  age"] = sMessage
8770: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 45 72  .            dEr
8780: 72 5b 22 61 53 75 67 67 65 73 74 69 6f 6e 73 22  r["aSuggestions"
8790: 5d 20 3d 20 6c 53 75 67 67 0a 20 20 20 20 20 20  ] = lSugg.      
87a0: 20 20 20 20 20 20 64 45 72 72 5b 22 55 52 4c 22        dErr["URL"
87b0: 5d 20 3d 20 73 55 52 4c 20 20 69 66 20 73 55 52  ] = sURL  if sUR
87c0: 4c 20 20 65 6c 73 65 20 22 22 0a 20 20 20 20 20  L  else "".     
87d0: 20 20 20 20 20 20 20 69 66 20 62 43 6f 6e 74 65         if bConte
87e0: 78 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  xt:.            
87f0: 20 20 20 20 64 45 72 72 5b 27 73 55 6e 64 65 72      dErr['sUnder
8800: 6c 69 6e 65 64 27 5d 20 3d 20 73 65 6c 66 2e 73  lined'] = self.s
8810: 53 65 6e 74 65 6e 63 65 30 5b 6e 53 74 61 72 74  Sentence0[nStart
8820: 3a 6e 45 6e 64 5d 0a 20 20 20 20 20 20 20 20 20  :nEnd].         
8830: 20 20 20 20 20 20 20 64 45 72 72 5b 27 73 42 65         dErr['sBe
8840: 66 6f 72 65 27 5d 20 3d 20 73 65 6c 66 2e 73 53  fore'] = self.sS
8850: 65 6e 74 65 6e 63 65 30 5b 6d 61 78 28 30 2c 6e  entence0[max(0,n
8860: 53 74 61 72 74 2d 38 30 29 3a 6e 53 74 61 72 74  Start-80):nStart
8870: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ].              
8880: 20 20 64 45 72 72 5b 27 73 41 66 74 65 72 27 5d    dErr['sAfter']
8890: 20 3d 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63   = self.sSentenc
88a0: 65 30 5b 6e 45 6e 64 3a 6e 45 6e 64 2b 38 30 5d  e0[nEnd:nEnd+80]
88b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
88c0: 75 72 6e 20 64 45 72 72 0a 0a 20 20 20 20 64 65  urn dErr..    de
88d0: 66 20 5f 65 78 70 61 6e 64 20 28 73 65 6c 66 2c  f _expand (self,
88e0: 20 73 54 65 78 74 2c 20 6e 54 6f 6b 65 6e 4f 66   sText, nTokenOf
88f0: 66 73 65 74 29 3a 0a 20 20 20 20 20 20 20 20 23  fset):.        #
8900: 70 72 69 6e 74 28 22 2a 22 2c 20 73 54 65 78 74  print("*", sText
8910: 29 0a 20 20 20 20 20 20 20 20 66 6f 72 20 6d 20  ).        for m 
8920: 69 6e 20 72 65 2e 66 69 6e 64 69 74 65 72 28 72  in re.finditer(r
8930: 22 5c 5c 28 5b 30 2d 39 5d 2b 29 22 2c 20 73 54  "\\([0-9]+)", sT
8940: 65 78 74 29 3a 0a 20 20 20 20 20 20 20 20 20 20  ext):.          
8950: 20 20 73 54 65 78 74 20 3d 20 73 54 65 78 74 2e    sText = sText.
8960: 72 65 70 6c 61 63 65 28 6d 2e 67 72 6f 75 70 28  replace(m.group(
8970: 30 29 2c 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b  0), self.lToken[
8980: 69 6e 74 28 6d 2e 67 72 6f 75 70 28 31 29 29 2b  int(m.group(1))+
8990: 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 5d 5b 22 73  nTokenOffset]["s
89a0: 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20 20  Value"]).       
89b0: 20 23 70 72 69 6e 74 28 22 3e 22 2c 20 73 54 65   #print(">", sTe
89c0: 78 74 29 0a 20 20 20 20 20 20 20 20 72 65 74 75  xt).        retu
89d0: 72 6e 20 73 54 65 78 74 0a 0a 20 20 20 20 64 65  rn sText..    de
89e0: 66 20 5f 74 61 67 41 6e 64 50 72 65 70 61 72 65  f _tagAndPrepare
89f0: 54 6f 6b 65 6e 46 6f 72 52 65 77 72 69 74 69 6e  TokenForRewritin
8a00: 67 20 28 73 65 6c 66 2c 20 73 57 68 61 74 2c 20  g (self, sWhat, 
8a10: 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61  nTokenRewriteSta
8a20: 72 74 2c 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74  rt, nTokenRewrit
8a30: 65 45 6e 64 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73  eEnd, nTokenOffs
8a40: 65 74 2c 20 62 55 70 70 65 72 63 61 73 65 3d 54  et, bUppercase=T
8a50: 72 75 65 2c 20 62 44 65 62 75 67 3d 46 61 6c 73  rue, bDebug=Fals
8a60: 65 29 3a 0a 20 20 20 20 20 20 20 20 22 74 65 78  e):.        "tex
8a70: 74 20 70 72 6f 63 65 73 73 6f 72 3a 20 72 65 77  t processor: rew
8a80: 72 69 74 65 20 74 6f 6b 65 6e 73 20 62 65 74 77  rite tokens betw
8a90: 65 65 6e 20 3c 6e 54 6f 6b 65 6e 52 65 77 72 69  een <nTokenRewri
8aa0: 74 65 53 74 61 72 74 3e 20 61 6e 64 20 3c 6e 54  teStart> and <nT
8ab0: 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e 64 3e 20  okenRewriteEnd> 
8ac0: 70 6f 73 69 74 69 6f 6e 22 0a 20 20 20 20 20 20  position".      
8ad0: 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20 20    if bDebug:.   
8ae0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
8af0: 20 20 20 53 54 41 52 54 3a 22 2c 20 6e 54 6f 6b     START:", nTok
8b00: 65 6e 52 65 77 72 69 74 65 53 74 61 72 74 2c 20  enRewriteStart, 
8b10: 22 45 4e 44 3a 22 2c 20 6e 54 6f 6b 65 6e 52 65  "END:", nTokenRe
8b20: 77 72 69 74 65 45 6e 64 29 0a 20 20 20 20 20 20  writeEnd).      
8b30: 20 20 69 66 20 73 57 68 61 74 20 3d 3d 20 22 2a    if sWhat == "*
8b40: 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ":.            #
8b50: 20 70 75 72 67 65 20 74 65 78 74 0a 20 20 20 20   purge text.    
8b60: 20 20 20 20 20 20 20 20 69 66 20 6e 54 6f 6b 65          if nToke
8b70: 6e 52 65 77 72 69 74 65 45 6e 64 20 2d 20 6e 54  nRewriteEnd - nT
8b80: 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61 72 74  okenRewriteStart
8b90: 20 3d 3d 20 30 3a 0a 20 20 20 20 20 20 20 20 20   == 0:.         
8ba0: 20 20 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b         self.lTok
8bb0: 65 6e 5b 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65  en[nTokenRewrite
8bc0: 53 74 61 72 74 5d 5b 22 62 54 6f 52 65 6d 6f 76  Start]["bToRemov
8bd0: 65 22 5d 20 3d 20 54 72 75 65 0a 20 20 20 20 20  e"] = True.     
8be0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
8bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72               for
8c00: 20 69 20 69 6e 20 72 61 6e 67 65 28 6e 54 6f 6b   i in range(nTok
8c10: 65 6e 52 65 77 72 69 74 65 53 74 61 72 74 2c 20  enRewriteStart, 
8c20: 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e 64  nTokenRewriteEnd
8c30: 2b 31 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  +1):.           
8c40: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6c 54           self.lT
8c50: 6f 6b 65 6e 5b 69 5d 5b 22 62 54 6f 52 65 6d 6f  oken[i]["bToRemo
8c60: 76 65 22 5d 20 3d 20 54 72 75 65 0a 20 20 20 20  ve"] = True.    
8c70: 20 20 20 20 65 6c 69 66 20 73 57 68 61 74 20 3d      elif sWhat =
8c80: 3d 20 22 e2 90 a3 22 3a 0a 20 20 20 20 20 20 20  = "...":.       
8c90: 20 20 20 20 20 23 20 6d 65 72 67 65 20 74 6f 6b       # merge tok
8ca0: 65 6e 73 0a 20 20 20 20 20 20 20 20 20 20 20 20  ens.            
8cb0: 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b  self.lToken[nTok
8cc0: 65 6e 52 65 77 72 69 74 65 53 74 61 72 74 5d 5b  enRewriteStart][
8cd0: 22 6e 4d 65 72 67 65 55 6e 74 69 6c 22 5d 20 3d  "nMergeUntil"] =
8ce0: 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e   nTokenRewriteEn
8cf0: 64 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  d.        elif s
8d00: 57 68 61 74 20 3d 3d 20 22 21 22 3a 0a 20 20 20  What == "!":.   
8d10: 20 20 20 20 20 20 20 20 20 23 20 69 6d 6d 75 6e           # immun
8d20: 69 74 79 0a 20 20 20 20 20 20 20 20 20 20 20 20  ity.            
8d30: 69 66 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65  if nTokenRewrite
8d40: 45 6e 64 20 2d 20 6e 54 6f 6b 65 6e 52 65 77 72  End - nTokenRewr
8d50: 69 74 65 53 74 61 72 74 20 3d 3d 20 30 3a 0a 20  iteStart == 0:. 
8d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
8d70: 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 6e 54 6f 6b 65  elf.lToken[nToke
8d80: 6e 52 65 77 72 69 74 65 53 74 61 72 74 5d 5b 22  nRewriteStart]["
8d90: 62 49 6d 6d 75 6e 65 22 5d 20 3d 20 54 72 75 65  bImmune"] = True
8da0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
8db0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
8dc0: 20 20 20 66 6f 72 20 69 20 69 6e 20 72 61 6e 67     for i in rang
8dd0: 65 28 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53  e(nTokenRewriteS
8de0: 74 61 72 74 2c 20 6e 54 6f 6b 65 6e 52 65 77 72  tart, nTokenRewr
8df0: 69 74 65 45 6e 64 2b 31 29 3a 0a 20 20 20 20 20  iteEnd+1):.     
8e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
8e10: 65 6c 66 2e 6c 54 6f 6b 65 6e 5b 69 5d 5b 22 62  elf.lToken[i]["b
8e20: 49 6d 6d 75 6e 65 22 5d 20 3d 20 54 72 75 65 0a  Immune"] = True.
8e30: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 57 68          elif sWh
8e40: 61 74 20 3d 3d 20 22 5f 22 3a 0a 20 20 20 20 20  at == "_":.     
8e50: 20 20 20 20 20 20 20 23 20 6e 65 75 74 72 61 6c         # neutral
8e60: 69 7a 65 64 20 74 6f 6b 65 6e 0a 20 20 20 20 20  ized token.     
8e70: 20 20 20 20 20 20 20 69 66 20 6e 54 6f 6b 65 6e         if nToken
8e80: 52 65 77 72 69 74 65 45 6e 64 20 2d 20 6e 54 6f  RewriteEnd - nTo
8e90: 6b 65 6e 52 65 77 72 69 74 65 53 74 61 72 74 20  kenRewriteStart 
8ea0: 3d 3d 20 30 3a 0a 20 20 20 20 20 20 20 20 20 20  == 0:.          
8eb0: 20 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65        self.lToke
8ec0: 6e 5b 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53  n[nTokenRewriteS
8ed0: 74 61 72 74 5d 5b 22 73 4e 65 77 56 61 6c 75 65  tart]["sNewValue
8ee0: 22 5d 20 3d 20 22 5f 22 0a 20 20 20 20 20 20 20  "] = "_".       
8ef0: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
8f00: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 69             for i
8f10: 20 69 6e 20 72 61 6e 67 65 28 6e 54 6f 6b 65 6e   in range(nToken
8f20: 52 65 77 72 69 74 65 53 74 61 72 74 2c 20 6e 54  RewriteStart, nT
8f30: 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e 64 2b 31  okenRewriteEnd+1
8f40: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
8f50: 20 20 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b         self.lTok
8f60: 65 6e 5b 69 5d 5b 22 73 4e 65 77 56 61 6c 75 65  en[i]["sNewValue
8f70: 22 5d 20 3d 20 22 5f 22 0a 20 20 20 20 20 20 20  "] = "_".       
8f80: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
8f90: 20 20 20 69 66 20 73 57 68 61 74 2e 73 74 61 72     if sWhat.star
8fa0: 74 73 77 69 74 68 28 22 3d 22 29 3a 0a 20 20 20  tswith("="):.   
8fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 57 68               sWh
8fc0: 61 74 20 3d 20 67 6c 6f 62 61 6c 73 28 29 5b 73  at = globals()[s
8fd0: 57 68 61 74 5b 31 3a 5d 5d 28 73 65 6c 66 2e 6c  What[1:]](self.l
8fe0: 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 4f 66 66  Token, nTokenOff
8ff0: 73 65 74 29 0a 20 20 20 20 20 20 20 20 20 20 20  set).           
9000: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
9010: 20 20 20 20 20 20 20 73 57 68 61 74 20 3d 20 73         sWhat = s
9020: 65 6c 66 2e 5f 65 78 70 61 6e 64 28 73 57 68 61  elf._expand(sWha
9030: 74 2c 20 6e 54 6f 6b 65 6e 4f 66 66 73 65 74 29  t, nTokenOffset)
9040: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 55 70  .            bUp
9050: 70 65 72 63 61 73 65 20 3d 20 62 55 70 70 65 72  percase = bUpper
9060: 63 61 73 65 20 61 6e 64 20 73 65 6c 66 2e 6c 54  case and self.lT
9070: 6f 6b 65 6e 5b 6e 54 6f 6b 65 6e 52 65 77 72 69  oken[nTokenRewri
9080: 74 65 53 74 61 72 74 5d 5b 22 73 56 61 6c 75 65  teStart]["sValue
9090: 22 5d 5b 30 3a 31 5d 2e 69 73 75 70 70 65 72 28  "][0:1].isupper(
90a0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ).            if
90b0: 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 45 6e   nTokenRewriteEn
90c0: 64 20 2d 20 6e 54 6f 6b 65 6e 52 65 77 72 69 74  d - nTokenRewrit
90d0: 65 53 74 61 72 74 20 3d 3d 20 30 3a 0a 20 20 20  eStart == 0:.   
90e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6f               # o
90f0: 6e 65 20 74 6f 6b 65 6e 0a 20 20 20 20 20 20 20  ne token.       
9100: 20 20 20 20 20 20 20 20 20 73 57 68 61 74 20 3d           sWhat =
9110: 20 73 57 68 61 74 20 2b 20 22 20 22 20 2a 20 28   sWhat + " " * (
9120: 6c 65 6e 28 73 65 6c 66 2e 6c 54 6f 6b 65 6e 5b  len(self.lToken[
9130: 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74 61  nTokenRewriteSta
9140: 72 74 5d 5b 22 73 56 61 6c 75 65 22 5d 29 2d 6c  rt]["sValue"])-l
9150: 65 6e 28 73 57 68 61 74 29 29 0a 20 20 20 20 20  en(sWhat)).     
9160: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 55             if bU
9170: 70 70 65 72 63 61 73 65 3a 0a 20 20 20 20 20 20  ppercase:.      
9180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 57                sW
9190: 68 61 74 20 3d 20 73 57 68 61 74 5b 30 3a 31 5d  hat = sWhat[0:1]
91a0: 2e 75 70 70 65 72 28 29 20 2b 20 73 57 68 61 74  .upper() + sWhat
91b0: 5b 31 3a 5d 0a 20 20 20 20 20 20 20 20 20 20 20  [1:].           
91c0: 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e       self.lToken
91d0: 5b 6e 54 6f 6b 65 6e 52 65 77 72 69 74 65 53 74  [nTokenRewriteSt
91e0: 61 72 74 5d 5b 22 73 4e 65 77 56 61 6c 75 65 22  art]["sNewValue"
91f0: 5d 20 3d 20 73 57 68 61 74 0a 20 20 20 20 20 20  ] = sWhat.      
9200: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
9210: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 73 65              # se
9220: 76 65 72 61 6c 20 74 6f 6b 65 6e 73 0a 20 20 20  veral tokens.   
9230: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 6f               lTo
9240: 6b 65 6e 56 61 6c 75 65 20 3d 20 73 57 68 61 74  kenValue = sWhat
9250: 2e 73 70 6c 69 74 28 22 7c 22 29 0a 20 20 20 20  .split("|").    
9260: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6c              if l
9270: 65 6e 28 6c 54 6f 6b 65 6e 56 61 6c 75 65 29 20  en(lTokenValue) 
9280: 21 3d 20 28 6e 54 6f 6b 65 6e 52 65 77 72 69 74  != (nTokenRewrit
9290: 65 45 6e 64 20 2d 20 6e 54 6f 6b 65 6e 52 65 77  eEnd - nTokenRew
92a0: 72 69 74 65 53 74 61 72 74 20 2b 20 31 29 3a 0a  riteStart + 1):.
92b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
92c0: 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72      print("Error
92d0: 2e 20 54 65 78 74 20 70 72 6f 63 65 73 73 6f 72  . Text processor
92e0: 3a 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 70 6c  : number of repl
92f0: 61 63 65 6d 65 6e 74 73 20 21 3d 20 6e 75 6d 62  acements != numb
9300: 65 72 20 6f 66 20 74 6f 6b 65 6e 73 2e 22 29 0a  er of tokens.").
9310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9320: 20 20 20 20 72 65 74 75 72 6e 0a 20 20 20 20 20      return.     
9330: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 69             for i
9340: 2c 20 73 56 61 6c 75 65 20 69 6e 20 7a 69 70 28  , sValue in zip(
9350: 72 61 6e 67 65 28 6e 54 6f 6b 65 6e 52 65 77 72  range(nTokenRewr
9360: 69 74 65 53 74 61 72 74 2c 20 6e 54 6f 6b 65 6e  iteStart, nToken
9370: 52 65 77 72 69 74 65 45 6e 64 2b 31 29 2c 20 6c  RewriteEnd+1), l
9380: 54 6f 6b 65 6e 56 61 6c 75 65 29 3a 0a 20 20 20  TokenValue):.   
9390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93a0: 20 69 66 20 6e 6f 74 20 73 56 61 6c 75 65 20 6f   if not sValue o
93b0: 72 20 73 56 61 6c 75 65 20 3d 3d 20 22 2a 22 3a  r sValue == "*":
93c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
93d0: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6c 54           self.lT
93e0: 6f 6b 65 6e 5b 69 5d 5b 22 62 54 6f 52 65 6d 6f  oken[i]["bToRemo
93f0: 76 65 22 5d 20 3d 20 54 72 75 65 0a 20 20 20 20  ve"] = True.    
9400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9410: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
9420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
9430: 20 62 55 70 70 65 72 63 61 73 65 3a 0a 20 20 20   bUppercase:.   
9440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9450: 20 20 20 20 20 20 20 20 20 73 56 61 6c 75 65 20           sValue 
9460: 3d 20 73 56 61 6c 75 65 5b 30 3a 31 5d 2e 75 70  = sValue[0:1].up
9470: 70 65 72 28 29 20 2b 20 73 56 61 6c 75 65 5b 31  per() + sValue[1
9480: 3a 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  :].             
9490: 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e             self.
94a0: 6c 54 6f 6b 65 6e 5b 69 5d 5b 22 73 4e 65 77 56  lToken[i]["sNewV
94b0: 61 6c 75 65 22 5d 20 3d 20 73 56 61 6c 75 65 0a  alue"] = sValue.
94c0: 0a 20 20 20 20 64 65 66 20 72 65 77 72 69 74 65  .    def rewrite
94d0: 20 28 73 65 6c 66 2c 20 62 44 65 62 75 67 3d 46   (self, bDebug=F
94e0: 61 6c 73 65 29 3a 0a 20 20 20 20 20 20 20 20 22  alse):.        "
94f0: 72 65 77 72 69 74 65 20 74 68 65 20 73 65 6e 74  rewrite the sent
9500: 65 6e 63 65 2c 20 6d 6f 64 69 66 79 20 74 6f 6b  ence, modify tok
9510: 65 6e 73 2c 20 70 75 72 67 65 20 74 68 65 20 74  ens, purge the t
9520: 6f 6b 65 6e 20 6c 69 73 74 22 0a 20 20 20 20 20  oken list".     
9530: 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20     if bDebug:.  
9540: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
9550: 22 52 45 57 52 49 54 45 22 29 0a 20 20 20 20 20  "REWRITE").     
9560: 20 20 20 6c 4e 65 77 54 6f 6b 65 6e 20 3d 20 5b     lNewToken = [
9570: 5d 0a 20 20 20 20 20 20 20 20 6e 4d 65 72 67 65  ].        nMerge
9580: 55 6e 74 69 6c 20 3d 20 30 0a 20 20 20 20 20 20  Until = 0.      
9590: 20 20 64 54 6f 6b 65 6e 4d 65 72 67 65 72 20 3d    dTokenMerger =
95a0: 20 4e 6f 6e 65 0a 20 20 20 20 20 20 20 20 66 6f   None.        fo
95b0: 72 20 64 54 6f 6b 65 6e 20 69 6e 20 73 65 6c 66  r dToken in self
95c0: 2e 6c 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20  .lToken:.       
95d0: 20 20 20 20 20 62 4b 65 65 70 54 6f 6b 65 6e 20       bKeepToken 
95e0: 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20 20  = True.         
95f0: 20 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73 54     if dToken["sT
9600: 79 70 65 22 5d 20 21 3d 20 22 49 4e 46 4f 22 3a  ype"] != "INFO":
9610: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9620: 20 69 66 20 22 62 49 6d 6d 75 6e 65 22 20 69 6e   if "bImmune" in
9630: 20 64 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20   dToken:.       
9640: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 45 72               nEr
9650: 72 6f 72 53 74 61 72 74 20 3d 20 73 65 6c 66 2e  rorStart = self.
9660: 6e 4f 66 66 73 65 74 57 69 74 68 69 6e 50 61 72  nOffsetWithinPar
9670: 61 67 72 61 70 68 20 2b 20 64 54 6f 6b 65 6e 5b  agraph + dToken[
9680: 22 6e 53 74 61 72 74 22 5d 0a 20 20 20 20 20 20  "nStart"].      
9690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
96a0: 20 6e 45 72 72 6f 72 53 74 61 72 74 20 69 6e 20   nErrorStart in 
96b0: 73 65 6c 66 2e 64 45 72 72 6f 72 3a 0a 20 20 20  self.dError:.   
96c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
96d0: 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a       if bDebug:.
96e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
96f0: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
9700: 74 28 22 69 6d 6d 75 6e 69 74 79 20 2d 3e 20 65  t("immunity -> e
9710: 72 72 6f 72 20 72 65 6d 6f 76 65 64 3a 22 2c 20  rror removed:", 
9720: 73 65 6c 66 2e 64 45 72 72 6f 72 5b 6e 45 72 72  self.dError[nErr
9730: 6f 72 53 74 61 72 74 5d 29 0a 20 20 20 20 20 20  orStart]).      
9740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9750: 20 20 64 65 6c 20 73 65 6c 66 2e 64 45 72 72 6f    del self.dErro
9760: 72 5b 6e 45 72 72 6f 72 53 74 61 72 74 5d 0a 20  r[nErrorStart]. 
9770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69                 i
9780: 66 20 6e 4d 65 72 67 65 55 6e 74 69 6c 20 61 6e  f nMergeUntil an
9790: 64 20 64 54 6f 6b 65 6e 5b 22 69 22 5d 20 3c 3d  d dToken["i"] <=
97a0: 20 6e 4d 65 72 67 65 55 6e 74 69 6c 3a 0a 20 20   nMergeUntil:.  
97b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
97c0: 20 20 64 54 6f 6b 65 6e 4d 65 72 67 65 72 5b 22    dTokenMerger["
97d0: 73 56 61 6c 75 65 22 5d 20 2b 3d 20 22 20 22 20  sValue"] += " " 
97e0: 2a 20 28 64 54 6f 6b 65 6e 5b 22 6e 53 74 61 72  * (dToken["nStar
97f0: 74 22 5d 20 2d 20 64 54 6f 6b 65 6e 4d 65 72 67  t"] - dTokenMerg
9800: 65 72 5b 22 6e 45 6e 64 22 5d 29 20 2b 20 64 54  er["nEnd"]) + dT
9810: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 0a 20  oken["sValue"]. 
9820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9830: 20 20 20 64 54 6f 6b 65 6e 4d 65 72 67 65 72 5b     dTokenMerger[
9840: 22 6e 45 6e 64 22 5d 20 3d 20 64 54 6f 6b 65 6e  "nEnd"] = dToken
9850: 5b 22 6e 45 6e 64 22 5d 0a 20 20 20 20 20 20 20  ["nEnd"].       
9860: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
9870: 62 44 65 62 75 67 3a 0a 20 20 20 20 20 20 20 20  bDebug:.        
9880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9890: 70 72 69 6e 74 28 22 20 20 4d 45 52 47 45 44 20  print("  MERGED 
98a0: 54 4f 4b 45 4e 3a 22 2c 20 64 54 6f 6b 65 6e 4d  TOKEN:", dTokenM
98b0: 65 72 67 65 72 5b 22 73 56 61 6c 75 65 22 5d 29  erger["sValue"])
98c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
98d0: 20 20 20 20 20 62 4b 65 65 70 54 6f 6b 65 6e 20       bKeepToken 
98e0: 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20  = False.        
98f0: 20 20 20 20 20 20 20 20 69 66 20 22 6e 4d 65 72          if "nMer
9900: 67 65 55 6e 74 69 6c 22 20 69 6e 20 64 54 6f 6b  geUntil" in dTok
9910: 65 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  en:.            
9920: 20 20 20 20 20 20 20 20 69 66 20 64 54 6f 6b 65          if dToke
9930: 6e 5b 22 69 22 5d 20 3e 20 6e 4d 65 72 67 65 55  n["i"] > nMergeU
9940: 6e 74 69 6c 3a 20 23 20 74 68 69 73 20 74 6f 6b  ntil: # this tok
9950: 65 6e 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  en is not alread
9960: 79 20 6d 65 72 67 65 64 20 77 69 74 68 20 61 20  y merged with a 
9970: 70 72 65 76 69 6f 75 73 20 74 6f 6b 65 6e 0a 20  previous token. 
9980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9990: 20 20 20 20 20 20 20 64 54 6f 6b 65 6e 4d 65 72         dTokenMer
99a0: 67 65 72 20 3d 20 64 54 6f 6b 65 6e 0a 20 20 20  ger = dToken.   
99b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
99c0: 20 69 66 20 64 54 6f 6b 65 6e 5b 22 6e 4d 65 72   if dToken["nMer
99d0: 67 65 55 6e 74 69 6c 22 5d 20 3e 20 6e 4d 65 72  geUntil"] > nMer
99e0: 67 65 55 6e 74 69 6c 3a 0a 20 20 20 20 20 20 20  geUntil:.       
99f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a00: 20 6e 4d 65 72 67 65 55 6e 74 69 6c 20 3d 20 64   nMergeUntil = d
9a10: 54 6f 6b 65 6e 5b 22 6e 4d 65 72 67 65 55 6e 74  Token["nMergeUnt
9a20: 69 6c 22 5d 0a 20 20 20 20 20 20 20 20 20 20 20  il"].           
9a30: 20 20 20 20 20 20 20 20 20 64 65 6c 20 64 54 6f           del dTo
9a40: 6b 65 6e 5b 22 6e 4d 65 72 67 65 55 6e 74 69 6c  ken["nMergeUntil
9a50: 22 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  "].             
9a60: 20 20 20 65 6c 69 66 20 22 62 54 6f 52 65 6d 6f     elif "bToRemo
9a70: 76 65 22 20 69 6e 20 64 54 6f 6b 65 6e 3a 0a 20  ve" in dToken:. 
9a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a90: 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a 20 20     if bDebug:.  
9aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ab0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 52        print("  R
9ac0: 45 4d 4f 56 45 44 3a 22 2c 20 64 54 6f 6b 65 6e  EMOVED:", dToken
9ad0: 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20  ["sValue"]).    
9ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9af0: 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 20 3d  self.sSentence =
9b00: 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 5b   self.sSentence[
9b10: 3a 64 54 6f 6b 65 6e 5b 22 6e 53 74 61 72 74 22  :dToken["nStart"
9b20: 5d 5d 20 2b 20 22 20 22 20 2a 20 28 64 54 6f 6b  ]] + " " * (dTok
9b30: 65 6e 5b 22 6e 45 6e 64 22 5d 20 2d 20 64 54 6f  en["nEnd"] - dTo
9b40: 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 29 20 2b  ken["nStart"]) +
9b50: 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 5b   self.sSentence[
9b60: 64 54 6f 6b 65 6e 5b 22 6e 45 6e 64 22 5d 3a 5d  dToken["nEnd"]:]
9b70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9b80: 20 20 20 20 20 62 4b 65 65 70 54 6f 6b 65 6e 20       bKeepToken 
9b90: 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20  = False.        
9ba0: 20 20 20 20 23 0a 20 20 20 20 20 20 20 20 20 20      #.          
9bb0: 20 20 69 66 20 62 4b 65 65 70 54 6f 6b 65 6e 3a    if bKeepToken:
9bc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9bd0: 20 6c 4e 65 77 54 6f 6b 65 6e 2e 61 70 70 65 6e   lNewToken.appen
9be0: 64 28 64 54 6f 6b 65 6e 29 0a 20 20 20 20 20 20  d(dToken).      
9bf0: 20 20 20 20 20 20 20 20 20 20 69 66 20 22 73 4e            if "sN
9c00: 65 77 56 61 6c 75 65 22 20 69 6e 20 64 54 6f 6b  ewValue" in dTok
9c10: 65 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  en:.            
9c20: 20 20 20 20 20 20 20 20 23 20 72 65 77 72 69 74          # rewrit
9c30: 65 20 74 6f 6b 65 6e 20 61 6e 64 20 73 65 6e 74  e token and sent
9c40: 65 6e 63 65 0a 20 20 20 20 20 20 20 20 20 20 20  ence.           
9c50: 20 20 20 20 20 20 20 20 20 69 66 20 62 44 65 62           if bDeb
9c60: 75 67 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ug:.            
9c70: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
9c80: 74 28 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65  t(dToken["sValue
9c90: 22 5d 2c 20 22 2d 3e 22 2c 20 64 54 6f 6b 65 6e  "], "->", dToken
9ca0: 5b 22 73 4e 65 77 56 61 6c 75 65 22 5d 29 0a 20  ["sNewValue"]). 
9cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9cc0: 20 20 20 64 54 6f 6b 65 6e 5b 22 73 52 65 61 6c     dToken["sReal
9cd0: 56 61 6c 75 65 22 5d 20 3d 20 64 54 6f 6b 65 6e  Value"] = dToken
9ce0: 5b 22 73 56 61 6c 75 65 22 5d 0a 20 20 20 20 20  ["sValue"].     
9cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
9d00: 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 20  Token["sValue"] 
9d10: 3d 20 64 54 6f 6b 65 6e 5b 22 73 4e 65 77 56 61  = dToken["sNewVa
9d20: 6c 75 65 22 5d 0a 20 20 20 20 20 20 20 20 20 20  lue"].          
9d30: 20 20 20 20 20 20 20 20 20 20 6e 44 69 66 66 4c            nDiffL
9d40: 65 6e 20 3d 20 6c 65 6e 28 64 54 6f 6b 65 6e 5b  en = len(dToken[
9d50: 22 73 52 65 61 6c 56 61 6c 75 65 22 5d 29 20 2d  "sRealValue"]) -
9d60: 20 6c 65 6e 28 64 54 6f 6b 65 6e 5b 22 73 4e 65   len(dToken["sNe
9d70: 77 56 61 6c 75 65 22 5d 29 0a 20 20 20 20 20 20  wValue"]).      
9d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 4e                sN
9d90: 65 77 52 65 70 6c 20 3d 20 28 64 54 6f 6b 65 6e  ewRepl = (dToken
9da0: 5b 22 73 4e 65 77 56 61 6c 75 65 22 5d 20 2b 20  ["sNewValue"] + 
9db0: 22 20 22 20 2a 20 6e 44 69 66 66 4c 65 6e 29 20  " " * nDiffLen) 
9dc0: 20 69 66 20 6e 44 69 66 66 4c 65 6e 20 3e 3d 20   if nDiffLen >= 
9dd0: 30 20 20 65 6c 73 65 20 64 54 6f 6b 65 6e 5b 22  0  else dToken["
9de0: 73 4e 65 77 56 61 6c 75 65 22 5d 5b 3a 6c 65 6e  sNewValue"][:len
9df0: 28 64 54 6f 6b 65 6e 5b 22 73 52 65 61 6c 56 61  (dToken["sRealVa
9e00: 6c 75 65 22 5d 29 5d 0a 20 20 20 20 20 20 20 20  lue"])].        
9e10: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66              self
9e20: 2e 73 53 65 6e 74 65 6e 63 65 20 3d 20 73 65 6c  .sSentence = sel
9e30: 66 2e 73 53 65 6e 74 65 6e 63 65 5b 3a 64 54 6f  f.sSentence[:dTo
9e40: 6b 65 6e 5b 22 6e 53 74 61 72 74 22 5d 5d 20 2b  ken["nStart"]] +
9e50: 20 73 4e 65 77 52 65 70 6c 20 2b 20 73 65 6c 66   sNewRepl + self
9e60: 2e 73 53 65 6e 74 65 6e 63 65 5b 64 54 6f 6b 65  .sSentence[dToke
9e70: 6e 5b 22 6e 45 6e 64 22 5d 3a 5d 0a 20 20 20 20  n["nEnd"]:].    
9e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9e90: 64 65 6c 20 64 54 6f 6b 65 6e 5b 22 73 4e 65 77  del dToken["sNew
9ea0: 56 61 6c 75 65 22 5d 0a 20 20 20 20 20 20 20 20  Value"].        
9eb0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
9ec0: 20 20 20 20 20 20 20 20 20 20 74 72 79 3a 0a 20            try:. 
9ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ee0: 20 20 20 64 65 6c 20 73 65 6c 66 2e 64 54 6f 6b     del self.dTok
9ef0: 65 6e 50 6f 73 5b 64 54 6f 6b 65 6e 5b 22 6e 53  enPos[dToken["nS
9f00: 74 61 72 74 22 5d 5d 0a 20 20 20 20 20 20 20 20  tart"]].        
9f10: 20 20 20 20 20 20 20 20 65 78 63 65 70 74 3a 0a          except:.
9f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9f30: 20 20 20 20 70 72 69 6e 74 28 73 65 6c 66 29 0a      print(self).
9f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9f50: 20 20 20 20 70 72 69 6e 74 28 64 54 6f 6b 65 6e      print(dToken
9f60: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
9f70: 20 20 20 20 20 20 65 78 69 74 28 29 0a 20 20 20        exit().   
9f80: 20 20 20 20 20 69 66 20 62 44 65 62 75 67 3a 0a       if bDebug:.
9f90: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
9fa0: 74 28 22 20 20 52 45 57 52 49 54 45 44 3a 22 2c  t("  REWRITED:",
9fb0: 20 73 65 6c 66 2e 73 53 65 6e 74 65 6e 63 65 29   self.sSentence)
9fc0: 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6c 54  .        self.lT
9fd0: 6f 6b 65 6e 2e 63 6c 65 61 72 28 29 0a 20 20 20  oken.clear().   
9fe0: 20 20 20 20 20 73 65 6c 66 2e 6c 54 6f 6b 65 6e       self.lToken
9ff0: 20 3d 20 6c 4e 65 77 54 6f 6b 65 6e 0a 0a 0a 0a   = lNewToken....
a000: 23 23 23 23 20 41 6e 61 6c 79 73 65 20 74 6f 6b  #### Analyse tok
a010: 65 6e 73 0a 0a 64 65 66 20 67 5f 76 61 6c 75 65  ens..def g_value
a020: 20 28 64 54 6f 6b 65 6e 2c 20 73 56 61 6c 75 65   (dToken, sValue
a030: 73 2c 20 6e 4c 65 66 74 3d 4e 6f 6e 65 2c 20 6e  s, nLeft=None, n
a040: 52 69 67 68 74 3d 4e 6f 6e 65 29 3a 0a 20 20 20  Right=None):.   
a050: 20 22 74 65 73 74 20 69 66 20 3c 64 54 6f 6b 65   "test if <dToke
a060: 6e 5b 27 73 56 61 6c 75 65 27 5d 3e 20 69 73 20  n['sValue']> is 
a070: 69 6e 20 73 56 61 6c 75 65 73 20 28 65 61 63 68  in sValues (each
a080: 20 76 61 6c 75 65 20 73 68 6f 75 6c 64 20 62 65   value should be
a090: 20 73 65 70 61 72 61 74 65 64 20 77 69 74 68 20   separated with 
a0a0: 7c 29 22 0a 20 20 20 20 73 56 61 6c 75 65 20 3d  |)".    sValue =
a0b0: 20 22 7c 22 2b 64 54 6f 6b 65 6e 5b 22 73 56 61   "|"+dToken["sVa
a0c0: 6c 75 65 22 5d 2b 22 7c 22 20 20 69 66 20 6e 4c  lue"]+"|"  if nL
a0d0: 65 66 74 20 69 73 20 4e 6f 6e 65 20 20 65 6c 73  eft is None  els
a0e0: 65 20 22 7c 22 2b 64 54 6f 6b 65 6e 5b 22 73 56  e "|"+dToken["sV
a0f0: 61 6c 75 65 22 5d 5b 73 6c 69 63 65 28 6e 4c 65  alue"][slice(nLe
a100: 66 74 2c 20 6e 52 69 67 68 74 29 5d 2b 22 7c 22  ft, nRight)]+"|"
a110: 0a 20 20 20 20 69 66 20 73 56 61 6c 75 65 20 69  .    if sValue i
a120: 6e 20 73 56 61 6c 75 65 73 3a 0a 20 20 20 20 20  n sValues:.     
a130: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20     return True. 
a140: 20 20 20 69 66 20 64 54 6f 6b 65 6e 5b 22 73 56     if dToken["sV
a150: 61 6c 75 65 22 5d 5b 30 3a 32 5d 2e 69 73 74 69  alue"][0:2].isti
a160: 74 6c 65 28 29 3a 20 23 20 77 65 20 74 65 73 74  tle(): # we test
a170: 20 6f 6e 6c 79 20 32 20 66 69 72 73 74 20 63 68   only 2 first ch
a180: 61 72 73 2c 20 74 6f 20 6d 61 6b 65 20 76 61 6c  ars, to make val
a190: 69 64 20 77 6f 72 64 73 20 73 75 63 68 20 61 73  id words such as
a1a0: 20 22 4c 61 69 73 73 65 7a 2d 6c 65 73 22 2c 20   "Laissez-les", 
a1b0: 22 50 61 73 73 65 2d 70 61 72 74 6f 75 74 22 2e  "Passe-partout".
a1c0: 0a 20 20 20 20 20 20 20 20 69 66 20 73 56 61 6c  .        if sVal
a1d0: 75 65 2e 6c 6f 77 65 72 28 29 20 69 6e 20 73 56  ue.lower() in sV
a1e0: 61 6c 75 65 73 3a 0a 20 20 20 20 20 20 20 20 20  alues:.         
a1f0: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20     return True. 
a200: 20 20 20 65 6c 69 66 20 64 54 6f 6b 65 6e 5b 22     elif dToken["
a210: 73 56 61 6c 75 65 22 5d 2e 69 73 75 70 70 65 72  sValue"].isupper
a220: 28 29 3a 0a 20 20 20 20 20 20 20 20 23 69 66 20  ():.        #if 
a230: 73 56 61 6c 75 65 2e 6c 6f 77 65 72 28 29 20 69  sValue.lower() i
a240: 6e 20 73 56 61 6c 75 65 73 3a 0a 20 20 20 20 20  n sValues:.     
a250: 20 20 20 23 20 20 20 20 72 65 74 75 72 6e 20 54     #    return T
a260: 72 75 65 0a 20 20 20 20 20 20 20 20 73 56 61 6c  rue.        sVal
a270: 75 65 20 3d 20 22 7c 22 2b 73 56 61 6c 75 65 5b  ue = "|"+sValue[
a280: 31 3a 5d 2e 63 61 70 69 74 61 6c 69 7a 65 28 29  1:].capitalize()
a290: 0a 20 20 20 20 20 20 20 20 69 66 20 73 56 61 6c  .        if sVal
a2a0: 75 65 2e 63 61 70 69 74 61 6c 69 7a 65 28 29 20  ue.capitalize() 
a2b0: 69 6e 20 73 56 61 6c 75 65 73 3a 0a 20 20 20 20  in sValues:.    
a2c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
a2d0: 72 75 65 0a 20 20 20 20 72 65 74 75 72 6e 20 46  rue.    return F
a2e0: 61 6c 73 65 0a 0a 0a 64 65 66 20 67 5f 6d 6f 72  alse...def g_mor
a2f0: 70 68 20 28 64 54 6f 6b 65 6e 2c 20 73 50 61 74  ph (dToken, sPat
a300: 74 65 72 6e 2c 20 73 4e 65 67 50 61 74 74 65 72  tern, sNegPatter
a310: 6e 3d 22 22 2c 20 6e 4c 65 66 74 3d 4e 6f 6e 65  n="", nLeft=None
a320: 2c 20 6e 52 69 67 68 74 3d 4e 6f 6e 65 2c 20 62  , nRight=None, b
a330: 4d 65 6d 6f 72 69 7a 65 4d 6f 72 70 68 3d 54 72  MemorizeMorph=Tr
a340: 75 65 29 3a 0a 20 20 20 20 22 61 6e 61 6c 79 73  ue):.    "analys
a350: 65 20 61 20 74 6f 6b 65 6e 2c 20 72 65 74 75 72  e a token, retur
a360: 6e 20 54 72 75 65 20 69 66 20 3c 73 4e 65 67 50  n True if <sNegP
a370: 61 74 74 65 72 6e 3e 20 6e 6f 74 20 69 6e 20 6d  attern> not in m
a380: 6f 72 70 68 6f 6c 6f 67 69 65 73 20 61 6e 64 20  orphologies and 
a390: 3c 73 50 61 74 74 65 72 6e 3e 20 69 6e 20 6d 6f  <sPattern> in mo
a3a0: 72 70 68 6f 6c 6f 67 69 65 73 22 0a 20 20 20 20  rphologies".    
a3b0: 69 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e 20 64  if "lMorph" in d
a3c0: 54 6f 6b 65 6e 3a 0a 20 20 20 20 20 20 20 20 6c  Token:.        l
a3d0: 4d 6f 72 70 68 20 3d 20 64 54 6f 6b 65 6e 5b 22  Morph = dToken["
a3e0: 6c 4d 6f 72 70 68 22 5d 0a 20 20 20 20 65 6c 73  lMorph"].    els
a3f0: 65 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e 4c  e:.        if nL
a400: 65 66 74 20 69 73 20 6e 6f 74 20 4e 6f 6e 65 3a  eft is not None:
a410: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 4d 6f  .            lMo
a420: 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65  rph = _oSpellChe
a430: 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54  cker.getMorph(dT
a440: 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d 5b 73  oken["sValue"][s
a450: 6c 69 63 65 28 6e 4c 65 66 74 2c 20 6e 52 69 67  lice(nLeft, nRig
a460: 68 74 29 5d 29 0a 20 20 20 20 20 20 20 20 20 20  ht)]).          
a470: 20 20 69 66 20 62 4d 65 6d 6f 72 69 7a 65 4d 6f    if bMemorizeMo
a480: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rph:.           
a490: 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f       dToken["lMo
a4a0: 72 70 68 22 5d 20 3d 20 6c 4d 6f 72 70 68 0a 20  rph"] = lMorph. 
a4b0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
a4c0: 20 20 20 20 20 20 20 20 20 6c 4d 6f 72 70 68 20           lMorph 
a4d0: 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  = _oSpellChecker
a4e0: 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e  .getMorph(dToken
a4f0: 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20  ["sValue"]).    
a500: 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70      if not lMorp
a510: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  h:.            r
a520: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
a530: 23 20 63 68 65 63 6b 20 6e 65 67 61 74 69 76 65  # check negative
a540: 20 63 6f 6e 64 69 74 69 6f 6e 0a 20 20 20 20 69   condition.    i
a550: 66 20 73 4e 65 67 50 61 74 74 65 72 6e 3a 0a 20  f sNegPattern:. 
a560: 20 20 20 20 20 20 20 69 66 20 73 4e 65 67 50 61         if sNegPa
a570: 74 74 65 72 6e 20 3d 3d 20 22 2a 22 3a 0a 20 20  ttern == "*":.  
a580: 20 20 20 20 20 20 20 20 20 20 23 20 61 6c 6c 20            # all 
a590: 6d 6f 72 70 68 20 6d 75 73 74 20 6d 61 74 63 68  morph must match
a5a0: 20 73 50 61 74 74 65 72 6e 0a 20 20 20 20 20 20   sPattern.      
a5b0: 20 20 20 20 20 20 69 66 20 6e 6f 74 20 6c 4d 6f        if not lMo
a5c0: 72 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  rph:.           
a5d0: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
a5e0: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 7a 50  e.            zP
a5f0: 61 74 74 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70  attern = re.comp
a600: 69 6c 65 28 73 50 61 74 74 65 72 6e 29 0a 20 20  ile(sPattern).  
a610: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
a620: 20 61 6c 6c 28 7a 50 61 74 74 65 72 6e 2e 73 65   all(zPattern.se
a630: 61 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f  arch(sMorph)  fo
a640: 72 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72  r sMorph in lMor
a650: 70 68 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  ph).        else
a660: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 7a 4e  :.            zN
a670: 65 67 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63  egPattern = re.c
a680: 6f 6d 70 69 6c 65 28 73 4e 65 67 50 61 74 74 65  ompile(sNegPatte
a690: 72 6e 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  rn).            
a6a0: 69 66 20 61 6e 79 28 7a 4e 65 67 50 61 74 74 65  if any(zNegPatte
a6b0: 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70 68  rn.search(sMorph
a6c0: 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  )  for sMorph in
a6d0: 20 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20   lMorph):.      
a6e0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
a6f0: 20 46 61 6c 73 65 0a 20 20 20 20 23 20 73 65 61   False.    # sea
a700: 72 63 68 20 73 50 61 74 74 65 72 6e 0a 20 20 20  rch sPattern.   
a710: 20 7a 50 61 74 74 65 72 6e 20 3d 20 72 65 2e 63   zPattern = re.c
a720: 6f 6d 70 69 6c 65 28 73 50 61 74 74 65 72 6e 29  ompile(sPattern)
a730: 0a 20 20 20 20 72 65 74 75 72 6e 20 61 6e 79 28  .    return any(
a740: 7a 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28  zPattern.search(
a750: 73 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f  sMorph)  for sMo
a760: 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 0a  rph in lMorph)..
a770: 0a 64 65 66 20 67 5f 61 6e 61 6c 79 73 65 20 28  .def g_analyse (
a780: 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e  dToken, sPattern
a790: 2c 20 73 4e 65 67 50 61 74 74 65 72 6e 3d 22 22  , sNegPattern=""
a7a0: 2c 20 6e 4c 65 66 74 3d 4e 6f 6e 65 2c 20 6e 52  , nLeft=None, nR
a7b0: 69 67 68 74 3d 4e 6f 6e 65 2c 20 62 4d 65 6d 6f  ight=None, bMemo
a7c0: 72 69 7a 65 4d 6f 72 70 68 3d 54 72 75 65 29 3a  rizeMorph=True):
a7d0: 0a 20 20 20 20 22 61 6e 61 6c 79 73 65 20 61 20  .    "analyse a 
a7e0: 74 6f 6b 65 6e 2c 20 72 65 74 75 72 6e 20 54 72  token, return Tr
a7f0: 75 65 20 69 66 20 3c 73 4e 65 67 50 61 74 74 65  ue if <sNegPatte
a800: 72 6e 3e 20 6e 6f 74 20 69 6e 20 6d 6f 72 70 68  rn> not in morph
a810: 6f 6c 6f 67 69 65 73 20 61 6e 64 20 3c 73 50 61  ologies and <sPa
a820: 74 74 65 72 6e 3e 20 69 6e 20 6d 6f 72 70 68 6f  ttern> in morpho
a830: 6c 6f 67 69 65 73 20 28 64 69 73 61 6d 62 69 67  logies (disambig
a840: 75 61 74 69 6f 6e 20 6f 66 66 29 22 0a 20 20 20  uation off)".   
a850: 20 69 66 20 6e 4c 65 66 74 20 69 73 20 6e 6f 74   if nLeft is not
a860: 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 20 20 6c   None:.        l
a870: 4d 6f 72 70 68 20 3d 20 5f 6f 53 70 65 6c 6c 43  Morph = _oSpellC
a880: 68 65 63 6b 65 72 2e 67 65 74 4d 6f 72 70 68 28  hecker.getMorph(
a890: 64 54 6f 6b 65 6e 5b 22 73 56 61 6c 75 65 22 5d  dToken["sValue"]
a8a0: 5b 73 6c 69 63 65 28 6e 4c 65 66 74 2c 20 6e 52  [slice(nLeft, nR
a8b0: 69 67 68 74 29 5d 29 0a 20 20 20 20 20 20 20 20  ight)]).        
a8c0: 69 66 20 62 4d 65 6d 6f 72 69 7a 65 4d 6f 72 70  if bMemorizeMorp
a8d0: 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 64  h:.            d
a8e0: 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20  Token["lMorph"] 
a8f0: 3d 20 6c 4d 6f 72 70 68 0a 20 20 20 20 65 6c 73  = lMorph.    els
a900: 65 3a 0a 20 20 20 20 20 20 20 20 6c 4d 6f 72 70  e:.        lMorp
a910: 68 20 3d 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b  h = _oSpellCheck
a920: 65 72 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b  er.getMorph(dTok
a930: 65 6e 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20  en["sValue"]).  
a940: 20 20 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a    if not lMorph:
a950: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
a960: 46 61 6c 73 65 0a 20 20 20 20 23 20 63 68 65 63  False.    # chec
a970: 6b 20 6e 65 67 61 74 69 76 65 20 63 6f 6e 64 69  k negative condi
a980: 74 69 6f 6e 0a 20 20 20 20 69 66 20 73 4e 65 67  tion.    if sNeg
a990: 50 61 74 74 65 72 6e 3a 0a 20 20 20 20 20 20 20  Pattern:.       
a9a0: 20 69 66 20 73 4e 65 67 50 61 74 74 65 72 6e 20   if sNegPattern 
a9b0: 3d 3d 20 22 2a 22 3a 0a 20 20 20 20 20 20 20 20  == "*":.        
a9c0: 20 20 20 20 23 20 61 6c 6c 20 6d 6f 72 70 68 20      # all morph 
a9d0: 6d 75 73 74 20 6d 61 74 63 68 20 73 50 61 74 74  must match sPatt
a9e0: 65 72 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20  ern.            
a9f0: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 3a 0a 20  if not lMorph:. 
aa00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72                 r
aa10: 65 74 75 72 6e 20 46 61 6c 73 65 0a 20 20 20 20  eturn False.    
aa20: 20 20 20 20 20 20 20 20 7a 50 61 74 74 65 72 6e          zPattern
aa30: 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73 50   = re.compile(sP
aa40: 61 74 74 65 72 6e 29 0a 20 20 20 20 20 20 20 20  attern).        
aa50: 20 20 20 20 72 65 74 75 72 6e 20 61 6c 6c 28 7a      return all(z
aa60: 50 61 74 74 65 72 6e 2e 73 65 61 72 63 68 28 73  Pattern.search(s
aa70: 4d 6f 72 70 68 29 20 20 66 6f 72 20 73 4d 6f 72  Morph)  for sMor
aa80: 70 68 20 69 6e 20 6c 4d 6f 72 70 68 29 0a 20 20  ph in lMorph).  
aa90: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
aaa0: 20 20 20 20 20 20 20 20 7a 4e 65 67 50 61 74 74          zNegPatt
aab0: 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ern = re.compile
aac0: 28 73 4e 65 67 50 61 74 74 65 72 6e 29 0a 20 20  (sNegPattern).  
aad0: 20 20 20 20 20 20 20 20 20 20 69 66 20 61 6e 79            if any
aae0: 28 7a 4e 65 67 50 61 74 74 65 72 6e 2e 73 65 61  (zNegPattern.sea
aaf0: 72 63 68 28 73 4d 6f 72 70 68 29 20 20 66 6f 72  rch(sMorph)  for
ab00: 20 73 4d 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70   sMorph in lMorp
ab10: 68 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  h):.            
ab20: 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73 65      return False
ab30: 0a 20 20 20 20 23 20 73 65 61 72 63 68 20 73 50  .    # search sP
ab40: 61 74 74 65 72 6e 0a 20 20 20 20 7a 50 61 74 74  attern.    zPatt
ab50: 65 72 6e 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65  ern = re.compile
ab60: 28 73 50 61 74 74 65 72 6e 29 0a 20 20 20 20 72  (sPattern).    r
ab70: 65 74 75 72 6e 20 61 6e 79 28 7a 50 61 74 74 65  eturn any(zPatte
ab80: 72 6e 2e 73 65 61 72 63 68 28 73 4d 6f 72 70 68  rn.search(sMorph
ab90: 29 20 20 66 6f 72 20 73 4d 6f 72 70 68 20 69 6e  )  for sMorph in
aba0: 20 6c 4d 6f 72 70 68 29 0a 0a 0a 64 65 66 20 67   lMorph)...def g
abb0: 5f 74 61 67 5f 62 65 66 6f 72 65 20 28 64 54 6f  _tag_before (dTo
abc0: 6b 65 6e 2c 20 64 54 61 67 73 2c 20 73 54 61 67  ken, dTags, sTag
abd0: 29 3a 0a 20 20 20 20 69 66 20 73 54 61 67 20 6e  ):.    if sTag n
abe0: 6f 74 20 69 6e 20 64 54 61 67 73 3a 0a 20 20 20  ot in dTags:.   
abf0: 20 20 20 20 20 72 65 74 75 72 6e 20 46 61 6c 73       return Fals
ac00: 65 0a 20 20 20 20 69 66 20 64 54 6f 6b 65 6e 5b  e.    if dToken[
ac10: 22 69 22 5d 20 3e 20 64 54 61 67 73 5b 73 54 61  "i"] > dTags[sTa
ac20: 67 5d 5b 30 5d 3a 0a 20 20 20 20 20 20 20 20 72  g][0]:.        r
ac30: 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20 20 72  eturn True.    r
ac40: 65 74 75 72 6e 20 46 61 6c 73 65 0a 0a 0a 64 65  eturn False...de
ac50: 66 20 67 5f 74 61 67 5f 61 66 74 65 72 20 28 64  f g_tag_after (d
ac60: 54 6f 6b 65 6e 2c 20 64 54 61 67 73 2c 20 73 54  Token, dTags, sT
ac70: 61 67 29 3a 0a 20 20 20 20 69 66 20 73 54 61 67  ag):.    if sTag
ac80: 20 6e 6f 74 20 69 6e 20 64 54 61 67 73 3a 0a 20   not in dTags:. 
ac90: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 46 61         return Fa
aca0: 6c 73 65 0a 20 20 20 20 69 66 20 64 54 6f 6b 65  lse.    if dToke
acb0: 6e 5b 22 69 22 5d 20 3c 20 64 54 61 67 73 5b 73  n["i"] < dTags[s
acc0: 54 61 67 5d 5b 31 5d 3a 0a 20 20 20 20 20 20 20  Tag][1]:.       
acd0: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20 20   return True.   
ace0: 20 72 65 74 75 72 6e 20 46 61 6c 73 65 0a 0a 0a   return False...
acf0: 23 23 23 23 20 44 69 73 61 6d 62 69 67 75 61 74  #### Disambiguat
ad00: 6f 72 0a 0a 64 65 66 20 67 5f 73 65 6c 65 63 74  or..def g_select
ad10: 20 28 64 54 6f 6b 65 6e 2c 20 73 50 61 74 74 65   (dToken, sPatte
ad20: 72 6e 2c 20 6c 44 65 66 61 75 6c 74 3d 4e 6f 6e  rn, lDefault=Non
ad30: 65 29 3a 0a 20 20 20 20 22 73 65 6c 65 63 74 20  e):.    "select 
ad40: 6d 6f 72 70 68 6f 6c 6f 67 69 65 73 20 66 6f 72  morphologies for
ad50: 20 3c 64 54 6f 6b 65 6e 3e 20 61 63 63 6f 72 64   <dToken> accord
ad60: 69 6e 67 20 74 6f 20 3c 73 50 61 74 74 65 72 6e  ing to <sPattern
ad70: 3e 2c 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e  >, always return
ad80: 20 54 72 75 65 22 0a 20 20 20 20 6c 4d 6f 72 70   True".    lMorp
ad90: 68 20 3d 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72  h = dToken["lMor
ada0: 70 68 22 5d 20 20 69 66 20 22 6c 4d 6f 72 70 68  ph"]  if "lMorph
adb0: 22 20 69 6e 20 64 54 6f 6b 65 6e 20 20 65 6c 73  " in dToken  els
adc0: 65 20 5f 6f 53 70 65 6c 6c 43 68 65 63 6b 65 72  e _oSpellChecker
add0: 2e 67 65 74 4d 6f 72 70 68 28 64 54 6f 6b 65 6e  .getMorph(dToken
ade0: 5b 22 73 56 61 6c 75 65 22 5d 29 0a 20 20 20 20  ["sValue"]).    
adf0: 69 66 20 6e 6f 74 20 6c 4d 6f 72 70 68 20 6f 72  if not lMorph or
ae00: 20 6c 65 6e 28 6c 4d 6f 72 70 68 29 20 3d 3d 20   len(lMorph) == 
ae10: 31 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6c 44  1:.        if lD
ae20: 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20 20  efault:.        
ae30: 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72      dToken["lMor
ae40: 70 68 22 5d 20 3d 20 6c 44 65 66 61 75 6c 74 0a  ph"] = lDefault.
ae50: 20 20 20 20 20 20 20 20 20 20 20 20 23 70 72 69              #pri
ae60: 6e 74 28 22 44 41 3a 22 2c 20 64 54 6f 6b 65 6e  nt("DA:", dToken
ae70: 5b 22 73 56 61 6c 75 65 22 5d 2c 20 64 54 6f 6b  ["sValue"], dTok
ae80: 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d 29 0a 20 20  en["lMorph"]).  
ae90: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 72 75        return Tru
aea0: 65 0a 20 20 20 20 6c 53 65 6c 65 63 74 20 3d 20  e.    lSelect = 
aeb0: 5b 20 73 4d 6f 72 70 68 20 20 66 6f 72 20 73 4d  [ sMorph  for sM
aec0: 6f 72 70 68 20 69 6e 20 6c 4d 6f 72 70 68 20 20  orph in lMorph  
aed0: 69 66 20 72 65 2e 73 65 61 72 63 68 28 73 50 61  if re.search(sPa
aee0: 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20 5d  ttern, sMorph) ]
aef0: 0a 20 20 20 20 69 66 20 6c 53 65 6c 65 63 74 3a  .    if lSelect:
af00: 0a 20 20 20 20 20 20 20 20 69 66 20 6c 65 6e 28  .        if len(
af10: 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c 65 6e 28  lSelect) != len(
af20: 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20 20  lMorph):.       
af30: 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f       dToken["lMo
af40: 72 70 68 22 5d 20 3d 20 6c 53 65 6c 65 63 74 0a  rph"] = lSelect.
af50: 20 20 20 20 65 6c 69 66 20 6c 44 65 66 61 75 6c      elif lDefaul
af60: 74 3a 0a 20 20 20 20 20 20 20 20 64 54 6f 6b 65  t:.        dToke
af70: 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 44  n["lMorph"] = lD
af80: 65 66 61 75 6c 74 0a 20 20 20 20 23 70 72 69 6e  efault.    #prin
af90: 74 28 22 44 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b  t("DA:", dToken[
afa0: 22 73 56 61 6c 75 65 22 5d 2c 20 64 54 6f 6b 65  "sValue"], dToke
afb0: 6e 5b 22 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20  n["lMorph"]).   
afc0: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64   return True...d
afd0: 65 66 20 67 5f 65 78 63 6c 75 64 65 20 28 64 54  ef g_exclude (dT
afe0: 6f 6b 65 6e 2c 20 73 50 61 74 74 65 72 6e 2c 20  oken, sPattern, 
aff0: 6c 44 65 66 61 75 6c 74 3d 4e 6f 6e 65 29 3a 0a  lDefault=None):.
b000: 20 20 20 20 22 73 65 6c 65 63 74 20 6d 6f 72 70      "select morp
b010: 68 6f 6c 6f 67 69 65 73 20 66 6f 72 20 3c 64 54  hologies for <dT
b020: 6f 6b 65 6e 3e 20 61 63 63 6f 72 64 69 6e 67 20  oken> according 
b030: 74 6f 20 3c 73 50 61 74 74 65 72 6e 3e 2c 20 61  to <sPattern>, a
b040: 6c 77 61 79 73 20 72 65 74 75 72 6e 20 54 72 75  lways return Tru
b050: 65 22 0a 20 20 20 20 6c 4d 6f 72 70 68 20 3d 20  e".    lMorph = 
b060: 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d  dToken["lMorph"]
b070: 20 20 69 66 20 22 6c 4d 6f 72 70 68 22 20 69 6e    if "lMorph" in
b080: 20 64 54 6f 6b 65 6e 20 20 65 6c 73 65 20 5f 6f   dToken  else _o
b090: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 67 65 74  SpellChecker.get
b0a0: 4d 6f 72 70 68 28 64 54 6f 6b 65 6e 5b 22 73 56  Morph(dToken["sV
b0b0: 61 6c 75 65 22 5d 29 0a 20 20 20 20 69 66 20 6e  alue"]).    if n
b0c0: 6f 74 20 6c 4d 6f 72 70 68 20 6f 72 20 6c 65 6e  ot lMorph or len
b0d0: 28 6c 4d 6f 72 70 68 29 20 3d 3d 20 31 3a 0a 20  (lMorph) == 1:. 
b0e0: 20 20 20 20 20 20 20 69 66 20 6c 44 65 66 61 75         if lDefau
b0f0: 6c 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  lt:.            
b100: 64 54 6f 6b 65 6e 5b 22 6c 4d 6f 72 70 68 22 5d  dToken["lMorph"]
b110: 20 3d 20 6c 44 65 66 61 75 6c 74 0a 20 20 20 20   = lDefault.    
b120: 20 20 20 20 20 20 20 20 23 70 72 69 6e 74 28 22          #print("
b130: 44 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56  DA:", dToken["sV
b140: 61 6c 75 65 22 5d 2c 20 64 54 6f 6b 65 6e 5b 22  alue"], dToken["
b150: 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20 20 20 20  lMorph"]).      
b160: 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 20 20    return True.  
b170: 20 20 6c 53 65 6c 65 63 74 20 3d 20 5b 20 73 4d    lSelect = [ sM
b180: 6f 72 70 68 20 20 66 6f 72 20 73 4d 6f 72 70 68  orph  for sMorph
b190: 20 69 6e 20 6c 4d 6f 72 70 68 20 20 69 66 20 6e   in lMorph  if n
b1a0: 6f 74 20 72 65 2e 73 65 61 72 63 68 28 73 50 61  ot re.search(sPa
b1b0: 74 74 65 72 6e 2c 20 73 4d 6f 72 70 68 29 20 5d  ttern, sMorph) ]
b1c0: 0a 20 20 20 20 69 66 20 6c 53 65 6c 65 63 74 3a  .    if lSelect:
b1d0: 0a 20 20 20 20 20 20 20 20 69 66 20 6c 65 6e 28  .        if len(
b1e0: 6c 53 65 6c 65 63 74 29 20 21 3d 20 6c 65 6e 28  lSelect) != len(
b1f0: 6c 4d 6f 72 70 68 29 3a 0a 20 20 20 20 20 20 20  lMorph):.       
b200: 20 20 20 20 20 64 54 6f 6b 65 6e 5b 22 6c 4d 6f       dToken["lMo
b210: 72 70 68 22 5d 20 3d 20 6c 53 65 6c 65 63 74 0a  rph"] = lSelect.
b220: 20 20 20 20 65 6c 69 66 20 6c 44 65 66 61 75 6c      elif lDefaul
b230: 74 3a 0a 20 20 20 20 20 20 20 20 64 54 6f 6b 65  t:.        dToke
b240: 6e 5b 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 44  n["lMorph"] = lD
b250: 65 66 61 75 6c 74 0a 20 20 20 20 23 70 72 69 6e  efault.    #prin
b260: 74 28 22 44 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b  t("DA:", dToken[
b270: 22 73 56 61 6c 75 65 22 5d 2c 20 64 54 6f 6b 65  "sValue"], dToke
b280: 6e 5b 22 6c 4d 6f 72 70 68 22 5d 29 0a 20 20 20  n["lMorph"]).   
b290: 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a 0a 64   return True...d
b2a0: 65 66 20 67 5f 64 65 66 69 6e 65 20 28 64 54 6f  ef g_define (dTo
b2b0: 6b 65 6e 2c 20 6c 4d 6f 72 70 68 29 3a 0a 20 20  ken, lMorph):.  
b2c0: 20 20 22 73 65 74 20 6d 6f 72 70 68 6f 6c 6f 67    "set morpholog
b2d0: 69 65 73 20 6f 66 20 3c 64 54 6f 6b 65 6e 3e 2c  ies of <dToken>,
b2e0: 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e 20 54   always return T
b2f0: 72 75 65 22 0a 20 20 20 20 64 54 6f 6b 65 6e 5b  rue".    dToken[
b300: 22 6c 4d 6f 72 70 68 22 5d 20 3d 20 6c 4d 6f 72  "lMorph"] = lMor
b310: 70 68 0a 20 20 20 20 23 70 72 69 6e 74 28 22 44  ph.    #print("D
b320: 41 3a 22 2c 20 64 54 6f 6b 65 6e 5b 22 73 56 61  A:", dToken["sVa
b330: 6c 75 65 22 5d 2c 20 6c 4d 6f 72 70 68 29 0a 20  lue"], lMorph). 
b340: 20 20 20 72 65 74 75 72 6e 20 54 72 75 65 0a 0a     return True..
b350: 0a 0a 23 23 23 23 20 47 52 41 4d 4d 41 52 20 43  ..#### GRAMMAR C
b360: 48 45 43 4b 45 52 20 50 4c 55 47 49 4e 53 0a 0a  HECKER PLUGINS..
b370: 24 7b 70 6c 75 67 69 6e 73 7d 0a 0a 0a 23 23 23  ${plugins}...###
b380: 23 20 43 41 4c 4c 41 42 4c 45 53 20 46 4f 52 20  # CALLABLES FOR 
b390: 52 45 47 45 58 20 52 55 4c 45 53 20 28 67 65 6e  REGEX RULES (gen
b3a0: 65 72 61 74 65 64 20 63 6f 64 65 29 0a 0a 24 7b  erated code)..${
b3b0: 63 61 6c 6c 61 62 6c 65 73 7d 0a 0a 0a 23 23 23  callables}...###
b3c0: 23 20 43 41 4c 4c 41 42 4c 45 53 20 46 4f 52 20  # CALLABLES FOR 
b3d0: 47 52 41 50 48 20 52 55 4c 45 53 20 28 67 65 6e  GRAPH RULES (gen
b3e0: 65 72 61 74 65 64 20 63 6f 64 65 29 0a 0a 24 7b  erated code)..${
b3f0: 67 72 61 70 68 5f 63 61 6c 6c 61 62 6c 65 73 7d  graph_callables}
b400: 0a                                               .