e0bda16a236bfcf2c17068f2ff0cb8551830244a
[SubU] /
1 """
2     pygments.formatters.terminal
3     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5     Formatter for terminal output with ANSI sequences.
6
7     :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
8     :license: BSD, see LICENSE for details.
9 """
10
11 from pip._vendor.pygments.formatter import Formatter
12 from pip._vendor.pygments.token import Keyword, Name, Comment, String, Error, \
13     Number, Operator, Generic, Token, Whitespace
14 from pip._vendor.pygments.console import ansiformat
15 from pip._vendor.pygments.util import get_choice_opt
16
17
18 __all__ = ['TerminalFormatter']
19
20
21 #: Map token types to a tuple of color values for light and dark
22 #: backgrounds.
23 TERMINAL_COLORS = {
24     Token:              ('',            ''),
25
26     Whitespace:         ('gray',   'brightblack'),
27     Comment:            ('gray',   'brightblack'),
28     Comment.Preproc:    ('cyan',        'brightcyan'),
29     Keyword:            ('blue',    'brightblue'),
30     Keyword.Type:       ('cyan',        'brightcyan'),
31     Operator.Word:      ('magenta',      'brightmagenta'),
32     Name.Builtin:       ('cyan',        'brightcyan'),
33     Name.Function:      ('green',   'brightgreen'),
34     Name.Namespace:     ('_cyan_',      '_brightcyan_'),
35     Name.Class:         ('_green_', '_brightgreen_'),
36     Name.Exception:     ('cyan',        'brightcyan'),
37     Name.Decorator:     ('brightblack',    'gray'),
38     Name.Variable:      ('red',     'brightred'),
39     Name.Constant:      ('red',     'brightred'),
40     Name.Attribute:     ('cyan',        'brightcyan'),
41     Name.Tag:           ('brightblue',        'brightblue'),
42     String:             ('yellow',       'yellow'),
43     Number:             ('blue',    'brightblue'),
44
45     Generic.Deleted:    ('brightred',        'brightred'),
46     Generic.Inserted:   ('green',  'brightgreen'),
47     Generic.Heading:    ('**',         '**'),
48     Generic.Subheading: ('*magenta*',   '*brightmagenta*'),
49     Generic.Prompt:     ('**',         '**'),
50     Generic.Error:      ('brightred',        'brightred'),
51
52     Error:              ('_brightred_',      '_brightred_'),
53 }
54
55
56 class TerminalFormatter(Formatter):
57     r"""
58     Format tokens with ANSI color sequences, for output in a text console.
59     Color sequences are terminated at newlines, so that paging the output
60     works correctly.
61
62     The `get_style_defs()` method doesn't do anything special since there is
63     no support for common styles.
64
65     Options accepted:
66
67     `bg`
68         Set to ``"light"`` or ``"dark"`` depending on the terminal's background
69         (default: ``"light"``).
70
71     `colorscheme`
72         A dictionary mapping token types to (lightbg, darkbg) color names or
73         ``None`` (default: ``None`` = use builtin colorscheme).
74
75     `linenos`
76         Set to ``True`` to have line numbers on the terminal output as well
77         (default: ``False`` = no line numbers).
78     """
79     name = 'Terminal'
80     aliases = ['terminal', 'console']
81     filenames = []
82
83     def __init__(self, **options):
84         Formatter.__init__(self, **options)
85         self.darkbg = get_choice_opt(options, 'bg',
86                                      ['light', 'dark'], 'light') == 'dark'
87         self.colorscheme = options.get('colorscheme', None) or TERMINAL_COLORS
88         self.linenos = options.get('linenos', False)
89         self._lineno = 0
90
91     def format(self, tokensource, outfile):
92         return Formatter.format(self, tokensource, outfile)
93
94     def _write_lineno(self, outfile):
95         self._lineno += 1
96         outfile.write("%s%04d: " % (self._lineno != 1 and '\n' or '', self._lineno))
97
98     def _get_color(self, ttype):
99         # self.colorscheme is a dict containing usually generic types, so we
100         # have to walk the tree of dots.  The base Token type must be a key,
101         # even if it's empty string, as in the default above.
102         colors = self.colorscheme.get(ttype)
103         while colors is None:
104             ttype = ttype.parent
105             colors = self.colorscheme.get(ttype)
106         return colors[self.darkbg]
107
108     def format_unencoded(self, tokensource, outfile):
109         if self.linenos:
110             self._write_lineno(outfile)
111
112         for ttype, value in tokensource:
113             color = self._get_color(ttype)
114
115             for line in value.splitlines(True):
116                 if color:
117                     outfile.write(ansiformat(color, line.rstrip('\n')))
118                 else:
119                     outfile.write(line.rstrip('\n'))
120                 if line.endswith('\n'):
121                     if self.linenos:
122                         self._write_lineno(outfile)
123                     else:
124                         outfile.write('\n')
125
126         if self.linenos:
127             outfile.write("\n")