You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
5.6 KiB

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