Get rid of QRegExp

It is not available in PyQt6 and we anyway use the python re module
everywhere else
This commit is contained in:
Kovid Goyal 2021-11-19 19:36:18 +05:30
parent 93f3ef821b
commit 3bff1f494f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 95 additions and 96 deletions

View File

@ -5,10 +5,10 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__license__ = 'GPL v3'
import json, os, traceback
import json, os, traceback, re
from qt.core import (Qt, QDialog, QDialogButtonBox, QSyntaxHighlighter, QFont,
QRegExp, QApplication, QTextCharFormat, QColor, QCursor,
QApplication, QTextCharFormat, QColor, QCursor,
QIcon, QSize, QPalette, QLineEdit, QByteArray, QFontInfo,
QFontDatabase, QVBoxLayout, QTableWidget, QTableWidgetItem,
QComboBox, QAbstractItemView, QTextOption, QFontMetrics)
@ -42,9 +42,6 @@ class ParenPosition:
class TemplateHighlighter(QSyntaxHighlighter):
Config = {}
Rules = []
Formats = {}
BN_FACTOR = 1000
KEYWORDS = ["program", 'if', 'then', 'else', 'elif', 'fi', 'for', 'rof',
@ -52,44 +49,44 @@ class TemplateHighlighter(QSyntaxHighlighter):
def __init__(self, parent=None, builtin_functions=None):
super().__init__(parent)
self.initializeFormats()
TemplateHighlighter.Rules.append((QRegExp(
r"\b[a-zA-Z]\w*\b(?!\(|\s+\()"
r"|\$+#?[a-zA-Z]\w*"),
"identifier"))
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.initialize_rules(builtin_functions)
self.regenerate_paren_positions()
self.highlighted_paren = False
def initialize_rules(self, builtin_functions):
r = []
def a(a, b):
r.append((re.compile(a), b))
a(
r"\b[a-zA-Z]\w*\b(?!\(|\s+\()"
r"|\$+#?[a-zA-Z]\w*",
"identifier")
a(
"|".join([r"\b%s\b" % keyword for keyword in self.KEYWORDS]),
"keyword")
a(
"|".join([r"\b%s\b" % builtin for builtin in
(builtin_functions if builtin_functions else
formatter_functions().get_builtins())]),
"builtin")
a(
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")
a(r"""(?:[^:]'[^']*'|"[^"]*")""", "string")
a(r'\(', "lparen")
a(r'\)', "rparen")
self.Rules = tuple(r)
def initializeFormats(self):
font_name = gprefs.get('gpm_template_editor_font', None)
size = gprefs['gpm_template_editor_font_size']
@ -98,7 +95,7 @@ class TemplateHighlighter(QSyntaxHighlighter):
font.setFixedPitch(True)
font.setPointSize(size)
font_name = font.family()
Config = self.Config
Config = self.Config = {}
Config["fontfamily"] = font_name
pal = QApplication.instance().palette()
for name, color, bold, italic in (
@ -118,6 +115,7 @@ class TemplateHighlighter(QSyntaxHighlighter):
baseFormat.setFontFamily(Config["fontfamily"])
Config["fontsize"] = size
baseFormat.setFontPointSize(Config["fontsize"])
self.Formats = {}
for name in ("normal", "keyword", "builtin", "comment", "identifier",
"string", "number", "lparen", "rparen"):
@ -146,17 +144,15 @@ class TemplateHighlighter(QSyntaxHighlighter):
self.setFormat(0, textLength, self.Formats["comment"])
return
for regex, format_ in TemplateHighlighter.Rules:
i = regex.indexIn(text)
while i >= 0:
length = regex.matchedLength()
for regex, format_ in self.Rules:
for m in regex.finditer(text):
i, length = m.start(), m.end() - m.start()
if format_ in ['lparen', 'rparen']:
pp = self.find_paren(bn, i)
if pp and pp.highlight:
self.setFormat(i, length, self.Formats[format_])
else:
self.setFormat(i, length, self.Formats[format_])
i = regex.indexIn(text, i + length)
if self.generate_paren_positions:
t = str(text)
@ -178,7 +174,7 @@ class TemplateHighlighter(QSyntaxHighlighter):
i = len(t)
else:
i = i + j
elif c in ['(', ')']:
elif c in ('(', ')'):
pp = ParenPosition(bn, i, c)
self.paren_positions.append(pp)
self.paren_pos_map[bn*self.BN_FACTOR+i] = pp
@ -186,7 +182,7 @@ class TemplateHighlighter(QSyntaxHighlighter):
def rehighlight(self):
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
QSyntaxHighlighter.rehighlight(self)
super().rehighlight()
QApplication.restoreOverrideCursor()
def check_cursor_pos(self, chr_, block, pos_in_block):
@ -196,7 +192,7 @@ class TemplateHighlighter(QSyntaxHighlighter):
if pp.block == block and pp.pos == pos_in_block:
found_pp = i
if chr_ not in ['(', ')']:
if chr_ not in ('(', ')'):
if self.highlighted_paren:
self.rehighlight()
self.highlighted_paren = False
@ -887,7 +883,8 @@ class EmbeddedTemplateDialog(TemplateDialog):
if __name__ == '__main__':
app = QApplication([])
from calibre.gui2 import Application
app = Application([])
from calibre.ebooks.metadata.book.base import field_metadata
d = TemplateDialog(None, '{title}', fm=field_metadata)
d.exec_()

View File

@ -8,7 +8,7 @@ import re, os
from qt.core import (QIcon, QFont, QLabel, QListWidget, QAction, QEvent,
QListWidgetItem, QTextCharFormat, QApplication, QSyntaxHighlighter,
QCursor, QColor, QWidget, QPixmap, QSplitterHandle, QToolButton,
Qt, pyqtSignal, QRegExp, QSize, QSplitter, QPainter, QPageSize, QPrinter,
Qt, pyqtSignal, QSize, QSplitter, QPainter, QPageSize, QPrinter,
QLineEdit, QComboBox, QPen, QGraphicsScene, QMenu, QStringListModel, QKeySequence,
QCompleter, QTimer, QRect, QGraphicsView, QPagedPaintDevice, QPalette, QClipboard)
@ -810,7 +810,7 @@ class EncodingComboBox(QComboBox): # {{{
class PythonHighlighter(QSyntaxHighlighter): # {{{
Rules = []
Rules = ()
Formats = {}
KEYWORDS = ["and", "as", "assert", "break", "class", "continue", "def",
@ -834,34 +834,41 @@ class PythonHighlighter(QSyntaxHighlighter): # {{{
def __init__(self, parent=None):
super().__init__(parent)
if not self.Rules:
self.initialize_class_members()
self.initializeFormats()
@classmethod
def initialize_class_members(cls):
cls.initializeFormats()
r = []
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(
def a(a, b):
r.append((a, b))
a(re.compile(
"|".join([r"\b%s\b" % keyword for keyword in cls.KEYWORDS])),
"keyword")
a(re.compile(
"|".join([r"\b%s\b" % builtin for builtin in cls.BUILTINS])),
"builtin")
a(re.compile(
"|".join([r"\b%s\b" % constant
for constant in self.CONSTANTS])), "constant"))
PythonHighlighter.Rules.append((QRegExp(
for constant in cls.CONSTANTS])), "constant")
a(re.compile(
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'''"""(?!')''')
"number")
a(re.compile(
r"\bPyQt5\b|\bQt?[A-Z][a-z]\w+\b"), "pyqt")
a(re.compile(r"\b@\w+\b"), "decorator")
stringRe = re.compile(r"""(?:'[^']*?'|"[^"]*?")""")
a(stringRe, "string")
cls.stringRe = re.compile(r"""(:?"["]".*?"["]"|'''.*?''')""")
a(cls.stringRe, "string")
cls.tripleSingleRe = re.compile(r"""'''(?!")""")
cls.tripleDoubleRe = re.compile(r'''"""(?!')''')
cls.Rules = tuple(r)
@classmethod
def initializeFormats(cls):
@ -896,36 +903,31 @@ class PythonHighlighter(QSyntaxHighlighter): # {{{
prevState = self.previousBlockState()
self.setFormat(0, textLength,
PythonHighlighter.Formats["normal"])
self.Formats["normal"])
if text.startswith("Traceback") or text.startswith("Error: "):
self.setCurrentBlockState(ERROR)
self.setFormat(0, textLength,
PythonHighlighter.Formats["error"])
self.Formats["error"])
return
if prevState == ERROR and \
not (text.startswith('>>>') or text.startswith("#")):
self.setCurrentBlockState(ERROR)
self.setFormat(0, textLength,
PythonHighlighter.Formats["error"])
self.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)
for regex, fmt in PythonHighlighter.Rules:
for m in regex.finditer(text):
self.setFormat(m.start(), m.end() - m.start(), self.Formats[fmt])
# 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"))
# PythonHighlighter.Rules.append((re.compile(r"#.*"), "comment"))
if not text:
pass
elif text[0] == "#":
self.setFormat(0, len(text),
PythonHighlighter.Formats["comment"])
self.setFormat(0, len(text), self.Formats["comment"])
else:
stack = []
for i, c in enumerate(text):
@ -935,33 +937,33 @@ class PythonHighlighter(QSyntaxHighlighter): # {{{
else:
stack.append(c)
elif c == "#" and len(stack) == 0:
self.setFormat(i, len(text),
PythonHighlighter.Formats["comment"])
self.setFormat(i, len(text), self.Formats["comment"])
break
self.setCurrentBlockState(NORMAL)
if self.stringRe.indexIn(text) != -1:
if self.stringRe.search(text) is not None:
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)):
for m, state in (
(self.tripleSingleRe.search(text), TRIPLESINGLE),
(self.tripleDoubleRe.search(text), TRIPLEDOUBLE)
):
i = -1 if m is None else m.start()
if self.previousBlockState() == state:
if i == -1:
i = len(text)
self.setCurrentBlockState(state)
self.setFormat(0, i + 3,
PythonHighlighter.Formats["string"])
self.Formats["string"])
elif i > -1:
self.setCurrentBlockState(state)
self.setFormat(i, len(text),
PythonHighlighter.Formats["string"])
self.Formats["string"])
def rehighlight(self):
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
QSyntaxHighlighter.rehighlight(self)
super().rehighlight()
QApplication.restoreOverrideCursor()
# }}}