Package pilas :: Package ejemplos :: Module syntax
[hide private]
[frames] | no frames]

Source Code for Module pilas.ejemplos.syntax

  1  # Ejemplo tomado desde la siguiente web: 
  2  #     http://diotavelli.net/PyQtWiki/Python%20syntax%20highlighting 
  3  import sys 
  4   
  5  from PyQt4.QtCore import QRegExp 
  6  from PyQt4.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter 
  7   
8 -def format(color, style=''):
9 """Return a QTextCharFormat with the given attributes. 10 """ 11 _color = QColor() 12 _color.setNamedColor(color) 13 14 _format = QTextCharFormat() 15 _format.setForeground(_color) 16 if 'bold' in style: 17 _format.setFontWeight(QFont.Bold) 18 if 'italic' in style: 19 _format.setFontItalic(True) 20 21 return _format
22 23 24 # Syntax styles that can be shared by all languages 25 STYLES = { 26 'keyword': format('blue'), 27 'operator': format('red'), 28 'brace': format('darkGray'), 29 'defclass': format('black', 'bold'), 30 'string': format('magenta'), 31 'string2': format('darkMagenta'), 32 'comment': format('darkGreen', 'italic'), 33 'self': format('black', 'italic'), 34 'numbers': format('brown'), 35 } 36 37
38 -class PythonHighlighter (QSyntaxHighlighter):
39 """Syntax highlighter for the Python language. 40 """ 41 # Python keywords 42 keywords = [ 43 'and', 'assert', 'break', 'class', 'continue', 'def', 44 'del', 'elif', 'else', 'except', 'exec', 'finally', 45 'for', 'from', 'global', 'if', 'import', 'in', 46 'is', 'lambda', 'not', 'or', 'pass', 'print', 47 'raise', 'return', 'try', 'while', 'yield', 48 'None', 'True', 'False', 49 ] 50 51 # Python operators 52 operators = [ 53 '=', 54 # Comparison 55 '==', '!=', '<', '<=', '>', '>=', 56 # Arithmetic 57 '\+', '-', '\*', '/', '//', '\%', '\*\*', 58 # In-place 59 '\+=', '-=', '\*=', '/=', '\%=', 60 # Bitwise 61 '\^', '\|', '\&', '\~', '>>', '<<', 62 ] 63 64 # Python braces 65 braces = [ 66 '\{', '\}', '\(', '\)', '\[', '\]', 67 ]
68 - def __init__(self, document):
69 QSyntaxHighlighter.__init__(self, document) 70 71 # Multi-line strings (expression, flag, style) 72 # FIXME: The triple-quotes in these two lines will mess up the 73 # syntax highlighting from this point onward 74 self.tri_single = (QRegExp("'''"), 1, STYLES['string2']) 75 self.tri_double = (QRegExp('"""'), 2, STYLES['string2']) 76 77 rules = [] 78 79 # Keyword, operator, and brace rules 80 rules += [(r'\b%s\b' % w, 0, STYLES['keyword']) 81 for w in PythonHighlighter.keywords] 82 rules += [(r'%s' % o, 0, STYLES['operator']) 83 for o in PythonHighlighter.operators] 84 rules += [(r'%s' % b, 0, STYLES['brace']) 85 for b in PythonHighlighter.braces] 86 87 # All other rules 88 rules += [ 89 # 'self' 90 (r'\bself\b', 0, STYLES['self']), 91 92 # Double-quoted string, possibly containing escape sequences 93 (r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']), 94 # Single-quoted string, possibly containing escape sequences 95 (r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']), 96 97 # 'def' followed by an identifier 98 (r'\bdef\b\s*(\w+)', 1, STYLES['defclass']), 99 # 'class' followed by an identifier 100 (r'\bclass\b\s*(\w+)', 1, STYLES['defclass']), 101 102 # From '#' until a newline 103 (r'#[^\n]*', 0, STYLES['comment']), 104 105 # Numeric literals 106 (r'\b[+-]?[0-9]+[lL]?\b', 0, STYLES['numbers']), 107 (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, STYLES['numbers']), 108 (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']), 109 ] 110 111 # Build a QRegExp for each pattern 112 self.rules = [(QRegExp(pat), index, fmt) 113 for (pat, index, fmt) in rules]
114 115
116 - def highlightBlock(self, text):
117 """Apply syntax highlighting to the given block of text. 118 """ 119 # Do other syntax formatting 120 for expression, nth, format in self.rules: 121 index = expression.indexIn(text, 0) 122 123 while index >= 0: 124 # We actually want the index of the nth match 125 index = expression.pos(nth) 126 length = expression.cap(nth).length() 127 self.setFormat(index, length, format) 128 index = expression.indexIn(text, index + length) 129 130 self.setCurrentBlockState(0) 131 132 # Do multi-line strings 133 in_multiline = self.match_multiline(text, *self.tri_single) 134 if not in_multiline: 135 in_multiline = self.match_multiline(text, *self.tri_double)
136 137
138 - def match_multiline(self, text, delimiter, in_state, style):
139 """Do highlighting of multi-line strings. ``delimiter`` should be a 140 ``QRegExp`` for triple-single-quotes or triple-double-quotes, and 141 ``in_state`` should be a unique integer to represent the corresponding 142 state changes when inside those strings. Returns True if we're still 143 inside a multi-line string when this function is finished. 144 """ 145 # If inside triple-single quotes, start at 0 146 if self.previousBlockState() == in_state: 147 start = 0 148 add = 0 149 # Otherwise, look for the delimiter on this line 150 else: 151 start = delimiter.indexIn(text) 152 # Move past this match 153 add = delimiter.matchedLength() 154 155 # As long as there's a delimiter match on this line... 156 while start >= 0: 157 # Look for the ending delimiter 158 end = delimiter.indexIn(text, start + add) 159 # Ending delimiter on this line? 160 if end >= add: 161 length = end - start + add + delimiter.matchedLength() 162 self.setCurrentBlockState(0) 163 # No; multi-line string 164 else: 165 self.setCurrentBlockState(in_state) 166 length = text.length() - start + add 167 # Apply formatting 168 self.setFormat(start, length, style) 169 # Look for the next match 170 start = delimiter.indexIn(text, start + length) 171 172 # Return True if still inside a multi-line string, False otherwise 173 if self.currentBlockState() == in_state: 174 return True 175 else: 176 return False
177