##// END OF EJS Templates
Cleaner version of color table by P. Wang.
Fernando Perez -
Show More
@@ -1,179 +1,180 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for coloring text in ANSI terminals.
3 3
4 4 $Id: ColorANSI.py 2167 2007-03-21 06:57:50Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 from IPython import Release
14 14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 15 __license__ = Release.license
16 16
17 17 __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
18 18
19 19 import os
20 20
21 21 from IPython.ipstruct import Struct
22 22
23 23 def make_color_table(in_class):
24 24 """Build a set of color attributes in a class.
25 25
26 26 Helper function for building the *TermColors classes."""
27 27
28 28 color_templates = (
29 # Dark colors
29 30 ("Black" , "0;30"),
30 31 ("Red" , "0;31"),
31 32 ("Green" , "0;32"),
32 33 ("Brown" , "0;33"),
33 34 ("Blue" , "0;34"),
34 35 ("Purple" , "0;35"),
35 36 ("Cyan" , "0;36"),
36 37 ("LightGray" , "0;37"),
38 # Light colors
37 39 ("DarkGray" , "1;30"),
38 40 ("LightRed" , "1;31"),
39 41 ("LightGreen" , "1;32"),
40 42 ("Yellow" , "1;33"),
41 43 ("LightBlue" , "1;34"),
42 44 ("LightPurple" , "1;35"),
43 45 ("LightCyan" , "1;36"),
44 ("White" , "1;37"), )
45
46 for name,value in color_templates:
47 setattr(in_class,name,in_class._base % value)
48
49 # Automatically add Blink versions of the above colors. This
50 # just involves setting the attribute field (before the first
51 # semicolon) to '5'.
52 # Note: this is a little easter egg contributed by Peter Wang from
53 # Enthought at the Scipy2008 sprint :)
54 value = '5'+value[1:]
55 setattr(in_class,"Blink"+name,in_class._base % value)
46 ("White" , "1;37"),
47 # Blinking colors. Probably should not be used in anything serious.
48 ("BlinkBlack" , "5;30"),
49 ("BlinkRed" , "5;31"),
50 ("BlinkGreen" , "5;32"),
51 ("BlinkYellow" , "5;33"),
52 ("BlinkBlue" , "5;34"),
53 ("BlinkPurple" , "5;35"),
54 ("BlinkCyan" , "5;36"),
55 ("BlinkLightGray", "5;37"),
56 )
56 57
57 58
58 59 class TermColors:
59 60 """Color escape sequences.
60 61
61 62 This class defines the escape sequences for all the standard (ANSI?)
62 63 colors in terminals. Also defines a NoColor escape which is just the null
63 64 string, suitable for defining 'dummy' color schemes in terminals which get
64 65 confused by color escapes.
65 66
66 67 This class should be used as a mixin for building color schemes."""
67 68
68 69 NoColor = '' # for color schemes in color-less terminals.
69 70 Normal = '\033[0m' # Reset normal coloring
70 71 _base = '\033[%sm' # Template for all other colors
71 72
72 73 # Build the actual color table as a set of class attributes:
73 74 make_color_table(TermColors)
74 75
75 76 class InputTermColors:
76 77 """Color escape sequences for input prompts.
77 78
78 79 This class is similar to TermColors, but the escapes are wrapped in \001
79 80 and \002 so that readline can properly know the length of each line and
80 81 can wrap lines accordingly. Use this class for any colored text which
81 82 needs to be used in input prompts, such as in calls to raw_input().
82 83
83 84 This class defines the escape sequences for all the standard (ANSI?)
84 85 colors in terminals. Also defines a NoColor escape which is just the null
85 86 string, suitable for defining 'dummy' color schemes in terminals which get
86 87 confused by color escapes.
87 88
88 89 This class should be used as a mixin for building color schemes."""
89 90
90 91 NoColor = '' # for color schemes in color-less terminals.
91 92
92 93 if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
93 94 # (X)emacs on W32 gets confused with \001 and \002 so we remove them
94 95 Normal = '\033[0m' # Reset normal coloring
95 96 _base = '\033[%sm' # Template for all other colors
96 97 else:
97 98 Normal = '\001\033[0m\002' # Reset normal coloring
98 99 _base = '\001\033[%sm\002' # Template for all other colors
99 100
100 101 # Build the actual color table as a set of class attributes:
101 102 make_color_table(InputTermColors)
102 103
103 104 class ColorScheme:
104 105 """Generic color scheme class. Just a name and a Struct."""
105 106 def __init__(self,__scheme_name_,colordict=None,**colormap):
106 107 self.name = __scheme_name_
107 108 if colordict is None:
108 109 self.colors = Struct(**colormap)
109 110 else:
110 111 self.colors = Struct(colordict)
111 112
112 113 def copy(self,name=None):
113 114 """Return a full copy of the object, optionally renaming it."""
114 115 if name is None:
115 116 name = self.name
116 117 return ColorScheme(name,self.colors.__dict__)
117 118
118 119 class ColorSchemeTable(dict):
119 120 """General class to handle tables of color schemes.
120 121
121 122 It's basically a dict of color schemes with a couple of shorthand
122 123 attributes and some convenient methods.
123 124
124 125 active_scheme_name -> obvious
125 126 active_colors -> actual color table of the active scheme"""
126 127
127 128 def __init__(self,scheme_list=None,default_scheme=''):
128 129 """Create a table of color schemes.
129 130
130 131 The table can be created empty and manually filled or it can be
131 132 created with a list of valid color schemes AND the specification for
132 133 the default active scheme.
133 134 """
134 135
135 136 # create object attributes to be set later
136 137 self.active_scheme_name = ''
137 138 self.active_colors = None
138 139
139 140 if scheme_list:
140 141 if default_scheme == '':
141 142 raise ValueError,'you must specify the default color scheme'
142 143 for scheme in scheme_list:
143 144 self.add_scheme(scheme)
144 145 self.set_active_scheme(default_scheme)
145 146
146 147 def copy(self):
147 148 """Return full copy of object"""
148 149 return ColorSchemeTable(self.values(),self.active_scheme_name)
149 150
150 151 def add_scheme(self,new_scheme):
151 152 """Add a new color scheme to the table."""
152 153 if not isinstance(new_scheme,ColorScheme):
153 154 raise ValueError,'ColorSchemeTable only accepts ColorScheme instances'
154 155 self[new_scheme.name] = new_scheme
155 156
156 157 def set_active_scheme(self,scheme,case_sensitive=0):
157 158 """Set the currently active scheme.
158 159
159 160 Names are by default compared in a case-insensitive way, but this can
160 161 be changed by setting the parameter case_sensitive to true."""
161 162
162 163 scheme_names = self.keys()
163 164 if case_sensitive:
164 165 valid_schemes = scheme_names
165 166 scheme_test = scheme
166 167 else:
167 168 valid_schemes = [s.lower() for s in scheme_names]
168 169 scheme_test = scheme.lower()
169 170 try:
170 171 scheme_idx = valid_schemes.index(scheme_test)
171 172 except ValueError:
172 173 raise ValueError,'Unrecognized color scheme: ' + scheme + \
173 174 '\nValid schemes: '+str(scheme_names).replace("'', ",'')
174 175 else:
175 176 active = scheme_names[scheme_idx]
176 177 self.active_scheme_name = active
177 178 self.active_colors = self[active].colors
178 179 # Now allow using '' as an index for the current active scheme
179 180 self[''] = self[active]
General Comments 0
You need to be logged in to leave comments. Login now