##// END OF EJS Templates
Merge branch 'epatters-qtfrontend' into kernelmanager...
Merge branch 'epatters-qtfrontend' into kernelmanager Conflicts: IPython/frontend/qt/kernelmanager.py IPython/frontend/qt/util.py

File last commit:

r2715:96d379e0
r2726:7ecaeab5 merge
Show More
pygments_highlighter.py
182 lines | 6.6 KiB | text/x-python | PythonLexer
/ IPython / frontend / qt / console / pygments_highlighter.py
epatters
Fixed imports and removed references to ETS/EPD
r2603 # System library imports.
epatters
Initial checkin of Qt frontend code.
r2602 from PyQt4 import QtGui
from pygments.lexer import RegexLexer, _TokenType, Text, Error
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 from pygments.lexers import PythonLexer
epatters
Initial checkin of Qt frontend code.
r2602 from pygments.styles.default import DefaultStyle
from pygments.token import Comment
def get_tokens_unprocessed(self, text, stack=('root',)):
""" Split ``text`` into (tokentype, text) pairs.
Monkeypatched to store the final stack on the object itself.
"""
pos = 0
tokendefs = self._tokens
epatters
Fixed imports and removed references to ETS/EPD
r2603 if hasattr(self, '_saved_state_stack'):
statestack = list(self._saved_state_stack)
epatters
Initial checkin of Qt frontend code.
r2602 else:
statestack = list(stack)
statetokens = tokendefs[statestack[-1]]
while 1:
for rexmatch, action, new_state in statetokens:
m = rexmatch(text, pos)
if m:
if type(action) is _TokenType:
yield pos, action, m.group()
else:
for item in action(self, m):
yield item
pos = m.end()
if new_state is not None:
# state transition
if isinstance(new_state, tuple):
for state in new_state:
if state == '#pop':
statestack.pop()
elif state == '#push':
statestack.append(statestack[-1])
else:
statestack.append(state)
elif isinstance(new_state, int):
# pop
del statestack[new_state:]
elif new_state == '#push':
statestack.append(statestack[-1])
else:
assert False, "wrong state def: %r" % new_state
statetokens = tokendefs[statestack[-1]]
break
else:
try:
if text[pos] == '\n':
# at EOL, reset state to "root"
pos += 1
statestack = ['root']
statetokens = tokendefs['root']
yield pos, Text, u'\n'
continue
yield pos, Error, text[pos]
pos += 1
except IndexError:
break
epatters
Fixed imports and removed references to ETS/EPD
r2603 self._saved_state_stack = list(statestack)
epatters
Initial checkin of Qt frontend code.
r2602
# Monkeypatch!
RegexLexer.get_tokens_unprocessed = get_tokens_unprocessed
class BlockUserData(QtGui.QTextBlockUserData):
""" Storage for the user data associated with each line.
"""
syntax_stack = ('root',)
def __init__(self, **kwds):
for key, value in kwds.iteritems():
setattr(self, key, value)
QtGui.QTextBlockUserData.__init__(self)
def __repr__(self):
attrs = ['syntax_stack']
kwds = ', '.join([ '%s=%r' % (attr, getattr(self, attr))
for attr in attrs ])
return 'BlockUserData(%s)' % kwds
class PygmentsHighlighter(QtGui.QSyntaxHighlighter):
""" Syntax highlighter that uses Pygments for parsing. """
def __init__(self, parent, lexer=None):
super(PygmentsHighlighter, self).__init__(parent)
self._lexer = lexer if lexer else PythonLexer()
self._style = DefaultStyle
# Caches for formats and brushes.
self._brushes = {}
self._formats = {}
def highlightBlock(self, qstring):
""" Highlight a block of text.
"""
qstring = unicode(qstring)
prev_data = self.previous_block_data()
if prev_data is not None:
epatters
Fixed imports and removed references to ETS/EPD
r2603 self._lexer._saved_state_stack = prev_data.syntax_stack
elif hasattr(self._lexer, '_saved_state_stack'):
del self._lexer._saved_state_stack
epatters
Initial checkin of Qt frontend code.
r2602
index = 0
# Lex the text using Pygments
for token, text in self._lexer.get_tokens(qstring):
l = len(text)
format = self._get_format(token)
if format is not None:
self.setFormat(index, l, format)
index += l
epatters
Fixed imports and removed references to ETS/EPD
r2603 if hasattr(self._lexer, '_saved_state_stack'):
data = BlockUserData(syntax_stack=self._lexer._saved_state_stack)
epatters
Initial checkin of Qt frontend code.
r2602 self.currentBlock().setUserData(data)
# Clean up for the next go-round.
epatters
Fixed imports and removed references to ETS/EPD
r2603 del self._lexer._saved_state_stack
epatters
Initial checkin of Qt frontend code.
r2602
def previous_block_data(self):
""" Convenience method for returning the previous block's user data.
"""
return self.currentBlock().previous().userData()
def _get_format(self, token):
""" Returns a QTextCharFormat for token or None.
"""
if token in self._formats:
return self._formats[token]
result = None
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 for key, value in self._style.style_for_token(token).items():
epatters
Initial checkin of Qt frontend code.
r2602 if value:
if result is None:
result = QtGui.QTextCharFormat()
if key == 'color':
result.setForeground(self._get_brush(value))
elif key == 'bgcolor':
result.setBackground(self._get_brush(value))
elif key == 'bold':
result.setFontWeight(QtGui.QFont.Bold)
elif key == 'italic':
result.setFontItalic(True)
elif key == 'underline':
result.setUnderlineStyle(
QtGui.QTextCharFormat.SingleUnderline)
elif key == 'sans':
result.setFontStyleHint(QtGui.QFont.SansSerif)
elif key == 'roman':
result.setFontStyleHint(QtGui.QFont.Times)
elif key == 'mono':
result.setFontStyleHint(QtGui.QFont.TypeWriter)
elif key == 'border':
# Borders are normally used for errors. We can't do a border
# so instead we do a wavy underline
result.setUnderlineStyle(
QtGui.QTextCharFormat.WaveUnderline)
result.setUnderlineColor(self._get_color(value))
self._formats[token] = result
return result
def _get_brush(self, color):
""" Returns a brush for the color.
"""
result = self._brushes.get(color)
if result is None:
qcolor = self._get_color(color)
result = QtGui.QBrush(qcolor)
self._brushes[color] = result
return result
def _get_color(self, color):
qcolor = QtGui.QColor()
epatters
* IPythonWidget now has IPython-style prompts that are futher stylabla via CSS...
r2715 qcolor.setRgb(int(color[:2], base=16),
epatters
Initial checkin of Qt frontend code.
r2602 int(color[2:4], base=16),
int(color[4:6], base=16))
return qcolor