1
# Copyright 2010-2011 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
11
# BS, HT, LF, CR, FF, ESC
12
VALID_ANSI_PATTERN = r"\x08\x09\x0A\x0C\x0D\x1B"
19
def setText(self, text):
24
"""Parser for ansi text."""
26
def __init__(self, stream):
34
def run(self, result):
41
ansi = self.stream.read()
43
if ord(ch) == 0x1B or len(escape) > 0:
45
if chr(0x1B) in [escape, ch]:
62
saved = [row + len(text), col]
66
elif ord(ch) in [0x1B, 0x5B]:
69
# Just after hitting the extended ESC marker
73
if ch in "0123456789;":
77
opts = escape.split(";") + ["", ""]
78
row = -len(text) + max(0, int("0" + opts[0]) - 1)
79
col = max(0, int("0" + opts[1]) - 1)
81
saved = [row + len(text), col]
87
text[row] = " " * (col + 1) + text[row][col + 1:]
91
text[row] = text[row][:col]
94
text = text[:row] + [""]
96
for i in range(row + len(text) + 1):
99
row -= max(1, int("0" + escape.split(";")[0]))
103
row += max(1, int("0" + escape.split(";")[0]))
108
col += max(1, int("0" + escape.split(";")[0]))
110
col = max(0, col - max(1, int("0" + escape.split(";")[0])))
116
if ch in "\r\n\f\t\b":
128
col = max(0, col - 1)
131
if len(text[row]) < col:
132
text[row] += " " * (col - len(text[row]))
133
text[row] = text[row][:col] + ch + text[row][col + 1:]
136
result.setText("\n".join(text))