From 0588c94a7bc95d44965870ca89f99f11f83d25e3 Mon Sep 17 00:00:00 2001 From: Gabriel Falcao Date: Thu, 6 Sep 2012 15:23:26 -0400 Subject: [PATCH] detecting ansi support --- couleur.py | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/couleur.py b/couleur.py index 8eda97d..95ce648 100644 --- a/couleur.py +++ b/couleur.py @@ -14,12 +14,32 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +import os import re import sys import uuid +import platform + __version__ = '0.3' from StringIO import StringIO + +SUPPORTS_ANSI = False +for handle in [sys.stdout, sys.stderr]: + if (hasattr(handle, "isatty") and handle.isatty()) or \ + ('TERM' in os.environ and os.environ['TERM'] == 'ANSI'): + if platform.system() == 'Windows' and not ( + 'TERM' in os.environ and os.environ['TERM'] == 'ANSI'): + SUPPORTS_ANSI = False + else: + SUPPORTS_ANSI = True + +if os.getenv('SURE_NO_COLORS'): + SUPPORTS_ANSI = False + +SUPPORTS_ANSI = False + + def minify(string): regex_items = re.compile('(\033\[(\d+)m)') regex_main = re.compile('(?P
(\033\[(\d+)m){2,})') @@ -35,6 +55,7 @@ def minify(string): return replaced + def translate_colors(string): for attr in re.findall("[#][{]on[:](\w+)[}]", string): string = string.replace( @@ -53,6 +74,7 @@ def translate_colors(string): return minify(string) + def ignore_colors(string): up_count_regex = re.compile(ur'[#][{]up[}]') up_count = len(up_count_regex.findall(string)) or 1 @@ -70,19 +92,24 @@ def ignore_colors(string): return string + class Writer(StringIO): original = None translate = True + def write(self, string): f = self.translate and translate_colors or ignore_colors self.original.write(f(string)) + class StdOutMocker(Writer): original = sys.__stdout__ + class StdErrMocker(Writer): original = sys.__stderr__ + class Proxy(object): def __init__(self, output): self.old_write = output.write @@ -120,12 +147,15 @@ class Proxy(object): self.output.write = self.old_write _proxy_registry = {} + + def proxy(output): if output not in _proxy_registry.keys(): _proxy_registry[output] = Proxy(output) return _proxy_registry[output] + def ansify(number): """Wraps the given ansi code to a proper escaped python output @@ -135,6 +165,7 @@ def ansify(number): number = unicode(number) return '\033[%sm' % number + class modifiers: reset = ansify(0) bold = ansify(1) @@ -145,6 +176,7 @@ class modifiers: strikethrough = ansify(9) up = '\r\033[A' + class forecolors: black = ansify(30) red = ansify(31) @@ -156,6 +188,7 @@ class forecolors: white = ansify(37) normal = ansify(39) + class backcolors: black = ansify(40) red = ansify(41) @@ -167,6 +200,7 @@ class backcolors: white = ansify(47) normal = ansify(49) + class empty(object): def __getattr__(self, attr): if attr != 'up': @@ -177,6 +211,7 @@ class empty(object): _sep1 = '_on_' _sep2 = '_and_' + class Shell(object): def __init__(self, indent=2, linebreak=False, bold=False, disabled=False): self._indentation_factor = indent @@ -188,7 +223,7 @@ class Shell(object): self._backcolors = backcolors() self._forecolors = forecolors() self._modifiers = modifiers() - if disabled: + if disabled or not SUPPORTS_ANSI: self._backcolors = empty() self._forecolors = empty() self._modifiers = empty() @@ -199,7 +234,6 @@ class Shell(object): def dedent(self): self._indent -= self._indentation_factor - def _fore(self, color): def get(what): try: @@ -244,12 +278,12 @@ class Shell(object): return dec - def __getattr__(self, attr): if not attr.startswith("_"): if _sep2 in attr: self._in_format = True printers = map(self._printer_for, attr.split(_sep2)) + def dec(string, replace=False): unique = str(uuid.uuid4()) string = string.replace(r'\|', unique)