1# coding: utf-8
2# Copyright (c) 2008-2011 Volvox Development Team
3#
4# Permission is hereby granted, free of charge, to any person obtaining a copy
5# of this software and associated documentation files (the "Software"), to deal
6# in the Software without restriction, including without limitation the rights
7# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8# copies of the Software, and to permit persons to whom the Software is
9# furnished to do so, subject to the following conditions:
10#
11# The above copyright notice and this permission notice shall be included in
12# all copies or substantial portions of the Software.
13#
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20# THE SOFTWARE.
21#
22# Author: Konstantin Lepa <konstantin.lepa@gmail.com>
23
24"""ANSII Color formatting for output in terminal."""
25
26from __future__ import print_function
27import os
28
29
30__ALL__ = [ 'colored', 'cprint' ]
31
32VERSION = (1, 1, 0)
33
34ATTRIBUTES = dict(
35        list(zip([
36            'bold',
37            'dark',
38            '',
39            'underline',
40            'blink',
41            '',
42            'reverse',
43            'concealed'
44            ],
45            list(range(1, 9))
46            ))
47        )
48del ATTRIBUTES['']
49
50
51HIGHLIGHTS = dict(
52        list(zip([
53            'on_grey',
54            'on_red',
55            'on_green',
56            'on_yellow',
57            'on_blue',
58            'on_magenta',
59            'on_cyan',
60            'on_white'
61            ],
62            list(range(40, 48))
63            ))
64        )
65
66
67COLORS = dict(
68        list(zip([
69            'grey',
70            'red',
71            'green',
72            'yellow',
73            'blue',
74            'magenta',
75            'cyan',
76            'white',
77            ],
78            list(range(30, 38))
79            ))
80        )
81
82
83RESET = '\033[0m'
84
85
86def colored(text, color=None, on_color=None, attrs=None):
87    """Colorize text.
88
89    Available text colors:
90        red, green, yellow, blue, magenta, cyan, white.
91
92    Available text highlights:
93        on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white.
94
95    Available attributes:
96        bold, dark, underline, blink, reverse, concealed.
97
98    Example:
99        colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink'])
100        colored('Hello, World!', 'green')
101    """
102    if os.getenv('ANSI_COLORS_DISABLED') is None:
103        fmt_str = '\033[%dm%s'
104        if color is not None:
105            text = fmt_str % (COLORS[color], text)
106
107        if on_color is not None:
108            text = fmt_str % (HIGHLIGHTS[on_color], text)
109
110        if attrs is not None:
111            for attr in attrs:
112                text = fmt_str % (ATTRIBUTES[attr], text)
113
114        text += RESET
115    return text
116
117
118def cprint(text, color=None, on_color=None, attrs=None, **kwargs):
119    """Print colorize text.
120
121    It accepts arguments of print function.
122    """
123
124    print((colored(text, color, on_color, attrs)), **kwargs)
125
126
127if __name__ == '__main__':
128    print('Current terminal type: %s' % os.getenv('TERM'))
129    print('Test basic colors:')
130    cprint('Grey color', 'grey')
131    cprint('Red color', 'red')
132    cprint('Green color', 'green')
133    cprint('Yellow color', 'yellow')
134    cprint('Blue color', 'blue')
135    cprint('Magenta color', 'magenta')
136    cprint('Cyan color', 'cyan')
137    cprint('White color', 'white')
138    print(('-' * 78))
139
140    print('Test highlights:')
141    cprint('On grey color', on_color='on_grey')
142    cprint('On red color', on_color='on_red')
143    cprint('On green color', on_color='on_green')
144    cprint('On yellow color', on_color='on_yellow')
145    cprint('On blue color', on_color='on_blue')
146    cprint('On magenta color', on_color='on_magenta')
147    cprint('On cyan color', on_color='on_cyan')
148    cprint('On white color', color='grey', on_color='on_white')
149    print('-' * 78)
150
151    print('Test attributes:')
152    cprint('Bold grey color', 'grey', attrs=['bold'])
153    cprint('Dark red color', 'red', attrs=['dark'])
154    cprint('Underline green color', 'green', attrs=['underline'])
155    cprint('Blink yellow color', 'yellow', attrs=['blink'])
156    cprint('Reversed blue color', 'blue', attrs=['reverse'])
157    cprint('Concealed Magenta color', 'magenta', attrs=['concealed'])
158    cprint('Bold underline reverse cyan color', 'cyan',
159            attrs=['bold', 'underline', 'reverse'])
160    cprint('Dark blink concealed white color', 'white',
161            attrs=['dark', 'blink', 'concealed'])
162    print(('-' * 78))
163
164    print('Test mixing:')
165    cprint('Underline red on grey color', 'red', 'on_grey',
166            ['underline'])
167    cprint('Reversed green on red color', 'green', 'on_red', ['reverse'])
168
169