irc.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. """
  2. pygments.formatters.irc
  3. ~~~~~~~~~~~~~~~~~~~~~~~
  4. Formatter for IRC output
  5. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS.
  6. :license: BSD, see LICENSE for details.
  7. """
  8. from pygments.formatter import Formatter
  9. from pygments.token import Keyword, Name, Comment, String, Error, \
  10. Number, Operator, Generic, Token, Whitespace
  11. from pygments.util import get_choice_opt
  12. __all__ = ['IRCFormatter']
  13. #: Map token types to a tuple of color values for light and dark
  14. #: backgrounds.
  15. IRC_COLORS = {
  16. Token: ('', ''),
  17. Whitespace: ('gray', 'brightblack'),
  18. Comment: ('gray', 'brightblack'),
  19. Comment.Preproc: ('cyan', 'brightcyan'),
  20. Keyword: ('blue', 'brightblue'),
  21. Keyword.Type: ('cyan', 'brightcyan'),
  22. Operator.Word: ('magenta', 'brightcyan'),
  23. Name.Builtin: ('cyan', 'brightcyan'),
  24. Name.Function: ('green', 'brightgreen'),
  25. Name.Namespace: ('_cyan_', '_brightcyan_'),
  26. Name.Class: ('_green_', '_brightgreen_'),
  27. Name.Exception: ('cyan', 'brightcyan'),
  28. Name.Decorator: ('brightblack', 'gray'),
  29. Name.Variable: ('red', 'brightred'),
  30. Name.Constant: ('red', 'brightred'),
  31. Name.Attribute: ('cyan', 'brightcyan'),
  32. Name.Tag: ('brightblue', 'brightblue'),
  33. String: ('yellow', 'yellow'),
  34. Number: ('blue', 'brightblue'),
  35. Generic.Deleted: ('brightred', 'brightred'),
  36. Generic.Inserted: ('green', 'brightgreen'),
  37. Generic.Heading: ('**', '**'),
  38. Generic.Subheading: ('*magenta*', '*brightmagenta*'),
  39. Generic.Error: ('brightred', 'brightred'),
  40. Error: ('_brightred_', '_brightred_'),
  41. }
  42. IRC_COLOR_MAP = {
  43. 'white': 0,
  44. 'black': 1,
  45. 'blue': 2,
  46. 'brightgreen': 3,
  47. 'brightred': 4,
  48. 'yellow': 5,
  49. 'magenta': 6,
  50. 'orange': 7,
  51. 'green': 7, #compat w/ ansi
  52. 'brightyellow': 8,
  53. 'lightgreen': 9,
  54. 'brightcyan': 9, # compat w/ ansi
  55. 'cyan': 10,
  56. 'lightblue': 11,
  57. 'red': 11, # compat w/ ansi
  58. 'brightblue': 12,
  59. 'brightmagenta': 13,
  60. 'brightblack': 14,
  61. 'gray': 15,
  62. }
  63. def ircformat(color, text):
  64. if len(color) < 1:
  65. return text
  66. add = sub = ''
  67. if '_' in color: # italic
  68. add += '\x1D'
  69. sub = '\x1D' + sub
  70. color = color.strip('_')
  71. if '*' in color: # bold
  72. add += '\x02'
  73. sub = '\x02' + sub
  74. color = color.strip('*')
  75. # underline (\x1F) not supported
  76. # backgrounds (\x03FF,BB) not supported
  77. if len(color) > 0: # actual color - may have issues with ircformat("red", "blah")+"10" type stuff
  78. add += '\x03' + str(IRC_COLOR_MAP[color]).zfill(2)
  79. sub = '\x03' + sub
  80. return add + text + sub
  81. return '<'+add+'>'+text+'</'+sub+'>'
  82. class IRCFormatter(Formatter):
  83. r"""
  84. Format tokens with IRC color sequences
  85. The `get_style_defs()` method doesn't do anything special since there is
  86. no support for common styles.
  87. Options accepted:
  88. `bg`
  89. Set to ``"light"`` or ``"dark"`` depending on the terminal's background
  90. (default: ``"light"``).
  91. `colorscheme`
  92. A dictionary mapping token types to (lightbg, darkbg) color names or
  93. ``None`` (default: ``None`` = use builtin colorscheme).
  94. `linenos`
  95. Set to ``True`` to have line numbers in the output as well
  96. (default: ``False`` = no line numbers).
  97. """
  98. name = 'IRC'
  99. aliases = ['irc', 'IRC']
  100. filenames = []
  101. def __init__(self, **options):
  102. Formatter.__init__(self, **options)
  103. self.darkbg = get_choice_opt(options, 'bg',
  104. ['light', 'dark'], 'light') == 'dark'
  105. self.colorscheme = options.get('colorscheme', None) or IRC_COLORS
  106. self.linenos = options.get('linenos', False)
  107. self._lineno = 0
  108. def _write_lineno(self, outfile):
  109. if self.linenos:
  110. self._lineno += 1
  111. outfile.write("%04d: " % self._lineno)
  112. def format_unencoded(self, tokensource, outfile):
  113. self._write_lineno(outfile)
  114. for ttype, value in tokensource:
  115. color = self.colorscheme.get(ttype)
  116. while color is None:
  117. ttype = ttype[:-1]
  118. color = self.colorscheme.get(ttype)
  119. if color:
  120. color = color[self.darkbg]
  121. spl = value.split('\n')
  122. for line in spl[:-1]:
  123. if line:
  124. outfile.write(ircformat(color, line))
  125. outfile.write('\n')
  126. self._write_lineno(outfile)
  127. if spl[-1]:
  128. outfile.write(ircformat(color, spl[-1]))
  129. else:
  130. outfile.write(value)