styles.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. """ Style utilities, templates, and defaults for syntax highlighting widgets.
  2. """
  3. #-----------------------------------------------------------------------------
  4. # Imports
  5. #-----------------------------------------------------------------------------
  6. from colorsys import rgb_to_hls
  7. from pygments.styles import get_style_by_name
  8. from pygments.token import Token
  9. #-----------------------------------------------------------------------------
  10. # Constants
  11. #-----------------------------------------------------------------------------
  12. default_template = '''\
  13. QPlainTextEdit, QTextEdit {
  14. background-color: %(bgcolor)s;
  15. background-clip: padding;
  16. color: %(fgcolor)s;
  17. selection-background-color: %(select)s;
  18. }
  19. .inverted {
  20. background-color: %(fgcolor)s;
  21. color: %(bgcolor)s;
  22. }
  23. .error { color: red; }
  24. .in-prompt-number { font-weight: bold; }
  25. .out-prompt-number { font-weight: bold; }
  26. '''
  27. # The default light style sheet: black text on a white background.
  28. default_light_style_template = default_template + '''\
  29. .in-prompt { color: navy; }
  30. .out-prompt { color: darkred; }
  31. '''
  32. default_light_style_sheet = default_light_style_template%dict(
  33. bgcolor='white', fgcolor='black', select="#ccc")
  34. default_light_syntax_style = 'default'
  35. # The default dark style sheet: white text on a black background.
  36. default_dark_style_template = default_template + '''\
  37. .in-prompt,
  38. .in-prompt-number { color: lime; }
  39. .out-prompt,
  40. .out-prompt-number { color: red; }
  41. '''
  42. default_dark_style_sheet = default_dark_style_template%dict(
  43. bgcolor='black', fgcolor='white', select="#555")
  44. default_dark_syntax_style = 'monokai'
  45. # The default monochrome
  46. default_bw_style_sheet = default_template%dict(
  47. bgcolor='white', fgcolor='black', select="#ccc")
  48. default_bw_syntax_style = 'bw'
  49. def hex_to_rgb(color):
  50. """Convert a hex color to rgb integer tuple."""
  51. if color.startswith('#'):
  52. color = color[1:]
  53. if len(color) == 3:
  54. color = ''.join([c*2 for c in color])
  55. if len(color) != 6:
  56. return False
  57. try:
  58. r = int(color[:2],16)
  59. g = int(color[2:4],16)
  60. b = int(color[4:],16)
  61. except ValueError:
  62. return False
  63. else:
  64. return r,g,b
  65. def dark_color(color):
  66. """Check whether a color is 'dark'.
  67. Currently, this is simply whether the luminance is <50%"""
  68. rgb = hex_to_rgb(color)
  69. if rgb:
  70. return rgb_to_hls(*rgb)[1] < 128
  71. else: # default to False
  72. return False
  73. def dark_style(stylename):
  74. """Guess whether the background of the style with name 'stylename'
  75. counts as 'dark'."""
  76. return dark_color(get_style_by_name(stylename).background_color)
  77. def get_colors(stylename):
  78. """Construct the keys to be used building the base stylesheet
  79. from a templatee."""
  80. style = get_style_by_name(stylename)
  81. fgcolor = style.style_for_token(Token.Text)['color'] or ''
  82. if len(fgcolor) in (3,6):
  83. # could be 'abcdef' or 'ace' hex, which needs '#' prefix
  84. try:
  85. int(fgcolor, 16)
  86. except TypeError:
  87. pass
  88. else:
  89. fgcolor = "#"+fgcolor
  90. return dict(
  91. bgcolor = style.background_color,
  92. select = style.highlight_color,
  93. fgcolor = fgcolor
  94. )
  95. def sheet_from_template(name, colors='lightbg'):
  96. """Use one of the base templates, and set bg/fg/select colors."""
  97. colors = colors.lower()
  98. if colors=='lightbg':
  99. return default_light_style_template%get_colors(name)
  100. elif colors=='linux':
  101. return default_dark_style_template%get_colors(name)
  102. elif colors=='nocolor':
  103. return default_bw_style_sheet
  104. else:
  105. raise KeyError("No such color scheme: %s"%colors)