Grammalecte  Hex Artifact Content

Artifact 8c11a24e229a3b9c28c9a4a462414350af8e92b348a12add834b6eeca5846335:


0000: 0a 69 6d 70 6f 72 74 20 72 65 0a 69 6d 70 6f 72  .import re.impor
0010: 74 20 74 72 61 63 65 62 61 63 6b 0a 69 6d 70 6f  t traceback.impo
0020: 72 74 20 6a 73 6f 6e 0a 0a 69 6d 70 6f 72 74 20  rt json..import 
0030: 63 6f 6d 70 69 6c 65 5f 72 75 6c 65 73 5f 6a 73  compile_rules_js
0040: 5f 63 6f 6e 76 65 72 74 20 61 73 20 6a 73 63 6f  _convert as jsco
0050: 6e 76 0a 0a 0a 64 44 45 46 20 3d 20 7b 7d 0a 6c  nv...dDEF = {}.l
0060: 46 55 4e 43 54 49 4f 4e 53 20 3d 20 5b 5d 0a 0a  FUNCTIONS = []..
0070: 61 52 55 4c 45 53 45 54 20 3d 20 73 65 74 28 29  aRULESET = set()
0080: 20 20 20 20 20 23 20 73 65 74 20 6f 66 20 72 75       # set of ru
0090: 6c 65 2d 69 64 73 20 74 6f 20 63 68 65 63 6b 20  le-ids to check 
00a0: 69 66 20 74 68 65 72 65 20 69 73 20 73 65 76 65  if there is seve
00b0: 72 61 6c 20 72 75 6c 65 73 20 77 69 74 68 20 74  ral rules with t
00c0: 68 65 20 73 61 6d 65 20 69 64 0a 6e 52 55 4c 45  he same id.nRULE
00d0: 57 49 54 48 4f 55 54 4e 41 4d 45 20 3d 20 30 0a  WITHOUTNAME = 0.
00e0: 0a 64 4a 53 52 45 47 45 58 45 53 20 3d 20 7b 7d  .dJSREGEXES = {}
00f0: 0a 0a 73 57 4f 52 44 4c 49 4d 49 54 4c 45 46 54  ..sWORDLIMITLEFT
0100: 20 20 3d 20 72 22 28 3f 3c 21 5b 5c 77 2e 2c e2    = r"(?<![\w.,.
0110: 80 93 2d 5d 29 22 20 20 20 23 20 72 22 28 3f 3c  ..-])"   # r"(?<
0120: 21 5b 2d 2e 2c e2 80 94 5d 29 5c 62 22 20 20 73  ![-.,...])\b"  s
0130: 65 65 6d 73 20 73 6c 6f 77 65 72 0a 73 57 4f 52  eems slower.sWOR
0140: 44 4c 49 4d 49 54 52 49 47 48 54 20 3d 20 72 22  DLIMITRIGHT = r"
0150: 28 3f 21 5b 5c 77 e2 80 93 2d 5d 29 22 20 20 20  (?![\w...-])"   
0160: 20 20 20 23 20 72 22 5c 62 28 3f 21 2d e2 80 94     # r"\b(?!-...
0170: 29 22 20 20 20 20 20 20 20 73 65 65 6d 73 20 73  )"       seems s
0180: 6c 6f 77 65 72 0a 0a 0a 64 65 66 20 70 72 65 70  lower...def prep
0190: 61 72 65 46 75 6e 63 74 69 6f 6e 20 28 73 29 3a  areFunction (s):
01a0: 0a 20 20 20 20 73 20 3d 20 73 2e 72 65 70 6c 61  .    s = s.repla
01b0: 63 65 28 22 5f 5f 61 6c 73 6f 5f 5f 22 2c 20 22  ce("__also__", "
01c0: 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20 20 20  bCondMemo").    
01d0: 73 20 3d 20 73 2e 72 65 70 6c 61 63 65 28 22 5f  s = s.replace("_
01e0: 5f 65 6c 73 65 5f 5f 22 2c 20 22 6e 6f 74 20 62  _else__", "not b
01f0: 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20 20 20 73  CondMemo").    s
0200: 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 53 74   = re.sub(r"isSt
0210: 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62 65 66  art *\(\)", 'bef
0220: 6f 72 65 28 22 5e 20 2a 24 7c 2c 20 2a 24 22 29  ore("^ *$|, *$")
0230: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0240: 2e 73 75 62 28 72 22 69 73 52 65 61 6c 53 74 61  .sub(r"isRealSta
0250: 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62 65 66 6f  rt *\(\)", 'befo
0260: 72 65 28 22 5e 20 2a 24 22 29 27 2c 20 73 29 0a  re("^ *$")', s).
0270: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0280: 22 69 73 53 74 61 72 74 30 20 2a 5c 28 5c 29 22  "isStart0 *\(\)"
0290: 2c 20 27 62 65 66 6f 72 65 30 28 22 5e 20 2a 24  , 'before0("^ *$
02a0: 7c 2c 20 2a 24 22 29 27 2c 20 73 29 0a 20 20 20  |, *$")', s).   
02b0: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73   s = re.sub(r"is
02c0: 52 65 61 6c 53 74 61 72 74 30 20 2a 5c 28 5c 29  RealStart0 *\(\)
02d0: 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e 20 2a  ", 'before0("^ *
02e0: 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  $")', s).    s =
02f0: 20 72 65 2e 73 75 62 28 72 22 69 73 45 6e 64 20   re.sub(r"isEnd 
0300: 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 28 22  *\(\)", 'after("
0310: 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29 0a 20  ^ *$|^,")', s). 
0320: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0330: 69 73 52 65 61 6c 45 6e 64 20 2a 5c 28 5c 29 22  isRealEnd *\(\)"
0340: 2c 20 27 61 66 74 65 72 28 22 5e 20 2a 24 22 29  , 'after("^ *$")
0350: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0360: 2e 73 75 62 28 72 22 69 73 45 6e 64 30 20 2a 5c  .sub(r"isEnd0 *\
0370: 28 5c 29 22 2c 20 27 61 66 74 65 72 30 28 22 5e  (\)", 'after0("^
0380: 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29 0a 20 20   *$|^,")', s).  
0390: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69    s = re.sub(r"i
03a0: 73 52 65 61 6c 45 6e 64 30 20 2a 5c 28 5c 29 22  sRealEnd0 *\(\)"
03b0: 2c 20 27 61 66 74 65 72 30 28 22 5e 20 2a 24 22  , 'after0("^ *$"
03c0: 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72  )', s).    s = r
03d0: 65 2e 73 75 62 28 72 22 28 73 65 6c 65 63 74 7c  e.sub(r"(select|
03e0: 65 78 63 6c 75 64 65 29 5b 28 5d 5b 5c 5c 5d 28  exclude)[(][\\](
03f0: 5c 64 2b 29 22 2c 20 27 5c 5c 31 28 64 44 41 2c  \d+)", '\\1(dDA,
0400: 20 6d 2e 73 74 61 72 74 28 5c 5c 32 29 2c 20 6d   m.start(\\2), m
0410: 2e 67 72 6f 75 70 28 5c 5c 32 29 27 2c 20 73 29  .group(\\2)', s)
0420: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0430: 72 22 64 65 66 69 6e 65 5b 28 5d 5b 5c 5c 5d 28  r"define[(][\\](
0440: 5c 64 2b 29 22 2c 20 27 64 65 66 69 6e 65 28 64  \d+)", 'define(d
0450: 44 41 2c 20 6d 2e 73 74 61 72 74 28 5c 5c 31 29  DA, m.start(\\1)
0460: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0470: 2e 73 75 62 28 72 22 28 6d 6f 72 70 68 7c 6d 6f  .sub(r"(morph|mo
0480: 72 70 68 65 78 7c 64 69 73 70 6c 61 79 49 6e 66  rphex|displayInf
0490: 6f 29 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c  o)[(][\\](\d+)",
04a0: 20 27 5c 5c 31 28 28 6d 2e 73 74 61 72 74 28 5c   '\\1((m.start(\
04b0: 5c 32 29 2c 20 6d 2e 67 72 6f 75 70 28 5c 5c 32  \2), m.group(\\2
04c0: 29 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ))', s).    s = 
04d0: 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68 7c  re.sub(r"(morph|
04e0: 6d 6f 72 70 68 65 78 7c 64 69 73 70 6c 61 79 49  morphex|displayI
04f0: 6e 66 6f 29 5b 28 5d 22 2c 20 27 5c 5c 31 28 64  nfo)[(]", '\\1(d
0500: 44 41 2c 20 27 2c 20 73 29 0a 20 20 20 20 73 20  DA, ', s).    s 
0510: 3d 20 72 65 2e 73 75 62 28 72 22 28 73 75 67 67  = re.sub(r"(sugg
0520: 5c 77 2b 7c 73 77 69 74 63 68 5c 77 2b 29 5c 28  \w+|switch\w+)\(
0530: 40 22 2c 20 27 5c 5c 31 28 6d 2e 67 72 6f 75 70  @", '\\1(m.group
0540: 28 69 5b 34 5d 29 27 2c 20 73 29 0a 20 20 20 20  (i[4])', s).    
0550: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 77 6f 72  s = re.sub(r"wor
0560: 64 5c 28 5c 73 2a 31 5c 62 22 2c 20 27 6e 65 78  d\(\s*1\b", 'nex
0570: 74 77 6f 72 64 31 28 73 2c 20 6d 2e 65 6e 64 28  tword1(s, m.end(
0580: 29 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20  )', s)          
0590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05a0: 20 20 20 20 20 20 20 20 23 20 77 6f 72 64 28 31          # word(1
05b0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
05c0: 28 72 22 77 6f 72 64 5c 28 5c 73 2a 2d 31 5c 62  (r"word\(\s*-1\b
05d0: 22 2c 20 27 70 72 65 76 77 6f 72 64 31 28 73 2c  ", 'prevword1(s,
05e0: 20 6d 2e 73 74 61 72 74 28 29 27 2c 20 73 29 20   m.start()', s) 
05f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0610: 77 6f 72 64 28 2d 31 29 0a 20 20 20 20 73 20 3d  word(-1).    s =
0620: 20 72 65 2e 73 75 62 28 72 22 77 6f 72 64 5c 28   re.sub(r"word\(
0630: 5c 73 2a 28 5c 64 29 22 2c 20 27 6e 65 78 74 77  \s*(\d)", 'nextw
0640: 6f 72 64 28 73 2c 20 6d 2e 65 6e 64 28 29 2c 20  ord(s, m.end(), 
0650: 5c 5c 31 27 2c 20 73 29 20 20 20 20 20 20 20 20  \\1', s)        
0660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0670: 20 20 20 20 20 23 20 77 6f 72 64 28 6e 29 0a 20       # word(n). 
0680: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0690: 77 6f 72 64 5c 28 5c 73 2a 2d 28 5c 64 29 22 2c  word\(\s*-(\d)",
06a0: 20 27 70 72 65 76 77 6f 72 64 28 73 2c 20 6d 2e   'prevword(s, m.
06b0: 73 74 61 72 74 28 29 2c 20 5c 5c 31 27 2c 20 73  start(), \\1', s
06c0: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
06d0: 20 20 20 20 20 20 20 20 20 20 20 23 20 77 6f 72             # wor
06e0: 64 28 2d 6e 29 0a 20 20 20 20 73 20 3d 20 72 65  d(-n).    s = re
06f0: 2e 73 75 62 28 72 22 62 65 66 6f 72 65 5c 28 5c  .sub(r"before\(\
0700: 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 5b 3a 6d 2e  s*", 'look(s[:m.
0710: 73 74 61 72 74 28 29 5d 2c 20 27 2c 20 73 29 20  start()], ', s) 
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0740: 20 20 23 20 62 65 66 6f 72 65 28 73 29 0a 20 20    # before(s).  
0750: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 61    s = re.sub(r"a
0760: 66 74 65 72 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  fter\(\s*", 'loo
0770: 6b 28 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 27  k(s[m.end():], '
0780: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07a0: 20 20 20 20 20 20 20 20 20 20 23 20 61 66 74 65            # afte
07b0: 72 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  r(s).    s = re.
07c0: 73 75 62 28 72 22 74 65 78 74 61 72 65 61 5c 28  sub(r"textarea\(
07d0: 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 2c 20 27  \s*", 'look(s, '
07e0: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
07f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0810: 20 23 20 74 65 78 74 61 72 65 61 28 73 29 0a 20   # textarea(s). 
0820: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0830: 62 65 66 6f 72 65 5f 63 68 6b 31 5c 28 5c 73 2a  before_chk1\(\s*
0840: 22 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44  ", 'look_chk1(dD
0850: 41 2c 20 73 5b 3a 6d 2e 73 74 61 72 74 28 29 5d  A, s[:m.start()]
0860: 2c 20 30 2c 20 27 2c 20 73 29 20 20 20 20 20 20  , 0, ', s)      
0870: 20 20 20 20 20 20 20 20 20 20 20 23 20 62 65 66             # bef
0880: 6f 72 65 5f 63 68 6b 31 28 73 29 0a 20 20 20 20  ore_chk1(s).    
0890: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 61 66 74  s = re.sub(r"aft
08a0: 65 72 5f 63 68 6b 31 5c 28 5c 73 2a 22 2c 20 27  er_chk1\(\s*", '
08b0: 6c 6f 6f 6b 5f 63 68 6b 31 28 64 44 41 2c 20 73  look_chk1(dDA, s
08c0: 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65 6e  [m.end():], m.en
08d0: 64 28 29 2c 20 27 2c 20 73 29 20 20 20 20 20 20  d(), ', s)      
08e0: 20 20 20 20 20 20 20 20 23 20 61 66 74 65 72 5f          # after_
08f0: 63 68 6b 31 28 73 29 0a 20 20 20 20 73 20 3d 20  chk1(s).    s = 
0900: 72 65 2e 73 75 62 28 72 22 74 65 78 74 61 72 65  re.sub(r"textare
0910: 61 5f 63 68 6b 31 5c 28 5c 73 2a 22 2c 20 27 6c  a_chk1\(\s*", 'l
0920: 6f 6f 6b 5f 63 68 6b 31 28 64 44 41 2c 20 73 2c  ook_chk1(dDA, s,
0930: 20 30 2c 20 27 2c 20 73 29 20 20 20 20 20 20 20   0, ', s)       
0940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0950: 20 20 20 20 23 20 74 65 78 74 61 72 65 61 5f 63      # textarea_c
0960: 68 6b 31 28 73 29 0a 20 20 20 20 73 20 3d 20 72  hk1(s).    s = r
0970: 65 2e 73 75 62 28 72 22 2f 30 22 2c 20 27 73 78  e.sub(r"/0", 'sx
0980: 5b 6d 2e 73 74 61 72 74 28 29 3a 6d 2e 65 6e 64  [m.start():m.end
0990: 28 29 5d 27 2c 20 73 29 20 20 20 20 20 20 20 20  ()]', s)        
09a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09c0: 20 20 20 23 20 2f 30 0a 20 20 20 20 73 20 3d 20     # /0.    s = 
09d0: 72 65 2e 73 75 62 28 72 22 62 65 66 6f 72 65 30  re.sub(r"before0
09e0: 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 78  \(\s*", 'look(sx
09f0: 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2c 20 27 2c  [:m.start()], ',
0a00: 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20   s)             
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a20: 20 20 20 20 23 20 62 65 66 6f 72 65 30 28 73 29      # before0(s)
0a30: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0a40: 72 22 61 66 74 65 72 30 5c 28 5c 73 2a 22 2c 20  r"after0\(\s*", 
0a50: 27 6c 6f 6f 6b 28 73 78 5b 6d 2e 65 6e 64 28 29  'look(sx[m.end()
0a60: 3a 5d 2c 20 27 2c 20 73 29 20 20 20 20 20 20 20  :], ', s)       
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61               # a
0a90: 66 74 65 72 30 28 73 29 0a 20 20 20 20 73 20 3d  fter0(s).    s =
0aa0: 20 72 65 2e 73 75 62 28 72 22 74 65 78 74 61 72   re.sub(r"textar
0ab0: 65 61 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b  ea0\(\s*", 'look
0ac0: 28 73 78 2c 20 27 2c 20 73 29 20 20 20 20 20 20  (sx, ', s)      
0ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0af0: 20 20 20 20 20 23 20 74 65 78 74 61 72 65 61 30       # textarea0
0b00: 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (s).    s = re.s
0b10: 75 62 28 72 22 62 65 66 6f 72 65 30 5f 63 68 6b  ub(r"before0_chk
0b20: 31 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63  1\(\s*", 'look_c
0b30: 68 6b 31 28 64 44 41 2c 20 73 78 5b 3a 6d 2e 73  hk1(dDA, sx[:m.s
0b40: 74 61 72 74 28 29 5d 2c 20 30 2c 20 27 2c 20 73  tart()], 0, ', s
0b50: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
0b60: 23 20 62 65 66 6f 72 65 30 5f 63 68 6b 31 28 73  # before0_chk1(s
0b70: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0b80: 28 72 22 61 66 74 65 72 30 5f 63 68 6b 31 5c 28  (r"after0_chk1\(
0b90: 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31  \s*", 'look_chk1
0ba0: 28 64 44 41 2c 20 73 78 5b 6d 2e 65 6e 64 28 29  (dDA, sx[m.end()
0bb0: 3a 5d 2c 20 6d 2e 65 6e 64 28 29 2c 20 27 2c 20  :], m.end(), ', 
0bc0: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 23 20  s)            # 
0bd0: 61 66 74 65 72 30 5f 63 68 6b 31 28 73 29 0a 20  after0_chk1(s). 
0be0: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0bf0: 74 65 78 74 61 72 65 61 30 5f 63 68 6b 31 5c 28  textarea0_chk1\(
0c00: 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 5f 63 68 6b 31  \s*", 'look_chk1
0c10: 28 64 44 41 2c 20 73 78 2c 20 30 2c 20 27 2c 20  (dDA, sx, 0, ', 
0c20: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s)              
0c30: 20 20 20 20 20 20 20 20 20 20 20 23 20 74 65 78             # tex
0c40: 74 61 72 65 61 30 5f 63 68 6b 31 28 73 29 0a 20  tarea0_chk1(s). 
0c50: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0c60: 69 73 45 6e 64 4f 66 4e 47 5c 28 5c 73 2a 5c 29  isEndOfNG\(\s*\)
0c70: 22 2c 20 27 69 73 45 6e 64 4f 66 4e 47 28 64 44  ", 'isEndOfNG(dD
0c80: 41 2c 20 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20  A, s[m.end():], 
0c90: 6d 2e 65 6e 64 28 29 29 27 2c 20 73 29 20 20 20  m.end())', s)   
0ca0: 20 20 20 20 20 20 20 20 20 20 20 23 20 69 73 45             # isE
0cb0: 6e 64 4f 66 4e 47 28 73 29 0a 20 20 20 20 73 20  ndOfNG(s).    s 
0cc0: 3d 20 72 65 2e 73 75 62 28 72 22 69 73 4e 65 78  = re.sub(r"isNex
0cd0: 74 4e 6f 74 43 4f 44 5c 28 5c 73 2a 5c 29 22 2c  tNotCOD\(\s*\)",
0ce0: 20 27 69 73 4e 65 78 74 4e 6f 74 43 4f 44 28 64   'isNextNotCOD(d
0cf0: 44 41 2c 20 73 5b 6d 2e 65 6e 64 28 29 3a 5d 2c  DA, s[m.end():],
0d00: 20 6d 2e 65 6e 64 28 29 29 27 2c 20 73 29 20 20   m.end())', s)  
0d10: 20 20 20 20 20 20 23 20 69 73 4e 65 78 74 4e 6f        # isNextNo
0d20: 74 43 4f 44 28 73 29 0a 20 20 20 20 73 20 3d 20  tCOD(s).    s = 
0d30: 72 65 2e 73 75 62 28 72 22 69 73 4e 65 78 74 56  re.sub(r"isNextV
0d40: 65 72 62 5c 28 5c 73 2a 5c 29 22 2c 20 27 69 73  erb\(\s*\)", 'is
0d50: 4e 65 78 74 56 65 72 62 28 64 44 41 2c 20 73 5b  NextVerb(dDA, s[
0d60: 6d 2e 65 6e 64 28 29 3a 5d 2c 20 6d 2e 65 6e 64  m.end():], m.end
0d70: 28 29 29 27 2c 20 73 29 20 20 20 20 20 20 20 20  ())', s)        
0d80: 20 20 20 20 23 20 69 73 4e 65 78 74 56 65 72 62      # isNextVerb
0d90: 28 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73  (s).    s = re.s
0da0: 75 62 28 72 22 5c 62 73 70 65 6c 6c 20 2a 5b 28  ub(r"\bspell *[(
0db0: 5d 22 2c 20 27 5f 6f 53 70 65 6c 6c 43 68 65 63  ]", '_oSpellChec
0dc0: 6b 65 72 2e 69 73 56 61 6c 69 64 28 27 2c 20 73  ker.isValid(', s
0dd0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0de0: 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27  (r"[\\](\d+)", '
0df0: 6d 2e 67 72 6f 75 70 28 5c 5c 31 29 27 2c 20 73  m.group(\\1)', s
0e00: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 73 0a 0a  ).    return s..
0e10: 0a 64 65 66 20 75 70 70 65 72 63 61 73 65 20 28  .def uppercase (
0e20: 73 2c 20 73 4c 61 6e 67 29 3a 0a 20 20 20 20 22  s, sLang):.    "
0e30: 28 66 6c 61 67 20 69 20 69 73 20 6e 6f 74 20 65  (flag i is not e
0e40: 6e 6f 75 67 68 29 3a 20 63 6f 6e 76 65 72 74 73  nough): converts
0e50: 20 72 65 67 65 78 20 74 6f 20 75 70 70 65 72 63   regex to upperc
0e60: 61 73 65 20 72 65 67 65 78 3a 20 27 66 6f 6f 27  ase regex: 'foo'
0e70: 20 62 65 63 6f 6d 65 73 20 27 5b 46 66 5d 5b 4f   becomes '[Ff][O
0e80: 6f 5d 5b 4f 6f 5d 27 2c 20 62 75 74 20 27 42 61  o][Oo]', but 'Ba
0e90: 72 27 20 62 65 63 6f 6d 65 73 20 27 42 5b 41 61  r' becomes 'B[Aa
0ea0: 5d 5b 52 72 5d 27 2e 22 0a 20 20 20 20 73 55 70  ][Rr]'.".    sUp
0eb0: 20 3d 20 22 22 0a 20 20 20 20 6e 53 74 61 74 65   = "".    nState
0ec0: 20 3d 20 30 0a 20 20 20 20 66 6f 72 20 69 20 69   = 0.    for i i
0ed0: 6e 20 72 61 6e 67 65 28 30 2c 20 6c 65 6e 28 73  n range(0, len(s
0ee0: 29 29 3a 0a 20 20 20 20 20 20 20 20 63 20 3d 20  )):.        c = 
0ef0: 73 5b 69 5d 0a 20 20 20 20 20 20 20 20 69 66 20  s[i].        if 
0f00: 63 20 3d 3d 20 22 5b 22 3a 0a 20 20 20 20 20 20  c == "[":.      
0f10: 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20 31        nState = 1
0f20: 0a 20 20 20 20 20 20 20 20 69 66 20 6e 53 74 61  .        if nSta
0f30: 74 65 20 3d 3d 20 31 20 61 6e 64 20 63 20 3d 3d  te == 1 and c ==
0f40: 20 22 5d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "]":.          
0f50: 20 20 6e 53 74 61 74 65 20 3d 20 30 0a 20 20 20    nState = 0.   
0f60: 20 20 20 20 20 69 66 20 63 20 3d 3d 20 22 3c 22       if c == "<"
0f70: 20 61 6e 64 20 69 20 3e 20 33 20 61 6e 64 20 73   and i > 3 and s
0f80: 5b 69 2d 33 3a 69 5d 20 3d 3d 20 22 28 3f 50 22  [i-3:i] == "(?P"
0f90: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53  :.            nS
0fa0: 74 61 74 65 20 3d 20 32 0a 20 20 20 20 20 20 20  tate = 2.       
0fb0: 20 69 66 20 6e 53 74 61 74 65 20 3d 3d 20 32 20   if nState == 2 
0fc0: 61 6e 64 20 63 20 3d 3d 20 22 3e 22 3a 0a 20 20  and c == ">":.  
0fd0: 20 20 20 20 20 20 20 20 20 20 6e 53 74 61 74 65            nState
0fe0: 20 3d 20 30 0a 20 20 20 20 20 20 20 20 69 66 20   = 0.        if 
0ff0: 63 20 3d 3d 20 22 3f 22 20 61 6e 64 20 69 20 3e  c == "?" and i >
1000: 20 30 20 61 6e 64 20 73 5b 69 2d 31 3a 69 5d 20   0 and s[i-1:i] 
1010: 3d 3d 20 22 28 22 20 61 6e 64 20 73 5b 69 2b 31  == "(" and s[i+1
1020: 3a 69 2b 32 5d 20 21 3d 20 22 3a 22 3a 0a 20 20  :i+2] != ":":.  
1030: 20 20 20 20 20 20 20 20 20 20 6e 53 74 61 74 65            nState
1040: 20 3d 20 35 0a 20 20 20 20 20 20 20 20 69 66 20   = 5.        if 
1050: 6e 53 74 61 74 65 20 3d 3d 20 35 20 61 6e 64 20  nState == 5 and 
1060: 63 20 3d 3d 20 22 29 22 3a 0a 20 20 20 20 20 20  c == ")":.      
1070: 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20 30        nState = 0
1080: 0a 20 20 20 20 20 20 20 20 69 66 20 63 2e 69 73  .        if c.is
1090: 61 6c 70 68 61 28 29 20 61 6e 64 20 63 2e 69 73  alpha() and c.is
10a0: 6c 6f 77 65 72 28 29 20 61 6e 64 20 6e 53 74 61  lower() and nSta
10b0: 74 65 20 3d 3d 20 30 3a 0a 20 20 20 20 20 20 20  te == 0:.       
10c0: 20 20 20 20 20 69 66 20 63 20 3d 3d 20 22 69 22       if c == "i"
10d0: 20 61 6e 64 20 28 73 4c 61 6e 67 20 3d 3d 20 22   and (sLang == "
10e0: 74 72 22 20 6f 72 20 73 4c 61 6e 67 20 3d 3d 20  tr" or sLang == 
10f0: 22 61 7a 22 29 3a 0a 20 20 20 20 20 20 20 20 20  "az"):.         
1100: 20 20 20 20 20 20 20 73 55 70 20 2b 3d 20 22 5b         sUp += "[
1110: c4 b0 22 20 2b 20 63 20 2b 20 22 5d 22 0a 20 20  .." + c + "]".  
1120: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
1130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1140: 73 55 70 20 2b 3d 20 22 5b 22 20 2b 20 63 2e 75  sUp += "[" + c.u
1150: 70 70 65 72 28 29 20 2b 20 63 20 2b 20 22 5d 22  pper() + c + "]"
1160: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 2e  .        elif c.
1170: 69 73 61 6c 70 68 61 28 29 20 61 6e 64 20 63 2e  isalpha() and c.
1180: 69 73 6c 6f 77 65 72 28 29 20 61 6e 64 20 6e 53  islower() and nS
1190: 74 61 74 65 20 3d 3d 20 31 20 61 6e 64 20 73 5b  tate == 1 and s[
11a0: 69 2b 31 3a 69 2b 32 5d 20 21 3d 20 22 2d 22 3a  i+1:i+2] != "-":
11b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
11c0: 73 5b 69 2d 31 3a 69 5d 20 3d 3d 20 22 2d 22 20  s[i-1:i] == "-" 
11d0: 61 6e 64 20 73 5b 69 2d 32 3a 69 2d 31 5d 2e 69  and s[i-2:i-1].i
11e0: 73 6c 6f 77 65 72 28 29 3a 20 20 23 20 5b 61 2d  slower():  # [a-
11f0: 7a 5d 20 2d 3e 20 5b 61 2d 7a 41 2d 5a 5d 0a 20  z] -> [a-zA-Z]. 
1200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
1210: 55 70 20 2b 3d 20 63 20 2b 20 73 5b 69 2d 32 3a  Up += c + s[i-2:
1220: 69 2d 31 5d 2e 75 70 70 65 72 28 29 20 2b 20 22  i-1].upper() + "
1230: 2d 22 20 2b 20 63 2e 75 70 70 65 72 28 29 0a 20  -" + c.upper(). 
1240: 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20             elif 
1250: 63 20 3d 3d 20 22 69 22 20 61 6e 64 20 28 73 4c  c == "i" and (sL
1260: 61 6e 67 20 3d 3d 20 22 74 72 22 20 6f 72 20 73  ang == "tr" or s
1270: 4c 61 6e 67 20 3d 3d 20 22 61 7a 22 29 3a 0a 20  Lang == "az"):. 
1280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
1290: 55 70 20 2b 3d 20 22 c4 b0 22 20 2b 20 63 0a 20  Up += ".." + c. 
12a0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
12b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
12c0: 20 73 55 70 20 2b 3d 20 63 2e 75 70 70 65 72 28   sUp += c.upper(
12d0: 29 20 2b 20 63 0a 20 20 20 20 20 20 20 20 65 6c  ) + c.        el
12e0: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
12f0: 73 55 70 20 2b 3d 20 63 0a 20 20 20 20 20 20 20  sUp += c.       
1300: 20 69 66 20 63 20 3d 3d 20 22 5c 5c 22 3a 0a 20   if c == "\\":. 
1310: 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61 74             nStat
1320: 65 20 3d 20 34 0a 20 20 20 20 20 20 20 20 65 6c  e = 4.        el
1330: 69 66 20 6e 53 74 61 74 65 20 3d 3d 20 34 3a 0a  if nState == 4:.
1340: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
1350: 74 65 20 3d 20 30 0a 20 20 20 20 72 65 74 75 72  te = 0.    retur
1360: 6e 20 73 55 70 0a 0a 0a 64 65 66 20 63 6f 75 6e  n sUp...def coun
1370: 74 47 72 6f 75 70 49 6e 52 65 67 65 78 20 28 73  tGroupInRegex (s
1380: 52 65 67 65 78 29 3a 0a 20 20 20 20 74 72 79 3a  Regex):.    try:
1390: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
13a0: 72 65 2e 63 6f 6d 70 69 6c 65 28 73 52 65 67 65  re.compile(sRege
13b0: 78 29 2e 67 72 6f 75 70 73 0a 20 20 20 20 65 78  x).groups.    ex
13c0: 63 65 70 74 3a 0a 20 20 20 20 20 20 20 20 74 72  cept:.        tr
13d0: 61 63 65 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78  aceback.print_ex
13e0: 63 28 29 0a 20 20 20 20 20 20 20 20 70 72 69 6e  c().        prin
13f0: 74 28 73 52 65 67 65 78 29 0a 20 20 20 20 72 65  t(sRegex).    re
1400: 74 75 72 6e 20 30 0a 0a 0a 64 65 66 20 63 72 65  turn 0...def cre
1410: 61 74 65 52 75 6c 65 20 28 73 2c 20 6e 49 64 4c  ateRule (s, nIdL
1420: 69 6e 65 2c 20 73 4c 61 6e 67 2c 20 62 50 61 72  ine, sLang, bPar
1430: 61 67 72 61 70 68 2c 20 64 4f 70 74 50 72 69 6f  agraph, dOptPrio
1440: 72 69 74 79 29 3a 0a 20 20 20 20 22 72 65 74 75  rity):.    "retu
1450: 72 6e 73 20 72 75 6c 65 20 61 73 20 6c 69 73 74  rns rule as list
1460: 20 5b 6f 70 74 69 6f 6e 20 6e 61 6d 65 2c 20 72   [option name, r
1470: 65 67 65 78 2c 20 62 43 61 73 65 49 6e 73 65 6e  egex, bCaseInsen
1480: 73 69 74 69 76 65 2c 20 69 64 65 6e 74 69 66 69  sitive, identifi
1490: 65 72 2c 20 6c 69 73 74 20 6f 66 20 61 63 74 69  er, list of acti
14a0: 6f 6e 73 5d 22 0a 20 20 20 20 67 6c 6f 62 61 6c  ons]".    global
14b0: 20 64 4a 53 52 45 47 45 58 45 53 0a 20 20 20 20   dJSREGEXES.    
14c0: 67 6c 6f 62 61 6c 20 6e 52 55 4c 45 57 49 54 48  global nRULEWITH
14d0: 4f 55 54 4e 41 4d 45 0a 0a 20 20 20 20 73 4c 69  OUTNAME..    sLi
14e0: 6e 65 49 64 20 3d 20 73 74 72 28 6e 49 64 4c 69  neId = str(nIdLi
14f0: 6e 65 29 20 2b 20 28 22 70 22 20 69 66 20 62 50  ne) + ("p" if bP
1500: 61 72 61 67 72 61 70 68 20 65 6c 73 65 20 22 73  aragraph else "s
1510: 22 29 0a 20 20 20 20 73 52 75 6c 65 49 64 20 3d  ").    sRuleId =
1520: 20 73 4c 69 6e 65 49 64 0a 0a 20 20 20 20 23 23   sLineId..    ##
1530: 23 23 20 47 52 41 50 48 20 43 41 4c 4c 0a 20 20  ## GRAPH CALL.  
1540: 20 20 69 66 20 73 2e 73 74 61 72 74 73 77 69 74    if s.startswit
1550: 68 28 22 40 40 40 40 22 29 3a 0a 20 20 20 20 20  h("@@@@"):.     
1560: 20 20 20 69 66 20 62 50 61 72 61 67 72 61 70 68     if bParagraph
1570: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  :.            pr
1580: 69 6e 74 28 22 45 72 72 6f 72 2e 20 47 72 61 70  int("Error. Grap
1590: 68 20 63 61 6c 6c 20 63 61 6e e2 80 99 74 20 62  h call can...t b
15a0: 65 20 6d 61 64 65 20 6f 6e 6c 79 20 61 66 74 65  e made only afte
15b0: 72 20 74 68 65 20 66 69 72 73 74 20 70 61 73 73  r the first pass
15c0: 20 28 73 65 6e 74 65 6e 63 65 20 62 79 20 73 65   (sentence by se
15d0: 6e 74 65 6e 63 65 29 22 29 0a 20 20 20 20 20 20  ntence)").      
15e0: 20 20 20 20 20 20 65 78 69 74 28 29 0a 20 20 20        exit().   
15f0: 20 20 20 20 20 72 65 74 75 72 6e 20 5b 22 40 40       return ["@@
1600: 40 40 22 2c 20 73 5b 34 3a 5d 2c 20 73 4c 69 6e  @@", s[4:], sLin
1610: 65 49 64 5d 0a 0a 20 20 20 20 23 23 23 23 20 4f  eId]..    #### O
1620: 50 54 49 4f 4e 53 0a 20 20 20 20 73 4f 70 74 69  PTIONS.    sOpti
1630: 6f 6e 20 3d 20 46 61 6c 73 65 20 20 20 20 20 20  on = False      
1640: 20 20 20 23 20 46 61 6c 73 65 20 6f 72 20 5b 61     # False or [a
1650: 2d 7a 30 2d 39 5d 2b 20 6e 61 6d 65 0a 20 20 20  -z0-9]+ name.   
1660: 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 34 20 20   nPriority = 4  
1670: 20 20 20 20 20 20 20 20 20 23 20 44 65 66 61 75           # Defau
1680: 6c 74 20 69 73 20 34 2c 20 76 61 6c 75 65 20 6d  lt is 4, value m
1690: 75 73 74 20 62 65 20 62 65 74 77 65 65 6e 20 30  ust be between 0
16a0: 20 61 6e 64 20 39 0a 20 20 20 20 74 47 72 6f 75   and 9.    tGrou
16b0: 70 73 20 3d 20 4e 6f 6e 65 20 20 20 20 20 20 20  ps = None       
16c0: 20 20 20 23 20 63 6f 64 65 20 66 6f 72 20 67 72     # code for gr
16d0: 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67  oups positioning
16e0: 20 28 6f 6e 6c 79 20 75 73 65 66 75 6c 20 66 6f   (only useful fo
16f0: 72 20 4a 61 76 61 53 63 72 69 70 74 29 0a 20 20  r JavaScript).  
1700: 20 20 63 43 61 73 65 4d 6f 64 65 20 3d 20 27 69    cCaseMode = 'i
1710: 27 20 20 20 20 20 20 20 20 20 23 20 69 3a 20 63  '         # i: c
1720: 61 73 65 20 69 6e 73 65 6e 73 69 74 69 76 65 2c  ase insensitive,
1730: 20 20 73 3a 20 63 61 73 65 20 73 65 6e 73 69 74    s: case sensit
1740: 69 76 65 2c 20 20 75 3a 20 75 70 70 65 72 63 61  ive,  u: upperca
1750: 73 69 6e 67 20 61 6c 6c 6f 77 65 64 0a 20 20 20  sing allowed.   
1760: 20 63 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20   cWordLimitLeft 
1770: 3d 20 27 5b 27 20 20 20 20 23 20 5b 3a 20 77 6f  = '['    # [: wo
1780: 72 64 20 6c 69 6d 69 74 2c 20 3c 3a 20 6e 6f 20  rd limit, <: no 
1790: 73 70 65 63 69 66 69 63 20 6c 69 6d 69 74 0a 20  specific limit. 
17a0: 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 52 69 67     cWordLimitRig
17b0: 68 74 20 3d 20 27 5d 27 20 20 20 23 20 5d 3a 20  ht = ']'   # ]: 
17c0: 77 6f 72 64 20 6c 69 6d 69 74 2c 20 3e 3a 20 6e  word limit, >: n
17d0: 6f 20 73 70 65 63 69 66 69 63 20 6c 69 6d 69 74  o specific limit
17e0: 0a 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63  .    m = re.matc
17f0: 68 28 22 5e 5f 5f 28 3f 50 3c 62 6f 72 64 65 72  h("^__(?P<border
1800: 73 5f 61 6e 64 5f 63 61 73 65 3e 5b 5b 3c 5d 5c  s_and_case>[[<]\
1810: 5c 77 5b 5d 3e 5d 29 28 3f 50 3c 6f 70 74 69 6f  \w[]>])(?P<optio
1820: 6e 3e 2f 5b 61 2d 7a 41 2d 5a 30 2d 39 5d 2b 7c  n>/[a-zA-Z0-9]+|
1830: 29 28 3f 50 3c 72 75 6c 65 69 64 3e 5c 5c 28 5c  )(?P<ruleid>\\(\
1840: 5c 77 2b 5c 5c 29 7c 29 28 3f 50 3c 70 72 69 6f  \w+\\)|)(?P<prio
1850: 72 69 74 79 3e 21 5b 30 2d 39 5d 7c 29 5f 5f 20  rity>![0-9]|)__ 
1860: 2a 22 2c 20 73 29 0a 20 20 20 20 69 66 20 6d 3a  *", s).    if m:
1870: 0a 20 20 20 20 20 20 20 20 63 57 6f 72 64 4c 69  .        cWordLi
1880: 6d 69 74 4c 65 66 74 20 3d 20 6d 2e 67 72 6f 75  mitLeft = m.grou
1890: 70 28 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f 63  p('borders_and_c
18a0: 61 73 65 27 29 5b 30 5d 0a 20 20 20 20 20 20 20  ase')[0].       
18b0: 20 63 43 61 73 65 4d 6f 64 65 20 3d 20 6d 2e 67   cCaseMode = m.g
18c0: 72 6f 75 70 28 27 62 6f 72 64 65 72 73 5f 61 6e  roup('borders_an
18d0: 64 5f 63 61 73 65 27 29 5b 31 5d 0a 20 20 20 20  d_case')[1].    
18e0: 20 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 52 69      cWordLimitRi
18f0: 67 68 74 20 3d 20 6d 2e 67 72 6f 75 70 28 27 62  ght = m.group('b
1900: 6f 72 64 65 72 73 5f 61 6e 64 5f 63 61 73 65 27  orders_and_case'
1910: 29 5b 32 5d 0a 20 20 20 20 20 20 20 20 73 4f 70  )[2].        sOp
1920: 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 27  tion = m.group('
1930: 6f 70 74 69 6f 6e 27 29 5b 31 3a 5d 20 20 69 66  option')[1:]  if
1940: 20 6d 2e 67 72 6f 75 70 28 27 6f 70 74 69 6f 6e   m.group('option
1950: 27 29 20 20 65 6c 73 65 20 46 61 6c 73 65 0a 20  ')  else False. 
1960: 20 20 20 20 20 20 20 69 66 20 6d 2e 67 72 6f 75         if m.grou
1970: 70 28 27 72 75 6c 65 69 64 27 29 3a 0a 20 20 20  p('ruleid'):.   
1980: 20 20 20 20 20 20 20 20 20 73 52 75 6c 65 49 64           sRuleId
1990: 20 3d 20 20 6d 2e 67 72 6f 75 70 28 27 72 75 6c   =  m.group('rul
19a0: 65 69 64 27 29 5b 31 3a 2d 31 5d 0a 20 20 20 20  eid')[1:-1].    
19b0: 20 20 20 20 20 20 20 20 69 66 20 73 52 75 6c 65          if sRule
19c0: 49 64 20 69 6e 20 61 52 55 4c 45 53 45 54 3a 0a  Id in aRULESET:.
19d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19e0: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20  print("# Error. 
19f0: 53 65 76 65 72 61 6c 20 72 75 6c 65 73 20 68 61  Several rules ha
1a00: 76 65 20 74 68 65 20 73 61 6d 65 20 69 64 3a 20  ve the same id: 
1a10: 22 20 2b 20 73 52 75 6c 65 49 64 29 0a 20 20 20  " + sRuleId).   
1a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 65 78 69               exi
1a30: 74 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  t().            
1a40: 61 52 55 4c 45 53 45 54 2e 61 64 64 28 73 52 75  aRULESET.add(sRu
1a50: 6c 65 49 64 29 0a 20 20 20 20 20 20 20 20 65 6c  leId).        el
1a60: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
1a70: 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45  nRULEWITHOUTNAME
1a80: 20 2b 3d 20 31 0a 20 20 20 20 20 20 20 20 6e 50   += 1.        nP
1a90: 72 69 6f 72 69 74 79 20 3d 20 64 4f 70 74 50 72  riority = dOptPr
1aa0: 69 6f 72 69 74 79 2e 67 65 74 28 73 4f 70 74 69  iority.get(sOpti
1ab0: 6f 6e 2c 20 34 29 0a 20 20 20 20 20 20 20 20 69  on, 4).        i
1ac0: 66 20 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f 72  f m.group('prior
1ad0: 69 74 79 27 29 3a 0a 20 20 20 20 20 20 20 20 20  ity'):.         
1ae0: 20 20 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 69     nPriority = i
1af0: 6e 74 28 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f  nt(m.group('prio
1b00: 72 69 74 79 27 29 5b 31 3a 5d 29 0a 20 20 20 20  rity')[1:]).    
1b10: 20 20 20 20 73 20 3d 20 73 5b 6d 2e 65 6e 64 28      s = s[m.end(
1b20: 30 29 3a 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20  0):].    else:. 
1b30: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
1b40: 57 61 72 6e 69 6e 67 2e 20 4e 6f 20 6f 70 74 69  Warning. No opti
1b50: 6f 6e 20 64 65 66 69 6e 65 64 20 61 74 20 6c 69  on defined at li
1b60: 6e 65 3a 20 22 20 2b 20 73 4c 69 6e 65 49 64 29  ne: " + sLineId)
1b70: 0a 0a 20 20 20 20 23 23 23 23 20 52 45 47 45 58  ..    #### REGEX
1b80: 20 54 52 49 47 47 45 52 0a 20 20 20 20 69 20 3d   TRIGGER.    i =
1b90: 20 73 2e 66 69 6e 64 28 22 20 3c 3c 2d 22 29 0a   s.find(" <<-").
1ba0: 20 20 20 20 69 66 20 69 20 3d 3d 20 2d 31 3a 0a      if i == -1:.
1bb0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
1bc0: 20 45 72 72 6f 72 3a 20 6e 6f 20 63 6f 6e 64 69   Error: no condi
1bd0: 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b  tion at line " +
1be0: 20 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20   sLineId).      
1bf0: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20    return None.  
1c00: 20 20 73 52 65 67 65 78 20 3d 20 73 5b 3a 69 5d    sRegex = s[:i]
1c10: 2e 73 74 72 69 70 28 29 0a 20 20 20 20 73 20 3d  .strip().    s =
1c20: 20 73 5b 69 2b 34 3a 5d 0a 20 20 20 20 0a 20 20   s[i+4:].    .  
1c30: 20 20 23 20 4a 53 20 67 72 6f 75 70 73 20 70 6f    # JS groups po
1c40: 73 69 74 69 6f 6e 69 6e 67 20 63 6f 64 65 73 0a  sitioning codes.
1c50: 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63      m = re.searc
1c60: 68 28 22 40 40 5c 5c 53 2b 22 2c 20 73 52 65 67  h("@@\\S+", sReg
1c70: 65 78 29 0a 20 20 20 20 69 66 20 6d 3a 0a 20 20  ex).    if m:.  
1c80: 20 20 20 20 20 20 74 47 72 6f 75 70 73 20 3d 20        tGroups = 
1c90: 6a 73 63 6f 6e 76 2e 67 72 6f 75 70 73 50 6f 73  jsconv.groupsPos
1ca0: 69 74 69 6f 6e 69 6e 67 43 6f 64 65 54 6f 4c 69  itioningCodeToLi
1cb0: 73 74 28 73 52 65 67 65 78 5b 6d 2e 73 74 61 72  st(sRegex[m.star
1cc0: 74 28 29 2b 32 3a 5d 29 0a 20 20 20 20 20 20 20  t()+2:]).       
1cd0: 20 73 52 65 67 65 78 20 3d 20 73 52 65 67 65 78   sRegex = sRegex
1ce0: 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73 74 72  [:m.start()].str
1cf0: 69 70 28 29 0a 20 20 20 20 23 20 4a 53 20 72 65  ip().    # JS re
1d00: 67 65 78 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73  gex.    m = re.s
1d10: 65 61 72 63 68 28 22 3c 6a 73 3e 2e 2b 3c 2f 6a  earch("<js>.+</j
1d20: 73 3e 69 3f 22 2c 20 73 52 65 67 65 78 29 0a 20  s>i?", sRegex). 
1d30: 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20     if m:.       
1d40: 20 64 4a 53 52 45 47 45 58 45 53 5b 73 4c 69 6e   dJSREGEXES[sLin
1d50: 65 49 64 5d 20 3d 20 6d 2e 67 72 6f 75 70 28 30  eId] = m.group(0
1d60: 29 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78  ).        sRegex
1d70: 20 3d 20 73 52 65 67 65 78 5b 3a 6d 2e 73 74 61   = sRegex[:m.sta
1d80: 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a 20 20  rt()].strip().  
1d90: 20 20 69 66 20 22 3c 6a 73 3e 22 20 69 6e 20 73    if "<js>" in s
1da0: 52 65 67 65 78 20 6f 72 20 22 3c 2f 6a 73 3e 22  Regex or "</js>"
1db0: 20 69 6e 20 73 52 65 67 65 78 3a 0a 20 20 20 20   in sRegex:.    
1dc0: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
1dd0: 6f 72 3a 20 4a 61 76 61 53 63 72 69 70 74 20 72  or: JavaScript r
1de0: 65 67 65 78 20 6e 6f 74 20 64 65 6c 69 6d 69 74  egex not delimit
1df0: 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  ed at line " + s
1e00: 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20  LineId).        
1e10: 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20  return None..   
1e20: 20 23 20 71 75 6f 74 65 73 20 3f 0a 20 20 20 20   # quotes ?.    
1e30: 69 66 20 73 52 65 67 65 78 2e 73 74 61 72 74 73  if sRegex.starts
1e40: 77 69 74 68 28 27 22 27 29 20 61 6e 64 20 73 52  with('"') and sR
1e50: 65 67 65 78 2e 65 6e 64 73 77 69 74 68 28 27 22  egex.endswith('"
1e60: 27 29 3a 0a 20 20 20 20 20 20 20 20 73 52 65 67  '):.        sReg
1e70: 65 78 20 3d 20 73 52 65 67 65 78 5b 31 3a 2d 31  ex = sRegex[1:-1
1e80: 5d 0a 0a 20 20 20 20 23 23 20 64 65 66 69 6e 69  ]..    ## defini
1e90: 74 69 6f 6e 73 0a 20 20 20 20 66 6f 72 20 73 44  tions.    for sD
1ea0: 65 66 2c 20 73 52 65 70 6c 20 69 6e 20 64 44 45  ef, sRepl in dDE
1eb0: 46 2e 69 74 65 6d 73 28 29 3a 0a 20 20 20 20 20  F.items():.     
1ec0: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
1ed0: 65 78 2e 72 65 70 6c 61 63 65 28 73 44 65 66 2c  ex.replace(sDef,
1ee0: 20 73 52 65 70 6c 29 0a 0a 20 20 20 20 23 23 20   sRepl)..    ## 
1ef0: 63 6f 75 6e 74 20 6e 75 6d 62 65 72 20 6f 66 20  count number of 
1f00: 67 72 6f 75 70 73 20 28 6d 75 73 74 20 62 65 20  groups (must be 
1f10: 64 6f 6e 65 20 62 65 66 6f 72 65 20 6d 6f 64 69  done before modi
1f20: 66 79 69 6e 67 20 74 68 65 20 72 65 67 65 78 29  fying the regex)
1f30: 0a 20 20 20 20 6e 47 72 6f 75 70 20 3d 20 63 6f  .    nGroup = co
1f40: 75 6e 74 47 72 6f 75 70 49 6e 52 65 67 65 78 28  untGroupInRegex(
1f50: 73 52 65 67 65 78 29 0a 20 20 20 20 69 66 20 6e  sRegex).    if n
1f60: 47 72 6f 75 70 20 3e 20 30 3a 0a 20 20 20 20 20  Group > 0:.     
1f70: 20 20 20 69 66 20 6e 6f 74 20 74 47 72 6f 75 70     if not tGroup
1f80: 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  s:.            p
1f90: 72 69 6e 74 28 22 23 20 57 61 72 6e 69 6e 67 3a  rint("# Warning:
1fa0: 20 67 72 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e   groups position
1fb0: 69 6e 67 20 63 6f 64 65 20 66 6f 72 20 4a 61 76  ing code for Jav
1fc0: 61 53 63 72 69 70 74 20 73 68 6f 75 6c 64 20 62  aScript should b
1fd0: 65 20 64 65 66 69 6e 65 64 20 61 74 20 6c 69 6e  e defined at lin
1fe0: 65 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 20  e " + sLineId). 
1ff0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2000: 20 20 20 20 20 20 20 20 20 69 66 20 6e 47 72 6f           if nGro
2010: 75 70 20 21 3d 20 6c 65 6e 28 74 47 72 6f 75 70  up != len(tGroup
2020: 73 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  s):.            
2030: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
2040: 6f 72 3a 20 67 72 6f 75 70 73 20 70 6f 73 69 74  or: groups posit
2050: 69 6f 6e 69 6e 67 20 63 6f 64 65 20 69 72 72 65  ioning code irre
2060: 6c 65 76 61 6e 74 20 61 74 20 6c 69 6e 65 20 22  levant at line "
2070: 20 2b 20 73 4c 69 6e 65 49 64 29 0a 0a 20 20 20   + sLineId)..   
2080: 20 23 23 20 77 6f 72 64 20 6c 69 6d 69 74 0a 20   ## word limit. 
2090: 20 20 20 69 66 20 63 57 6f 72 64 4c 69 6d 69 74     if cWordLimit
20a0: 4c 65 66 74 20 3d 3d 20 27 5b 27 20 61 6e 64 20  Left == '[' and 
20b0: 6e 6f 74 20 73 52 65 67 65 78 2e 73 74 61 72 74  not sRegex.start
20c0: 73 77 69 74 68 28 28 22 5e 22 2c 20 27 e2 80 99  swith(("^", '...
20d0: 27 2c 20 22 27 22 2c 20 22 2c 22 29 29 3a 0a 20  ', "'", ",")):. 
20e0: 20 20 20 20 20 20 20 73 52 65 67 65 78 20 3d 20         sRegex = 
20f0: 73 57 4f 52 44 4c 49 4d 49 54 4c 45 46 54 20 2b  sWORDLIMITLEFT +
2100: 20 73 52 65 67 65 78 0a 20 20 20 20 69 66 20 63   sRegex.    if c
2110: 57 6f 72 64 4c 69 6d 69 74 52 69 67 68 74 20 3d  WordLimitRight =
2120: 3d 20 27 5d 27 20 61 6e 64 20 6e 6f 74 20 73 52  = ']' and not sR
2130: 65 67 65 78 2e 65 6e 64 73 77 69 74 68 28 28 22  egex.endswith(("
2140: 24 22 2c 20 27 e2 80 99 27 2c 20 22 27 22 2c 20  $", '...', "'", 
2150: 22 2c 22 29 29 3a 0a 20 20 20 20 20 20 20 20 73  ",")):.        s
2160: 52 65 67 65 78 20 3d 20 73 52 65 67 65 78 20 2b  Regex = sRegex +
2170: 20 73 57 4f 52 44 4c 49 4d 49 54 52 49 47 48 54   sWORDLIMITRIGHT
2180: 0a 0a 20 20 20 20 23 23 20 63 61 73 69 6e 67 20  ..    ## casing 
2190: 6d 6f 64 65 0a 20 20 20 20 69 66 20 63 43 61 73  mode.    if cCas
21a0: 65 4d 6f 64 65 20 3d 3d 20 22 69 22 3a 0a 20 20  eMode == "i":.  
21b0: 20 20 20 20 20 20 62 43 61 73 65 49 6e 73 65 6e        bCaseInsen
21c0: 73 69 74 69 76 65 20 3d 20 54 72 75 65 0a 20 20  sitive = True.  
21d0: 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73 52 65        if not sRe
21e0: 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28 22  gex.startswith("
21f0: 28 3f 69 29 22 29 3a 0a 20 20 20 20 20 20 20 20  (?i)"):.        
2200: 20 20 20 20 73 52 65 67 65 78 20 3d 20 22 28 3f      sRegex = "(?
2210: 69 29 22 20 2b 20 73 52 65 67 65 78 0a 20 20 20  i)" + sRegex.   
2220: 20 65 6c 69 66 20 63 43 61 73 65 4d 6f 64 65 20   elif cCaseMode 
2230: 3d 3d 20 22 73 22 3a 0a 20 20 20 20 20 20 20 20  == "s":.        
2240: 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65  bCaseInsensitive
2250: 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20   = False.       
2260: 20 73 52 65 67 65 78 20 3d 20 73 52 65 67 65 78   sRegex = sRegex
2270: 2e 72 65 70 6c 61 63 65 28 22 28 3f 69 29 22 2c  .replace("(?i)",
2280: 20 22 22 29 0a 20 20 20 20 65 6c 69 66 20 63 43   "").    elif cC
2290: 61 73 65 4d 6f 64 65 20 3d 3d 20 22 75 22 3a 0a  aseMode == "u":.
22a0: 20 20 20 20 20 20 20 20 62 43 61 73 65 49 6e 73          bCaseIns
22b0: 65 6e 73 69 74 69 76 65 20 3d 20 46 61 6c 73 65  ensitive = False
22c0: 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78 20  .        sRegex 
22d0: 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61 63 65  = sRegex.replace
22e0: 28 22 28 3f 69 29 22 2c 20 22 22 29 0a 20 20 20  ("(?i)", "").   
22f0: 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 75 70       sRegex = up
2300: 70 65 72 63 61 73 65 28 73 52 65 67 65 78 2c 20  percase(sRegex, 
2310: 73 4c 61 6e 67 29 0a 20 20 20 20 65 6c 73 65 3a  sLang).    else:
2320: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
2330: 23 20 55 6e 6b 6e 6f 77 6e 20 63 61 73 65 20 6d  # Unknown case m
2340: 6f 64 65 20 5b 22 20 2b 20 63 43 61 73 65 4d 6f  ode [" + cCaseMo
2350: 64 65 20 2b 20 22 5d 20 61 74 20 6c 69 6e 65 20  de + "] at line 
2360: 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 0a 20 20  " + sLineId)..  
2370: 20 20 23 23 20 63 68 65 63 6b 20 72 65 67 65 78    ## check regex
2380: 0a 20 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20  .    try:.      
2390: 20 20 7a 20 3d 20 72 65 2e 63 6f 6d 70 69 6c 65    z = re.compile
23a0: 28 73 52 65 67 65 78 29 0a 20 20 20 20 65 78 63  (sRegex).    exc
23b0: 65 70 74 3a 0a 20 20 20 20 20 20 20 20 70 72 69  ept:.        pri
23c0: 6e 74 28 22 23 20 52 65 67 65 78 20 65 72 72 6f  nt("# Regex erro
23d0: 72 20 61 74 20 6c 69 6e 65 20 22 2c 20 6e 49 64  r at line ", nId
23e0: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 70 72  Line).        pr
23f0: 69 6e 74 28 73 52 65 67 65 78 29 0a 20 20 20 20  int(sRegex).    
2400: 20 20 20 20 74 72 61 63 65 62 61 63 6b 2e 70 72      traceback.pr
2410: 69 6e 74 5f 65 78 63 28 29 0a 20 20 20 20 20 20  int_exc().      
2420: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20    return None.  
2430: 20 20 23 23 20 67 72 6f 75 70 73 20 69 6e 20 6e    ## groups in n
2440: 6f 6e 20 67 72 6f 75 70 69 6e 67 20 70 61 72 65  on grouping pare
2450: 6e 74 68 65 73 69 73 0a 20 20 20 20 66 6f 72 20  nthesis.    for 
2460: 78 20 69 6e 20 72 65 2e 66 69 6e 64 69 74 65 72  x in re.finditer
2470: 28 22 5c 28 5c 3f 3a 5b 5e 29 5d 2a 5c 28 5b 5b  ("\(\?:[^)]*\([[
2480: 5c 77 20 2d 5d 22 2c 20 73 52 65 67 65 78 29 3a  \w -]", sRegex):
2490: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
24a0: 23 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f 75 70  # Warning: group
24b0: 73 20 69 6e 73 69 64 65 20 6e 6f 6e 20 67 72 6f  s inside non gro
24c0: 75 70 69 6e 67 20 70 61 72 65 6e 74 68 65 73 69  uping parenthesi
24d0: 73 20 69 6e 20 72 65 67 65 78 20 61 74 20 6c 69  s in regex at li
24e0: 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a  ne " + sLineId).
24f0: 0a 20 20 20 20 23 23 23 23 20 50 41 52 53 45 20  .    #### PARSE 
2500: 41 43 54 49 4f 4e 53 0a 20 20 20 20 6c 41 63 74  ACTIONS.    lAct
2510: 69 6f 6e 73 20 3d 20 5b 5d 0a 20 20 20 20 6e 41  ions = [].    nA
2520: 63 74 69 6f 6e 20 3d 20 31 0a 20 20 20 20 66 6f  ction = 1.    fo
2530: 72 20 73 41 63 74 69 6f 6e 20 69 6e 20 73 2e 73  r sAction in s.s
2540: 70 6c 69 74 28 22 20 3c 3c 2d 20 22 29 3a 0a 20  plit(" <<- "):. 
2550: 20 20 20 20 20 20 20 74 20 3d 20 63 72 65 61 74         t = creat
2560: 65 41 63 74 69 6f 6e 28 73 52 75 6c 65 49 64 20  eAction(sRuleId 
2570: 2b 20 22 5f 22 20 2b 20 73 74 72 28 6e 41 63 74  + "_" + str(nAct
2580: 69 6f 6e 29 2c 20 73 41 63 74 69 6f 6e 2c 20 6e  ion), sAction, n
2590: 47 72 6f 75 70 29 0a 20 20 20 20 20 20 20 20 6e  Group).        n
25a0: 41 63 74 69 6f 6e 20 2b 3d 20 31 0a 20 20 20 20  Action += 1.    
25b0: 20 20 20 20 69 66 20 74 3a 0a 20 20 20 20 20 20      if t:.      
25c0: 20 20 20 20 20 20 6c 41 63 74 69 6f 6e 73 2e 61        lActions.a
25d0: 70 70 65 6e 64 28 74 29 0a 20 20 20 20 69 66 20  ppend(t).    if 
25e0: 6e 6f 74 20 6c 41 63 74 69 6f 6e 73 3a 0a 20 20  not lActions:.  
25f0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e        return Non
2600: 65 0a 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 73  e..    return [s
2610: 4f 70 74 69 6f 6e 2c 20 73 52 65 67 65 78 2c 20  Option, sRegex, 
2620: 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65  bCaseInsensitive
2630: 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75 6c 65  , sLineId, sRule
2640: 49 64 2c 20 6e 50 72 69 6f 72 69 74 79 2c 20 6c  Id, nPriority, l
2650: 41 63 74 69 6f 6e 73 2c 20 74 47 72 6f 75 70 73  Actions, tGroups
2660: 5d 0a 0a 0a 64 65 66 20 63 72 65 61 74 65 41 63  ]...def createAc
2670: 74 69 6f 6e 20 28 73 49 64 41 63 74 69 6f 6e 2c  tion (sIdAction,
2680: 20 73 41 63 74 69 6f 6e 2c 20 6e 47 72 6f 75 70   sAction, nGroup
2690: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20  ):.    "returns 
26a0: 61 6e 20 61 63 74 69 6f 6e 20 74 6f 20 70 65 72  an action to per
26b0: 66 6f 72 6d 20 61 73 20 61 20 74 75 70 6c 65 20  form as a tuple 
26c0: 28 63 6f 6e 64 69 74 69 6f 6e 2c 20 61 63 74 69  (condition, acti
26d0: 6f 6e 20 74 79 70 65 2c 20 61 63 74 69 6f 6e 5b  on type, action[
26e0: 2c 20 69 47 72 6f 75 70 20 5b 2c 20 6d 65 73 73  , iGroup [, mess
26f0: 61 67 65 2c 20 55 52 4c 20 5d 5d 29 22 0a 20 20  age, URL ]])".  
2700: 20 20 67 6c 6f 62 61 6c 20 6c 46 55 4e 43 54 49    global lFUNCTI
2710: 4f 4e 53 0a 0a 20 20 20 20 6d 20 3d 20 72 65 2e  ONS..    m = re.
2720: 73 65 61 72 63 68 28 72 22 28 5b 2d 7e 3d 3e 5d  search(r"([-~=>]
2730: 29 28 5c 64 2a 7c 29 3e 3e 22 2c 20 73 41 63 74  )(\d*|)>>", sAct
2740: 69 6f 6e 29 0a 20 20 20 20 69 66 20 6e 6f 74 20  ion).    if not 
2750: 6d 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  m:.        print
2760: 28 22 23 20 4e 6f 20 61 63 74 69 6f 6e 20 61 74  ("# No action at
2770: 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74   line " + sIdAct
2780: 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 72 65 74  ion).        ret
2790: 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20 20 23 23  urn None..    ##
27a0: 23 23 20 43 4f 4e 44 49 54 49 4f 4e 0a 20 20 20  ## CONDITION.   
27b0: 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 73 41   sCondition = sA
27c0: 63 74 69 6f 6e 5b 3a 6d 2e 73 74 61 72 74 28 29  ction[:m.start()
27d0: 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 69 66  ].strip().    if
27e0: 20 73 43 6f 6e 64 69 74 69 6f 6e 3a 0a 20 20 20   sCondition:.   
27f0: 20 20 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e 20       sCondition 
2800: 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74 69 6f  = prepareFunctio
2810: 6e 28 73 43 6f 6e 64 69 74 69 6f 6e 29 0a 20 20  n(sCondition).  
2820: 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e 53        lFUNCTIONS
2830: 2e 61 70 70 65 6e 64 28 28 22 63 5f 22 2b 73 49  .append(("c_"+sI
2840: 64 41 63 74 69 6f 6e 2c 20 73 43 6f 6e 64 69 74  dAction, sCondit
2850: 69 6f 6e 29 29 0a 20 20 20 20 20 20 20 20 66 6f  ion)).        fo
2860: 72 20 78 20 69 6e 20 72 65 2e 66 69 6e 64 69 74  r x in re.findit
2870: 65 72 28 22 5b 2e 5d 28 3f 3a 67 72 6f 75 70 7c  er("[.](?:group|
2880: 73 74 61 72 74 7c 65 6e 64 29 5b 28 5d 28 5c 64  start|end)[(](\d
2890: 2b 29 5b 29 5d 22 2c 20 73 43 6f 6e 64 69 74 69  +)[)]", sConditi
28a0: 6f 6e 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  on):.           
28b0: 20 69 66 20 69 6e 74 28 78 2e 67 72 6f 75 70 28   if int(x.group(
28c0: 31 29 29 20 3e 20 6e 47 72 6f 75 70 3a 0a 20 20  1)) > nGroup:.  
28d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
28e0: 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20  int("# Error in 
28f0: 67 72 6f 75 70 73 20 69 6e 20 63 6f 6e 64 69 74  groups in condit
2900: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
2910: 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 20 28 22  sIdAction + " ("
2920: 2b 73 74 72 28 6e 47 72 6f 75 70 29 2b 22 20 67  +str(nGroup)+" g
2930: 72 6f 75 70 73 20 6f 6e 6c 79 29 22 29 0a 20 20  roups only)").  
2940: 20 20 20 20 20 20 69 66 20 22 2e 6d 61 74 63 68        if ".match
2950: 22 20 69 6e 20 73 43 6f 6e 64 69 74 69 6f 6e 3a  " in sCondition:
2960: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
2970: 6e 74 28 22 23 20 45 72 72 6f 72 2e 20 4a 53 20  nt("# Error. JS 
2980: 63 6f 6d 70 61 74 69 62 69 6c 69 74 79 2e 20 44  compatibility. D
2990: 6f 6e 27 74 20 75 73 65 20 2e 6d 61 74 63 68 28  on't use .match(
29a0: 29 20 69 6e 20 63 6f 6e 64 69 74 69 6f 6e 2c 20  ) in condition, 
29b0: 75 73 65 20 2e 73 65 61 72 63 68 28 29 22 29 0a  use .search()").
29c0: 20 20 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69          sConditi
29d0: 6f 6e 20 3d 20 22 63 5f 22 2b 73 49 64 41 63 74  on = "c_"+sIdAct
29e0: 69 6f 6e 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  ion.    else:.  
29f0: 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e        sCondition
2a00: 20 3d 20 4e 6f 6e 65 0a 0a 20 20 20 20 23 23 23   = None..    ###
2a10: 23 20 69 47 72 6f 75 70 20 2f 20 70 6f 73 69 74  # iGroup / posit
2a20: 69 6f 6e 69 6e 67 0a 20 20 20 20 69 47 72 6f 75  ioning.    iGrou
2a30: 70 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75 70 28  p = int(m.group(
2a40: 32 29 29 20 69 66 20 6d 2e 67 72 6f 75 70 28 32  2)) if m.group(2
2a50: 29 20 65 6c 73 65 20 30 0a 20 20 20 20 69 66 20  ) else 0.    if 
2a60: 69 47 72 6f 75 70 20 3e 20 6e 47 72 6f 75 70 3a  iGroup > nGroup:
2a70: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
2a80: 23 20 53 65 6c 65 63 74 65 64 20 67 72 6f 75 70  # Selected group
2a90: 20 3e 20 67 72 6f 75 70 20 6e 75 6d 62 65 72 20   > group number 
2aa0: 69 6e 20 72 65 67 65 78 20 61 74 20 6c 69 6e 65  in regex at line
2ab0: 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a   " + sIdAction).
2ac0: 20 20 20 20 0a 20 20 20 20 23 23 23 23 20 41 43      .    #### AC
2ad0: 54 49 4f 4e 0a 20 20 20 20 73 41 63 74 69 6f 6e  TION.    sAction
2ae0: 20 3d 20 73 41 63 74 69 6f 6e 5b 6d 2e 65 6e 64   = sAction[m.end
2af0: 28 29 3a 5d 2e 73 74 72 69 70 28 29 0a 20 20 20  ():].strip().   
2b00: 20 63 41 63 74 69 6f 6e 20 3d 20 6d 2e 67 72 6f   cAction = m.gro
2b10: 75 70 28 31 29 0a 20 20 20 20 69 66 20 63 41 63  up(1).    if cAc
2b20: 74 69 6f 6e 20 3d 3d 20 22 2d 22 3a 0a 20 20 20  tion == "-":.   
2b30: 20 20 20 20 20 23 23 20 65 72 72 6f 72 0a 20 20       ## error.  
2b40: 20 20 20 20 20 20 69 4d 73 67 20 3d 20 73 41 63        iMsg = sAc
2b50: 74 69 6f 6e 2e 66 69 6e 64 28 22 20 23 20 22 29  tion.find(" # ")
2b60: 0a 20 20 20 20 20 20 20 20 69 66 20 69 4d 73 67  .        if iMsg
2b70: 20 3d 3d 20 2d 31 3a 0a 20 20 20 20 20 20 20 20   == -1:.        
2b80: 20 20 20 20 73 4d 73 67 20 3d 20 22 23 20 45 72      sMsg = "# Er
2b90: 72 6f 72 2e 20 45 72 72 6f 72 20 6d 65 73 73 61  ror. Error messa
2ba0: 67 65 20 6e 6f 74 20 66 6f 75 6e 64 2e 22 0a 20  ge not found.". 
2bb0: 20 20 20 20 20 20 20 20 20 20 20 73 55 52 4c 20             sURL 
2bc0: 3d 20 22 22 0a 20 20 20 20 20 20 20 20 20 20 20  = "".           
2bd0: 20 70 72 69 6e 74 28 73 4d 73 67 20 2b 20 22 20   print(sMsg + " 
2be0: 41 63 74 69 6f 6e 20 69 64 3a 20 22 20 2b 20 73  Action id: " + s
2bf0: 49 64 41 63 74 69 6f 6e 29 0a 20 20 20 20 20 20  IdAction).      
2c00: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
2c10: 20 20 20 20 73 4d 73 67 20 3d 20 73 41 63 74 69      sMsg = sActi
2c20: 6f 6e 5b 69 4d 73 67 2b 33 3a 5d 2e 73 74 72 69  on[iMsg+3:].stri
2c30: 70 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  p().            
2c40: 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f  sAction = sActio
2c50: 6e 5b 3a 69 4d 73 67 5d 2e 73 74 72 69 70 28 29  n[:iMsg].strip()
2c60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 55 52  .            sUR
2c70: 4c 20 3d 20 22 22 0a 20 20 20 20 20 20 20 20 20  L = "".         
2c80: 20 20 20 6d 55 52 4c 20 3d 20 72 65 2e 73 65 61     mURL = re.sea
2c90: 72 63 68 28 22 5b 7c 5d 20 2a 28 68 74 74 70 73  rch("[|] *(https
2ca0: 3f 3a 2f 2f 2e 2a 29 22 2c 20 73 4d 73 67 29 0a  ?://.*)", sMsg).
2cb0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6d              if m
2cc0: 55 52 4c 3a 0a 20 20 20 20 20 20 20 20 20 20 20  URL:.           
2cd0: 20 20 20 20 20 73 55 52 4c 20 3d 20 6d 55 52 4c       sURL = mURL
2ce0: 2e 67 72 6f 75 70 28 31 29 2e 73 74 72 69 70 28  .group(1).strip(
2cf0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
2d00: 20 20 73 4d 73 67 20 3d 20 73 4d 73 67 5b 3a 6d    sMsg = sMsg[:m
2d10: 55 52 4c 2e 73 74 61 72 74 28 30 29 5d 2e 73 74  URL.start(0)].st
2d20: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20  rip().          
2d30: 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20 3d    if sMsg[0:1] =
2d40: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20  = "=":.         
2d50: 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 70 72         sMsg = pr
2d60: 65 70 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 4d  epareFunction(sM
2d70: 73 67 5b 31 3a 5d 29 0a 20 20 20 20 20 20 20 20  sg[1:]).        
2d80: 20 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f          lFUNCTIO
2d90: 4e 53 2e 61 70 70 65 6e 64 28 28 22 6d 5f 22 2b  NS.append(("m_"+
2da0: 73 49 64 41 63 74 69 6f 6e 2c 20 73 4d 73 67 29  sIdAction, sMsg)
2db0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
2dc0: 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69    for x in re.fi
2dd0: 6e 64 69 74 65 72 28 22 67 72 6f 75 70 5b 28 5d  nditer("group[(]
2de0: 28 5c 64 2b 29 5b 29 5d 22 2c 20 73 4d 73 67 29  (\d+)[)]", sMsg)
2df0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2e00: 20 20 20 20 20 20 69 66 20 69 6e 74 28 78 2e 67        if int(x.g
2e10: 72 6f 75 70 28 31 29 29 20 3e 20 6e 47 72 6f 75  roup(1)) > nGrou
2e20: 70 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  p:.             
2e30: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
2e40: 28 22 23 20 45 72 72 6f 72 20 69 6e 20 67 72 6f  ("# Error in gro
2e50: 75 70 73 20 69 6e 20 6d 65 73 73 61 67 65 20 61  ups in message a
2e60: 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63  t line " + sIdAc
2e70: 74 69 6f 6e 20 2b 20 22 20 28 22 2b 73 74 72 28  tion + " ("+str(
2e80: 6e 47 72 6f 75 70 29 2b 22 20 67 72 6f 75 70 73  nGroup)+" groups
2e90: 20 6f 6e 6c 79 29 22 29 0a 20 20 20 20 20 20 20   only)").       
2ea0: 20 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20           sMsg = 
2eb0: 22 3d 6d 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a  "=m_"+sIdAction.
2ec0: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
2ed0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2ee0: 20 20 66 6f 72 20 78 20 69 6e 20 72 65 2e 66 69    for x in re.fi
2ef0: 6e 64 69 74 65 72 28 72 22 5c 5c 28 5c 64 2b 29  nditer(r"\\(\d+)
2f00: 22 2c 20 73 4d 73 67 29 3a 0a 20 20 20 20 20 20  ", sMsg):.      
2f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
2f20: 20 69 6e 74 28 78 2e 67 72 6f 75 70 28 31 29 29   int(x.group(1))
2f30: 20 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20 20   > nGroup:.     
2f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f50: 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f     print("# Erro
2f60: 72 20 69 6e 20 67 72 6f 75 70 73 20 69 6e 20 6d  r in groups in m
2f70: 65 73 73 61 67 65 20 61 74 20 6c 69 6e 65 20 22  essage at line "
2f80: 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22   + sIdAction + "
2f90: 20 28 22 2b 73 74 72 28 6e 47 72 6f 75 70 29 2b   ("+str(nGroup)+
2fa0: 22 20 67 72 6f 75 70 73 20 6f 6e 6c 79 29 22 29  " groups only)")
2fb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2fc0: 20 69 66 20 72 65 2e 73 65 61 72 63 68 28 22 5b   if re.search("[
2fd0: 2e 5d 5c 5c 77 2b 5b 28 5d 22 2c 20 73 4d 73 67  .]\\w+[(]", sMsg
2fe0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
2ff0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
3000: 45 72 72 6f 72 20 69 6e 20 6d 65 73 73 61 67 65  Error in message
3010: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64   at line " + sId
3020: 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 54 68 69  Action + ":  Thi
3030: 73 20 6d 65 73 73 61 67 65 20 6c 6f 6f 6b 73 20  s message looks 
3040: 6c 69 6b 65 20 63 6f 64 65 2e 20 4c 69 6e 65 20  like code. Line 
3050: 73 68 6f 75 6c 64 20 62 65 67 69 6e 20 77 69 74  should begin wit
3060: 68 20 3d 22 29 0a 20 20 20 20 20 20 20 20 20 20  h =").          
3070: 20 20 0a 20 20 20 20 69 66 20 73 41 63 74 69 6f    .    if sActio
3080: 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 20 6f 72  n[0:1] == "=" or
3090: 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d 22 3a   cAction == "=":
30a0: 0a 20 20 20 20 20 20 20 20 69 66 20 22 64 65 66  .        if "def
30b0: 69 6e 65 22 20 69 6e 20 73 41 63 74 69 6f 6e 20  ine" in sAction 
30c0: 61 6e 64 20 6e 6f 74 20 72 65 2e 73 65 61 72 63  and not re.searc
30d0: 68 28 72 22 64 65 66 69 6e 65 5c 28 5c 5c 5c 64  h(r"define\(\\\d
30e0: 2b 20 2a 2c 20 2a 5c 5b 2e 2a 5c 5d 20 2a 5c 29  + *, *\[.*\] *\)
30f0: 22 2c 20 73 41 63 74 69 6f 6e 29 3a 0a 20 20 20  ", sAction):.   
3100: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3110: 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f  # Error in actio
3120: 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  n at line " + sI
3130: 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 73 65 63  dAction + ": sec
3140: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 66 6f 72  ond argument for
3150: 20 64 65 66 69 6e 65 20 6d 75 73 74 20 62 65 20   define must be 
3160: 61 20 6c 69 73 74 20 6f 66 20 73 74 72 69 6e 67  a list of string
3170: 73 22 29 0a 20 20 20 20 20 20 20 20 73 41 63 74  s").        sAct
3180: 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46 75 6e  ion = prepareFun
3190: 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 29 0a 20  ction(sAction). 
31a0: 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d         sAction =
31b0: 20 73 41 63 74 69 6f 6e 2e 72 65 70 6c 61 63 65   sAction.replace
31c0: 28 22 6d 2e 67 72 6f 75 70 28 69 5b 34 5d 29 22  ("m.group(i[4])"
31d0: 2c 20 22 6d 2e 67 72 6f 75 70 28 22 2b 73 74 72  , "m.group("+str
31e0: 28 69 47 72 6f 75 70 29 2b 22 29 22 29 0a 20 20  (iGroup)+")").  
31f0: 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72        for x in r
3200: 65 2e 66 69 6e 64 69 74 65 72 28 22 67 72 6f 75  e.finditer("grou
3210: 70 5b 28 5d 28 5c 64 2b 29 5b 29 5d 22 2c 20 73  p[(](\d+)[)]", s
3220: 41 63 74 69 6f 6e 29 3a 0a 20 20 20 20 20 20 20  Action):.       
3230: 20 20 20 20 20 69 66 20 69 6e 74 28 78 2e 67 72       if int(x.gr
3240: 6f 75 70 28 31 29 29 20 3e 20 6e 47 72 6f 75 70  oup(1)) > nGroup
3250: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
3260: 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72    print("# Error
3270: 20 69 6e 20 67 72 6f 75 70 73 20 69 6e 20 72 65   in groups in re
3280: 70 6c 61 63 65 6d 65 6e 74 20 61 74 20 6c 69 6e  placement at lin
3290: 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20  e " + sIdAction 
32a0: 2b 20 22 20 28 22 2b 73 74 72 28 6e 47 72 6f 75  + " ("+str(nGrou
32b0: 70 29 2b 22 20 67 72 6f 75 70 73 20 6f 6e 6c 79  p)+" groups only
32c0: 29 22 29 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  )").    else:.  
32d0: 20 20 20 20 20 20 66 6f 72 20 78 20 69 6e 20 72        for x in r
32e0: 65 2e 66 69 6e 64 69 74 65 72 28 72 22 5c 5c 28  e.finditer(r"\\(
32f0: 5c 64 2b 29 22 2c 20 73 41 63 74 69 6f 6e 29 3a  \d+)", sAction):
3300: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
3310: 69 6e 74 28 78 2e 67 72 6f 75 70 28 31 29 29 20  int(x.group(1)) 
3320: 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20 20 20  > nGroup:.      
3330: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
3340: 22 23 20 45 72 72 6f 72 20 69 6e 20 67 72 6f 75  "# Error in grou
3350: 70 73 20 69 6e 20 72 65 70 6c 61 63 65 6d 65 6e  ps in replacemen
3360: 74 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  t at line " + sI
3370: 64 41 63 74 69 6f 6e 20 2b 20 22 20 28 22 2b 73  dAction + " ("+s
3380: 74 72 28 6e 47 72 6f 75 70 29 2b 22 20 67 72 6f  tr(nGroup)+" gro
3390: 75 70 73 20 6f 6e 6c 79 29 22 29 0a 20 20 20 20  ups only)").    
33a0: 20 20 20 20 69 66 20 72 65 2e 73 65 61 72 63 68      if re.search
33b0: 28 22 5b 2e 5d 5c 5c 77 2b 5b 28 5d 7c 73 75 67  ("[.]\\w+[(]|sug
33c0: 67 5c 5c 77 2b 5b 28 5d 22 2c 20 73 41 63 74 69  g\\w+[(]", sActi
33d0: 6f 6e 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  on):.           
33e0: 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20   print("# Error 
33f0: 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e  in action at lin
3400: 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20  e " + sIdAction 
3410: 2b 20 22 3a 20 20 54 68 69 73 20 61 63 74 69 6f  + ":  This actio
3420: 6e 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 63 6f 64  n looks like cod
3430: 65 2e 20 4c 69 6e 65 20 73 68 6f 75 6c 64 20 62  e. Line should b
3440: 65 67 69 6e 20 77 69 74 68 20 3d 22 29 0a 0a 20  egin with =").. 
3450: 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d     if cAction ==
3460: 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 23 23   "-":.        ##
3470: 20 65 72 72 6f 72 20 64 65 74 65 63 74 65 64 20   error detected 
3480: 2d 2d 3e 20 73 75 67 67 65 73 74 69 6f 6e 0a 20  --> suggestion. 
3490: 20 20 20 20 20 20 20 69 66 20 6e 6f 74 20 73 41         if not sA
34a0: 63 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20  ction:.         
34b0: 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f     print("# Erro
34c0: 72 20 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c  r in action at l
34d0: 69 6e 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f  ine " + sIdActio
34e0: 6e 20 2b 20 22 3a 20 20 54 68 69 73 20 61 63 74  n + ":  This act
34f0: 69 6f 6e 20 69 73 20 65 6d 70 74 79 2e 22 29 0a  ion is empty.").
3500: 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69          if sActi
3510: 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a  on[0:1] == "=":.
3520: 20 20 20 20 20 20 20 20 20 20 20 20 6c 46 55 4e              lFUN
3530: 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22  CTIONS.append(("
3540: 73 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73  s_"+sIdAction, s
3550: 41 63 74 69 6f 6e 5b 31 3a 5d 29 29 0a 20 20 20  Action[1:])).   
3560: 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e           sAction
3570: 20 3d 20 22 3d 73 5f 22 2b 73 49 64 41 63 74 69   = "=s_"+sIdActi
3580: 6f 6e 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  on.        elif 
3590: 73 41 63 74 69 6f 6e 2e 73 74 61 72 74 73 77 69  sAction.startswi
35a0: 74 68 28 27 22 27 29 20 61 6e 64 20 73 41 63 74  th('"') and sAct
35b0: 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28 27 22 27  ion.endswith('"'
35c0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ):.            s
35d0: 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e  Action = sAction
35e0: 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20 69  [1:-1].        i
35f0: 66 20 6e 6f 74 20 73 4d 73 67 3a 0a 20 20 20 20  f not sMsg:.    
3600: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
3610: 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f 6e   Error in action
3620: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64   at line " + sId
3630: 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 74 68 65  Action + ":  the
3640: 20 6d 65 73 73 61 67 65 20 69 73 20 65 6d 70 74   message is empt
3650: 79 2e 22 29 0a 20 20 20 20 20 20 20 20 72 65 74  y.").        ret
3660: 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c  urn [sCondition,
3670: 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f   cAction, sActio
3680: 6e 2c 20 69 47 72 6f 75 70 2c 20 73 4d 73 67 2c  n, iGroup, sMsg,
3690: 20 73 55 52 4c 5d 0a 20 20 20 20 65 6c 69 66 20   sURL].    elif 
36a0: 63 41 63 74 69 6f 6e 20 3d 3d 20 22 7e 22 3a 0a  cAction == "~":.
36b0: 20 20 20 20 20 20 20 20 23 23 20 74 65 78 74 20          ## text 
36c0: 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20 20 20  processor.      
36d0: 20 20 69 66 20 6e 6f 74 20 73 41 63 74 69 6f 6e    if not sAction
36e0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  :.            pr
36f0: 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20  int("# Error in 
3700: 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22  action at line "
3710: 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22   + sIdAction + "
3720: 3a 20 20 54 68 69 73 20 61 63 74 69 6f 6e 20 69  :  This action i
3730: 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20 20 20  s empty.").     
3740: 20 20 20 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a     if sAction[0:
3750: 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20  1] == "=":.     
3760: 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e         lFUNCTION
3770: 53 2e 61 70 70 65 6e 64 28 28 22 70 5f 22 2b 73  S.append(("p_"+s
3780: 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f  IdAction, sActio
3790: 6e 5b 31 3a 5d 29 29 0a 20 20 20 20 20 20 20 20  n[1:])).        
37a0: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 22 3d      sAction = "=
37b0: 70 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20  p_"+sIdAction.  
37c0: 20 20 20 20 20 20 65 6c 69 66 20 73 41 63 74 69        elif sActi
37d0: 6f 6e 2e 73 74 61 72 74 73 77 69 74 68 28 27 22  on.startswith('"
37e0: 27 29 20 61 6e 64 20 73 41 63 74 69 6f 6e 2e 65  ') and sAction.e
37f0: 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20 20  ndswith('"'):.  
3800: 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f            sActio
3810: 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 2d 31  n = sAction[1:-1
3820: 5d 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ].        return
3830: 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41   [sCondition, cA
3840: 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 2c 20  ction, sAction, 
3850: 69 47 72 6f 75 70 5d 0a 20 20 20 20 65 6c 69 66  iGroup].    elif
3860: 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d 22 3a   cAction == "=":
3870: 0a 20 20 20 20 20 20 20 20 23 23 20 64 69 73 61  .        ## disa
3880: 6d 62 69 67 75 61 74 6f 72 0a 20 20 20 20 20 20  mbiguator.      
3890: 20 20 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31    if sAction[0:1
38a0: 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20  ] == "=":.      
38b0: 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20        sAction = 
38c0: 73 41 63 74 69 6f 6e 5b 31 3a 5d 0a 20 20 20 20  sAction[1:].    
38d0: 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63 74 69      if not sActi
38e0: 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  on:.            
38f0: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69  print("# Error i
3900: 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65  n action at line
3910: 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b   " + sIdAction +
3920: 20 22 3a 20 20 54 68 69 73 20 61 63 74 69 6f 6e   ":  This action
3930: 20 69 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20   is empty.").   
3940: 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e 53 2e       lFUNCTIONS.
3950: 61 70 70 65 6e 64 28 28 22 64 5f 22 2b 73 49 64  append(("d_"+sId
3960: 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 29  Action, sAction)
3970: 29 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f  ).        sActio
3980: 6e 20 3d 20 22 64 5f 22 2b 73 49 64 41 63 74 69  n = "d_"+sIdActi
3990: 6f 6e 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  on.        retur
39a0: 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63  n [sCondition, c
39b0: 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 5d  Action, sAction]
39c0: 0a 20 20 20 20 65 6c 69 66 20 63 41 63 74 69 6f  .    elif cActio
39d0: 6e 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20 20 20  n == ">":.      
39e0: 20 20 23 23 20 6e 6f 20 61 63 74 69 6f 6e 2c 20    ## no action, 
39f0: 62 72 65 61 6b 20 6c 6f 6f 70 20 69 66 20 63 6f  break loop if co
3a00: 6e 64 69 74 69 6f 6e 20 69 73 20 46 61 6c 73 65  ndition is False
3a10: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3a20: 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41 63  [sCondition, cAc
3a30: 74 69 6f 6e 2c 20 22 22 5d 0a 20 20 20 20 65 6c  tion, ""].    el
3a40: 73 65 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e  se:.        prin
3a50: 74 28 22 23 20 55 6e 6b 6e 6f 77 6e 20 61 63 74  t("# Unknown act
3a60: 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ion at line " + 
3a70: 73 49 64 41 63 74 69 6f 6e 29 0a 20 20 20 20 20  sIdAction).     
3a80: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a     return None..
3a90: 0a 64 65 66 20 5f 63 61 6c 63 52 75 6c 65 73 53  .def _calcRulesS
3aa0: 74 61 74 73 20 28 6c 52 75 6c 65 73 29 3a 0a 20  tats (lRules):. 
3ab0: 20 20 20 64 20 3d 20 7b 27 3d 27 3a 30 2c 20 27     d = {'=':0, '
3ac0: 7e 27 3a 20 30 2c 20 27 2d 27 3a 20 30 2c 20 27  ~': 0, '-': 0, '
3ad0: 3e 27 3a 20 30 7d 0a 20 20 20 20 66 6f 72 20 61  >': 0}.    for a
3ae0: 52 75 6c 65 20 69 6e 20 6c 52 75 6c 65 73 3a 0a  Rule in lRules:.
3af0: 20 20 20 20 20 20 20 20 69 66 20 61 52 75 6c 65          if aRule
3b00: 5b 30 5d 20 21 3d 20 22 40 40 40 40 22 3a 0a 20  [0] != "@@@@":. 
3b10: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 61             for a
3b20: 41 63 74 69 6f 6e 20 69 6e 20 61 52 75 6c 65 5b  Action in aRule[
3b30: 36 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  6]:.            
3b40: 20 20 20 20 64 5b 61 41 63 74 69 6f 6e 5b 31 5d      d[aAction[1]
3b50: 5d 20 3d 20 64 5b 61 41 63 74 69 6f 6e 5b 31 5d  ] = d[aAction[1]
3b60: 5d 20 2b 20 31 0a 20 20 20 20 72 65 74 75 72 6e  ] + 1.    return
3b70: 20 28 64 2c 20 6c 65 6e 28 6c 52 75 6c 65 73 29   (d, len(lRules)
3b80: 29 0a 0a 0a 64 65 66 20 64 69 73 70 6c 61 79 53  )...def displayS
3b90: 74 61 74 73 20 28 6c 50 61 72 61 67 72 61 70 68  tats (lParagraph
3ba0: 52 75 6c 65 73 2c 20 6c 53 65 6e 74 65 6e 63 65  Rules, lSentence
3bb0: 52 75 6c 65 73 29 3a 0a 20 20 20 20 70 72 69 6e  Rules):.    prin
3bc0: 74 28 22 20 20 7b 3a 3e 31 38 7d 20 7b 3a 3e 31  t("  {:>18} {:>1
3bd0: 38 7d 20 7b 3a 3e 31 38 7d 20 7b 3a 3e 31 38 7d  8} {:>18} {:>18}
3be0: 22 2e 66 6f 72 6d 61 74 28 22 44 49 53 41 4d 42  ".format("DISAMB
3bf0: 49 47 55 41 54 4f 52 22 2c 20 22 54 45 58 54 20  IGUATOR", "TEXT 
3c00: 50 52 4f 43 45 53 53 4f 52 22 2c 20 22 47 52 41  PROCESSOR", "GRA
3c10: 4d 4d 41 52 20 43 48 45 43 4b 49 4e 47 22 2c 20  MMAR CHECKING", 
3c20: 22 52 45 47 45 58 22 29 29 0a 20 20 20 20 64 2c  "REGEX")).    d,
3c30: 20 6e 52 75 6c 65 20 3d 20 5f 63 61 6c 63 52 75   nRule = _calcRu
3c40: 6c 65 73 53 74 61 74 73 28 6c 50 61 72 61 67 72  lesStats(lParagr
3c50: 61 70 68 52 75 6c 65 73 29 0a 20 20 20 20 70 72  aphRules).    pr
3c60: 69 6e 74 28 22 c2 a7 20 7b 3a 3e 31 30 7d 20 61  int(".. {:>10} a
3c70: 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20 61 63  ctions {:>10} ac
3c80: 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20 61 63 74  tions {:>10} act
3c90: 69 6f 6e 73 20 20 69 6e 20 7b 3a 3e 38 7d 20 72  ions  in {:>8} r
3ca0: 75 6c 65 73 22 2e 66 6f 72 6d 61 74 28 64 5b 27  ules".format(d['
3cb0: 3d 27 5d 2c 20 64 5b 27 7e 27 5d 2c 20 64 5b 27  ='], d['~'], d['
3cc0: 2d 27 5d 2c 20 6e 52 75 6c 65 29 29 0a 20 20 20  -'], nRule)).   
3cd0: 20 64 2c 20 6e 52 75 6c 65 20 3d 20 5f 63 61 6c   d, nRule = _cal
3ce0: 63 52 75 6c 65 73 53 74 61 74 73 28 6c 53 65 6e  cRulesStats(lSen
3cf0: 74 65 6e 63 65 52 75 6c 65 73 29 0a 20 20 20 20  tenceRules).    
3d00: 70 72 69 6e 74 28 22 73 20 7b 3a 3e 31 30 7d 20  print("s {:>10} 
3d10: 61 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20 61  actions {:>10} a
3d20: 63 74 69 6f 6e 73 20 7b 3a 3e 31 30 7d 20 61 63  ctions {:>10} ac
3d30: 74 69 6f 6e 73 20 20 69 6e 20 7b 3a 3e 38 7d 20  tions  in {:>8} 
3d40: 72 75 6c 65 73 22 2e 66 6f 72 6d 61 74 28 64 5b  rules".format(d[
3d50: 27 3d 27 5d 2c 20 64 5b 27 7e 27 5d 2c 20 64 5b  '='], d['~'], d[
3d60: 27 2d 27 5d 2c 20 6e 52 75 6c 65 29 29 0a 0a 0a  '-'], nRule))...
3d70: 64 65 66 20 6d 65 72 67 65 52 75 6c 65 73 42 79  def mergeRulesBy
3d80: 4f 70 74 69 6f 6e 20 28 6c 52 75 6c 65 73 29 3a  Option (lRules):
3d90: 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20 61 20  .    "returns a 
3da0: 6c 69 73 74 20 6f 66 20 74 75 70 6c 65 73 20 5b  list of tuples [
3db0: 6f 70 74 69 6f 6e 2c 20 6c 69 73 74 20 6f 66 20  option, list of 
3dc0: 72 75 6c 65 73 5d 20 6b 65 65 70 69 6e 67 20 74  rules] keeping t
3dd0: 68 65 20 72 75 6c 65 73 20 6f 72 64 65 72 22 0a  he rules order".
3de0: 20 20 20 20 6c 46 69 6e 61 6c 20 3d 20 5b 5d 0a      lFinal = [].
3df0: 20 20 20 20 6c 54 65 6d 70 20 3d 20 5b 5d 0a 20      lTemp = []. 
3e00: 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 4e 6f 6e     sOption = Non
3e10: 65 0a 20 20 20 20 66 6f 72 20 61 52 75 6c 65 20  e.    for aRule 
3e20: 69 6e 20 6c 52 75 6c 65 73 3a 0a 20 20 20 20 20  in lRules:.     
3e30: 20 20 20 69 66 20 61 52 75 6c 65 5b 30 5d 20 21     if aRule[0] !
3e40: 3d 20 73 4f 70 74 69 6f 6e 3a 0a 20 20 20 20 20  = sOption:.     
3e50: 20 20 20 20 20 20 20 69 66 20 73 4f 70 74 69 6f         if sOptio
3e60: 6e 20 21 3d 20 4e 6f 6e 65 3a 0a 20 20 20 20 20  n != None:.     
3e70: 20 20 20 20 20 20 20 20 20 20 20 6c 46 69 6e 61             lFina
3e80: 6c 2e 61 70 70 65 6e 64 28 5b 73 4f 70 74 69 6f  l.append([sOptio
3e90: 6e 2c 20 6c 54 65 6d 70 5d 29 0a 20 20 20 20 20  n, lTemp]).     
3ea0: 20 20 20 20 20 20 20 23 20 6e 65 77 20 74 75 70         # new tup
3eb0: 6c 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  le.            s
3ec0: 4f 70 74 69 6f 6e 20 3d 20 61 52 75 6c 65 5b 30  Option = aRule[0
3ed0: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 54  ].            lT
3ee0: 65 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20  emp = [].       
3ef0: 20 6c 54 65 6d 70 2e 61 70 70 65 6e 64 28 61 52   lTemp.append(aR
3f00: 75 6c 65 5b 31 3a 5d 29 0a 20 20 20 20 6c 46 69  ule[1:]).    lFi
3f10: 6e 61 6c 2e 61 70 70 65 6e 64 28 5b 73 4f 70 74  nal.append([sOpt
3f20: 69 6f 6e 2c 20 6c 54 65 6d 70 5d 29 0a 20 20 20  ion, lTemp]).   
3f30: 20 72 65 74 75 72 6e 20 6c 46 69 6e 61 6c 0a 0a   return lFinal..
3f40: 0a 64 65 66 20 70 72 65 70 61 72 65 4f 70 74 69  .def prepareOpti
3f50: 6f 6e 73 20 28 6c 4f 70 74 69 6f 6e 4c 69 6e 65  ons (lOptionLine
3f60: 73 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73  s):.    "returns
3f70: 20 61 20 64 69 63 74 69 6f 6e 61 72 79 20 77 69   a dictionary wi
3f80: 74 68 20 64 61 74 61 20 61 62 6f 75 74 20 6f 70  th data about op
3f90: 74 69 6f 6e 73 22 0a 20 20 20 20 73 4c 61 6e 67  tions".    sLang
3fa0: 20 3d 20 22 22 0a 20 20 20 20 73 44 65 66 61 75   = "".    sDefau
3fb0: 6c 74 55 49 4c 61 6e 67 20 3d 20 22 22 0a 20 20  ltUILang = "".  
3fc0: 20 20 6c 53 74 72 75 63 74 4f 70 74 20 3d 20 5b    lStructOpt = [
3fd0: 5d 0a 20 20 20 20 6c 4f 70 74 20 3d 20 5b 5d 0a  ].    lOpt = [].
3fe0: 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 20 3d 20      dOptLabel = 
3ff0: 7b 7d 0a 20 20 20 20 64 4f 70 74 50 72 69 6f 72  {}.    dOptPrior
4000: 69 74 79 20 3d 20 7b 7d 0a 20 20 20 20 66 6f 72  ity = {}.    for
4010: 20 73 4c 69 6e 65 20 69 6e 20 6c 4f 70 74 69 6f   sLine in lOptio
4020: 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20 20 20  nLines:.        
4030: 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65 2e 73 74  sLine = sLine.st
4040: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 69 66  rip().        if
4050: 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74   sLine.startswit
4060: 68 28 22 4f 50 54 47 52 4f 55 50 2f 22 29 3a 0a  h("OPTGROUP/"):.
4070: 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20              m = 
4080: 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 47 52 4f  re.match("OPTGRO
4090: 55 50 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29 3a 28  UP/([a-z0-9]+):(
40a0: 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20  .+)$", sLine).  
40b0: 20 20 20 20 20 20 20 20 20 20 6c 53 74 72 75 63            lStruc
40c0: 74 4f 70 74 2e 61 70 70 65 6e 64 28 20 28 6d 2e  tOpt.append( (m.
40d0: 67 72 6f 75 70 28 31 29 2c 20 6c 69 73 74 28 6d  group(1), list(m
40e0: 61 70 28 73 74 72 2e 73 70 6c 69 74 2c 20 6d 2e  ap(str.split, m.
40f0: 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74 28 22  group(2).split("
4100: 2c 22 29 29 29 29 20 29 0a 20 20 20 20 20 20 20  ,")))) ).       
4110: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
4120: 74 73 77 69 74 68 28 22 4f 50 54 53 4f 46 54 57  tswith("OPTSOFTW
4130: 41 52 45 3a 22 29 3a 0a 20 20 20 20 20 20 20 20  ARE:"):.        
4140: 20 20 20 20 6c 4f 70 74 20 3d 20 5b 20 5b 73 2c      lOpt = [ [s,
4150: 20 7b 7d 5d 20 20 66 6f 72 20 73 20 69 6e 20 73   {}]  for s in s
4160: 4c 69 6e 65 5b 31 32 3a 5d 2e 73 74 72 69 70 28  Line[12:].strip(
4170: 29 2e 73 70 6c 69 74 28 29 20 5d 20 20 23 20 64  ).split() ]  # d
4180: 6f 6e e2 80 99 74 20 75 73 65 20 74 75 70 6c 65  on...t use tuple
4190: 73 20 28 73 2c 20 7b 7d 29 2c 20 62 65 63 61 75  s (s, {}), becau
41a0: 73 65 20 75 6e 6b 6e 6f 77 6e 20 74 6f 20 4a 53  se unknown to JS
41b0: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
41c0: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
41d0: 4f 50 54 2f 22 29 3a 0a 20 20 20 20 20 20 20 20  OPT/"):.        
41e0: 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68      m = re.match
41f0: 28 22 4f 50 54 2f 28 5b 61 2d 7a 30 2d 39 5d 2b  ("OPT/([a-z0-9]+
4200: 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29  ):(.+)$", sLine)
4210: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 72  .            for
4220: 20 69 2c 20 73 4f 70 74 20 69 6e 20 65 6e 75 6d   i, sOpt in enum
4230: 65 72 61 74 65 28 6d 2e 67 72 6f 75 70 28 32 29  erate(m.group(2)
4240: 2e 73 70 6c 69 74 28 29 29 3a 0a 20 20 20 20 20  .split()):.     
4250: 20 20 20 20 20 20 20 20 20 20 20 6c 4f 70 74 5b             lOpt[
4260: 69 5d 5b 31 5d 5b 6d 2e 67 72 6f 75 70 28 31 29  i][1][m.group(1)
4270: 5d 20 3d 20 20 65 76 61 6c 28 73 4f 70 74 29 0a  ] =  eval(sOpt).
4280: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
4290: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f  ne.startswith("O
42a0: 50 54 50 52 49 4f 52 49 54 59 2f 22 29 3a 0a 20  PTPRIORITY/"):. 
42b0: 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72             m = r
42c0: 65 2e 6d 61 74 63 68 28 22 4f 50 54 50 52 49 4f  e.match("OPTPRIO
42d0: 52 49 54 59 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29  RITY/([a-z0-9]+)
42e0: 3a 20 2a 28 5b 30 2d 39 5d 29 24 22 2c 20 73 4c  : *([0-9])$", sL
42f0: 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20 20  ine).           
4300: 20 64 4f 70 74 50 72 69 6f 72 69 74 79 5b 6d 2e   dOptPriority[m.
4310: 67 72 6f 75 70 28 31 29 5d 20 3d 20 69 6e 74 28  group(1)] = int(
4320: 6d 2e 67 72 6f 75 70 28 32 29 29 0a 20 20 20 20  m.group(2)).    
4330: 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73      elif sLine.s
4340: 74 61 72 74 73 77 69 74 68 28 22 4f 50 54 4c 41  tartswith("OPTLA
4350: 4e 47 2f 22 29 3a 0a 20 20 20 20 20 20 20 20 20  NG/"):.         
4360: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
4370: 22 4f 50 54 4c 41 4e 47 2f 28 5b 61 2d 7a 5d 5b  "OPTLANG/([a-z][
4380: 61 2d 7a 5d 28 3f 3a 5f 5b 41 2d 5a 5d 5b 41 2d  a-z](?:_[A-Z][A-
4390: 5a 5d 7c 29 29 3a 28 2e 2b 29 24 22 2c 20 73 4c  Z]|)):(.+)$", sL
43a0: 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20 20  ine).           
43b0: 20 73 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f 75 70   sLang = m.group
43c0: 28 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20 20 20  (1)[:2].        
43d0: 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 5b 73 4c      dOptLabel[sL
43e0: 61 6e 67 5d 20 3d 20 7b 20 22 5f 5f 6f 70 74 69  ang] = { "__opti
43f0: 6f 6e 74 69 74 6c 65 5f 5f 22 3a 20 6d 2e 67 72  ontitle__": m.gr
4400: 6f 75 70 28 32 29 2e 73 74 72 69 70 28 29 20 7d  oup(2).strip() }
4410: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
4420: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
4430: 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41 4e 47  OPTDEFAULTUILANG
4440: 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  :"):.           
4450: 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f   m = re.match("O
4460: 50 54 44 45 46 41 55 4c 54 55 49 4c 41 4e 47 3a  PTDEFAULTUILANG:
4470: 20 2a 28 5b 61 2d 7a 5d 5b 61 2d 7a 5d 28 3f 3a   *([a-z][a-z](?:
4480: 5f 5b 41 2d 5a 5d 5b 41 2d 5a 5d 7c 29 29 24 22  _[A-Z][A-Z]|))$"
4490: 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20  , sLine).       
44a0: 20 20 20 20 20 73 44 65 66 61 75 6c 74 55 49 4c       sDefaultUIL
44b0: 61 6e 67 20 3d 20 6d 2e 67 72 6f 75 70 28 31 29  ang = m.group(1)
44c0: 5b 3a 32 5d 0a 20 20 20 20 20 20 20 20 65 6c 69  [:2].        eli
44d0: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
44e0: 74 68 28 22 4f 50 54 4c 41 42 45 4c 2f 22 29 3a  th("OPTLABEL/"):
44f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d  .            m =
4500: 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 4c 41   re.match("OPTLA
4510: 42 45 4c 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29 3a  BEL/([a-z0-9]+):
4520: 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20  (.+)$", sLine). 
4530: 20 20 20 20 20 20 20 20 20 20 20 64 4f 70 74 4c             dOptL
4540: 61 62 65 6c 5b 73 4c 61 6e 67 5d 5b 6d 2e 67 72  abel[sLang][m.gr
4550: 6f 75 70 28 31 29 5d 20 3d 20 6c 69 73 74 28 6d  oup(1)] = list(m
4560: 61 70 28 73 74 72 2e 73 74 72 69 70 2c 20 6d 2e  ap(str.strip, m.
4570: 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74 28 22  group(2).split("
4580: 7c 22 29 29 29 20 20 69 66 20 22 7c 22 20 69 6e  |")))  if "|" in
4590: 20 6d 2e 67 72 6f 75 70 28 32 29 20 20 65 6c 73   m.group(2)  els
45a0: 65 20 20 5b 6d 2e 67 72 6f 75 70 28 32 29 2e 73  e  [m.group(2).s
45b0: 74 72 69 70 28 29 2c 20 22 22 5d 0a 20 20 20 20  trip(), ""].    
45c0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
45d0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
45e0: 72 72 6f 72 2e 20 57 72 6f 6e 67 20 6f 70 74 69  rror. Wrong opti
45f0: 6f 6e 20 6c 69 6e 65 20 69 6e 3a 5c 6e 20 20 22  on line in:\n  "
4600: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72  ).            pr
4610: 69 6e 74 28 73 4c 69 6e 65 29 0a 20 20 20 20 70  int(sLine).    p
4620: 72 69 6e 74 28 22 20 20 6f 70 74 69 6f 6e 73 20  rint("  options 
4630: 64 65 66 69 6e 65 64 20 66 6f 72 3a 20 22 20 2b  defined for: " +
4640: 20 22 2c 20 22 2e 6a 6f 69 6e 28 5b 20 74 5b 30   ", ".join([ t[0
4650: 5d 20 66 6f 72 20 74 20 69 6e 20 6c 4f 70 74 20  ] for t in lOpt 
4660: 5d 29 29 0a 20 20 20 20 64 4f 70 74 69 6f 6e 73  ])).    dOptions
4670: 20 3d 20 7b 20 22 6c 53 74 72 75 63 74 4f 70 74   = { "lStructOpt
4680: 22 3a 20 6c 53 74 72 75 63 74 4f 70 74 2c 20 22  ": lStructOpt, "
4690: 64 4f 70 74 4c 61 62 65 6c 22 3a 20 64 4f 70 74  dOptLabel": dOpt
46a0: 4c 61 62 65 6c 2c 20 22 73 44 65 66 61 75 6c 74  Label, "sDefault
46b0: 55 49 4c 61 6e 67 22 3a 20 73 44 65 66 61 75 6c  UILang": sDefaul
46c0: 74 55 49 4c 61 6e 67 20 7d 0a 20 20 20 20 64 4f  tUILang }.    dO
46d0: 70 74 69 6f 6e 73 2e 75 70 64 61 74 65 28 7b 20  ptions.update({ 
46e0: 22 64 4f 70 74 22 2b 6b 3a 20 76 20 20 66 6f 72  "dOpt"+k: v  for
46f0: 20 6b 2c 20 76 20 69 6e 20 6c 4f 70 74 20 7d 29   k, v in lOpt })
4700: 0a 20 20 20 20 72 65 74 75 72 6e 20 64 4f 70 74  .    return dOpt
4710: 69 6f 6e 73 2c 20 64 4f 70 74 50 72 69 6f 72 69  ions, dOptPriori
4720: 74 79 0a 0a 0a 64 65 66 20 70 72 69 6e 74 42 6f  ty...def printBo
4730: 6f 6b 6d 61 72 6b 20 28 6e 4c 65 76 65 6c 2c 20  okmark (nLevel, 
4740: 73 43 6f 6d 6d 65 6e 74 2c 20 6e 4c 69 6e 65 29  sComment, nLine)
4750: 3a 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 7b  :.    print("  {
4760: 3a 3e 36 7d 3a 20 20 7b 7d 22 2e 66 6f 72 6d 61  :>6}:  {}".forma
4770: 74 28 6e 4c 69 6e 65 2c 20 22 20 20 22 20 2a 20  t(nLine, "  " * 
4780: 6e 4c 65 76 65 6c 20 2b 20 73 43 6f 6d 6d 65 6e  nLevel + sCommen
4790: 74 29 29 0a 0a 0a 64 65 66 20 6d 61 6b 65 20 28  t))...def make (
47a0: 73 70 4c 61 6e 67 2c 20 73 4c 61 6e 67 2c 20 62  spLang, sLang, b
47b0: 4a 61 76 61 53 63 72 69 70 74 29 3a 0a 20 20 20  JavaScript):.   
47c0: 20 22 63 6f 6d 70 69 6c 65 20 72 75 6c 65 73 2c   "compile rules,
47d0: 20 72 65 74 75 72 6e 73 20 61 20 64 69 63 74 69   returns a dicti
47e0: 6f 6e 61 72 79 20 6f 66 20 76 61 6c 75 65 73 22  onary of values"
47f0: 0a 20 20 20 20 23 20 66 6f 72 20 63 6c 61 72 69  .    # for clari
4800: 74 79 20 70 75 72 70 6f 73 65 2c 20 64 6f 6e e2  ty purpose, don.
4810: 80 99 74 20 63 72 65 61 74 65 20 61 6e 79 20 66  ..t create any f
4820: 69 6c 65 20 68 65 72 65 0a 0a 20 20 20 20 70 72  ile here..    pr
4830: 69 6e 74 28 22 3e 20 72 65 61 64 20 72 75 6c 65  int("> read rule
4840: 73 20 66 69 6c 65 2e 2e 2e 22 29 0a 20 20 20 20  s file...").    
4850: 74 72 79 3a 0a 20 20 20 20 20 20 20 20 6c 52 75  try:.        lRu
4860: 6c 65 73 20 3d 20 6f 70 65 6e 28 73 70 4c 61 6e  les = open(spLan
4870: 67 20 2b 20 22 2f 72 75 6c 65 73 2e 67 72 78 22  g + "/rules.grx"
4880: 2c 20 27 72 27 2c 20 65 6e 63 6f 64 69 6e 67 3d  , 'r', encoding=
4890: 22 75 74 66 2d 38 22 29 2e 72 65 61 64 6c 69 6e  "utf-8").readlin
48a0: 65 73 28 29 0a 20 20 20 20 65 78 63 65 70 74 3a  es().    except:
48b0: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
48c0: 45 72 72 6f 72 2e 20 52 75 6c 65 73 20 66 69 6c  Error. Rules fil
48d0: 65 20 69 6e 20 70 72 6f 6a 65 63 74 20 5b 22 20  e in project [" 
48e0: 2b 20 73 4c 61 6e 67 20 2b 20 22 5d 20 6e 6f 74  + sLang + "] not
48f0: 20 66 6f 75 6e 64 2e 22 29 0a 20 20 20 20 20 20   found.").      
4900: 20 20 65 78 69 74 28 29 0a 0a 20 20 20 20 23 20    exit()..    # 
4910: 72 65 6d 6f 76 69 6e 67 20 63 6f 6d 6d 65 6e 74  removing comment
4920: 73 2c 20 7a 65 72 6f 69 6e 67 20 65 6d 70 74 79  s, zeroing empty
4930: 20 6c 69 6e 65 73 2c 20 63 72 65 61 74 69 6e 67   lines, creating
4940: 20 64 65 66 69 6e 69 74 69 6f 6e 73 2c 20 73 74   definitions, st
4950: 6f 72 69 6e 67 20 74 65 73 74 73 2c 20 6d 65 72  oring tests, mer
4960: 67 69 6e 67 20 72 75 6c 65 20 6c 69 6e 65 73 0a  ging rule lines.
4970: 20 20 20 20 70 72 69 6e 74 28 22 20 20 70 61 72      print("  par
4980: 73 69 6e 67 20 72 75 6c 65 73 2e 2e 2e 22 29 0a  sing rules...").
4990: 20 20 20 20 67 6c 6f 62 61 6c 20 64 44 45 46 0a      global dDEF.
49a0: 20 20 20 20 6c 4c 69 6e 65 20 3d 20 5b 5d 0a 20      lLine = []. 
49b0: 20 20 20 6c 52 75 6c 65 4c 69 6e 65 20 3d 20 5b     lRuleLine = [
49c0: 5d 0a 20 20 20 20 6c 54 65 73 74 20 3d 20 5b 5d  ].    lTest = []
49d0: 0a 20 20 20 20 6c 4f 70 74 20 3d 20 5b 5d 0a 0a  .    lOpt = []..
49e0: 20 20 20 20 66 6f 72 20 69 2c 20 73 4c 69 6e 65      for i, sLine
49f0: 20 69 6e 20 65 6e 75 6d 65 72 61 74 65 28 6c 52   in enumerate(lR
4a00: 75 6c 65 73 2c 20 31 29 3a 0a 20 20 20 20 20 20  ules, 1):.      
4a10: 20 20 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74    if sLine.start
4a20: 73 77 69 74 68 28 27 23 45 4e 44 27 29 3a 0a 20  swith('#END'):. 
4a30: 20 20 20 20 20 20 20 20 20 20 20 23 20 61 72 62             # arb
4a40: 69 74 72 61 72 79 20 65 6e 64 0a 20 20 20 20 20  itrary end.     
4a50: 20 20 20 20 20 20 20 70 72 69 6e 74 42 6f 6f 6b         printBook
4a60: 6d 61 72 6b 28 30 2c 20 22 42 52 45 41 4b 20 42  mark(0, "BREAK B
4a70: 59 20 23 45 4e 44 22 2c 20 69 29 0a 20 20 20 20  Y #END", i).    
4a80: 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20          break.  
4a90: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
4aa0: 2e 73 74 61 72 74 73 77 69 74 68 28 22 23 22 29  .startswith("#")
4ab0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
4ac0: 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 20 20 20 20  comment.        
4ad0: 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 20 20      pass.       
4ae0: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
4af0: 74 73 77 69 74 68 28 22 40 40 40 40 22 29 3a 0a  tswith("@@@@"):.
4b00: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 72 75              # ru
4b10: 6c 65 73 20 67 72 61 70 68 20 63 61 6c 6c 0a 20  les graph call. 
4b20: 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72             m = r
4b30: 65 2e 6d 61 74 63 68 28 72 22 40 40 40 40 47 52  e.match(r"@@@@GR
4b40: 41 50 48 3a 20 2a 28 5c 77 2b 29 40 40 40 40 22  APH: *(\w+)@@@@"
4b50: 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 29  , sLine.strip())
4b60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
4b70: 6d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  m:.             
4b80: 20 20 20 23 6c 52 75 6c 65 4c 69 6e 65 2e 61 70     #lRuleLine.ap
4b90: 70 65 6e 64 28 5b 22 40 47 52 41 50 48 4c 49 4e  pend(["@GRAPHLIN
4ba0: 4b 22 2c 20 6d 2e 67 72 6f 75 70 28 31 29 5d 29  K", m.group(1)])
4bb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4bc0: 20 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 31   printBookmark(1
4bd0: 2c 20 22 40 47 52 41 50 48 3a 20 22 20 2b 20 6d  , "@GRAPH: " + m
4be0: 2e 67 72 6f 75 70 28 31 29 2c 20 69 29 0a 20 20  .group(1), i).  
4bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 52                lR
4c00: 75 6c 65 4c 69 6e 65 2e 61 70 70 65 6e 64 28 5b  uleLine.append([
4c10: 69 2c 20 22 40 40 40 40 22 2b 6d 2e 67 72 6f 75  i, "@@@@"+m.grou
4c20: 70 28 31 29 5d 29 0a 20 20 20 20 20 20 20 20 65  p(1)]).        e
4c30: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
4c40: 77 69 74 68 28 22 44 45 46 3a 22 29 3a 0a 20 20  with("DEF:"):.  
4c50: 20 20 20 20 20 20 20 20 20 20 23 20 64 65 66 69            # defi
4c60: 6e 69 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20  nition.         
4c70: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
4c80: 22 44 45 46 3a 20 2b 28 5b 61 2d 7a 41 2d 5a 5f  "DEF: +([a-zA-Z_
4c90: 5d 5b 61 2d 7a 41 2d 5a 5f 30 2d 39 5d 2a 29 20  ][a-zA-Z_0-9]*) 
4ca0: 2b 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 2e 73  +(.+)$", sLine.s
4cb0: 74 72 69 70 28 29 29 0a 20 20 20 20 20 20 20 20  trip()).        
4cc0: 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20      if m:.      
4cd0: 20 20 20 20 20 20 20 20 20 20 64 44 45 46 5b 22            dDEF["
4ce0: 7b 22 2b 6d 2e 67 72 6f 75 70 28 31 29 2b 22 7d  {"+m.group(1)+"}
4cf0: 22 5d 20 3d 20 6d 2e 67 72 6f 75 70 28 32 29 0a  "] = m.group(2).
4d00: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
4d10: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
4d20: 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72 20 69    print("Error i
4d30: 6e 20 64 65 66 69 6e 69 74 69 6f 6e 3a 20 22 2c  n definition: ",
4d40: 20 65 6e 64 3d 22 22 29 0a 20 20 20 20 20 20 20   end="").       
4d50: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 73           print(s
4d60: 4c 69 6e 65 2e 73 74 72 69 70 28 29 29 0a 20 20  Line.strip()).  
4d70: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
4d80: 2e 73 74 61 72 74 73 77 69 74 68 28 22 54 45 53  .startswith("TES
4d90: 54 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  T:"):.          
4da0: 20 20 23 20 74 65 73 74 0a 20 20 20 20 20 20 20    # test.       
4db0: 20 20 20 20 20 6c 54 65 73 74 2e 61 70 70 65 6e       lTest.appen
4dc0: 64 28 22 72 7b 3a 3c 37 7d 22 2e 66 6f 72 6d 61  d("r{:<7}".forma
4dd0: 74 28 69 29 20 2b 20 22 20 20 22 20 2b 20 73 4c  t(i) + "  " + sL
4de0: 69 6e 65 5b 35 3a 5d 2e 73 74 72 69 70 28 29 29  ine[5:].strip())
4df0: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
4e00: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
4e10: 54 4f 44 4f 3a 22 29 3a 0a 20 20 20 20 20 20 20  TODO:"):.       
4e20: 20 20 20 20 20 23 20 74 6f 64 6f 0a 20 20 20 20       # todo.    
4e30: 20 20 20 20 20 20 20 20 70 61 73 73 0a 20 20 20          pass.   
4e40: 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e       elif sLine.
4e50: 73 74 61 72 74 73 77 69 74 68 28 28 22 4f 50 54  startswith(("OPT
4e60: 47 52 4f 55 50 2f 22 2c 20 22 4f 50 54 53 4f 46  GROUP/", "OPTSOF
4e70: 54 57 41 52 45 3a 22 2c 20 22 4f 50 54 2f 22 2c  TWARE:", "OPT/",
4e80: 20 22 4f 50 54 4c 41 4e 47 2f 22 2c 20 22 4f 50   "OPTLANG/", "OP
4e90: 54 44 45 46 41 55 4c 54 55 49 4c 41 4e 47 3a 22  TDEFAULTUILANG:"
4ea0: 2c 20 22 4f 50 54 4c 41 42 45 4c 2f 22 2c 20 22  , "OPTLABEL/", "
4eb0: 4f 50 54 50 52 49 4f 52 49 54 59 2f 22 29 29 3a  OPTPRIORITY/")):
4ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 6f  .            # o
4ed0: 70 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 20  ptions.         
4ee0: 20 20 20 6c 4f 70 74 2e 61 70 70 65 6e 64 28 73     lOpt.append(s
4ef0: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 65 6c  Line).        el
4f00: 69 66 20 72 65 2e 6d 61 74 63 68 28 22 5b 20 c2  if re.match("[ .
4f10: a0 5c 74 5d 2a 24 22 2c 20 73 4c 69 6e 65 29 3a  .\t]*$", sLine):
4f20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 65  .            # e
4f30: 6d 70 74 79 20 6c 69 6e 65 0a 20 20 20 20 20 20  mpty line.      
4f40: 20 20 20 20 20 20 70 61 73 73 0a 20 20 20 20 20        pass.     
4f50: 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74     elif sLine.st
4f60: 61 72 74 73 77 69 74 68 28 22 21 21 22 29 3a 0a  artswith("!!"):.
4f70: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 62 6f              # bo
4f80: 6f 6b 6d 61 72 6b 0a 20 20 20 20 20 20 20 20 20  okmark.         
4f90: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
4fa0: 22 21 21 2b 22 2c 20 73 4c 69 6e 65 29 0a 20 20  "!!+", sLine).  
4fb0: 20 20 20 20 20 20 20 20 20 20 6e 45 78 4d 6b 20            nExMk 
4fc0: 3d 20 6c 65 6e 28 6d 2e 67 72 6f 75 70 28 30 29  = len(m.group(0)
4fd0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ).            if
4fe0: 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 5d 2e 73   sLine[nExMk:].s
4ff0: 74 72 69 70 28 29 3a 0a 20 20 20 20 20 20 20 20  trip():.        
5000: 20 20 20 20 20 20 20 20 70 72 69 6e 74 42 6f 6f          printBoo
5010: 6b 6d 61 72 6b 28 6e 45 78 4d 6b 2d 32 2c 20 73  kmark(nExMk-2, s
5020: 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 5d 2e 73 74 72  Line[nExMk:].str
5030: 69 70 28 29 2c 20 69 29 0a 20 20 20 20 20 20 20  ip(), i).       
5040: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
5050: 74 73 77 69 74 68 28 28 22 20 20 20 20 22 2c 20  tswith(("    ", 
5060: 22 5c 74 22 29 29 3a 0a 20 20 20 20 20 20 20 20  "\t")):.        
5070: 20 20 20 20 23 20 72 75 6c 65 20 28 63 6f 6e 74      # rule (cont
5080: 69 6e 75 61 74 69 6f 6e 29 0a 20 20 20 20 20 20  inuation).      
5090: 20 20 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 5b        lRuleLine[
50a0: 2d 31 5d 5b 31 5d 20 2b 3d 20 22 20 22 20 2b 20  -1][1] += " " + 
50b0: 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 0a 20 20  sLine.strip().  
50c0: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
50d0: 20 20 20 20 20 20 20 20 23 20 6e 65 77 20 72 75          # new ru
50e0: 6c 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  le.            l
50f0: 52 75 6c 65 4c 69 6e 65 2e 61 70 70 65 6e 64 28  RuleLine.append(
5100: 5b 69 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70 28  [i, sLine.strip(
5110: 29 5d 29 0a 0a 20 20 20 20 23 20 67 65 6e 65 72  )])..    # gener
5120: 61 74 69 6e 67 20 6f 70 74 69 6f 6e 73 20 66 69  ating options fi
5130: 6c 65 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20  les.    print(" 
5140: 20 70 61 72 73 69 6e 67 20 6f 70 74 69 6f 6e 73   parsing options
5150: 2e 2e 2e 22 29 0a 20 20 20 20 74 72 79 3a 0a 20  ...").    try:. 
5160: 20 20 20 20 20 20 20 64 4f 70 74 69 6f 6e 73 2c         dOptions,
5170: 20 64 4f 70 74 50 72 69 6f 72 69 74 79 20 3d 20   dOptPriority = 
5180: 70 72 65 70 61 72 65 4f 70 74 69 6f 6e 73 28 6c  prepareOptions(l
5190: 4f 70 74 29 0a 20 20 20 20 65 78 63 65 70 74 3a  Opt).    except:
51a0: 0a 20 20 20 20 20 20 20 20 74 72 61 63 65 62 61  .        traceba
51b0: 63 6b 2e 70 72 69 6e 74 5f 65 78 63 28 29 0a 20  ck.print_exc(). 
51c0: 20 20 20 20 20 20 20 65 78 69 74 28 29 0a 0a 20         exit().. 
51d0: 20 20 20 23 20 74 65 73 74 73 0a 20 20 20 20 70     # tests.    p
51e0: 72 69 6e 74 28 22 20 20 6c 69 73 74 20 74 65 73  rint("  list tes
51f0: 74 73 2e 2e 2e 22 29 0a 20 20 20 20 73 47 43 54  ts...").    sGCT
5200: 65 73 74 73 20 3d 20 22 5c 6e 22 2e 6a 6f 69 6e  ests = "\n".join
5210: 28 6c 54 65 73 74 29 0a 20 20 20 20 73 47 43 54  (lTest).    sGCT
5220: 65 73 74 73 4a 53 20 3d 20 27 7b 20 22 61 44 61  estsJS = '{ "aDa
5230: 74 61 22 3a 20 27 20 2b 20 6a 73 6f 6e 2e 64 75  ta": ' + json.du
5240: 6d 70 73 28 6c 54 65 73 74 2c 20 65 6e 73 75 72  mps(lTest, ensur
5250: 65 5f 61 73 63 69 69 3d 46 61 6c 73 65 29 20 2b  e_ascii=False) +
5260: 20 22 20 7d 5c 6e 22 0a 0a 20 20 20 20 23 20 70   " }\n"..    # p
5270: 72 6f 63 65 73 73 69 6e 67 0a 20 20 20 20 70 72  rocessing.    pr
5280: 69 6e 74 28 22 20 20 70 72 65 70 61 72 69 6e 67  int("  preparing
5290: 20 72 75 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20   rules...").    
52a0: 62 50 61 72 61 67 72 61 70 68 20 3d 20 54 72 75  bParagraph = Tru
52b0: 65 0a 20 20 20 20 6c 50 61 72 61 67 72 61 70 68  e.    lParagraph
52c0: 52 75 6c 65 73 20 3d 20 5b 5d 0a 20 20 20 20 6c  Rules = [].    l
52d0: 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 20 3d 20  SentenceRules = 
52e0: 5b 5d 0a 20 20 20 20 6c 50 61 72 61 67 72 61 70  [].    lParagrap
52f0: 68 52 75 6c 65 73 4a 53 20 3d 20 5b 5d 0a 20 20  hRulesJS = [].  
5300: 20 20 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73    lSentenceRules
5310: 4a 53 20 3d 20 5b 5d 0a 0a 20 20 20 20 66 6f 72  JS = []..    for
5320: 20 6e 4c 69 6e 65 2c 20 73 4c 69 6e 65 20 69 6e   nLine, sLine in
5330: 20 6c 52 75 6c 65 4c 69 6e 65 3a 0a 20 20 20 20   lRuleLine:.    
5340: 20 20 20 20 69 66 20 73 4c 69 6e 65 3a 0a 20 20      if sLine:.  
5350: 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4c 69            if sLi
5360: 6e 65 20 3d 3d 20 22 5b 2b 2b 5d 22 3a 0a 20 20  ne == "[++]":.  
5370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 50                bP
5380: 61 72 61 67 72 61 70 68 20 3d 20 46 61 6c 73 65  aragraph = False
5390: 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73  .            els
53a0: 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e:.             
53b0: 20 20 20 61 52 75 6c 65 20 3d 20 63 72 65 61 74     aRule = creat
53c0: 65 52 75 6c 65 28 73 4c 69 6e 65 2c 20 6e 4c 69  eRule(sLine, nLi
53d0: 6e 65 2c 20 73 4c 61 6e 67 2c 20 62 50 61 72 61  ne, sLang, bPara
53e0: 67 72 61 70 68 2c 20 64 4f 70 74 50 72 69 6f 72  graph, dOptPrior
53f0: 69 74 79 29 0a 20 20 20 20 20 20 20 20 20 20 20  ity).           
5400: 20 20 20 20 20 69 66 20 61 52 75 6c 65 3a 0a 20       if aRule:. 
5410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5420: 20 20 20 69 66 20 62 50 61 72 61 67 72 61 70 68     if bParagraph
5430: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5440: 20 20 20 20 20 20 20 20 20 20 6c 50 61 72 61 67            lParag
5450: 72 61 70 68 52 75 6c 65 73 2e 61 70 70 65 6e 64  raphRules.append
5460: 28 61 52 75 6c 65 29 0a 20 20 20 20 20 20 20 20  (aRule).        
5470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5480: 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 4a  lParagraphRulesJ
5490: 53 2e 61 70 70 65 6e 64 28 6a 73 63 6f 6e 76 2e  S.append(jsconv.
54a0: 70 79 52 75 6c 65 54 6f 4a 53 28 61 52 75 6c 65  pyRuleToJS(aRule
54b0: 2c 20 64 4a 53 52 45 47 45 58 45 53 2c 20 73 57  , dJSREGEXES, sW
54c0: 4f 52 44 4c 49 4d 49 54 4c 45 46 54 29 29 0a 20  ORDLIMITLEFT)). 
54d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54e0: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
54f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5500: 20 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 2e   lSentenceRules.
5510: 61 70 70 65 6e 64 28 61 52 75 6c 65 29 0a 20 20  append(aRule).  
5520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5530: 20 20 20 20 20 20 6c 53 65 6e 74 65 6e 63 65 52        lSentenceR
5540: 75 6c 65 73 4a 53 2e 61 70 70 65 6e 64 28 6a 73  ulesJS.append(js
5550: 63 6f 6e 76 2e 70 79 52 75 6c 65 54 6f 4a 53 28  conv.pyRuleToJS(
5560: 61 52 75 6c 65 2c 20 64 4a 53 52 45 47 45 58 45  aRule, dJSREGEXE
5570: 53 2c 20 73 57 4f 52 44 4c 49 4d 49 54 4c 45 46  S, sWORDLIMITLEF
5580: 54 29 29 0a 0a 20 20 20 20 23 20 63 72 65 61 74  T))..    # creat
5590: 69 6e 67 20 66 69 6c 65 20 77 69 74 68 20 61 6c  ing file with al
55a0: 6c 20 66 75 6e 63 74 69 6f 6e 73 20 63 61 6c 6c  l functions call
55b0: 61 62 6c 65 20 62 79 20 72 75 6c 65 73 0a 20 20  able by rules.  
55c0: 20 20 70 72 69 6e 74 28 22 20 20 63 72 65 61 74    print("  creat
55d0: 69 6e 67 20 63 61 6c 6c 61 62 6c 65 73 2e 2e 2e  ing callables...
55e0: 22 29 0a 20 20 20 20 73 50 79 43 61 6c 6c 61 62  ").    sPyCallab
55f0: 6c 65 73 20 3d 20 22 23 20 67 65 6e 65 72 61 74  les = "# generat
5600: 65 64 20 63 6f 64 65 2c 20 64 6f 20 6e 6f 74 20  ed code, do not 
5610: 65 64 69 74 5c 6e 22 0a 20 20 20 20 73 4a 53 43  edit\n".    sJSC
5620: 61 6c 6c 61 62 6c 65 73 20 3d 20 22 2f 2f 20 67  allables = "// g
5630: 65 6e 65 72 61 74 65 64 20 63 6f 64 65 2c 20 64  enerated code, d
5640: 6f 20 6e 6f 74 20 65 64 69 74 5c 6e 63 6f 6e 73  o not edit\ncons
5650: 74 20 6f 45 76 61 6c 46 75 6e 63 20 3d 20 7b 5c  t oEvalFunc = {\
5660: 6e 22 0a 20 20 20 20 66 6f 72 20 73 46 75 6e 63  n".    for sFunc
5670: 4e 61 6d 65 2c 20 73 52 65 74 75 72 6e 20 69 6e  Name, sReturn in
5680: 20 6c 46 55 4e 43 54 49 4f 4e 53 3a 0a 20 20 20   lFUNCTIONS:.   
5690: 20 20 20 20 20 63 54 79 70 65 20 3d 20 73 46 75       cType = sFu
56a0: 6e 63 4e 61 6d 65 5b 30 3a 31 5d 0a 20 20 20 20  ncName[0:1].    
56b0: 20 20 20 20 69 66 20 63 54 79 70 65 20 3d 3d 20      if cType == 
56c0: 22 63 22 3a 20 23 20 63 6f 6e 64 69 74 69 6f 6e  "c": # condition
56d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61  .            sPa
56e0: 72 61 6d 73 20 3d 20 22 73 2c 20 73 78 2c 20 6d  rams = "s, sx, m
56f0: 2c 20 64 44 41 2c 20 73 43 6f 75 6e 74 72 79 2c  , dDA, sCountry,
5700: 20 62 43 6f 6e 64 4d 65 6d 6f 22 0a 20 20 20 20   bCondMemo".    
5710: 20 20 20 20 65 6c 69 66 20 63 54 79 70 65 20 3d      elif cType =
5720: 3d 20 22 6d 22 3a 20 23 20 6d 65 73 73 61 67 65  = "m": # message
5730: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61  .            sPa
5740: 72 61 6d 73 20 3d 20 22 73 2c 20 6d 22 0a 20 20  rams = "s, m".  
5750: 20 20 20 20 20 20 65 6c 69 66 20 63 54 79 70 65        elif cType
5760: 20 3d 3d 20 22 73 22 3a 20 23 20 73 75 67 67 65   == "s": # sugge
5770: 73 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20  stion.          
5780: 20 20 73 50 61 72 61 6d 73 20 3d 20 22 73 2c 20    sParams = "s, 
5790: 6d 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  m".        elif 
57a0: 63 54 79 70 65 20 3d 3d 20 22 70 22 3a 20 23 20  cType == "p": # 
57b0: 70 72 65 70 72 6f 63 65 73 73 6f 72 0a 20 20 20  preprocessor.   
57c0: 20 20 20 20 20 20 20 20 20 73 50 61 72 61 6d 73           sParams
57d0: 20 3d 20 22 73 2c 20 6d 22 0a 20 20 20 20 20 20   = "s, m".      
57e0: 20 20 65 6c 69 66 20 63 54 79 70 65 20 3d 3d 20    elif cType == 
57f0: 22 64 22 3a 20 23 20 64 69 73 61 6d 62 69 67 75  "d": # disambigu
5800: 61 74 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20  ator.           
5810: 20 73 50 61 72 61 6d 73 20 3d 20 22 73 2c 20 6d   sParams = "s, m
5820: 2c 20 64 44 41 22 0a 20 20 20 20 20 20 20 20 65  , dDA".        e
5830: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
5840: 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f 77   print("# Unknow
5850: 6e 20 66 75 6e 63 74 69 6f 6e 20 74 79 70 65 20  n function type 
5860: 69 6e 20 5b 22 20 2b 20 73 46 75 6e 63 4e 61 6d  in [" + sFuncNam
5870: 65 20 2b 20 22 5d 22 29 0a 20 20 20 20 20 20 20  e + "]").       
5880: 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20       continue.  
5890: 20 20 20 20 20 20 73 50 79 43 61 6c 6c 61 62 6c        sPyCallabl
58a0: 65 73 20 2b 3d 20 22 64 65 66 20 7b 7d 20 28 7b  es += "def {} ({
58b0: 7d 29 3a 5c 6e 22 2e 66 6f 72 6d 61 74 28 73 46  }):\n".format(sF
58c0: 75 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61 6d 73  uncName, sParams
58d0: 29 0a 20 20 20 20 20 20 20 20 73 50 79 43 61 6c  ).        sPyCal
58e0: 6c 61 62 6c 65 73 20 2b 3d 20 22 20 20 20 20 72  lables += "    r
58f0: 65 74 75 72 6e 20 22 20 2b 20 73 52 65 74 75 72  eturn " + sRetur
5900: 6e 20 2b 20 22 5c 6e 22 0a 20 20 20 20 20 20 20  n + "\n".       
5910: 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d   sJSCallables +=
5920: 20 22 20 20 20 20 7b 7d 3a 20 66 75 6e 63 74 69   "    {}: functi
5930: 6f 6e 20 28 7b 7d 29 22 2e 66 6f 72 6d 61 74 28  on ({})".format(
5940: 73 46 75 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61  sFuncName, sPara
5950: 6d 73 29 20 2b 20 22 20 7b 5c 6e 22 0a 20 20 20  ms) + " {\n".   
5960: 20 20 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65       sJSCallable
5970: 73 20 2b 3d 20 22 20 20 20 20 20 20 20 20 72 65  s += "        re
5980: 74 75 72 6e 20 22 20 2b 20 6a 73 63 6f 6e 76 2e  turn " + jsconv.
5990: 70 79 32 6a 73 28 73 52 65 74 75 72 6e 29 20 2b  py2js(sReturn) +
59a0: 20 22 3b 5c 6e 22 0a 20 20 20 20 20 20 20 20 73   ";\n".        s
59b0: 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22  JSCallables += "
59c0: 20 20 20 20 7d 2c 5c 6e 22 0a 20 20 20 20 73 4a      },\n".    sJ
59d0: 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 7d  SCallables += "}
59e0: 5c 6e 22 0a 0a 20 20 20 20 64 69 73 70 6c 61 79  \n"..    display
59f0: 53 74 61 74 73 28 6c 50 61 72 61 67 72 61 70 68  Stats(lParagraph
5a00: 52 75 6c 65 73 2c 20 6c 53 65 6e 74 65 6e 63 65  Rules, lSentence
5a10: 52 75 6c 65 73 29 0a 0a 20 20 20 20 70 72 69 6e  Rules)..    prin
5a20: 74 28 22 55 6e 6e 61 6d 65 64 20 72 75 6c 65 73  t("Unnamed rules
5a30: 3a 20 22 20 2b 20 73 74 72 28 6e 52 55 4c 45 57  : " + str(nRULEW
5a40: 49 54 48 4f 55 54 4e 41 4d 45 29 29 0a 0a 20 20  ITHOUTNAME))..  
5a50: 20 20 64 20 3d 20 7b 20 22 63 61 6c 6c 61 62 6c    d = { "callabl
5a60: 65 73 22 3a 20 73 50 79 43 61 6c 6c 61 62 6c 65  es": sPyCallable
5a70: 73 2c 0a 20 20 20 20 20 20 20 20 20 20 22 63 61  s,.          "ca
5a80: 6c 6c 61 62 6c 65 73 4a 53 22 3a 20 73 4a 53 43  llablesJS": sJSC
5a90: 61 6c 6c 61 62 6c 65 73 2c 0a 20 20 20 20 20 20  allables,.      
5aa0: 20 20 20 20 22 72 65 67 65 78 5f 67 63 74 65 73      "regex_gctes
5ab0: 74 73 22 3a 20 73 47 43 54 65 73 74 73 2c 0a 20  ts": sGCTests,. 
5ac0: 20 20 20 20 20 20 20 20 20 22 72 65 67 65 78 5f           "regex_
5ad0: 67 63 74 65 73 74 73 4a 53 22 3a 20 73 47 43 54  gctestsJS": sGCT
5ae0: 65 73 74 73 4a 53 2c 0a 20 20 20 20 20 20 20 20  estsJS,.        
5af0: 20 20 22 70 61 72 61 67 72 61 70 68 5f 72 75 6c    "paragraph_rul
5b00: 65 73 22 3a 20 6d 65 72 67 65 52 75 6c 65 73 42  es": mergeRulesB
5b10: 79 4f 70 74 69 6f 6e 28 6c 50 61 72 61 67 72 61  yOption(lParagra
5b20: 70 68 52 75 6c 65 73 29 2c 0a 20 20 20 20 20 20  phRules),.      
5b30: 20 20 20 20 22 73 65 6e 74 65 6e 63 65 5f 72 75      "sentence_ru
5b40: 6c 65 73 22 3a 20 6d 65 72 67 65 52 75 6c 65 73  les": mergeRules
5b50: 42 79 4f 70 74 69 6f 6e 28 6c 53 65 6e 74 65 6e  ByOption(lSenten
5b60: 63 65 52 75 6c 65 73 29 2c 0a 20 20 20 20 20 20  ceRules),.      
5b70: 20 20 20 20 22 70 61 72 61 67 72 61 70 68 5f 72      "paragraph_r
5b80: 75 6c 65 73 5f 4a 53 22 3a 20 6a 73 63 6f 6e 76  ules_JS": jsconv
5b90: 2e 77 72 69 74 65 52 75 6c 65 73 54 6f 4a 53 41  .writeRulesToJSA
5ba0: 72 72 61 79 28 6d 65 72 67 65 52 75 6c 65 73 42  rray(mergeRulesB
5bb0: 79 4f 70 74 69 6f 6e 28 6c 50 61 72 61 67 72 61  yOption(lParagra
5bc0: 70 68 52 75 6c 65 73 4a 53 29 29 2c 0a 20 20 20  phRulesJS)),.   
5bd0: 20 20 20 20 20 20 20 22 73 65 6e 74 65 6e 63 65         "sentence
5be0: 5f 72 75 6c 65 73 5f 4a 53 22 3a 20 6a 73 63 6f  _rules_JS": jsco
5bf0: 6e 76 2e 77 72 69 74 65 52 75 6c 65 73 54 6f 4a  nv.writeRulesToJ
5c00: 53 41 72 72 61 79 28 6d 65 72 67 65 52 75 6c 65  SArray(mergeRule
5c10: 73 42 79 4f 70 74 69 6f 6e 28 6c 53 65 6e 74 65  sByOption(lSente
5c20: 6e 63 65 52 75 6c 65 73 4a 53 29 29 20 7d 0a 20  nceRulesJS)) }. 
5c30: 20 20 20 64 2e 75 70 64 61 74 65 28 64 4f 70 74     d.update(dOpt
5c40: 69 6f 6e 73 29 0a 0a 20 20 20 20 72 65 74 75 72  ions)..    retur
5c50: 6e 20 64 0a                                      n d.