Commit 0a860f45 authored by Jacek Sowiński's avatar Jacek Sowiński

Even safer base 16 colors

- Colors specified by name will return safe ANSI codes.
- Colors specified by number will return ANSI code from xterm 256 color
  chart.
- Defaults are also *safe*.
parent 877a6a7a
......@@ -38,7 +38,7 @@ class ColorsTest(TopydoTest):
config(p_overrides={('colorscheme', 'project_color'): 'yellow'})
color = Colors().get_project_color()
self.assertEqual(color, '\033[1;38;5;3m')
self.assertEqual(color, '\033[1;33m')
def test_project_color4(self):
config(p_overrides={('colorscheme', 'project_color'): '686'})
......@@ -62,7 +62,7 @@ class ColorsTest(TopydoTest):
config(p_overrides={('colorscheme', 'context_color'): 'magenta'})
color = Colors().get_context_color()
self.assertEqual(color, '\033[1;38;5;5m')
self.assertEqual(color, '\033[1;35m')
def test_context_color4(self):
config(p_overrides={('colorscheme', 'context_color'): '392'})
......@@ -86,7 +86,7 @@ class ColorsTest(TopydoTest):
config(p_overrides={('colorscheme', 'metadata_color'): 'light-red'})
color = Colors().get_metadata_color()
self.assertEqual(color, '\033[1;38;5;9m')
self.assertEqual(color, '\033[1;1;31m')
def test_metadata_color4(self):
config(p_overrides={('colorscheme', 'metadata_color'): '777'})
......@@ -110,7 +110,7 @@ class ColorsTest(TopydoTest):
config(p_overrides={('colorscheme', 'link_color'): 'red'})
color = Colors().get_link_color()
self.assertEqual(color, '\033[4;38;5;1m')
self.assertEqual(color, '\033[4;31m')
def test_link_color4(self):
config(p_overrides={('colorscheme', 'link_color'): '777'})
......@@ -130,16 +130,18 @@ class ColorsTest(TopydoTest):
config("test/data/ColorsTest2.conf")
color = Colors().get_priority_colors()
self.assertEqual(color['A'], '\033[0;38;5;5m')
self.assertEqual(color['B'], '\033[0;38;5;6m')
self.assertEqual(color['C'], '\033[0;38;5;7m')
self.assertEqual(color['A'], '\033[0;35m')
self.assertEqual(color['B'], '\033[0;1;36m')
self.assertEqual(color['C'], '\033[0;37m')
def test_priority_color3(self):
config("test/data/ColorsTest3.conf")
color = Colors().get_priority_colors()
self.assertEqual(color['A'], '\033[0;35m')
self.assertEqual(color['B'], '\033[0;1;36m')
self.assertEqual(color['Z'], NEUTRAL_COLOR)
self.assertEqual(color['D'], '\033[0;38;5;1m')
self.assertEqual(color['D'], '\033[0;31m')
self.assertEqual(color['C'], '\033[0;38;5;7m')
def test_priority_color4(self):
......@@ -174,10 +176,10 @@ class ColorsTest(TopydoTest):
link_color = Colors().get_link_color()
metadata_color = Colors().get_metadata_color()
self.assertEqual(pri_color['A'], '\033[0;38;5;6m')
self.assertEqual(pri_color['B'], '\033[0;38;5;3m')
self.assertEqual(pri_color['C'], '\033[0;38;5;4m')
self.assertEqual(project_color, '\033[1;38;5;1m')
self.assertEqual(context_color, '\033[1;38;5;5m')
self.assertEqual(link_color, '\033[4;38;5;6m')
self.assertEqual(metadata_color, '\033[1;38;5;2m')
self.assertEqual(pri_color['A'], '\033[0;36m')
self.assertEqual(pri_color['B'], '\033[0;33m')
self.assertEqual(pri_color['C'], '\033[0;34m')
self.assertEqual(project_color, '\033[1;31m')
self.assertEqual(context_color, '\033[1;35m')
self.assertEqual(link_color, '\033[4;36m')
self.assertEqual(metadata_color, '\033[1;32m')
[colorscheme]
priority_colors = A:magenta,B:cyan,C:gray
priority_colors = A:magenta,B:light-cyan,C:gray
[colorscheme]
priority_colors = A:magenta,B:cyan,C:7,D:red,Z:foobar
priority_colors = A:magenta,B:light-cyan,C:7,D:red,Z:foobar
......@@ -28,11 +28,13 @@ class Colors(object):
self.metadata_color = config().metadata_color()
self.link_color = config().link_color()
def _int_to_ansi(self, p_int, p_decorator='normal'):
def _int_to_ansi(self, p_int, p_decorator='normal', p_safe=True):
"""
Returns ansi code for color based on xterm color id (0-255) and
decoration, where decoration can be one of: normal, bold, faint,
italic, or underline.
italic, or underline. When p_safe is True, resulting ansi code is
constructed in most compatible way, but with support for only base 16
colors.
"""
decoration_dict = {
'normal': '0',
......@@ -45,11 +47,13 @@ class Colors(object):
decoration = decoration_dict[p_decorator]
try:
if 8 > int(p_int) >=0:
return '\033[{};3{}m'.format(decoration, str(p_int))
elif 16 > int(p_int):
p_int = int(p_int) - 8
return '\033[{};9{}m'.format(decoration, str(p_int))
if p_safe:
if 8 > int(p_int) >=0:
return '\033[{};3{}m'.format(decoration, str(p_int))
elif 16 > int(p_int):
p_int = int(p_int) - 8
return '\033[{};1;3{}m'.format(decoration, str(p_int))
if 256 > int(p_int) >=0:
return '\033[{};38;5;{}m'.format(decoration, str(p_int))
else:
......@@ -94,7 +98,7 @@ class Colors(object):
if p_color == '':
ansi = ''
else:
ansi = self._int_to_ansi(p_color, p_decorator)
ansi = self._int_to_ansi(p_color, p_decorator, False)
if not ansi:
ansi = self._name_to_ansi(p_color, p_decorator)
......
......@@ -69,11 +69,11 @@ class _Config:
'append_parent_contexts': '0',
# colorscheme
'project_color': '1',
'context_color': '5',
'metadata_color': '2',
'link_color': '6',
'priority_colors': 'A:6,B:3,C:4',
'project_color': 'red',
'context_color': 'magenta',
'metadata_color': 'green',
'link_color': 'cyan',
'priority_colors': 'A:cyan,B:yellow,C:blue',
}
self.config = {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment