Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
terminal256.py339 linesDownload Raw Back to formatters
1"""2    pygments.formatters.terminal2563    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~4 5    Formatter for 256-color terminal output with ANSI sequences.6 7    RGB-to-XTERM color conversion routines adapted from xterm256-conv8    tool (http://frexx.de/xterm-256-notes/data/xterm256-conv2.tar.bz2)9    by Wolfgang Frisch.10 11    Formatter version 1.12 13    :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.14    :license: BSD, see LICENSE for details.15"""16 17# TODO:18#  - Options to map style's bold/underline/italic/border attributes19#    to some ANSI attrbutes (something like 'italic=underline')20#  - An option to output "style RGB to xterm RGB/index" conversion table21#  - An option to indicate that we are running in "reverse background"22#    xterm. This means that default colors are white-on-black, not23#    black-on-while, so colors like "white background" need to be converted24#    to "white background, black foreground", etc...25 26from pygments.formatter import Formatter27from pygments.console import codes28from pygments.style import ansicolors29 30 31__all__ = ['Terminal256Formatter', 'TerminalTrueColorFormatter']32 33 34class EscapeSequence:35    def __init__(self, fg=None, bg=None, bold=False, underline=False, italic=False):36        self.fg = fg37        self.bg = bg38        self.bold = bold39        self.underline = underline40        self.italic = italic41 42    def escape(self, attrs):43        if len(attrs):44            return "\x1b[" + ";".join(attrs) + "m"45        return ""46 47    def color_string(self):48        attrs = []49        if self.fg is not None:50            if self.fg in ansicolors:51                esc = codes[self.fg.replace('ansi','')]52                if ';01m' in esc:53                    self.bold = True54                # extract fg color code.55                attrs.append(esc[2:4])56            else:57                attrs.extend(("38", "5", "%i" % self.fg))58        if self.bg is not None:59            if self.bg in ansicolors:60                esc = codes[self.bg.replace('ansi','')]61                # extract fg color code, add 10 for bg.62                attrs.append(str(int(esc[2:4])+10))63            else:64                attrs.extend(("48", "5", "%i" % self.bg))65        if self.bold:66            attrs.append("01")67        if self.underline:68            attrs.append("04")69        if self.italic:70            attrs.append("03")71        return self.escape(attrs)72 73    def true_color_string(self):74        attrs = []75        if self.fg:76            attrs.extend(("38", "2", str(self.fg[0]), str(self.fg[1]), str(self.fg[2])))77        if self.bg:78            attrs.extend(("48", "2", str(self.bg[0]), str(self.bg[1]), str(self.bg[2])))79        if self.bold:80            attrs.append("01")81        if self.underline:82            attrs.append("04")83        if self.italic:84            attrs.append("03")85        return self.escape(attrs)86 87    def reset_string(self):88        attrs = []89        if self.fg is not None:90            attrs.append("39")91        if self.bg is not None:92            attrs.append("49")93        if self.bold or self.underline or self.italic:94            attrs.append("00")95        return self.escape(attrs)96 97 98class Terminal256Formatter(Formatter):99    """100    Format tokens with ANSI color sequences, for output in a 256-color101    terminal or console.  Like in `TerminalFormatter` color sequences102    are terminated at newlines, so that paging the output works correctly.103 104    The formatter takes colors from a style defined by the `style` option105    and converts them to nearest ANSI 256-color escape sequences. Bold and106    underline attributes from the style are preserved (and displayed).107 108    .. versionadded:: 0.9109 110    .. versionchanged:: 2.2111       If the used style defines foreground colors in the form ``#ansi*``, then112       `Terminal256Formatter` will map these to non extended foreground color.113       See :ref:`AnsiTerminalStyle` for more information.114 115    .. versionchanged:: 2.4116       The ANSI color names have been updated with names that are easier to117       understand and align with colornames of other projects and terminals.118       See :ref:`this table <new-ansi-color-names>` for more information.119 120 121    Options accepted:122 123    `style`124        The style to use, can be a string or a Style subclass (default:125        ``'default'``).126 127    `linenos`128        Set to ``True`` to have line numbers on the terminal output as well129        (default: ``False`` = no line numbers).130    """131    name = 'Terminal256'132    aliases = ['terminal256', 'console256', '256']133    filenames = []134 135    def __init__(self, **options):136        Formatter.__init__(self, **options)137 138        self.xterm_colors = []139        self.best_match = {}140        self.style_string = {}141 142        self.usebold = 'nobold' not in options143        self.useunderline = 'nounderline' not in options144        self.useitalic = 'noitalic' not in options145 146        self._build_color_table()  # build an RGB-to-256 color conversion table147        self._setup_styles()  # convert selected style's colors to term. colors148 149        self.linenos = options.get('linenos', False)150        self._lineno = 0151 152    def _build_color_table(self):153        # colors 0..15: 16 basic colors154 155        self.xterm_colors.append((0x00, 0x00, 0x00))  # 0156        self.xterm_colors.append((0xcd, 0x00, 0x00))  # 1157        self.xterm_colors.append((0x00, 0xcd, 0x00))  # 2158        self.xterm_colors.append((0xcd, 0xcd, 0x00))  # 3159        self.xterm_colors.append((0x00, 0x00, 0xee))  # 4160        self.xterm_colors.append((0xcd, 0x00, 0xcd))  # 5161        self.xterm_colors.append((0x00, 0xcd, 0xcd))  # 6162        self.xterm_colors.append((0xe5, 0xe5, 0xe5))  # 7163        self.xterm_colors.append((0x7f, 0x7f, 0x7f))  # 8164        self.xterm_colors.append((0xff, 0x00, 0x00))  # 9165        self.xterm_colors.append((0x00, 0xff, 0x00))  # 10166        self.xterm_colors.append((0xff, 0xff, 0x00))  # 11167        self.xterm_colors.append((0x5c, 0x5c, 0xff))  # 12168        self.xterm_colors.append((0xff, 0x00, 0xff))  # 13169        self.xterm_colors.append((0x00, 0xff, 0xff))  # 14170        self.xterm_colors.append((0xff, 0xff, 0xff))  # 15171 172        # colors 16..231: the 6x6x6 color cube173 174        valuerange = (0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff)175 176        for i in range(216):177            r = valuerange[(i // 36) % 6]178            g = valuerange[(i // 6) % 6]179            b = valuerange[i % 6]180            self.xterm_colors.append((r, g, b))181 182        # colors 232..255: grayscale183 184        for i in range(24):185            v = 8 + i * 10186            self.xterm_colors.append((v, v, v))187 188    def _closest_color(self, r, g, b):189        distance = 257*257*3  # "infinity" (>distance from #000000 to #ffffff)190        match = 0191 192        for i in range(0, 256):193            values = self.xterm_colors[i]194 195            rd = r - values[0]196            gd = g - values[1]197            bd = b - values[2]198            d = rd*rd + gd*gd + bd*bd199 200            if d < distance:201                match = i202                distance = d203        return match204 205    def _color_index(self, color):206        index = self.best_match.get(color, None)207        if color in ansicolors:208            # strip the `ansi/#ansi` part and look up code209            index = color210            self.best_match[color] = index211        if index is None:212            try:213                rgb = int(str(color), 16)214            except ValueError:215                rgb = 0216 217            r = (rgb >> 16) & 0xff218            g = (rgb >> 8) & 0xff219            b = rgb & 0xff220            index = self._closest_color(r, g, b)221            self.best_match[color] = index222        return index223 224    def _setup_styles(self):225        for ttype, ndef in self.style:226            escape = EscapeSequence()227            # get foreground from ansicolor if set228            if ndef['ansicolor']:229                escape.fg = self._color_index(ndef['ansicolor'])230            elif ndef['color']:231                escape.fg = self._color_index(ndef['color'])232            if ndef['bgansicolor']:233                escape.bg = self._color_index(ndef['bgansicolor'])234            elif ndef['bgcolor']:235                escape.bg = self._color_index(ndef['bgcolor'])236            if self.usebold and ndef['bold']:237                escape.bold = True238            if self.useunderline and ndef['underline']:239                escape.underline = True240            if self.useitalic and ndef['italic']:241                escape.italic = True242            self.style_string[str(ttype)] = (escape.color_string(),243                                             escape.reset_string())244 245    def _write_lineno(self, outfile):246        self._lineno += 1247        outfile.write("%s%04d: " % (self._lineno != 1 and '\n' or '', self._lineno))248 249    def format(self, tokensource, outfile):250        return Formatter.format(self, tokensource, outfile)251 252    def format_unencoded(self, tokensource, outfile):253        if self.linenos:254            self._write_lineno(outfile)255 256        for ttype, value in tokensource:257            not_found = True258            while ttype and not_found:259                try:260                    # outfile.write( "<" + str(ttype) + ">" )261                    on, off = self.style_string[str(ttype)]262 263                    # Like TerminalFormatter, add "reset colors" escape sequence264                    # on newline.265                    spl = value.split('\n')266                    for line in spl[:-1]:267                        if line:268                            outfile.write(on + line + off)269                        if self.linenos:270                            self._write_lineno(outfile)271                        else:272                            outfile.write('\n')273 274                    if spl[-1]:275                        outfile.write(on + spl[-1] + off)276 277                    not_found = False278                    # outfile.write( '#' + str(ttype) + '#' )279 280                except KeyError:281                    # ottype = ttype282                    ttype = ttype.parent283                    # outfile.write( '!' + str(ottype) + '->' + str(ttype) + '!' )284 285            if not_found:286                outfile.write(value)287 288        if self.linenos:289            outfile.write("\n")290 291 292 293class TerminalTrueColorFormatter(Terminal256Formatter):294    r"""295    Format tokens with ANSI color sequences, for output in a true-color296    terminal or console.  Like in `TerminalFormatter` color sequences297    are terminated at newlines, so that paging the output works correctly.298 299    .. versionadded:: 2.1300 301    Options accepted:302 303    `style`304        The style to use, can be a string or a Style subclass (default:305        ``'default'``).306    """307    name = 'TerminalTrueColor'308    aliases = ['terminal16m', 'console16m', '16m']309    filenames = []310 311    def _build_color_table(self):312        pass313 314    def _color_tuple(self, color):315        try:316            rgb = int(str(color), 16)317        except ValueError:318            return None319        r = (rgb >> 16) & 0xff320        g = (rgb >> 8) & 0xff321        b = rgb & 0xff322        return (r, g, b)323 324    def _setup_styles(self):325        for ttype, ndef in self.style:326            escape = EscapeSequence()327            if ndef['color']:328                escape.fg = self._color_tuple(ndef['color'])329            if ndef['bgcolor']:330                escape.bg = self._color_tuple(ndef['bgcolor'])331            if self.usebold and ndef['bold']:332                escape.bold = True333            if self.useunderline and ndef['underline']:334                escape.underline = True335            if self.useitalic and ndef['italic']:336                escape.italic = True337            self.style_string[str(ttype)] = (escape.true_color_string(),338                                             escape.reset_string())339 
codekingpro/portable-devtools · Team Ai