|
@@ -0,0 +1,132 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+import sys
|
|
|
+import re
|
|
|
+from PyQt5 import QtCore, QtGui
|
|
|
+from pygments import highlight
|
|
|
+from pygments.lexers import *
|
|
|
+from pygments.formatter import Formatter
|
|
|
+from pygments.styles import get_all_styles, get_style_by_name
|
|
|
+import time
|
|
|
+
|
|
|
+# Copyright (C) 2008 Christophe Kibleur <kib2@free.fr>
|
|
|
+#
|
|
|
+# This file is part of WikiParser (http://thewikiblog.appspot.com/).
|
|
|
+#
|
|
|
+
|
|
|
+def hex2QColor(c):
|
|
|
+ r=int(c[0:2],16)
|
|
|
+ g=int(c[2:4],16)
|
|
|
+ b=int(c[4:6],16)
|
|
|
+ return QtGui.QColor(r,g,b)
|
|
|
+
|
|
|
+
|
|
|
+class QFormatter(Formatter):
|
|
|
+ def __init__(self, linenos=True, style="default"): #, style
|
|
|
+ Formatter.__init__(self)
|
|
|
+ self.data=[]
|
|
|
+ self.style = get_style_by_name(style)
|
|
|
+ self.linenos = linenos
|
|
|
+ # styles = list(get_all_styles())
|
|
|
+ # print(styles)
|
|
|
+ # Create a dictionary of text styles, indexed
|
|
|
+ # by pygments token names, containing QTextCharFormat
|
|
|
+ # instances according to pygments' description
|
|
|
+ # of each style
|
|
|
+
|
|
|
+ self.styles={}
|
|
|
+ for token, style in self.style:
|
|
|
+ qtf=QtGui.QTextCharFormat()
|
|
|
+
|
|
|
+ if style['color']:
|
|
|
+ qtf.setForeground(hex2QColor(style['color']))
|
|
|
+ if style['bgcolor']:
|
|
|
+ qtf.setBackground(hex2QColor(style['bgcolor']))
|
|
|
+ if style['bold']:
|
|
|
+ qtf.setFontWeight(QtGui.QFont.Bold)
|
|
|
+ if style['italic']:
|
|
|
+ qtf.setFontItalic(True)
|
|
|
+ if style['underline']:
|
|
|
+ qtf.setFontUnderline(True)
|
|
|
+
|
|
|
+ self.styles[str(token)]=qtf
|
|
|
+
|
|
|
+ def format(self, tokensource, outfile):
|
|
|
+ global styles
|
|
|
+ # We ignore outfile, keep output in a buffer
|
|
|
+ self.data=[]
|
|
|
+
|
|
|
+ # Just store a list of styles, one for each character
|
|
|
+ # in the input. Obviously a smarter thing with
|
|
|
+ # offsets and lengths is a good idea!
|
|
|
+ print(tokensource)
|
|
|
+
|
|
|
+ for ttype, value in tokensource:
|
|
|
+ l=len(value)
|
|
|
+ t=str(ttype)
|
|
|
+ self.data.extend([self.styles[t],]*l)
|
|
|
+
|
|
|
+
|
|
|
+class Highlighter(QtGui.QSyntaxHighlighter):
|
|
|
+
|
|
|
+ def __init__(self, parent, mode):
|
|
|
+ QtGui.QSyntaxHighlighter.__init__(self, parent)
|
|
|
+ self.tstamp=time.time()
|
|
|
+
|
|
|
+ # Keep the formatter and lexer, initializing them
|
|
|
+ # may be costly.
|
|
|
+ if not mode == "md":
|
|
|
+ self.formatter=QFormatter(linenos=True, style="monokai-hcb")
|
|
|
+ else:
|
|
|
+ self.formatter=QFormatter(linenos=False, style="github")
|
|
|
+
|
|
|
+ self.lexer=get_lexer_by_name(mode)
|
|
|
+
|
|
|
+ def highlightBlock(self, text):
|
|
|
+ """Takes a block, applies format to the document.
|
|
|
+ according to what's in it.
|
|
|
+ """
|
|
|
+
|
|
|
+ # I need to know where in the document we are,
|
|
|
+ # because our formatting info is global to
|
|
|
+ # the document
|
|
|
+ cb = self.currentBlock()
|
|
|
+ p = cb.position()
|
|
|
+
|
|
|
+ # The \n is not really needed, but sometimes
|
|
|
+ # you are in an empty last block, so your position is
|
|
|
+ # **after** the end of the document.
|
|
|
+ text=str(self.document().toPlainText())+'\n'
|
|
|
+
|
|
|
+ # Yes, re-highlight the whole document.
|
|
|
+ # There **must** be some optimizacion possibilities
|
|
|
+ # but it seems fast enough.
|
|
|
+ highlight(text,self.lexer,self.formatter)
|
|
|
+
|
|
|
+ # Just apply the formatting to this block.
|
|
|
+ # For titles, it may be necessary to backtrack
|
|
|
+ # and format a couple of blocks **earlier**.
|
|
|
+ for i in range(len(str(text))):
|
|
|
+ try:
|
|
|
+ self.setFormat(i,1,self.formatter.data[p+i])
|
|
|
+ except IndexError:
|
|
|
+ pass
|
|
|
+
|
|
|
+ # I may need to do something about this being called
|
|
|
+ # too quickly.
|
|
|
+ self.tstamp=time.time()
|
|
|
+
|
|
|
+
|
|
|
+# if __name__ == "__main__":
|
|
|
+# app = QtGui.QApplication(sys.argv)
|
|
|
+#
|
|
|
+# rst = QtGui.QPlainTextEdit()
|
|
|
+# rst.setWindowTitle('reSt')
|
|
|
+# hl=Highlighter(rst.document(),"rest")
|
|
|
+# rst.show()
|
|
|
+#
|
|
|
+# python = QtGui.QPlainTextEdit()
|
|
|
+# python.setWindowTitle('python')
|
|
|
+# hl=Highlighter(python.document(),"python")
|
|
|
+# python.show()
|
|
|
+#
|
|
|
+# sys.exit(app.exec_())
|