style.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.style
  4. ~~~~~~~~~~~~~~
  5. Basic style object.
  6. :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. from pygments.token import Token, STANDARD_TYPES
  10. from pygments.util import add_metaclass
  11. # Default mapping of #ansixxx to RGB colors.
  12. _ansimap = {
  13. # dark
  14. '#ansiblack': '000000',
  15. '#ansidarkred': '7f0000',
  16. '#ansidarkgreen': '007f00',
  17. '#ansibrown': '7f7fe0',
  18. '#ansidarkblue': '00007f',
  19. '#ansipurple': '7f007f',
  20. '#ansiteal': '007f7f',
  21. '#ansilightgray': 'e5e5e5',
  22. # normal
  23. '#ansidarkgray': '555555',
  24. '#ansired': 'ff0000',
  25. '#ansigreen': '00ff00',
  26. '#ansiyellow': 'ffff00',
  27. '#ansiblue': '0000ff',
  28. '#ansifuchsia': 'ff00ff',
  29. '#ansiturquoise': '00ffff',
  30. '#ansiwhite': 'ffffff',
  31. }
  32. ansicolors = set(_ansimap)
  33. class StyleMeta(type):
  34. def __new__(mcs, name, bases, dct):
  35. obj = type.__new__(mcs, name, bases, dct)
  36. for token in STANDARD_TYPES:
  37. if token not in obj.styles:
  38. obj.styles[token] = ''
  39. def colorformat(text):
  40. if text in ansicolors:
  41. return text
  42. if text[0:1] == '#':
  43. col = text[1:]
  44. if len(col) == 6:
  45. return col
  46. elif len(col) == 3:
  47. return col[0]*2 + col[1]*2 + col[2]*2
  48. elif text == '':
  49. return ''
  50. assert False, "wrong color format %r" % text
  51. _styles = obj._styles = {}
  52. for ttype in obj.styles:
  53. for token in ttype.split():
  54. if token in _styles:
  55. continue
  56. ndef = _styles.get(token.parent, None)
  57. styledefs = obj.styles.get(token, '').split()
  58. if not ndef or token is None:
  59. ndef = ['', 0, 0, 0, '', '', 0, 0, 0]
  60. elif 'noinherit' in styledefs and token is not Token:
  61. ndef = _styles[Token][:]
  62. else:
  63. ndef = ndef[:]
  64. _styles[token] = ndef
  65. for styledef in obj.styles.get(token, '').split():
  66. if styledef == 'noinherit':
  67. pass
  68. elif styledef == 'bold':
  69. ndef[1] = 1
  70. elif styledef == 'nobold':
  71. ndef[1] = 0
  72. elif styledef == 'italic':
  73. ndef[2] = 1
  74. elif styledef == 'noitalic':
  75. ndef[2] = 0
  76. elif styledef == 'underline':
  77. ndef[3] = 1
  78. elif styledef == 'nounderline':
  79. ndef[3] = 0
  80. elif styledef[:3] == 'bg:':
  81. ndef[4] = colorformat(styledef[3:])
  82. elif styledef[:7] == 'border:':
  83. ndef[5] = colorformat(styledef[7:])
  84. elif styledef == 'roman':
  85. ndef[6] = 1
  86. elif styledef == 'sans':
  87. ndef[7] = 1
  88. elif styledef == 'mono':
  89. ndef[8] = 1
  90. else:
  91. ndef[0] = colorformat(styledef)
  92. return obj
  93. def style_for_token(cls, token):
  94. t = cls._styles[token]
  95. ansicolor = bgansicolor = None
  96. color = t[0]
  97. if color.startswith('#ansi'):
  98. ansicolor = color
  99. color = _ansimap[color]
  100. bgcolor = t[4]
  101. if bgcolor.startswith('#ansi'):
  102. bgansicolor = bgcolor
  103. bgcolor = _ansimap[bgcolor]
  104. return {
  105. 'color': color or None,
  106. 'bold': bool(t[1]),
  107. 'italic': bool(t[2]),
  108. 'underline': bool(t[3]),
  109. 'bgcolor': bgcolor or None,
  110. 'border': t[5] or None,
  111. 'roman': bool(t[6]) or None,
  112. 'sans': bool(t[7]) or None,
  113. 'mono': bool(t[8]) or None,
  114. 'ansicolor': ansicolor,
  115. 'bgansicolor': bgansicolor,
  116. }
  117. def list_styles(cls):
  118. return list(cls)
  119. def styles_token(cls, ttype):
  120. return ttype in cls._styles
  121. def __iter__(cls):
  122. for token in cls._styles:
  123. yield token, cls.style_for_token(token)
  124. def __len__(cls):
  125. return len(cls._styles)
  126. @add_metaclass(StyleMeta)
  127. class Style(object):
  128. #: overall background color (``None`` means transparent)
  129. background_color = '#ffffff'
  130. #: highlight background color
  131. highlight_color = '#ffffcc'
  132. #: Style definitions for individual token types.
  133. styles = {}