Finishes quick-n-dirty MD syntax highlighter

This commit is contained in:
Olivier Keshavjee 2016-03-24 10:50:13 +01:00
parent c92daf32d1
commit f5addd3985

View file

@ -17,6 +17,13 @@ class MMDHighlighter(basicHighlighter):
'Italic2': '(_)([^_].+?[^_])(_)', 'Italic2': '(_)([^_].+?[^_])(_)',
'Title': '^(#+)(\s*)(.*)(#*)', 'Title': '^(#+)(\s*)(.*)(#*)',
'HTML': '<.+?>', 'HTML': '<.+?>',
'Blockquotes': '^(> )+.*$',
'OrderedList': '^\d+\.\s+',
'UnorderedList': '^[\*\+-]\s+',
'Code': '^\s{4,}.*$',
'Links-inline': '(\[)(.*?)(\])(\()(.*?)(\))',
'Links-ref': '(\[)(.*?)(\])\s?(\[)(.*?)(\])',
'Links-ref2': '^\s{,3}(\[)(.*?)(\]:)\s+([^\s]*)\s*(.*?)*$',
} }
def __init__(self, editor, style="Default"): def __init__(self, editor, style="Default"):
@ -24,6 +31,10 @@ class MMDHighlighter(basicHighlighter):
self.editor = editor self.editor = editor
self.rules = {}
for key in self.MARKDOWN_REGEX:
self.rules[key] = re.compile(self.MARKDOWN_REGEX[key])
def highlightBlock(self, text): def highlightBlock(self, text):
basicHighlighter.highlightBlockBefore(self, text) basicHighlighter.highlightBlockBefore(self, text)
@ -32,34 +43,88 @@ class MMDHighlighter(basicHighlighter):
basicHighlighter.highlightBlockAfter(self, text) basicHighlighter.highlightBlockAfter(self, text)
def doHighlightBlock(self, text): def doHighlightBlock(self, text):
"""
A quick-n-dirty very basic highlighter, that fails in most non-trivial cases. And is ugly.
"""
fop = QTextCharFormat() # Creates textCharFormat
fop.setForeground(Qt.lightGray) cfOperator = QTextCharFormat()
fb = QTextCharFormat() cfOperator.setForeground(Qt.lightGray)
fb.setFontWeight(QFont.Bold) cfBold = QTextCharFormat()
fi = QTextCharFormat() cfBold.setFontWeight(QFont.Bold)
fi.setFontItalic(True) cfItalic = QTextCharFormat()
cfItalic.setFontItalic(True)
# Titles (only atx-style, with #, not underlined)
defaultSize = self._defaultCharFormat.font().pointSize()
r = self.rules["Title"]
for m in r.finditer(text):
cfOperator.setFontPointSize(defaultSize + 12 - 2 * len(m.group(1)))
cfBold.setFontPointSize(defaultSize + 12 - 2 * len(m.group(1)))
self.setFormat(m.start(1), len(m.group(1)), cfOperator)
self.setFormat(m.start(3), len(m.group(3)), cfBold)
self.setFormat(m.start(4), len(m.group(4)), cfOperator)
# Code blocks
r = self.rules["Code"]
format = QTextCharFormat()
format.setForeground(Qt.darkGray)
format.setFontFixedPitch(True)
for m in r.finditer(text):
self.setFormat(m.start(), m.end() - m.start(), format)
# Basic stuff
stuff = [
("Blockquotes", Qt.blue),
("OrderedList", Qt.red),
("UnorderedList", Qt.darkRed),
("HTML", Qt.darkGreen),
]
for name, color in stuff:
r = self.rules[name]
format = QTextCharFormat()
format.setForeground(color)
for m in r.finditer(text):
self.setFormat(m.start(), m.end() - m.start(), format)
# Bold and Italic
for name, style in [ for name, style in [
("Italic", fi), ("Italic", cfItalic),
("Italic2", fi), ("Italic2", cfItalic),
("Bold", fb), ("Bold", cfBold),
("Bold2", fb), ("Bold2", cfBold),
]: ]:
r = re.compile(self.MARKDOWN_REGEX[name]) r = self.rules[name]
for m in r.finditer(text): for m in r.finditer(text):
self.setFormat(m.start(1), len(m.group(1)), fop) self.setFormat(m.start(1), len(m.group(1)), cfOperator)
self.setFormat(m.start(2), len(m.group(2)), style) self.setFormat(m.start(2), len(m.group(2)), style)
self.setFormat(m.start(3), len(m.group(3)), fop) self.setFormat(m.start(3), len(m.group(3)), cfOperator)
fps = self._defaultCharFormat.font().pointSize() # Links
cfURL = QTextCharFormat()
cfURL.setForeground(Qt.darkGreen)
cfURL.setFontItalic(True)
cfText = QTextCharFormat()
cfText.setForeground(Qt.darkBlue)
cfIdentifier = QTextCharFormat()
cfIdentifier.setForeground(Qt.darkMagenta)
r = re.compile(self.MARKDOWN_REGEX["Title"]) for type in ['Links-inline', 'Links-ref']:
r = self.rules[type]
for m in r.finditer(text):
self.setFormat(m.start(1), len(m.group(1)), cfOperator)
self.setFormat(m.start(2), len(m.group(2)), cfText)
self.setFormat(m.start(3), len(m.group(3)), cfOperator)
self.setFormat(m.start(4), len(m.group(4)), cfOperator)
self.setFormat(m.start(5), len(m.group(5)), cfURL if "inline" in type else cfIdentifier)
self.setFormat(m.start(6), len(m.group(6)), cfOperator)
r = self.rules["Links-ref2"]
for m in r.finditer(text): for m in r.finditer(text):
fop.setFontPointSize(fps + 12 - 2 * len(m.group(1))) self.setFormat(m.start(1), len(m.group(1)), cfOperator)
fb.setFontPointSize(fps + 12 - 2 * len(m.group(1))) self.setFormat(m.start(2), len(m.group(2)), cfIdentifier)
self.setFormat(m.start(3), len(m.group(3)), cfOperator)
self.setFormat(m.start(1), len(m.group(1)), fop) self.setFormat(m.start(4), len(m.group(4)), cfURL)
self.setFormat(m.start(3), len(m.group(3)), fb) self.setFormat(m.start(5), len(m.group(5)), cfText)
self.setFormat(m.start(4), len(m.group(4)), fop)