Grammalecte  Hex Artifact Content

Artifact 0e87a1f5c889a000ef9adece84352466e151d4750d78d756b574081094f48b32:


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 20 3d 20 7b 7d 0a 6c 46 55 4e 43 54  dDEF = {}.lFUNCT
00d0: 49 4f 4e 53 20 3d 20 5b 5d 0a 0a 61 52 55 4c 45  IONS = []..aRULE
00e0: 53 45 54 20 3d 20 73 65 74 28 29 20 20 20 20 20  SET = set()     
00f0: 23 20 73 65 74 20 6f 66 20 72 75 6c 65 2d 69 64  # set of rule-id
0100: 73 20 74 6f 20 63 68 65 63 6b 20 69 66 20 74 68  s to check if th
0110: 65 72 65 20 69 73 20 73 65 76 65 72 61 6c 20 72  ere is several r
0120: 75 6c 65 73 20 77 69 74 68 20 74 68 65 20 73 61  ules with the sa
0130: 6d 65 20 69 64 0a 6e 52 55 4c 45 57 49 54 48 4f  me id.nRULEWITHO
0140: 55 54 4e 41 4d 45 20 3d 20 30 0a 0a 64 4a 53 52  UTNAME = 0..dJSR
0150: 45 47 45 58 45 53 20 3d 20 7b 7d 0a 0a 73 57 4f  EGEXES = {}..sWO
0160: 52 44 4c 49 4d 49 54 4c 45 46 54 20 20 3d 20 72  RDLIMITLEFT  = r
0170: 22 28 3f 3c 21 5b 5c 77 2e 2c e2 80 93 2d 5d 29  "(?<![\w.,...-])
0180: 22 20 20 20 23 20 72 22 28 3f 3c 21 5b 2d 2e 2c  "   # r"(?<![-.,
0190: e2 80 94 5d 29 5c 62 22 20 20 73 65 65 6d 73 20  ...])\b"  seems 
01a0: 73 6c 6f 77 65 72 0a 73 57 4f 52 44 4c 49 4d 49  slower.sWORDLIMI
01b0: 54 52 49 47 48 54 20 3d 20 72 22 28 3f 21 5b 5c  TRIGHT = r"(?![\
01c0: 77 e2 80 93 2d 5d 29 22 20 20 20 20 20 20 23 20  w...-])"      # 
01d0: 72 22 5c 62 28 3f 21 2d e2 80 94 29 22 20 20 20  r"\b(?!-...)"   
01e0: 20 20 20 20 73 65 65 6d 73 20 73 6c 6f 77 65 72      seems slower
01f0: 0a 0a 0a 64 65 66 20 63 6f 6e 76 65 72 74 52 47  ...def convertRG
0200: 42 54 6f 49 6e 74 65 67 65 72 20 28 72 2c 20 67  BToInteger (r, g
0210: 2c 20 62 29 3a 0a 20 20 20 20 22 72 62 67 20 28  , b):.    "rbg (
0220: 69 6e 74 2c 20 69 6e 74 2c 20 69 6e 74 29 20 2d  int, int, int) -
0230: 3e 20 69 6e 74 22 0a 20 20 20 20 72 65 74 75 72  > int".    retur
0240: 6e 20 28 72 20 26 20 32 35 35 29 20 3c 3c 20 31  n (r & 255) << 1
0250: 36 20 7c 20 28 67 20 26 20 32 35 35 29 20 3c 3c  6 | (g & 255) <<
0260: 20 38 20 7c 20 28 62 20 26 20 32 35 35 29 0a 0a   8 | (b & 255)..
0270: 0a 64 65 66 20 63 6f 6e 76 65 72 74 48 53 4c 54  .def convertHSLT
0280: 6f 52 42 47 20 28 68 2c 20 73 2c 20 6c 29 3a 0a  oRBG (h, s, l):.
0290: 20 20 20 20 22 68 73 6c 20 28 69 6e 74 2c 20 69      "hsl (int, i
02a0: 6e 74 2c 20 69 6e 74 29 20 2d 3e 20 5b 69 6e 74  nt, int) -> [int
02b0: 2c 20 69 6e 74 2c 20 69 6e 74 5d 22 0a 20 20 20  , int, int]".   
02c0: 20 72 2c 20 67 2c 20 62 20 3d 20 63 6f 6c 6f 72   r, g, b = color
02d0: 73 79 73 2e 68 6c 73 5f 74 6f 5f 72 67 62 28 68  sys.hls_to_rgb(h
02e0: 2f 33 36 30 2c 20 6c 2f 31 30 30 2c 20 73 2f 31  /360, l/100, s/1
02f0: 30 30 29 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  00).    return [
0300: 72 6f 75 6e 64 28 72 2a 32 35 35 29 2c 20 72 6f  round(r*255), ro
0310: 75 6e 64 28 67 2a 32 35 35 29 2c 20 72 6f 75 6e  und(g*255), roun
0320: 64 28 62 2a 32 35 35 29 5d 0a 0a 0a 64 65 66 20  d(b*255)]...def 
0330: 63 72 65 61 74 65 43 6f 6c 6f 72 73 20 28 64 43  createColors (dC
0340: 6f 6c 6f 72 29 3a 0a 20 20 20 20 22 64 69 63 74  olor):.    "dict
0350: 69 6f 6e 61 72 79 20 6f 66 20 63 6f 6c 6f 72 73  ionary of colors
0360: 20 7b 63 6f 6c 6f 72 5f 6e 61 6d 65 3a 20 5b 68   {color_name: [h
0370: 2c 20 73 2c 20 6c 5d 7d 20 2d 3e 20 72 65 74 75  , s, l]} -> retu
0380: 72 6e 73 20 64 69 63 74 69 6f 6e 61 72 79 20 6f  rns dictionary o
0390: 66 20 63 6f 6c 6f 72 73 20 61 73 20 64 69 63 74  f colors as dict
03a0: 69 6f 6e 61 72 69 65 73 20 6f 66 20 63 6f 6c 6f  ionaries of colo
03b0: 72 20 74 79 70 65 73 22 0a 20 20 20 20 64 43 6f  r types".    dCo
03c0: 6c 6f 72 54 79 70 65 20 3d 20 7b 0a 20 20 20 20  lorType = {.    
03d0: 20 20 20 20 22 73 43 53 53 22 3a 20 7b 7d 2c 20      "sCSS": {}, 
03e0: 20 20 20 20 23 20 64 69 63 74 69 6f 6e 61 72 79      # dictionary
03f0: 20 6f 66 20 63 6f 6c 6f 72 73 20 61 73 20 73 74   of colors as st
0400: 72 69 6e 67 73 20 66 6f 72 20 48 54 4d 4c 2f 43  rings for HTML/C
0410: 53 53 20 28 65 78 61 6d 70 6c 65 3a 20 68 73 6c  SS (example: hsl
0420: 28 30 2c 20 35 30 25 2c 20 35 30 25 29 29 0a 20  (0, 50%, 50%)). 
0430: 20 20 20 20 20 20 20 22 61 52 47 42 22 3a 20 7b         "aRGB": {
0440: 7d 2c 20 20 20 20 20 23 20 64 69 63 74 69 6f 6e  },     # diction
0450: 61 72 79 20 6f 66 20 63 6f 6c 6f 72 73 20 61 73  ary of colors as
0460: 20 52 47 42 20 74 75 70 6c 65 0a 20 20 20 20 20   RGB tuple.     
0470: 20 20 20 22 6e 49 6e 74 22 3a 20 7b 7d 20 20 20     "nInt": {}   
0480: 20 20 20 23 20 64 69 63 74 69 6f 6e 61 72 79 20     # dictionary 
0490: 6f 66 20 63 6f 6c 6f 72 73 20 61 73 20 69 6e 74  of colors as int
04a0: 65 67 65 72 20 76 61 6c 75 65 73 20 28 66 6f 72  eger values (for
04b0: 20 57 72 69 74 65 72 29 0a 20 20 20 20 7d 0a 20   Writer).    }. 
04c0: 20 20 20 66 6f 72 20 73 4b 65 79 2c 20 61 48 53     for sKey, aHS
04d0: 4c 20 69 6e 20 64 43 6f 6c 6f 72 2e 69 74 65 6d  L in dColor.item
04e0: 73 28 29 3a 0a 20 20 20 20 20 20 20 20 64 43 6f  s():.        dCo
04f0: 6c 6f 72 54 79 70 65 5b 22 73 43 53 53 22 5d 5b  lorType["sCSS"][
0500: 73 4b 65 79 5d 20 3d 20 22 68 73 6c 28 7b 7d 2c  sKey] = "hsl({},
0510: 20 7b 7d 25 2c 20 7b 7d 25 29 22 2e 66 6f 72 6d   {}%, {}%)".form
0520: 61 74 28 2a 61 48 53 4c 29 0a 20 20 20 20 20 20  at(*aHSL).      
0530: 20 20 64 43 6f 6c 6f 72 54 79 70 65 5b 22 61 52    dColorType["aR
0540: 47 42 22 5d 5b 73 4b 65 79 5d 20 3d 20 63 6f 6e  GB"][sKey] = con
0550: 76 65 72 74 48 53 4c 54 6f 52 42 47 28 2a 61 48  vertHSLToRBG(*aH
0560: 53 4c 29 0a 20 20 20 20 20 20 20 20 64 43 6f 6c  SL).        dCol
0570: 6f 72 54 79 70 65 5b 22 6e 49 6e 74 22 5d 5b 73  orType["nInt"][s
0580: 4b 65 79 5d 20 3d 20 63 6f 6e 76 65 72 74 52 47  Key] = convertRG
0590: 42 54 6f 49 6e 74 65 67 65 72 28 2a 64 43 6f 6c  BToInteger(*dCol
05a0: 6f 72 54 79 70 65 5b 22 61 52 47 42 22 5d 5b 73  orType["aRGB"][s
05b0: 4b 65 79 5d 29 0a 20 20 20 20 72 65 74 75 72 6e  Key]).    return
05c0: 20 64 43 6f 6c 6f 72 54 79 70 65 0a 0a 0a 64 65   dColorType...de
05d0: 66 20 70 72 65 70 61 72 65 46 75 6e 63 74 69 6f  f prepareFunctio
05e0: 6e 20 28 73 29 3a 0a 20 20 20 20 22 63 6f 6e 76  n (s):.    "conv
05f0: 65 72 74 20 73 69 6d 70 6c 65 20 72 75 6c 65 20  ert simple rule 
0600: 73 79 6e 74 61 78 20 74 6f 20 61 20 73 74 72 69  syntax to a stri
0610: 6e 67 20 6f 66 20 50 79 74 68 6f 6e 20 63 6f 64  ng of Python cod
0620: 65 22 0a 20 20 20 20 73 20 3d 20 73 2e 72 65 70  e".    s = s.rep
0630: 6c 61 63 65 28 22 5f 5f 61 6c 73 6f 5f 5f 22 2c  lace("__also__",
0640: 20 22 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20   "bCondMemo").  
0650: 20 20 73 20 3d 20 73 2e 72 65 70 6c 61 63 65 28    s = s.replace(
0660: 22 5f 5f 65 6c 73 65 5f 5f 22 2c 20 22 6e 6f 74  "__else__", "not
0670: 20 62 43 6f 6e 64 4d 65 6d 6f 22 29 0a 20 20 20   bCondMemo").   
0680: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73   s = re.sub(r"is
0690: 53 74 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62  Start *\(\)", 'b
06a0: 65 66 6f 72 65 28 22 5e 20 2a 24 7c 2c 20 2a 24  efore("^ *$|, *$
06b0: 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ")', s).    s = 
06c0: 72 65 2e 73 75 62 28 72 22 69 73 52 65 61 6c 53  re.sub(r"isRealS
06d0: 74 61 72 74 20 2a 5c 28 5c 29 22 2c 20 27 62 65  tart *\(\)", 'be
06e0: 66 6f 72 65 28 22 5e 20 2a 24 22 29 27 2c 20 73  fore("^ *$")', s
06f0: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0700: 28 72 22 69 73 53 74 61 72 74 30 20 2a 5c 28 5c  (r"isStart0 *\(\
0710: 29 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e 20  )", 'before0("^ 
0720: 2a 24 7c 2c 20 2a 24 22 29 27 2c 20 73 29 0a 20  *$|, *$")', s). 
0730: 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22     s = re.sub(r"
0740: 69 73 52 65 61 6c 53 74 61 72 74 30 20 2a 5c 28  isRealStart0 *\(
0750: 5c 29 22 2c 20 27 62 65 66 6f 72 65 30 28 22 5e  \)", 'before0("^
0760: 20 2a 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73   *$")', s).    s
0770: 20 3d 20 72 65 2e 73 75 62 28 72 22 69 73 45 6e   = re.sub(r"isEn
0780: 64 20 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72  d *\(\)", 'after
0790: 28 22 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29  ("^ *$|^,")', s)
07a0: 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28  .    s = re.sub(
07b0: 72 22 69 73 52 65 61 6c 45 6e 64 20 2a 5c 28 5c  r"isRealEnd *\(\
07c0: 29 22 2c 20 27 61 66 74 65 72 28 22 5e 20 2a 24  )", 'after("^ *$
07d0: 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20  ")', s).    s = 
07e0: 72 65 2e 73 75 62 28 72 22 69 73 45 6e 64 30 20  re.sub(r"isEnd0 
07f0: 2a 5c 28 5c 29 22 2c 20 27 61 66 74 65 72 30 28  *\(\)", 'after0(
0800: 22 5e 20 2a 24 7c 5e 2c 22 29 27 2c 20 73 29 0a  "^ *$|^,")', s).
0810: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
0820: 22 69 73 52 65 61 6c 45 6e 64 30 20 2a 5c 28 5c  "isRealEnd0 *\(\
0830: 29 22 2c 20 27 61 66 74 65 72 30 28 22 5e 20 2a  )", 'after0("^ *
0840: 24 22 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  $")', s).    s =
0850: 20 72 65 2e 73 75 62 28 72 22 28 73 65 6c 65 63   re.sub(r"(selec
0860: 74 7c 65 78 63 6c 75 64 65 29 5b 28 5d 5b 5c 5c  t|exclude)[(][\\
0870: 5d 28 5c 64 2b 29 22 2c 20 27 5c 5c 31 28 64 54  ](\d+)", '\\1(dT
0880: 6f 6b 65 6e 50 6f 73 2c 20 6d 2e 73 74 61 72 74  okenPos, m.start
0890: 28 5c 5c 32 29 2c 20 6d 2e 67 72 6f 75 70 28 5c  (\\2), m.group(\
08a0: 5c 32 29 27 2c 20 73 29 0a 20 20 20 20 73 20 3d  \2)', s).    s =
08b0: 20 72 65 2e 73 75 62 28 72 22 64 65 66 69 6e 65   re.sub(r"define
08c0: 5b 28 5d 5b 5c 5c 5d 28 5c 64 2b 29 22 2c 20 27  [(][\\](\d+)", '
08d0: 64 65 66 69 6e 65 28 64 54 6f 6b 65 6e 50 6f 73  define(dTokenPos
08e0: 2c 20 6d 2e 73 74 61 72 74 28 5c 5c 31 29 27 2c  , m.start(\\1)',
08f0: 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73   s).    s = re.s
0900: 75 62 28 72 22 28 6d 6f 72 70 68 7c 64 69 73 70  ub(r"(morph|disp
0910: 6c 61 79 49 6e 66 6f 29 5b 28 5d 5b 5c 5c 5d 28  layInfo)[(][\\](
0920: 5c 64 2b 29 22 2c 20 27 5c 5c 31 28 28 6d 2e 73  \d+)", '\\1((m.s
0930: 74 61 72 74 28 5c 5c 32 29 2c 20 6d 2e 67 72 6f  tart(\\2), m.gro
0940: 75 70 28 5c 5c 32 29 29 27 2c 20 73 29 0a 20 20  up(\\2))', s).  
0950: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 28    s = re.sub(r"(
0960: 6d 6f 72 70 68 7c 64 69 73 70 6c 61 79 49 6e 66  morph|displayInf
0970: 6f 29 5b 28 5d 22 2c 20 27 5c 5c 31 28 64 54 6f  o)[(]", '\\1(dTo
0980: 6b 65 6e 50 6f 73 2c 20 27 2c 20 73 29 0a 20 20  kenPos, ', s).  
0990: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 28    s = re.sub(r"(
09a0: 73 75 67 67 5c 77 2b 7c 73 77 69 74 63 68 5c 77  sugg\w+|switch\w
09b0: 2b 29 5c 28 40 22 2c 20 27 5c 5c 31 28 6d 2e 67  +)\(@", '\\1(m.g
09c0: 72 6f 75 70 28 69 5b 34 5d 29 27 2c 20 73 29 0a  roup(i[4])', s).
09d0: 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72      s = re.sub(r
09e0: 22 77 6f 72 64 5c 28 5c 73 2a 31 5c 62 22 2c 20  "word\(\s*1\b", 
09f0: 27 6e 65 78 74 77 6f 72 64 31 28 73 53 65 6e 74  'nextword1(sSent
0a00: 65 6e 63 65 2c 20 6d 2e 65 6e 64 28 29 27 2c 20  ence, m.end()', 
0a10: 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s)              
0a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a30: 20 20 20 20 23 20 77 6f 72 64 28 31 29 0a 20 20      # word(1).  
0a40: 20 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 77    s = re.sub(r"w
0a50: 6f 72 64 5c 28 5c 73 2a 2d 31 5c 62 22 2c 20 27  ord\(\s*-1\b", '
0a60: 70 72 65 76 77 6f 72 64 31 28 73 53 65 6e 74 65  prevword1(sSente
0a70: 6e 63 65 2c 20 6d 2e 73 74 61 72 74 28 29 27 2c  nce, m.start()',
0a80: 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20 20   s)             
0a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0aa0: 20 20 23 20 77 6f 72 64 28 2d 31 29 0a 20 20 20    # word(-1).   
0ab0: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 77 6f   s = re.sub(r"wo
0ac0: 72 64 5c 28 5c 73 2a 28 5c 64 29 22 2c 20 27 6e  rd\(\s*(\d)", 'n
0ad0: 65 78 74 77 6f 72 64 28 73 53 65 6e 74 65 6e 63  extword(sSentenc
0ae0: 65 2c 20 6d 2e 65 6e 64 28 29 2c 20 5c 5c 31 27  e, m.end(), \\1'
0af0: 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20 20  , s)            
0b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b10: 20 23 20 77 6f 72 64 28 6e 29 0a 20 20 20 20 73   # word(n).    s
0b20: 20 3d 20 72 65 2e 73 75 62 28 72 22 77 6f 72 64   = re.sub(r"word
0b30: 5c 28 5c 73 2a 2d 28 5c 64 29 22 2c 20 27 70 72  \(\s*-(\d)", 'pr
0b40: 65 76 77 6f 72 64 28 73 53 65 6e 74 65 6e 63 65  evword(sSentence
0b50: 2c 20 6d 2e 73 74 61 72 74 28 29 2c 20 5c 5c 31  , m.start(), \\1
0b60: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23                 #
0b80: 20 77 6f 72 64 28 2d 6e 29 0a 20 20 20 20 73 20   word(-n).    s 
0b90: 3d 20 72 65 2e 73 75 62 28 72 22 62 65 66 6f 72  = re.sub(r"befor
0ba0: 65 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28 73  e\(\s*", 'look(s
0bb0: 53 65 6e 74 65 6e 63 65 5b 3a 6d 2e 73 74 61 72  Sentence[:m.star
0bc0: 74 28 29 5d 2c 20 27 2c 20 73 29 20 20 20 20 20  t()], ', s)     
0bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20                # 
0bf0: 62 65 66 6f 72 65 28 73 53 65 6e 74 65 6e 63 65  before(sSentence
0c00: 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75 62  ).    s = re.sub
0c10: 28 72 22 61 66 74 65 72 5c 28 5c 73 2a 22 2c 20  (r"after\(\s*", 
0c20: 27 6c 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 5b  'look(sSentence[
0c30: 6d 2e 65 6e 64 28 29 3a 5d 2c 20 27 2c 20 73 29  m.end():], ', s)
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c60: 20 20 20 20 20 20 23 20 61 66 74 65 72 28 73 53        # after(sS
0c70: 65 6e 74 65 6e 63 65 29 0a 20 20 20 20 73 20 3d  entence).    s =
0c80: 20 72 65 2e 73 75 62 28 72 22 74 65 78 74 61 72   re.sub(r"textar
0c90: 65 61 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f 6b 28  ea\(\s*", 'look(
0ca0: 73 53 65 6e 74 65 6e 63 65 2c 20 27 2c 20 73 29  sSentence, ', s)
0cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 23 20 74               # t
0ce0: 65 78 74 61 72 65 61 28 73 53 65 6e 74 65 6e 63  extarea(sSentenc
0cf0: 65 29 0a 20 20 20 20 73 20 3d 20 72 65 2e 73 75  e).    s = re.su
0d00: 62 28 72 22 2f 30 22 2c 20 27 73 53 65 6e 74 65  b(r"/0", 'sSente
0d10: 6e 63 65 30 5b 6d 2e 73 74 61 72 74 28 29 3a 6d  nce0[m.start():m
0d20: 2e 65 6e 64 28 29 5d 27 2c 20 73 29 20 20 20 20  .end()]', s)    
0d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d50: 20 20 20 20 20 20 20 23 20 2f 30 0a 20 20 20 20         # /0.    
0d60: 73 20 3d 20 72 65 2e 73 75 62 28 72 22 62 65 66  s = re.sub(r"bef
0d70: 6f 72 65 30 5c 28 5c 73 2a 22 2c 20 27 6c 6f 6f  ore0\(\s*", 'loo
0d80: 6b 28 73 53 65 6e 74 65 6e 63 65 30 5b 3a 6d 2e  k(sSentence0[:m.
0d90: 73 74 61 72 74 28 29 5d 2c 20 27 2c 20 73 29 20  start()], ', s) 
0da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0dc0: 23 20 62 65 66 6f 72 65 30 28 73 53 65 6e 74 65  # before0(sSente
0dd0: 6e 63 65 29 0a 20 20 20 20 73 20 3d 20 72 65 2e  nce).    s = re.
0de0: 73 75 62 28 72 22 61 66 74 65 72 30 5c 28 5c 73  sub(r"after0\(\s
0df0: 2a 22 2c 20 27 6c 6f 6f 6b 28 73 53 65 6e 74 65  *", 'look(sSente
0e00: 6e 63 65 30 5b 6d 2e 65 6e 64 28 29 3a 5d 2c 20  nce0[m.end():], 
0e10: 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20 20  ', s)           
0e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e30: 20 20 20 20 20 20 20 20 20 23 20 61 66 74 65 72           # after
0e40: 30 28 73 53 65 6e 74 65 6e 63 65 29 0a 20 20 20  0(sSentence).   
0e50: 20 73 20 3d 20 72 65 2e 73 75 62 28 72 22 74 65   s = re.sub(r"te
0e60: 78 74 61 72 65 61 30 5c 28 5c 73 2a 22 2c 20 27  xtarea0\(\s*", '
0e70: 6c 6f 6f 6b 28 73 53 65 6e 74 65 6e 63 65 30 2c  look(sSentence0,
0e80: 20 27 2c 20 73 29 20 20 20 20 20 20 20 20 20 20   ', s)          
0e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0eb0: 20 23 20 74 65 78 74 61 72 65 61 30 28 73 53 65   # textarea0(sSe
0ec0: 6e 74 65 6e 63 65 29 0a 20 20 20 20 73 20 3d 20  ntence).    s = 
0ed0: 72 65 2e 73 75 62 28 72 22 5c 62 73 70 65 6c 6c  re.sub(r"\bspell
0ee0: 20 2a 5b 28 5d 22 2c 20 27 5f 6f 53 70 65 6c 6c   *[(]", '_oSpell
0ef0: 43 68 65 63 6b 65 72 2e 69 73 56 61 6c 69 64 28  Checker.isValid(
0f00: 27 2c 20 73 29 0a 20 20 20 20 73 20 3d 20 72 65  ', s).    s = re
0f10: 2e 73 75 62 28 72 22 5b 5c 5c 5d 28 5c 64 2b 29  .sub(r"[\\](\d+)
0f20: 22 2c 20 27 6d 2e 67 72 6f 75 70 28 5c 5c 31 29  ", 'm.group(\\1)
0f30: 27 2c 20 73 29 0a 20 20 20 20 72 65 74 75 72 6e  ', s).    return
0f40: 20 73 0a 0a 0a 64 65 66 20 75 70 70 65 72 63 61   s...def upperca
0f50: 73 65 20 28 73 54 65 78 74 2c 20 73 4c 61 6e 67  se (sText, sLang
0f60: 29 3a 0a 20 20 20 20 22 28 66 6c 61 67 20 69 20  ):.    "(flag i 
0f70: 69 73 20 6e 6f 74 20 65 6e 6f 75 67 68 29 3a 20  is not enough): 
0f80: 63 6f 6e 76 65 72 74 73 20 72 65 67 65 78 20 74  converts regex t
0f90: 6f 20 75 70 70 65 72 63 61 73 65 20 72 65 67 65  o uppercase rege
0fa0: 78 3a 20 27 66 6f 6f 27 20 62 65 63 6f 6d 65 73  x: 'foo' becomes
0fb0: 20 27 5b 46 66 5d 5b 4f 6f 5d 5b 4f 6f 5d 27 2c   '[Ff][Oo][Oo]',
0fc0: 20 62 75 74 20 27 42 61 72 27 20 62 65 63 6f 6d   but 'Bar' becom
0fd0: 65 73 20 27 42 5b 41 61 5d 5b 52 72 5d 27 2e 22  es 'B[Aa][Rr]'."
0fe0: 0a 20 20 20 20 73 55 70 20 3d 20 22 22 0a 20 20  .    sUp = "".  
0ff0: 20 20 6e 53 74 61 74 65 20 3d 20 30 0a 20 20 20    nState = 0.   
1000: 20 66 6f 72 20 69 2c 20 63 20 69 6e 20 65 6e 75   for i, c in enu
1010: 6d 65 72 61 74 65 28 73 54 65 78 74 29 3a 0a 20  merate(sText):. 
1020: 20 20 20 20 20 20 20 69 66 20 63 20 3d 3d 20 22         if c == "
1030: 5b 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  [":.            
1040: 6e 53 74 61 74 65 20 3d 20 31 0a 20 20 20 20 20  nState = 1.     
1050: 20 20 20 69 66 20 6e 53 74 61 74 65 20 3d 3d 20     if nState == 
1060: 31 20 61 6e 64 20 63 20 3d 3d 20 22 5d 22 3a 0a  1 and c == "]":.
1070: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
1080: 74 65 20 3d 20 30 0a 20 20 20 20 20 20 20 20 69  te = 0.        i
1090: 66 20 63 20 3d 3d 20 22 3c 22 20 61 6e 64 20 69  f c == "<" and i
10a0: 20 3e 20 33 20 61 6e 64 20 73 54 65 78 74 5b 69   > 3 and sText[i
10b0: 2d 33 3a 69 5d 20 3d 3d 20 22 28 3f 50 22 3a 0a  -3:i] == "(?P":.
10c0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
10d0: 74 65 20 3d 20 32 0a 20 20 20 20 20 20 20 20 69  te = 2.        i
10e0: 66 20 6e 53 74 61 74 65 20 3d 3d 20 32 20 61 6e  f nState == 2 an
10f0: 64 20 63 20 3d 3d 20 22 3e 22 3a 0a 20 20 20 20  d c == ">":.    
1100: 20 20 20 20 20 20 20 20 6e 53 74 61 74 65 20 3d          nState =
1110: 20 30 0a 20 20 20 20 20 20 20 20 69 66 20 63 20   0.        if c 
1120: 3d 3d 20 22 3f 22 20 61 6e 64 20 69 20 3e 20 30  == "?" and i > 0
1130: 20 61 6e 64 20 73 54 65 78 74 5b 69 2d 31 3a 69   and sText[i-1:i
1140: 5d 20 3d 3d 20 22 28 22 20 61 6e 64 20 73 54 65  ] == "(" and sTe
1150: 78 74 5b 69 2b 31 3a 69 2b 32 5d 20 21 3d 20 22  xt[i+1:i+2] != "
1160: 3a 22 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  :":.            
1170: 6e 53 74 61 74 65 20 3d 20 35 0a 20 20 20 20 20  nState = 5.     
1180: 20 20 20 69 66 20 6e 53 74 61 74 65 20 3d 3d 20     if nState == 
1190: 35 20 61 6e 64 20 63 20 3d 3d 20 22 29 22 3a 0a  5 and c == ")":.
11a0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
11b0: 74 65 20 3d 20 30 0a 20 20 20 20 20 20 20 20 69  te = 0.        i
11c0: 66 20 63 2e 69 73 61 6c 70 68 61 28 29 20 61 6e  f c.isalpha() an
11d0: 64 20 63 2e 69 73 6c 6f 77 65 72 28 29 20 61 6e  d c.islower() an
11e0: 64 20 6e 53 74 61 74 65 20 3d 3d 20 30 3a 0a 20  d nState == 0:. 
11f0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 63 20             if c 
1200: 3d 3d 20 22 69 22 20 61 6e 64 20 73 4c 61 6e 67  == "i" and sLang
1210: 20 69 6e 20 28 22 74 72 22 2c 20 22 61 7a 22 29   in ("tr", "az")
1220: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1230: 20 20 73 55 70 20 2b 3d 20 22 5b c4 b0 22 20 2b    sUp += "[.." +
1240: 20 63 20 2b 20 22 5d 22 0a 20 20 20 20 20 20 20   c + "]".       
1250: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
1260: 20 20 20 20 20 20 20 20 20 20 20 73 55 70 20 2b             sUp +
1270: 3d 20 22 5b 22 20 2b 20 63 2e 75 70 70 65 72 28  = "[" + c.upper(
1280: 29 20 2b 20 63 20 2b 20 22 5d 22 0a 20 20 20 20  ) + c + "]".    
1290: 20 20 20 20 65 6c 69 66 20 63 2e 69 73 61 6c 70      elif c.isalp
12a0: 68 61 28 29 20 61 6e 64 20 63 2e 69 73 6c 6f 77  ha() and c.islow
12b0: 65 72 28 29 20 61 6e 64 20 6e 53 74 61 74 65 20  er() and nState 
12c0: 3d 3d 20 31 20 61 6e 64 20 73 54 65 78 74 5b 69  == 1 and sText[i
12d0: 2b 31 3a 69 2b 32 5d 20 21 3d 20 22 2d 22 3a 0a  +1:i+2] != "-":.
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73              if s
12f0: 54 65 78 74 5b 69 2d 31 3a 69 5d 20 3d 3d 20 22  Text[i-1:i] == "
1300: 2d 22 20 61 6e 64 20 73 54 65 78 74 5b 69 2d 32  -" and sText[i-2
1310: 3a 69 2d 31 5d 2e 69 73 6c 6f 77 65 72 28 29 3a  :i-1].islower():
1320: 20 20 23 20 5b 61 2d 7a 5d 20 2d 3e 20 5b 61 2d    # [a-z] -> [a-
1330: 7a 41 2d 5a 5d 0a 20 20 20 20 20 20 20 20 20 20  zA-Z].          
1340: 20 20 20 20 20 20 73 55 70 20 2b 3d 20 63 20 2b        sUp += c +
1350: 20 73 54 65 78 74 5b 69 2d 32 3a 69 2d 31 5d 2e   sText[i-2:i-1].
1360: 75 70 70 65 72 28 29 20 2b 20 22 2d 22 20 2b 20  upper() + "-" + 
1370: 63 2e 75 70 70 65 72 28 29 0a 20 20 20 20 20 20  c.upper().      
1380: 20 20 20 20 20 20 65 6c 69 66 20 63 20 3d 3d 20        elif c == 
1390: 22 69 22 20 61 6e 64 20 73 4c 61 6e 67 20 69 6e  "i" and sLang in
13a0: 20 28 22 74 72 22 2c 20 22 61 7a 22 29 3a 0a 20   ("tr", "az"):. 
13b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
13c0: 55 70 20 2b 3d 20 22 c4 b0 22 20 2b 20 63 0a 20  Up += ".." + c. 
13d0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
13e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
13f0: 20 73 55 70 20 2b 3d 20 63 2e 75 70 70 65 72 28   sUp += c.upper(
1400: 29 20 2b 20 63 0a 20 20 20 20 20 20 20 20 65 6c  ) + c.        el
1410: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
1420: 73 55 70 20 2b 3d 20 63 0a 20 20 20 20 20 20 20  sUp += c.       
1430: 20 69 66 20 63 20 3d 3d 20 22 5c 5c 22 3a 0a 20   if c == "\\":. 
1440: 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61 74             nStat
1450: 65 20 3d 20 34 0a 20 20 20 20 20 20 20 20 65 6c  e = 4.        el
1460: 69 66 20 6e 53 74 61 74 65 20 3d 3d 20 34 3a 0a  if nState == 4:.
1470: 20 20 20 20 20 20 20 20 20 20 20 20 6e 53 74 61              nSta
1480: 74 65 20 3d 20 30 0a 20 20 20 20 72 65 74 75 72  te = 0.    retur
1490: 6e 20 73 55 70 0a 0a 0a 64 65 66 20 63 6f 75 6e  n sUp...def coun
14a0: 74 47 72 6f 75 70 49 6e 52 65 67 65 78 20 28 73  tGroupInRegex (s
14b0: 52 65 67 65 78 29 3a 0a 20 20 20 20 22 72 65 74  Regex):.    "ret
14c0: 75 72 6e 73 20 74 68 65 20 6e 75 6d 62 65 72 20  urns the number 
14d0: 6f 66 20 67 72 6f 75 70 73 20 69 6e 20 3c 73 52  of groups in <sR
14e0: 65 67 65 78 3e 22 0a 20 20 20 20 74 72 79 3a 0a  egex>".    try:.
14f0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72          return r
1500: 65 2e 63 6f 6d 70 69 6c 65 28 73 52 65 67 65 78  e.compile(sRegex
1510: 29 2e 67 72 6f 75 70 73 0a 20 20 20 20 65 78 63  ).groups.    exc
1520: 65 70 74 20 72 65 2e 65 72 72 6f 72 3a 0a 20 20  ept re.error:.  
1530: 20 20 20 20 20 20 74 72 61 63 65 62 61 63 6b 2e        traceback.
1540: 70 72 69 6e 74 5f 65 78 63 28 29 0a 20 20 20 20  print_exc().    
1550: 20 20 20 20 70 72 69 6e 74 28 73 52 65 67 65 78      print(sRegex
1560: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 30 0a 0a  ).    return 0..
1570: 0a 64 65 66 20 63 72 65 61 74 65 52 75 6c 65 20  .def createRule 
1580: 28 73 2c 20 6e 49 64 4c 69 6e 65 2c 20 73 4c 61  (s, nIdLine, sLa
1590: 6e 67 2c 20 62 50 61 72 61 67 72 61 70 68 2c 20  ng, bParagraph, 
15a0: 64 4f 70 74 50 72 69 6f 72 69 74 79 29 3a 0a 20  dOptPriority):. 
15b0: 20 20 20 22 72 65 74 75 72 6e 73 20 72 75 6c 65     "returns rule
15c0: 20 61 73 20 6c 69 73 74 20 5b 6f 70 74 69 6f 6e   as list [option
15d0: 20 6e 61 6d 65 2c 20 72 65 67 65 78 2c 20 62 43   name, regex, bC
15e0: 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65 2c 20  aseInsensitive, 
15f0: 69 64 65 6e 74 69 66 69 65 72 2c 20 6c 69 73 74  identifier, list
1600: 20 6f 66 20 61 63 74 69 6f 6e 73 5d 22 0a 20 20   of actions]".  
1610: 20 20 67 6c 6f 62 61 6c 20 64 4a 53 52 45 47 45    global dJSREGE
1620: 58 45 53 0a 20 20 20 20 67 6c 6f 62 61 6c 20 6e  XES.    global n
1630: 52 55 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45 0a  RULEWITHOUTNAME.
1640: 0a 20 20 20 20 73 4c 69 6e 65 49 64 20 3d 20 22  .    sLineId = "
1650: 23 22 20 2b 20 73 74 72 28 6e 49 64 4c 69 6e 65  #" + str(nIdLine
1660: 29 20 2b 20 28 22 70 22 20 69 66 20 62 50 61 72  ) + ("p" if bPar
1670: 61 67 72 61 70 68 20 65 6c 73 65 20 22 73 22 29  agraph else "s")
1680: 0a 20 20 20 20 73 52 75 6c 65 49 64 20 3d 20 73  .    sRuleId = s
1690: 4c 69 6e 65 49 64 0a 0a 20 20 20 20 23 23 23 23  LineId..    ####
16a0: 20 47 52 41 50 48 20 43 41 4c 4c 0a 20 20 20 20   GRAPH CALL.    
16b0: 69 66 20 73 2e 73 74 61 72 74 73 77 69 74 68 28  if s.startswith(
16c0: 22 40 40 40 40 22 29 3a 0a 20 20 20 20 20 20 20  "@@@@"):.       
16d0: 20 69 66 20 62 50 61 72 61 67 72 61 70 68 3a 0a   if bParagraph:.
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
16f0: 74 28 22 45 72 72 6f 72 2e 20 47 72 61 70 68 20  t("Error. Graph 
1700: 63 61 6c 6c 20 63 61 6e 20 62 65 20 6d 61 64 65  call can be made
1710: 20 6f 6e 6c 79 20 61 66 74 65 72 20 74 68 65 20   only after the 
1720: 66 69 72 73 74 20 70 61 73 73 20 28 73 65 6e 74  first pass (sent
1730: 65 6e 63 65 20 62 79 20 73 65 6e 74 65 6e 63 65  ence by sentence
1740: 29 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  )").            
1750: 65 78 69 74 28 29 0a 20 20 20 20 20 20 20 20 72  exit().        r
1760: 65 74 75 72 6e 20 5b 22 40 40 40 40 22 2c 20 73  eturn ["@@@@", s
1770: 5b 34 3a 5d 2c 20 73 4c 69 6e 65 49 64 5d 0a 0a  [4:], sLineId]..
1780: 20 20 20 20 23 23 23 23 20 4f 50 54 49 4f 4e 53      #### OPTIONS
1790: 0a 20 20 20 20 73 4f 70 74 69 6f 6e 20 3d 20 46  .    sOption = F
17a0: 61 6c 73 65 20 20 20 20 20 20 20 20 20 23 20 46  alse         # F
17b0: 61 6c 73 65 20 6f 72 20 5b 61 2d 7a 30 2d 39 5d  alse or [a-z0-9]
17c0: 2b 20 6e 61 6d 65 0a 20 20 20 20 6e 50 72 69 6f  + name.    nPrio
17d0: 72 69 74 79 20 3d 20 34 20 20 20 20 20 20 20 20  rity = 4        
17e0: 20 20 20 23 20 44 65 66 61 75 6c 74 20 69 73 20     # Default is 
17f0: 34 2c 20 76 61 6c 75 65 20 6d 75 73 74 20 62 65  4, value must be
1800: 20 62 65 74 77 65 65 6e 20 30 20 61 6e 64 20 39   between 0 and 9
1810: 0a 20 20 20 20 74 47 72 6f 75 70 73 20 3d 20 4e  .    tGroups = N
1820: 6f 6e 65 20 20 20 20 20 20 20 20 20 20 23 20 63  one          # c
1830: 6f 64 65 20 66 6f 72 20 67 72 6f 75 70 73 20 70  ode for groups p
1840: 6f 73 69 74 69 6f 6e 69 6e 67 20 28 6f 6e 6c 79  ositioning (only
1850: 20 75 73 65 66 75 6c 20 66 6f 72 20 4a 61 76 61   useful for Java
1860: 53 63 72 69 70 74 29 0a 20 20 20 20 63 43 61 73  Script).    cCas
1870: 65 4d 6f 64 65 20 3d 20 27 69 27 20 20 20 20 20  eMode = 'i'     
1880: 20 20 20 20 23 20 69 3a 20 63 61 73 65 20 69 6e      # i: case in
1890: 73 65 6e 73 69 74 69 76 65 2c 20 20 73 3a 20 63  sensitive,  s: c
18a0: 61 73 65 20 73 65 6e 73 69 74 69 76 65 2c 20 20  ase sensitive,  
18b0: 75 3a 20 75 70 70 65 72 63 61 73 69 6e 67 20 61  u: uppercasing a
18c0: 6c 6c 6f 77 65 64 0a 20 20 20 20 63 57 6f 72 64  llowed.    cWord
18d0: 4c 69 6d 69 74 4c 65 66 74 20 3d 20 27 5b 27 20  LimitLeft = '[' 
18e0: 20 20 20 23 20 5b 3a 20 77 6f 72 64 20 6c 69 6d     # [: word lim
18f0: 69 74 2c 20 3c 3a 20 6e 6f 20 73 70 65 63 69 66  it, <: no specif
1900: 69 63 20 6c 69 6d 69 74 0a 20 20 20 20 63 57 6f  ic limit.    cWo
1910: 72 64 4c 69 6d 69 74 52 69 67 68 74 20 3d 20 27  rdLimitRight = '
1920: 5d 27 20 20 20 23 20 5d 3a 20 77 6f 72 64 20 6c  ]'   # ]: word l
1930: 69 6d 69 74 2c 20 3e 3a 20 6e 6f 20 73 70 65 63  imit, >: no spec
1940: 69 66 69 63 20 6c 69 6d 69 74 0a 20 20 20 20 6d  ific limit.    m
1950: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 5e 5f 5f   = re.match("^__
1960: 28 3f 50 3c 62 6f 72 64 65 72 73 5f 61 6e 64 5f  (?P<borders_and_
1970: 63 61 73 65 3e 5b 5c 5c 5b 3c 5d 5c 5c 77 5b 5c  case>[\\[<]\\w[\
1980: 5c 5d 3e 5d 29 28 3f 50 3c 6f 70 74 69 6f 6e 3e  \]>])(?P<option>
1990: 2f 5b 61 2d 7a 41 2d 5a 30 2d 39 5d 2b 7c 29 28  /[a-zA-Z0-9]+|)(
19a0: 3f 50 3c 72 75 6c 65 69 64 3e 5c 5c 28 5c 5c 77  ?P<ruleid>\\(\\w
19b0: 2b 5c 5c 29 7c 29 28 3f 50 3c 70 72 69 6f 72 69  +\\)|)(?P<priori
19c0: 74 79 3e 21 5b 30 2d 39 5d 7c 29 5f 5f 20 2a 22  ty>![0-9]|)__ *"
19d0: 2c 20 73 29 0a 20 20 20 20 69 66 20 6d 3a 0a 20  , s).    if m:. 
19e0: 20 20 20 20 20 20 20 63 57 6f 72 64 4c 69 6d 69         cWordLimi
19f0: 74 4c 65 66 74 20 3d 20 6d 2e 67 72 6f 75 70 28  tLeft = m.group(
1a00: 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f 63 61 73  'borders_and_cas
1a10: 65 27 29 5b 30 5d 0a 20 20 20 20 20 20 20 20 63  e')[0].        c
1a20: 43 61 73 65 4d 6f 64 65 20 3d 20 6d 2e 67 72 6f  CaseMode = m.gro
1a30: 75 70 28 27 62 6f 72 64 65 72 73 5f 61 6e 64 5f  up('borders_and_
1a40: 63 61 73 65 27 29 5b 31 5d 0a 20 20 20 20 20 20  case')[1].      
1a50: 20 20 63 57 6f 72 64 4c 69 6d 69 74 52 69 67 68    cWordLimitRigh
1a60: 74 20 3d 20 6d 2e 67 72 6f 75 70 28 27 62 6f 72  t = m.group('bor
1a70: 64 65 72 73 5f 61 6e 64 5f 63 61 73 65 27 29 5b  ders_and_case')[
1a80: 32 5d 0a 20 20 20 20 20 20 20 20 73 4f 70 74 69  2].        sOpti
1a90: 6f 6e 20 3d 20 6d 2e 67 72 6f 75 70 28 27 6f 70  on = m.group('op
1aa0: 74 69 6f 6e 27 29 5b 31 3a 5d 20 20 69 66 20 6d  tion')[1:]  if m
1ab0: 2e 67 72 6f 75 70 28 27 6f 70 74 69 6f 6e 27 29  .group('option')
1ac0: 20 20 65 6c 73 65 20 46 61 6c 73 65 0a 20 20 20    else False.   
1ad0: 20 20 20 20 20 69 66 20 6d 2e 67 72 6f 75 70 28       if m.group(
1ae0: 27 72 75 6c 65 69 64 27 29 3a 0a 20 20 20 20 20  'ruleid'):.     
1af0: 20 20 20 20 20 20 20 73 52 75 6c 65 49 64 20 3d         sRuleId =
1b00: 20 20 6d 2e 67 72 6f 75 70 28 27 72 75 6c 65 69    m.group('rulei
1b10: 64 27 29 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20  d')[1:-1].      
1b20: 20 20 20 20 20 20 69 66 20 73 52 75 6c 65 49 64        if sRuleId
1b30: 20 69 6e 20 61 52 55 4c 45 53 45 54 3a 0a 20 20   in aRULESET:.  
1b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
1b50: 69 6e 74 28 22 23 20 45 72 72 6f 72 2e 20 53 65  int("# Error. Se
1b60: 76 65 72 61 6c 20 72 75 6c 65 73 20 68 61 76 65  veral rules have
1b70: 20 74 68 65 20 73 61 6d 65 20 69 64 3a 20 22 20   the same id: " 
1b80: 2b 20 73 52 75 6c 65 49 64 29 0a 20 20 20 20 20  + sRuleId).     
1b90: 20 20 20 20 20 20 20 20 20 20 20 65 78 69 74 28             exit(
1ba0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 52  ).            aR
1bb0: 55 4c 45 53 45 54 2e 61 64 64 28 73 52 75 6c 65  ULESET.add(sRule
1bc0: 49 64 29 0a 20 20 20 20 20 20 20 20 65 6c 73 65  Id).        else
1bd0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 52  :.            nR
1be0: 55 4c 45 57 49 54 48 4f 55 54 4e 41 4d 45 20 2b  ULEWITHOUTNAME +
1bf0: 3d 20 31 0a 20 20 20 20 20 20 20 20 6e 50 72 69  = 1.        nPri
1c00: 6f 72 69 74 79 20 3d 20 64 4f 70 74 50 72 69 6f  ority = dOptPrio
1c10: 72 69 74 79 2e 67 65 74 28 73 4f 70 74 69 6f 6e  rity.get(sOption
1c20: 2c 20 34 29 0a 20 20 20 20 20 20 20 20 69 66 20  , 4).        if 
1c30: 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f 72 69 74  m.group('priorit
1c40: 79 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  y'):.           
1c50: 20 6e 50 72 69 6f 72 69 74 79 20 3d 20 69 6e 74   nPriority = int
1c60: 28 6d 2e 67 72 6f 75 70 28 27 70 72 69 6f 72 69  (m.group('priori
1c70: 74 79 27 29 5b 31 3a 5d 29 0a 20 20 20 20 20 20  ty')[1:]).      
1c80: 20 20 73 20 3d 20 73 5b 6d 2e 65 6e 64 28 30 29    s = s[m.end(0)
1c90: 3a 5d 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20  :].    else:.   
1ca0: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 57 61       print("# Wa
1cb0: 72 6e 69 6e 67 2e 20 4e 6f 20 6f 70 74 69 6f 6e  rning. No option
1cc0: 20 64 65 66 69 6e 65 64 20 61 74 20 6c 69 6e 65   defined at line
1cd0: 3a 20 22 20 2b 20 73 4c 69 6e 65 49 64 29 0a 0a  : " + sLineId)..
1ce0: 20 20 20 20 23 23 23 23 20 52 45 47 45 58 20 54      #### REGEX T
1cf0: 52 49 47 47 45 52 0a 20 20 20 20 69 20 3d 20 73  RIGGER.    i = s
1d00: 2e 66 69 6e 64 28 22 20 3c 3c 2d 22 29 0a 20 20  .find(" <<-").  
1d10: 20 20 69 66 20 69 20 3d 3d 20 2d 31 3a 0a 20 20    if i == -1:.  
1d20: 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45        print("# E
1d30: 72 72 6f 72 3a 20 6e 6f 20 63 6f 6e 64 69 74 69  rror: no conditi
1d40: 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  on at line " + s
1d50: 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20 20  LineId).        
1d60: 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20 20 20 20  return None.    
1d70: 73 52 65 67 65 78 20 3d 20 73 5b 3a 69 5d 2e 73  sRegex = s[:i].s
1d80: 74 72 69 70 28 29 0a 20 20 20 20 73 20 3d 20 73  trip().    s = s
1d90: 5b 69 2b 34 3a 5d 0a 0a 20 20 20 20 23 20 4a 53  [i+4:]..    # JS
1da0: 20 67 72 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e   groups position
1db0: 69 6e 67 20 63 6f 64 65 73 0a 20 20 20 20 6d 20  ing codes.    m 
1dc0: 3d 20 72 65 2e 73 65 61 72 63 68 28 22 40 40 5c  = re.search("@@\
1dd0: 5c 53 2b 22 2c 20 73 52 65 67 65 78 29 0a 20 20  \S+", sRegex).  
1de0: 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20 20 20    if m:.        
1df0: 74 47 72 6f 75 70 73 20 3d 20 6a 73 63 6f 6e 76  tGroups = jsconv
1e00: 2e 67 72 6f 75 70 73 50 6f 73 69 74 69 6f 6e 69  .groupsPositioni
1e10: 6e 67 43 6f 64 65 54 6f 4c 69 73 74 28 73 52 65  ngCodeToList(sRe
1e20: 67 65 78 5b 6d 2e 73 74 61 72 74 28 29 2b 32 3a  gex[m.start()+2:
1e30: 5d 29 0a 20 20 20 20 20 20 20 20 73 52 65 67 65  ]).        sRege
1e40: 78 20 3d 20 73 52 65 67 65 78 5b 3a 6d 2e 73 74  x = sRegex[:m.st
1e50: 61 72 74 28 29 5d 2e 73 74 72 69 70 28 29 0a 20  art()].strip(). 
1e60: 20 20 20 23 20 4a 53 20 72 65 67 65 78 0a 20 20     # JS regex.  
1e70: 20 20 6d 20 3d 20 72 65 2e 73 65 61 72 63 68 28    m = re.search(
1e80: 22 3c 6a 73 3e 2e 2b 3c 2f 6a 73 3e 69 3f 22 2c  "<js>.+</js>i?",
1e90: 20 73 52 65 67 65 78 29 0a 20 20 20 20 69 66 20   sRegex).    if 
1ea0: 6d 3a 0a 20 20 20 20 20 20 20 20 64 4a 53 52 45  m:.        dJSRE
1eb0: 47 45 58 45 53 5b 73 4c 69 6e 65 49 64 5d 20 3d  GEXES[sLineId] =
1ec0: 20 6d 2e 67 72 6f 75 70 28 30 29 0a 20 20 20 20   m.group(0).    
1ed0: 20 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65      sRegex = sRe
1ee0: 67 65 78 5b 3a 6d 2e 73 74 61 72 74 28 29 5d 2e  gex[:m.start()].
1ef0: 73 74 72 69 70 28 29 0a 20 20 20 20 69 66 20 22  strip().    if "
1f00: 3c 6a 73 3e 22 20 69 6e 20 73 52 65 67 65 78 20  <js>" in sRegex 
1f10: 6f 72 20 22 3c 2f 6a 73 3e 22 20 69 6e 20 73 52  or "</js>" in sR
1f20: 65 67 65 78 3a 0a 20 20 20 20 20 20 20 20 70 72  egex:.        pr
1f30: 69 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 4a 61  int("# Error: Ja
1f40: 76 61 53 63 72 69 70 74 20 72 65 67 65 78 20 6e  vaScript regex n
1f50: 6f 74 20 64 65 6c 69 6d 69 74 65 64 20 61 74 20  ot delimited at 
1f60: 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49 64  line " + sLineId
1f70: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
1f80: 20 4e 6f 6e 65 0a 0a 20 20 20 20 23 20 71 75 6f   None..    # quo
1f90: 74 65 73 20 3f 0a 20 20 20 20 69 66 20 73 52 65  tes ?.    if sRe
1fa0: 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28 27  gex.startswith('
1fb0: 22 27 29 20 61 6e 64 20 73 52 65 67 65 78 2e 65  "') and sRegex.e
1fc0: 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20 20  ndswith('"'):.  
1fd0: 20 20 20 20 20 20 73 52 65 67 65 78 20 3d 20 73        sRegex = s
1fe0: 52 65 67 65 78 5b 31 3a 2d 31 5d 0a 0a 20 20 20  Regex[1:-1]..   
1ff0: 20 23 23 20 64 65 66 69 6e 69 74 69 6f 6e 73 0a   ## definitions.
2000: 20 20 20 20 66 6f 72 20 73 44 65 66 2c 20 73 52      for sDef, sR
2010: 65 70 6c 20 69 6e 20 64 44 45 46 2e 69 74 65 6d  epl in dDEF.item
2020: 73 28 29 3a 0a 20 20 20 20 20 20 20 20 73 52 65  s():.        sRe
2030: 67 65 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70  gex = sRegex.rep
2040: 6c 61 63 65 28 73 44 65 66 2c 20 73 52 65 70 6c  lace(sDef, sRepl
2050: 29 0a 0a 20 20 20 20 23 23 20 63 6f 75 6e 74 20  )..    ## count 
2060: 6e 75 6d 62 65 72 20 6f 66 20 67 72 6f 75 70 73  number of groups
2070: 20 28 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 62   (must be done b
2080: 65 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20  efore modifying 
2090: 74 68 65 20 72 65 67 65 78 29 0a 20 20 20 20 6e  the regex).    n
20a0: 47 72 6f 75 70 20 3d 20 63 6f 75 6e 74 47 72 6f  Group = countGro
20b0: 75 70 49 6e 52 65 67 65 78 28 73 52 65 67 65 78  upInRegex(sRegex
20c0: 29 0a 20 20 20 20 69 66 20 6e 47 72 6f 75 70 20  ).    if nGroup 
20d0: 3e 20 30 3a 0a 20 20 20 20 20 20 20 20 69 66 20  > 0:.        if 
20e0: 6e 6f 74 20 74 47 72 6f 75 70 73 3a 0a 20 20 20  not tGroups:.   
20f0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22           print("
2100: 23 20 57 61 72 6e 69 6e 67 3a 20 67 72 6f 75 70  # Warning: group
2110: 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67 20 63 6f  s positioning co
2120: 64 65 20 66 6f 72 20 4a 61 76 61 53 63 72 69 70  de for JavaScrip
2130: 74 20 73 68 6f 75 6c 64 20 62 65 20 64 65 66 69  t should be defi
2140: 6e 65 64 20 61 74 20 6c 69 6e 65 20 22 20 2b 20  ned at line " + 
2150: 73 4c 69 6e 65 49 64 29 0a 20 20 20 20 20 20 20  sLineId).       
2160: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
2170: 20 20 20 69 66 20 6e 47 72 6f 75 70 20 21 3d 20     if nGroup != 
2180: 6c 65 6e 28 74 47 72 6f 75 70 73 29 3a 0a 20 20  len(tGroups):.  
2190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72                pr
21a0: 69 6e 74 28 22 23 20 45 72 72 6f 72 3a 20 67 72  int("# Error: gr
21b0: 6f 75 70 73 20 70 6f 73 69 74 69 6f 6e 69 6e 67  oups positioning
21c0: 20 63 6f 64 65 20 69 72 72 65 6c 65 76 61 6e 74   code irrelevant
21d0: 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69   at line " + sLi
21e0: 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 20 77 6f  neId)..    ## wo
21f0: 72 64 20 6c 69 6d 69 74 0a 20 20 20 20 69 66 20  rd limit.    if 
2200: 63 57 6f 72 64 4c 69 6d 69 74 4c 65 66 74 20 3d  cWordLimitLeft =
2210: 3d 20 27 5b 27 20 61 6e 64 20 6e 6f 74 20 73 52  = '[' and not sR
2220: 65 67 65 78 2e 73 74 61 72 74 73 77 69 74 68 28  egex.startswith(
2230: 28 22 5e 22 2c 20 27 e2 80 99 27 2c 20 22 27 22  ("^", '...', "'"
2240: 2c 20 22 2c 22 29 29 3a 0a 20 20 20 20 20 20 20  , ",")):.       
2250: 20 73 52 65 67 65 78 20 3d 20 73 57 4f 52 44 4c   sRegex = sWORDL
2260: 49 4d 49 54 4c 45 46 54 20 2b 20 73 52 65 67 65  IMITLEFT + sRege
2270: 78 0a 20 20 20 20 69 66 20 63 57 6f 72 64 4c 69  x.    if cWordLi
2280: 6d 69 74 52 69 67 68 74 20 3d 3d 20 27 5d 27 20  mitRight == ']' 
2290: 61 6e 64 20 6e 6f 74 20 73 52 65 67 65 78 2e 65  and not sRegex.e
22a0: 6e 64 73 77 69 74 68 28 28 22 24 22 2c 20 27 e2  ndswith(("$", '.
22b0: 80 99 27 2c 20 22 27 22 2c 20 22 2c 22 29 29 3a  ..', "'", ",")):
22c0: 0a 20 20 20 20 20 20 20 20 73 52 65 67 65 78 20  .        sRegex 
22d0: 3d 20 73 52 65 67 65 78 20 2b 20 73 57 4f 52 44  = sRegex + sWORD
22e0: 4c 49 4d 49 54 52 49 47 48 54 0a 0a 20 20 20 20  LIMITRIGHT..    
22f0: 23 23 20 63 61 73 69 6e 67 20 6d 6f 64 65 0a 20  ## casing mode. 
2300: 20 20 20 69 66 20 63 43 61 73 65 4d 6f 64 65 20     if cCaseMode 
2310: 3d 3d 20 22 69 22 3a 0a 20 20 20 20 20 20 20 20  == "i":.        
2320: 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69 76 65  bCaseInsensitive
2330: 20 3d 20 54 72 75 65 0a 20 20 20 20 20 20 20 20   = True.        
2340: 69 66 20 6e 6f 74 20 73 52 65 67 65 78 2e 73 74  if not sRegex.st
2350: 61 72 74 73 77 69 74 68 28 22 28 3f 69 29 22 29  artswith("(?i)")
2360: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 52  :.            sR
2370: 65 67 65 78 20 3d 20 22 28 3f 69 29 22 20 2b 20  egex = "(?i)" + 
2380: 73 52 65 67 65 78 0a 20 20 20 20 65 6c 69 66 20  sRegex.    elif 
2390: 63 43 61 73 65 4d 6f 64 65 20 3d 3d 20 22 73 22  cCaseMode == "s"
23a0: 3a 0a 20 20 20 20 20 20 20 20 62 43 61 73 65 49  :.        bCaseI
23b0: 6e 73 65 6e 73 69 74 69 76 65 20 3d 20 46 61 6c  nsensitive = Fal
23c0: 73 65 0a 20 20 20 20 20 20 20 20 73 52 65 67 65  se.        sRege
23d0: 78 20 3d 20 73 52 65 67 65 78 2e 72 65 70 6c 61  x = sRegex.repla
23e0: 63 65 28 22 28 3f 69 29 22 2c 20 22 22 29 0a 20  ce("(?i)", ""). 
23f0: 20 20 20 65 6c 69 66 20 63 43 61 73 65 4d 6f 64     elif cCaseMod
2400: 65 20 3d 3d 20 22 75 22 3a 0a 20 20 20 20 20 20  e == "u":.      
2410: 20 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74 69    bCaseInsensiti
2420: 76 65 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20  ve = False.     
2430: 20 20 20 73 52 65 67 65 78 20 3d 20 73 52 65 67     sRegex = sReg
2440: 65 78 2e 72 65 70 6c 61 63 65 28 22 28 3f 69 29  ex.replace("(?i)
2450: 22 2c 20 22 22 29 0a 20 20 20 20 20 20 20 20 73  ", "").        s
2460: 52 65 67 65 78 20 3d 20 75 70 70 65 72 63 61 73  Regex = uppercas
2470: 65 28 73 52 65 67 65 78 2c 20 73 4c 61 6e 67 29  e(sRegex, sLang)
2480: 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20  .    else:.     
2490: 20 20 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e     print("# Unkn
24a0: 6f 77 6e 20 63 61 73 65 20 6d 6f 64 65 20 5b 22  own case mode ["
24b0: 20 2b 20 63 43 61 73 65 4d 6f 64 65 20 2b 20 22   + cCaseMode + "
24c0: 5d 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 4c  ] at line " + sL
24d0: 69 6e 65 49 64 29 0a 0a 20 20 20 20 23 23 20 63  ineId)..    ## c
24e0: 68 65 63 6b 20 72 65 67 65 78 0a 20 20 20 20 74  heck regex.    t
24f0: 72 79 3a 0a 20 20 20 20 20 20 20 20 72 65 2e 63  ry:.        re.c
2500: 6f 6d 70 69 6c 65 28 73 52 65 67 65 78 29 0a 20  ompile(sRegex). 
2510: 20 20 20 65 78 63 65 70 74 20 72 65 2e 65 72 72     except re.err
2520: 6f 72 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e  or:.        prin
2530: 74 28 22 23 20 52 65 67 65 78 20 65 72 72 6f 72  t("# Regex error
2540: 20 61 74 20 6c 69 6e 65 20 22 2c 20 6e 49 64 4c   at line ", nIdL
2550: 69 6e 65 29 0a 20 20 20 20 20 20 20 20 70 72 69  ine).        pri
2560: 6e 74 28 73 52 65 67 65 78 29 0a 20 20 20 20 20  nt(sRegex).     
2570: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 20     return None. 
2580: 20 20 20 23 23 20 67 72 6f 75 70 73 20 69 6e 20     ## groups in 
2590: 6e 6f 6e 20 67 72 6f 75 70 69 6e 67 20 70 61 72  non grouping par
25a0: 65 6e 74 68 65 73 69 73 0a 20 20 20 20 66 6f 72  enthesis.    for
25b0: 20 5f 20 69 6e 20 72 65 2e 66 69 6e 64 69 74 65   _ in re.findite
25c0: 72 28 72 22 5c 28 5c 3f 3a 5b 5e 29 5d 2a 5c 28  r(r"\(\?:[^)]*\(
25d0: 5b 5c 5b 5c 77 20 2d 5d 22 2c 20 73 52 65 67 65  [\[\w -]", sRege
25e0: 78 29 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e  x):.        prin
25f0: 74 28 22 23 20 57 61 72 6e 69 6e 67 3a 20 67 72  t("# Warning: gr
2600: 6f 75 70 73 20 69 6e 73 69 64 65 20 6e 6f 6e 20  oups inside non 
2610: 67 72 6f 75 70 69 6e 67 20 70 61 72 65 6e 74 68  grouping parenth
2620: 65 73 69 73 20 69 6e 20 72 65 67 65 78 20 61 74  esis in regex at
2630: 20 6c 69 6e 65 20 22 20 2b 20 73 4c 69 6e 65 49   line " + sLineI
2640: 64 29 0a 0a 20 20 20 20 23 23 23 23 20 50 41 52  d)..    #### PAR
2650: 53 45 20 41 43 54 49 4f 4e 53 0a 20 20 20 20 6c  SE ACTIONS.    l
2660: 41 63 74 69 6f 6e 73 20 3d 20 5b 5d 0a 20 20 20  Actions = [].   
2670: 20 6e 41 63 74 69 6f 6e 20 3d 20 31 0a 20 20 20   nAction = 1.   
2680: 20 66 6f 72 20 73 41 63 74 69 6f 6e 20 69 6e 20   for sAction in 
2690: 73 2e 73 70 6c 69 74 28 22 20 3c 3c 2d 20 22 29  s.split(" <<- ")
26a0: 3a 0a 20 20 20 20 20 20 20 20 74 20 3d 20 63 72  :.        t = cr
26b0: 65 61 74 65 41 63 74 69 6f 6e 28 73 52 75 6c 65  eateAction(sRule
26c0: 49 64 20 2b 20 22 5f 22 20 2b 20 73 74 72 28 6e  Id + "_" + str(n
26d0: 41 63 74 69 6f 6e 29 2c 20 73 41 63 74 69 6f 6e  Action), sAction
26e0: 2c 20 6e 47 72 6f 75 70 29 0a 20 20 20 20 20 20  , nGroup).      
26f0: 20 20 6e 41 63 74 69 6f 6e 20 2b 3d 20 31 0a 20    nAction += 1. 
2700: 20 20 20 20 20 20 20 69 66 20 74 3a 0a 20 20 20         if t:.   
2710: 20 20 20 20 20 20 20 20 20 6c 41 63 74 69 6f 6e           lAction
2720: 73 2e 61 70 70 65 6e 64 28 74 29 0a 20 20 20 20  s.append(t).    
2730: 69 66 20 6e 6f 74 20 6c 41 63 74 69 6f 6e 73 3a  if not lActions:
2740: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
2750: 4e 6f 6e 65 0a 0a 20 20 20 20 72 65 74 75 72 6e  None..    return
2760: 20 5b 73 4f 70 74 69 6f 6e 2c 20 73 52 65 67 65   [sOption, sRege
2770: 78 2c 20 62 43 61 73 65 49 6e 73 65 6e 73 69 74  x, bCaseInsensit
2780: 69 76 65 2c 20 73 4c 69 6e 65 49 64 2c 20 73 52  ive, sLineId, sR
2790: 75 6c 65 49 64 2c 20 6e 50 72 69 6f 72 69 74 79  uleId, nPriority
27a0: 2c 20 6c 41 63 74 69 6f 6e 73 2c 20 74 47 72 6f  , lActions, tGro
27b0: 75 70 73 5d 0a 0a 0a 64 65 66 20 63 68 65 63 6b  ups]...def check
27c0: 52 65 66 65 72 65 6e 63 65 4e 75 6d 62 65 72 73  ReferenceNumbers
27d0: 20 28 73 54 65 78 74 2c 20 73 41 63 74 69 6f 6e   (sText, sAction
27e0: 49 64 2c 20 6e 54 6f 6b 65 6e 29 3a 0a 20 20 20  Id, nToken):.   
27f0: 20 22 63 68 65 63 6b 20 69 66 20 74 6f 6b 65 6e   "check if token
2800: 20 72 65 66 65 72 65 6e 63 65 73 20 69 6e 20 3c   references in <
2810: 73 54 65 78 74 3e 20 67 72 65 61 74 65 72 20 74  sText> greater t
2820: 68 61 6e 20 3c 6e 54 6f 6b 65 6e 3e 20 28 64 65  han <nToken> (de
2830: 62 75 67 67 69 6e 67 29 22 0a 20 20 20 20 66 6f  bugging)".    fo
2840: 72 20 78 20 69 6e 20 72 65 2e 66 69 6e 64 69 74  r x in re.findit
2850: 65 72 28 72 22 5c 5c 28 5c 64 2b 29 22 2c 20 73  er(r"\\(\d+)", s
2860: 54 65 78 74 29 3a 0a 20 20 20 20 20 20 20 20 69  Text):.        i
2870: 66 20 69 6e 74 28 78 2e 67 72 6f 75 70 28 31 29  f int(x.group(1)
2880: 29 20 3e 20 6e 54 6f 6b 65 6e 3a 0a 20 20 20 20  ) > nToken:.    
2890: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
28a0: 20 45 72 72 6f 72 20 69 6e 20 74 6f 6b 65 6e 20   Error in token 
28b0: 69 6e 64 65 78 20 61 74 20 6c 69 6e 65 20 22 20  index at line " 
28c0: 2b 20 73 41 63 74 69 6f 6e 49 64 20 2b 20 22 20  + sActionId + " 
28d0: 28 22 2b 73 74 72 28 6e 54 6f 6b 65 6e 29 2b 22  ("+str(nToken)+"
28e0: 20 74 6f 6b 65 6e 73 20 6f 6e 6c 79 29 22 29 0a   tokens only)").
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
2900: 74 28 73 54 65 78 74 29 0a 0a 0a 64 65 66 20 63  t(sText)...def c
2910: 68 65 63 6b 49 66 54 68 65 72 65 49 73 43 6f 64  heckIfThereIsCod
2920: 65 20 28 73 54 65 78 74 2c 20 73 41 63 74 69 6f  e (sText, sActio
2930: 6e 49 64 29 3a 0a 20 20 20 20 22 63 68 65 63 6b  nId):.    "check
2940: 20 69 66 20 74 68 65 72 65 20 69 73 20 63 6f 64   if there is cod
2950: 65 20 69 6e 20 3c 73 54 65 78 74 3e 20 28 64 65  e in <sText> (de
2960: 62 75 67 67 69 6e 67 29 22 0a 20 20 20 20 69 66  bugging)".    if
2970: 20 72 65 2e 73 65 61 72 63 68 28 22 5b 2e 5d 5c   re.search("[.]\
2980: 5c 77 2b 5b 28 5d 7c 73 75 67 67 5c 5c 77 2b 5b  \w+[(]|sugg\\w+[
2990: 28 5d 7c 5c 5c 28 5b 30 2d 39 5d 7c 5c 5c 5b 5b  (]|\\([0-9]|\\[[
29a0: 30 2d 39 5d 22 2c 20 73 54 65 78 74 29 3a 0a 20  0-9]", sText):. 
29b0: 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23 20         print("# 
29c0: 57 61 72 6e 69 6e 67 20 61 74 20 6c 69 6e 65 20  Warning at line 
29d0: 22 20 2b 20 73 41 63 74 69 6f 6e 49 64 20 2b 20  " + sActionId + 
29e0: 22 3a 20 20 54 68 69 73 20 6d 65 73 73 61 67 65  ":  This message
29f0: 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 63 6f 64 65   looks like code
2a00: 2e 20 4c 69 6e 65 20 73 68 6f 75 6c 64 20 70 72  . Line should pr
2a10: 6f 62 61 62 6c 79 20 62 65 67 69 6e 20 77 69 74  obably begin wit
2a20: 68 20 3d 22 29 0a 20 20 20 20 20 20 20 20 70 72  h =").        pr
2a30: 69 6e 74 28 73 54 65 78 74 29 0a 0a 0a 64 65 66  int(sText)...def
2a40: 20 63 72 65 61 74 65 41 63 74 69 6f 6e 20 28 73   createAction (s
2a50: 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f  IdAction, sActio
2a60: 6e 2c 20 6e 47 72 6f 75 70 29 3a 0a 20 20 20 20  n, nGroup):.    
2a70: 22 72 65 74 75 72 6e 73 20 61 6e 20 61 63 74 69  "returns an acti
2a80: 6f 6e 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 73  on to perform as
2a90: 20 61 20 74 75 70 6c 65 20 28 63 6f 6e 64 69 74   a tuple (condit
2aa0: 69 6f 6e 2c 20 61 63 74 69 6f 6e 20 74 79 70 65  ion, action type
2ab0: 2c 20 61 63 74 69 6f 6e 5b 2c 20 69 47 72 6f 75  , action[, iGrou
2ac0: 70 20 5b 2c 20 6d 65 73 73 61 67 65 2c 20 55 52  p [, message, UR
2ad0: 4c 20 5d 5d 29 22 0a 20 20 20 20 6d 20 3d 20 72  L ]])".    m = r
2ae0: 65 2e 73 65 61 72 63 68 28 72 22 28 5b 2d 7e 3d  e.search(r"([-~=
2af0: 3e 5d 29 28 5c 64 2a 7c 29 3e 3e 22 2c 20 73 41  >])(\d*|)>>", sA
2b00: 63 74 69 6f 6e 29 0a 20 20 20 20 69 66 20 6e 6f  ction).    if no
2b10: 74 20 6d 3a 0a 20 20 20 20 20 20 20 20 70 72 69  t m:.        pri
2b20: 6e 74 28 22 23 20 4e 6f 20 61 63 74 69 6f 6e 20  nt("# No action 
2b30: 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49 64 41  at line " + sIdA
2b40: 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 72  ction).        r
2b50: 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a 20 20 20 20  eturn None..    
2b60: 23 23 23 23 20 43 4f 4e 44 49 54 49 4f 4e 0a 20  #### CONDITION. 
2b70: 20 20 20 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20     sCondition = 
2b80: 73 41 63 74 69 6f 6e 5b 3a 6d 2e 73 74 61 72 74  sAction[:m.start
2b90: 28 29 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20  ()].strip().    
2ba0: 69 66 20 73 43 6f 6e 64 69 74 69 6f 6e 3a 0a 20  if sCondition:. 
2bb0: 20 20 20 20 20 20 20 73 43 6f 6e 64 69 74 69 6f         sConditio
2bc0: 6e 20 3d 20 70 72 65 70 61 72 65 46 75 6e 63 74  n = prepareFunct
2bd0: 69 6f 6e 28 73 43 6f 6e 64 69 74 69 6f 6e 29 0a  ion(sCondition).
2be0: 20 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f          lFUNCTIO
2bf0: 4e 53 2e 61 70 70 65 6e 64 28 28 22 5f 63 5f 22  NS.append(("_c_"
2c00: 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73 43 6f 6e  +sIdAction, sCon
2c10: 64 69 74 69 6f 6e 29 29 0a 20 20 20 20 20 20 20  dition)).       
2c20: 20 63 68 65 63 6b 52 65 66 65 72 65 6e 63 65 4e   checkReferenceN
2c30: 75 6d 62 65 72 73 28 73 43 6f 6e 64 69 74 69 6f  umbers(sConditio
2c40: 6e 2c 20 73 49 64 41 63 74 69 6f 6e 2c 20 6e 47  n, sIdAction, nG
2c50: 72 6f 75 70 29 0a 20 20 20 20 20 20 20 20 69 66  roup).        if
2c60: 20 22 2e 6d 61 74 63 68 22 20 69 6e 20 73 43 6f   ".match" in sCo
2c70: 6e 64 69 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20  ndition:.       
2c80: 20 20 20 20 20 70 72 69 6e 74 28 22 23 20 45 72       print("# Er
2c90: 72 6f 72 2e 20 4a 53 20 63 6f 6d 70 61 74 69 62  ror. JS compatib
2ca0: 69 6c 69 74 79 2e 20 44 6f 6e 27 74 20 75 73 65  ility. Don't use
2cb0: 20 2e 6d 61 74 63 68 28 29 20 69 6e 20 63 6f 6e   .match() in con
2cc0: 64 69 74 69 6f 6e 2c 20 75 73 65 20 2e 73 65 61  dition, use .sea
2cd0: 72 63 68 28 29 22 29 0a 20 20 20 20 20 20 20 20  rch()").        
2ce0: 73 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 22 5f 63  sCondition = "_c
2cf0: 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20 20  _"+sIdAction.   
2d00: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 73   else:.        s
2d10: 43 6f 6e 64 69 74 69 6f 6e 20 3d 20 4e 6f 6e 65  Condition = None
2d20: 0a 0a 20 20 20 20 23 23 23 23 20 69 47 72 6f 75  ..    #### iGrou
2d30: 70 20 2f 20 70 6f 73 69 74 69 6f 6e 69 6e 67 0a  p / positioning.
2d40: 20 20 20 20 69 47 72 6f 75 70 20 3d 20 69 6e 74      iGroup = int
2d50: 28 6d 2e 67 72 6f 75 70 28 32 29 29 20 69 66 20  (m.group(2)) if 
2d60: 6d 2e 67 72 6f 75 70 28 32 29 20 65 6c 73 65 20  m.group(2) else 
2d70: 30 0a 20 20 20 20 69 66 20 69 47 72 6f 75 70 20  0.    if iGroup 
2d80: 3e 20 6e 47 72 6f 75 70 3a 0a 20 20 20 20 20 20  > nGroup:.      
2d90: 20 20 70 72 69 6e 74 28 22 23 20 53 65 6c 65 63    print("# Selec
2da0: 74 65 64 20 67 72 6f 75 70 20 3e 20 67 72 6f 75  ted group > grou
2db0: 70 20 6e 75 6d 62 65 72 20 69 6e 20 72 65 67 65  p number in rege
2dc0: 78 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73 49  x at line " + sI
2dd0: 64 41 63 74 69 6f 6e 29 0a 0a 20 20 20 20 23 23  dAction)..    ##
2de0: 23 23 20 41 43 54 49 4f 4e 0a 20 20 20 20 73 41  ## ACTION.    sA
2df0: 63 74 69 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b  ction = sAction[
2e00: 6d 2e 65 6e 64 28 29 3a 5d 2e 73 74 72 69 70 28  m.end():].strip(
2e10: 29 0a 20 20 20 20 63 41 63 74 69 6f 6e 20 3d 20  ).    cAction = 
2e20: 6d 2e 67 72 6f 75 70 28 31 29 0a 20 20 20 20 69  m.group(1).    i
2e30: 66 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 2d 22  f cAction == "-"
2e40: 3a 0a 20 20 20 20 20 20 20 20 23 23 20 65 72 72  :.        ## err
2e50: 6f 72 0a 20 20 20 20 20 20 20 20 69 4d 73 67 20  or.        iMsg 
2e60: 3d 20 73 41 63 74 69 6f 6e 2e 66 69 6e 64 28 22  = sAction.find("
2e70: 20 23 20 22 29 0a 20 20 20 20 20 20 20 20 69 66   # ").        if
2e80: 20 69 4d 73 67 20 3d 3d 20 2d 31 3a 0a 20 20 20   iMsg == -1:.   
2e90: 20 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20           sMsg = 
2ea0: 22 23 20 45 72 72 6f 72 2e 20 45 72 72 6f 72 20  "# Error. Error 
2eb0: 6d 65 73 73 61 67 65 20 6e 6f 74 20 66 6f 75 6e  message not foun
2ec0: 64 2e 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  d.".            
2ed0: 73 55 52 4c 20 3d 20 22 22 0a 20 20 20 20 20 20  sURL = "".      
2ee0: 20 20 20 20 20 20 70 72 69 6e 74 28 73 4d 73 67        print(sMsg
2ef0: 20 2b 20 22 20 41 63 74 69 6f 6e 20 69 64 3a 20   + " Action id: 
2f00: 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a 20  " + sIdAction). 
2f10: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
2f20: 20 20 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20           sMsg = 
2f30: 73 41 63 74 69 6f 6e 5b 69 4d 73 67 2b 33 3a 5d  sAction[iMsg+3:]
2f40: 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20  .strip().       
2f50: 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73       sAction = s
2f60: 41 63 74 69 6f 6e 5b 3a 69 4d 73 67 5d 2e 73 74  Action[:iMsg].st
2f70: 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20 20  rip().          
2f80: 20 20 73 55 52 4c 20 3d 20 22 22 0a 20 20 20 20    sURL = "".    
2f90: 20 20 20 20 20 20 20 20 6d 55 52 4c 20 3d 20 72          mURL = r
2fa0: 65 2e 73 65 61 72 63 68 28 22 5b 7c 5d 20 2a 28  e.search("[|] *(
2fb0: 68 74 74 70 73 3f 3a 2f 2f 2e 2a 29 22 2c 20 73  https?://.*)", s
2fc0: 4d 73 67 29 0a 20 20 20 20 20 20 20 20 20 20 20  Msg).           
2fd0: 20 69 66 20 6d 55 52 4c 3a 0a 20 20 20 20 20 20   if mURL:.      
2fe0: 20 20 20 20 20 20 20 20 20 20 73 55 52 4c 20 3d            sURL =
2ff0: 20 6d 55 52 4c 2e 67 72 6f 75 70 28 31 29 2e 73   mURL.group(1).s
3000: 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20 20  trip().         
3010: 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 73 4d         sMsg = sM
3020: 73 67 5b 3a 6d 55 52 4c 2e 73 74 61 72 74 28 30  sg[:mURL.start(0
3030: 29 5d 2e 73 74 72 69 70 28 29 0a 20 20 20 20 20  )].strip().     
3040: 20 20 20 20 20 20 20 63 68 65 63 6b 52 65 66 65         checkRefe
3050: 72 65 6e 63 65 4e 75 6d 62 65 72 73 28 73 4d 73  renceNumbers(sMs
3060: 67 2c 20 73 49 64 41 63 74 69 6f 6e 2c 20 6e 47  g, sIdAction, nG
3070: 72 6f 75 70 29 0a 20 20 20 20 20 20 20 20 20 20  roup).          
3080: 20 20 69 66 20 73 4d 73 67 5b 30 3a 31 5d 20 3d    if sMsg[0:1] =
3090: 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 20  = "=":.         
30a0: 20 20 20 20 20 20 20 73 4d 73 67 20 3d 20 70 72         sMsg = pr
30b0: 65 70 61 72 65 46 75 6e 63 74 69 6f 6e 28 73 4d  epareFunction(sM
30c0: 73 67 5b 31 3a 5d 29 0a 20 20 20 20 20 20 20 20  sg[1:]).        
30d0: 20 20 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f          lFUNCTIO
30e0: 4e 53 2e 61 70 70 65 6e 64 28 28 22 5f 6d 5f 22  NS.append(("_m_"
30f0: 2b 73 49 64 41 63 74 69 6f 6e 2c 20 73 4d 73 67  +sIdAction, sMsg
3100: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  )).             
3110: 20 20 20 73 4d 73 67 20 3d 20 22 3d 5f 6d 5f 22     sMsg = "=_m_"
3120: 2b 73 49 64 41 63 74 69 6f 6e 0a 20 20 20 20 20  +sIdAction.     
3130: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
3140: 20 20 20 20 20 20 20 20 20 20 20 20 20 63 68 65               che
3150: 63 6b 49 66 54 68 65 72 65 49 73 43 6f 64 65 28  ckIfThereIsCode(
3160: 73 4d 73 67 2c 20 73 49 64 41 63 74 69 6f 6e 29  sMsg, sIdAction)
3170: 0a 0a 20 20 20 20 63 68 65 63 6b 52 65 66 65 72  ..    checkRefer
3180: 65 6e 63 65 4e 75 6d 62 65 72 73 28 73 41 63 74  enceNumbers(sAct
3190: 69 6f 6e 2c 20 73 49 64 41 63 74 69 6f 6e 2c 20  ion, sIdAction, 
31a0: 6e 47 72 6f 75 70 29 0a 20 20 20 20 69 66 20 73  nGroup).    if s
31b0: 41 63 74 69 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22  Action[0:1] == "
31c0: 3d 22 20 6f 72 20 63 41 63 74 69 6f 6e 20 3d 3d  =" or cAction ==
31d0: 20 22 3d 22 3a 0a 20 20 20 20 20 20 20 20 73 41   "=":.        sA
31e0: 63 74 69 6f 6e 20 3d 20 70 72 65 70 61 72 65 46  ction = prepareF
31f0: 75 6e 63 74 69 6f 6e 28 73 41 63 74 69 6f 6e 29  unction(sAction)
3200: 0a 20 20 20 20 20 20 20 20 73 41 63 74 69 6f 6e  .        sAction
3210: 20 3d 20 73 41 63 74 69 6f 6e 2e 72 65 70 6c 61   = sAction.repla
3220: 63 65 28 22 6d 2e 67 72 6f 75 70 28 69 5b 34 5d  ce("m.group(i[4]
3230: 29 22 2c 20 22 6d 2e 67 72 6f 75 70 28 22 2b 73  )", "m.group("+s
3240: 74 72 28 69 47 72 6f 75 70 29 2b 22 29 22 29 0a  tr(iGroup)+")").
3250: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
3260: 20 20 63 68 65 63 6b 49 66 54 68 65 72 65 49 73    checkIfThereIs
3270: 43 6f 64 65 28 73 41 63 74 69 6f 6e 2c 20 73 49  Code(sAction, sI
3280: 64 41 63 74 69 6f 6e 29 0a 0a 20 20 20 20 69 66  dAction)..    if
3290: 20 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3e 22 3a   cAction == ">":
32a0: 0a 20 20 20 20 20 20 20 20 23 23 20 6e 6f 20 61  .        ## no a
32b0: 63 74 69 6f 6e 2c 20 62 72 65 61 6b 20 6c 6f 6f  ction, break loo
32c0: 70 20 69 66 20 63 6f 6e 64 69 74 69 6f 6e 20 69  p if condition i
32d0: 73 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20 20  s False.        
32e0: 72 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69  return [sConditi
32f0: 6f 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 22 22 5d  on, cAction, ""]
3300: 0a 0a 20 20 20 20 69 66 20 6e 6f 74 20 73 41 63  ..    if not sAc
3310: 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 70 72  tion:.        pr
3320: 69 6e 74 28 22 23 20 45 72 72 6f 72 20 69 6e 20  int("# Error in 
3330: 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65 20 22  action at line "
3340: 20 2b 20 73 49 64 41 63 74 69 6f 6e 20 2b 20 22   + sIdAction + "
3350: 3a 20 20 54 68 69 73 20 61 63 74 69 6f 6e 20 69  :  This action i
3360: 73 20 65 6d 70 74 79 2e 22 29 0a 20 20 20 20 20  s empty.").     
3370: 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a 0a     return None..
3380: 20 20 20 20 69 66 20 63 41 63 74 69 6f 6e 20 3d      if cAction =
3390: 3d 20 22 2d 22 3a 0a 20 20 20 20 20 20 20 20 23  = "-":.        #
33a0: 23 20 65 72 72 6f 72 20 64 65 74 65 63 74 65 64  # error detected
33b0: 20 2d 2d 3e 20 73 75 67 67 65 73 74 69 6f 6e 0a   --> suggestion.
33c0: 20 20 20 20 20 20 20 20 69 66 20 73 41 63 74 69          if sActi
33d0: 6f 6e 5b 30 3a 31 5d 20 3d 3d 20 22 3d 22 3a 0a  on[0:1] == "=":.
33e0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 46 55 4e              lFUN
33f0: 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64 28 28 22  CTIONS.append(("
3400: 5f 73 5f 22 2b 73 49 64 41 63 74 69 6f 6e 2c 20  _s_"+sIdAction, 
3410: 73 41 63 74 69 6f 6e 5b 31 3a 5d 29 29 0a 20 20  sAction[1:])).  
3420: 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69 6f            sActio
3430: 6e 20 3d 20 22 3d 5f 73 5f 22 2b 73 49 64 41 63  n = "=_s_"+sIdAc
3440: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 65 6c 69  tion.        eli
3450: 66 20 73 41 63 74 69 6f 6e 2e 73 74 61 72 74 73  f sAction.starts
3460: 77 69 74 68 28 27 22 27 29 20 61 6e 64 20 73 41  with('"') and sA
3470: 63 74 69 6f 6e 2e 65 6e 64 73 77 69 74 68 28 27  ction.endswith('
3480: 22 27 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  "'):.           
3490: 20 73 41 63 74 69 6f 6e 20 3d 20 73 41 63 74 69   sAction = sActi
34a0: 6f 6e 5b 31 3a 2d 31 5d 0a 20 20 20 20 20 20 20  on[1:-1].       
34b0: 20 69 66 20 6e 6f 74 20 73 4d 73 67 3a 0a 20 20   if not sMsg:.  
34c0: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 28            print(
34d0: 22 23 20 45 72 72 6f 72 20 69 6e 20 61 63 74 69  "# Error in acti
34e0: 6f 6e 20 61 74 20 6c 69 6e 65 20 22 20 2b 20 73  on at line " + s
34f0: 49 64 41 63 74 69 6f 6e 20 2b 20 22 3a 20 20 74  IdAction + ":  t
3500: 68 65 20 6d 65 73 73 61 67 65 20 69 73 20 65 6d  he message is em
3510: 70 74 79 2e 22 29 0a 20 20 20 20 20 20 20 20 72  pty.").        r
3520: 65 74 75 72 6e 20 5b 73 43 6f 6e 64 69 74 69 6f  eturn [sConditio
3530: 6e 2c 20 63 41 63 74 69 6f 6e 2c 20 73 41 63 74  n, cAction, sAct
3540: 69 6f 6e 2c 20 69 47 72 6f 75 70 2c 20 73 4d 73  ion, iGroup, sMs
3550: 67 2c 20 73 55 52 4c 5d 0a 20 20 20 20 69 66 20  g, sURL].    if 
3560: 63 41 63 74 69 6f 6e 20 3d 3d 20 22 7e 22 3a 0a  cAction == "~":.
3570: 20 20 20 20 20 20 20 20 23 23 20 74 65 78 74 20          ## text 
3580: 70 72 6f 63 65 73 73 6f 72 0a 20 20 20 20 20 20  processor.      
3590: 20 20 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31    if sAction[0:1
35a0: 5d 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20  ] == "=":.      
35b0: 20 20 20 20 20 20 6c 46 55 4e 43 54 49 4f 4e 53        lFUNCTIONS
35c0: 2e 61 70 70 65 6e 64 28 28 22 5f 70 5f 22 2b 73  .append(("_p_"+s
35d0: 49 64 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f  IdAction, sActio
35e0: 6e 5b 31 3a 5d 29 29 0a 20 20 20 20 20 20 20 20  n[1:])).        
35f0: 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 22 3d      sAction = "=
3600: 5f 70 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20  _p_"+sIdAction. 
3610: 20 20 20 20 20 20 20 65 6c 69 66 20 73 41 63 74         elif sAct
3620: 69 6f 6e 2e 73 74 61 72 74 73 77 69 74 68 28 27  ion.startswith('
3630: 22 27 29 20 61 6e 64 20 73 41 63 74 69 6f 6e 2e  "') and sAction.
3640: 65 6e 64 73 77 69 74 68 28 27 22 27 29 3a 0a 20  endswith('"'):. 
3650: 20 20 20 20 20 20 20 20 20 20 20 73 41 63 74 69             sActi
3660: 6f 6e 20 3d 20 73 41 63 74 69 6f 6e 5b 31 3a 2d  on = sAction[1:-
3670: 31 5d 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  1].        retur
3680: 6e 20 5b 73 43 6f 6e 64 69 74 69 6f 6e 2c 20 63  n [sCondition, c
3690: 41 63 74 69 6f 6e 2c 20 73 41 63 74 69 6f 6e 2c  Action, sAction,
36a0: 20 69 47 72 6f 75 70 5d 0a 20 20 20 20 69 66 20   iGroup].    if 
36b0: 63 41 63 74 69 6f 6e 20 3d 3d 20 22 3d 22 3a 0a  cAction == "=":.
36c0: 20 20 20 20 20 20 20 20 23 23 20 64 69 73 61 6d          ## disam
36d0: 62 69 67 75 61 74 6f 72 0a 20 20 20 20 20 20 20  biguator.       
36e0: 20 69 66 20 73 41 63 74 69 6f 6e 5b 30 3a 31 5d   if sAction[0:1]
36f0: 20 3d 3d 20 22 3d 22 3a 0a 20 20 20 20 20 20 20   == "=":.       
3700: 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 73       sAction = s
3710: 41 63 74 69 6f 6e 5b 31 3a 5d 0a 20 20 20 20 20  Action[1:].     
3720: 20 20 20 69 66 20 22 64 65 66 69 6e 65 22 20 69     if "define" i
3730: 6e 20 73 41 63 74 69 6f 6e 20 61 6e 64 20 6e 6f  n sAction and no
3740: 74 20 72 65 2e 73 65 61 72 63 68 28 72 22 64 65  t re.search(r"de
3750: 66 69 6e 65 5c 28 64 54 6f 6b 65 6e 50 6f 73 2c  fine\(dTokenPos,
3760: 20 2a 6d 5c 2e 73 74 61 72 74 2e 2a 2c 20 5c 5b   *m\.start.*, \[
3770: 2e 2a 5c 5d 20 2a 5c 29 22 2c 20 73 41 63 74 69  .*\] *\)", sActi
3780: 6f 6e 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  on):.           
3790: 20 70 72 69 6e 74 28 22 23 20 45 72 72 6f 72 20   print("# Error 
37a0: 69 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e  in action at lin
37b0: 65 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 20  e " + sIdAction 
37c0: 2b 20 22 3a 20 73 65 63 6f 6e 64 20 61 72 67 75  + ": second argu
37d0: 6d 65 6e 74 20 66 6f 72 20 64 65 66 69 6e 65 20  ment for define 
37e0: 6d 75 73 74 20 62 65 20 61 20 6c 69 73 74 20 6f  must be a list o
37f0: 66 20 73 74 72 69 6e 67 73 22 29 0a 20 20 20 20  f strings").    
3800: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 73 41          print(sA
3810: 63 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20 6c  ction).        l
3820: 46 55 4e 43 54 49 4f 4e 53 2e 61 70 70 65 6e 64  FUNCTIONS.append
3830: 28 28 22 5f 64 5f 22 2b 73 49 64 41 63 74 69 6f  (("_d_"+sIdActio
3840: 6e 2c 20 73 41 63 74 69 6f 6e 29 29 0a 20 20 20  n, sAction)).   
3850: 20 20 20 20 20 73 41 63 74 69 6f 6e 20 3d 20 22       sAction = "
3860: 5f 64 5f 22 2b 73 49 64 41 63 74 69 6f 6e 0a 20  _d_"+sIdAction. 
3870: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 5b 73         return [s
3880: 43 6f 6e 64 69 74 69 6f 6e 2c 20 63 41 63 74 69  Condition, cActi
3890: 6f 6e 2c 20 73 41 63 74 69 6f 6e 5d 0a 20 20 20  on, sAction].   
38a0: 20 70 72 69 6e 74 28 22 23 20 55 6e 6b 6e 6f 77   print("# Unknow
38b0: 6e 20 61 63 74 69 6f 6e 20 61 74 20 6c 69 6e 65  n action at line
38c0: 20 22 20 2b 20 73 49 64 41 63 74 69 6f 6e 29 0a   " + sIdAction).
38d0: 20 20 20 20 72 65 74 75 72 6e 20 4e 6f 6e 65 0a      return None.
38e0: 0a 0a 64 65 66 20 5f 63 61 6c 63 52 75 6c 65 73  ..def _calcRules
38f0: 53 74 61 74 73 20 28 6c 52 75 6c 65 73 29 3a 0a  Stats (lRules):.
3900: 20 20 20 20 22 63 6f 75 6e 74 20 72 75 6c 65 73      "count rules
3910: 20 61 6e 64 20 61 63 74 69 6f 6e 73 22 0a 20 20   and actions".  
3920: 20 20 64 20 3d 20 7b 27 3d 27 3a 30 2c 20 27 7e    d = {'=':0, '~
3930: 27 3a 20 30 2c 20 27 2d 27 3a 20 30 2c 20 27 3e  ': 0, '-': 0, '>
3940: 27 3a 20 30 7d 0a 20 20 20 20 66 6f 72 20 61 52  ': 0}.    for aR
3950: 75 6c 65 20 69 6e 20 6c 52 75 6c 65 73 3a 0a 20  ule in lRules:. 
3960: 20 20 20 20 20 20 20 69 66 20 61 52 75 6c 65 5b         if aRule[
3970: 30 5d 20 21 3d 20 22 40 40 40 40 22 3a 0a 20 20  0] != "@@@@":.  
3980: 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 61 41            for aA
3990: 63 74 69 6f 6e 20 69 6e 20 61 52 75 6c 65 5b 36  ction in aRule[6
39a0: 5d 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ]:.             
39b0: 20 20 20 64 5b 61 41 63 74 69 6f 6e 5b 31 5d 5d     d[aAction[1]]
39c0: 20 3d 20 64 5b 61 41 63 74 69 6f 6e 5b 31 5d 5d   = d[aAction[1]]
39d0: 20 2b 20 31 0a 20 20 20 20 72 65 74 75 72 6e 20   + 1.    return 
39e0: 28 64 2c 20 6c 65 6e 28 6c 52 75 6c 65 73 29 29  (d, len(lRules))
39f0: 0a 0a 0a 64 65 66 20 64 69 73 70 6c 61 79 53 74  ...def displaySt
3a00: 61 74 73 20 28 6c 50 61 72 61 67 72 61 70 68 52  ats (lParagraphR
3a10: 75 6c 65 73 2c 20 6c 53 65 6e 74 65 6e 63 65 52  ules, lSentenceR
3a20: 75 6c 65 73 29 3a 0a 20 20 20 20 22 64 69 73 70  ules):.    "disp
3a30: 6c 61 79 20 72 75 6c 65 73 20 6e 75 6d 62 65 72  lay rules number
3a40: 73 22 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20  s".    print("  
3a50: 7b 3a 3e 31 38 7d 20 7b 3a 3e 31 38 7d 20 7b 3a  {:>18} {:>18} {:
3a60: 3e 31 38 7d 20 7b 3a 3e 31 38 7d 22 2e 66 6f 72  >18} {:>18}".for
3a70: 6d 61 74 28 22 44 49 53 41 4d 42 49 47 55 41 54  mat("DISAMBIGUAT
3a80: 4f 52 22 2c 20 22 54 45 58 54 20 50 52 4f 43 45  OR", "TEXT PROCE
3a90: 53 53 4f 52 22 2c 20 22 47 52 41 4d 4d 41 52 20  SSOR", "GRAMMAR 
3aa0: 43 48 45 43 4b 49 4e 47 22 2c 20 22 52 45 47 45  CHECKING", "REGE
3ab0: 58 22 29 29 0a 20 20 20 20 64 2c 20 6e 52 75 6c  X")).    d, nRul
3ac0: 65 20 3d 20 5f 63 61 6c 63 52 75 6c 65 73 53 74  e = _calcRulesSt
3ad0: 61 74 73 28 6c 50 61 72 61 67 72 61 70 68 52 75  ats(lParagraphRu
3ae0: 6c 65 73 29 0a 20 20 20 20 70 72 69 6e 74 28 22  les).    print("
3af0: c2 a7 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e  .. {:>10} action
3b00: 73 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73  s {:>10} actions
3b10: 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73 20   {:>10} actions 
3b20: 20 69 6e 20 7b 3a 3e 38 7d 20 72 75 6c 65 73 22   in {:>8} rules"
3b30: 2e 66 6f 72 6d 61 74 28 64 5b 27 3d 27 5d 2c 20  .format(d['='], 
3b40: 64 5b 27 7e 27 5d 2c 20 64 5b 27 2d 27 5d 2c 20  d['~'], d['-'], 
3b50: 6e 52 75 6c 65 29 29 0a 20 20 20 20 64 2c 20 6e  nRule)).    d, n
3b60: 52 75 6c 65 20 3d 20 5f 63 61 6c 63 52 75 6c 65  Rule = _calcRule
3b70: 73 53 74 61 74 73 28 6c 53 65 6e 74 65 6e 63 65  sStats(lSentence
3b80: 52 75 6c 65 73 29 0a 20 20 20 20 70 72 69 6e 74  Rules).    print
3b90: 28 22 73 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f  ("s {:>10} actio
3ba0: 6e 73 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e  ns {:>10} action
3bb0: 73 20 7b 3a 3e 31 30 7d 20 61 63 74 69 6f 6e 73  s {:>10} actions
3bc0: 20 20 69 6e 20 7b 3a 3e 38 7d 20 72 75 6c 65 73    in {:>8} rules
3bd0: 22 2e 66 6f 72 6d 61 74 28 64 5b 27 3d 27 5d 2c  ".format(d['='],
3be0: 20 64 5b 27 7e 27 5d 2c 20 64 5b 27 2d 27 5d 2c   d['~'], d['-'],
3bf0: 20 6e 52 75 6c 65 29 29 0a 0a 0a 64 65 66 20 6d   nRule))...def m
3c00: 65 72 67 65 52 75 6c 65 73 42 79 4f 70 74 69 6f  ergeRulesByOptio
3c10: 6e 20 28 6c 52 75 6c 65 73 29 3a 0a 20 20 20 20  n (lRules):.    
3c20: 22 72 65 74 75 72 6e 73 20 61 20 6c 69 73 74 20  "returns a list 
3c30: 6f 66 20 74 75 70 6c 65 73 20 5b 6f 70 74 69 6f  of tuples [optio
3c40: 6e 2c 20 6c 69 73 74 20 6f 66 20 72 75 6c 65 73  n, list of rules
3c50: 5d 20 6b 65 65 70 69 6e 67 20 74 68 65 20 72 75  ] keeping the ru
3c60: 6c 65 73 20 6f 72 64 65 72 22 0a 20 20 20 20 6c  les order".    l
3c70: 46 69 6e 61 6c 20 3d 20 5b 5d 0a 20 20 20 20 6c  Final = [].    l
3c80: 54 65 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 73 4f  Temp = [].    sO
3c90: 70 74 69 6f 6e 20 3d 20 4e 6f 6e 65 0a 20 20 20  ption = None.   
3ca0: 20 66 6f 72 20 61 52 75 6c 65 20 69 6e 20 6c 52   for aRule in lR
3cb0: 75 6c 65 73 3a 0a 20 20 20 20 20 20 20 20 69 66  ules:.        if
3cc0: 20 61 52 75 6c 65 5b 30 5d 20 21 3d 20 73 4f 70   aRule[0] != sOp
3cd0: 74 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 20 20  tion:.          
3ce0: 20 20 69 66 20 73 4f 70 74 69 6f 6e 20 69 73 20    if sOption is 
3cf0: 6e 6f 74 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20  not None:.      
3d00: 20 20 20 20 20 20 20 20 20 20 6c 46 69 6e 61 6c            lFinal
3d10: 2e 61 70 70 65 6e 64 28 5b 73 4f 70 74 69 6f 6e  .append([sOption
3d20: 2c 20 6c 54 65 6d 70 5d 29 0a 20 20 20 20 20 20  , lTemp]).      
3d30: 20 20 20 20 20 20 23 20 6e 65 77 20 74 75 70 6c        # new tupl
3d40: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 4f  e.            sO
3d50: 70 74 69 6f 6e 20 3d 20 61 52 75 6c 65 5b 30 5d  ption = aRule[0]
3d60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 54 65  .            lTe
3d70: 6d 70 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20 20  mp = [].        
3d80: 6c 54 65 6d 70 2e 61 70 70 65 6e 64 28 61 52 75  lTemp.append(aRu
3d90: 6c 65 5b 31 3a 5d 29 0a 20 20 20 20 6c 46 69 6e  le[1:]).    lFin
3da0: 61 6c 2e 61 70 70 65 6e 64 28 5b 73 4f 70 74 69  al.append([sOpti
3db0: 6f 6e 2c 20 6c 54 65 6d 70 5d 29 0a 20 20 20 20  on, lTemp]).    
3dc0: 72 65 74 75 72 6e 20 6c 46 69 6e 61 6c 0a 0a 0a  return lFinal...
3dd0: 64 65 66 20 70 72 65 70 61 72 65 4f 70 74 69 6f  def prepareOptio
3de0: 6e 73 20 28 6c 4f 70 74 69 6f 6e 4c 69 6e 65 73  ns (lOptionLines
3df0: 29 3a 0a 20 20 20 20 22 72 65 74 75 72 6e 73 20  ):.    "returns 
3e00: 61 20 64 69 63 74 69 6f 6e 61 72 79 20 77 69 74  a dictionary wit
3e10: 68 20 64 61 74 61 20 61 62 6f 75 74 20 6f 70 74  h data about opt
3e20: 69 6f 6e 73 22 0a 20 20 20 20 73 4c 61 6e 67 20  ions".    sLang 
3e30: 3d 20 22 22 0a 20 20 20 20 73 44 65 66 61 75 6c  = "".    sDefaul
3e40: 74 55 49 4c 61 6e 67 20 3d 20 22 22 0a 20 20 20  tUILang = "".   
3e50: 20 6c 53 74 72 75 63 74 4f 70 74 20 3d 20 5b 5d   lStructOpt = []
3e60: 0a 20 20 20 20 6c 4f 70 74 20 3d 20 5b 5d 0a 20  .    lOpt = []. 
3e70: 20 20 20 6c 4f 70 74 43 6f 6c 6f 72 20 3d 20 5b     lOptColor = [
3e80: 5d 0a 20 20 20 20 64 43 6f 6c 6f 72 20 3d 20 7b  ].    dColor = {
3e90: 7d 0a 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 20  }.    dOptLabel 
3ea0: 3d 20 7b 7d 0a 20 20 20 20 64 4f 70 74 50 72 69  = {}.    dOptPri
3eb0: 6f 72 69 74 79 20 3d 20 7b 7d 0a 20 20 20 20 66  ority = {}.    f
3ec0: 6f 72 20 73 4c 69 6e 65 20 69 6e 20 6c 4f 70 74  or sLine in lOpt
3ed0: 69 6f 6e 4c 69 6e 65 73 3a 0a 20 20 20 20 20 20  ionLines:.      
3ee0: 20 20 73 4c 69 6e 65 20 3d 20 73 4c 69 6e 65 2e    sLine = sLine.
3ef0: 73 74 72 69 70 28 29 0a 20 20 20 20 20 20 20 20  strip().        
3f00: 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77  if sLine.startsw
3f10: 69 74 68 28 22 4f 50 54 47 52 4f 55 50 2f 22 29  ith("OPTGROUP/")
3f20: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20  :.            m 
3f30: 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 47  = re.match("OPTG
3f40: 52 4f 55 50 2f 28 5b 61 2d 7a 30 2d 39 5d 2b 29  ROUP/([a-z0-9]+)
3f50: 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a  :(.+)$", sLine).
3f60: 20 20 20 20 20 20 20 20 20 20 20 20 6c 53 74 72              lStr
3f70: 75 63 74 4f 70 74 2e 61 70 70 65 6e 64 28 20 5b  uctOpt.append( [
3f80: 6d 2e 67 72 6f 75 70 28 31 29 2c 20 6c 69 73 74  m.group(1), list
3f90: 28 6d 61 70 28 73 74 72 2e 73 70 6c 69 74 2c 20  (map(str.split, 
3fa0: 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74  m.group(2).split
3fb0: 28 22 2c 22 29 29 29 5d 20 29 0a 20 20 20 20 20  (",")))] ).     
3fc0: 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74     elif sLine.st
3fd0: 61 72 74 73 77 69 74 68 28 22 4f 50 54 53 4f 46  artswith("OPTSOF
3fe0: 54 57 41 52 45 3a 22 29 3a 0a 20 20 20 20 20 20  TWARE:"):.      
3ff0: 20 20 20 20 20 20 6c 4f 70 74 20 3d 20 5b 20 5b        lOpt = [ [
4000: 73 2c 20 7b 7d 5d 20 20 66 6f 72 20 73 20 69 6e  s, {}]  for s in
4010: 20 73 4c 69 6e 65 5b 31 32 3a 5d 2e 73 74 72 69   sLine[12:].stri
4020: 70 28 29 2e 73 70 6c 69 74 28 29 20 5d 20 20 23  p().split() ]  #
4030: 20 64 6f 6e e2 80 99 74 20 75 73 65 20 74 75 70   don...t use tup
4040: 6c 65 73 20 28 73 2c 20 7b 7d 29 2c 20 62 65 63  les (s, {}), bec
4050: 61 75 73 65 20 75 6e 6b 6e 6f 77 6e 20 74 6f 20  ause unknown to 
4060: 4a 53 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  JS.        elif 
4070: 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68  sLine.startswith
4080: 28 22 4f 50 54 2f 22 29 3a 0a 20 20 20 20 20 20  ("OPT/"):.      
4090: 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74        m = re.mat
40a0: 63 68 28 22 4f 50 54 2f 28 5b 61 2d 7a 30 2d 39  ch("OPT/([a-z0-9
40b0: 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e  ]+):(.+)$", sLin
40c0: 65 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  e).            f
40d0: 6f 72 20 69 2c 20 73 4f 70 74 20 69 6e 20 65 6e  or i, sOpt in en
40e0: 75 6d 65 72 61 74 65 28 6d 2e 67 72 6f 75 70 28  umerate(m.group(
40f0: 32 29 2e 73 70 6c 69 74 28 29 29 3a 0a 20 20 20  2).split()):.   
4100: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 4f 70               lOp
4110: 74 5b 69 5d 5b 31 5d 5b 6d 2e 67 72 6f 75 70 28  t[i][1][m.group(
4120: 31 29 5d 20 3d 20 73 4f 70 74 20 69 6e 20 28 22  1)] = sOpt in ("
4130: 54 72 75 65 22 2c 20 22 74 72 75 65 22 2c 20 22  True", "true", "
4140: 59 65 73 22 2c 20 22 79 65 73 22 29 0a 20 20 20  Yes", "yes").   
4150: 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e       elif sLine.
4160: 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54 43  startswith("OPTC
4170: 4f 4c 4f 52 54 48 45 4d 45 3a 22 29 3a 0a 20 20  OLORTHEME:"):.  
4180: 20 20 20 20 20 20 20 20 20 20 6c 4f 70 74 43 6f            lOptCo
4190: 6c 6f 72 20 3d 20 5b 20 5b 73 2c 20 7b 7d 5d 20  lor = [ [s, {}] 
41a0: 20 66 6f 72 20 73 20 69 6e 20 73 4c 69 6e 65 5b   for s in sLine[
41b0: 31 34 3a 5d 2e 73 74 72 69 70 28 29 2e 73 70 6c  14:].strip().spl
41c0: 69 74 28 29 20 5d 20 20 23 20 64 6f 6e e2 80 99  it() ]  # don...
41d0: 74 20 75 73 65 20 74 75 70 6c 65 73 20 28 73 2c  t use tuples (s,
41e0: 20 7b 7d 29 2c 20 62 65 63 61 75 73 65 20 75 6e   {}), because un
41f0: 6b 6e 6f 77 6e 20 74 6f 20 4a 53 0a 20 20 20 20  known to JS.    
4200: 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73      elif sLine.s
4210: 74 61 72 74 73 77 69 74 68 28 22 4f 50 54 43 4f  tartswith("OPTCO
4220: 4c 4f 52 2f 22 29 3a 0a 20 20 20 20 20 20 20 20  LOR/"):.        
4230: 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68      m = re.match
4240: 28 22 4f 50 54 43 4f 4c 4f 52 2f 28 5b 61 2d 7a  ("OPTCOLOR/([a-z
4250: 30 2d 39 5d 2b 29 3a 28 2e 2b 29 24 22 2c 20 73  0-9]+):(.+)$", s
4260: 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20 20  Line).          
4270: 20 20 66 6f 72 20 69 2c 20 73 43 6f 6c 6f 72 20    for i, sColor 
4280: 69 6e 20 65 6e 75 6d 65 72 61 74 65 28 6d 2e 67  in enumerate(m.g
4290: 72 6f 75 70 28 32 29 2e 73 70 6c 69 74 28 29 29  roup(2).split())
42a0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
42b0: 20 20 6c 4f 70 74 43 6f 6c 6f 72 5b 69 5d 5b 31    lOptColor[i][1
42c0: 5d 5b 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20  ][m.group(1)] = 
42d0: 73 43 6f 6c 6f 72 0a 20 20 20 20 20 20 20 20 65  sColor.        e
42e0: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
42f0: 77 69 74 68 28 22 43 4f 4c 4f 52 2f 22 29 3a 0a  with("COLOR/"):.
4300: 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d 20              m = 
4310: 72 65 2e 6d 61 74 63 68 28 22 43 4f 4c 4f 52 2f  re.match("COLOR/
4320: 28 5b 61 2d 7a 41 2d 5a 30 2d 39 5f 5d 2b 29 3a  ([a-zA-Z0-9_]+):
4330: 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29 0a 20  (.+)$", sLine). 
4340: 20 20 20 20 20 20 20 20 20 20 20 64 43 6f 6c 6f             dColo
4350: 72 5b 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20  r[m.group(1)] = 
4360: 5b 20 69 6e 74 28 73 29 20 66 6f 72 20 73 20 69  [ int(s) for s i
4370: 6e 20 6d 2e 67 72 6f 75 70 28 32 29 2e 73 74 72  n m.group(2).str
4380: 69 70 28 29 2e 73 70 6c 69 74 28 22 2c 22 29 20  ip().split(",") 
4390: 5d 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  ].        elif s
43a0: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
43b0: 22 4f 50 54 50 52 49 4f 52 49 54 59 2f 22 29 3a  "OPTPRIORITY/"):
43c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 20 3d  .            m =
43d0: 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54 50 52   re.match("OPTPR
43e0: 49 4f 52 49 54 59 2f 28 5b 61 2d 7a 30 2d 39 5d  IORITY/([a-z0-9]
43f0: 2b 29 3a 20 2a 28 5b 30 2d 39 5d 29 24 22 2c 20  +): *([0-9])$", 
4400: 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20  sLine).         
4410: 20 20 20 64 4f 70 74 50 72 69 6f 72 69 74 79 5b     dOptPriority[
4420: 6d 2e 67 72 6f 75 70 28 31 29 5d 20 3d 20 69 6e  m.group(1)] = in
4430: 74 28 6d 2e 67 72 6f 75 70 28 32 29 29 0a 20 20  t(m.group(2)).  
4440: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
4450: 2e 73 74 61 72 74 73 77 69 74 68 28 22 4f 50 54  .startswith("OPT
4460: 4c 41 4e 47 2f 22 29 3a 0a 20 20 20 20 20 20 20  LANG/"):.       
4470: 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63       m = re.matc
4480: 68 28 22 4f 50 54 4c 41 4e 47 2f 28 5b 61 2d 7a  h("OPTLANG/([a-z
4490: 5d 5b 61 2d 7a 5d 28 3f 3a 5f 5b 41 2d 5a 5d 5b  ][a-z](?:_[A-Z][
44a0: 41 2d 5a 5d 7c 29 29 3a 28 2e 2b 29 24 22 2c 20  A-Z]|)):(.+)$", 
44b0: 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20 20  sLine).         
44c0: 20 20 20 73 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f     sLang = m.gro
44d0: 75 70 28 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20  up(1)[:2].      
44e0: 20 20 20 20 20 20 64 4f 70 74 4c 61 62 65 6c 5b        dOptLabel[
44f0: 73 4c 61 6e 67 5d 20 3d 20 7b 20 22 5f 5f 6f 70  sLang] = { "__op
4500: 74 69 6f 6e 74 69 74 6c 65 5f 5f 22 3a 20 6d 2e  tiontitle__": m.
4510: 67 72 6f 75 70 28 32 29 2e 73 74 72 69 70 28 29  group(2).strip()
4520: 20 7d 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20   }.        elif 
4530: 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68  sLine.startswith
4540: 28 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41  ("OPTDEFAULTUILA
4550: 4e 47 3a 22 29 3a 0a 20 20 20 20 20 20 20 20 20  NG:"):.         
4560: 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28     m = re.match(
4570: 22 4f 50 54 44 45 46 41 55 4c 54 55 49 4c 41 4e  "OPTDEFAULTUILAN
4580: 47 3a 20 2a 28 5b 61 2d 7a 5d 5b 61 2d 7a 5d 28  G: *([a-z][a-z](
4590: 3f 3a 5f 5b 41 2d 5a 5d 5b 41 2d 5a 5d 7c 29 29  ?:_[A-Z][A-Z]|))
45a0: 24 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20  $", sLine).     
45b0: 20 20 20 20 20 20 20 73 44 65 66 61 75 6c 74 55         sDefaultU
45c0: 49 4c 61 6e 67 20 3d 20 6d 2e 67 72 6f 75 70 28  ILang = m.group(
45d0: 31 29 5b 3a 32 5d 0a 20 20 20 20 20 20 20 20 65  1)[:2].        e
45e0: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
45f0: 77 69 74 68 28 22 4f 50 54 4c 41 42 45 4c 2f 22  with("OPTLABEL/"
4600: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d  ):.            m
4610: 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 4f 50 54   = re.match("OPT
4620: 4c 41 42 45 4c 2f 28 5b 61 2d 7a 30 2d 39 5d 2b  LABEL/([a-z0-9]+
4630: 29 3a 28 2e 2b 29 24 22 2c 20 73 4c 69 6e 65 29  ):(.+)$", sLine)
4640: 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 4f 70  .            dOp
4650: 74 4c 61 62 65 6c 5b 73 4c 61 6e 67 5d 5b 6d 2e  tLabel[sLang][m.
4660: 67 72 6f 75 70 28 31 29 5d 20 3d 20 6c 69 73 74  group(1)] = list
4670: 28 6d 61 70 28 73 74 72 2e 73 74 72 69 70 2c 20  (map(str.strip, 
4680: 6d 2e 67 72 6f 75 70 28 32 29 2e 73 70 6c 69 74  m.group(2).split
4690: 28 22 7c 22 29 29 29 20 20 69 66 20 22 7c 22 20  ("|")))  if "|" 
46a0: 69 6e 20 6d 2e 67 72 6f 75 70 28 32 29 20 20 65  in m.group(2)  e
46b0: 6c 73 65 20 20 5b 6d 2e 67 72 6f 75 70 28 32 29  lse  [m.group(2)
46c0: 2e 73 74 72 69 70 28 29 2c 20 22 22 5d 0a 20 20  .strip(), ""].  
46d0: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
46e0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 28 22 23          print("#
46f0: 20 45 72 72 6f 72 2e 20 57 72 6f 6e 67 20 6f 70   Error. Wrong op
4700: 74 69 6f 6e 20 6c 69 6e 65 20 69 6e 3a 5c 6e 20  tion line in:\n 
4710: 20 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20   ").            
4720: 70 72 69 6e 74 28 73 4c 69 6e 65 29 0a 20 20 20  print(sLine).   
4730: 20 70 72 69 6e 74 28 22 20 20 6f 70 74 69 6f 6e   print("  option
4740: 73 20 64 65 66 69 6e 65 64 20 66 6f 72 3a 20 22  s defined for: "
4750: 20 2b 20 22 2c 20 22 2e 6a 6f 69 6e 28 5b 20 74   + ", ".join([ t
4760: 5b 30 5d 20 66 6f 72 20 74 20 69 6e 20 6c 4f 70  [0] for t in lOp
4770: 74 20 5d 29 29 0a 20 20 20 20 64 4f 70 74 69 6f  t ])).    dOptio
4780: 6e 73 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 22  ns = {.        "
4790: 6c 53 74 72 75 63 74 4f 70 74 22 3a 20 6c 53 74  lStructOpt": lSt
47a0: 72 75 63 74 4f 70 74 2c 20 22 64 4f 70 74 4c 61  ructOpt, "dOptLa
47b0: 62 65 6c 22 3a 20 64 4f 70 74 4c 61 62 65 6c 2c  bel": dOptLabel,
47c0: 20 22 73 44 65 66 61 75 6c 74 55 49 4c 61 6e 67   "sDefaultUILang
47d0: 22 3a 20 73 44 65 66 61 75 6c 74 55 49 4c 61 6e  ": sDefaultUILan
47e0: 67 2c 20 5c 0a 20 20 20 20 20 20 20 20 22 64 43  g, \.        "dC
47f0: 6f 6c 6f 72 54 79 70 65 22 3a 20 63 72 65 61 74  olorType": creat
4800: 65 43 6f 6c 6f 72 73 28 64 43 6f 6c 6f 72 29 2c  eColors(dColor),
4810: 20 22 64 4f 70 74 43 6f 6c 6f 72 22 3a 20 7b 20   "dOptColor": { 
4820: 73 3a 20 64 20 20 66 6f 72 20 73 2c 20 64 20 69  s: d  for s, d i
4830: 6e 20 6c 4f 70 74 43 6f 6c 6f 72 20 7d 0a 20 20  n lOptColor }.  
4840: 20 20 7d 0a 20 20 20 20 64 4f 70 74 69 6f 6e 73    }.    dOptions
4850: 2e 75 70 64 61 74 65 28 7b 20 22 64 4f 70 74 22  .update({ "dOpt"
4860: 2b 6b 3a 20 76 20 20 66 6f 72 20 6b 2c 20 76 20  +k: v  for k, v 
4870: 69 6e 20 6c 4f 70 74 20 7d 29 0a 20 20 20 20 72  in lOpt }).    r
4880: 65 74 75 72 6e 20 64 4f 70 74 69 6f 6e 73 2c 20  eturn dOptions, 
4890: 64 4f 70 74 50 72 69 6f 72 69 74 79 0a 0a 0a 64  dOptPriority...d
48a0: 65 66 20 70 72 69 6e 74 42 6f 6f 6b 6d 61 72 6b  ef printBookmark
48b0: 20 28 6e 4c 65 76 65 6c 2c 20 73 43 6f 6d 6d 65   (nLevel, sComme
48c0: 6e 74 2c 20 6e 4c 69 6e 65 29 3a 0a 20 20 20 20  nt, nLine):.    
48d0: 22 70 72 69 6e 74 20 62 6f 6f 6b 6d 61 72 6b 20  "print bookmark 
48e0: 77 69 74 68 69 6e 20 74 68 65 20 72 75 6c 65 73  within the rules
48f0: 20 66 69 6c 65 22 0a 20 20 20 20 70 72 69 6e 74   file".    print
4900: 28 22 20 20 7b 3a 3e 36 7d 3a 20 20 7b 7d 22 2e  ("  {:>6}:  {}".
4910: 66 6f 72 6d 61 74 28 6e 4c 69 6e 65 2c 20 22 20  format(nLine, " 
4920: 20 22 20 2a 20 6e 4c 65 76 65 6c 20 2b 20 73 43   " * nLevel + sC
4930: 6f 6d 6d 65 6e 74 29 29 0a 0a 0a 64 65 66 20 6d  omment))...def m
4940: 61 6b 65 20 28 73 70 4c 61 6e 67 2c 20 73 4c 61  ake (spLang, sLa
4950: 6e 67 2c 20 62 55 73 65 43 61 63 68 65 3d 46 61  ng, bUseCache=Fa
4960: 6c 73 65 29 3a 0a 20 20 20 20 22 63 6f 6d 70 69  lse):.    "compi
4970: 6c 65 20 72 75 6c 65 73 2c 20 72 65 74 75 72 6e  le rules, return
4980: 73 20 61 20 64 69 63 74 69 6f 6e 61 72 79 20 6f  s a dictionary o
4990: 66 20 76 61 6c 75 65 73 22 0a 20 20 20 20 23 20  f values".    # 
49a0: 66 6f 72 20 63 6c 61 72 69 74 79 20 70 75 72 70  for clarity purp
49b0: 6f 73 65 2c 20 64 6f 6e e2 80 99 74 20 63 72 65  ose, don...t cre
49c0: 61 74 65 20 61 6e 79 20 66 69 6c 65 20 68 65 72  ate any file her
49d0: 65 0a 0a 20 20 20 20 69 66 20 62 55 73 65 43 61  e..    if bUseCa
49e0: 63 68 65 20 61 6e 64 20 6f 73 2e 70 61 74 68 2e  che and os.path.
49f0: 69 73 66 69 6c 65 28 22 5f 62 75 69 6c 64 2f 64  isfile("_build/d
4a00: 61 74 61 5f 63 61 63 68 65 2e 6a 73 6f 6e 22 29  ata_cache.json")
4a10: 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e 74 28  :.        print(
4a20: 22 3e 20 64 6f 6e e2 80 99 74 20 72 65 62 75 69  "> don...t rebui
4a30: 6c 64 20 72 75 6c 65 73 2c 20 75 73 65 20 63 61  ld rules, use ca
4a40: 63 68 65 2e 2e 2e 22 29 0a 20 20 20 20 20 20 20  che...").       
4a50: 20 73 4a 53 4f 4e 20 3d 20 6f 70 65 6e 28 22 5f   sJSON = open("_
4a60: 62 75 69 6c 64 2f 64 61 74 61 5f 63 61 63 68 65  build/data_cache
4a70: 2e 6a 73 6f 6e 22 2c 20 22 72 22 2c 20 65 6e 63  .json", "r", enc
4a80: 6f 64 69 6e 67 3d 22 75 74 66 2d 38 22 29 2e 72  oding="utf-8").r
4a90: 65 61 64 28 29 0a 20 20 20 20 20 20 20 20 64 43  ead().        dC
4aa0: 61 63 68 65 56 61 72 73 20 3d 20 6a 73 6f 6e 2e  acheVars = json.
4ab0: 6c 6f 61 64 73 28 73 4a 53 4f 4e 29 0a 20 20 20  loads(sJSON).   
4ac0: 20 20 20 20 20 70 72 69 6e 74 28 22 20 20 62 75       print("  bu
4ad0: 69 6c 64 20 6d 61 64 65 20 61 74 3a 20 22 20 2b  ild made at: " +
4ae0: 20 74 69 6d 65 2e 73 74 72 66 74 69 6d 65 28 22   time.strftime("
4af0: 25 59 2d 25 6d 2d 25 64 20 25 48 3a 25 4d 3a 25  %Y-%m-%d %H:%M:%
4b00: 53 22 2c 20 74 69 6d 65 2e 67 6d 74 69 6d 65 28  S", time.gmtime(
4b10: 64 43 61 63 68 65 56 61 72 73 2e 67 65 74 28 22  dCacheVars.get("
4b20: 66 42 75 69 6c 64 54 69 6d 65 22 2c 20 30 29 29  fBuildTime", 0))
4b30: 29 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  )).        retur
4b40: 6e 20 64 43 61 63 68 65 56 61 72 73 0a 0a 20 20  n dCacheVars..  
4b50: 20 20 66 42 75 69 6c 64 54 69 6d 65 20 3d 20 74    fBuildTime = t
4b60: 69 6d 65 2e 74 69 6d 65 28 29 0a 0a 20 20 20 20  ime.time()..    
4b70: 70 72 69 6e 74 28 22 3e 20 72 65 61 64 20 72 75  print("> read ru
4b80: 6c 65 73 20 66 69 6c 65 2e 2e 2e 22 29 0a 20 20  les file...").  
4b90: 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20 6c    try:.        l
4ba0: 52 75 6c 65 73 20 3d 20 6f 70 65 6e 28 73 70 4c  Rules = open(spL
4bb0: 61 6e 67 20 2b 20 22 2f 72 75 6c 65 73 2e 67 72  ang + "/rules.gr
4bc0: 78 22 2c 20 27 72 27 2c 20 65 6e 63 6f 64 69 6e  x", 'r', encodin
4bd0: 67 3d 22 75 74 66 2d 38 22 29 2e 72 65 61 64 6c  g="utf-8").readl
4be0: 69 6e 65 73 28 29 0a 20 20 20 20 65 78 63 65 70  ines().    excep
4bf0: 74 20 4f 53 45 72 72 6f 72 3a 0a 20 20 20 20 20  t OSError:.     
4c00: 20 20 20 70 72 69 6e 74 28 22 45 72 72 6f 72 2e     print("Error.
4c10: 20 52 75 6c 65 73 20 66 69 6c 65 20 69 6e 20 70   Rules file in p
4c20: 72 6f 6a 65 63 74 20 5b 22 20 2b 20 73 4c 61 6e  roject [" + sLan
4c30: 67 20 2b 20 22 5d 20 6e 6f 74 20 66 6f 75 6e 64  g + "] not found
4c40: 2e 22 29 0a 20 20 20 20 20 20 20 20 65 78 69 74  .").        exit
4c50: 28 29 0a 0a 20 20 20 20 23 20 72 65 6d 6f 76 69  ()..    # removi
4c60: 6e 67 20 63 6f 6d 6d 65 6e 74 73 2c 20 7a 65 72  ng comments, zer
4c70: 6f 69 6e 67 20 65 6d 70 74 79 20 6c 69 6e 65 73  oing empty lines
4c80: 2c 20 63 72 65 61 74 69 6e 67 20 64 65 66 69 6e  , creating defin
4c90: 69 74 69 6f 6e 73 2c 20 73 74 6f 72 69 6e 67 20  itions, storing 
4ca0: 74 65 73 74 73 2c 20 6d 65 72 67 69 6e 67 20 72  tests, merging r
4cb0: 75 6c 65 20 6c 69 6e 65 73 0a 20 20 20 20 70 72  ule lines.    pr
4cc0: 69 6e 74 28 22 20 20 70 61 72 73 69 6e 67 20 72  int("  parsing r
4cd0: 75 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20 6c 52  ules...").    lR
4ce0: 75 6c 65 4c 69 6e 65 20 3d 20 5b 5d 0a 20 20 20  uleLine = [].   
4cf0: 20 6c 54 65 73 74 20 3d 20 5b 5d 0a 20 20 20 20   lTest = [].    
4d00: 6c 4f 70 74 20 3d 20 5b 5d 0a 20 20 20 20 62 47  lOpt = [].    bG
4d10: 72 61 70 68 20 3d 20 46 61 6c 73 65 0a 20 20 20  raph = False.   
4d20: 20 6c 47 72 61 70 68 52 75 6c 65 20 3d 20 5b 5d   lGraphRule = []
4d30: 0a 0a 20 20 20 20 66 6f 72 20 69 2c 20 73 4c 69  ..    for i, sLi
4d40: 6e 65 20 69 6e 20 65 6e 75 6d 65 72 61 74 65 28  ne in enumerate(
4d50: 6c 52 75 6c 65 73 2c 20 31 29 3a 0a 20 20 20 20  lRules, 1):.    
4d60: 20 20 20 20 69 66 20 73 4c 69 6e 65 2e 73 74 61      if sLine.sta
4d70: 72 74 73 77 69 74 68 28 27 23 45 4e 44 27 29 3a  rtswith('#END'):
4d80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20 61  .            # a
4d90: 72 62 69 74 72 61 72 79 20 65 6e 64 0a 20 20 20  rbitrary end.   
4da0: 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 42 6f           printBo
4db0: 6f 6b 6d 61 72 6b 28 30 2c 20 22 42 52 45 41 4b  okmark(0, "BREAK
4dc0: 20 42 59 20 23 45 4e 44 22 2c 20 69 29 0a 20 20   BY #END", i).  
4dd0: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 0a            break.
4de0: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
4df0: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 23  ne.startswith("#
4e00: 22 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  "):.            
4e10: 23 20 63 6f 6d 6d 65 6e 74 0a 20 20 20 20 20 20  # comment.      
4e20: 20 20 20 20 20 20 70 61 73 73 0a 20 20 20 20 20        pass.     
4e30: 20 20 20 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74     elif sLine.st
4e40: 61 72 74 73 77 69 74 68 28 22 44 45 46 3a 22 29  artswith("DEF:")
4e50: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
4e60: 64 65 66 69 6e 69 74 69 6f 6e 0a 20 20 20 20 20  definition.     
4e70: 20 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61         m = re.ma
4e80: 74 63 68 28 22 44 45 46 3a 20 2b 28 5b 61 2d 7a  tch("DEF: +([a-z
4e90: 41 2d 5a 5f 5d 5b 61 2d 7a 41 2d 5a 5f 30 2d 39  A-Z_][a-zA-Z_0-9
4ea0: 5d 2a 29 20 2b 28 2e 2b 29 24 22 2c 20 73 4c 69  ]*) +(.+)$", sLi
4eb0: 6e 65 2e 73 74 72 69 70 28 29 29 0a 20 20 20 20  ne.strip()).    
4ec0: 20 20 20 20 20 20 20 20 69 66 20 6d 3a 0a 20 20          if m:.  
4ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64 44                dD
4ee0: 45 46 5b 22 7b 22 2b 6d 2e 67 72 6f 75 70 28 31  EF["{"+m.group(1
4ef0: 29 2b 22 7d 22 5d 20 3d 20 6d 2e 67 72 6f 75 70  )+"}"] = m.group
4f00: 28 32 29 0a 20 20 20 20 20 20 20 20 20 20 20 20  (2).            
4f10: 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20  else:.          
4f20: 20 20 20 20 20 20 70 72 69 6e 74 28 22 45 72 72        print("Err
4f30: 6f 72 20 69 6e 20 64 65 66 69 6e 69 74 69 6f 6e  or in definition
4f40: 3a 20 22 2c 20 65 6e 64 3d 22 22 29 0a 20 20 20  : ", end="").   
4f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
4f60: 6e 74 28 73 4c 69 6e 65 2e 73 74 72 69 70 28 29  nt(sLine.strip()
4f70: 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73  ).        elif s
4f80: 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28  Line.startswith(
4f90: 22 54 45 53 54 3a 22 29 3a 0a 20 20 20 20 20 20  "TEST:"):.      
4fa0: 20 20 20 20 20 20 23 20 74 65 73 74 0a 20 20 20        # test.   
4fb0: 20 20 20 20 20 20 20 20 20 6c 54 65 73 74 2e 61           lTest.a
4fc0: 70 70 65 6e 64 28 22 7b 3a 3c 38 7d 22 2e 66 6f  ppend("{:<8}".fo
4fd0: 72 6d 61 74 28 69 29 20 2b 20 22 20 20 22 20 2b  rmat(i) + "  " +
4fe0: 20 73 4c 69 6e 65 5b 35 3a 5d 2e 73 74 72 69 70   sLine[5:].strip
4ff0: 28 29 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66  ()).        elif
5000: 20 73 4c 69 6e 65 2e 73 74 61 72 74 73 77 69 74   sLine.startswit
5010: 68 28 22 54 4f 44 4f 3a 22 29 3a 0a 20 20 20 20  h("TODO:"):.    
5020: 20 20 20 20 20 20 20 20 23 20 74 6f 64 6f 0a 20          # todo. 
5030: 20 20 20 20 20 20 20 20 20 20 20 70 61 73 73 0a             pass.
5040: 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69          elif sLi
5050: 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 28 22  ne.startswith(("
5060: 4f 50 54 47 52 4f 55 50 2f 22 2c 20 22 4f 50 54  OPTGROUP/", "OPT
5070: 53 4f 46 54 57 41 52 45 3a 22 2c 20 22 4f 50 54  SOFTWARE:", "OPT
5080: 2f 22 2c 20 5c 0a 20 20 20 20 20 20 20 20 20 20  /", \.          
5090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50a0: 20 20 20 20 20 20 22 43 4f 4c 4f 52 2f 22 2c 20        "COLOR/", 
50b0: 22 4f 50 54 43 4f 4c 4f 52 54 48 45 4d 45 3a 22  "OPTCOLORTHEME:"
50c0: 2c 20 22 4f 50 54 43 4f 4c 4f 52 2f 22 2c 20 5c  , "OPTCOLOR/", \
50d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
50e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50f0: 20 22 4f 50 54 4c 41 4e 47 2f 22 2c 20 22 4f 50   "OPTLANG/", "OP
5100: 54 44 45 46 41 55 4c 54 55 49 4c 41 4e 47 3a 22  TDEFAULTUILANG:"
5110: 2c 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  , \.            
5120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5130: 20 20 20 20 22 4f 50 54 4c 41 42 45 4c 2f 22 2c      "OPTLABEL/",
5140: 20 22 4f 50 54 50 52 49 4f 52 49 54 59 2f 22 29   "OPTPRIORITY/")
5150: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ):.            #
5160: 20 6f 70 74 69 6f 6e 73 0a 20 20 20 20 20 20 20   options.       
5170: 20 20 20 20 20 6c 4f 70 74 2e 61 70 70 65 6e 64       lOpt.append
5180: 28 73 4c 69 6e 65 29 0a 20 20 20 20 20 20 20 20  (sLine).        
5190: 65 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74  elif sLine.start
51a0: 73 77 69 74 68 28 22 21 21 22 29 3a 0a 20 20 20  swith("!!"):.   
51b0: 20 20 20 20 20 20 20 20 20 23 20 62 6f 6f 6b 6d           # bookm
51c0: 61 72 6b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ark.            
51d0: 6d 20 3d 20 72 65 2e 6d 61 74 63 68 28 22 21 21  m = re.match("!!
51e0: 2b 22 2c 20 73 4c 69 6e 65 29 0a 20 20 20 20 20  +", sLine).     
51f0: 20 20 20 20 20 20 20 6e 45 78 4d 6b 20 3d 20 6c         nExMk = l
5200: 65 6e 28 6d 2e 67 72 6f 75 70 28 30 29 29 0a 20  en(m.group(0)). 
5210: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 73 4c             if sL
5220: 69 6e 65 5b 6e 45 78 4d 6b 3a 5d 2e 73 74 72 69  ine[nExMk:].stri
5230: 70 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  p():.           
5240: 20 20 20 20 20 70 72 69 6e 74 42 6f 6f 6b 6d 61       printBookma
5250: 72 6b 28 6e 45 78 4d 6b 2d 32 2c 20 73 4c 69 6e  rk(nExMk-2, sLin
5260: 65 5b 6e 45 78 4d 6b 3a 2d 33 5d 2e 73 74 72 69  e[nExMk:-3].stri
5270: 70 28 29 2c 20 69 29 0a 20 20 20 20 20 20 20 20  p(), i).        
5280: 23 20 47 72 61 70 68 20 72 75 6c 65 73 0a 20 20  # Graph rules.  
5290: 20 20 20 20 20 20 65 6c 69 66 20 73 4c 69 6e 65        elif sLine
52a0: 2e 73 74 61 72 74 73 77 69 74 68 28 22 40 40 40  .startswith("@@@
52b0: 40 47 52 41 50 48 3a 22 29 3a 0a 20 20 20 20 20  @GRAPH:"):.     
52c0: 20 20 20 20 20 20 20 23 20 72 75 6c 65 73 20 67         # rules g
52d0: 72 61 70 68 20 63 61 6c 6c 0a 20 20 20 20 20 20  raph call.      
52e0: 20 20 20 20 20 20 6d 20 3d 20 72 65 2e 6d 61 74        m = re.mat
52f0: 63 68 28 72 22 40 40 40 40 47 52 41 50 48 3a 20  ch(r"@@@@GRAPH: 
5300: 2a 28 5c 77 2b 29 22 2c 20 73 4c 69 6e 65 2e 73  *(\w+)", sLine.s
5310: 74 72 69 70 28 29 29 0a 20 20 20 20 20 20 20 20  trip()).        
5320: 20 20 20 20 69 66 20 6d 3a 0a 20 20 20 20 20 20      if m:.      
5330: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 42            printB
5340: 6f 6f 6b 6d 61 72 6b 28 30 2c 20 22 47 52 41 50  ookmark(0, "GRAP
5350: 48 3a 20 22 20 2b 20 6d 2e 67 72 6f 75 70 28 31  H: " + m.group(1
5360: 29 2c 20 69 29 0a 20 20 20 20 20 20 20 20 20 20  ), i).          
5370: 20 20 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 2e        lRuleLine.
5380: 61 70 70 65 6e 64 28 5b 69 2c 20 22 40 40 40 40  append([i, "@@@@
5390: 22 2b 6d 2e 67 72 6f 75 70 28 31 29 5d 29 0a 20  "+m.group(1)]). 
53a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62                 b
53b0: 47 72 61 70 68 20 3d 20 54 72 75 65 0a 20 20 20  Graph = True.   
53c0: 20 20 20 20 20 20 20 20 20 6c 47 72 61 70 68 52           lGraphR
53d0: 75 6c 65 2e 61 70 70 65 6e 64 28 5b 69 2c 20 73  ule.append([i, s
53e0: 4c 69 6e 65 5d 29 0a 20 20 20 20 20 20 20 20 20  Line]).         
53f0: 20 20 20 62 47 72 61 70 68 20 3d 20 54 72 75 65     bGraph = True
5400: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 73 4c  .        elif sL
5410: 69 6e 65 2e 73 74 61 72 74 73 77 69 74 68 28 22  ine.startswith("
5420: 40 40 40 40 45 4e 44 5f 47 52 41 50 48 22 29 3a  @@@@END_GRAPH"):
5430: 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 6c 47  .            #lG
5440: 72 61 70 68 52 75 6c 65 2e 61 70 70 65 6e 64 28  raphRule.append(
5450: 5b 69 2c 20 73 4c 69 6e 65 5d 29 0a 20 20 20 20  [i, sLine]).    
5460: 20 20 20 20 20 20 20 20 70 72 69 6e 74 42 6f 6f          printBoo
5470: 6b 6d 61 72 6b 28 30 2c 20 22 45 4e 44 47 52 41  kmark(0, "ENDGRA
5480: 50 48 22 2c 20 69 29 0a 20 20 20 20 20 20 20 20  PH", i).        
5490: 20 20 20 20 62 47 72 61 70 68 20 3d 20 46 61 6c      bGraph = Fal
54a0: 73 65 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  se.        elif 
54b0: 72 65 2e 6d 61 74 63 68 28 22 40 40 40 40 20 2a  re.match("@@@@ *
54c0: 24 22 2c 20 73 4c 69 6e 65 29 3a 0a 20 20 20 20  $", sLine):.    
54d0: 20 20 20 20 20 20 20 20 70 61 73 73 0a 20 20 20          pass.   
54e0: 20 20 20 20 20 65 6c 69 66 20 62 47 72 61 70 68       elif bGraph
54f0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 47  :.            lG
5500: 72 61 70 68 52 75 6c 65 2e 61 70 70 65 6e 64 28  raphRule.append(
5510: 5b 69 2c 20 73 4c 69 6e 65 5d 29 0a 20 20 20 20  [i, sLine]).    
5520: 20 20 20 20 23 20 52 65 67 65 78 20 72 75 6c 65      # Regex rule
5530: 73 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 72  s.        elif r
5540: 65 2e 6d 61 74 63 68 28 22 5b 20 c2 a0 5c 74 5d  e.match("[ ..\t]
5550: 2a 24 22 2c 20 73 4c 69 6e 65 29 3a 0a 20 20 20  *$", sLine):.   
5560: 20 20 20 20 20 20 20 20 20 23 20 65 6d 70 74 79           # empty
5570: 20 6c 69 6e 65 0a 20 20 20 20 20 20 20 20 20 20   line.          
5580: 20 20 70 61 73 73 0a 20 20 20 20 20 20 20 20 65    pass.        e
5590: 6c 69 66 20 73 4c 69 6e 65 2e 73 74 61 72 74 73  lif sLine.starts
55a0: 77 69 74 68 28 28 22 20 20 20 20 22 2c 20 22 5c  with(("    ", "\
55b0: 74 22 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20  t")):.          
55c0: 20 20 23 20 72 75 6c 65 20 28 63 6f 6e 74 69 6e    # rule (contin
55d0: 75 61 74 69 6f 6e 29 0a 20 20 20 20 20 20 20 20  uation).        
55e0: 20 20 20 20 6c 52 75 6c 65 4c 69 6e 65 5b 2d 31      lRuleLine[-1
55f0: 5d 5b 31 5d 20 2b 3d 20 22 20 22 20 2b 20 73 4c  ][1] += " " + sL
5600: 69 6e 65 2e 73 74 72 69 70 28 29 0a 20 20 20 20  ine.strip().    
5610: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
5620: 20 20 20 20 20 20 23 20 6e 65 77 20 72 75 6c 65        # new rule
5630: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 52 75  .            lRu
5640: 6c 65 4c 69 6e 65 2e 61 70 70 65 6e 64 28 5b 69  leLine.append([i
5650: 2c 20 73 4c 69 6e 65 2e 73 74 72 69 70 28 29 5d  , sLine.strip()]
5660: 29 0a 0a 20 20 20 20 23 20 67 65 6e 65 72 61 74  )..    # generat
5670: 69 6e 67 20 6f 70 74 69 6f 6e 73 20 66 69 6c 65  ing options file
5680: 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 70  s.    print("  p
5690: 61 72 73 69 6e 67 20 6f 70 74 69 6f 6e 73 2e 2e  arsing options..
56a0: 2e 22 29 0a 20 20 20 20 64 4f 70 74 69 6f 6e 73  .").    dOptions
56b0: 2c 20 64 4f 70 74 50 72 69 6f 72 69 74 79 20 3d  , dOptPriority =
56c0: 20 70 72 65 70 61 72 65 4f 70 74 69 6f 6e 73 28   prepareOptions(
56d0: 6c 4f 70 74 29 0a 0a 20 20 20 20 23 20 74 65 73  lOpt)..    # tes
56e0: 74 73 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20  ts.    print("  
56f0: 6c 69 73 74 20 74 65 73 74 73 2e 2e 2e 22 29 0a  list tests...").
5700: 20 20 20 20 73 47 43 54 65 73 74 73 20 3d 20 22      sGCTests = "
5710: 5c 6e 22 2e 6a 6f 69 6e 28 6c 54 65 73 74 29 0a  \n".join(lTest).
5720: 20 20 20 20 73 47 43 54 65 73 74 73 4a 53 20 3d      sGCTestsJS =
5730: 20 27 7b 20 22 61 44 61 74 61 22 3a 20 27 20 2b   '{ "aData": ' +
5740: 20 6a 73 6f 6e 2e 64 75 6d 70 73 28 6c 54 65 73   json.dumps(lTes
5750: 74 2c 20 65 6e 73 75 72 65 5f 61 73 63 69 69 3d  t, ensure_ascii=
5760: 46 61 6c 73 65 29 20 2b 20 22 20 7d 5c 6e 22 0a  False) + " }\n".
5770: 0a 20 20 20 20 23 20 70 72 6f 63 65 73 73 69 6e  .    # processin
5780: 67 0a 20 20 20 20 70 72 69 6e 74 28 22 20 20 70  g.    print("  p
5790: 72 65 70 61 72 69 6e 67 20 72 75 6c 65 73 2e 2e  reparing rules..
57a0: 2e 22 29 0a 20 20 20 20 62 50 61 72 61 67 72 61  .").    bParagra
57b0: 70 68 20 3d 20 54 72 75 65 0a 20 20 20 20 6c 50  ph = True.    lP
57c0: 61 72 61 67 72 61 70 68 52 75 6c 65 73 20 3d 20  aragraphRules = 
57d0: 5b 5d 0a 20 20 20 20 6c 53 65 6e 74 65 6e 63 65  [].    lSentence
57e0: 52 75 6c 65 73 20 3d 20 5b 5d 0a 20 20 20 20 6c  Rules = [].    l
57f0: 50 61 72 61 67 72 61 70 68 52 75 6c 65 73 4a 53  ParagraphRulesJS
5800: 20 3d 20 5b 5d 0a 20 20 20 20 6c 53 65 6e 74 65   = [].    lSente
5810: 6e 63 65 52 75 6c 65 73 4a 53 20 3d 20 5b 5d 0a  nceRulesJS = [].
5820: 0a 20 20 20 20 66 6f 72 20 6e 4c 69 6e 65 2c 20  .    for nLine, 
5830: 73 4c 69 6e 65 20 69 6e 20 6c 52 75 6c 65 4c 69  sLine in lRuleLi
5840: 6e 65 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  ne:.        if s
5850: 4c 69 6e 65 3a 0a 20 20 20 20 20 20 20 20 20 20  Line:.          
5860: 20 20 69 66 20 73 4c 69 6e 65 20 3d 3d 20 22 5b    if sLine == "[
5870: 2b 2b 5d 22 3a 0a 20 20 20 20 20 20 20 20 20 20  ++]":.          
5880: 20 20 20 20 20 20 62 50 61 72 61 67 72 61 70 68        bParagraph
5890: 20 3d 20 46 61 6c 73 65 0a 20 20 20 20 20 20 20   = False.       
58a0: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
58b0: 20 20 20 20 20 20 20 20 20 20 20 61 52 75 6c 65             aRule
58c0: 20 3d 20 63 72 65 61 74 65 52 75 6c 65 28 73 4c   = createRule(sL
58d0: 69 6e 65 2c 20 6e 4c 69 6e 65 2c 20 73 4c 61 6e  ine, nLine, sLan
58e0: 67 2c 20 62 50 61 72 61 67 72 61 70 68 2c 20 64  g, bParagraph, d
58f0: 4f 70 74 50 72 69 6f 72 69 74 79 29 0a 20 20 20  OptPriority).   
5900: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
5910: 61 52 75 6c 65 3a 0a 20 20 20 20 20 20 20 20 20  aRule:.         
5920: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 62 50             if bP
5930: 61 72 61 67 72 61 70 68 3a 0a 20 20 20 20 20 20  aragraph:.      
5940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5950: 20 20 6c 50 61 72 61 67 72 61 70 68 52 75 6c 65    lParagraphRule
5960: 73 2e 61 70 70 65 6e 64 28 61 52 75 6c 65 29 0a  s.append(aRule).
5970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5980: 20 20 20 20 20 20 20 20 6c 50 61 72 61 67 72 61          lParagra
5990: 70 68 52 75 6c 65 73 4a 53 2e 61 70 70 65 6e 64  phRulesJS.append
59a0: 28 6a 73 63 6f 6e 76 2e 70 79 52 75 6c 65 54 6f  (jsconv.pyRuleTo
59b0: 4a 53 28 61 52 75 6c 65 2c 20 64 4a 53 52 45 47  JS(aRule, dJSREG
59c0: 45 58 45 53 2c 20 73 57 4f 52 44 4c 49 4d 49 54  EXES, sWORDLIMIT
59d0: 4c 45 46 54 29 29 0a 20 20 20 20 20 20 20 20 20  LEFT)).         
59e0: 20 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a             else:
59f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
5a00: 20 20 20 20 20 20 20 20 20 6c 53 65 6e 74 65 6e           lSenten
5a10: 63 65 52 75 6c 65 73 2e 61 70 70 65 6e 64 28 61  ceRules.append(a
5a20: 52 75 6c 65 29 0a 20 20 20 20 20 20 20 20 20 20  Rule).          
5a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 53                lS
5a40: 65 6e 74 65 6e 63 65 52 75 6c 65 73 4a 53 2e 61  entenceRulesJS.a
5a50: 70 70 65 6e 64 28 6a 73 63 6f 6e 76 2e 70 79 52  ppend(jsconv.pyR
5a60: 75 6c 65 54 6f 4a 53 28 61 52 75 6c 65 2c 20 64  uleToJS(aRule, d
5a70: 4a 53 52 45 47 45 58 45 53 2c 20 73 57 4f 52 44  JSREGEXES, sWORD
5a80: 4c 49 4d 49 54 4c 45 46 54 29 29 0a 0a 20 20 20  LIMITLEFT))..   
5a90: 20 23 20 63 72 65 61 74 69 6e 67 20 66 69 6c 65   # creating file
5aa0: 20 77 69 74 68 20 61 6c 6c 20 66 75 6e 63 74 69   with all functi
5ab0: 6f 6e 73 20 63 61 6c 6c 61 62 6c 65 20 62 79 20  ons callable by 
5ac0: 72 75 6c 65 73 0a 20 20 20 20 70 72 69 6e 74 28  rules.    print(
5ad0: 22 20 20 63 72 65 61 74 69 6e 67 20 63 61 6c 6c  "  creating call
5ae0: 61 62 6c 65 73 20 66 6f 72 20 72 65 67 65 78 20  ables for regex 
5af0: 72 75 6c 65 73 2e 2e 2e 22 29 0a 20 20 20 20 73  rules...").    s
5b00: 50 79 43 61 6c 6c 61 62 6c 65 73 20 3d 20 22 22  PyCallables = ""
5b10: 0a 20 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65  .    sJSCallable
5b20: 73 20 3d 20 22 22 0a 20 20 20 20 66 6f 72 20 73  s = "".    for s
5b30: 46 75 6e 63 4e 61 6d 65 2c 20 73 52 65 74 75 72  FuncName, sRetur
5b40: 6e 20 69 6e 20 6c 46 55 4e 43 54 49 4f 4e 53 3a  n in lFUNCTIONS:
5b50: 0a 20 20 20 20 20 20 20 20 69 66 20 73 46 75 6e  .        if sFun
5b60: 63 4e 61 6d 65 2e 73 74 61 72 74 73 77 69 74 68  cName.startswith
5b70: 28 22 5f 63 5f 22 29 3a 20 23 20 63 6f 6e 64 69  ("_c_"): # condi
5b80: 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20  tion.           
5b90: 20 73 50 61 72 61 6d 73 20 3d 20 22 73 53 65 6e   sParams = "sSen
5ba0: 74 65 6e 63 65 2c 20 73 53 65 6e 74 65 6e 63 65  tence, sSentence
5bb0: 30 2c 20 6d 2c 20 64 54 6f 6b 65 6e 50 6f 73 2c  0, m, dTokenPos,
5bc0: 20 73 43 6f 75 6e 74 72 79 2c 20 62 43 6f 6e 64   sCountry, bCond
5bd0: 4d 65 6d 6f 22 0a 20 20 20 20 20 20 20 20 65 6c  Memo".        el
5be0: 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e 73 74 61  if sFuncName.sta
5bf0: 72 74 73 77 69 74 68 28 22 5f 6d 5f 22 29 3a 20  rtswith("_m_"): 
5c00: 23 20 6d 65 73 73 61 67 65 0a 20 20 20 20 20 20  # message.      
5c10: 20 20 20 20 20 20 73 50 61 72 61 6d 73 20 3d 20        sParams = 
5c20: 22 73 53 65 6e 74 65 6e 63 65 2c 20 6d 22 0a 20  "sSentence, m". 
5c30: 20 20 20 20 20 20 20 65 6c 69 66 20 73 46 75 6e         elif sFun
5c40: 63 4e 61 6d 65 2e 73 74 61 72 74 73 77 69 74 68  cName.startswith
5c50: 28 22 5f 73 5f 22 29 3a 20 23 20 73 75 67 67 65  ("_s_"): # sugge
5c60: 73 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20  stion.          
5c70: 20 20 73 50 61 72 61 6d 73 20 3d 20 22 73 53 65    sParams = "sSe
5c80: 6e 74 65 6e 63 65 2c 20 6d 22 0a 20 20 20 20 20  ntence, m".     
5c90: 20 20 20 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d     elif sFuncNam
5ca0: 65 2e 73 74 61 72 74 73 77 69 74 68 28 22 5f 70  e.startswith("_p
5cb0: 5f 22 29 3a 20 23 20 70 72 65 70 72 6f 63 65 73  _"): # preproces
5cc0: 73 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20  sor.            
5cd0: 73 50 61 72 61 6d 73 20 3d 20 22 73 53 65 6e 74  sParams = "sSent
5ce0: 65 6e 63 65 2c 20 6d 22 0a 20 20 20 20 20 20 20  ence, m".       
5cf0: 20 65 6c 69 66 20 73 46 75 6e 63 4e 61 6d 65 2e   elif sFuncName.
5d00: 73 74 61 72 74 73 77 69 74 68 28 22 5f 64 5f 22  startswith("_d_"
5d10: 29 3a 20 23 20 64 69 73 61 6d 62 69 67 75 61 74  ): # disambiguat
5d20: 6f 72 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  or.            s
5d30: 50 61 72 61 6d 73 20 3d 20 22 73 53 65 6e 74 65  Params = "sSente
5d40: 6e 63 65 2c 20 6d 2c 20 64 54 6f 6b 65 6e 50 6f  nce, m, dTokenPo
5d50: 73 22 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a  s".        else:
5d60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  .            pri
5d70: 6e 74 28 22 23 20 55 6e 6b 6e 6f 77 6e 20 66 75  nt("# Unknown fu
5d80: 6e 63 74 69 6f 6e 20 74 79 70 65 20 69 6e 20 5b  nction type in [
5d90: 22 20 2b 20 73 46 75 6e 63 4e 61 6d 65 20 2b 20  " + sFuncName + 
5da0: 22 5d 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  "]").           
5db0: 20 63 6f 6e 74 69 6e 75 65 0a 20 20 20 20 20 20   continue.      
5dc0: 20 20 23 20 50 79 74 68 6f 6e 0a 20 20 20 20 20    # Python.     
5dd0: 20 20 20 73 50 79 43 61 6c 6c 61 62 6c 65 73 20     sPyCallables 
5de0: 2b 3d 20 22 64 65 66 20 7b 7d 20 28 7b 7d 29 3a  += "def {} ({}):
5df0: 5c 6e 22 2e 66 6f 72 6d 61 74 28 73 46 75 6e 63  \n".format(sFunc
5e00: 4e 61 6d 65 2c 20 73 50 61 72 61 6d 73 29 0a 20  Name, sParams). 
5e10: 20 20 20 20 20 20 20 73 50 79 43 61 6c 6c 61 62         sPyCallab
5e20: 6c 65 73 20 2b 3d 20 22 20 20 20 20 72 65 74 75  les += "    retu
5e30: 72 6e 20 22 20 2b 20 73 52 65 74 75 72 6e 20 2b  rn " + sReturn +
5e40: 20 22 5c 6e 22 0a 20 20 20 20 20 20 20 20 23 20   "\n".        # 
5e50: 4a 61 76 61 53 63 72 69 70 74 0a 20 20 20 20 20  JavaScript.     
5e60: 20 20 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20     sJSCallables 
5e70: 2b 3d 20 22 20 20 20 20 7b 7d 3a 20 66 75 6e 63  += "    {}: func
5e80: 74 69 6f 6e 20 28 7b 7d 29 22 2e 66 6f 72 6d 61  tion ({})".forma
5e90: 74 28 73 46 75 6e 63 4e 61 6d 65 2c 20 73 50 61  t(sFuncName, sPa
5ea0: 72 61 6d 73 29 20 2b 20 22 20 7b 5c 6e 22 0a 20  rams) + " {\n". 
5eb0: 20 20 20 20 20 20 20 73 4a 53 43 61 6c 6c 61 62         sJSCallab
5ec0: 6c 65 73 20 2b 3d 20 22 20 20 20 20 20 20 20 20  les += "        
5ed0: 72 65 74 75 72 6e 20 22 20 2b 20 6a 73 63 6f 6e  return " + jscon
5ee0: 76 2e 70 79 32 6a 73 28 73 52 65 74 75 72 6e 29  v.py2js(sReturn)
5ef0: 20 2b 20 22 3b 5c 6e 22 0a 20 20 20 20 20 20 20   + ";\n".       
5f00: 20 73 4a 53 43 61 6c 6c 61 62 6c 65 73 20 2b 3d   sJSCallables +=
5f10: 20 22 20 20 20 20 7d 2c 5c 6e 22 0a 0a 20 20 20   "    },\n"..   
5f20: 20 64 69 73 70 6c 61 79 53 74 61 74 73 28 6c 50   displayStats(lP
5f30: 61 72 61 67 72 61 70 68 52 75 6c 65 73 2c 20 6c  aragraphRules, l
5f40: 53 65 6e 74 65 6e 63 65 52 75 6c 65 73 29 0a 0a  SentenceRules)..
5f50: 20 20 20 20 70 72 69 6e 74 28 22 55 6e 6e 61 6d      print("Unnam
5f60: 65 64 20 72 75 6c 65 73 3a 20 22 20 2b 20 73 74  ed rules: " + st
5f70: 72 28 6e 52 55 4c 45 57 49 54 48 4f 55 54 4e 41  r(nRULEWITHOUTNA
5f80: 4d 45 29 29 0a 0a 20 20 20 20 64 56 61 72 73 20  ME))..    dVars 
5f90: 3d 20 7b 0a 20 20 20 20 20 20 20 20 22 66 42 75  = {.        "fBu
5fa0: 69 6c 64 54 69 6d 65 22 3a 20 66 42 75 69 6c 64  ildTime": fBuild
5fb0: 54 69 6d 65 2c 0a 20 20 20 20 20 20 20 20 22 63  Time,.        "c
5fc0: 61 6c 6c 61 62 6c 65 73 22 3a 20 73 50 79 43 61  allables": sPyCa
5fd0: 6c 6c 61 62 6c 65 73 2c 0a 20 20 20 20 20 20 20  llables,.       
5fe0: 20 22 63 61 6c 6c 61 62 6c 65 73 4a 53 22 3a 20   "callablesJS": 
5ff0: 73 4a 53 43 61 6c 6c 61 62 6c 65 73 2c 0a 20 20  sJSCallables,.  
6000: 20 20 20 20 20 20 22 67 63 74 65 73 74 73 22 3a        "gctests":
6010: 20 73 47 43 54 65 73 74 73 2c 0a 20 20 20 20 20   sGCTests,.     
6020: 20 20 20 22 67 63 74 65 73 74 73 4a 53 22 3a 20     "gctestsJS": 
6030: 73 47 43 54 65 73 74 73 4a 53 2c 0a 20 20 20 20  sGCTestsJS,.    
6040: 20 20 20 20 22 70 61 72 61 67 72 61 70 68 5f 72      "paragraph_r
6050: 75 6c 65 73 22 3a 20 6d 65 72 67 65 52 75 6c 65  ules": mergeRule
6060: 73 42 79 4f 70 74 69 6f 6e 28 6c 50 61 72 61 67  sByOption(lParag
6070: 72 61 70 68 52 75 6c 65 73 29 2c 0a 20 20 20 20  raphRules),.    
6080: 20 20 20 20 22 73 65 6e 74 65 6e 63 65 5f 72 75      "sentence_ru
6090: 6c 65 73 22 3a 20 6d 65 72 67 65 52 75 6c 65 73  les": mergeRules
60a0: 42 79 4f 70 74 69 6f 6e 28 6c 53 65 6e 74 65 6e  ByOption(lSenten
60b0: 63 65 52 75 6c 65 73 29 2c 0a 20 20 20 20 20 20  ceRules),.      
60c0: 20 20 22 70 61 72 61 67 72 61 70 68 5f 72 75 6c    "paragraph_rul
60d0: 65 73 5f 4a 53 22 3a 20 6a 73 63 6f 6e 76 2e 77  es_JS": jsconv.w
60e0: 72 69 74 65 52 75 6c 65 73 54 6f 4a 53 41 72 72  riteRulesToJSArr
60f0: 61 79 28 6d 65 72 67 65 52 75 6c 65 73 42 79 4f  ay(mergeRulesByO
6100: 70 74 69 6f 6e 28 6c 50 61 72 61 67 72 61 70 68  ption(lParagraph
6110: 52 75 6c 65 73 4a 53 29 29 2c 0a 20 20 20 20 20  RulesJS)),.     
6120: 20 20 20 22 73 65 6e 74 65 6e 63 65 5f 72 75 6c     "sentence_rul
6130: 65 73 5f 4a 53 22 3a 20 6a 73 63 6f 6e 76 2e 77  es_JS": jsconv.w
6140: 72 69 74 65 52 75 6c 65 73 54 6f 4a 53 41 72 72  riteRulesToJSArr
6150: 61 79 28 6d 65 72 67 65 52 75 6c 65 73 42 79 4f  ay(mergeRulesByO
6160: 70 74 69 6f 6e 28 6c 53 65 6e 74 65 6e 63 65 52  ption(lSentenceR
6170: 75 6c 65 73 4a 53 29 29 0a 20 20 20 20 7d 0a 20  ulesJS)).    }. 
6180: 20 20 20 64 56 61 72 73 2e 75 70 64 61 74 65 28     dVars.update(
6190: 64 4f 70 74 69 6f 6e 73 29 0a 0a 20 20 20 20 23  dOptions)..    #
61a0: 20 63 6f 6d 70 69 6c 65 20 67 72 61 70 68 20 72   compile graph r
61b0: 75 6c 65 73 0a 20 20 20 20 64 56 61 72 73 32 20  ules.    dVars2 
61c0: 3d 20 63 72 67 2e 6d 61 6b 65 28 6c 47 72 61 70  = crg.make(lGrap
61d0: 68 52 75 6c 65 2c 20 64 44 45 46 2c 20 73 4c 61  hRule, dDEF, sLa
61e0: 6e 67 2c 20 64 4f 70 74 50 72 69 6f 72 69 74 79  ng, dOptPriority
61f0: 29 0a 20 20 20 20 64 56 61 72 73 2e 75 70 64 61  ).    dVars.upda
6200: 74 65 28 64 56 61 72 73 32 29 0a 0a 20 20 20 20  te(dVars2)..    
6210: 77 69 74 68 20 6f 70 65 6e 28 22 5f 62 75 69 6c  with open("_buil
6220: 64 2f 64 61 74 61 5f 63 61 63 68 65 2e 6a 73 6f  d/data_cache.jso
6230: 6e 22 2c 20 22 77 22 2c 20 65 6e 63 6f 64 69 6e  n", "w", encodin
6240: 67 3d 22 75 74 66 2d 38 22 29 20 61 73 20 68 44  g="utf-8") as hD
6250: 73 74 3a 0a 20 20 20 20 20 20 20 20 68 44 73 74  st:.        hDst
6260: 2e 77 72 69 74 65 28 6a 73 6f 6e 2e 64 75 6d 70  .write(json.dump
6270: 73 28 64 56 61 72 73 2c 20 65 6e 73 75 72 65 5f  s(dVars, ensure_
6280: 61 73 63 69 69 3d 46 61 6c 73 65 29 29 0a 20 20  ascii=False)).  
6290: 20 20 72 65 74 75 72 6e 20 64 56 61 72 73 0a       return dVars.