colors~20120418-182926.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. import re
  15. from functools import partial
  16. __version__ = '1.0.2'
  17. COLORS = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan',
  18. 'white')
  19. STYLES = ('bold', 'faint', 'italic', 'underline', 'blink', 'blink2',
  20. 'negative', 'concealed', 'crossed')
  21. def color(s, fg=None, bg=None, style=None):
  22. sgr = []
  23. if fg:
  24. if fg in COLORS:
  25. sgr.append(str(30 + COLORS.index(fg)))
  26. elif isinstance(fg, int) and 0 <= fg <= 255:
  27. sgr.append('38;5;%d' % int(fg))
  28. else:
  29. raise Exception('Invalid color "%s"' % fg)
  30. if bg:
  31. if bg in COLORS:
  32. sgr.append(str(40 + COLORS.index(bg)))
  33. elif isinstance(bg, int) and 0 <= bg <= 255:
  34. sgr.append('48;5;%d' % bg)
  35. else:
  36. raise Exception('Invalid color "%s"' % bg)
  37. if style:
  38. for st in style.split('+'):
  39. if st in STYLES:
  40. sgr.append(str(1 + STYLES.index(st)))
  41. else:
  42. raise Exception('Invalid style "%s"' % st)
  43. if sgr:
  44. prefix = '\x1b[' + ';'.join(sgr) + 'm'
  45. suffix = '\x1b[0m'
  46. return prefix + s + suffix
  47. else:
  48. return s
  49. def strip_color(s):
  50. return re.sub('\x1b\[.+?m', '', s)
  51. # Foreground shortcuts
  52. black = partial(color, fg='black')
  53. red = partial(color, fg='red')
  54. green = partial(color, fg='green')
  55. yellow = partial(color, fg='yellow')
  56. blue = partial(color, fg='blue')
  57. magenta = partial(color, fg='magenta')
  58. cyan = partial(color, fg='cyan')
  59. white = partial(color, fg='white')
  60. # Style shortcuts
  61. bold = partial(color, style='bold')
  62. faint = partial(color, style='faint')
  63. italic = partial(color, style='italic')
  64. underline = partial(color, style='underline')
  65. blink = partial(color, style='blink')
  66. blink2 = partial(color, style='blink2')
  67. negative = partial(color, style='negative')
  68. concealed = partial(color, style='concealed')
  69. crossed = partial(color, style='crossed')