style.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. """
  2. pygments.style
  3. ~~~~~~~~~~~~~~
  4. Basic style object.
  5. :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.
  6. :license: BSD, see LICENSE for details.
  7. """
  8. from pygments.token import Token, STANDARD_TYPES
  9. # Default mapping of ansixxx to RGB colors.
  10. _ansimap = {
  11. # dark
  12. 'ansiblack': '000000',
  13. 'ansired': '7f0000',
  14. 'ansigreen': '007f00',
  15. 'ansiyellow': '7f7fe0',
  16. 'ansiblue': '00007f',
  17. 'ansimagenta': '7f007f',
  18. 'ansicyan': '007f7f',
  19. 'ansigray': 'e5e5e5',
  20. # normal
  21. 'ansibrightblack': '555555',
  22. 'ansibrightred': 'ff0000',
  23. 'ansibrightgreen': '00ff00',
  24. 'ansibrightyellow': 'ffff00',
  25. 'ansibrightblue': '0000ff',
  26. 'ansibrightmagenta': 'ff00ff',
  27. 'ansibrightcyan': '00ffff',
  28. 'ansiwhite': 'ffffff',
  29. }
  30. # mapping of deprecated #ansixxx colors to new color names
  31. _deprecated_ansicolors = {
  32. # dark
  33. '#ansiblack': 'ansiblack',
  34. '#ansidarkred': 'ansired',
  35. '#ansidarkgreen': 'ansigreen',
  36. '#ansibrown': 'ansiyellow',
  37. '#ansidarkblue': 'ansiblue',
  38. '#ansipurple': 'ansimagenta',
  39. '#ansiteal': 'ansicyan',
  40. '#ansilightgray': 'ansigray',
  41. # normal
  42. '#ansidarkgray': 'ansibrightblack',
  43. '#ansired': 'ansibrightred',
  44. '#ansigreen': 'ansibrightgreen',
  45. '#ansiyellow': 'ansibrightyellow',
  46. '#ansiblue': 'ansibrightblue',
  47. '#ansifuchsia': 'ansibrightmagenta',
  48. '#ansiturquoise': 'ansibrightcyan',
  49. '#ansiwhite': 'ansiwhite',
  50. }
  51. ansicolors = set(_ansimap)
  52. class StyleMeta(type):
  53. def __new__(mcs, name, bases, dct):
  54. obj = type.__new__(mcs, name, bases, dct)
  55. for token in STANDARD_TYPES:
  56. if token not in obj.styles:
  57. obj.styles[token] = ''
  58. def colorformat(text):
  59. if text in ansicolors:
  60. return text
  61. if text[0:1] == '#':
  62. col = text[1:]
  63. if len(col) == 6:
  64. return col
  65. elif len(col) == 3:
  66. return col[0] * 2 + col[1] * 2 + col[2] * 2
  67. elif text == '':
  68. return ''
  69. elif text == 'transparent':
  70. return text
  71. elif text.startswith('var') or text.startswith('calc'):
  72. return text
  73. assert False, f"wrong color format {text!r}"
  74. _styles = obj._styles = {}
  75. for ttype in obj.styles:
  76. for token in ttype.split():
  77. if token in _styles:
  78. continue
  79. ndef = _styles.get(token.parent, None)
  80. styledefs = obj.styles.get(token, '').split()
  81. if not ndef or token is None:
  82. ndef = ['', 0, 0, 0, '', '', 0, 0, 0]
  83. elif 'noinherit' in styledefs and token is not Token:
  84. ndef = _styles[Token][:]
  85. else:
  86. ndef = ndef[:]
  87. _styles[token] = ndef
  88. for styledef in obj.styles.get(token, '').split():
  89. if styledef == 'noinherit':
  90. pass
  91. elif styledef == 'bold':
  92. ndef[1] = 1
  93. elif styledef == 'nobold':
  94. ndef[1] = 0
  95. elif styledef == 'italic':
  96. ndef[2] = 1
  97. elif styledef == 'noitalic':
  98. ndef[2] = 0
  99. elif styledef == 'underline':
  100. ndef[3] = 1
  101. elif styledef == 'nounderline':
  102. ndef[3] = 0
  103. elif styledef[:3] == 'bg:':
  104. ndef[4] = colorformat(styledef[3:])
  105. elif styledef[:7] == 'border:':
  106. ndef[5] = colorformat(styledef[7:])
  107. elif styledef == 'roman':
  108. ndef[6] = 1
  109. elif styledef == 'sans':
  110. ndef[7] = 1
  111. elif styledef == 'mono':
  112. ndef[8] = 1
  113. else:
  114. ndef[0] = colorformat(styledef)
  115. return obj
  116. def style_for_token(cls, token):
  117. t = cls._styles[token]
  118. ansicolor = bgansicolor = None
  119. color = t[0]
  120. if color in _deprecated_ansicolors:
  121. color = _deprecated_ansicolors[color]
  122. if color in ansicolors:
  123. ansicolor = color
  124. color = _ansimap[color]
  125. bgcolor = t[4]
  126. if bgcolor in _deprecated_ansicolors:
  127. bgcolor = _deprecated_ansicolors[bgcolor]
  128. if bgcolor in ansicolors:
  129. bgansicolor = bgcolor
  130. bgcolor = _ansimap[bgcolor]
  131. return {
  132. 'color': color or None,
  133. 'bold': bool(t[1]),
  134. 'italic': bool(t[2]),
  135. 'underline': bool(t[3]),
  136. 'bgcolor': bgcolor or None,
  137. 'border': t[5] or None,
  138. 'roman': bool(t[6]) or None,
  139. 'sans': bool(t[7]) or None,
  140. 'mono': bool(t[8]) or None,
  141. 'ansicolor': ansicolor,
  142. 'bgansicolor': bgansicolor,
  143. }
  144. def list_styles(cls):
  145. return list(cls)
  146. def styles_token(cls, ttype):
  147. return ttype in cls._styles
  148. def __iter__(cls):
  149. for token in cls._styles:
  150. yield token, cls.style_for_token(token)
  151. def __len__(cls):
  152. return len(cls._styles)
  153. class Style(metaclass=StyleMeta):
  154. #: overall background color (``None`` means transparent)
  155. background_color = '#ffffff'
  156. #: highlight background color
  157. highlight_color = '#ffffcc'
  158. #: line number font color
  159. line_number_color = 'inherit'
  160. #: line number background color
  161. line_number_background_color = 'transparent'
  162. #: special line number font color
  163. line_number_special_color = '#000000'
  164. #: special line number background color
  165. line_number_special_background_color = '#ffffc0'
  166. #: Style definitions for individual token types.
  167. styles = {}
  168. #: user-friendly style name (used when selecting the style, so this
  169. # should be all-lowercase, no spaces, hyphens)
  170. name = 'unnamed'
  171. aliases = []
  172. # Attribute for lexers defined within Pygments. If set
  173. # to True, the style is not shown in the style gallery
  174. # on the website. This is intended for language-specific
  175. # styles.
  176. web_style_gallery_exclude = False