Add Qt syntax highlighting.

This commit is contained in:
Bastian Kleineidam 2011-04-26 21:31:45 +02:00
parent 66079549ef
commit d7d563bf6e
6 changed files with 112 additions and 12 deletions

View file

@ -142,6 +142,7 @@ doccheck:
linkcheck/gui/properties.py \
linkcheck/gui/settings.py \
linkcheck/gui/statistics.py \
linkcheck/gui/syntax.py \
linkcheck/gui/updater.py \
linkcheck/gui/urlmodel.py \
linkcheck/gui/urlsave.py \

View file

@ -1,5 +1,9 @@
6.9 "" (released xx.xx.2011)
Features:
- gui: Add syntax highlighting for Qt editor in case QScintilla
is not installed.
6.8 "Ghost in the shell" (released 26.4.2011)

View file

@ -50,13 +50,7 @@ class EditorWindow (QtGui.QDialog, Ui_EditorDialog):
def setContentType (self, content_type):
"""Choose a lexer according to given content type."""
lexerclass = ContentTypeLexers.get(content_type.lower())
if lexerclass:
lexer = lexerclass()
lexer.setFont(self.editor.font())
self.editor.setLexer(lexer)
else:
# use no styling
self.editor.setLexer()
self.editor.highlight(lexerclass)
def setText (self, text, line=1, col=1):
"""Set editor text and jump to given line and column."""

View file

@ -97,3 +97,13 @@ class Editor (Qsci.QsciScintilla):
# folding margin colors (foreground,background)
self.setFoldMarginColors(QtGui.QColor("#f5f5dc"),
QtGui.QColor("#aaaaaa"))
def highlight (self, lexerclass):
"""Set syntax highlighter."""
if lexerclass:
lexer = lexerclass()
lexer.setFont(self.font())
self.setLexer(lexer)
else:
# use no styling
self.setLexer()

View file

@ -18,9 +18,14 @@
Text editor implemented with Qt
"""
from PyQt4 import QtGui, QtCore
from . import syntax
# Empty lexer dictionary indicating no support for syntax highlighting
ContentTypeLexers = {}
# Map MIME type to QSyntaxHighlighter class
ContentTypeLexers = {
"text/html": syntax.HtmlHighlighter,
"application/xml": syntax.XmlHighlighter,
"text/plain+ini": syntax.IniHighlighter,
}
class LineNumberArea (QtGui.QWidget):
"""Display line numbers."""
@ -50,9 +55,12 @@ class Editor (QtGui.QPlainTextEdit):
self.updateLineNumberAreaWidth(0)
self.highlightCurrentLine()
def setLexer (self):
"""Does nothing."""
pass
def highlight (self, lexerclass):
"""Set syntax highlighter."""
if lexerclass:
self.lexer = lexerclass(self.document())
else:
self.lexer = None
def setText (self, text):
"""Set editor text."""

83
linkcheck/gui/syntax.py Normal file
View file

@ -0,0 +1,83 @@
# syntax.py
from PyQt4 import QtCore, QtGui
def format(color, style=''):
"""Return a QTextCharFormat with the given attributes."""
format = QtGui.QTextCharFormat()
format.setForeground(getattr(QtCore.Qt, color))
if 'bold' in style:
format.setFontWeight(QtGui.QFont.Bold)
if 'italic' in style:
format.setFontItalic(True)
return format
class Highlighter (QtGui.QSyntaxHighlighter):
"""Base class for all highlighters."""
def __init__ (self, document):
"""Initialize rules and styles."""
super(Highlighter, self).__init__(document)
self.rules = []
self.styles = {}
def highlightBlock(self, text):
"""Highlight a text block."""
for expression, format in self.rules:
# get first match
index = expression.indexIn(text)
while index >= 0:
length = expression.matchedLength()
self.setFormat(index, length, format)
# jump to next match
index = expression.indexIn(text, index + length)
self.setCurrentBlockState(0)
def addRule (self, pattern, style):
"""Add a rule pattern with given style."""
self.rules.append((QtCore.QRegExp(pattern), self.styles[style]))
class XmlHighlighter (Highlighter):
"""XML syntax highlighter."""
def __init__(self, document):
"""Set XML syntax rules."""
super(XmlHighlighter, self).__init__(document)
self.styles.update({
'keyword': format('darkBlue'),
'attribute': format('darkGreen'),
'comment': format('darkYellow'),
'string': format('darkMagenta'),
})
# keywords
for reg in ('/>', '>', '<!?[a-zA-Z0-9_]+'):
self.addRule(reg, 'keyword')
# attributes
self.addRule(r"\b[A-Za-z0-9_]+(?=\s*\=)", 'attribute')
# double-quoted string, possibly containing escape sequences
self.addRule(r'"[^"\\]*(\\.[^"\\]*)*"', 'string')
# single-quoted string, possibly containing escape sequences
self.addRule(r"'[^'\\]*(\\.[^'\\]*)*'", 'string')
# comments
self.addRule(r"<!--[^>]*-->", 'comment')
# Treat HTML as XML
HtmlHighlighter = XmlHighlighter
class IniHighlighter (Highlighter):
"""INI syntax highlighter."""
def __init__(self, document):
"""Set INI syntax rules."""
super(IniHighlighter, self).__init__(document)
self.styles.update({
'section': format('darkBlue'),
'property': format('darkGreen'),
'comment': format('darkYellow'),
})
self.addRule(r'\b\[[a-zA-Z0-9_]+\]\b', 'section')
self.addRule(r'\b[a-zA-Z0-9_]+\](?=\s*\=)', 'property')
self.addRule(r'#[^\n]*', 'comment')