def __init__(self, parent=None): super().__init__(parent) self.initializeFormats() PythonHighlighter.Rules.append((QRegExp("|".join( [r"\b%s\b" % keyword for keyword in self.KEYWORDS])), "keyword")) PythonHighlighter.Rules.append((QRegExp("|".join( [r"\b%s\b" % builtin for builtin in self.BUILTINS])), "builtin")) PythonHighlighter.Rules.append((QRegExp("|".join([ r"\b%s\b" % constant for constant in self.CONSTANTS ])), "constant")) PythonHighlighter.Rules.append( (QRegExp(r"\b[+-]?[0-9]+[lL]?\b" r"|\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b" r"|\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"), "number")) PythonHighlighter.Rules.append( (QRegExp(r"\bPyQt5\b|\bQt?[A-Z][a-z]\w+\b"), "pyqt")) PythonHighlighter.Rules.append((QRegExp(r"\b@\w+\b"), "decorator")) stringRe = QRegExp(r"""(?:'[^']*'|"[^"]*")""") stringRe.setMinimal(True) PythonHighlighter.Rules.append((stringRe, "string")) self.stringRe = QRegExp(r"""(:?"["]".*"["]"|'''.*''')""") self.stringRe.setMinimal(True) PythonHighlighter.Rules.append((self.stringRe, "string")) self.tripleSingleRe = QRegExp(r"""'''(?!")""") self.tripleDoubleRe = QRegExp(r'''"""(?!')''')
def __init__(self, parent=None, builtin_functions=None): super(TemplateHighlighter, self).__init__(parent) self.initializeFormats() TemplateHighlighter.Rules.append((QRegExp( "|".join([r"\b%s\b" % keyword for keyword in self.KEYWORDS])), "keyword")) TemplateHighlighter.Rules.append((QRegExp( "|".join([r"\b%s\b" % builtin for builtin in (builtin_functions if builtin_functions else formatter_functions().get_builtins())])), "builtin")) TemplateHighlighter.Rules.append((QRegExp( r"\b[+-]?[0-9]+[lL]?\b" r"|\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b" r"|\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"), "number")) stringRe = QRegExp(r"""(?:[^:]'[^']*'|"[^"]*")""") stringRe.setMinimal(True) TemplateHighlighter.Rules.append((stringRe, "string")) lparenRe = QRegExp(r'\(') lparenRe.setMinimal(True) TemplateHighlighter.Rules.append((lparenRe, "lparen")) rparenRe = QRegExp(r'\)') rparenRe.setMinimal(True) TemplateHighlighter.Rules.append((rparenRe, "rparen")) self.regenerate_paren_positions() self.highlighted_paren = False
class PythonHighlighter(QSyntaxHighlighter): # {{{ Rules = [] Formats = {} KEYWORDS = [ "and", "as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "exec", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "not", "or", "pass", "print", "raise", "return", "try", "while", "with", "yield" ] BUILTINS = [ "abs", "all", "any", "basestring", "bool", "callable", "chr", "classmethod", "cmp", "compile", "complex", "delattr", "dict", "dir", "divmod", "enumerate", "eval", "execfile", "exit", "file", "filter", "float", "frozenset", "getattr", "globals", "hasattr", "hex", "id", "int", "isinstance", "issubclass", "iter", "len", "list", "locals", "long", "map", "max", "min", "object", "oct", "open", "ord", "pow", "property", "range", "reduce", "repr", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str", "sum", "super", "tuple", "type", "unichr", "unicode", "vars", "xrange", "zip" ] CONSTANTS = ["False", "True", "None", "NotImplemented", "Ellipsis"] def __init__(self, parent=None): super().__init__(parent) self.initializeFormats() PythonHighlighter.Rules.append((QRegExp("|".join( [r"\b%s\b" % keyword for keyword in self.KEYWORDS])), "keyword")) PythonHighlighter.Rules.append((QRegExp("|".join( [r"\b%s\b" % builtin for builtin in self.BUILTINS])), "builtin")) PythonHighlighter.Rules.append((QRegExp("|".join([ r"\b%s\b" % constant for constant in self.CONSTANTS ])), "constant")) PythonHighlighter.Rules.append( (QRegExp(r"\b[+-]?[0-9]+[lL]?\b" r"|\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b" r"|\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b"), "number")) PythonHighlighter.Rules.append( (QRegExp(r"\bPyQt5\b|\bQt?[A-Z][a-z]\w+\b"), "pyqt")) PythonHighlighter.Rules.append((QRegExp(r"\b@\w+\b"), "decorator")) stringRe = QRegExp(r"""(?:'[^']*'|"[^"]*")""") stringRe.setMinimal(True) PythonHighlighter.Rules.append((stringRe, "string")) self.stringRe = QRegExp(r"""(:?"["]".*"["]"|'''.*''')""") self.stringRe.setMinimal(True) PythonHighlighter.Rules.append((self.stringRe, "string")) self.tripleSingleRe = QRegExp(r"""'''(?!")""") self.tripleDoubleRe = QRegExp(r'''"""(?!')''') @classmethod def initializeFormats(cls): baseFormat = QTextCharFormat() baseFormat.setFontFamily('monospace') p = QApplication.instance().palette() for name, color, bold, italic in ( ("normal", None, False, False), ("keyword", p.color(QPalette.ColorRole.Link).name(), True, False), ("builtin", p.color(QPalette.ColorRole.Link).name(), False, False), ("constant", p.color(QPalette.ColorRole.Link).name(), False, False), ("decorator", "#0000E0", False, False), ("comment", "#007F00", False, True), ("string", "#808000", False, False), ("number", "#924900", False, False), ("error", "#FF0000", False, False), ("pyqt", "#50621A", False, False)): fmt = QTextCharFormat(baseFormat) if color is not None: fmt.setForeground(QColor(color)) if bold: fmt.setFontWeight(QFont.Weight.Bold) if italic: fmt.setFontItalic(italic) cls.Formats[name] = fmt def highlightBlock(self, text): NORMAL, TRIPLESINGLE, TRIPLEDOUBLE, ERROR = range(4) textLength = len(text) prevState = self.previousBlockState() self.setFormat(0, textLength, PythonHighlighter.Formats["normal"]) if text.startswith("Traceback") or text.startswith("Error: "): self.setCurrentBlockState(ERROR) self.setFormat(0, textLength, PythonHighlighter.Formats["error"]) return if prevState == ERROR and \ not (text.startswith('>>>') or text.startswith("#")): self.setCurrentBlockState(ERROR) self.setFormat(0, textLength, PythonHighlighter.Formats["error"]) return for regex, format in PythonHighlighter.Rules: i = regex.indexIn(text) while i >= 0: length = regex.matchedLength() self.setFormat(i, length, PythonHighlighter.Formats[format]) i = regex.indexIn(text, i + length) # Slow but good quality highlighting for comments. For more # speed, comment this out and add the following to __init__: # PythonHighlighter.Rules.append((QRegExp(r"#.*"), "comment")) if not text: pass elif text[0] == "#": self.setFormat(0, len(text), PythonHighlighter.Formats["comment"]) else: stack = [] for i, c in enumerate(text): if c in ('"', "'"): if stack and stack[-1] == c: stack.pop() else: stack.append(c) elif c == "#" and len(stack) == 0: self.setFormat(i, len(text), PythonHighlighter.Formats["comment"]) break self.setCurrentBlockState(NORMAL) if self.stringRe.indexIn(text) != -1: return # This is fooled by triple quotes inside single quoted strings for i, state in ((self.tripleSingleRe.indexIn(text), TRIPLESINGLE), (self.tripleDoubleRe.indexIn(text), TRIPLEDOUBLE)): if self.previousBlockState() == state: if i == -1: i = len(text) self.setCurrentBlockState(state) self.setFormat(0, i + 3, PythonHighlighter.Formats["string"]) elif i > -1: self.setCurrentBlockState(state) self.setFormat(i, len(text), PythonHighlighter.Formats["string"]) def rehighlight(self): QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor)) QSyntaxHighlighter.rehighlight(self) QApplication.restoreOverrideCursor()