diff options
-rw-r--r-- | ranger/gui/ansi.py | 47 | ||||
-rw-r--r-- | test/tc_ansi.py | 9 |
2 files changed, 36 insertions, 20 deletions
diff --git a/ranger/gui/ansi.py b/ranger/gui/ansi.py index 7d5f2623..fe0753a1 100644 --- a/ranger/gui/ansi.py +++ b/ranger/gui/ansi.py @@ -1,4 +1,5 @@ # Copyright (C) 2010 David Barnett <davidbarnett2@gmail.com> +# Copyright (C) 2010 Roman Zimbelmann <romanz@lavabit.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -13,26 +14,45 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +from ranger.gui import color import re -ansi_re = re.compile('(\x1b' + r'\[\d+(?:;\d+)*?m)') +ansi_re = re.compile('(\033' + r'\[\d+(?:;\d+)*?[a-zA-Z])') def split_ansi_from_text(ansi_text): return ansi_re.split(ansi_text) def text_with_fg_bg(ansi_text): for chunk in split_ansi_from_text(ansi_text): - if chunk.startswith('\x1b'): - attr_text = re.match('\x1b' + r'\[(.*?)m', chunk).group(1) - fg, bg = -1, -1 - for attr in attr_text.split(';'): - m = re.match('^3(\d)$', attr) - if m: - fg = int(m.group(1)) - m = re.match('^4(\d)$', attr) - if m: - bg = int(m.group(1)) - yield (fg, bg) + if chunk[0] == '\033': + if chunk[-1] != 'm': + continue + match = re.match(r'^.\[(.*).$', chunk) + attr_args = match.group(1) + fg, bg, attr = -1, -1, 0 + + # Convert arguments to attributes/colors + for arg in attr_args.split(';'): + n = int(arg) + if n == 0: + fg, bg, attr = 0, 0, 0 + elif n == 1: + attr |= color.bold + elif n == 4: + attr |= color.underline + elif n == 7: + attr |= color.reverse + elif n == 8: + attr |= color.invisible + elif n >= 30 and n <= 37: + fg = n - 30 + elif n == 39: + fg = -1 + elif n >= 40 and n <= 47: + bg = n - 40 + elif n == 49: + bg = -1 + yield (fg, bg, attr) else: yield chunk @@ -48,7 +68,8 @@ def char_slice(ansi_text, start, end): for chunk in split_ansi_from_text(ansi_text): m = ansi_re.match(chunk) if m: - last_color = chunk + if chunk[-1] == 'm': + last_color = chunk else: if skip_len_left > len(chunk): skip_len_left -= len(chunk) diff --git a/test/tc_ansi.py b/test/tc_ansi.py index 5fc4e53b..0a6ad8b1 100644 --- a/test/tc_ansi.py +++ b/test/tc_ansi.py @@ -19,12 +19,6 @@ import unittest from ranger.gui import ansi class TestDisplayable(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - pass - def test_char_len(self): ansi_string = "[0;30;40mX[0m" self.assertEqual(ansi.char_len(ansi_string), 1) @@ -39,7 +33,8 @@ class TestDisplayable(unittest.TestCase): def test_char_slice(self): ansi_string = "[0;30;40mX[0;31;41mY[0m" - self.assertEqual(ansi.char_slice(ansi_string, 0, 1), "[0;30;40mX") + expected = "[0;30;40mX" + self.assertEqual(ansi.char_slice(ansi_string, 0, 1), expected) if __name__ == '__main__': unittest.main() |