summaryrefslogtreecommitdiffstats
path: root/contrib/python/Pygments/py2/pygments/formatters/terminal.py
blob: a9749e25e72de13b79e2253d7b46838d692a7c7d (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
128
129
130
131
132
133
134
135
136
# -*- coding: utf-8 -*- 
""" 
    pygments.formatters.terminal 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 
    Formatter for terminal output with ANSI sequences. 
 
    :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details. 
""" 
 
import sys 
 
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): 
        # hack: if the output is a terminal and has an encoding set, 
        # use that to avoid unicode encode problems 
        if not self.encoding and hasattr(outfile, "encoding") and \ 
           hasattr(outfile, "isatty") and outfile.isatty() and \ 
           sys.version_info < (3,): 
            self.encoding = outfile.encoding 
        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")