mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
93f3ef821b
commit
3bff1f494f
@ -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_()
|
||||
|
@ -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()
|
||||
|
||||
# }}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user