1 ##########################################################################
3 # Copyright 2011-2012 Jose Fonseca
4 # Copyright 2008-2009 VMware, Inc.
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 ##########################################################################/
33 class PlainHighlighter:
45 def __init__(self, stream = sys.stdout):
48 def write(self, text):
49 self.stream.write(text)
57 def color(self, color):
60 def bold(self, enable = True):
70 class AnsiHighlighter(PlainHighlighter):
71 '''Highlighter for plain-text files which outputs ANSI escape codes. See
72 http://en.wikipedia.org/wiki/ANSI_escape_code for more information
73 concerning ANSI escape codes.
90 def __init__(self, stream = sys.stdout):
91 PlainHighlighter.__init__(self, stream)
93 def _escape(self, code):
94 self.stream.write(self._csi + code)
97 self._escape(self._normal)
99 def color(self, color):
100 self._escape(str(30 + color) + 'm')
102 def bold(self, enable = True):
112 self._escape(self._italic)
115 class WindowsConsoleHighlighter(PlainHighlighter):
116 '''Highlighter for the Windows Console. See
117 http://code.activestate.com/recipes/496901/ for more information.
120 INVALID_HANDLE_VALUE = -1
121 STD_INPUT_HANDLE = -10
122 STD_OUTPUT_HANDLE = -11
123 STD_ERROR_HANDLE = -12
125 FOREGROUND_BLUE = 0x01
126 FOREGROUND_GREEN = 0x02
127 FOREGROUND_RED = 0x04
128 FOREGROUND_INTENSITY = 0x08
129 BACKGROUND_BLUE = 0x10
130 BACKGROUND_GREEN = 0x20
131 BACKGROUND_RED = 0x40
132 BACKGROUND_INTENSITY = 0x80
134 COMMON_LVB_LEADING_BYTE = 0x0100
135 COMMON_LVB_TRAILING_BYTE = 0x0200
136 COMMON_LVB_GRID_HORIZONTAL = 0x0400
137 COMMON_LVB_GRID_LVERTICAL = 0x0800
138 COMMON_LVB_GRID_RVERTICAL = 0x1000
139 COMMON_LVB_REVERSE_VIDEO = 0x4000
140 COMMON_LVB_UNDERSCORE = 0x8000
142 _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
143 _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
147 green = FOREGROUND_GREEN
148 blue = FOREGROUND_BLUE
149 white = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
151 def __init__(self, stream = sys.stdout):
152 PlainHighlighter.__init__(self, stream)
154 if stream is sys.stdin:
155 nStdHandle = self.STD_INPUT_HANDLE
156 elif stream is sys.stdout:
157 nStdHandle = self.STD_OUTPUT_HANDLE
158 elif stream is sys.stderr:
159 nStdHandle = self.STD_ERROR_HANDLE
163 if nStdHandle is not None:
165 self._handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle)
167 self._handle = self.INVALID_HANDLE_VALUE
169 self._attribute = self.white
171 def _setAttribute(self, attr):
172 if self._handle != self.INVALID_HANDLE_VALUE:
174 ctypes.windll.kernel32.SetConsoleTextAttribute(self._handle, attr)
175 self._attribute = attr
178 self._setAttribute(self._normal)
180 def color(self, color):
181 intensity = self._attribute & self.FOREGROUND_INTENSITY
182 self._setAttribute(color | intensity)
184 def bold(self, enable = True):
186 attribute = self._attribute | self.FOREGROUND_INTENSITY
188 attribute = self._attribute & ~self.FOREGROUND_INTENSITY
189 self._setAttribute(attribute)
195 if platform.system() == 'Windows':
196 ColorHighlighter = WindowsConsoleHighlighter
198 ColorHighlighter = AnsiHighlighter
201 def AutoHighlighter(stream = sys.stdout):
203 return ColorHighlighter(stream)
205 return PlainHighlighter(stream)
208 class _LessHighlighter(AnsiHighlighter):
210 def __init__(self, less):
211 AnsiHighlighter.__init__(self, less.stdin)
215 self.less.stdin.close()
219 def LessHighlighter():
220 if sys.stdout.isatty():
222 less = subprocess.Popen(
223 args = ['less', '-FRXn'],
224 stdin = subprocess.PIPE
227 return ColorHighlighter()
229 return _LessHighlighter(less)
230 return PlainHighlighter(sys.stdout)