Index: compile_rules.py ================================================================== --- compile_rules.py +++ compile_rules.py @@ -24,19 +24,22 @@ sWORDLIMITLEFT = r"(? int" return (r & 255) << 16 | (g & 255) << 8 | (b & 255) def convertHSLToRBG (h, s, l): + "hsl (int, int, int) -> [int, int, int]" r, g, b = colorsys.hls_to_rgb(h/360, l/100, s/100) return [round(r*255), round(g*255), round(b*255)] def createColors (dColor): + "dictionary of colors {color_name: [h, s, l]} -> returns dictionary of colors as dictionaries of color types" dColorType = { "sCSS": {}, # dictionary of colors as strings for HTML/CSS (example: hsl(0, 50%, 50%)) "aRGB": {}, # dictionary of colors as RGB tuple "nInt": {} # dictionary of colors as integer values (for Writer) } @@ -78,37 +81,36 @@ s = re.sub(r"\bspell *[(]", '_oSpellChecker.isValid(', s) s = re.sub(r"[\\](\d+)", 'm.group(\\1)', s) return s -def uppercase (s, sLang): +def uppercase (sText, sLang): "(flag i is not enough): converts regex to uppercase regex: 'foo' becomes '[Ff][Oo][Oo]', but 'Bar' becomes 'B[Aa][Rr]'." sUp = "" nState = 0 - for i in range(0, len(s)): - c = s[i] + for i, c in enumerate(sText): if c == "[": nState = 1 if nState == 1 and c == "]": nState = 0 - if c == "<" and i > 3 and s[i-3:i] == "(?P": + if c == "<" and i > 3 and sText[i-3:i] == "(?P": nState = 2 if nState == 2 and c == ">": nState = 0 - if c == "?" and i > 0 and s[i-1:i] == "(" and s[i+1:i+2] != ":": + if c == "?" and i > 0 and sText[i-1:i] == "(" and sText[i+1:i+2] != ":": nState = 5 if nState == 5 and c == ")": nState = 0 if c.isalpha() and c.islower() and nState == 0: - if c == "i" and (sLang == "tr" or sLang == "az"): + if c == "i" and sLang in ("tr", "az"): sUp += "[İ" + c + "]" else: sUp += "[" + c.upper() + c + "]" - elif c.isalpha() and c.islower() and nState == 1 and s[i+1:i+2] != "-": - if s[i-1:i] == "-" and s[i-2:i-1].islower(): # [a-z] -> [a-zA-Z] - sUp += c + s[i-2:i-1].upper() + "-" + c.upper() - elif c == "i" and (sLang == "tr" or sLang == "az"): + elif c.isalpha() and c.islower() and nState == 1 and sText[i+1:i+2] != "-": + if sText[i-1:i] == "-" and sText[i-2:i-1].islower(): # [a-z] -> [a-zA-Z] + sUp += c + sText[i-2:i-1].upper() + "-" + c.upper() + elif c == "i" and sLang in ("tr", "az"): sUp += "İ" + c else: sUp += c.upper() + c else: sUp += c @@ -121,11 +123,11 @@ def countGroupInRegex (sRegex): "returns the number of groups in " try: return re.compile(sRegex).groups - except: + except re.error: traceback.print_exc() print(sRegex) return 0 @@ -233,17 +235,16 @@ print("# Unknown case mode [" + cCaseMode + "] at line " + sLineId) ## check regex try: re.compile(sRegex) - except: + except re.error: print("# Regex error at line ", nIdLine) print(sRegex) - traceback.print_exc() return None ## groups in non grouping parenthesis - for x in re.finditer(r"\(\?:[^)]*\([\[\w -]", sRegex): + for _ in re.finditer(r"\(\?:[^)]*\([\[\w -]", sRegex): print("# Warning: groups inside non grouping parenthesis in regex at line " + sLineId) #### PARSE ACTIONS lActions = [] nAction = 1 @@ -346,31 +347,30 @@ elif sAction.startswith('"') and sAction.endswith('"'): sAction = sAction[1:-1] if not sMsg: print("# Error in action at line " + sIdAction + ": the message is empty.") return [sCondition, cAction, sAction, iGroup, sMsg, sURL] - elif cAction == "~": + if cAction == "~": ## text processor if sAction[0:1] == "=": lFUNCTIONS.append(("_p_"+sIdAction, sAction[1:])) sAction = "=_p_"+sIdAction elif sAction.startswith('"') and sAction.endswith('"'): sAction = sAction[1:-1] return [sCondition, cAction, sAction, iGroup] - elif cAction == "=": + if cAction == "=": ## disambiguator if sAction[0:1] == "=": sAction = sAction[1:] if "define" in sAction and not re.search(r"define\(dTokenPos, *m\.start.*, \[.*\] *\)", sAction): print("# Error in action at line " + sIdAction + ": second argument for define must be a list of strings") print(sAction) lFUNCTIONS.append(("_d_"+sIdAction, sAction)) sAction = "_d_"+sIdAction return [sCondition, cAction, sAction] - else: - print("# Unknown action at line " + sIdAction) - return None + print("# Unknown action at line " + sIdAction) + return None def _calcRulesStats (lRules): "count rules and actions" d = {'=':0, '~': 0, '-': 0, '>': 0} @@ -395,11 +395,11 @@ lFinal = [] lTemp = [] sOption = None for aRule in lRules: if aRule[0] != sOption: - if sOption != None: + if sOption is not None: lFinal.append([sOption, lTemp]) # new tuple sOption = aRule[0] lTemp = [] lTemp.append(aRule[1:]) @@ -425,11 +425,11 @@ elif sLine.startswith("OPTSOFTWARE:"): lOpt = [ [s, {}] for s in sLine[12:].strip().split() ] # don’t use tuples (s, {}), because unknown to JS elif sLine.startswith("OPT/"): m = re.match("OPT/([a-z0-9]+):(.+)$", sLine) for i, sOpt in enumerate(m.group(2).split()): - lOpt[i][1][m.group(1)] = eval(sOpt) + lOpt[i][1][m.group(1)] = sOpt in ("True", "true", "Yes", "yes") elif sLine.startswith("OPTCOLORTHEME:"): lOptColor = [ [s, {}] for s in sLine[14:].strip().split() ] # don’t use tuples (s, {}), because unknown to JS elif sLine.startswith("OPTCOLOR/"): m = re.match("OPTCOLOR/([a-z0-9]+):(.+)$", sLine) for i, sColor in enumerate(m.group(2).split()): @@ -481,11 +481,11 @@ fBuildTime = time.time() print("> read rules file...") try: lRules = open(spLang + "/rules.grx", 'r', encoding="utf-8").readlines() - except: + except OSError: print("Error. Rules file in project [" + sLang + "] not found.") exit() # removing comments, zeroing empty lines, creating definitions, storing tests, merging rule lines print(" parsing rules...") @@ -558,15 +558,11 @@ # new rule lRuleLine.append([i, sLine.strip()]) # generating options files print(" parsing options...") - try: - dOptions, dOptPriority = prepareOptions(lOpt) - except: - traceback.print_exc() - exit() + dOptions, dOptPriority = prepareOptions(lOpt) # tests print(" list tests...") sGCTests = "\n".join(lTest) sGCTestsJS = '{ "aData": ' + json.dumps(lTest, ensure_ascii=False) + " }\n"