pmacs3/buffer/color.py

100 lines
2.9 KiB
Python

import re
import lex
from buffer import Buffer
from buffer.data import DataBuffer
from highlight import Highlighter
color_map = {
'B': 'black',
'r': 'red',
'g': 'green',
'y': 'yellow',
'b': 'blue',
'm': 'magenta',
'c': 'cyan',
'w': 'white',
'd': 'default',
'*': 'bold',
}
reverse_map = {
'black': 'B',
'blue': 'b',
'cyan': 'c',
'default': 'd',
'green': 'g',
'magenta': 'm',
'red': 'r',
'white': 'w',
'yellow': 'y',
'bold': '*',
}
def get_cbuf_code(*args):
return '[' + ':'.join([reverse_map[x] for x in args]) + ']'
# NOTE: this highlighter will not reprocess the data given. it is intended to
# be used with read-only buffers like DataBuffer and ColorBuffer
class ColorHighlighter(Highlighter):
color_re = re.compile(r'\[([a-zA-Z0-9\*:]+)\]')
def __init__(self):
self.tokens = []
def append_token(self, y, x, s, color):
s2 = s.replace('\\[', '[')
s2 = s2.replace('\\]', ']')
s2 = s2.replace('\\\\', '\\')
t = lex.Token('color_data', None, y, x, s2, color)
self.tokens[y].append(t)
return len(s) - len(s2)
def delete_token(self, y, i):
del self.tokens[y][i]
def relex(self, lines, y1, x1, y2, x2, token=None):
for y in range(y1, y2 + 1):
self.highlight_line(y, lines[y])
def highlight_line(self, y, line):
self.tokens[y] = []
c = ['default', 'default']
i = 0
offset = 0
while i < len(line):
m = self.color_re.search(line, i)
if m:
(j, k) = (m.start(), m.end())
if j > i:
offset += self.append_token(y, i - offset, line[i:j], c)
fields = m.group(1).split(':')
c = [color_map.get(x, x) for x in fields]
offset += k - j
i = k
else:
offset += self.append_token(y, i - offset, line[i:], c)
break
def highlight(self, lines):
if self.tokens:
return
self.tokens = [None] * len(lines)
for y in range(0, len(lines)):
self.highlight_line(y, lines[y])
class ColorDataBuffer(DataBuffer):
btype = 'colordata'
modename = 'colortext'
color_re = re.compile(r'\[([a-z:]+)\]')
def _highlight(self, data):
data2 = ColorHighlighter.color_re.sub('', data)
data2 = data2.replace('\\[', '[')
data2 = data2.replace('\\]', ']')
data2 = data2.replace('\\\\', '\\')
Buffer.set_data(self, data2, force=True)
lines = data.split(self.nl)
self.highlights = {'Colortext': ColorHighlighter()}
self.highlights['Colortext'].highlight(lines)
self.modified = False
def __init__(self, name, data):
DataBuffer.__init__(self, name, '')
self._highlight(data)
def set_data(self, data, force=True):
self._highlight(data)