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