소스 검색

added styntax highlighting, ooooyeah!

Bachir Soussi Chiadmi 7 년 전
부모
커밋
8e8a55fc19
3개의 변경된 파일146개의 추가작업 그리고 3개의 파일을 삭제
  1. 4 0
      classes/content.py
  2. 10 3
      classes/design.py
  3. 132 0
      classes/highlighter.py

+ 4 - 0
classes/content.py

@@ -8,6 +8,8 @@ from PyQt5.QtCore import QSettings
 from PyQt5.QtGui import QKeySequence
 from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QVBoxLayout, QSplitter, QListWidget, QListWidgetItem, QAbstractItemView, QPushButton, QInputDialog, QPlainTextEdit, QTextEdit, QShortcut
 
+from classes import highlighter
+
 import markdown2
 import json
 
@@ -193,6 +195,8 @@ class MarkdownEditor(QWidget):
 
       self.editor = QPlainTextEdit(self)
       self.editor.setStyleSheet(self.styles)
+
+      self.hl=highlighter.Highlighter(self.editor.document(),"md")
       self.hbox.addWidget(self.editor)
 
       self.viewer = QTextEdit(self)

+ 10 - 3
classes/design.py

@@ -11,6 +11,11 @@ from PyQt5.QtWebKit import QWebSettings
 from PyQt5.QtWebKitWidgets import QWebView, QWebInspector
 from PyQt5.QtPrintSupport import QPrintPreviewDialog, QPrinter
 
+# from pygments import highlight
+# from pygments.lexers import *
+# from pygments.formatter import Formatter
+from classes import highlighter
+
 
 class WebkitView(QWebView):
    def __init__(self, parent, core):
@@ -170,12 +175,14 @@ class WebViewToolBar(QWidget):
 
 
 class CodeEditor(QPlainTextEdit):
-   def __init__(self, core, tabs, file=None):
+   def __init__(self, core, tabs, file, mode):
       super(CodeEditor, self).__init__()
       self.core = core
       self.tabs = tabs
       self.file = file
       self.setText()
+      self.setTabStopWidth(15)
+      self.hl= highlighter.Highlighter(self.document(),mode)
 
       self.shortcut = QShortcut(QKeySequence("Ctrl+s"), self)
       self.shortcut.activated.connect(self.save)
@@ -233,8 +240,8 @@ class Editor(QWidget):
       # Initialize tab screen
       self.tabs = QTabWidget()
 
-      self.scsstab = CodeEditor(core, self.tabs, 'assets/css/styles.scss')
-      self.jstab = CodeEditor(core, self.tabs, 'assets/js/script.js')
+      self.scsstab = CodeEditor(core, self.tabs, 'assets/css/styles.scss', "scss")
+      self.jstab = CodeEditor(core, self.tabs, 'assets/js/script.js', 'js')
 
       # Add tabs
       self.tabs.addTab(self.scsstab,"scss")

+ 132 - 0
classes/highlighter.py

@@ -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_())