Grammalecte  Hex Artifact Content

Artifact ed8f69534c827e99c7255bd441487ec8c16180f9e362ad66462980d6d3f5c60a:


0000: 22 22 22 0a 47 72 61 6d 6d 61 6c 65 63 74 65 3a  """.Grammalecte:
0010: 20 63 6f 6d 70 69 6c 65 20 72 75 6c 65 73 0a 22   compile rules."
0020: 22 22 0a 0a 69 6d 70 6f 72 74 20 72 65 0a 69 6d  ""..import re.im
0030: 70 6f 72 74 20 6f 73 0a 69 6d 70 6f 72 74 20 74  port os.import t
0040: 72 61 63 65 62 61 63 6b 0a 69 6d 70 6f 72 74 20  raceback.import 
0050: 6a 73 6f 6e 0a 69 6d 70 6f 72 74 20 63 6f 6c 6f  json.import colo
0060: 72 73 79 73 0a 69 6d 70 6f 72 74 20 74 69 6d 65  rsys.import time
0070: 0a 0a 69 6d 70 6f 72 74 20 63 6f 6d 70 69 6c 65  ..import compile
0080: 5f 72 75 6c 65 73 5f 6a 73 5f 63 6f 6e 76 65 72  _rules_js_conver
0090: 74 20 61 73 20 6a 73 63 6f 6e 76 0a 69 6d 70 6f  t as jsconv.impo
00a0: 72 74 20 63 6f 6d 70 69 6c 65 5f 72 75 6c 65 73  rt compile_rules
00b0: 5f 67 72 61 70 68 20 61 73 20 63 72 67 0a 0a 0a  _graph as crg...
00c0: 64 44 45 46 49 4e 49 54 49 4f 4e 53 20 3d 20 7b  dDEFINITIONS = {
00d0: 7d 0a 64 44 45 43 4c 45 4e 53 49 4f 4e 53 20 3d  }.dDECLENSIONS =
00e0: 20 7b 7d 0a 6c 46 55 4e 43 54 49 4f 4e 53 20 3d   {}.lFUNCTIONS =
00f0: 20 5b 5d 0a 0a 61 52 55 4c 45 53 45 54 20 3d 20   []..aRULESET = 
0100: 73 65 74 28 29 20 20 20 20 20 23 20 73 65 74 20  set()     # set 
0110: 6f 66 20 72 75 6c 65 2d 69 64 73 20 74 6f 20 63  of rule-ids to c
0120: 68 65 63 6b 20 69 66 20 74 68 65 72 65 20 69 73  heck if there is
0130: 20 73 65 76 65 72 61 6c 20 72 75 6c 65 73 20 77   several rules w
0140: 69 74 68 20 74 68 65 20 73 61 6d 65 20 69 64 0a  ith the same id.
0150: 0a 64 4a 53 52 45 47 45 58 45 53 20 3d 20 7b 7d  .dJSREGEXES = {}
0160: 0a 0a 73 57 4f 52 44 4c 49 4d 49 54 4c 45 46 54  ..sWORDLIMITLEFT
0170: 20 20 3d 20 72 22 28 3f 3c 21 5b 5c 77 2e 2c e2    = r"(?<![\w.,.
0180: 80 93 2d 5d 29 22 20 20 20 23 20 72 22 28 3f 3c  ..-])"   # r"(?<
0190: 21 5b 2d 2e 2c e2 80 94 5d 29 5c 62 22 20 20 73  ![-.,...])\b"  s
01a0: 65 65 6d 73 20 73 6c 6f 77 65 72 0a 73 57 4f 52  eems slower.sWOR
01b0: 44 4c 49 4d 49 54 52 49 47 48 54 20 3d 20 72 22  DLIMITRIGHT = r"
01c0: 28 3f 21 5b 5c 77 e2 80 93 2d 5d 29 22 20 20 20  (?![\w...-])"   
01d0: 20 20 20 23 20 72 22 5c 62 28 3f 21 2d e2 80 94     # r"\b(?!-...
01e0: 29 22 20 20 20 20 20 20 20 73 65 65 6d 73 20 73  )"       seems s
01f0: 6c 6f 77 65 72 0a 0a 0a 64 65 66 20 63 6f 6e 76  lower...def conv
0200: 65 72 74 52 47 42 54 6f 49 6e 74 65 67 65 72 20  ertRGBToInteger 
0210: 28 72 2c 20 67 2c 20 62 29 3a 0a 20 20 20 20 22  (r, g, b):.    "
0220: 72 62 67 20 28 69 6e 74 2c 20 69 6e 74 2c 20 69  rbg (int, int, i
0230: 6e 74 29 20 2d 3e 20 69 6e 74 22 0a 20 20 20 20  nt) -> int".    
0240: 72 65 74 75 72 6e 20 28 72 20 26 20 32 35 35 29  return (r & 255)
0250: 20 3c 3c 20 31 36 20 7c 20 28 67 20 26 20 32 35   << 16 | (g & 25
0260: 35 29 20 3c 3c 20 38 20 7c 20 28 62 20 26 20 32  5) << 8 | (b & 2
0270: 35 35 29 0a 0a 0a 64 65 66 20 63 6f 6e 76 65 72  55)...def conver
0280: 74 48 53 4c 54 6f 52 42 47 20 28 68 2c 20 73 2c  tHSLToRBG (h, s,
0290: 20 6c 29 3a 0a 20 20 20 20 22 68 73 6c 20 28 69   l):.    "hsl (i
02a0: 6e 74 2c 20 69 6e 74 2c 20 69 6e 74 29 20 2d 3e  nt, int, int) ->
02b0: 20 5b 69 6e 74 2c 20 69 6e 74 2c 20 69 6e 74 5d   [int, int, int]
02c0: 22 0a 20 20 20 20 72 2c 20 67 2c 20 62 20 3d 20  ".    r, g, b = 
02d0: 63 6f 6c 6f 72 73 79 73 2e 68 6c 73 5f 74 6f 5f  colorsys.hls_to_
02e0: 72 67 62 28 68 2f 33 36 30 2c 20 6c 2f 31 30 30  rgb(h/360, l/100
02f0: 2c 20 73 2f 31 30 30 29 0a 20 20 20 20 72 65 74  , s/100).    ret
0300: 75 72 6e 20 5b 72 6f 75 6e 64 28 72 2a 32 35 35  urn [round(r*255
0310: 29 2c 20 72 6f 75 6e 64 28 67 2a 32 35 35 29 2c  ), round(g*255),
0320: 20 72 6f 75 6e 64 28 62 2a 32 35 35 29 5d 0a 0a   round(b*255)]..
0330: 0a 64 65 66 20 63 72 65 61 74 65 43 6f 6c 6f 72  .def createColor
0340: 73 20 28 64 43 6f 6c 6f 72 29 3a 0a 20 20 20 20  s (dColor):.    
0350: 22 64 69 63 74 69 6f 6e 61 72 79 20 6f 66 20 63  "dictionary of c
0360: 6f 6c 6f 72 73 20 7b 63 6f 6c 6f 72 5f 6e 61 6d  olors {color_nam
0370: 65 3a 20 5b 68 2c 20 73 2c 20 6c 5d 7d 20 2d 3e  e: [h, s, l]} ->
0380: 20 72 65 74 75 72 6e 73 20 64 69 63 74 69 6f 6e   returns diction
0390: 61 72 79 20 6f 66 20 63 6f 6c 6f 72 73 20 61 73  ary of colors as
03a0: 20 64 69 63 74 69 6f 6e 61 72 69 65 73 20 6f 66   dictionaries of
03b0: 20 63 6f 6c 6f 72 20 74 79 70 65 73 22 0a 20 20   color types".  
03c0: 20 20 64 43 6f 6c 6f 72 54 79 70 65 20 3d 20 7b    dColorType = {
03d0: 0a 20 20 20 20 20 20 20 20 22 61 48 53 4c 22 3a  .        "aHSL":
03e0: 20 7b 7d 2c 20 20 20 20 20 23 20 64 69 63 74 69   {},     # dicti
03f0: 6f 6e 61 72 79 20 6f 66 20 63 6f 6c 6f 72 73 20  onary of colors 
0400: 61 73 20 48 53 4c 20 6c 69 73 74 0a 20 20 20 20  as HSL list.    
0410: 20 20 20 20 22 73 43 53 53 22 3a 20 7b 7d 2c 20      "sCSS": {}, 
0420: 20 20 20 20 23 20 64 69 63 74 69 6f 6e 61 72 79      # dictionary
0430: 20 6f 66 20 63 6f 6c 6f 72 73 20 61 73 20 73 74   of colors as st
0440: 72 69 6e 67 73 20 66 6f 72 20 48 54 4d 4c 2f 43  rings for HTML/C
0450: 53 53 20 28 65 78 61 6d 70 6c 65 3a 20 68 73 6c  SS (example: hsl
0460: 28 30 2c 20 35 30 25 2c 20 35 30 25 29 29 0a 20  (0, 50%, 50%)). 
0470: 20 20 20 20 20 20 20 22 61 52 47 42 22 3a 20 7b         "aRGB": {
0480: 7d 2c 20 20 20 20 20 23 20 64 69 63 74 69 6f 6e  },     # diction
0490: 61 72 79 20 6f 66 20 63 6f 6c 6f 72 73 20 61 73  ary of colors as
04a0: 20 52 47 42 20 6c 69 73 74 0a 20 20 20 20 20 20   RGB list.      
04b0: 20 20 22 6e 49 6e 74 22 3a 20 7b 7d 20 20 20 20    "nInt": {}    
04c0: 20 20 23 20 64 69 63 74 69 6f 6e 61 72 79 20 6f    # dictionary o
04d0: 66 20 63 6f 6c 6f 72 73 20 61 73 20 69 6e 74 65  f colors as inte
04e0: 67 65 72 20 76 61 6c 75 65 73 20 28 66 6f 72 20  ger values (for 
04f0: 57 72 69 74 65 72 29 0a 20 20 20 20 7d 0a 20 20  Writer).    }.  
0500: 20 20 66 6f 72 20 73 4b 65 79 2c 20 61 48 53 4c    for sKey, aHSL
0510: 20 69 6e 20 64 43 6f 6c 6f 72 2e 69 74 65 6d 73   in dColor.items
0520: 28 29 3a 0a 20 20 20 20 20 20 20 20 64 43 6f 6c  ():.        dCol
0530: 6f 72 54 79 70 65 5b 22 61 48 53 4c 22 5d 5b 73  orType["aHSL"][s
0540: 4b 65 79 5d 20 3d 20 61 48 53 4c 0a 20 20 20 20  Key] = aHSL.    
0550: 20 20 20 20 64 43 6f 6c 6f 72 54 79 70 65 5b 22      dColorType["
0560: 73 43 53 53 22 5d 5b 73 4b 65 79 5d 20 3d 20 22  sCSS"][sKey] = "
0570: 68 73 6c 28 7b 7d 2c 20 7b 7d 25 2c 20 7b 7d 25  hsl({}, {}%, {}%
0580: 29 22 2e 66 6f 72 6d 61 74 28 2a 61 48 53 4c 29  )".format(*aHSL)
0590: 0a 20 20 20 20 20 20 20 20 64 43 6f 6c 6f 72 54  .        dColorT
05a0: 79 70 65 5b 22 61 52 47 42 22 5d 5b 73 4b 65 79  ype["aRGB"][sKey
05b0: 5d 20 3d 20 63 6f 6e 76 65 72 74 48 53 4c 54 6f  ] = convertHSLTo
05c0: 52 42 47 28 2a 61 48 53 4c 29 0a 20 20 20 20 20  RBG(*aHSL).     
05d0: 20 20 20 64 43 6f 6c 6f 72 54 79 70 65 5b 22 6e     dColorType["n
05e0: 49 6e 74 22 5d 5b 73 4b 65 79 5d 20 3d 20 63 6f  Int"][sKey] = co
05f0: 6e 76 65 72 74 52 47 42 54 6f 49 6e 74 65 67 65  nvertRGBToIntege
0600: 72 28 2a 64 43 6f 6c 6f 72 54 79 70 65 5b 22 61  r(*dColorType["a
0610: 52 47 42 22 5d 5b 73 4b 65 79 5d 29 0a 20 20 20  RGB"][sKey]).   
0620: 20 72 65 74 75 72 6e 20 64 43 6f 6c 6f 72 54 79   return dColorTy
0630: 70 65 0a 0a 0a 64 65 66 20 70 72 65 70 61 72 65  pe...def prepare
0640: 46 75 6e 63 74 69 6f 6e 20 28 73 29 3a 0a 20 20  Function (s):.  
0650: 20 20 22 63 6f 6e 76 65 72 74 20 73 69 6d 70 6c    "convert simpl
0660: 65 20 72 75 6c 65 20 73 79 6e 74 61 78 20 74 6f  e rule syntax to
0670: 20 61 20 73 74 72 69 6e 67 20 6f 66 20 50 79 74   a string of Pyt
0680: 68 6f 6e 20 63 6f 64 65 22 0a 20 20 20 20 73 20  hon code".    s 
0690: 3d 20 73 2e 72 65 70 6c 61 63 65 28 22 5f 5f 61  = s.replace("__a
06a0: 6c 73 6f 5f 5f 22 2c 20 22 62 43 6f 6e 64 4d 65  lso__", "bCondMe
06b0: 6d 6f 22 29 0a 20 20 20 20 73 20 3d 20 73 2e 72  mo").    s = s.r
06c0: 65 70 6c 61 63 65 28 22 5f 5f 65 6c 73 65 5f 5f  eplace("__else__
06d0: 22 2c 20 22 6e 6f 74 20 62 43 6f 6e 64 4d 65 6d  ", "not bCondMem
06e0: 6f 22 29 0a 20 20 20 20 73 20 3d 20 73 2e 72 65  o").    s = s.re
06f0: 70 6c 61 63 65 28 22 73 43 6f 6e 74 65 78 74 22  place("sContext"
0700: 2c 20 22 5f 73 41 70 70 43 6f 6e 74 65 78 74 22  , "_sAppContext"
0710: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0720: 28 72 22 69 73 53 74 61 72 74 20 2a 5c 28 5c 29  (r"isStart *\(\)
0730: 22 2c 20 27 62 65 66 6f 72 65 28 22 5e 20 2a 24  ", 'before("^ *$
0740: 7c 2c 20 2a 24 22 29 27 2c 20 73 29 0a 20 20 20  |, *$")', s).   
0750: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73   s = re.sub(r"is
0760: 52 65 61 6c 53 74 61 72 74 20 2a 5c 28 5c 29 22  RealStart *\(\)"
0770: 2c 20 27 62 65 66 6f 72 65 28 22 5e 20 2a 24 22  , 'before("^ *$"
0780: 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72  )', s).    s = r
0790: 65 2e 73 75 62 28 72 22 69 73 53 74 61 72 74 30  e.sub(r"isStart0
07a0: 20 2a 5c 28 5c 29 22 2c 20 27 62 65 66 6f 72 65   *\(\)", 'before
07b0: 30 28 22 5e 20 2a 24 7c 2c 20 2a 24 22 29 27 2c  0("^ *$|, *$")',
07c0: 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   s).    s = re.s
07d0: 75 62 28 72 22 69 73 52 65 61 6c 53 74 61 72 74  ub(r"isRealStart
07e0: 30 20 2a 5c 28 5c 29 22 2c 20 27 62 65 66 6f 72  0 *\(\)", 'befor
07f0: 65 30 28 22 5e 20 2a 24 22 29 27 2c 20 73 29 0a  e0("^ *$")', s).
0800: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0810: 22 69 73 45 6e 64 20 2a 5c 28 5c 29 22 2c 20 27  "isEnd *\(\)", '
0820: 61 66 74 65 72 28 22 5e 20 2a 24 7c 5e 2c 22 29  after("^ *$|^,")
0830: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0840: 2e 73 75 62 28 72 22 69 73 52 65 61 6c 45 6e 64  .sub(r"isRealEnd
0850: 20 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 28   *\(\)", 'after(
0860: 22 5e 20 2a 24 22 29 27 2c 20 73 29 0a 20 20 20  "^ *$")', s).   
0870: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73   s = re.sub(r"is
0880: 45 6e 64 30 20 2a 5c 28 5c 29 22 2c 20 27 61 66  End0 *\(\)", 'af
0890: 74 65 72 30 28 22 5e 20 2a 24 7c 5e 2c 22 29 27  ter0("^ *$|^,")'
08a0: 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  , s).    s = re.
08b0: 73 75 62 28 72 22 69 73 52 65 61 6c 45 6e 64 30  sub(r"isRealEnd0
08c0: 20 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 30   *\(\)", 'after0
08d0: 28 22 5e 20 2a 24 22 29 27 2c 20 73 29 0a 20 20  ("^ *$")', s).  
08e0: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 28    s = re.sub(r"(
08f0: 73 65 6c 65 63 74 7c 65 78 63 6c 75 64 65 29 5b  select|exclude)[
0900: 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 5c  (][\\](\d+)", '\
0910: 5c 31 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 6d 2e  \1(dTokenPos, m.
0920: 73 74 61 72 74 28 5c 5c 32 29 2c 20 6d 2e 67 72  start(\\2), m.gr
0930: 6f 75 70 28 5c 5c 32 29 27 2c 20 73 29 0a 20 20  oup(\\2)', s).  
0940: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 64    s = re.sub(r"d
0950: 65 66 69 6e 65 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b  efine[(][\\](\d+
0960: 29 22 2c 20 27 64 65 66 69 6e 65 28 64 54 6f 6b  )", 'define(dTok
0970: 65 6e 50 6f 73 2c 20 6d 2e 73 74 61 72 74 28 5c  enPos, m.start(\
0980: 5c 31 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  \1)', s).    s =
0990: 20 72 65 2e 73 75 62 28 72 22 28 6d 6f 72 70 68   re.sub(r"(morph
09a0: 7c 64 69 73 70 6c 61 79 49 6e 66 6f 29 5b 28 5d  |displayInfo)[(]
09b0: 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27 5c 5c 31  [\\](\d+)", '\\1
09c0: 28 28 6d 2e 73 74 61 72 74 28 5c 5c 32 29 2c 20  ((m.start(\\2), 
09d0: 6d 2e 67 72 6f 75 70 28 5c 5c 32 29 29 27 2c 20  m.group(\\2))', 
09e0: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
09f0: 62 28 72 22 28 6d 6f 72 70 68 7c 64 69 73 70 6c  b(r"(morph|displ
0a00: 61 79 49 6e 66 6f 29 5b 28 5d 22 2c 20 27 5c 5c  ayInfo)[(]", '\\
0a10: 31 28 64 54 6f 6b 65 6e 50 6f 73 2c 20 27 2c 20  1(dTokenPos, ', 
0a20: 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  s).    s = re.su
0a30: 62 28 72 22 28 73 75 67 67 5c 77 2b 7c 73 77 69  b(r"(sugg\w+|swi
0a40: 74 63 68 5c 77 2b 29 5c 28 40 22 2c 20 27 5c 5c  tch\w+)\(@", '\\
0a50: 31 28 6d 2e 67 72 6f 75 70 28 69 5b 34 5d 29 27  1(m.group(i[4])'
0a60: 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  , s).    s = re.
0a70: 73 75 62 28 72 22 77 6f 72 64 5c 28 5c 73 2a 31  sub(r"word\(\s*1
0a80: 5c 62 22 2c 20 27 6e 65 78 74 77 6f 72 64 31 28  \b", 'nextword1(
0a90: 73 53 65 6e 74 65 6e 63 65 2c 20 6d 2e 65 6e 64  sSentence, m.end
0aa0: 28 29 27 2c 20 73 29 20 20 20 20 20 20 20 20 20  ()', s)         
0ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ac0: 20 20 20 20 20 20 20 20 20 23 20 77 6f 72 64 28           # word(
0ad0: 31 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  1).    s = re.su
0ae0: 62 28 72 22 77 6f 72 64 5c 28 5c 73 2a 2d 31 5c  b(r"word\(\s*-1\
0af0: 62 22 2c 20 27 70 72 65 76 77 6f 72 64 31 28 73  b", 'prevword1(s
0b00: 53 65 6e 74 65 6e 63 65 2c 20 6d 2e 73 74 61 72  Sentence, m.star
0b10: 74 28 29 27 2c 20 73 29 20 20 20 20 20 20 20 20  t()', s)        
0b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b30: 20 20 20 20 20 20 20 23 20 77 6f 72 64 28 2d 31         # word(-1
0b40: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0b50: 28 72 22 77 6f 72 64 5c 28 5c 73 2a 28 5c 64 29  (r"word\(\s*(\d)
0b60: 22 2c 20 27 6e 65 78 74 77 6f 72 64 28 73 53 65  ", 'nextword(sSe
0b70: 6e 74 65 6e 63 65 2c 20 6d 2e 65 6e 64 28 29 2c  ntence, m.end(),
0b80: 20 5c 5c 31 27 2c 20 73 29 20 20 20 20 20 20 20   \\1', s)       
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ba0: 20 20 20 20 20 20 23 20 77 6f 72 64 28 6e 29 0a        # word(n).
0bb0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0bc0: 22 77 6f 72 64 5c 28 5c 73 2a 2d 28 5c 64 29 22  "word\(\s*-(\d)"
0bd0: 2c 20 27 70 72 65 76 77 6f 72 64 28 73 53 65 6e  , 'prevword(sSen
0be0: 74 65 6e 63 65 2c 20 6d 2e 73 74 61 72 74 28 29  tence, m.start()
0bf0: 2c 20 5c 5c 31 27 2c 20 73 29 20 20 20 20 20 20  , \\1', s)      
0c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c10: 20 20 20 20 23 20 77 6f 72 64 28 2d 6e 29 0a 20      # word(-n). 
0c20: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0c30: 62 65 66 6f 72 65 5c 28 5c 73 2a 22 2c 20 27 6c  before\(\s*", 'l
0c40: 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 5b 3a 6d  ook(sSentence[:m
0c50: 2e 73 74 61 72 74 28 29 5d 2c 20 27 2c 20 73 29  .start()], ', s)
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c80: 20 20 20 23 20 62 65 66 6f 72 65 28 73 53 65 6e     # before(sSen
0c90: 74 65 6e 63 65 29 0a 20 20 20 20 73 20 3d 20 72  tence).    s = r
0ca0: 65 2e 73 75 62 28 72 22 61 66 74 65 72 5c 28 5c  e.sub(r"after\(\
0cb0: 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73 53 65 6e 74  s*", 'look(sSent
0cc0: 65 6e 63 65 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20  ence[m.end():], 
0cd0: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cf0: 20 20 20 20 20 20 20 20 20 20 20 23 20 61 66 74             # aft
0d00: 65 72 28 73 53 65 6e 74 65 6e 63 65 29 0a 20 20  er(sSentence).  
0d10: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 74    s = re.sub(r"t
0d20: 65 78 74 61 72 65 61 5c 28 5c 73 2a 22 2c 20 27  extarea\(\s*", '
0d30: 6c 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 2c 20  look(sSentence, 
0d40: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d70: 20 20 23 20 74 65 78 74 61 72 65 61 28 73 53 65    # textarea(sSe
0d80: 6e 74 65 6e 63 65 29 0a 20 20 20 20 73 20 3d 20  ntence).    s = 
0d90: 72 65 2e 73 75 62 28 72 22 2f 30 22 2c 20 27 73  re.sub(r"/0", 's
0da0: 53 65 6e 74 65 6e 63 65 30 5b 6d 2e 73 74 61 72  Sentence0[m.star
0db0: 74 28 29 3a 6d 2e 65 6e 64 28 29 5d 27 2c 20 73  t():m.end()]', s
0dc0: 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  )               
0dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0de0: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 2f 30              # /0
0df0: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
0e00: 72 22 62 65 66 6f 72 65 30 5c 28 5c 73 2a 22 2c  r"before0\(\s*",
0e10: 20 27 6c 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65   'look(sSentence
0e20: 30 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2c 20 27  0[:m.start()], '
0e30: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e50: 20 20 20 20 20 23 20 62 65 66 6f 72 65 30 28 73       # before0(s
0e60: 53 65 6e 74 65 6e 63 65 29 0a 20 20 20 20 73 20  Sentence).    s 
0e70: 3d 20 72 65 2e 73 75 62 28 72 22 61 66 74 65 72  = re.sub(r"after
0e80: 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73  0\(\s*", 'look(s
0e90: 53 65 6e 74 65 6e 63 65 30 5b 6d 2e 65 6e 64 28  Sentence0[m.end(
0ea0: 29 3a 5d 2c 20 27 2c 20 73 29 20 20 20 20 20 20  ):], ', s)      
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0ed0: 61 66 74 65 72 30 28 73 53 65 6e 74 65 6e 63 65  after0(sSentence
0ee0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0ef0: 28 72 22 74 65 78 74 61 72 65 61 30 5c 28 5c 73  (r"textarea0\(\s
0f00: 2a 22 2c 20 27 6c 6f 6f 6b 28 73 53 65 6e 74 65  *", 'look(sSente
0f10: 6e 63 65 30 2c 20 27 2c 20 73 29 20 20 20 20 20  nce0, ', s)     
0f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f40: 20 20 20 20 20 20 23 20 74 65 78 74 61 72 65 61        # textarea
0f50: 30 28 73 53 65 6e 74 65 6e 63 65 29 0a 20 20 20  0(sSentence).   
0f60: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 5c 62   s = re.sub(r"\b
0f70: 73 70 65 6c 6c 20 2a 5b 28 5d 22 2c 20 27 5f 6f  spell *[(]", '_o
0f80: 53 70 65 6c 6c 43 68 65 63 6b 65 72 2e 69 73 56  SpellChecker.isV
0f90: 61 6c 69 64 28 27 2c 20 73 29 0a 20 20 20 20 73  alid(', s).    s
0fa0: 20 3d 20 72 65 2e 73 75 62 28 72 22 5b 5c 5c 5d   = re.sub(r"[\\]
0fb0: 28 5c 64 2b 29 22 2c 20 27 6d 2e 67 72 6f 75 70  (\d+)", 'm.group
0fc0: 28 5c 5c 31 29 27 2c 20 73 29 0a 20 20 20 20 72  (\\1)', s).    r
0fd0: 65 74 75 72 6e 20 73 0a 0a 0a 64 65 66 20 75 70  eturn s...def up
0fe0: 70 65 72 63 61 73 65 20 28 73 54 65 78 74 2c 20  percase (sText, 
0ff0: 73 4c 61 6e 67 29 3a 0a 20 20 20 20 22 28 66 6c  sLang):.    "(fl
1000: 61 67 20 69 20 69 73 20 6e 6f 74 20 65 6e 6f 75  ag i is not enou
1010: 67 68 29 3a 20 63 6f 6e 76 65 72 74 73 20 72 65  gh): converts re
1020: 67 65 78 20 74 6f 20 75 70 70 65 72 63 61 73 65  gex to uppercase
1030: 20 72 65 67 65 78 3a 20 27 66 6f 6f 27 20 62 65   regex: 'foo' be
1040: 63 6f 6d 65 73 20 27 5b 46 66 5d 5b 4f 6f 5d 5b  comes '[Ff][Oo][
1050: 4f 6f 5d 27 2c 20 62 75 74 20 27 42 61 72 27 20  Oo]', but 'Bar' 
1060: 62 65 63 6f 6d 65 73 20 27 42 5b 41 61 5d 5b 52  becomes 'B[Aa][R
1070: 72 5d 27 2e 22 0a 20 20 20 20 73 55 70 20 3d 20  r]'.".    sUp = 
1080: 22 22 0a 20 20 20 20 6e 53 74 61 74 65 20 3d 20  "".    nState = 
1090: 30 0a 20 20 20 20 66 6f 72 20 69 2c 20 63 20 69  0.    for i, c i
10a0: 6e 20 65 6e 75 6d 65 72 61 74 65 28 73 54 65 78  n enumerate(sTex
10b0: 74 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 63  t):.        if c
10c0: 20 3d 3d 20 22 5b 22 3a 0a 20 20 20 20 20 20 20   == "[":.       
10d0: 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20 31 0a       nState = 1.
10e0: 20 20 20 20 20 20 20 20 69 66 20 6e 53 74 61 74          if nStat
10f0: 65 20 3d 3d 20 31 20 61 6e 64 20 63 20 3d 3d 20  e == 1 and c == 
1100: 22 5d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "]":.           
1110: 20 6e 53 74 61 74 65 20 3d 20 30 0a 20 20 20 20   nState = 0.    
1120: 20 20 20 20 69 66 20 63 20 3d 3d 20 22 3c 22 20      if c == "<" 
1130: 61 6e 64 20 69 20 3e 20 33 20 61 6e 64 20 73 54  and i > 3 and sT
1140: 65 78 74 5b 69 2d 33 3a 69 5d 20 3d 3d 20 22 28  ext[i-3:i] == "(
1150: 3f 50 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ?P":.           
1160: 20 6e 53 74 61 74 65 20 3d 20 32 0a 20 20 20 20   nState = 2.    
1170: 20 20 20 20 69 66 20 6e 53 74 61 74 65 20 3d 3d      if nState ==
1180: 20 32 20 61 6e 64 20 63 20 3d 3d 20 22 3e 22 3a   2 and c == ">":
1190: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74  .            nSt
11a0: 61 74 65 20 3d 20 30 0a 20 20 20 20 20 20 20 20  ate = 0.        
11b0: 69 66 20 63 20 3d 3d 20 22 3f 22 20 61 6e 64 20  if c == "?" and 
11c0: 69 20 3e 20 30 20 61 6e 64 20 73 54 65 78 74 5b  i > 0 and sText[
11d0: 69 2d 31 3a 69 5d 20 3d 3d 20 22 28 22 20 61 6e  i-1:i] == "(" an
11e0: 64 20 73 54 65 78 74 5b 69 2b 31 3a 69 2b 32 5d  d sText[i+1:i+2]
11f0: 20 21 3d 20 22 3a 22 3a 0a 20 20 20 20 20 20 20   != ":":.       
1200: 20 20 20 20 20 6e 53 74 61 74 65 20 3d 20 35 0a       nState = 5.
1210: 20 20 20 20 20 20 20 20 69 66 20 6e 53 74 61 74          if nStat
1220: 65 20 3d 3d 20 35 20 61 6e 64 20 63 20 3d 3d 20  e == 5 and c == 
1230: 22 29 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ")":.           
1240: 20 6e 53 74 61 74 65 20 3d 20 30 0a 20 20 20 20   nState = 0.    
1250: 20 20 20 20 69 66 20 63 2e 69 73 61 6c 70 68 61      if c.isalpha
1260: 28 29 20 61 6e 64 20 63 2e 69 73 6c 6f 77 65 72  () and c.islower
1270: 28 29 20 61 6e 64 20 6e 53 74 61 74 65 20 3d 3d  () and nState ==
1280: 20 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20   0:.            
1290: 69 66 20 63 20 3d 3d 20 22 69 22 20 61 6e 64 20  if c == "i" and 
12a0: 73 4c 61 6e 67 20 69 6e 20 28 22 74 72 22 2c 20  sLang in ("tr", 
12b0: 22 61 7a 22 29 3a 0a 20 20 20 20 20 20 20 20 20  "az"):.         
12c0: 20 20 20 20 20 20 20 73 55 70 20 2b 3d 20 22 5b         sUp += "[
12d0: c4 b0 22 20 2b 20 63 20 2b 20 22 5d 22 0a 20 20  .." + c + "]".  
12e0: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
12f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1300: 73 55 70 20 2b 3d 20 22 5b 22 20 2b 20 63 2e 75  sUp += "[" + c.u
1310: 70 70 65 72 28 29 20 2b 20 63 20 2b 20 22 5d 22  pper() + c + "]"
1320: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 63 2e  .        elif c.
1330: 69 73 61 6c 70 68 61 28 29 20 61 6e 64 20 63 2e  isalpha() and c.
1340: 69 73 6c 6f 77 65 72 28 29 20 61 6e 64 20 6e 53  islower() and nS
1350: 74 61 74 65 20 3d 3d 20 31 20 61 6e 64 20 73 54  tate == 1 and sT
1360: 65 78 74 5b 69 2b 31 3a 69 2b 32 5d 20 21 3d 20  ext[i+1:i+2] != 
1370: 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "-":.           
1380: 20 69 66 20 73 54 65 78 74 5b 69 2d 31 3a 69 5d   if sText[i-1:i]
1390: 20 3d 3d 20 22 2d 22 20 61 6e 64 20 73 54 65 78   == "-" and sTex
13a0: 74 5b 69 2d 32 3a 69 2d 31 5d 2e 69 73 6c 6f 77  t[i-2:i-1].islow
13b0: 65 72 28 29 3a 20 20 23 20 5b 61 2d 7a 5d 20 2d  er():  # [a-z] -
13c0: 3e 20 5b 61 2d 7a 41 2d 5a 5d 0a 20 20 20 20 20  > [a-zA-Z].     
13d0: 20 20 20 20 20 20 20 20 20 20 20 73 55 70 20 2b             sUp +
13e0: 3d 20 63 20 2b 20 73 54 65 78 74 5b 69 2d 32 3a  = c + sText[i-2:
13f0: 69 2d 31 5d 2e 75 70 70 65 72 28 29 20 2b 20 22  i-1].upper() + "
1400: 2d 22 20 2b 20 63 2e 75 70 70 65 72 28 29 0a 20  -" + c.upper(). 
1410: 20 20 20 20 20 20 20 20 20 20 20 65 6c 69 66 20             elif 
1420: 63 20 3d 3d 20 22 69 22 20 61 6e 64 20 73 4c 61  c == "i" and sLa
1430: 6e 67 20 69 6e 20 28 22 74 72 22 2c 20 22 61 7a  ng in ("tr", "az
1440: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
1450: 20 20 20 20 73 55 70 20 2b 3d 20 22 c4 b0 22 20      sUp += ".." 
1460: 2b 20 63 0a 20 20 20 20 20 20 20 20 20 20 20 20  + c.            
1470: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
1480: 20 20 20 20 20 20 73 55 70 20 2b 3d 20 63 2e 75        sUp += c.u
1490: 70 70 65 72 28 29 20 2b 20 63 0a 20 20 20 20 20  pper() + c.     
14a0: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
14b0: 20 20 20 20 20 73 55 70 20 2b 3d 20 63 0a 20 20       sUp += c.  
14c0: 20 20 20 20 20 20 69 66 20 63 20 3d 3d 20 22 5c        if c == "\
14d0: 5c 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  \":.            
14e0: 6e 53 74 61 74 65 20 3d 20 34 0a 20 20 20 20 20  nState = 4.     
14f0: 20 20 20 65 6c 69 66 20 6e 53 74 61 74 65 20 3d     elif nState =
1500: 3d 20 34 3a 0a 20 20 20 20 20 20 20 20 20 20 20  = 4:.           
1510: 20 6e 53 74 61 74 65 20 3d 20 30 0a 20 20 20 20   nState = 0.    
1520: 72 65 74 75 72 6e 20 73 55 70 0a 0a 0a 64 65 66  return sUp...def
1530: 20 63 6f 75 6e 74 47 72 6f 75 70 49 6e 52 65 67   countGroupInReg
1540: 65 78 20 28 73 52 65 67 65 78 29 3a 0a 20 20 20  ex (sRegex):.   
1550: 20 22 72 65 74 75 72 6e 73 20 74 68 65 20 6e 75   "returns the nu
1560: 6d 62 65 72 20 6f 66 20 67 72 6f 75 70 73 20 69  mber of groups i
1570: 6e 20 3c 73 52 65 67 65 78 3e 22 0a 20 20 20 20  n <sRegex>".    
1580: 74 72 79 3a 0a 20 20 20 20 20 20 20 20 72 65 74  try:.        ret
1590: 75 72 6e 20 72 65 2e 63 6f 6d 70 69 6c 65 28 73  urn re.compile(s
15a0: 52 65 67 65 78 29 2e 67 72 6f 75 70 73 0a 20 20  Regex).groups.  
15b0: 20 20 65 78 63 65 70 74 20 72 65 2e 65 72 72 6f    except re.erro
15c0: 72 3a 0a 20 20 20 20 20 20 20 20 74 72 61 63 65  r:.        trace
15d0: 62 61 63 6b 2e 70 72 69 6e 74 5f 65 78 63 28 29  back.print_exc()
15e0: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 73  .        print(s
15f0: 52 65 67 65 78 29 0a 20 20 20 20 72 65 74 75 72  Regex).    retur
1600: 6e 20 30 0a 0a 0a 64 65 66 20 63 72 65 61 74 65  n 0...def create
1610: 52 75 6c 65 20 28 73 2c 20 6e 49 64 4c 69 6e 65  Rule (s, nIdLine
1620: 2c 20 73 4c 61 6e 67 2c 20 62 50 61 72 61 67 72  , sLang, bParagr
1630: 61 70 68 2c 20 64 4f 70 74 50 72 69 6f 72 69 74  aph, dOptPriorit
1640: 79 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73  y):.    "returns
1650: 20 72 75 6c 65 20 61 73 20 6c 69 73 74 20 5b 6f   rule as list [o
1660: 70 74 69 6f 6e 20 6e 61 6d 65 2c 20 72 65 67 65  ption name, rege
1670: 78 2c 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74  x, bCaseInsensit
1680: 69 76 65 2c 20 69 64 65 6e 74 69 66 69 65 72 2c  ive, identifier,
1690: 20 6c 69 73 74 20 6f 66 20 61 63 74 69 6f 6e 73   list of actions
16a0: 5d 22 0a 20 20 20 20 67 6c 6f 62 61 6c 20 64 4a  ]".    global dJ
16b0: 53 52 45 47 45 58 45 53 0a 0a 20 20 20 20 73 4c  SREGEXES..    sL
16c0: 69 6e 65 49 64 20 3d 20 22 23 22 20 2b 20 73 74  ineId = "#" + st
16d0: 72 28 6e 49 64 4c 69 6e 65 29 20 2b 20 28 22 70  r(nIdLine) + ("p
16e0: 22 20 69 66 20 62 50 61 72 61 67 72 61 70 68 20  " if bParagraph 
16f0: 65 6c 73 65 20 22 73 22 29 0a 20 20 20 20 73 52  else "s").    sR
1700: 75 6c 65 49 64 20 3d 20 73 4c 69 6e 65 49 64 0a  uleId = sLineId.
1710: 0a 20 20 20 20 23 23 23 23 20 47 52 41 50 48 20  .    #### GRAPH 
1720: 43 41 4c 4c 0a 20 20 20 20 69 66 20 73 2e 73 74  CALL.    if s.st
1730: 61 72 74 73 77 69 74 68 28 22 40 40 40 40 22 29  artswith("@@@@")
1740: 3a 0a 20 20 20 20 20 20 20 20 69 66 20 62 50 61  :.        if bPa
1750: 72 61 67 72 61 70 68 3a 0a 20 20 20 20 20 20 20  ragraph:.       
1760: 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f       print("Erro
1770: 72 2e 20 47 72 61 70 68 20 63 61 6c 6c 20 63 61  r. Graph call ca
1780: 6e 20 62 65 20 6d 61 64 65 20 6f 6e 6c 79 20 61  n be made only a
1790: 66 74 65 72 20 74 68 65 20 66 69 72 73 74 20 70  fter the first p
17a0: 61 73 73 20 28 73 65 6e 74 65 6e 63 65 20 62 79  ass (sentence by
17b0: 20 73 65 6e 74 65 6e 63 65 29 22 29 0a 20 20 20   sentence)").   
17c0: 20 20 20 20 20 20 20 20 20 65 78 69 74 28 29 0a           exit().
17d0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b          return [
17e0: 22 40 40 40 40 22 2c 20 73 5b 34 3a 5d 2c 20 73  "@@@@", s[4:], s
17f0: 4c 69 6e 65 49 64 5d 0a 0a 20 20 20 20 23 23 23  LineId]..    ###
1800: 23 20 4f 50 54 49 4f 4e 53 0a 20 20 20 20 73 4f  # OPTIONS.    sO
1810: 70 74 69 6f 6e 20 3d 20 46 61 6c 73 65 20 20 20  ption = False   
1820: 20 20 20 20 20 20 23 20 46 61 6c 73 65 20 6f 72        # False or
1830: 20 5b 61 2d 7a 30 2d 39 5d 2b 20 6e 61 6d 65 0a   [a-z0-9]+ name.
1840: 20 20 20 20 6e 50 72 69 6f 72 69 74 79 20 3d 20      nPriority = 
1850: 34 20 20 20 20 20 20 20 20 20 20 20 23 20 44 65  4           # De
1860: 66 61 75 6c 74 20 69 73 20 34 2c 20 76 61 6c 75  fault is 4, valu
1870: 65 20 6d 75 73 74 20 62 65 20 62 65 74 77 65 65  e must be betwee
1880: 6e 20 30 20 61 6e 64 20 39 0a 20 20 20 20 74 47  n 0 and 9.    tG
1890: 72 6f 75 70 73 20 3d 20 4e 6f 6e 65 20 20 20 20  roups = None    
18a0: 20 20 20 20 20 20 23 20 63 6f 64 65 20 66 6f 72        # code for
18b0: 20 67 72 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e   groups position
18c0: 69 6e 67 20 28 6f 6e 6c 79 20 75 73 65 66 75 6c  ing (only useful
18d0: 20 66 6f 72 20 4a 61 76 61 53 63 72 69 70 74 29   for JavaScript)
18e0: 0a 20 20 20 20 63 43 61 73 65 4d 6f 64 65 20 3d  .    cCaseMode =
18f0: 20 27 69 27 20 20 20 20 20 20 20 20 20 23 20 69   'i'         # i
1900: 3a 20 63 61 73 65 20 69 6e 73 65 6e 73 69 74 69  : case insensiti
1910: 76 65 2c 20 20 73 3a 20 63 61 73 65 20 73 65 6e  ve,  s: case sen
1920: 73 69 74 69 76 65 2c 20 20 75 3a 20 75 70 70 65  sitive,  u: uppe
1930: 72 63 61 73 69 6e 67 20 61 6c 6c 6f 77 65 64 0a  rcasing allowed.
1940: 20 20 20 20 63 57 6f 72 64 4c 69 6d 69 74 4c 65      cWordLimitLe
1950: 66 74 20 3d 20 27 5b 27 20 20 20 20 23 20 5b 3a  ft = '['    # [:
1960: 20 77 6f 72 64 20 6c 69 6d 69 74 2c 20 3c 3a 20   word limit, <: 
1970: 6e 6f 20 73 70 65 63 69 66 69 63 20 6c 69 6d 69  no specific limi
1980: 74 0a 20 20 20 20 63 57 6f 72 64 4c 69 6d 69 74  t.    cWordLimit
1990: 52 69 67 68 74 20 3d 20 27 5d 27 20 20 20 23 20  Right = ']'   # 
19a0: 5d 3a 20 77 6f 72 64 20 6c 69 6d 69 74 2c 20 3e  ]: word limit, >
19b0: 3a 20 6e 6f 20 73 70 65 63 69 66 69 63 20 6c 69  : no specific li
19c0: 6d 69 74 0a 20 20 20 20 6d 20 3d 20 72 65 2e 6d  mit.    m = re.m
19d0: 61 74 63 68 28 22 5e 5f 5f 28 3f 50 3c 62 6f 72  atch("^__(?P<bor
19e0: 64 65 72 73 5f 61 6e 64 5f 63 61 73 65 3e 5b 5c  ders_and_case>[\
19f0: 5c 5b 3c 5d 5c 5c 77 5b 5c 5c 5d 3e 5d 29 28 3f  \[<]\\w[\\]>])(?
1a00: 50 3c 6f 70 74 69 6f 6e 3e 2f 5b 61 2d 7a 41 2d  P<option>/[a-zA-
1a10: 5a 30 2d 39 5d 2b 7c 29 28 3f 50 3c 72 75 6c 65  Z0-9]+|)(?P<rule
1a20: 69 64 3e 5c 5c 28 5c 5c 77 2b 5c 5c 29 29 28 3f  id>\\(\\w+\\))(?
1a30: 50 3c 70 72 69 6f 72 69 74 79 3e 21 5b 30 2d 39  P<priority>![0-9
1a40: 5d 7c 29 5f 5f 20 2a 22 2c 20 73 29 0a 20 20 20  ]|)__ *", s).   
1a50: 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20 63   if m:.        c
1a60: 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20 3d 20  WordLimitLeft = 
1a70: 6d 2e 67 72 6f 75 70 28 27 62 6f 72 64 65 72 73  m.group('borders
1a80: 5f 61 6e 64 5f 63 61 73 65 27 29 5b 30 5d 0a 20  _and_case')[0]. 
1a90: 20 20 20 20 20 20 20 63 43 61 73 65 4d 6f 64 65         cCaseMode
1aa0: 20 3d 20 6d 2e 67 72 6f 75 70 28 27 62 6f 72 64   = m.group('bord
1ab0: 65 72 73 5f 61 6e 64 5f 63 61 73 65 27 29 5b 31  ers_and_case')[1
1ac0: 5d 0a 20 20 20 20 20 20 20 20 63 57 6f 72 64 4c  ].        cWordL
1ad0: 69 6d 69 74 52 69 67 68 74 20 3d 20 6d 2e 67 72  imitRight = m.gr
1ae0: 6f 75 70 28 27 62 6f 72 64 65 72 73 5f 61 6e 64  oup('borders_and
1af0: 5f 63 61 73 65 27 29 5b 32 5d 0a 20 20 20 20 20  _case')[2].     
1b00: 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 6d 2e 67     sOption = m.g
1b10: 72 6f 75 70 28 27 6f 70 74 69 6f 6e 27 29 5b 31  roup('option')[1
1b20: 3a 5d 20 20 69 66 20 6d 2e 67 72 6f 75 70 28 27  :]  if m.group('
1b30: 6f 70 74 69 6f 6e 27 29 20 20 65 6c 73 65 20 46  option')  else F
1b40: 61 6c 73 65 0a 20 20 20 20 20 20 20 20 73 52 75  alse.        sRu
1b50: 6c 65 49 64 20 3d 20 20 6d 2e 67 72 6f 75 70 28  leId =  m.group(
1b60: 27 72 75 6c 65 69 64 27 29 5b 31 3a 2d 31 5d 0a  'ruleid')[1:-1].
1b70: 20 20 20 20 20 20 20 20 69 66 20 73 52 75 6c 65          if sRule
1b80: 49 64 20 69 6e 20 61 52 55 4c 45 53 45 54 3a 0a  Id in aRULESET:.
1b90: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
1ba0: 74 28 22 23 20 45 72 72 6f 72 2e 20 53 65 76 65  t("# Error. Seve
1bb0: 72 61 6c 20 72 75 6c 65 73 20 68 61 76 65 20 74  ral rules have t
1bc0: 68 65 20 73 61 6d 65 20 69 64 3a 20 22 20 2b 20  he same id: " + 
1bd0: 73 52 75 6c 65 49 64 29 0a 20 20 20 20 20 20 20  sRuleId).       
1be0: 20 20 20 20 20 65 78 69 74 28 29 0a 20 20 20 20       exit().    
1bf0: 20 20 20 20 61 52 55 4c 45 53 45 54 2e 61 64 64      aRULESET.add
1c00: 28 73 52 75 6c 65 49 64 29 0a 20 20 20 20 20 20  (sRuleId).      
1c10: 20 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 64 4f    nPriority = dO
1c20: 70 74 50 72 69 6f 72 69 74 79 2e 67 65 74 28 73  ptPriority.get(s
1c30: 4f 70 74 69 6f 6e 2c 20 34 29 0a 20 20 20 20 20  Option, 4).     
1c40: 20 20 20 69 66 20 6d 2e 67 72 6f 75 70 28 27 70     if m.group('p
1c50: 72 69 6f 72 69 74 79 27 29 3a 0a 20 20 20 20 20  riority'):.     
1c60: 20 20 20 20 20 20 20 6e 50 72 69 6f 72 69 74 79         nPriority
1c70: 20 3d 20 69 6e 74 28 6d 2e 67 72 6f 75 70 28 27   = int(m.group('
1c80: 70 72 69 6f 72 69 74 79 27 29 5b 31 3a 5d 29 0a  priority')[1:]).
1c90: 20 20 20 20 20 20 20 20 73 20 3d 20 73 5b 6d 2e          s = s[m.
1ca0: 65 6e 64 28 30 29 3a 5d 0a 20 20 20 20 65 6c 73  end(0):].    els
1cb0: 65 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  e:.        print
1cc0: 28 22 23 20 57 61 72 6e 69 6e 67 2e 20 52 75 6c  ("# Warning. Rul
1cd0: 65 20 77 72 6f 6e 67 6c 79 20 73 68 61 70 65 64  e wrongly shaped
1ce0: 20 61 74 20 6c 69 6e 65 3a 20 22 20 2b 20 73 4c   at line: " + sL
1cf0: 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20 65  ineId).        e
1d00: 78 69 74 28 29 0a 0a 20 20 20 20 23 23 23 23 20  xit()..    #### 
1d10: 52 45 47 45 58 20 54 52 49 47 47 45 52 0a 20 20  REGEX TRIGGER.  
1d20: 20 20 69 20 3d 20 73 2e 66 69 6e 64 28 22 20 3c    i = s.find(" <
1d30: 3c 2d 22 29 0a 20 20 20 20 69 66 20 69 20 3d 3d  <-").    if i ==
1d40: 20 2d 31 3a 0a 20 20 20 20 20 20 20 20 70 72 69   -1:.        pri
1d50: 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 6e 6f 20  nt("# Error: no 
1d60: 63 6f 6e 64 69 74 69 6f 6e 20 61 74 20 6c 69 6e  condition at lin
1d70: 65 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 20  e " + sLineId). 
1d80: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 6f         return No
1d90: 6e 65 0a 20 20 20 20 73 52 65 67 65 78 20 3d 20  ne.    sRegex = 
1da0: 73 5b 3a 69 5d 2e 73 74 72 69 70 28 29 0a 20 20  s[:i].strip().  
1db0: 20 20 73 20 3d 20 73 5b 69 2b 34 3a 5d 0a 0a 20    s = s[i+4:].. 
1dc0: 20 20 20 23 20 4a 53 20 67 72 6f 75 70 73 20 70     # JS groups p
1dd0: 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f 64 65 73  ositioning codes
1de0: 0a 20 20 20 20 6d 20 3d 20 72 65 2e 73 65 61 72  .    m = re.sear
1df0: 63 68 28 22 40 40 5c 5c 53 2b 22 2c 20 73 52 65  ch("@@\\S+", sRe
1e00: 67 65 78 29 0a 20 20 20 20 69 66 20 6d 3a 0a 20  gex).    if m:. 
1e10: 20 20 20 20 20 20 20 74 47 72 6f 75 70 73 20 3d         tGroups =
1e20: 20 6a 73 63 6f 6e 76 2e 67 72 6f 75 70 73 50 6f   jsconv.groupsPo
1e30: 73 69 74 69 6f 6e 69 6e 67 43 6f 64 65 54 6f 4c  sitioningCodeToL
1e40: 69 73 74 28 73 52 65 67 65 78 5b 6d 2e 73 74 61  ist(sRegex[m.sta
1e50: 72 74 28 29 2b 32 3a 5d 29 0a 20 20 20 20 20 20  rt()+2:]).      
1e60: 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67 65    sRegex = sRege
1e70: 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2e 73 74  x[:m.start()].st
1e80: 72 69 70 28 29 0a 20 20 20 20 23 20 4a 53 20 72  rip().    # JS r
1e90: 65 67 65 78 0a 20 20 20 20 6d 20 3d 20 72 65 2e  egex.    m = re.
1ea0: 73 65 61 72 63 68 28 22 3c 6a 73 3e 2e 2b 3c 2f  search("<js>.+</
1eb0: 6a 73 3e 69 3f 22 2c 20 73 52 65 67 65 78 29 0a  js>i?", sRegex).
1ec0: 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20      if m:.      
1ed0: 20 20 64 4a 53 52 45 47 45 58 45 53 5b 73 4c 69    dJSREGEXES[sLi
1ee0: 6e 65 49 64 5d 20 3d 20 6d 2e 67 72 6f 75 70 28  neId] = m.group(
1ef0: 30 29 0a 20 20 20 20 20 20 20 20 73 52 65 67 65  0).        sRege
1f00: 78 20 3d 20 73 52 65 67 65 78 5b 3a 6d 2e 73 74  x = sRegex[:m.st
1f10: 61 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a 20  art()].strip(). 
1f20: 20 20 20 69 66 20 22 3c 6a 73 3e 22 20 69 6e 20     if "<js>" in 
1f30: 73 52 65 67 65 78 20 6f 72 20 22 3c 2f 6a 73 3e  sRegex or "</js>
1f40: 22 20 69 6e 20 73 52 65 67 65 78 3a 0a 20 20 20  " in sRegex:.   
1f50: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72       print("# Er
1f60: 72 6f 72 3a 20 4a 61 76 61 53 63 72 69 70 74 20  ror: JavaScript 
1f70: 72 65 67 65 78 20 6e 6f 74 20 64 65 6c 69 6d 69  regex not delimi
1f80: 74 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ted at line " + 
1f90: 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20  sLineId).       
1fa0: 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20   return None..  
1fb0: 20 20 23 20 71 75 6f 74 65 73 20 3f 0a 20 20 20    # quotes ?.   
1fc0: 20 69 66 20 73 52 65 67 65 78 2e 73 74 61 72 74   if sRegex.start
1fd0: 73 77 69 74 68 28 27 22 27 29 20 61 6e 64 20 73  swith('"') and s
1fe0: 52 65 67 65 78 2e 65 6e 64 73 77 69 74 68 28 27  Regex.endswith('
1ff0: 22 27 29 3a 0a 20 20 20 20 20 20 20 20 73 52 65  "'):.        sRe
2000: 67 65 78 20 3d 20 73 52 65 67 65 78 5b 31 3a 2d  gex = sRegex[1:-
2010: 31 5d 0a 0a 20 20 20 20 23 23 20 64 65 66 69 6e  1]..    ## defin
2020: 69 74 69 6f 6e 73 0a 20 20 20 20 66 6f 72 20 73  itions.    for s
2030: 44 65 66 2c 20 73 52 65 70 6c 20 69 6e 20 64 44  Def, sRepl in dD
2040: 45 46 49 4e 49 54 49 4f 4e 53 2e 69 74 65 6d 73  EFINITIONS.items
2050: 28 29 3a 0a 20 20 20 20 20 20 20 20 73 52 65 67  ():.        sReg
2060: 65 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c  ex = sRegex.repl
2070: 61 63 65 28 73 44 65 66 2c 20 73 52 65 70 6c 29  ace(sDef, sRepl)
2080: 0a 0a 20 20 20 20 23 23 20 63 6f 75 6e 74 20 6e  ..    ## count n
2090: 75 6d 62 65 72 20 6f 66 20 67 72 6f 75 70 73 20  umber of groups 
20a0: 28 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 62 65  (must be done be
20b0: 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20 74  fore modifying t
20c0: 68 65 20 72 65 67 65 78 29 0a 20 20 20 20 6e 47  he regex).    nG
20d0: 72 6f 75 70 20 3d 20 63 6f 75 6e 74 47 72 6f 75  roup = countGrou
20e0: 70 49 6e 52 65 67 65 78 28 73 52 65 67 65 78 29  pInRegex(sRegex)
20f0: 0a 20 20 20 20 69 66 20 6e 47 72 6f 75 70 20 3e  .    if nGroup >
2100: 20 30 3a 0a 20 20 20 20 20 20 20 20 69 66 20 6e   0:.        if n
2110: 6f 74 20 74 47 72 6f 75 70 73 3a 0a 20 20 20 20  ot tGroups:.    
2120: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
2130: 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f 75 70 73   Warning: groups
2140: 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f 64   positioning cod
2150: 65 20 66 6f 72 20 4a 61 76 61 53 63 72 69 70 74  e for JavaScript
2160: 20 73 68 6f 75 6c 64 20 62 65 20 64 65 66 69 6e   should be defin
2170: 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  ed at line " + s
2180: 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20  LineId).        
2190: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
21a0: 20 20 69 66 20 6e 47 72 6f 75 70 20 21 3d 20 6c    if nGroup != l
21b0: 65 6e 28 74 47 72 6f 75 70 73 29 3a 0a 20 20 20  en(tGroups):.   
21c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
21d0: 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 67 72 6f  nt("# Error: gro
21e0: 75 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20  ups positioning 
21f0: 63 6f 64 65 20 69 72 72 65 6c 65 76 61 6e 74 20  code irrelevant 
2200: 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e  at line " + sLin
2210: 65 49 64 29 0a 0a 20 20 20 20 23 23 20 77 6f 72  eId)..    ## wor
2220: 64 20 6c 69 6d 69 74 0a 20 20 20 20 69 66 20 63  d limit.    if c
2230: 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20 3d 3d  WordLimitLeft ==
2240: 20 27 5b 27 20 61 6e 64 20 6e 6f 74 20 73 52 65   '[' and not sRe
2250: 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28 28  gex.startswith((
2260: 22 5e 22 2c 20 27 e2 80 99 27 2c 20 22 27 22 2c  "^", '...', "'",
2270: 20 22 2c 22 29 29 3a 0a 20 20 20 20 20 20 20 20   ",")):.        
2280: 73 52 65 67 65 78 20 3d 20 73 57 4f 52 44 4c 49  sRegex = sWORDLI
2290: 4d 49 54 4c 45 46 54 20 2b 20 73 52 65 67 65 78  MITLEFT + sRegex
22a0: 0a 20 20 20 20 69 66 20 63 57 6f 72 64 4c 69 6d  .    if cWordLim
22b0: 69 74 52 69 67 68 74 20 3d 3d 20 27 5d 27 20 61  itRight == ']' a
22c0: 6e 64 20 6e 6f 74 20 73 52 65 67 65 78 2e 65 6e  nd not sRegex.en
22d0: 64 73 77 69 74 68 28 28 22 24 22 2c 20 27 e2 80  dswith(("$", '..
22e0: 99 27 2c 20 22 27 22 2c 20 22 2c 22 29 29 3a 0a  .', "'", ",")):.
22f0: 20 20 20 20 20 20 20 20 73 52 65 67 65 78 20 3d          sRegex =
2300: 20 73 52 65 67 65 78 20 2b 20 73 57 4f 52 44 4c   sRegex + sWORDL
2310: 49 4d 49 54 52 49 47 48 54 0a 0a 20 20 20 20 23  IMITRIGHT..    #
2320: 23 20 63 61 73 69 6e 67 20 6d 6f 64 65 0a 20 20  # casing mode.  
2330: 20 20 69 66 20 63 43 61 73 65 4d 6f 64 65 20 3d    if cCaseMode =
2340: 3d 20 22 69 22 3a 0a 20 20 20 20 20 20 20 20 62  = "i":.        b
2350: 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65 20  CaseInsensitive 
2360: 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20 69  = True.        i
2370: 66 20 6e 6f 74 20 73 52 65 67 65 78 2e 73 74 61  f not sRegex.sta
2380: 72 74 73 77 69 74 68 28 22 28 3f 69 29 22 29 3a  rtswith("(?i)"):
2390: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 52 65  .            sRe
23a0: 67 65 78 20 3d 20 22 28 3f 69 29 22 20 2b 20 73  gex = "(?i)" + s
23b0: 52 65 67 65 78 0a 20 20 20 20 65 6c 69 66 20 63  Regex.    elif c
23c0: 43 61 73 65 4d 6f 64 65 20 3d 3d 20 22 73 22 3a  CaseMode == "s":
23d0: 0a 20 20 20 20 20 20 20 20 62 43 61 73 65 49 6e  .        bCaseIn
23e0: 73 65 6e 73 69 74 69 76 65 20 3d 20 46 61 6c 73  sensitive = Fals
23f0: 65 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78  e.        sRegex
2400: 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61 63   = sRegex.replac
2410: 65 28 22 28 3f 69 29 22 2c 20 22 22 29 0a 20 20  e("(?i)", "").  
2420: 20 20 65 6c 69 66 20 63 43 61 73 65 4d 6f 64 65    elif cCaseMode
2430: 20 3d 3d 20 22 75 22 3a 0a 20 20 20 20 20 20 20   == "u":.       
2440: 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76   bCaseInsensitiv
2450: 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20  e = False.      
2460: 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67 65    sRegex = sRege
2470: 78 2e 72 65 70 6c 61 63 65 28 22 28 3f 69 29 22  x.replace("(?i)"
2480: 2c 20 22 22 29 0a 20 20 20 20 20 20 20 20 73 52  , "").        sR
2490: 65 67 65 78 20 3d 20 75 70 70 65 72 63 61 73 65  egex = uppercase
24a0: 28 73 52 65 67 65 78 2c 20 73 4c 61 6e 67 29 0a  (sRegex, sLang).
24b0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
24c0: 20 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f    print("# Unkno
24d0: 77 6e 20 63 61 73 65 20 6d 6f 64 65 20 5b 22 20  wn case mode [" 
24e0: 2b 20 63 43 61 73 65 4d 6f 64 65 20 2b 20 22 5d  + cCaseMode + "]
24f0: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69   at line " + sLi
2500: 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 20 63 68  neId)..    ## ch
2510: 65 63 6b 20 72 65 67 65 78 0a 20 20 20 20 74 72  eck regex.    tr
2520: 79 3a 0a 20 20 20 20 20 20 20 20 72 65 2e 63 6f  y:.        re.co
2530: 6d 70 69 6c 65 28 73 52 65 67 65 78 29 0a 20 20  mpile(sRegex).  
2540: 20 20 65 78 63 65 70 74 20 72 65 2e 65 72 72 6f    except re.erro
2550: 72 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  r:.        print
2560: 28 22 23 20 52 65 67 65 78 20 65 72 72 6f 72 20  ("# Regex error 
2570: 61 74 20 6c 69 6e 65 20 22 2c 20 6e 49 64 4c 69  at line ", nIdLi
2580: 6e 65 29 0a 20 20 20 20 20 20 20 20 70 72 69 6e  ne).        prin
2590: 74 28 73 52 65 67 65 78 29 0a 20 20 20 20 20 20  t(sRegex).      
25a0: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20    return None.  
25b0: 20 20 23 23 20 67 72 6f 75 70 73 20 69 6e 20 6e    ## groups in n
25c0: 6f 6e 20 67 72 6f 75 70 69 6e 67 20 70 61 72 65  on grouping pare
25d0: 6e 74 68 65 73 69 73 0a 20 20 20 20 66 6f 72 20  nthesis.    for 
25e0: 5f 20 69 6e 20 72 65 2e 66 69 6e 64 69 74 65 72  _ in re.finditer
25f0: 28 72 22 5c 28 5c 3f 3a 5b 5e 29 5d 2a 5c 28 5b  (r"\(\?:[^)]*\([
2600: 5c 5b 5c 77 20 2d 5d 22 2c 20 73 52 65 67 65 78  \[\w -]", sRegex
2610: 29 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74  ):.        print
2620: 28 22 23 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f  ("# Warning: gro
2630: 75 70 73 20 69 6e 73 69 64 65 20 6e 6f 6e 20 67  ups inside non g
2640: 72 6f 75 70 69 6e 67 20 70 61 72 65 6e 74 68 65  rouping parenthe
2650: 73 69 73 20 69 6e 20 72 65 67 65 78 20 61 74 20  sis in regex at 
2660: 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64  line " + sLineId
2670: 29 0a 0a 20 20 20 20 23 23 23 23 20 50 41 52 53  )..    #### PARS
2680: 45 20 41 43 54 49 4f 4e 53 0a 20 20 20 20 6c 41  E ACTIONS.    lA
2690: 63 74 69 6f 6e 73 20 3d 20 5b 5d 0a 20 20 20 20  ctions = [].    
26a0: 6e 41 63 74 69 6f 6e 20 3d 20 31 0a 20 20 20 20  nAction = 1.    
26b0: 66 6f 72 20 73 41 63 74 69 6f 6e 20 69 6e 20 73  for sAction in s
26c0: 2e 73 70 6c 69 74 28 22 20 3c 3c 2d 20 22 29 3a  .split(" <<- "):
26d0: 0a 20 20 20 20 20 20 20 20 74 20 3d 20 63 72 65  .        t = cre
26e0: 61 74 65 41 63 74 69 6f 6e 28 73 52 75 6c 65 49  ateAction(sRuleI
26f0: 64 20 2b 20 22 5f 22 20 2b 20 73 74 72 28 6e 41  d + "_" + str(nA
2700: 63 74 69 6f 6e 29 2c 20 73 41 63 74 69 6f 6e 2c  ction), sAction,
2710: 20 6e 47 72 6f 75 70 29 0a 20 20 20 20 20 20 20   nGroup).       
2720: 20 6e 41 63 74 69 6f 6e 20 2b 3d 20 31 0a 20 20   nAction += 1.  
2730: 20 20 20 20 20 20 69 66 20 74 3a 0a 20 20 20 20        if t:.    
2740: 20 20 20 20 20 20 20 20 6c 41 63 74 69 6f 6e 73          lActions
2750: 2e 61 70 70 65 6e 64 28 74 29 0a 20 20 20 20 69  .append(t).    i
2760: 66 20 6e 6f 74 20 6c 41 63 74 69 6f 6e 73 3a 0a  f not lActions:.
2770: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e          return N
2780: 6f 6e 65 0a 0a 20 20 20 20 72 65 74 75 72 6e 20  one..    return 
2790: 5b 73 4f 70 74 69 6f 6e 2c 20 73 52 65 67 65 78  [sOption, sRegex
27a0: 2c 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69  , bCaseInsensiti
27b0: 76 65 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52 75  ve, sLineId, sRu
27c0: 6c 65 49 64 2c 20 6e 50 72 69 6f 72 69 74 79 2c  leId, nPriority,
27d0: 20 6c 41 63 74 69 6f 6e 73 2c 20 74 47 72 6f 75   lActions, tGrou
27e0: 70 73 5d 0a 0a 0a 64 65 66 20 63 68 65 63 6b 52  ps]...def checkR
27f0: 65 66 65 72 65 6e 63 65 4e 75 6d 62 65 72 73 20  eferenceNumbers 
2800: 28 73 54 65 78 74 2c 20 73 41 63 74 69 6f 6e 49  (sText, sActionI
2810: 64 2c 20 6e 54 6f 6b 65 6e 29 3a 0a 20 20 20 20  d, nToken):.    
2820: 22 63 68 65 63 6b 20 69 66 20 74 6f 6b 65 6e 20  "check if token 
2830: 72 65 66 65 72 65 6e 63 65 73 20 69 6e 20 3c 73  references in <s
2840: 54 65 78 74 3e 20 67 72 65 61 74 65 72 20 74 68  Text> greater th
2850: 61 6e 20 3c 6e 54 6f 6b 65 6e 3e 20 28 64 65 62  an <nToken> (deb
2860: 75 67 67 69 6e 67 29 22 0a 20 20 20 20 66 6f 72  ugging)".    for
2870: 20 78 20 69 6e 20 72 65 2e 66 69 6e 64 69 74 65   x in re.findite
2880: 72 28 72 22 5c 5c 28 5c 64 2b 29 22 2c 20 73 54  r(r"\\(\d+)", sT
2890: 65 78 74 29 3a 0a 20 20 20 20 20 20 20 20 69 66  ext):.        if
28a0: 20 69 6e 74 28 78 2e 67 72 6f 75 70 28 31 29 29   int(x.group(1))
28b0: 20 3e 20 6e 54 6f 6b 65 6e 3a 0a 20 20 20 20 20   > nToken:.     
28c0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
28d0: 45 72 72 6f 72 20 69 6e 20 74 6f 6b 65 6e 20 69  Error in token i
28e0: 6e 64 65 78 20 61 74 20 6c 69 6e 65 20 22 20 2b  ndex at line " +
28f0: 20 73 41 63 74 69 6f 6e 49 64 20 2b 20 22 20 28   sActionId + " (
2900: 22 2b 73 74 72 28 6e 54 6f 6b 65 6e 29 2b 22 20  "+str(nToken)+" 
2910: 74 6f 6b 65 6e 73 20 6f 6e 6c 79 29 22 29 0a 20  tokens only)"). 
2920: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
2930: 28 73 54 65 78 74 29 0a 0a 0a 64 65 66 20 63 68  (sText)...def ch
2940: 65 63 6b 49 66 54 68 65 72 65 49 73 43 6f 64 65  eckIfThereIsCode
2950: 20 28 73 54 65 78 74 2c 20 73 41 63 74 69 6f 6e   (sText, sAction
2960: 49 64 29 3a 0a 20 20 20 20 22 63 68 65 63 6b 20  Id):.    "check 
2970: 69 66 20 74 68 65 72 65 20 69 73 20 63 6f 64 65  if there is code
2980: 20 69 6e 20 3c 73 54 65 78 74 3e 20 28 64 65 62   in <sText> (deb
2990: 75 67 67 69 6e 67 29 22 0a 20 20 20 20 69 66 20  ugging)".    if 
29a0: 72 65 2e 73 65 61 72 63 68 28 22 5b 2e 5d 5c 5c  re.search("[.]\\
29b0: 77 2b 5b 28 5d 7c 73 75 67 67 5c 5c 77 2b 5b 28  w+[(]|sugg\\w+[(
29c0: 5d 7c 5c 5c 28 5b 30 2d 39 5d 7c 5c 5c 5b 5b 30  ]|\\([0-9]|\\[[0
29d0: 2d 39 5d 22 2c 20 73 54 65 78 74 29 3a 0a 20 20  -9]", sText):.  
29e0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 57        print("# W
29f0: 61 72 6e 69 6e 67 20 61 74 20 6c 69 6e 65 20 22  arning at line "
2a00: 20 2b 20 73 41 63 74 69 6f 6e 49 64 20 2b 20 22   + sActionId + "
2a10: 3a 20 20 54 68 69 73 20 6d 65 73 73 61 67 65 20  :  This message 
2a20: 6c 6f 6f 6b 73 20 6c 69 6b 65 20 63 6f 64 65 2e  looks like code.
2a30: 20 4c 69 6e 65 20 73 68 6f 75 6c 64 20 70 72 6f   Line should pro
2a40: 62 61 62 6c 79 20 62 65 67 69 6e 20 77 69 74 68  bably begin with
2a50: 20 3d 22 29 0a 20 20 20 20 20 20 20 20 70 72 69   =").        pri
2a60: 6e 74 28 73 54 65 78 74 29 0a 0a 0a 64 65 66 20  nt(sText)...def 
2a70: 63 72 65 61 74 65 41 63 74 69 6f 6e 20 28 73 49  createAction (sI
2a80: 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e  dAction, sAction
2a90: 2c 20 6e 47 72 6f 75 70 29 3a 0a 20 20 20 20 22  , nGroup):.    "
2aa0: 72 65 74 75 72 6e 73 20 61 6e 20 61 63 74 69 6f  returns an actio
2ab0: 6e 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 73 20  n to perform as 
2ac0: 61 20 74 75 70 6c 65 20 28 63 6f 6e 64 69 74 69  a tuple (conditi
2ad0: 6f 6e 2c 20 61 63 74 69 6f 6e 20 74 79 70 65 2c  on, action type,
2ae0: 20 61 63 74 69 6f 6e 5b 2c 20 69 47 72 6f 75 70   action[, iGroup
2af0: 20 5b 2c 20 6d 65 73 73 61 67 65 2c 20 55 52 4c   [, message, URL
2b00: 20 5d 5d 29 22 0a 20 20 20 20 6d 20 3d 20 72 65   ]])".    m = re
2b10: 2e 73 65 61 72 63 68 28 72 22 28 5b 2d 7e 3d 3e  .search(r"([-~=>
2b20: 5d 29 28 5c 64 2a 7c 29 3e 3e 22 2c 20 73 41 63  ])(\d*|)>>", sAc
2b30: 74 69 6f 6e 29 0a 20 20 20 20 69 66 20 6e 6f 74  tion).    if not
2b40: 20 6d 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e   m:.        prin
2b50: 74 28 22 23 20 4e 6f 20 61 63 74 69 6f 6e 20 61  t("# No action a
2b60: 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41 63  t line " + sIdAc
2b70: 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 72 65  tion).        re
2b80: 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20 20 23  turn None..    #
2b90: 23 23 23 20 43 4f 4e 44 49 54 49 4f 4e 0a 20 20  ### CONDITION.  
2ba0: 20 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 73    sCondition = s
2bb0: 41 63 74 69 6f 6e 5b 3a 6d 2e 73 74 61 72 74 28  Action[:m.start(
2bc0: 29 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 69  )].strip().    i
2bd0: 66 20 73 43 6f 6e 64 69 74 69 6f 6e 3a 0a 20 20  f sCondition:.  
2be0: 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e        sCondition
2bf0: 20 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74 69   = prepareFuncti
2c00: 6f 6e 28 73 43 6f 6e 64 69 74 69 6f 6e 29 0a 20  on(sCondition). 
2c10: 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e         lFUNCTION
2c20: 53 2e 61 70 70 65 6e 64 28 28 22 5f 63 5f 22 2b  S.append(("_c_"+
2c30: 73 49 64 41 63 74 69 6f 6e 2c 20 73 43 6f 6e 64  sIdAction, sCond
2c40: 69 74 69 6f 6e 29 29 0a 20 20 20 20 20 20 20 20  ition)).        
2c50: 63 68 65 63 6b 52 65 66 65 72 65 6e 63 65 4e 75  checkReferenceNu
2c60: 6d 62 65 72 73 28 73 43 6f 6e 64 69 74 69 6f 6e  mbers(sCondition
2c70: 2c 20 73 49 64 41 63 74 69 6f 6e 2c 20 6e 47 72  , sIdAction, nGr
2c80: 6f 75 70 29 0a 20 20 20 20 20 20 20 20 69 66 20  oup).        if 
2c90: 22 2e 6d 61 74 63 68 22 20 69 6e 20 73 43 6f 6e  ".match" in sCon
2ca0: 64 69 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20  dition:.        
2cb0: 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72 72      print("# Err
2cc0: 6f 72 2e 20 4a 53 20 63 6f 6d 70 61 74 69 62 69  or. JS compatibi
2cd0: 6c 69 74 79 2e 20 44 6f 6e 27 74 20 75 73 65 20  lity. Don't use 
2ce0: 2e 6d 61 74 63 68 28 29 20 69 6e 20 63 6f 6e 64  .match() in cond
2cf0: 69 74 69 6f 6e 2c 20 75 73 65 20 2e 73 65 61 72  ition, use .sear
2d00: 63 68 28 29 22 29 0a 20 20 20 20 20 20 20 20 73  ch()").        s
2d10: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 5f 63 5f  Condition = "_c_
2d20: 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20 20 20  "+sIdAction.    
2d30: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 73 43  else:.        sC
2d40: 6f 6e 64 69 74 69 6f 6e 20 3d 20 4e 6f 6e 65 0a  ondition = None.
2d50: 0a 20 20 20 20 23 23 23 23 20 69 47 72 6f 75 70  .    #### iGroup
2d60: 20 2f 20 70 6f 73 69 74 69 6f 6e 69 6e 67 0a 20   / positioning. 
2d70: 20 20 20 69 47 72 6f 75 70 20 3d 20 69 6e 74 28     iGroup = int(
2d80: 6d 2e 67 72 6f 75 70 28 32 29 29 20 69 66 20 6d  m.group(2)) if m
2d90: 2e 67 72 6f 75 70 28 32 29 20 65 6c 73 65 20 30  .group(2) else 0
2da0: 0a 20 20 20 20 69 66 20 69 47 72 6f 75 70 20 3e  .    if iGroup >
2db0: 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20 20 20 20   nGroup:.       
2dc0: 20 70 72 69 6e 74 28 22 23 20 53 65 6c 65 63 74   print("# Select
2dd0: 65 64 20 67 72 6f 75 70 20 3e 20 67 72 6f 75 70  ed group > group
2de0: 20 6e 75 6d 62 65 72 20 69 6e 20 72 65 67 65 78   number in regex
2df0: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64   at line " + sId
2e00: 41 63 74 69 6f 6e 29 0a 0a 20 20 20 20 23 23 23  Action)..    ###
2e10: 23 20 41 43 54 49 4f 4e 0a 20 20 20 20 73 41 63  # ACTION.    sAc
2e20: 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 6d  tion = sAction[m
2e30: 2e 65 6e 64 28 29 3a 5d 2e 73 74 72 69 70 28 29  .end():].strip()
2e40: 0a 20 20 20 20 63 41 63 74 69 6f 6e 20 3d 20 6d  .    cAction = m
2e50: 2e 67 72 6f 75 70 28 31 29 0a 20 20 20 20 69 66  .group(1).    if
2e60: 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 2d 22 3a   cAction == "-":
2e70: 0a 20 20 20 20 20 20 20 20 23 23 20 65 72 72 6f  .        ## erro
2e80: 72 0a 20 20 20 20 20 20 20 20 69 4d 73 67 20 3d  r.        iMsg =
2e90: 20 73 41 63 74 69 6f 6e 2e 66 69 6e 64 28 22 20   sAction.find(" 
2ea0: 23 20 22 29 0a 20 20 20 20 20 20 20 20 69 66 20  # ").        if 
2eb0: 69 4d 73 67 20 3d 3d 20 2d 31 3a 0a 20 20 20 20  iMsg == -1:.    
2ec0: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 22          sMsg = "
2ed0: 23 20 45 72 72 6f 72 2e 20 45 72 72 6f 72 20 6d  # Error. Error m
2ee0: 65 73 73 61 67 65 20 6e 6f 74 20 66 6f 75 6e 64  essage not found
2ef0: 2e 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  .".            s
2f00: 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20 20 20  URL = "".       
2f10: 20 20 20 20 20 70 72 69 6e 74 28 73 4d 73 67 20       print(sMsg 
2f20: 2b 20 22 20 41 63 74 69 6f 6e 20 69 64 3a 20 22  + " Action id: "
2f30: 20 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a 20 20   + sIdAction).  
2f40: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
2f50: 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73          sMsg = s
2f60: 41 63 74 69 6f 6e 5b 69 4d 73 67 2b 33 3a 5d 2e  Action[iMsg+3:].
2f70: 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20  strip().        
2f80: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41      sAction = sA
2f90: 63 74 69 6f 6e 5b 3a 69 4d 73 67 5d 2e 73 74 72  ction[:iMsg].str
2fa0: 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20 20  ip().           
2fb0: 20 73 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20   sURL = "".     
2fc0: 20 20 20 20 20 20 20 6d 55 52 4c 20 3d 20 72 65         mURL = re
2fd0: 2e 73 65 61 72 63 68 28 22 5b 7c 5d 20 2a 28 68  .search("[|] *(h
2fe0: 74 74 70 73 3f 3a 2f 2f 2e 2a 29 22 2c 20 73 4d  ttps?://.*)", sM
2ff0: 73 67 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  sg).            
3000: 69 66 20 6d 55 52 4c 3a 0a 20 20 20 20 20 20 20  if mURL:.       
3010: 20 20 20 20 20 20 20 20 20 73 55 52 4c 20 3d 20           sURL = 
3020: 6d 55 52 4c 2e 67 72 6f 75 70 28 31 29 2e 73 74  mURL.group(1).st
3030: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20  rip().          
3040: 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73 4d 73        sMsg = sMs
3050: 67 5b 3a 6d 55 52 4c 2e 73 74 61 72 74 28 30 29  g[:mURL.start(0)
3060: 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20 20  ].strip().      
3070: 20 20 20 20 20 20 63 68 65 63 6b 52 65 66 65 72        checkRefer
3080: 65 6e 63 65 4e 75 6d 62 65 72 73 28 73 4d 73 67  enceNumbers(sMsg
3090: 2c 20 73 49 64 41 63 74 69 6f 6e 2c 20 6e 47 72  , sIdAction, nGr
30a0: 6f 75 70 29 0a 20 20 20 20 20 20 20 20 20 20 20  oup).           
30b0: 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20 3d 3d   if sMsg[0:1] ==
30c0: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20 20   "=":.          
30d0: 20 20 20 20 20 20 73 4d 73 67 20 3d 20 70 72 65        sMsg = pre
30e0: 70 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 4d 73  pareFunction(sMs
30f0: 67 5b 31 3a 5d 29 0a 20 20 20 20 20 20 20 20 20  g[1:]).         
3100: 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e         lFUNCTION
3110: 53 2e 61 70 70 65 6e 64 28 28 22 5f 6d 5f 22 2b  S.append(("_m_"+
3120: 73 49 64 41 63 74 69 6f 6e 2c 20 73 4d 73 67 29  sIdAction, sMsg)
3130: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
3140: 20 20 73 4d 73 67 20 3d 20 22 3d 5f 6d 5f 22 2b    sMsg = "=_m_"+
3150: 73 49 64 41 63 74 69 6f 6e 0a 20 20 20 20 20 20  sIdAction.      
3160: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
3170: 20 20 20 20 20 20 20 20 20 20 20 20 63 68 65 63              chec
3180: 6b 49 66 54 68 65 72 65 49 73 43 6f 64 65 28 73  kIfThereIsCode(s
3190: 4d 73 67 2c 20 73 49 64 41 63 74 69 6f 6e 29 0a  Msg, sIdAction).
31a0: 0a 20 20 20 20 63 68 65 63 6b 52 65 66 65 72 65  .    checkRefere
31b0: 6e 63 65 4e 75 6d 62 65 72 73 28 73 41 63 74 69  nceNumbers(sActi
31c0: 6f 6e 2c 20 73 49 64 41 63 74 69 6f 6e 2c 20 6e  on, sIdAction, n
31d0: 47 72 6f 75 70 29 0a 20 20 20 20 69 66 20 73 41  Group).    if sA
31e0: 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d  ction[0:1] == "=
31f0: 22 20 6f 72 20 63 41 63 74 69 6f 6e 20 3d 3d 20  " or cAction == 
3200: 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 73 41 63  "=":.        sAc
3210: 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46 75  tion = prepareFu
3220: 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 29 0a  nction(sAction).
3230: 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e 20          sAction 
3240: 3d 20 73 41 63 74 69 6f 6e 2e 72 65 70 6c 61 63  = sAction.replac
3250: 65 28 22 6d 2e 67 72 6f 75 70 28 69 5b 34 5d 29  e("m.group(i[4])
3260: 22 2c 20 22 6d 2e 67 72 6f 75 70 28 22 2b 73 74  ", "m.group("+st
3270: 72 28 69 47 72 6f 75 70 29 2b 22 29 22 29 0a 20  r(iGroup)+")"). 
3280: 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20     else:.       
3290: 20 63 68 65 63 6b 49 66 54 68 65 72 65 49 73 43   checkIfThereIsC
32a0: 6f 64 65 28 73 41 63 74 69 6f 6e 2c 20 73 49 64  ode(sAction, sId
32b0: 41 63 74 69 6f 6e 29 0a 0a 20 20 20 20 69 66 20  Action)..    if 
32c0: 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3e 22 3a 0a  cAction == ">":.
32d0: 20 20 20 20 20 20 20 20 23 23 20 6e 6f 20 61 63          ## no ac
32e0: 74 69 6f 6e 2c 20 62 72 65 61 6b 20 6c 6f 6f 70  tion, break loop
32f0: 20 69 66 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73   if condition is
3300: 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 72   False.        r
3310: 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f  eturn [sConditio
3320: 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 22 22 5d 0a  n, cAction, ""].
3330: 0a 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63 74  .    if not sAct
3340: 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 70 72 69  ion:.        pri
3350: 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20 61  nt("# Error in a
3360: 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20  ction at line " 
3370: 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a  + sIdAction + ":
3380: 20 20 54 68 69 73 20 61 63 74 69 6f 6e 20 69 73    This action is
3390: 20 65 6d 70 74 79 2e 22 29 0a 20 20 20 20 20 20   empty.").      
33a0: 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20    return None.. 
33b0: 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d 3d     if cAction ==
33c0: 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 23 23   "-":.        ##
33d0: 20 65 72 72 6f 72 20 64 65 74 65 63 74 65 64 20   error detected 
33e0: 2d 2d 3e 20 73 75 67 67 65 73 74 69 6f 6e 0a 20  --> suggestion. 
33f0: 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69 6f         if sActio
3400: 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a 20  n[0:1] == "=":. 
3410: 20 20 20 20 20 20 20 20 20 20 20 6c 46 55 4e 43             lFUNC
3420: 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22 5f  TIONS.append(("_
3430: 73 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73  s_"+sIdAction, s
3440: 41 63 74 69 6f 6e 5b 31 3a 5d 29 29 0a 20 20 20  Action[1:])).   
3450: 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e           sAction
3460: 20 3d 20 22 3d 5f 73 5f 22 2b 73 49 64 41 63 74   = "=_s_"+sIdAct
3470: 69 6f 6e 0a 20 20 20 20 20 20 20 20 65 6c 69 66  ion.        elif
3480: 20 73 41 63 74 69 6f 6e 2e 73 74 61 72 74 73 77   sAction.startsw
3490: 69 74 68 28 27 22 27 29 20 61 6e 64 20 73 41 63  ith('"') and sAc
34a0: 74 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28 27 22  tion.endswith('"
34b0: 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  '):.            
34c0: 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f  sAction = sActio
34d0: 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20 20  n[1:-1].        
34e0: 69 66 20 6e 6f 74 20 73 4d 73 67 3a 0a 20 20 20  if not sMsg:.   
34f0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
3500: 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69 6f  # Error in actio
3510: 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  n at line " + sI
3520: 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 74 68  dAction + ":  th
3530: 65 20 6d 65 73 73 61 67 65 20 69 73 20 65 6d 70  e message is emp
3540: 74 79 2e 22 29 0a 20 20 20 20 20 20 20 20 72 65  ty.").        re
3550: 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e  turn [sCondition
3560: 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74 69  , cAction, sActi
3570: 6f 6e 2c 20 69 47 72 6f 75 70 2c 20 73 4d 73 67  on, iGroup, sMsg
3580: 2c 20 73 55 52 4c 5d 0a 20 20 20 20 69 66 20 63  , sURL].    if c
3590: 41 63 74 69 6f 6e 20 3d 3d 20 22 7e 22 3a 0a 20  Action == "~":. 
35a0: 20 20 20 20 20 20 20 23 23 20 74 65 78 74 20 70         ## text p
35b0: 72 6f 63 65 73 73 6f 72 0a 20 20 20 20 20 20 20  rocessor.       
35c0: 20 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d   if sAction[0:1]
35d0: 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20   == "=":.       
35e0: 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e 53 2e       lFUNCTIONS.
35f0: 61 70 70 65 6e 64 28 28 22 5f 70 5f 22 2b 73 49  append(("_p_"+sI
3600: 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e  dAction, sAction
3610: 5b 31 3a 5d 29 29 0a 20 20 20 20 20 20 20 20 20  [1:])).         
3620: 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 22 3d 5f     sAction = "=_
3630: 70 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20  p_"+sIdAction.  
3640: 20 20 20 20 20 20 65 6c 69 66 20 73 41 63 74 69        elif sActi
3650: 6f 6e 2e 73 74 61 72 74 73 77 69 74 68 28 27 22  on.startswith('"
3660: 27 29 20 61 6e 64 20 73 41 63 74 69 6f 6e 2e 65  ') and sAction.e
3670: 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20 20  ndswith('"'):.  
3680: 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f            sActio
3690: 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 2d 31  n = sAction[1:-1
36a0: 5d 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ].        return
36b0: 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41   [sCondition, cA
36c0: 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 2c 20  ction, sAction, 
36d0: 69 47 72 6f 75 70 5d 0a 20 20 20 20 69 66 20 63  iGroup].    if c
36e0: 41 63 74 69 6f 6e 20 3d 3d 20 22 3d 22 3a 0a 20  Action == "=":. 
36f0: 20 20 20 20 20 20 20 23 23 20 64 69 73 61 6d 62         ## disamb
3700: 69 67 75 61 74 6f 72 0a 20 20 20 20 20 20 20 20  iguator.        
3710: 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d 20  if sAction[0:1] 
3720: 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20  == "=":.        
3730: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73 41      sAction = sA
3740: 63 74 69 6f 6e 5b 31 3a 5d 0a 20 20 20 20 20 20  ction[1:].      
3750: 20 20 69 66 20 22 64 65 66 69 6e 65 22 20 69 6e    if "define" in
3760: 20 73 41 63 74 69 6f 6e 20 61 6e 64 20 6e 6f 74   sAction and not
3770: 20 72 65 2e 73 65 61 72 63 68 28 72 22 64 65 66   re.search(r"def
3780: 69 6e 65 5c 28 64 54 6f 6b 65 6e 50 6f 73 2c 20  ine\(dTokenPos, 
3790: 2a 6d 5c 2e 73 74 61 72 74 2e 2a 2c 20 5c 5b 2e  *m\.start.*, \[.
37a0: 2a 5c 5d 20 2a 5c 29 22 2c 20 73 41 63 74 69 6f  *\] *\)", sActio
37b0: 6e 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  n):.            
37c0: 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69  print("# Error i
37d0: 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65  n action at line
37e0: 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b   " + sIdAction +
37f0: 20 22 3a 20 73 65 63 6f 6e 64 20 61 72 67 75 6d   ": second argum
3800: 65 6e 74 20 66 6f 72 20 64 65 66 69 6e 65 20 6d  ent for define m
3810: 75 73 74 20 62 65 20 61 20 6c 69 73 74 20 6f 66  ust be a list of
3820: 20 73 74 72 69 6e 67 73 22 29 0a 20 20 20 20 20   strings").     
3830: 20 20 20 20 20 20 20 70 72 69 6e 74 28 73 41 63         print(sAc
3840: 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 6c 46  tion).        lF
3850: 55 4e 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28  UNCTIONS.append(
3860: 28 22 5f 64 5f 22 2b 73 49 64 41 63 74 69 6f 6e  ("_d_"+sIdAction
3870: 2c 20 73 41 63 74 69 6f 6e 29 29 0a 20 20 20 20  , sAction)).    
3880: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 22 5f      sAction = "_
3890: 64 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20  d_"+sIdAction.  
38a0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 73 43        return [sC
38b0: 6f 6e 64 69 74 69 6f 6e 2c 20 63 41 63 74 69 6f  ondition, cActio
38c0: 6e 2c 20 73 41 63 74 69 6f 6e 5d 0a 20 20 20 20  n, sAction].    
38d0: 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f 77 6e  print("# Unknown
38e0: 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20   action at line 
38f0: 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a 20  " + sIdAction). 
3900: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a     return None..
3910: 0a 64 65 66 20 5f 63 61 6c 63 52 75 6c 65 73 53  .def _calcRulesS
3920: 74 61 74 73 20 28 6c 52 75 6c 65 73 29 3a 0a 20  tats (lRules):. 
3930: 20 20 20 22 63 6f 75 6e 74 20 72 75 6c 65 73 20     "count rules 
3940: 61 6e 64 20 61 63 74 69 6f 6e 73 22 0a 20 20 20  and actions".   
3950: 20 64 20 3d 20 7b 27 3d 27 3a 30 2c 20 27 7e 27   d = {'=':0, '~'
3960: 3a 20 30 2c 20 27 2d 27 3a 20 30 2c 20 27 3e 27  : 0, '-': 0, '>'
3970: 3a 20 30 7d 0a 20 20 20 20 66 6f 72 20 61 52 75  : 0}.    for aRu
3980: 6c 65 20 69 6e 20 6c 52 75 6c 65 73 3a 0a 20 20  le in lRules:.  
3990: 20 20 20 20 20 20 69 66 20 61 52 75 6c 65 5b 30        if aRule[0
39a0: 5d 20 21 3d 20 22 40 40 40 40 22 3a 0a 20 20 20  ] != "@@@@":.   
39b0: 20 20 20 20 20 20 20 20 20 66 6f 72 20 61 41 63           for aAc
39c0: 74 69 6f 6e 20 69 6e 20 61 52 75 6c 65 5b 36 5d  tion in aRule[6]
39d0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
39e0: 20 20 64 5b 61 41 63 74 69 6f 6e 5b 31 5d 5d 20    d[aAction[1]] 
39f0: 3d 20 64 5b 61 41 63 74 69 6f 6e 5b 31 5d 5d 20  = d[aAction[1]] 
3a00: 2b 20 31 0a 20 20 20 20 72 65 74 75 72 6e 20 28  + 1.    return (
3a10: 64 2c 20 6c 65 6e 28 6c 52 75 6c 65 73 29 29 0a  d, len(lRules)).
3a20: 0a 0a 64 65 66 20 64 69 73 70 6c 61 79 53 74 61  ..def displaySta
3a30: 74 73 20 28 6c 50 61 72 61 67 72 61 70 68 52 75  ts (lParagraphRu
3a40: 6c 65 73 2c 20 6c 53 65 6e 74 65 6e 63 65 52 75  les, lSentenceRu
3a50: 6c 65 73 29 3a 0a 20 20 20 20 22 64 69 73 70 6c  les):.    "displ
3a60: 61 79 20 72 75 6c 65 73 20 6e 75 6d 62 65 72 73  ay rules numbers
3a70: 22 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 7b  ".    print("  {
3a80: 3a 3e 31 38 7d 20 7b 3a 3e 31 38 7d 20 7b 3a 3e  :>18} {:>18} {:>
3a90: 31 38 7d 20 7b 3a 3e 31 38 7d 22 2e 66 6f 72 6d  18} {:>18}".form
3aa0: 61 74 28 22 44 49 53 41 4d 42 49 47 55 41 54 4f  at("DISAMBIGUATO
3ab0: 52 22 2c 20 22 54 45 58 54 20 50 52 4f 43 45 53  R", "TEXT PROCES
3ac0: 53 4f 52 22 2c 20 22 47 52 41 4d 4d 41 52 20 43  SOR", "GRAMMAR C
3ad0: 48 45 43 4b 49 4e 47 22 2c 20 22 52 45 47 45 58  HECKING", "REGEX
3ae0: 22 29 29 0a 20 20 20 20 64 2c 20 6e 52 75 6c 65  ")).    d, nRule
3af0: 20 3d 20 5f 63 61 6c 63 52 75 6c 65 73 53 74 61   = _calcRulesSta
3b00: 74 73 28 6c 50 61 72 61 67 72 61 70 68 52 75 6c  ts(lParagraphRul
3b10: 65 73 29 0a 20 20 20 20 70 72 69 6e 74 28 22 c2  es).    print(".
3b20: a7 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73  . {:>10} actions
3b30: 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73 20   {:>10} actions 
3b40: 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73 20 20  {:>10} actions  
3b50: 69 6e 20 7b 3a 3e 38 7d 20 72 75 6c 65 73 22 2e  in {:>8} rules".
3b60: 66 6f 72 6d 61 74 28 64 5b 27 3d 27 5d 2c 20 64  format(d['='], d
3b70: 5b 27 7e 27 5d 2c 20 64 5b 27 2d 27 5d 2c 20 6e  ['~'], d['-'], n
3b80: 52 75 6c 65 29 29 0a 20 20 20 20 64 2c 20 6e 52  Rule)).    d, nR
3b90: 75 6c 65 20 3d 20 5f 63 61 6c 63 52 75 6c 65 73  ule = _calcRules
3ba0: 53 74 61 74 73 28 6c 53 65 6e 74 65 6e 63 65 52  Stats(lSentenceR
3bb0: 75 6c 65 73 29 0a 20 20 20 20 70 72 69 6e 74 28  ules).    print(
3bc0: 22 73 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e  "s {:>10} action
3bd0: 73 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73  s {:>10} actions
3be0: 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73 20   {:>10} actions 
3bf0: 20 69 6e 20 7b 3a 3e 38 7d 20 72 75 6c 65 73 22   in {:>8} rules"
3c00: 2e 66 6f 72 6d 61 74 28 64 5b 27 3d 27 5d 2c 20  .format(d['='], 
3c10: 64 5b 27 7e 27 5d 2c 20 64 5b 27 2d 27 5d 2c 20  d['~'], d['-'], 
3c20: 6e 52 75 6c 65 29 29 0a 0a 0a 64 65 66 20 6d 65  nRule))...def me
3c30: 72 67 65 52 75 6c 65 73 42 79 4f 70 74 69 6f 6e  rgeRulesByOption
3c40: 20 28 6c 52 75 6c 65 73 29 3a 0a 20 20 20 20 22   (lRules):.    "
3c50: 72 65 74 75 72 6e 73 20 61 20 6c 69 73 74 20 6f  returns a list o
3c60: 66 20 74 75 70 6c 65 73 20 5b 6f 70 74 69 6f 6e  f tuples [option
3c70: 2c 20 6c 69 73 74 20 6f 66 20 72 75 6c 65 73 5d  , list of rules]
3c80: 20 6b 65 65 70 69 6e 67 20 74 68 65 20 72 75 6c   keeping the rul
3c90: 65 73 20 6f 72 64 65 72 22 0a 20 20 20 20 6c 46  es order".    lF
3ca0: 69 6e 61 6c 20 3d 20 5b 5d 0a 20 20 20 20 6c 54  inal = [].    lT
3cb0: 65 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 73 4f 70  emp = [].    sOp
3cc0: 74 69 6f 6e 20 3d 20 4e 6f 6e 65 0a 20 20 20 20  tion = None.    
3cd0: 66 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c 52 75  for aRule in lRu
3ce0: 6c 65 73 3a 0a 20 20 20 20 20 20 20 20 69 66 20  les:.        if 
3cf0: 61 52 75 6c 65 5b 30 5d 20 21 3d 20 73 4f 70 74  aRule[0] != sOpt
3d00: 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ion:.           
3d10: 20 69 66 20 73 4f 70 74 69 6f 6e 20 69 73 20 6e   if sOption is n
3d20: 6f 74 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 20  ot None:.       
3d30: 20 20 20 20 20 20 20 20 20 6c 46 69 6e 61 6c 2e           lFinal.
3d40: 61 70 70 65 6e 64 28 5b 73 4f 70 74 69 6f 6e 2c  append([sOption,
3d50: 20 6c 54 65 6d 70 5d 29 0a 20 20 20 20 20 20 20   lTemp]).       
3d60: 20 20 20 20 20 23 20 6e 65 77 20 74 75 70 6c 65       # new tuple
3d70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4f 70  .            sOp
3d80: 74 69 6f 6e 20 3d 20 61 52 75 6c 65 5b 30 5d 0a  tion = aRule[0].
3d90: 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 65 6d              lTem
3da0: 70 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20 6c  p = [].        l
3db0: 54 65 6d 70 2e 61 70 70 65 6e 64 28 61 52 75 6c  Temp.append(aRul
3dc0: 65 5b 31 3a 5d 29 0a 20 20 20 20 6c 46 69 6e 61  e[1:]).    lFina
3dd0: 6c 2e 61 70 70 65 6e 64 28 5b 73 4f 70 74 69 6f  l.append([sOptio
3de0: 6e 2c 20 6c 54 65 6d 70 5d 29 0a 20 20 20 20 72  n, lTemp]).    r
3df0: 65 74 75 72 6e 20 6c 46 69 6e 61 6c 0a 0a 0a 64  eturn lFinal...d
3e00: 65 66 20 70 72 65 70 61 72 65 4f 70 74 69 6f 6e  ef prepareOption
3e10: 73 20 28 6c 4f 70 74 69 6f 6e 4c 69 6e 65 73 29  s (lOptionLines)
3e20: 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20 61  :.    "returns a
3e30: 20 64 69 63 74 69 6f 6e 61 72 79 20 77 69 74 68   dictionary with
3e40: 20 64 61 74 61 20 61 62 6f 75 74 20 6f 70 74 69   data about opti
3e50: 6f 6e 73 22 0a 20 20 20 20 73 4c 61 6e 67 20 3d  ons".    sLang =
3e60: 20 22 22 0a 20 20 20 20 73 44 65 66 61 75 6c 74   "".    sDefault
3e70: 55 49 4c 61 6e 67 20 3d 20 22 22 0a 20 20 20 20  UILang = "".    
3e80: 6c 53 74 72 75 63 74 4f 70 74 20 3d 20 5b 5d 0a  lStructOpt = [].
3e90: 20 20 20 20 6c 4f 70 74 20 3d 20 5b 5d 0a 20 20      lOpt = [].  
3ea0: 20 20 6c 4f 70 74 43 6f 6c 6f 72 20 3d 20 5b 5d    lOptColor = []
3eb0: 0a 20 20 20 20 64 43 6f 6c 6f 72 20 3d 20 7b 7d  .    dColor = {}
3ec0: 0a 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 20 3d  .    dOptLabel =
3ed0: 20 7b 7d 0a 20 20 20 20 64 4f 70 74 50 72 69 6f   {}.    dOptPrio
3ee0: 72 69 74 79 20 3d 20 7b 7d 0a 20 20 20 20 66 6f  rity = {}.    fo
3ef0: 72 20 73 4c 69 6e 65 20 69 6e 20 6c 4f 70 74 69  r sLine in lOpti
3f00: 6f 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20 20  onLines:.       
3f10: 20 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65 2e 73   sLine = sLine.s
3f20: 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 69  trip().        i
3f30: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
3f40: 74 68 28 22 4f 50 54 47 52 4f 55 50 2f 22 29 3a  th("OPTGROUP/"):
3f50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d  .            m =
3f60: 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 47 52   re.match("OPTGR
3f70: 4f 55 50 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29 3a  OUP/([a-z0-9]+):
3f80: 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20  (.+)$", sLine). 
3f90: 20 20 20 20 20 20 20 20 20 20 20 6c 53 74 72 75             lStru
3fa0: 63 74 4f 70 74 2e 61 70 70 65 6e 64 28 20 5b 6d  ctOpt.append( [m
3fb0: 2e 67 72 6f 75 70 28 31 29 2c 20 6c 69 73 74 28  .group(1), list(
3fc0: 6d 61 70 28 73 74 72 2e 73 70 6c 69 74 2c 20 6d  map(str.split, m
3fd0: 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74 28  .group(2).split(
3fe0: 22 2c 22 29 29 29 5d 20 29 0a 20 20 20 20 20 20  ",")))] ).      
3ff0: 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61    elif sLine.sta
4000: 72 74 73 77 69 74 68 28 22 4f 50 54 53 4f 46 54  rtswith("OPTSOFT
4010: 57 41 52 45 3a 22 29 3a 0a 20 20 20 20 20 20 20  WARE:"):.       
4020: 20 20 20 20 20 6c 4f 70 74 20 3d 20 5b 20 5b 73       lOpt = [ [s
4030: 2c 20 7b 7d 5d 20 20 66 6f 72 20 73 20 69 6e 20  , {}]  for s in 
4040: 73 4c 69 6e 65 5b 31 32 3a 5d 2e 73 74 72 69 70  sLine[12:].strip
4050: 28 29 2e 73 70 6c 69 74 28 29 20 5d 20 20 23 20  ().split() ]  # 
4060: 64 6f 6e e2 80 99 74 20 75 73 65 20 74 75 70 6c  don...t use tupl
4070: 65 73 20 28 73 2c 20 7b 7d 29 2c 20 62 65 63 61  es (s, {}), beca
4080: 75 73 65 20 75 6e 6b 6e 6f 77 6e 20 74 6f 20 4a  use unknown to J
4090: 53 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  S.        elif s
40a0: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
40b0: 22 4f 50 54 2f 22 29 3a 0a 20 20 20 20 20 20 20  "OPT/"):.       
40c0: 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63       m = re.matc
40d0: 68 28 22 4f 50 54 2f 28 5b 61 2d 7a 30 2d 39 5d  h("OPT/([a-z0-9]
40e0: 2b 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65  +):(.+)$", sLine
40f0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  ).            fo
4100: 72 20 69 2c 20 73 4f 70 74 20 69 6e 20 65 6e 75  r i, sOpt in enu
4110: 6d 65 72 61 74 65 28 6d 2e 67 72 6f 75 70 28 32  merate(m.group(2
4120: 29 2e 73 70 6c 69 74 28 29 29 3a 0a 20 20 20 20  ).split()):.    
4130: 20 20 20 20 20 20 20 20 20 20 20 20 6c 4f 70 74              lOpt
4140: 5b 69 5d 5b 31 5d 5b 6d 2e 67 72 6f 75 70 28 31  [i][1][m.group(1
4150: 29 5d 20 3d 20 73 4f 70 74 20 69 6e 20 28 22 54  )] = sOpt in ("T
4160: 72 75 65 22 2c 20 22 74 72 75 65 22 2c 20 22 59  rue", "true", "Y
4170: 65 73 22 2c 20 22 79 65 73 22 29 0a 20 20 20 20  es", "yes").    
4180: 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73      elif sLine.s
4190: 74 61 72 74 73 77 69 74 68 28 22 4f 50 54 43 4f  tartswith("OPTCO
41a0: 4c 4f 52 54 48 45 4d 45 3a 22 29 3a 0a 20 20 20  LORTHEME:"):.   
41b0: 20 20 20 20 20 20 20 20 20 6c 4f 70 74 43 6f 6c           lOptCol
41c0: 6f 72 20 3d 20 5b 20 5b 73 2c 20 7b 7d 5d 20 20  or = [ [s, {}]  
41d0: 66 6f 72 20 73 20 69 6e 20 73 4c 69 6e 65 5b 31  for s in sLine[1
41e0: 34 3a 5d 2e 73 74 72 69 70 28 29 2e 73 70 6c 69  4:].strip().spli
41f0: 74 28 29 20 5d 20 20 23 20 64 6f 6e e2 80 99 74  t() ]  # don...t
4200: 20 75 73 65 20 74 75 70 6c 65 73 20 28 73 2c 20   use tuples (s, 
4210: 7b 7d 29 2c 20 62 65 63 61 75 73 65 20 75 6e 6b  {}), because unk
4220: 6e 6f 77 6e 20 74 6f 20 4a 53 0a 20 20 20 20 20  nown to JS.     
4230: 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74     elif sLine.st
4240: 61 72 74 73 77 69 74 68 28 22 4f 50 54 43 4f 4c  artswith("OPTCOL
4250: 4f 52 2f 22 29 3a 0a 20 20 20 20 20 20 20 20 20  OR/"):.         
4260: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
4270: 22 4f 50 54 43 4f 4c 4f 52 2f 28 5b 61 2d 7a 30  "OPTCOLOR/([a-z0
4280: 2d 39 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73 4c  -9]+):(.+)$", sL
4290: 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20 20  ine).           
42a0: 20 66 6f 72 20 69 2c 20 73 43 6f 6c 6f 72 20 69   for i, sColor i
42b0: 6e 20 65 6e 75 6d 65 72 61 74 65 28 6d 2e 67 72  n enumerate(m.gr
42c0: 6f 75 70 28 32 29 2e 73 70 6c 69 74 28 29 29 3a  oup(2).split()):
42d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
42e0: 20 6c 4f 70 74 43 6f 6c 6f 72 5b 69 5d 5b 31 5d   lOptColor[i][1]
42f0: 5b 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20 73  [m.group(1)] = s
4300: 43 6f 6c 6f 72 0a 20 20 20 20 20 20 20 20 65 6c  Color.        el
4310: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
4320: 69 74 68 28 22 43 4f 4c 4f 52 2f 22 29 3a 0a 20  ith("COLOR/"):. 
4330: 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72             m = r
4340: 65 2e 6d 61 74 63 68 28 22 43 4f 4c 4f 52 2f 28  e.match("COLOR/(
4350: 5b 61 2d 7a 41 2d 5a 30 2d 39 5f 5d 2b 29 3a 28  [a-zA-Z0-9_]+):(
4360: 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20  .+)$", sLine).  
4370: 20 20 20 20 20 20 20 20 20 20 64 43 6f 6c 6f 72            dColor
4380: 5b 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20 5b  [m.group(1)] = [
4390: 20 69 6e 74 28 73 29 20 66 6f 72 20 73 20 69 6e   int(s) for s in
43a0: 20 6d 2e 67 72 6f 75 70 28 32 29 2e 73 74 72 69   m.group(2).stri
43b0: 70 28 29 2e 73 70 6c 69 74 28 22 2c 22 29 20 5d  p().split(",") ]
43c0: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
43d0: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
43e0: 4f 50 54 50 52 49 4f 52 49 54 59 2f 22 29 3a 0a  OPTPRIORITY/"):.
43f0: 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20              m = 
4400: 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 50 52 49  re.match("OPTPRI
4410: 4f 52 49 54 59 2f 28 5b 61 2d 7a 30 2d 39 5d 2b  ORITY/([a-z0-9]+
4420: 29 3a 20 2a 28 5b 30 2d 39 5d 29 24 22 2c 20 73  ): *([0-9])$", s
4430: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20  Line).          
4440: 20 20 64 4f 70 74 50 72 69 6f 72 69 74 79 5b 6d    dOptPriority[m
4450: 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20 69 6e 74  .group(1)] = int
4460: 28 6d 2e 67 72 6f 75 70 28 32 29 29 0a 20 20 20  (m.group(2)).   
4470: 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e       elif sLine.
4480: 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54 4c  startswith("OPTL
4490: 41 4e 47 2f 22 29 3a 0a 20 20 20 20 20 20 20 20  ANG/"):.        
44a0: 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68      m = re.match
44b0: 28 22 4f 50 54 4c 41 4e 47 2f 28 5b 61 2d 7a 5d  ("OPTLANG/([a-z]
44c0: 5b 61 2d 7a 5d 28 3f 3a 5f 5b 41 2d 5a 5d 5b 41  [a-z](?:_[A-Z][A
44d0: 2d 5a 5d 7c 29 29 3a 28 2e 2b 29 24 22 2c 20 73  -Z]|)):(.+)$", s
44e0: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20  Line).          
44f0: 20 20 73 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f 75    sLang = m.grou
4500: 70 28 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20 20  p(1)[:2].       
4510: 20 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 5b 73       dOptLabel[s
4520: 4c 61 6e 67 5d 20 3d 20 7b 20 22 5f 5f 6f 70 74  Lang] = { "__opt
4530: 69 6f 6e 74 69 74 6c 65 5f 5f 22 3a 20 6d 2e 67  iontitle__": m.g
4540: 72 6f 75 70 28 32 29 2e 73 74 72 69 70 28 29 20  roup(2).strip() 
4550: 7d 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  }.        elif s
4560: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
4570: 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41 4e  "OPTDEFAULTUILAN
4580: 47 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20  G:"):.          
4590: 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22    m = re.match("
45a0: 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41 4e 47  OPTDEFAULTUILANG
45b0: 3a 20 2a 28 5b 61 2d 7a 5d 5b 61 2d 7a 5d 28 3f  : *([a-z][a-z](?
45c0: 3a 5f 5b 41 2d 5a 5d 5b 41 2d 5a 5d 7c 29 29 24  :_[A-Z][A-Z]|))$
45d0: 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20 20  ", sLine).      
45e0: 20 20 20 20 20 20 73 44 65 66 61 75 6c 74 55 49        sDefaultUI
45f0: 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f 75 70 28 31  Lang = m.group(1
4600: 29 5b 3a 32 5d 0a 20 20 20 20 20 20 20 20 65 6c  )[:2].        el
4610: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
4620: 69 74 68 28 22 4f 50 54 4c 41 42 45 4c 2f 22 29  ith("OPTLABEL/")
4630: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20  :.            m 
4640: 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 4c  = re.match("OPTL
4650: 41 42 45 4c 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29  ABEL/([a-z0-9]+)
4660: 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a  :(.+)$", sLine).
4670: 20 20 20 20 20 20 20 20 20 20 20 20 64 4f 70 74              dOpt
4680: 4c 61 62 65 6c 5b 73 4c 61 6e 67 5d 5b 6d 2e 67  Label[sLang][m.g
4690: 72 6f 75 70 28 31 29 5d 20 3d 20 6c 69 73 74 28  roup(1)] = list(
46a0: 6d 61 70 28 73 74 72 2e 73 74 72 69 70 2c 20 6d  map(str.strip, m
46b0: 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74 28  .group(2).split(
46c0: 22 7c 22 29 29 29 20 20 69 66 20 22 7c 22 20 69  "|")))  if "|" i
46d0: 6e 20 6d 2e 67 72 6f 75 70 28 32 29 20 20 65 6c  n m.group(2)  el
46e0: 73 65 20 20 5b 6d 2e 67 72 6f 75 70 28 32 29 2e  se  [m.group(2).
46f0: 73 74 72 69 70 28 29 2c 20 22 22 5d 0a 20 20 20  strip(), ""].   
4700: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
4710: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
4720: 45 72 72 6f 72 2e 20 57 72 6f 6e 67 20 6f 70 74  Error. Wrong opt
4730: 69 6f 6e 20 6c 69 6e 65 20 69 6e 3a 5c 6e 20 20  ion line in:\n  
4740: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  ").            p
4750: 72 69 6e 74 28 73 4c 69 6e 65 29 0a 20 20 20 20  rint(sLine).    
4760: 70 72 69 6e 74 28 22 20 20 6f 70 74 69 6f 6e 73  print("  options
4770: 20 64 65 66 69 6e 65 64 20 66 6f 72 3a 20 22 20   defined for: " 
4780: 2b 20 22 2c 20 22 2e 6a 6f 69 6e 28 5b 20 74 5b  + ", ".join([ t[
4790: 30 5d 20 66 6f 72 20 74 20 69 6e 20 6c 4f 70 74  0] for t in lOpt
47a0: 20 5d 29 29 0a 20 20 20 20 64 4f 70 74 69 6f 6e   ])).    dOption
47b0: 73 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 22 6c  s = {.        "l
47c0: 53 74 72 75 63 74 4f 70 74 22 3a 20 6c 53 74 72  StructOpt": lStr
47d0: 75 63 74 4f 70 74 2c 20 22 64 4f 70 74 4c 61 62  uctOpt, "dOptLab
47e0: 65 6c 22 3a 20 64 4f 70 74 4c 61 62 65 6c 2c 20  el": dOptLabel, 
47f0: 22 73 44 65 66 61 75 6c 74 55 49 4c 61 6e 67 22  "sDefaultUILang"
4800: 3a 20 73 44 65 66 61 75 6c 74 55 49 4c 61 6e 67  : sDefaultUILang
4810: 2c 20 5c 0a 20 20 20 20 20 20 20 20 22 64 43 6f  , \.        "dCo
4820: 6c 6f 72 54 79 70 65 22 3a 20 63 72 65 61 74 65  lorType": create
4830: 43 6f 6c 6f 72 73 28 64 43 6f 6c 6f 72 29 2c 20  Colors(dColor), 
4840: 22 64 4f 70 74 43 6f 6c 6f 72 22 3a 20 7b 20 73  "dOptColor": { s
4850: 3a 20 64 20 20 66 6f 72 20 73 2c 20 64 20 69 6e  : d  for s, d in
4860: 20 6c 4f 70 74 43 6f 6c 6f 72 20 7d 0a 20 20 20   lOptColor }.   
4870: 20 7d 0a 20 20 20 20 64 4f 70 74 69 6f 6e 73 2e   }.    dOptions.
4880: 75 70 64 61 74 65 28 7b 20 22 64 4f 70 74 22 2b  update({ "dOpt"+
4890: 6b 3a 20 76 20 20 66 6f 72 20 6b 2c 20 76 20 69  k: v  for k, v i
48a0: 6e 20 6c 4f 70 74 20 7d 29 0a 20 20 20 20 72 65  n lOpt }).    re
48b0: 74 75 72 6e 20 64 4f 70 74 69 6f 6e 73 2c 20 64  turn dOptions, d
48c0: 4f 70 74 50 72 69 6f 72 69 74 79 0a 0a 0a 64 65  OptPriority...de
48d0: 66 20 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 20  f printBookmark 
48e0: 28 6e 4c 65 76 65 6c 2c 20 73 43 6f 6d 6d 65 6e  (nLevel, sCommen
48f0: 74 2c 20 6e 4c 69 6e 65 29 3a 0a 20 20 20 20 22  t, nLine):.    "
4900: 70 72 69 6e 74 20 62 6f 6f 6b 6d 61 72 6b 20 77  print bookmark w
4910: 69 74 68 69 6e 20 74 68 65 20 72 75 6c 65 73 20  ithin the rules 
4920: 66 69 6c 65 22 0a 20 20 20 20 70 72 69 6e 74 28  file".    print(
4930: 22 20 20 7b 3a 3e 36 7d 3a 20 20 7b 7d 22 2e 66  "  {:>6}:  {}".f
4940: 6f 72 6d 61 74 28 6e 4c 69 6e 65 2c 20 22 20 20  ormat(nLine, "  
4950: 22 20 2a 20 6e 4c 65 76 65 6c 20 2b 20 73 43 6f  " * nLevel + sCo
4960: 6d 6d 65 6e 74 29 29 0a 0a 0a 64 65 66 20 6d 61  mment))...def ma
4970: 6b 65 20 28 73 70 4c 61 6e 67 2c 20 73 4c 61 6e  ke (spLang, sLan
4980: 67 2c 20 62 55 73 65 43 61 63 68 65 3d 46 61 6c  g, bUseCache=Fal
4990: 73 65 29 3a 0a 20 20 20 20 22 63 6f 6d 70 69 6c  se):.    "compil
49a0: 65 20 72 75 6c 65 73 2c 20 72 65 74 75 72 6e 73  e rules, returns
49b0: 20 61 20 64 69 63 74 69 6f 6e 61 72 79 20 6f 66   a dictionary of
49c0: 20 76 61 6c 75 65 73 22 0a 20 20 20 20 23 20 66   values".    # f
49d0: 6f 72 20 63 6c 61 72 69 74 79 20 70 75 72 70 6f  or clarity purpo
49e0: 73 65 2c 20 64 6f 6e e2 80 99 74 20 63 72 65 61  se, don...t crea
49f0: 74 65 20 61 6e 79 20 66 69 6c 65 20 68 65 72 65  te any file here
4a00: 0a 0a 20 20 20 20 69 66 20 62 55 73 65 43 61 63  ..    if bUseCac
4a10: 68 65 20 61 6e 64 20 6f 73 2e 70 61 74 68 2e 69  he and os.path.i
4a20: 73 66 69 6c 65 28 22 5f 62 75 69 6c 64 2f 64 61  sfile("_build/da
4a30: 74 61 5f 63 61 63 68 65 2e 6a 73 6f 6e 22 29 3a  ta_cache.json"):
4a40: 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22  .        print("
4a50: 3e 20 64 6f 6e e2 80 99 74 20 72 65 62 75 69 6c  > don...t rebuil
4a60: 64 20 72 75 6c 65 73 2c 20 75 73 65 20 63 61 63  d rules, use cac
4a70: 68 65 2e 2e 2e 22 29 0a 20 20 20 20 20 20 20 20  he...").        
4a80: 73 4a 53 4f 4e 20 3d 20 6f 70 65 6e 28 22 5f 62  sJSON = open("_b
4a90: 75 69 6c 64 2f 64 61 74 61 5f 63 61 63 68 65 2e  uild/data_cache.
4aa0: 6a 73 6f 6e 22 2c 20 22 72 22 2c 20 65 6e 63 6f  json", "r", enco
4ab0: 64 69 6e 67 3d 22 75 74 66 2d 38 22 29 2e 72 65  ding="utf-8").re
4ac0: 61 64 28 29 0a 20 20 20 20 20 20 20 20 64 43 61  ad().        dCa
4ad0: 63 68 65 56 61 72 73 20 3d 20 6a 73 6f 6e 2e 6c  cheVars = json.l
4ae0: 6f 61 64 73 28 73 4a 53 4f 4e 29 0a 20 20 20 20  oads(sJSON).    
4af0: 20 20 20 20 70 72 69 6e 74 28 22 20 20 62 75 69      print("  bui
4b00: 6c 64 20 6d 61 64 65 20 61 74 3a 20 22 20 2b 20  ld made at: " + 
4b10: 74 69 6d 65 2e 73 74 72 66 74 69 6d 65 28 22 25  time.strftime("%
4b20: 59 2d 25 6d 2d 25 64 20 25 48 3a 25 4d 3a 25 53  Y-%m-%d %H:%M:%S
4b30: 22 2c 20 74 69 6d 65 2e 67 6d 74 69 6d 65 28 64  ", time.gmtime(d
4b40: 43 61 63 68 65 56 61 72 73 2e 67 65 74 28 22 66  CacheVars.get("f
4b50: 42 75 69 6c 64 54 69 6d 65 22 2c 20 30 29 29 29  BuildTime", 0)))
4b60: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
4b70: 20 64 43 61 63 68 65 56 61 72 73 0a 0a 20 20 20   dCacheVars..   
4b80: 20 66 42 75 69 6c 64 54 69 6d 65 20 3d 20 74 69   fBuildTime = ti
4b90: 6d 65 2e 74 69 6d 65 28 29 0a 0a 20 20 20 20 70  me.time()..    p
4ba0: 72 69 6e 74 28 22 3e 20 72 65 61 64 20 72 75 6c  rint("> read rul
4bb0: 65 73 20 66 69 6c 65 2e 2e 2e 22 29 0a 20 20 20  es file...").   
4bc0: 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 6c 52   try:.        lR
4bd0: 75 6c 65 73 20 3d 20 6f 70 65 6e 28 73 70 4c 61  ules = open(spLa
4be0: 6e 67 20 2b 20 22 2f 72 75 6c 65 73 2e 67 72 78  ng + "/rules.grx
4bf0: 22 2c 20 27 72 27 2c 20 65 6e 63 6f 64 69 6e 67  ", 'r', encoding
4c00: 3d 22 75 74 66 2d 38 22 29 2e 72 65 61 64 6c 69  ="utf-8").readli
4c10: 6e 65 73 28 29 0a 20 20 20 20 65 78 63 65 70 74  nes().    except
4c20: 20 4f 53 45 72 72 6f 72 3a 0a 20 20 20 20 20 20   OSError:.      
4c30: 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72 2e 20    print("Error. 
4c40: 52 75 6c 65 73 20 66 69 6c 65 20 69 6e 20 70 72  Rules file in pr
4c50: 6f 6a 65 63 74 20 5b 22 20 2b 20 73 4c 61 6e 67  oject [" + sLang
4c60: 20 2b 20 22 5d 20 6e 6f 74 20 66 6f 75 6e 64 2e   + "] not found.
4c70: 22 29 0a 20 20 20 20 20 20 20 20 65 78 69 74 28  ").        exit(
4c80: 29 0a 0a 20 20 20 20 23 20 72 65 6d 6f 76 69 6e  )..    # removin
4c90: 67 20 63 6f 6d 6d 65 6e 74 73 2c 20 7a 65 72 6f  g comments, zero
4ca0: 69 6e 67 20 65 6d 70 74 79 20 6c 69 6e 65 73 2c  ing empty lines,
4cb0: 20 63 72 65 61 74 69 6e 67 20 64 65 66 69 6e 69   creating defini
4cc0: 74 69 6f 6e 73 2c 20 73 74 6f 72 69 6e 67 20 74  tions, storing t
4cd0: 65 73 74 73 2c 20 6d 65 72 67 69 6e 67 20 72 75  ests, merging ru
4ce0: 6c 65 20 6c 69 6e 65 73 0a 20 20 20 20 70 72 69  le lines.    pri
4cf0: 6e 74 28 22 20 20 70 61 72 73 69 6e 67 20 72 75  nt("  parsing ru
4d00: 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20 6c 52 75  les...").    lRu
4d10: 6c 65 4c 69 6e 65 20 3d 20 5b 5d 0a 20 20 20 20  leLine = [].    
4d20: 6c 54 65 73 74 20 3d 20 5b 5d 0a 20 20 20 20 6c  lTest = [].    l
4d30: 4f 70 74 20 3d 20 5b 5d 0a 20 20 20 20 62 47 72  Opt = [].    bGr
4d40: 61 70 68 20 3d 20 46 61 6c 73 65 0a 20 20 20 20  aph = False.    
4d50: 6c 47 72 61 70 68 52 75 6c 65 20 3d 20 5b 5d 0a  lGraphRule = [].
4d60: 0a 20 20 20 20 66 6f 72 20 69 2c 20 73 4c 69 6e  .    for i, sLin
4d70: 65 20 69 6e 20 65 6e 75 6d 65 72 61 74 65 28 6c  e in enumerate(l
4d80: 52 75 6c 65 73 2c 20 31 29 3a 0a 20 20 20 20 20  Rules, 1):.     
4d90: 20 20 20 69 66 20 73 4c 69 6e 65 2e 73 74 61 72     if sLine.star
4da0: 74 73 77 69 74 68 28 27 23 45 4e 44 27 29 3a 0a  tswith('#END'):.
4db0: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61 72              # ar
4dc0: 62 69 74 72 61 72 79 20 65 6e 64 0a 20 20 20 20  bitrary end.    
4dd0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 42 6f 6f          printBoo
4de0: 6b 6d 61 72 6b 28 30 2c 20 22 42 52 45 41 4b 20  kmark(0, "BREAK 
4df0: 42 59 20 23 45 4e 44 22 2c 20 69 29 0a 20 20 20  BY #END", i).   
4e00: 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20           break. 
4e10: 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e         elif sLin
4e20: 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 23 22  e.startswith("#"
4e30: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ):.            #
4e40: 20 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 20 20 20   comment.       
4e50: 20 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 20       pass.      
4e60: 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61    elif sLine.sta
4e70: 72 74 73 77 69 74 68 28 22 44 45 46 3a 22 29 3a  rtswith("DEF:"):
4e80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 64  .            # d
4e90: 65 66 69 6e 69 74 69 6f 6e 0a 20 20 20 20 20 20  efinition.      
4ea0: 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74        m = re.mat
4eb0: 63 68 28 22 44 45 46 3a 20 2b 28 5b 61 2d 7a 41  ch("DEF: +([a-zA
4ec0: 2d 5a 5f 5d 5b 61 2d 7a 41 2d 5a 5f 30 2d 39 5d  -Z_][a-zA-Z_0-9]
4ed0: 2a 29 20 2b 28 2e 2b 29 24 22 2c 20 73 4c 69 6e  *) +(.+)$", sLin
4ee0: 65 2e 73 74 72 69 70 28 29 29 0a 20 20 20 20 20  e.strip()).     
4ef0: 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20 20         if m:.   
4f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 44 45               dDE
4f10: 46 49 4e 49 54 49 4f 4e 53 5b 22 7b 22 2b 6d 2e  FINITIONS["{"+m.
4f20: 67 72 6f 75 70 28 31 29 2b 22 7d 22 5d 20 3d 20  group(1)+"}"] = 
4f30: 6d 2e 67 72 6f 75 70 28 32 29 0a 20 20 20 20 20  m.group(2).     
4f40: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
4f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
4f60: 6e 74 28 22 45 72 72 6f 72 20 69 6e 20 64 65 66  nt("Error in def
4f70: 69 6e 69 74 69 6f 6e 3a 20 22 2c 20 65 6e 64 3d  inition: ", end=
4f80: 22 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  "").            
4f90: 20 20 20 20 70 72 69 6e 74 28 73 4c 69 6e 65 2e      print(sLine.
4fa0: 73 74 72 69 70 28 29 29 0a 20 20 20 20 20 20 20  strip()).       
4fb0: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
4fc0: 74 73 77 69 74 68 28 22 44 45 43 4c 3a 22 29 3a  tswith("DECL:"):
4fd0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 64  .            # d
4fe0: 65 63 6c 65 6e 73 69 6f 6e 73 0a 20 20 20 20 20  eclensions.     
4ff0: 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61         m = re.ma
5000: 74 63 68 28 72 22 44 45 43 4c 3a 20 2b 28 5c 2b  tch(r"DECL: +(\+
5010: 5c 77 2b 29 20 28 2e 2b 29 24 22 2c 20 73 4c 69  \w+) (.+)$", sLi
5020: 6e 65 2e 73 74 72 69 70 28 29 29 0a 20 20 20 20  ne.strip()).    
5030: 20 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20          if m:.  
5040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 44                dD
5050: 45 43 4c 45 4e 53 49 4f 4e 53 5b 6d 2e 67 72 6f  ECLENSIONS[m.gro
5060: 75 70 28 31 29 5d 20 3d 20 6d 2e 67 72 6f 75 70  up(1)] = m.group
5070: 28 32 29 2e 73 74 72 69 70 28 29 2e 73 70 6c 69  (2).strip().spli
5080: 74 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  t().            
5090: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
50a0: 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72        print("Err
50b0: 6f 72 20 69 6e 20 64 65 63 6c 65 6e 73 69 6f 6e  or in declension
50c0: 20 6c 69 73 74 3a 20 22 2c 20 65 6e 64 3d 22 22   list: ", end=""
50d0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
50e0: 20 20 70 72 69 6e 74 28 73 4c 69 6e 65 2e 73 74    print(sLine.st
50f0: 72 69 70 28 29 29 0a 20 20 20 20 20 20 20 20 65  rip()).        e
5100: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
5110: 77 69 74 68 28 22 54 45 53 54 3a 22 29 3a 0a 20  with("TEST:"):. 
5120: 20 20 20 20 20 20 20 20 20 20 20 23 20 74 65 73             # tes
5130: 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 54  t.            lT
5140: 65 73 74 2e 61 70 70 65 6e 64 28 22 7b 3a 3c 38  est.append("{:<8
5150: 7d 22 2e 66 6f 72 6d 61 74 28 69 29 20 2b 20 22  }".format(i) + "
5160: 20 20 22 20 2b 20 73 4c 69 6e 65 5b 35 3a 5d 2e    " + sLine[5:].
5170: 73 74 72 69 70 28 29 29 0a 20 20 20 20 20 20 20  strip()).       
5180: 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72   elif sLine.star
5190: 74 73 77 69 74 68 28 22 54 4f 44 4f 3a 22 29 3a  tswith("TODO:"):
51a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 74  .            # t
51b0: 6f 64 6f 0a 20 20 20 20 20 20 20 20 20 20 20 20  odo.            
51c0: 70 61 73 73 0a 20 20 20 20 20 20 20 20 65 6c 69  pass.        eli
51d0: 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69  f sLine.startswi
51e0: 74 68 28 28 22 4f 50 54 47 52 4f 55 50 2f 22 2c  th(("OPTGROUP/",
51f0: 20 22 4f 50 54 53 4f 46 54 57 41 52 45 3a 22 2c   "OPTSOFTWARE:",
5200: 20 22 4f 50 54 2f 22 2c 20 5c 0a 20 20 20 20 20   "OPT/", \.     
5210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5220: 20 20 20 20 20 20 20 20 20 20 20 22 43 4f 4c 4f             "COLO
5230: 52 2f 22 2c 20 22 4f 50 54 43 4f 4c 4f 52 54 48  R/", "OPTCOLORTH
5240: 45 4d 45 3a 22 2c 20 22 4f 50 54 43 4f 4c 4f 52  EME:", "OPTCOLOR
5250: 2f 22 2c 20 5c 0a 20 20 20 20 20 20 20 20 20 20  /", \.          
5260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5270: 20 20 20 20 20 20 22 4f 50 54 4c 41 4e 47 2f 22        "OPTLANG/"
5280: 2c 20 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c  , "OPTDEFAULTUIL
5290: 41 4e 47 3a 22 2c 20 5c 0a 20 20 20 20 20 20 20  ANG:", \.       
52a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
52b0: 20 20 20 20 20 20 20 20 20 22 4f 50 54 4c 41 42           "OPTLAB
52c0: 45 4c 2f 22 2c 20 22 4f 50 54 50 52 49 4f 52 49  EL/", "OPTPRIORI
52d0: 54 59 2f 22 29 29 3a 0a 20 20 20 20 20 20 20 20  TY/")):.        
52e0: 20 20 20 20 23 20 6f 70 74 69 6f 6e 73 0a 20 20      # options.  
52f0: 20 20 20 20 20 20 20 20 20 20 6c 4f 70 74 2e 61            lOpt.a
5300: 70 70 65 6e 64 28 73 4c 69 6e 65 29 0a 20 20 20  ppend(sLine).   
5310: 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e       elif sLine.
5320: 73 74 61 72 74 73 77 69 74 68 28 22 21 21 22 29  startswith("!!")
5330: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
5340: 62 6f 6f 6b 6d 61 72 6b 0a 20 20 20 20 20 20 20  bookmark.       
5350: 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63       m = re.matc
5360: 68 28 22 21 21 2b 22 2c 20 73 4c 69 6e 65 29 0a  h("!!+", sLine).
5370: 20 20 20 20 20 20 20 20 20 20 20 20 6e 45 78 4d              nExM
5380: 6b 20 3d 20 6c 65 6e 28 6d 2e 67 72 6f 75 70 28  k = len(m.group(
5390: 30 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  0)).            
53a0: 69 66 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 5d  if sLine[nExMk:]
53b0: 2e 73 74 72 69 70 28 29 3a 0a 20 20 20 20 20 20  .strip():.      
53c0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 42            printB
53d0: 6f 6f 6b 6d 61 72 6b 28 6e 45 78 4d 6b 2d 32 2c  ookmark(nExMk-2,
53e0: 20 73 4c 69 6e 65 5b 6e 45 78 4d 6b 3a 2d 33 5d   sLine[nExMk:-3]
53f0: 2e 73 74 72 69 70 28 29 2c 20 69 29 0a 20 20 20  .strip(), i).   
5400: 20 20 20 20 20 23 20 47 72 61 70 68 20 72 75 6c       # Graph rul
5410: 65 73 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  es.        elif 
5420: 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68  sLine.startswith
5430: 28 22 40 40 40 40 47 52 41 50 48 3a 22 29 3a 0a  ("@@@@GRAPH:"):.
5440: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 72 75              # ru
5450: 6c 65 73 20 67 72 61 70 68 20 63 61 6c 6c 0a 20  les graph call. 
5460: 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20 72             m = r
5470: 65 2e 6d 61 74 63 68 28 72 22 40 40 40 40 47 52  e.match(r"@@@@GR
5480: 41 50 48 3a 20 2a 28 5c 77 2b 29 22 2c 20 73 4c  APH: *(\w+)", sL
5490: 69 6e 65 2e 73 74 72 69 70 28 29 29 0a 20 20 20  ine.strip()).   
54a0: 20 20 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20           if m:. 
54b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
54c0: 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b 28 30 2c 20  rintBookmark(0, 
54d0: 22 47 52 41 50 48 3a 20 22 20 2b 20 6d 2e 67 72  "GRAPH: " + m.gr
54e0: 6f 75 70 28 31 29 2c 20 69 29 0a 20 20 20 20 20  oup(1), i).     
54f0: 20 20 20 20 20 20 20 20 20 20 20 6c 52 75 6c 65             lRule
5500: 4c 69 6e 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20  Line.append([i, 
5510: 22 40 40 40 40 22 2b 6d 2e 67 72 6f 75 70 28 31  "@@@@"+m.group(1
5520: 29 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  )]).            
5530: 20 20 20 20 6c 47 72 61 70 68 52 75 6c 65 2e 61      lGraphRule.a
5540: 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69 6e 65 5d  ppend([i, sLine]
5550: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
5560: 20 20 62 47 72 61 70 68 20 3d 20 54 72 75 65 0a    bGraph = True.
5570: 20 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65              else
5580: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5590: 20 20 70 72 69 6e 74 28 22 47 72 61 70 68 20 65    print("Graph e
55a0: 72 72 6f 72 20 61 74 20 6c 69 6e 65 22 2c 20 69  rror at line", i
55b0: 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  ).        elif s
55c0: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
55d0: 28 22 40 40 40 40 45 4e 44 5f 47 52 41 50 48 22  ("@@@@END_GRAPH"
55e0: 2c 20 22 40 40 40 40 45 4e 44 47 52 41 50 48 22  , "@@@@ENDGRAPH"
55f0: 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  )):.            
5600: 23 6c 47 72 61 70 68 52 75 6c 65 2e 61 70 70 65  #lGraphRule.appe
5610: 6e 64 28 5b 69 2c 20 73 4c 69 6e 65 5d 29 0a 20  nd([i, sLine]). 
5620: 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74             print
5630: 42 6f 6f 6b 6d 61 72 6b 28 30 2c 20 22 45 4e 44  Bookmark(0, "END
5640: 47 52 41 50 48 22 2c 20 69 29 0a 20 20 20 20 20  GRAPH", i).     
5650: 20 20 20 20 20 20 20 62 47 72 61 70 68 20 3d 20         bGraph = 
5660: 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20 65 6c  False.        el
5670: 69 66 20 72 65 2e 6d 61 74 63 68 28 22 40 40 40  if re.match("@@@
5680: 40 20 2a 24 22 2c 20 73 4c 69 6e 65 29 3a 0a 20  @ *$", sLine):. 
5690: 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73 0a             pass.
56a0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 62 47 72          elif bGr
56b0: 61 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  aph:.           
56c0: 20 6c 47 72 61 70 68 52 75 6c 65 2e 61 70 70 65   lGraphRule.appe
56d0: 6e 64 28 5b 69 2c 20 73 4c 69 6e 65 5d 29 0a 20  nd([i, sLine]). 
56e0: 20 20 20 20 20 20 20 23 20 52 65 67 65 78 20 72         # Regex r
56f0: 75 6c 65 73 0a 20 20 20 20 20 20 20 20 65 6c 69  ules.        eli
5700: 66 20 72 65 2e 6d 61 74 63 68 28 22 5b 20 c2 a0  f re.match("[ ..
5710: 5c 74 5d 2a 24 22 2c 20 73 4c 69 6e 65 29 3a 0a  \t]*$", sLine):.
5720: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 65 6d              # em
5730: 70 74 79 20 6c 69 6e 65 0a 20 20 20 20 20 20 20  pty line.       
5740: 20 20 20 20 20 70 61 73 73 0a 20 20 20 20 20 20       pass.      
5750: 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61    elif sLine.sta
5760: 72 74 73 77 69 74 68 28 22 20 20 20 20 22 29 3a  rtswith("    "):
5770: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 72  .            # r
5780: 75 6c 65 20 28 63 6f 6e 74 69 6e 75 61 74 69 6f  ule (continuatio
5790: 6e 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  n).            l
57a0: 52 75 6c 65 4c 69 6e 65 5b 2d 31 5d 5b 31 5d 20  RuleLine[-1][1] 
57b0: 2b 3d 20 22 20 22 20 2b 20 73 4c 69 6e 65 2e 73  += " " + sLine.s
57c0: 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 65  trip().        e
57d0: 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20  lse:.           
57e0: 20 23 20 6e 65 77 20 72 75 6c 65 0a 20 20 20 20   # new rule.    
57f0: 20 20 20 20 20 20 20 20 6c 52 75 6c 65 4c 69 6e          lRuleLin
5800: 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20 73 4c 69  e.append([i, sLi
5810: 6e 65 2e 73 74 72 69 70 28 29 5d 29 0a 0a 20 20  ne.strip()])..  
5820: 20 20 23 20 67 65 6e 65 72 61 74 69 6e 67 20 6f    # generating o
5830: 70 74 69 6f 6e 73 20 66 69 6c 65 73 0a 20 20 20  ptions files.   
5840: 20 70 72 69 6e 74 28 22 20 20 70 61 72 73 69 6e   print("  parsin
5850: 67 20 6f 70 74 69 6f 6e 73 2e 2e 2e 22 29 0a 20  g options..."). 
5860: 20 20 20 64 4f 70 74 69 6f 6e 73 2c 20 64 4f 70     dOptions, dOp
5870: 74 50 72 69 6f 72 69 74 79 20 3d 20 70 72 65 70  tPriority = prep
5880: 61 72 65 4f 70 74 69 6f 6e 73 28 6c 4f 70 74 29  areOptions(lOpt)
5890: 0a 0a 20 20 20 20 23 20 74 65 73 74 73 0a 20 20  ..    # tests.  
58a0: 20 20 70 72 69 6e 74 28 22 20 20 6c 69 73 74 20    print("  list 
58b0: 74 65 73 74 73 2e 2e 2e 22 29 0a 20 20 20 20 73  tests...").    s
58c0: 47 43 54 65 73 74 73 20 3d 20 22 5c 6e 22 2e 6a  GCTests = "\n".j
58d0: 6f 69 6e 28 6c 54 65 73 74 29 0a 20 20 20 20 73  oin(lTest).    s
58e0: 47 43 54 65 73 74 73 4a 53 20 3d 20 27 7b 20 22  GCTestsJS = '{ "
58f0: 61 44 61 74 61 22 3a 20 27 20 2b 20 6a 73 6f 6e  aData": ' + json
5900: 2e 64 75 6d 70 73 28 6c 54 65 73 74 2c 20 65 6e  .dumps(lTest, en
5910: 73 75 72 65 5f 61 73 63 69 69 3d 46 61 6c 73 65  sure_ascii=False
5920: 29 20 2b 20 22 20 7d 5c 6e 22 0a 0a 20 20 20 20  ) + " }\n"..    
5930: 23 20 70 72 6f 63 65 73 73 69 6e 67 0a 20 20 20  # processing.   
5940: 20 70 72 69 6e 74 28 22 20 20 70 72 65 70 61 72   print("  prepar
5950: 69 6e 67 20 72 75 6c 65 73 2e 2e 2e 22 29 0a 20  ing rules..."). 
5960: 20 20 20 62 50 61 72 61 67 72 61 70 68 20 3d 20     bParagraph = 
5970: 54 72 75 65 0a 20 20 20 20 6c 50 61 72 61 67 72  True.    lParagr
5980: 61 70 68 52 75 6c 65 73 20 3d 20 5b 5d 0a 20 20  aphRules = [].  
5990: 20 20 6c 53 65 6e 74 65 6e 63 65 52 75 6c 65 73    lSentenceRules
59a0: 20 3d 20 5b 5d 0a 20 20 20 20 6c 50 61 72 61 67   = [].    lParag
59b0: 72 61 70 68 52 75 6c 65 73 4a 53 20 3d 20 5b 5d  raphRulesJS = []
59c0: 0a 20 20 20 20 6c 53 65 6e 74 65 6e 63 65 52 75  .    lSentenceRu
59d0: 6c 65 73 4a 53 20 3d 20 5b 5d 0a 0a 20 20 20 20  lesJS = []..    
59e0: 66 6f 72 20 6e 4c 69 6e 65 2c 20 73 4c 69 6e 65  for nLine, sLine
59f0: 20 69 6e 20 6c 52 75 6c 65 4c 69 6e 65 3a 0a 20   in lRuleLine:. 
5a00: 20 20 20 20 20 20 20 69 66 20 73 4c 69 6e 65 3a         if sLine:
5a10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
5a20: 73 4c 69 6e 65 20 3d 3d 20 22 5b 2b 2b 5d 22 3a  sLine == "[++]":
5a30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5a40: 20 62 50 61 72 61 67 72 61 70 68 20 3d 20 46 61   bParagraph = Fa
5a50: 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  lse.            
5a60: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
5a70: 20 20 20 20 20 20 61 52 75 6c 65 20 3d 20 63 72        aRule = cr
5a80: 65 61 74 65 52 75 6c 65 28 73 4c 69 6e 65 2c 20  eateRule(sLine, 
5a90: 6e 4c 69 6e 65 2c 20 73 4c 61 6e 67 2c 20 62 50  nLine, sLang, bP
5aa0: 61 72 61 67 72 61 70 68 2c 20 64 4f 70 74 50 72  aragraph, dOptPr
5ab0: 69 6f 72 69 74 79 29 0a 20 20 20 20 20 20 20 20  iority).        
5ac0: 20 20 20 20 20 20 20 20 69 66 20 61 52 75 6c 65          if aRule
5ad0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
5ae0: 20 20 20 20 20 20 69 66 20 62 50 61 72 61 67 72        if bParagr
5af0: 61 70 68 3a 0a 20 20 20 20 20 20 20 20 20 20 20  aph:.           
5b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 50 61               lPa
5b10: 72 61 67 72 61 70 68 52 75 6c 65 73 2e 61 70 70  ragraphRules.app
5b20: 65 6e 64 28 61 52 75 6c 65 29 0a 20 20 20 20 20  end(aRule).     
5b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b40: 20 20 20 6c 50 61 72 61 67 72 61 70 68 52 75 6c     lParagraphRul
5b50: 65 73 4a 53 2e 61 70 70 65 6e 64 28 6a 73 63 6f  esJS.append(jsco
5b60: 6e 76 2e 70 79 52 75 6c 65 54 6f 4a 53 28 61 52  nv.pyRuleToJS(aR
5b70: 75 6c 65 2c 20 64 4a 53 52 45 47 45 58 45 53 2c  ule, dJSREGEXES,
5b80: 20 73 57 4f 52 44 4c 49 4d 49 54 4c 45 46 54 29   sWORDLIMITLEFT)
5b90: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ).              
5ba0: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
5bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5bc0: 20 20 20 20 6c 53 65 6e 74 65 6e 63 65 52 75 6c      lSentenceRul
5bd0: 65 73 2e 61 70 70 65 6e 64 28 61 52 75 6c 65 29  es.append(aRule)
5be0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5bf0: 20 20 20 20 20 20 20 20 20 6c 53 65 6e 74 65 6e           lSenten
5c00: 63 65 52 75 6c 65 73 4a 53 2e 61 70 70 65 6e 64  ceRulesJS.append
5c10: 28 6a 73 63 6f 6e 76 2e 70 79 52 75 6c 65 54 6f  (jsconv.pyRuleTo
5c20: 4a 53 28 61 52 75 6c 65 2c 20 64 4a 53 52 45 47  JS(aRule, dJSREG
5c30: 45 58 45 53 2c 20 73 57 4f 52 44 4c 49 4d 49 54  EXES, sWORDLIMIT
5c40: 4c 45 46 54 29 29 0a 0a 20 20 20 20 23 20 63 72  LEFT))..    # cr
5c50: 65 61 74 69 6e 67 20 66 69 6c 65 20 77 69 74 68  eating file with
5c60: 20 61 6c 6c 20 66 75 6e 63 74 69 6f 6e 73 20 63   all functions c
5c70: 61 6c 6c 61 62 6c 65 20 62 79 20 72 75 6c 65 73  allable by rules
5c80: 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 63 72  .    print("  cr
5c90: 65 61 74 69 6e 67 20 63 61 6c 6c 61 62 6c 65 73  eating callables
5ca0: 20 66 6f 72 20 72 65 67 65 78 20 72 75 6c 65 73   for regex rules
5cb0: 2e 2e 2e 22 29 0a 20 20 20 20 73 50 79 43 61 6c  ...").    sPyCal
5cc0: 6c 61 62 6c 65 73 20 3d 20 22 22 0a 20 20 20 20  lables = "".    
5cd0: 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20 3d 20 22  sJSCallables = "
5ce0: 22 0a 20 20 20 20 66 6f 72 20 73 46 75 6e 63 4e  ".    for sFuncN
5cf0: 61 6d 65 2c 20 73 52 65 74 75 72 6e 20 69 6e 20  ame, sReturn in 
5d00: 6c 46 55 4e 43 54 49 4f 4e 53 3a 0a 20 20 20 20  lFUNCTIONS:.    
5d10: 20 20 20 20 69 66 20 73 46 75 6e 63 4e 61 6d 65      if sFuncName
5d20: 2e 73 74 61 72 74 73 77 69 74 68 28 22 5f 63 5f  .startswith("_c_
5d30: 22 29 3a 20 23 20 63 6f 6e 64 69 74 69 6f 6e 0a  "): # condition.
5d40: 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61 72              sPar
5d50: 61 6d 73 20 3d 20 22 73 53 65 6e 74 65 6e 63 65  ams = "sSentence
5d60: 2c 20 73 53 65 6e 74 65 6e 63 65 30 2c 20 6d 2c  , sSentence0, m,
5d70: 20 64 54 6f 6b 65 6e 50 6f 73 2c 20 73 43 6f 75   dTokenPos, sCou
5d80: 6e 74 72 79 2c 20 62 43 6f 6e 64 4d 65 6d 6f 22  ntry, bCondMemo"
5d90: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 46  .        elif sF
5da0: 75 6e 63 4e 61 6d 65 2e 73 74 61 72 74 73 77 69  uncName.startswi
5db0: 74 68 28 22 5f 6d 5f 22 29 3a 20 23 20 6d 65 73  th("_m_"): # mes
5dc0: 73 61 67 65 0a 20 20 20 20 20 20 20 20 20 20 20  sage.           
5dd0: 20 73 50 61 72 61 6d 73 20 3d 20 22 73 53 65 6e   sParams = "sSen
5de0: 74 65 6e 63 65 2c 20 6d 22 0a 20 20 20 20 20 20  tence, m".      
5df0: 20 20 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d 65    elif sFuncName
5e00: 2e 73 74 61 72 74 73 77 69 74 68 28 22 5f 73 5f  .startswith("_s_
5e10: 22 29 3a 20 23 20 73 75 67 67 65 73 74 69 6f 6e  "): # suggestion
5e20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 50 61  .            sPa
5e30: 72 61 6d 73 20 3d 20 22 73 53 65 6e 74 65 6e 63  rams = "sSentenc
5e40: 65 2c 20 6d 22 0a 20 20 20 20 20 20 20 20 65 6c  e, m".        el
5e50: 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61  if sFuncName.sta
5e60: 72 74 73 77 69 74 68 28 22 5f 70 5f 22 29 3a 20  rtswith("_p_"): 
5e70: 23 20 70 72 65 70 72 6f 63 65 73 73 6f 72 0a 20  # preprocessor. 
5e80: 20 20 20 20 20 20 20 20 20 20 20 73 50 61 72 61             sPara
5e90: 6d 73 20 3d 20 22 73 53 65 6e 74 65 6e 63 65 2c  ms = "sSentence,
5ea0: 20 6d 22 0a 20 20 20 20 20 20 20 20 65 6c 69 66   m".        elif
5eb0: 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61 72 74   sFuncName.start
5ec0: 73 77 69 74 68 28 22 5f 64 5f 22 29 3a 20 23 20  swith("_d_"): # 
5ed0: 64 69 73 61 6d 62 69 67 75 61 74 6f 72 0a 20 20  disambiguator.  
5ee0: 20 20 20 20 20 20 20 20 20 20 73 50 61 72 61 6d            sParam
5ef0: 73 20 3d 20 22 73 53 65 6e 74 65 6e 63 65 2c 20  s = "sSentence, 
5f00: 6d 2c 20 64 54 6f 6b 65 6e 50 6f 73 22 0a 20 20  m, dTokenPos".  
5f10: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
5f20: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
5f30: 20 55 6e 6b 6e 6f 77 6e 20 66 75 6e 63 74 69 6f   Unknown functio
5f40: 6e 20 74 79 70 65 20 69 6e 20 5b 22 20 2b 20 73  n type in [" + s
5f50: 46 75 6e 63 4e 61 6d 65 20 2b 20 22 5d 22 29 0a  FuncName + "]").
5f60: 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74              cont
5f70: 69 6e 75 65 0a 20 20 20 20 20 20 20 20 23 20 50  inue.        # P
5f80: 79 74 68 6f 6e 0a 20 20 20 20 20 20 20 20 73 50  ython.        sP
5f90: 79 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 64  yCallables += "d
5fa0: 65 66 20 7b 7d 20 28 7b 7d 29 3a 5c 6e 22 2e 66  ef {} ({}):\n".f
5fb0: 6f 72 6d 61 74 28 73 46 75 6e 63 4e 61 6d 65 2c  ormat(sFuncName,
5fc0: 20 73 50 61 72 61 6d 73 29 0a 20 20 20 20 20 20   sParams).      
5fd0: 20 20 73 50 79 43 61 6c 6c 61 62 6c 65 73 20 2b    sPyCallables +
5fe0: 3d 20 22 20 20 20 20 72 65 74 75 72 6e 20 22 20  = "    return " 
5ff0: 2b 20 73 52 65 74 75 72 6e 20 2b 20 22 5c 6e 22  + sReturn + "\n"
6000: 0a 20 20 20 20 20 20 20 20 23 20 4a 61 76 61 53  .        # JavaS
6010: 63 72 69 70 74 0a 20 20 20 20 20 20 20 20 73 4a  cript.        sJ
6020: 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20  SCallables += " 
6030: 20 20 20 7b 7d 3a 20 66 75 6e 63 74 69 6f 6e 20     {}: function 
6040: 28 7b 7d 29 22 2e 66 6f 72 6d 61 74 28 73 46 75  ({})".format(sFu
6050: 6e 63 4e 61 6d 65 2c 20 73 50 61 72 61 6d 73 29  ncName, sParams)
6060: 20 2b 20 22 20 7b 5c 6e 22 0a 20 20 20 20 20 20   + " {\n".      
6070: 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b    sJSCallables +
6080: 3d 20 22 20 20 20 20 20 20 20 20 72 65 74 75 72  = "        retur
6090: 6e 20 22 20 2b 20 6a 73 63 6f 6e 76 2e 70 79 32  n " + jsconv.py2
60a0: 6a 73 28 73 52 65 74 75 72 6e 29 20 2b 20 22 3b  js(sReturn) + ";
60b0: 5c 6e 22 0a 20 20 20 20 20 20 20 20 73 4a 53 43  \n".        sJSC
60c0: 61 6c 6c 61 62 6c 65 73 20 2b 3d 20 22 20 20 20  allables += "   
60d0: 20 7d 2c 5c 6e 22 0a 0a 20 20 20 20 64 69 73 70   },\n"..    disp
60e0: 6c 61 79 53 74 61 74 73 28 6c 50 61 72 61 67 72  layStats(lParagr
60f0: 61 70 68 52 75 6c 65 73 2c 20 6c 53 65 6e 74 65  aphRules, lSente
6100: 6e 63 65 52 75 6c 65 73 29 0a 0a 20 20 20 20 64  nceRules)..    d
6110: 56 61 72 73 20 3d 20 7b 0a 20 20 20 20 20 20 20  Vars = {.       
6120: 20 22 66 42 75 69 6c 64 54 69 6d 65 22 3a 20 66   "fBuildTime": f
6130: 42 75 69 6c 64 54 69 6d 65 2c 0a 20 20 20 20 20  BuildTime,.     
6140: 20 20 20 22 63 61 6c 6c 61 62 6c 65 73 22 3a 20     "callables": 
6150: 73 50 79 43 61 6c 6c 61 62 6c 65 73 2c 0a 20 20  sPyCallables,.  
6160: 20 20 20 20 20 20 22 63 61 6c 6c 61 62 6c 65 73        "callables
6170: 4a 53 22 3a 20 73 4a 53 43 61 6c 6c 61 62 6c 65  JS": sJSCallable
6180: 73 2c 0a 20 20 20 20 20 20 20 20 22 67 63 74 65  s,.        "gcte
6190: 73 74 73 22 3a 20 73 47 43 54 65 73 74 73 2c 0a  sts": sGCTests,.
61a0: 20 20 20 20 20 20 20 20 22 67 63 74 65 73 74 73          "gctests
61b0: 4a 53 22 3a 20 73 47 43 54 65 73 74 73 4a 53 2c  JS": sGCTestsJS,
61c0: 0a 20 20 20 20 20 20 20 20 22 70 61 72 61 67 72  .        "paragr
61d0: 61 70 68 5f 72 75 6c 65 73 22 3a 20 6d 65 72 67  aph_rules": merg
61e0: 65 52 75 6c 65 73 42 79 4f 70 74 69 6f 6e 28 6c  eRulesByOption(l
61f0: 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 29 2c  ParagraphRules),
6200: 0a 20 20 20 20 20 20 20 20 22 73 65 6e 74 65 6e  .        "senten
6210: 63 65 5f 72 75 6c 65 73 22 3a 20 6d 65 72 67 65  ce_rules": merge
6220: 52 75 6c 65 73 42 79 4f 70 74 69 6f 6e 28 6c 53  RulesByOption(lS
6230: 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 2c 0a 20  entenceRules),. 
6240: 20 20 20 20 20 20 20 22 70 61 72 61 67 72 61 70         "paragrap
6250: 68 5f 72 75 6c 65 73 5f 4a 53 22 3a 20 6a 73 63  h_rules_JS": jsc
6260: 6f 6e 76 2e 77 72 69 74 65 52 75 6c 65 73 54 6f  onv.writeRulesTo
6270: 4a 53 41 72 72 61 79 28 6d 65 72 67 65 52 75 6c  JSArray(mergeRul
6280: 65 73 42 79 4f 70 74 69 6f 6e 28 6c 50 61 72 61  esByOption(lPara
6290: 67 72 61 70 68 52 75 6c 65 73 4a 53 29 29 2c 0a  graphRulesJS)),.
62a0: 20 20 20 20 20 20 20 20 22 73 65 6e 74 65 6e 63          "sentenc
62b0: 65 5f 72 75 6c 65 73 5f 4a 53 22 3a 20 6a 73 63  e_rules_JS": jsc
62c0: 6f 6e 76 2e 77 72 69 74 65 52 75 6c 65 73 54 6f  onv.writeRulesTo
62d0: 4a 53 41 72 72 61 79 28 6d 65 72 67 65 52 75 6c  JSArray(mergeRul
62e0: 65 73 42 79 4f 70 74 69 6f 6e 28 6c 53 65 6e 74  esByOption(lSent
62f0: 65 6e 63 65 52 75 6c 65 73 4a 53 29 29 0a 20 20  enceRulesJS)).  
6300: 20 20 7d 0a 20 20 20 20 64 56 61 72 73 2e 75 70    }.    dVars.up
6310: 64 61 74 65 28 64 4f 70 74 69 6f 6e 73 29 0a 0a  date(dOptions)..
6320: 20 20 20 20 23 20 63 6f 6d 70 69 6c 65 20 67 72      # compile gr
6330: 61 70 68 20 72 75 6c 65 73 0a 20 20 20 20 64 56  aph rules.    dV
6340: 61 72 73 32 20 3d 20 63 72 67 2e 6d 61 6b 65 28  ars2 = crg.make(
6350: 6c 47 72 61 70 68 52 75 6c 65 2c 20 73 4c 61 6e  lGraphRule, sLan
6360: 67 2c 20 64 44 45 46 49 4e 49 54 49 4f 4e 53 2c  g, dDEFINITIONS,
6370: 20 64 44 45 43 4c 45 4e 53 49 4f 4e 53 2c 20 64   dDECLENSIONS, d
6380: 4f 70 74 50 72 69 6f 72 69 74 79 29 0a 20 20 20  OptPriority).   
6390: 20 64 56 61 72 73 2e 75 70 64 61 74 65 28 64 56   dVars.update(dV
63a0: 61 72 73 32 29 0a 0a 20 20 20 20 77 69 74 68 20  ars2)..    with 
63b0: 6f 70 65 6e 28 22 5f 62 75 69 6c 64 2f 64 61 74  open("_build/dat
63c0: 61 5f 63 61 63 68 65 2e 6a 73 6f 6e 22 2c 20 22  a_cache.json", "
63d0: 77 22 2c 20 65 6e 63 6f 64 69 6e 67 3d 22 75 74  w", encoding="ut
63e0: 66 2d 38 22 29 20 61 73 20 68 44 73 74 3a 0a 20  f-8") as hDst:. 
63f0: 20 20 20 20 20 20 20 68 44 73 74 2e 77 72 69 74         hDst.writ
6400: 65 28 6a 73 6f 6e 2e 64 75 6d 70 73 28 64 56 61  e(json.dumps(dVa
6410: 72 73 2c 20 65 6e 73 75 72 65 5f 61 73 63 69 69  rs, ensure_ascii
6420: 3d 46 61 6c 73 65 29 29 0a 20 20 20 20 72 65 74  =False)).    ret
6430: 75 72 6e 20 64 56 61 72 73 0a                    urn dVars.