File manager - Edit - /home/newsbmcs.com/public_html/static/img/logo/pygments.zip
Back
PK i��Z���� � formatters/other.pynu �[��� """ pygments.formatters.other ~~~~~~~~~~~~~~~~~~~~~~~~~ Other formatters: NullFormatter, RawTokenFormatter. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.util import get_choice_opt from pip._vendor.pygments.token import Token from pip._vendor.pygments.console import colorize __all__ = ['NullFormatter', 'RawTokenFormatter', 'TestcaseFormatter'] class NullFormatter(Formatter): """ Output the text unchanged without any formatting. """ name = 'Text only' aliases = ['text', 'null'] filenames = ['*.txt'] def format(self, tokensource, outfile): enc = self.encoding for ttype, value in tokensource: if enc: outfile.write(value.encode(enc)) else: outfile.write(value) class RawTokenFormatter(Formatter): r""" Format tokens as a raw representation for storing token streams. The format is ``tokentype<TAB>repr(tokenstring)\n``. The output can later be converted to a token stream with the `RawTokenLexer`, described in the :doc:`lexer list <lexers>`. Only two options are accepted: `compress` If set to ``'gz'`` or ``'bz2'``, compress the output with the given compression algorithm after encoding (default: ``''``). `error_color` If set to a color name, highlight error tokens using that color. If set but with no value, defaults to ``'red'``. .. versionadded:: 0.11 """ name = 'Raw tokens' aliases = ['raw', 'tokens'] filenames = ['*.raw'] unicodeoutput = False def __init__(self, **options): Formatter.__init__(self, **options) # We ignore self.encoding if it is set, since it gets set for lexer # and formatter if given with -Oencoding on the command line. # The RawTokenFormatter outputs only ASCII. Override here. self.encoding = 'ascii' # let pygments.format() do the right thing self.compress = get_choice_opt(options, 'compress', ['', 'none', 'gz', 'bz2'], '') self.error_color = options.get('error_color', None) if self.error_color is True: self.error_color = 'red' if self.error_color is not None: try: colorize(self.error_color, '') except KeyError: raise ValueError(f"Invalid color {self.error_color!r} specified") def format(self, tokensource, outfile): try: outfile.write(b'') except TypeError: raise TypeError('The raw tokens formatter needs a binary ' 'output file') if self.compress == 'gz': import gzip outfile = gzip.GzipFile('', 'wb', 9, outfile) write = outfile.write flush = outfile.close elif self.compress == 'bz2': import bz2 compressor = bz2.BZ2Compressor(9) def write(text): outfile.write(compressor.compress(text)) def flush(): outfile.write(compressor.flush()) outfile.flush() else: write = outfile.write flush = outfile.flush if self.error_color: for ttype, value in tokensource: line = b"%r\t%r\n" % (ttype, value) if ttype is Token.Error: write(colorize(self.error_color, line)) else: write(line) else: for ttype, value in tokensource: write(b"%r\t%r\n" % (ttype, value)) flush() TESTCASE_BEFORE = '''\ def testNeedsName(lexer): fragment = %r tokens = [ ''' TESTCASE_AFTER = '''\ ] assert list(lexer.get_tokens(fragment)) == tokens ''' class TestcaseFormatter(Formatter): """ Format tokens as appropriate for a new testcase. .. versionadded:: 2.0 """ name = 'Testcase' aliases = ['testcase'] def __init__(self, **options): Formatter.__init__(self, **options) if self.encoding is not None and self.encoding != 'utf-8': raise ValueError("Only None and utf-8 are allowed encodings.") def format(self, tokensource, outfile): indentation = ' ' * 12 rawbuf = [] outbuf = [] for ttype, value in tokensource: rawbuf.append(value) outbuf.append(f'{indentation}({ttype}, {value!r}),\n') before = TESTCASE_BEFORE % (''.join(rawbuf),) during = ''.join(outbuf) after = TESTCASE_AFTER if self.encoding is None: outfile.write(before + during + after) else: outfile.write(before.encode('utf-8')) outfile.write(during.encode('utf-8')) outfile.write(after.encode('utf-8')) outfile.flush() PK i��Z��9Mu u formatters/irc.pynu �[��� """ pygments.formatters.irc ~~~~~~~~~~~~~~~~~~~~~~~ Formatter for IRC output :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.token import Keyword, Name, Comment, String, Error, \ Number, Operator, Generic, Token, Whitespace from pip._vendor.pygments.util import get_choice_opt __all__ = ['IRCFormatter'] #: Map token types to a tuple of color values for light and dark #: backgrounds. IRC_COLORS = { Token: ('', ''), Whitespace: ('gray', 'brightblack'), Comment: ('gray', 'brightblack'), Comment.Preproc: ('cyan', 'brightcyan'), Keyword: ('blue', 'brightblue'), Keyword.Type: ('cyan', 'brightcyan'), Operator.Word: ('magenta', 'brightcyan'), 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.Error: ('brightred', 'brightred'), Error: ('_brightred_', '_brightred_'), } IRC_COLOR_MAP = { 'white': 0, 'black': 1, 'blue': 2, 'brightgreen': 3, 'brightred': 4, 'yellow': 5, 'magenta': 6, 'orange': 7, 'green': 7, #compat w/ ansi 'brightyellow': 8, 'lightgreen': 9, 'brightcyan': 9, # compat w/ ansi 'cyan': 10, 'lightblue': 11, 'red': 11, # compat w/ ansi 'brightblue': 12, 'brightmagenta': 13, 'brightblack': 14, 'gray': 15, } def ircformat(color, text): if len(color) < 1: return text add = sub = '' if '_' in color: # italic add += '\x1D' sub = '\x1D' + sub color = color.strip('_') if '*' in color: # bold add += '\x02' sub = '\x02' + sub color = color.strip('*') # underline (\x1F) not supported # backgrounds (\x03FF,BB) not supported if len(color) > 0: # actual color - may have issues with ircformat("red", "blah")+"10" type stuff add += '\x03' + str(IRC_COLOR_MAP[color]).zfill(2) sub = '\x03' + sub return add + text + sub return '<'+add+'>'+text+'</'+sub+'>' class IRCFormatter(Formatter): r""" Format tokens with IRC color sequences 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 in the output as well (default: ``False`` = no line numbers). """ name = 'IRC' aliases = ['irc', 'IRC'] 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 IRC_COLORS self.linenos = options.get('linenos', False) self._lineno = 0 def _write_lineno(self, outfile): if self.linenos: self._lineno += 1 outfile.write("%04d: " % self._lineno) def format_unencoded(self, tokensource, outfile): self._write_lineno(outfile) for ttype, value in tokensource: color = self.colorscheme.get(ttype) while color is None: ttype = ttype[:-1] color = self.colorscheme.get(ttype) if color: color = color[self.darkbg] spl = value.split('\n') for line in spl[:-1]: if line: outfile.write(ircformat(color, line)) outfile.write('\n') self._write_lineno(outfile) if spl[-1]: outfile.write(ircformat(color, spl[-1])) else: outfile.write(value) PK i��Z7�v� formatters/svg.pynu �[��� """ pygments.formatters.svg ~~~~~~~~~~~~~~~~~~~~~~~ Formatter for SVG output. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.token import Comment from pip._vendor.pygments.util import get_bool_opt, get_int_opt __all__ = ['SvgFormatter'] def escape_html(text): """Escape &, <, > as well as single and double quotes for HTML.""" return text.replace('&', '&'). \ replace('<', '<'). \ replace('>', '>'). \ replace('"', '"'). \ replace("'", ''') class2style = {} class SvgFormatter(Formatter): """ Format tokens as an SVG graphics file. This formatter is still experimental. Each line of code is a ``<text>`` element with explicit ``x`` and ``y`` coordinates containing ``<tspan>`` elements with the individual token styles. By default, this formatter outputs a full SVG document including doctype declaration and the ``<svg>`` root element. .. versionadded:: 0.9 Additional options accepted: `nowrap` Don't wrap the SVG ``<text>`` elements in ``<svg><g>`` elements and don't add a XML declaration and a doctype. If true, the `fontfamily` and `fontsize` options are ignored. Defaults to ``False``. `fontfamily` The value to give the wrapping ``<g>`` element's ``font-family`` attribute, defaults to ``"monospace"``. `fontsize` The value to give the wrapping ``<g>`` element's ``font-size`` attribute, defaults to ``"14px"``. `linenos` If ``True``, add line numbers (default: ``False``). `linenostart` The line number for the first line (default: ``1``). `linenostep` If set to a number n > 1, only every nth line number is printed. `linenowidth` Maximum width devoted to line numbers (default: ``3*ystep``, sufficient for up to 4-digit line numbers. Increase width for longer code blocks). `xoffset` Starting offset in X direction, defaults to ``0``. `yoffset` Starting offset in Y direction, defaults to the font size if it is given in pixels, or ``20`` else. (This is necessary since text coordinates refer to the text baseline, not the top edge.) `ystep` Offset to add to the Y coordinate for each subsequent line. This should roughly be the text size plus 5. It defaults to that value if the text size is given in pixels, or ``25`` else. `spacehack` Convert spaces in the source to `` ``, which are non-breaking spaces. SVG provides the ``xml:space`` attribute to control how whitespace inside tags is handled, in theory, the ``preserve`` value could be used to keep all whitespace as-is. However, many current SVG viewers don't obey that rule, so this option is provided as a workaround and defaults to ``True``. """ name = 'SVG' aliases = ['svg'] filenames = ['*.svg'] def __init__(self, **options): Formatter.__init__(self, **options) self.nowrap = get_bool_opt(options, 'nowrap', False) self.fontfamily = options.get('fontfamily', 'monospace') self.fontsize = options.get('fontsize', '14px') self.xoffset = get_int_opt(options, 'xoffset', 0) fs = self.fontsize.strip() if fs.endswith('px'): fs = fs[:-2].strip() try: int_fs = int(fs) except ValueError: int_fs = 20 self.yoffset = get_int_opt(options, 'yoffset', int_fs) self.ystep = get_int_opt(options, 'ystep', int_fs + 5) self.spacehack = get_bool_opt(options, 'spacehack', True) self.linenos = get_bool_opt(options,'linenos',False) self.linenostart = get_int_opt(options,'linenostart',1) self.linenostep = get_int_opt(options,'linenostep',1) self.linenowidth = get_int_opt(options,'linenowidth', 3*self.ystep) self._stylecache = {} def format_unencoded(self, tokensource, outfile): """ Format ``tokensource``, an iterable of ``(tokentype, tokenstring)`` tuples and write it into ``outfile``. For our implementation we put all lines in their own 'line group'. """ x = self.xoffset y = self.yoffset if not self.nowrap: if self.encoding: outfile.write(f'<?xml version="1.0" encoding="{self.encoding}"?>\n') else: outfile.write('<?xml version="1.0"?>\n') outfile.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" ' '"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/' 'svg10.dtd">\n') outfile.write('<svg xmlns="http://www.w3.org/2000/svg">\n') outfile.write(f'<g font-family="{self.fontfamily}" font-size="{self.fontsize}">\n') counter = self.linenostart counter_step = self.linenostep counter_style = self._get_style(Comment) line_x = x if self.linenos: if counter % counter_step == 0: outfile.write(f'<text x="{x+self.linenowidth}" y="{y}" {counter_style} text-anchor="end">{counter}</text>') line_x += self.linenowidth + self.ystep counter += 1 outfile.write(f'<text x="{line_x}" y="{y}" xml:space="preserve">') for ttype, value in tokensource: style = self._get_style(ttype) tspan = style and '<tspan' + style + '>' or '' tspanend = tspan and '</tspan>' or '' value = escape_html(value) if self.spacehack: value = value.expandtabs().replace(' ', ' ') parts = value.split('\n') for part in parts[:-1]: outfile.write(tspan + part + tspanend) y += self.ystep outfile.write('</text>\n') if self.linenos and counter % counter_step == 0: outfile.write(f'<text x="{x+self.linenowidth}" y="{y}" text-anchor="end" {counter_style}>{counter}</text>') counter += 1 outfile.write(f'<text x="{line_x}" y="{y}" ' 'xml:space="preserve">') outfile.write(tspan + parts[-1] + tspanend) outfile.write('</text>') if not self.nowrap: outfile.write('</g></svg>\n') def _get_style(self, tokentype): if tokentype in self._stylecache: return self._stylecache[tokentype] otokentype = tokentype while not self.style.styles_token(tokentype): tokentype = tokentype.parent value = self.style.style_for_token(tokentype) result = '' if value['color']: result = ' fill="#' + value['color'] + '"' if value['bold']: result += ' font-weight="bold"' if value['italic']: result += ' font-style="italic"' self._stylecache[otokentype] = result return result PK i��ZofK��- �- formatters/terminal256.pynu �[��� """ pygments.formatters.terminal256 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Formatter for 256-color terminal output with ANSI sequences. RGB-to-XTERM color conversion routines adapted from xterm256-conv tool (http://frexx.de/xterm-256-notes/data/xterm256-conv2.tar.bz2) by Wolfgang Frisch. Formatter version 1. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ # TODO: # - Options to map style's bold/underline/italic/border attributes # to some ANSI attrbutes (something like 'italic=underline') # - An option to output "style RGB to xterm RGB/index" conversion table # - An option to indicate that we are running in "reverse background" # xterm. This means that default colors are white-on-black, not # black-on-while, so colors like "white background" need to be converted # to "white background, black foreground", etc... from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.console import codes from pip._vendor.pygments.style import ansicolors __all__ = ['Terminal256Formatter', 'TerminalTrueColorFormatter'] class EscapeSequence: def __init__(self, fg=None, bg=None, bold=False, underline=False, italic=False): self.fg = fg self.bg = bg self.bold = bold self.underline = underline self.italic = italic def escape(self, attrs): if len(attrs): return "\x1b[" + ";".join(attrs) + "m" return "" def color_string(self): attrs = [] if self.fg is not None: if self.fg in ansicolors: esc = codes[self.fg.replace('ansi','')] if ';01m' in esc: self.bold = True # extract fg color code. attrs.append(esc[2:4]) else: attrs.extend(("38", "5", "%i" % self.fg)) if self.bg is not None: if self.bg in ansicolors: esc = codes[self.bg.replace('ansi','')] # extract fg color code, add 10 for bg. attrs.append(str(int(esc[2:4])+10)) else: attrs.extend(("48", "5", "%i" % self.bg)) if self.bold: attrs.append("01") if self.underline: attrs.append("04") if self.italic: attrs.append("03") return self.escape(attrs) def true_color_string(self): attrs = [] if self.fg: attrs.extend(("38", "2", str(self.fg[0]), str(self.fg[1]), str(self.fg[2]))) if self.bg: attrs.extend(("48", "2", str(self.bg[0]), str(self.bg[1]), str(self.bg[2]))) if self.bold: attrs.append("01") if self.underline: attrs.append("04") if self.italic: attrs.append("03") return self.escape(attrs) def reset_string(self): attrs = [] if self.fg is not None: attrs.append("39") if self.bg is not None: attrs.append("49") if self.bold or self.underline or self.italic: attrs.append("00") return self.escape(attrs) class Terminal256Formatter(Formatter): """ Format tokens with ANSI color sequences, for output in a 256-color terminal or console. Like in `TerminalFormatter` color sequences are terminated at newlines, so that paging the output works correctly. The formatter takes colors from a style defined by the `style` option and converts them to nearest ANSI 256-color escape sequences. Bold and underline attributes from the style are preserved (and displayed). .. versionadded:: 0.9 .. versionchanged:: 2.2 If the used style defines foreground colors in the form ``#ansi*``, then `Terminal256Formatter` will map these to non extended foreground color. See :ref:`AnsiTerminalStyle` for more information. .. versionchanged:: 2.4 The ANSI color names have been updated with names that are easier to understand and align with colornames of other projects and terminals. See :ref:`this table <new-ansi-color-names>` for more information. Options accepted: `style` The style to use, can be a string or a Style subclass (default: ``'default'``). `linenos` Set to ``True`` to have line numbers on the terminal output as well (default: ``False`` = no line numbers). """ name = 'Terminal256' aliases = ['terminal256', 'console256', '256'] filenames = [] def __init__(self, **options): Formatter.__init__(self, **options) self.xterm_colors = [] self.best_match = {} self.style_string = {} self.usebold = 'nobold' not in options self.useunderline = 'nounderline' not in options self.useitalic = 'noitalic' not in options self._build_color_table() # build an RGB-to-256 color conversion table self._setup_styles() # convert selected style's colors to term. colors self.linenos = options.get('linenos', False) self._lineno = 0 def _build_color_table(self): # colors 0..15: 16 basic colors self.xterm_colors.append((0x00, 0x00, 0x00)) # 0 self.xterm_colors.append((0xcd, 0x00, 0x00)) # 1 self.xterm_colors.append((0x00, 0xcd, 0x00)) # 2 self.xterm_colors.append((0xcd, 0xcd, 0x00)) # 3 self.xterm_colors.append((0x00, 0x00, 0xee)) # 4 self.xterm_colors.append((0xcd, 0x00, 0xcd)) # 5 self.xterm_colors.append((0x00, 0xcd, 0xcd)) # 6 self.xterm_colors.append((0xe5, 0xe5, 0xe5)) # 7 self.xterm_colors.append((0x7f, 0x7f, 0x7f)) # 8 self.xterm_colors.append((0xff, 0x00, 0x00)) # 9 self.xterm_colors.append((0x00, 0xff, 0x00)) # 10 self.xterm_colors.append((0xff, 0xff, 0x00)) # 11 self.xterm_colors.append((0x5c, 0x5c, 0xff)) # 12 self.xterm_colors.append((0xff, 0x00, 0xff)) # 13 self.xterm_colors.append((0x00, 0xff, 0xff)) # 14 self.xterm_colors.append((0xff, 0xff, 0xff)) # 15 # colors 16..232: the 6x6x6 color cube valuerange = (0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff) for i in range(217): r = valuerange[(i // 36) % 6] g = valuerange[(i // 6) % 6] b = valuerange[i % 6] self.xterm_colors.append((r, g, b)) # colors 233..253: grayscale for i in range(1, 22): v = 8 + i * 10 self.xterm_colors.append((v, v, v)) def _closest_color(self, r, g, b): distance = 257*257*3 # "infinity" (>distance from #000000 to #ffffff) match = 0 for i in range(0, 254): values = self.xterm_colors[i] rd = r - values[0] gd = g - values[1] bd = b - values[2] d = rd*rd + gd*gd + bd*bd if d < distance: match = i distance = d return match def _color_index(self, color): index = self.best_match.get(color, None) if color in ansicolors: # strip the `ansi/#ansi` part and look up code index = color self.best_match[color] = index if index is None: try: rgb = int(str(color), 16) except ValueError: rgb = 0 r = (rgb >> 16) & 0xff g = (rgb >> 8) & 0xff b = rgb & 0xff index = self._closest_color(r, g, b) self.best_match[color] = index return index def _setup_styles(self): for ttype, ndef in self.style: escape = EscapeSequence() # get foreground from ansicolor if set if ndef['ansicolor']: escape.fg = self._color_index(ndef['ansicolor']) elif ndef['color']: escape.fg = self._color_index(ndef['color']) if ndef['bgansicolor']: escape.bg = self._color_index(ndef['bgansicolor']) elif ndef['bgcolor']: escape.bg = self._color_index(ndef['bgcolor']) if self.usebold and ndef['bold']: escape.bold = True if self.useunderline and ndef['underline']: escape.underline = True if self.useitalic and ndef['italic']: escape.italic = True self.style_string[str(ttype)] = (escape.color_string(), escape.reset_string()) def _write_lineno(self, outfile): self._lineno += 1 outfile.write("%s%04d: " % (self._lineno != 1 and '\n' or '', self._lineno)) def format(self, tokensource, outfile): return Formatter.format(self, tokensource, outfile) def format_unencoded(self, tokensource, outfile): if self.linenos: self._write_lineno(outfile) for ttype, value in tokensource: not_found = True while ttype and not_found: try: # outfile.write( "<" + str(ttype) + ">" ) on, off = self.style_string[str(ttype)] # Like TerminalFormatter, add "reset colors" escape sequence # on newline. spl = value.split('\n') for line in spl[:-1]: if line: outfile.write(on + line + off) if self.linenos: self._write_lineno(outfile) else: outfile.write('\n') if spl[-1]: outfile.write(on + spl[-1] + off) not_found = False # outfile.write( '#' + str(ttype) + '#' ) except KeyError: # ottype = ttype ttype = ttype.parent # outfile.write( '!' + str(ottype) + '->' + str(ttype) + '!' ) if not_found: outfile.write(value) if self.linenos: outfile.write("\n") class TerminalTrueColorFormatter(Terminal256Formatter): r""" Format tokens with ANSI color sequences, for output in a true-color terminal or console. Like in `TerminalFormatter` color sequences are terminated at newlines, so that paging the output works correctly. .. versionadded:: 2.1 Options accepted: `style` The style to use, can be a string or a Style subclass (default: ``'default'``). """ name = 'TerminalTrueColor' aliases = ['terminal16m', 'console16m', '16m'] filenames = [] def _build_color_table(self): pass def _color_tuple(self, color): try: rgb = int(str(color), 16) except ValueError: return None r = (rgb >> 16) & 0xff g = (rgb >> 8) & 0xff b = rgb & 0xff return (r, g, b) def _setup_styles(self): for ttype, ndef in self.style: escape = EscapeSequence() if ndef['color']: escape.fg = self._color_tuple(ndef['color']) if ndef['bgcolor']: escape.bg = self._color_tuple(ndef['bgcolor']) if self.usebold and ndef['bold']: escape.bold = True if self.useunderline and ndef['underline']: escape.underline = True if self.useitalic and ndef['italic']: escape.italic = True self.style_string[str(ttype)] = (escape.true_color_string(), escape.reset_string()) PK i��Z�(�Z �Z formatters/img.pynu �[��� """ pygments.formatters.img ~~~~~~~~~~~~~~~~~~~~~~~ Formatter for Pixmap output. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os import sys from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.util import get_bool_opt, get_int_opt, get_list_opt, \ get_choice_opt import subprocess # Import this carefully try: from PIL import Image, ImageDraw, ImageFont pil_available = True except ImportError: pil_available = False try: import _winreg except ImportError: try: import winreg as _winreg except ImportError: _winreg = None __all__ = ['ImageFormatter', 'GifImageFormatter', 'JpgImageFormatter', 'BmpImageFormatter'] # For some unknown reason every font calls it something different STYLES = { 'NORMAL': ['', 'Roman', 'Book', 'Normal', 'Regular', 'Medium'], 'ITALIC': ['Oblique', 'Italic'], 'BOLD': ['Bold'], 'BOLDITALIC': ['Bold Oblique', 'Bold Italic'], } # A sane default for modern systems DEFAULT_FONT_NAME_NIX = 'DejaVu Sans Mono' DEFAULT_FONT_NAME_WIN = 'Courier New' DEFAULT_FONT_NAME_MAC = 'Menlo' class PilNotAvailable(ImportError): """When Python imaging library is not available""" class FontNotFound(Exception): """When there are no usable fonts specified""" class FontManager: """ Manages a set of fonts: normal, italic, bold, etc... """ def __init__(self, font_name, font_size=14): self.font_name = font_name self.font_size = font_size self.fonts = {} self.encoding = None self.variable = False if hasattr(font_name, 'read') or os.path.isfile(font_name): font = ImageFont.truetype(font_name, self.font_size) self.variable = True for style in STYLES: self.fonts[style] = font return if sys.platform.startswith('win'): if not font_name: self.font_name = DEFAULT_FONT_NAME_WIN self._create_win() elif sys.platform.startswith('darwin'): if not font_name: self.font_name = DEFAULT_FONT_NAME_MAC self._create_mac() else: if not font_name: self.font_name = DEFAULT_FONT_NAME_NIX self._create_nix() def _get_nix_font_path(self, name, style): proc = subprocess.Popen(['fc-list', f"{name}:style={style}", 'file'], stdout=subprocess.PIPE, stderr=None) stdout, _ = proc.communicate() if proc.returncode == 0: lines = stdout.splitlines() for line in lines: if line.startswith(b'Fontconfig warning:'): continue path = line.decode().strip().strip(':') if path: return path return None def _create_nix(self): for name in STYLES['NORMAL']: path = self._get_nix_font_path(self.font_name, name) if path is not None: self.fonts['NORMAL'] = ImageFont.truetype(path, self.font_size) break else: raise FontNotFound(f'No usable fonts named: "{self.font_name}"') for style in ('ITALIC', 'BOLD', 'BOLDITALIC'): for stylename in STYLES[style]: path = self._get_nix_font_path(self.font_name, stylename) if path is not None: self.fonts[style] = ImageFont.truetype(path, self.font_size) break else: if style == 'BOLDITALIC': self.fonts[style] = self.fonts['BOLD'] else: self.fonts[style] = self.fonts['NORMAL'] def _get_mac_font_path(self, font_map, name, style): return font_map.get((name + ' ' + style).strip().lower()) def _create_mac(self): font_map = {} for font_dir in (os.path.join(os.getenv("HOME"), 'Library/Fonts/'), '/Library/Fonts/', '/System/Library/Fonts/'): font_map.update( (os.path.splitext(f)[0].lower(), os.path.join(font_dir, f)) for f in os.listdir(font_dir) if f.lower().endswith(('ttf', 'ttc'))) for name in STYLES['NORMAL']: path = self._get_mac_font_path(font_map, self.font_name, name) if path is not None: self.fonts['NORMAL'] = ImageFont.truetype(path, self.font_size) break else: raise FontNotFound(f'No usable fonts named: "{self.font_name}"') for style in ('ITALIC', 'BOLD', 'BOLDITALIC'): for stylename in STYLES[style]: path = self._get_mac_font_path(font_map, self.font_name, stylename) if path is not None: self.fonts[style] = ImageFont.truetype(path, self.font_size) break else: if style == 'BOLDITALIC': self.fonts[style] = self.fonts['BOLD'] else: self.fonts[style] = self.fonts['NORMAL'] def _lookup_win(self, key, basename, styles, fail=False): for suffix in ('', ' (TrueType)'): for style in styles: try: valname = '{}{}{}'.format(basename, style and ' '+style, suffix) val, _ = _winreg.QueryValueEx(key, valname) return val except OSError: continue else: if fail: raise FontNotFound(f'Font {basename} ({styles[0]}) not found in registry') return None def _create_win(self): lookuperror = None keynames = [ (_winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows NT\CurrentVersion\Fonts'), (_winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Fonts'), (_winreg.HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\Fonts'), (_winreg.HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows\CurrentVersion\Fonts') ] for keyname in keynames: try: key = _winreg.OpenKey(*keyname) try: path = self._lookup_win(key, self.font_name, STYLES['NORMAL'], True) self.fonts['NORMAL'] = ImageFont.truetype(path, self.font_size) for style in ('ITALIC', 'BOLD', 'BOLDITALIC'): path = self._lookup_win(key, self.font_name, STYLES[style]) if path: self.fonts[style] = ImageFont.truetype(path, self.font_size) else: if style == 'BOLDITALIC': self.fonts[style] = self.fonts['BOLD'] else: self.fonts[style] = self.fonts['NORMAL'] return except FontNotFound as err: lookuperror = err finally: _winreg.CloseKey(key) except OSError: pass else: # If we get here, we checked all registry keys and had no luck # We can be in one of two situations now: # * All key lookups failed. In this case lookuperror is None and we # will raise a generic error # * At least one lookup failed with a FontNotFound error. In this # case, we will raise that as a more specific error if lookuperror: raise lookuperror raise FontNotFound('Can\'t open Windows font registry key') def get_char_size(self): """ Get the character size. """ return self.get_text_size('M') def get_text_size(self, text): """ Get the text size (width, height). """ font = self.fonts['NORMAL'] if hasattr(font, 'getbbox'): # Pillow >= 9.2.0 return font.getbbox(text)[2:4] else: return font.getsize(text) def get_font(self, bold, oblique): """ Get the font based on bold and italic flags. """ if bold and oblique: if self.variable: return self.get_style('BOLDITALIC') return self.fonts['BOLDITALIC'] elif bold: if self.variable: return self.get_style('BOLD') return self.fonts['BOLD'] elif oblique: if self.variable: return self.get_style('ITALIC') return self.fonts['ITALIC'] else: if self.variable: return self.get_style('NORMAL') return self.fonts['NORMAL'] def get_style(self, style): """ Get the specified style of the font if it is a variable font. If not found, return the normal font. """ font = self.fonts[style] for style_name in STYLES[style]: try: font.set_variation_by_name(style_name) return font except ValueError: pass except OSError: return font return font class ImageFormatter(Formatter): """ Create a PNG image from source code. This uses the Python Imaging Library to generate a pixmap from the source code. .. versionadded:: 0.10 Additional options accepted: `image_format` An image format to output to that is recognised by PIL, these include: * "PNG" (default) * "JPEG" * "BMP" * "GIF" `line_pad` The extra spacing (in pixels) between each line of text. Default: 2 `font_name` The font name to be used as the base font from which others, such as bold and italic fonts will be generated. This really should be a monospace font to look sane. If a filename or a file-like object is specified, the user must provide different styles of the font. Default: "Courier New" on Windows, "Menlo" on Mac OS, and "DejaVu Sans Mono" on \\*nix `font_size` The font size in points to be used. Default: 14 `image_pad` The padding, in pixels to be used at each edge of the resulting image. Default: 10 `line_numbers` Whether line numbers should be shown: True/False Default: True `line_number_start` The line number of the first line. Default: 1 `line_number_step` The step used when printing line numbers. Default: 1 `line_number_bg` The background colour (in "#123456" format) of the line number bar, or None to use the style background color. Default: "#eed" `line_number_fg` The text color of the line numbers (in "#123456"-like format). Default: "#886" `line_number_chars` The number of columns of line numbers allowable in the line number margin. Default: 2 `line_number_bold` Whether line numbers will be bold: True/False Default: False `line_number_italic` Whether line numbers will be italicized: True/False Default: False `line_number_separator` Whether a line will be drawn between the line number area and the source code area: True/False Default: True `line_number_pad` The horizontal padding (in pixels) between the line number margin, and the source code area. Default: 6 `hl_lines` Specify a list of lines to be highlighted. .. versionadded:: 1.2 Default: empty list `hl_color` Specify the color for highlighting lines. .. versionadded:: 1.2 Default: highlight color of the selected style """ # Required by the pygments mapper name = 'img' aliases = ['img', 'IMG', 'png'] filenames = ['*.png'] unicodeoutput = False default_image_format = 'png' def __init__(self, **options): """ See the class docstring for explanation of options. """ if not pil_available: raise PilNotAvailable( 'Python Imaging Library is required for this formatter') Formatter.__init__(self, **options) self.encoding = 'latin1' # let pygments.format() do the right thing # Read the style self.styles = dict(self.style) if self.style.background_color is None: self.background_color = '#fff' else: self.background_color = self.style.background_color # Image options self.image_format = get_choice_opt( options, 'image_format', ['png', 'jpeg', 'gif', 'bmp'], self.default_image_format, normcase=True) self.image_pad = get_int_opt(options, 'image_pad', 10) self.line_pad = get_int_opt(options, 'line_pad', 2) # The fonts fontsize = get_int_opt(options, 'font_size', 14) self.fonts = FontManager(options.get('font_name', ''), fontsize) self.fontw, self.fonth = self.fonts.get_char_size() # Line number options self.line_number_fg = options.get('line_number_fg', '#886') self.line_number_bg = options.get('line_number_bg', '#eed') self.line_number_chars = get_int_opt(options, 'line_number_chars', 2) self.line_number_bold = get_bool_opt(options, 'line_number_bold', False) self.line_number_italic = get_bool_opt(options, 'line_number_italic', False) self.line_number_pad = get_int_opt(options, 'line_number_pad', 6) self.line_numbers = get_bool_opt(options, 'line_numbers', True) self.line_number_separator = get_bool_opt(options, 'line_number_separator', True) self.line_number_step = get_int_opt(options, 'line_number_step', 1) self.line_number_start = get_int_opt(options, 'line_number_start', 1) if self.line_numbers: self.line_number_width = (self.fontw * self.line_number_chars + self.line_number_pad * 2) else: self.line_number_width = 0 self.hl_lines = [] hl_lines_str = get_list_opt(options, 'hl_lines', []) for line in hl_lines_str: try: self.hl_lines.append(int(line)) except ValueError: pass self.hl_color = options.get('hl_color', self.style.highlight_color) or '#f90' self.drawables = [] def get_style_defs(self, arg=''): raise NotImplementedError('The -S option is meaningless for the image ' 'formatter. Use -O style=<stylename> instead.') def _get_line_height(self): """ Get the height of a line. """ return self.fonth + self.line_pad def _get_line_y(self, lineno): """ Get the Y coordinate of a line number. """ return lineno * self._get_line_height() + self.image_pad def _get_char_width(self): """ Get the width of a character. """ return self.fontw def _get_char_x(self, linelength): """ Get the X coordinate of a character position. """ return linelength + self.image_pad + self.line_number_width def _get_text_pos(self, linelength, lineno): """ Get the actual position for a character and line position. """ return self._get_char_x(linelength), self._get_line_y(lineno) def _get_linenumber_pos(self, lineno): """ Get the actual position for the start of a line number. """ return (self.image_pad, self._get_line_y(lineno)) def _get_text_color(self, style): """ Get the correct color for the token from the style. """ if style['color'] is not None: fill = '#' + style['color'] else: fill = '#000' return fill def _get_text_bg_color(self, style): """ Get the correct background color for the token from the style. """ if style['bgcolor'] is not None: bg_color = '#' + style['bgcolor'] else: bg_color = None return bg_color def _get_style_font(self, style): """ Get the correct font for the style. """ return self.fonts.get_font(style['bold'], style['italic']) def _get_image_size(self, maxlinelength, maxlineno): """ Get the required image size. """ return (self._get_char_x(maxlinelength) + self.image_pad, self._get_line_y(maxlineno + 0) + self.image_pad) def _draw_linenumber(self, posno, lineno): """ Remember a line number drawable to paint later. """ self._draw_text( self._get_linenumber_pos(posno), str(lineno).rjust(self.line_number_chars), font=self.fonts.get_font(self.line_number_bold, self.line_number_italic), text_fg=self.line_number_fg, text_bg=None, ) def _draw_text(self, pos, text, font, text_fg, text_bg): """ Remember a single drawable tuple to paint later. """ self.drawables.append((pos, text, font, text_fg, text_bg)) def _create_drawables(self, tokensource): """ Create drawables for the token content. """ lineno = charno = maxcharno = 0 maxlinelength = linelength = 0 for ttype, value in tokensource: while ttype not in self.styles: ttype = ttype.parent style = self.styles[ttype] # TODO: make sure tab expansion happens earlier in the chain. It # really ought to be done on the input, as to do it right here is # quite complex. value = value.expandtabs(4) lines = value.splitlines(True) # print lines for i, line in enumerate(lines): temp = line.rstrip('\n') if temp: self._draw_text( self._get_text_pos(linelength, lineno), temp, font = self._get_style_font(style), text_fg = self._get_text_color(style), text_bg = self._get_text_bg_color(style), ) temp_width, _ = self.fonts.get_text_size(temp) linelength += temp_width maxlinelength = max(maxlinelength, linelength) charno += len(temp) maxcharno = max(maxcharno, charno) if line.endswith('\n'): # add a line for each extra line in the value linelength = 0 charno = 0 lineno += 1 self.maxlinelength = maxlinelength self.maxcharno = maxcharno self.maxlineno = lineno def _draw_line_numbers(self): """ Create drawables for the line numbers. """ if not self.line_numbers: return for p in range(self.maxlineno): n = p + self.line_number_start if (n % self.line_number_step) == 0: self._draw_linenumber(p, n) def _paint_line_number_bg(self, im): """ Paint the line number background on the image. """ if not self.line_numbers: return if self.line_number_fg is None: return draw = ImageDraw.Draw(im) recth = im.size[-1] rectw = self.image_pad + self.line_number_width - self.line_number_pad draw.rectangle([(0, 0), (rectw, recth)], fill=self.line_number_bg) if self.line_number_separator: draw.line([(rectw, 0), (rectw, recth)], fill=self.line_number_fg) del draw def format(self, tokensource, outfile): """ Format ``tokensource``, an iterable of ``(tokentype, tokenstring)`` tuples and write it into ``outfile``. This implementation calculates where it should draw each token on the pixmap, then calculates the required pixmap size and draws the items. """ self._create_drawables(tokensource) self._draw_line_numbers() im = Image.new( 'RGB', self._get_image_size(self.maxlinelength, self.maxlineno), self.background_color ) self._paint_line_number_bg(im) draw = ImageDraw.Draw(im) # Highlight if self.hl_lines: x = self.image_pad + self.line_number_width - self.line_number_pad + 1 recth = self._get_line_height() rectw = im.size[0] - x for linenumber in self.hl_lines: y = self._get_line_y(linenumber - 1) draw.rectangle([(x, y), (x + rectw, y + recth)], fill=self.hl_color) for pos, value, font, text_fg, text_bg in self.drawables: if text_bg: # see deprecations https://pillow.readthedocs.io/en/stable/releasenotes/9.2.0.html#font-size-and-offset-methods if hasattr(draw, 'textsize'): text_size = draw.textsize(text=value, font=font) else: text_size = font.getbbox(value)[2:] draw.rectangle([pos[0], pos[1], pos[0] + text_size[0], pos[1] + text_size[1]], fill=text_bg) draw.text(pos, value, font=font, fill=text_fg) im.save(outfile, self.image_format.upper()) # Add one formatter per format, so that the "-f gif" option gives the correct result # when used in pygmentize. class GifImageFormatter(ImageFormatter): """ Create a GIF image from source code. This uses the Python Imaging Library to generate a pixmap from the source code. .. versionadded:: 1.0 """ name = 'img_gif' aliases = ['gif'] filenames = ['*.gif'] default_image_format = 'gif' class JpgImageFormatter(ImageFormatter): """ Create a JPEG image from source code. This uses the Python Imaging Library to generate a pixmap from the source code. .. versionadded:: 1.0 """ name = 'img_jpg' aliases = ['jpg', 'jpeg'] filenames = ['*.jpg'] default_image_format = 'jpeg' class BmpImageFormatter(ImageFormatter): """ Create a bitmap image from source code. This uses the Python Imaging Library to generate a pixmap from the source code. .. versionadded:: 1.0 """ name = 'img_bmp' aliases = ['bmp', 'bitmap'] filenames = ['*.bmp'] default_image_format = 'bmp' PK i��Z � � � formatters/bbcode.pynu �[��� """ pygments.formatters.bbcode ~~~~~~~~~~~~~~~~~~~~~~~~~~ BBcode formatter. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.util import get_bool_opt __all__ = ['BBCodeFormatter'] class BBCodeFormatter(Formatter): """ Format tokens with BBcodes. These formatting codes are used by many bulletin boards, so you can highlight your sourcecode with pygments before posting it there. This formatter has no support for background colors and borders, as there are no common BBcode tags for that. Some board systems (e.g. phpBB) don't support colors in their [code] tag, so you can't use the highlighting together with that tag. Text in a [code] tag usually is shown with a monospace font (which this formatter can do with the ``monofont`` option) and no spaces (which you need for indentation) are removed. Additional options accepted: `style` The style to use, can be a string or a Style subclass (default: ``'default'``). `codetag` If set to true, put the output into ``[code]`` tags (default: ``false``) `monofont` If set to true, add a tag to show the code with a monospace font (default: ``false``). """ name = 'BBCode' aliases = ['bbcode', 'bb'] filenames = [] def __init__(self, **options): Formatter.__init__(self, **options) self._code = get_bool_opt(options, 'codetag', False) self._mono = get_bool_opt(options, 'monofont', False) self.styles = {} self._make_styles() def _make_styles(self): for ttype, ndef in self.style: start = end = '' if ndef['color']: start += '[color=#{}]'.format(ndef['color']) end = '[/color]' + end if ndef['bold']: start += '[b]' end = '[/b]' + end if ndef['italic']: start += '[i]' end = '[/i]' + end if ndef['underline']: start += '[u]' end = '[/u]' + end # there are no common BBcodes for background-color and border self.styles[ttype] = start, end def format_unencoded(self, tokensource, outfile): if self._code: outfile.write('[code]') if self._mono: outfile.write('[font=monospace]') lastval = '' lasttype = None for ttype, value in tokensource: while ttype not in self.styles: ttype = ttype.parent if ttype == lasttype: lastval += value else: if lastval: start, end = self.styles[lasttype] outfile.write(''.join((start, lastval, end))) lastval = value lasttype = ttype if lastval: start, end = self.styles[lasttype] outfile.write(''.join((start, lastval, end))) if self._mono: outfile.write('[/font]') if self._code: outfile.write('[/code]') if self._code or self._mono: outfile.write('\n') PK i��Z����P P formatters/_mapping.pynu �[��� # Automatically generated by scripts/gen_mapfiles.py. # DO NOT EDIT BY HAND; run `tox -e mapfiles` instead. FORMATTERS = { 'BBCodeFormatter': ('pygments.formatters.bbcode', 'BBCode', ('bbcode', 'bb'), (), 'Format tokens with BBcodes. These formatting codes are used by many bulletin boards, so you can highlight your sourcecode with pygments before posting it there.'), 'BmpImageFormatter': ('pygments.formatters.img', 'img_bmp', ('bmp', 'bitmap'), ('*.bmp',), 'Create a bitmap image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), 'GifImageFormatter': ('pygments.formatters.img', 'img_gif', ('gif',), ('*.gif',), 'Create a GIF image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), 'GroffFormatter': ('pygments.formatters.groff', 'groff', ('groff', 'troff', 'roff'), (), 'Format tokens with groff escapes to change their color and font style.'), 'HtmlFormatter': ('pygments.formatters.html', 'HTML', ('html',), ('*.html', '*.htm'), "Format tokens as HTML 4 ``<span>`` tags. By default, the content is enclosed in a ``<pre>`` tag, itself wrapped in a ``<div>`` tag (but see the `nowrap` option). The ``<div>``'s CSS class can be set by the `cssclass` option."), 'IRCFormatter': ('pygments.formatters.irc', 'IRC', ('irc', 'IRC'), (), 'Format tokens with IRC color sequences'), 'ImageFormatter': ('pygments.formatters.img', 'img', ('img', 'IMG', 'png'), ('*.png',), 'Create a PNG image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), 'JpgImageFormatter': ('pygments.formatters.img', 'img_jpg', ('jpg', 'jpeg'), ('*.jpg',), 'Create a JPEG image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), 'LatexFormatter': ('pygments.formatters.latex', 'LaTeX', ('latex', 'tex'), ('*.tex',), 'Format tokens as LaTeX code. This needs the `fancyvrb` and `color` standard packages.'), 'NullFormatter': ('pygments.formatters.other', 'Text only', ('text', 'null'), ('*.txt',), 'Output the text unchanged without any formatting.'), 'PangoMarkupFormatter': ('pygments.formatters.pangomarkup', 'Pango Markup', ('pango', 'pangomarkup'), (), 'Format tokens as Pango Markup code. It can then be rendered to an SVG.'), 'RawTokenFormatter': ('pygments.formatters.other', 'Raw tokens', ('raw', 'tokens'), ('*.raw',), 'Format tokens as a raw representation for storing token streams.'), 'RtfFormatter': ('pygments.formatters.rtf', 'RTF', ('rtf',), ('*.rtf',), 'Format tokens as RTF markup. This formatter automatically outputs full RTF documents with color information and other useful stuff. Perfect for Copy and Paste into Microsoft(R) Word(R) documents.'), 'SvgFormatter': ('pygments.formatters.svg', 'SVG', ('svg',), ('*.svg',), 'Format tokens as an SVG graphics file. This formatter is still experimental. Each line of code is a ``<text>`` element with explicit ``x`` and ``y`` coordinates containing ``<tspan>`` elements with the individual token styles.'), 'Terminal256Formatter': ('pygments.formatters.terminal256', 'Terminal256', ('terminal256', 'console256', '256'), (), 'Format tokens with ANSI color sequences, for output in a 256-color terminal or console. Like in `TerminalFormatter` color sequences are terminated at newlines, so that paging the output works correctly.'), 'TerminalFormatter': ('pygments.formatters.terminal', 'Terminal', ('terminal', 'console'), (), '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.'), 'TerminalTrueColorFormatter': ('pygments.formatters.terminal256', 'TerminalTrueColor', ('terminal16m', 'console16m', '16m'), (), 'Format tokens with ANSI color sequences, for output in a true-color terminal or console. Like in `TerminalFormatter` color sequences are terminated at newlines, so that paging the output works correctly.'), 'TestcaseFormatter': ('pygments.formatters.other', 'Testcase', ('testcase',), (), 'Format tokens as appropriate for a new testcase.'), } PK i��Z��R B B formatters/terminal.pynu �[��� """ pygments.formatters.terminal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Formatter for terminal output with ANSI sequences. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.token import Keyword, Name, Comment, String, Error, \ Number, Operator, Generic, Token, Whitespace from pip._vendor.pygments.console import ansiformat from pip._vendor.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") PK i��Zs�3� � formatters/pangomarkup.pynu �[��� """ pygments.formatters.pangomarkup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Formatter for Pango markup output. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.formatter import Formatter __all__ = ['PangoMarkupFormatter'] _escape_table = { ord('&'): '&', ord('<'): '<', } def escape_special_chars(text, table=_escape_table): """Escape & and < for Pango Markup.""" return text.translate(table) class PangoMarkupFormatter(Formatter): """ Format tokens as Pango Markup code. It can then be rendered to an SVG. .. versionadded:: 2.9 """ name = 'Pango Markup' aliases = ['pango', 'pangomarkup'] filenames = [] def __init__(self, **options): Formatter.__init__(self, **options) self.styles = {} for token, style in self.style: start = '' end = '' if style['color']: start += '<span fgcolor="#{}">'.format(style['color']) end = '</span>' + end if style['bold']: start += '<b>' end = '</b>' + end if style['italic']: start += '<i>' end = '</i>' + end if style['underline']: start += '<u>' end = '</u>' + end self.styles[token] = (start, end) def format_unencoded(self, tokensource, outfile): lastval = '' lasttype = None outfile.write('<tt>') for ttype, value in tokensource: while ttype not in self.styles: ttype = ttype.parent if ttype == lasttype: lastval += escape_special_chars(value) else: if lastval: stylebegin, styleend = self.styles[lasttype] outfile.write(stylebegin + lastval + styleend) lastval = escape_special_chars(value) lasttype = ttype if lastval: stylebegin, styleend = self.styles[lasttype] outfile.write(stylebegin + lastval + styleend) outfile.write('</tt>') PK i��Z0n��jK jK formatters/latex.pynu �[��� """ pygments.formatters.latex ~~~~~~~~~~~~~~~~~~~~~~~~~ Formatter for LaTeX fancyvrb output. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from io import StringIO from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.lexer import Lexer, do_insertions from pip._vendor.pygments.token import Token, STANDARD_TYPES from pip._vendor.pygments.util import get_bool_opt, get_int_opt __all__ = ['LatexFormatter'] def escape_tex(text, commandprefix): return text.replace('\\', '\x00'). \ replace('{', '\x01'). \ replace('}', '\x02'). \ replace('\x00', rf'\{commandprefix}Zbs{{}}'). \ replace('\x01', rf'\{commandprefix}Zob{{}}'). \ replace('\x02', rf'\{commandprefix}Zcb{{}}'). \ replace('^', rf'\{commandprefix}Zca{{}}'). \ replace('_', rf'\{commandprefix}Zus{{}}'). \ replace('&', rf'\{commandprefix}Zam{{}}'). \ replace('<', rf'\{commandprefix}Zlt{{}}'). \ replace('>', rf'\{commandprefix}Zgt{{}}'). \ replace('#', rf'\{commandprefix}Zsh{{}}'). \ replace('%', rf'\{commandprefix}Zpc{{}}'). \ replace('$', rf'\{commandprefix}Zdl{{}}'). \ replace('-', rf'\{commandprefix}Zhy{{}}'). \ replace("'", rf'\{commandprefix}Zsq{{}}'). \ replace('"', rf'\{commandprefix}Zdq{{}}'). \ replace('~', rf'\{commandprefix}Zti{{}}') DOC_TEMPLATE = r''' \documentclass{%(docclass)s} \usepackage{fancyvrb} \usepackage{color} \usepackage[%(encoding)s]{inputenc} %(preamble)s %(styledefs)s \begin{document} \section*{%(title)s} %(code)s \end{document} ''' ## Small explanation of the mess below :) # # The previous version of the LaTeX formatter just assigned a command to # each token type defined in the current style. That obviously is # problematic if the highlighted code is produced for a different style # than the style commands themselves. # # This version works much like the HTML formatter which assigns multiple # CSS classes to each <span> tag, from the most specific to the least # specific token type, thus falling back to the parent token type if one # is not defined. Here, the classes are there too and use the same short # forms given in token.STANDARD_TYPES. # # Highlighted code now only uses one custom command, which by default is # \PY and selectable by the commandprefix option (and in addition the # escapes \PYZat, \PYZlb and \PYZrb which haven't been renamed for # backwards compatibility purposes). # # \PY has two arguments: the classes, separated by +, and the text to # render in that style. The classes are resolved into the respective # style commands by magic, which serves to ignore unknown classes. # # The magic macros are: # * \PY@it, \PY@bf, etc. are unconditionally wrapped around the text # to render in \PY@do. Their definition determines the style. # * \PY@reset resets \PY@it etc. to do nothing. # * \PY@toks parses the list of classes, using magic inspired by the # keyval package (but modified to use plusses instead of commas # because fancyvrb redefines commas inside its environments). # * \PY@tok processes one class, calling the \PY@tok@classname command # if it exists. # * \PY@tok@classname sets the \PY@it etc. to reflect the chosen style # for its class. # * \PY resets the style, parses the classnames and then calls \PY@do. # # Tip: to read this code, print it out in substituted form using e.g. # >>> print STYLE_TEMPLATE % {'cp': 'PY'} STYLE_TEMPLATE = r''' \makeatletter \def\%(cp)s@reset{\let\%(cp)s@it=\relax \let\%(cp)s@bf=\relax%% \let\%(cp)s@ul=\relax \let\%(cp)s@tc=\relax%% \let\%(cp)s@bc=\relax \let\%(cp)s@ff=\relax} \def\%(cp)s@tok#1{\csname %(cp)s@tok@#1\endcsname} \def\%(cp)s@toks#1+{\ifx\relax#1\empty\else%% \%(cp)s@tok{#1}\expandafter\%(cp)s@toks\fi} \def\%(cp)s@do#1{\%(cp)s@bc{\%(cp)s@tc{\%(cp)s@ul{%% \%(cp)s@it{\%(cp)s@bf{\%(cp)s@ff{#1}}}}}}} \def\%(cp)s#1#2{\%(cp)s@reset\%(cp)s@toks#1+\relax+\%(cp)s@do{#2}} %(styles)s \def\%(cp)sZbs{\char`\\} \def\%(cp)sZus{\char`\_} \def\%(cp)sZob{\char`\{} \def\%(cp)sZcb{\char`\}} \def\%(cp)sZca{\char`\^} \def\%(cp)sZam{\char`\&} \def\%(cp)sZlt{\char`\<} \def\%(cp)sZgt{\char`\>} \def\%(cp)sZsh{\char`\#} \def\%(cp)sZpc{\char`\%%} \def\%(cp)sZdl{\char`\$} \def\%(cp)sZhy{\char`\-} \def\%(cp)sZsq{\char`\'} \def\%(cp)sZdq{\char`\"} \def\%(cp)sZti{\char`\~} %% for compatibility with earlier versions \def\%(cp)sZat{@} \def\%(cp)sZlb{[} \def\%(cp)sZrb{]} \makeatother ''' def _get_ttype_name(ttype): fname = STANDARD_TYPES.get(ttype) if fname: return fname aname = '' while fname is None: aname = ttype[-1] + aname ttype = ttype.parent fname = STANDARD_TYPES.get(ttype) return fname + aname class LatexFormatter(Formatter): r""" Format tokens as LaTeX code. This needs the `fancyvrb` and `color` standard packages. Without the `full` option, code is formatted as one ``Verbatim`` environment, like this: .. sourcecode:: latex \begin{Verbatim}[commandchars=\\\{\}] \PY{k}{def }\PY{n+nf}{foo}(\PY{n}{bar}): \PY{k}{pass} \end{Verbatim} Wrapping can be disabled using the `nowrap` option. The special command used here (``\PY``) and all the other macros it needs are output by the `get_style_defs` method. With the `full` option, a complete LaTeX document is output, including the command definitions in the preamble. The `get_style_defs()` method of a `LatexFormatter` returns a string containing ``\def`` commands defining the macros needed inside the ``Verbatim`` environments. Additional options accepted: `nowrap` If set to ``True``, don't wrap the tokens at all, not even inside a ``\begin{Verbatim}`` environment. This disables most other options (default: ``False``). `style` The style to use, can be a string or a Style subclass (default: ``'default'``). `full` Tells the formatter to output a "full" document, i.e. a complete self-contained document (default: ``False``). `title` If `full` is true, the title that should be used to caption the document (default: ``''``). `docclass` If the `full` option is enabled, this is the document class to use (default: ``'article'``). `preamble` If the `full` option is enabled, this can be further preamble commands, e.g. ``\usepackage`` (default: ``''``). `linenos` If set to ``True``, output line numbers (default: ``False``). `linenostart` The line number for the first line (default: ``1``). `linenostep` If set to a number n > 1, only every nth line number is printed. `verboptions` Additional options given to the Verbatim environment (see the *fancyvrb* docs for possible values) (default: ``''``). `commandprefix` The LaTeX commands used to produce colored output are constructed using this prefix and some letters (default: ``'PY'``). .. versionadded:: 0.7 .. versionchanged:: 0.10 The default is now ``'PY'`` instead of ``'C'``. `texcomments` If set to ``True``, enables LaTeX comment lines. That is, LaTex markup in comment tokens is not escaped so that LaTeX can render it (default: ``False``). .. versionadded:: 1.2 `mathescape` If set to ``True``, enables LaTeX math mode escape in comments. That is, ``'$...$'`` inside a comment will trigger math mode (default: ``False``). .. versionadded:: 1.2 `escapeinside` If set to a string of length 2, enables escaping to LaTeX. Text delimited by these 2 characters is read as LaTeX code and typeset accordingly. It has no effect in string literals. It has no effect in comments if `texcomments` or `mathescape` is set. (default: ``''``). .. versionadded:: 2.0 `envname` Allows you to pick an alternative environment name replacing Verbatim. The alternate environment still has to support Verbatim's option syntax. (default: ``'Verbatim'``). .. versionadded:: 2.0 """ name = 'LaTeX' aliases = ['latex', 'tex'] filenames = ['*.tex'] def __init__(self, **options): Formatter.__init__(self, **options) self.nowrap = get_bool_opt(options, 'nowrap', False) self.docclass = options.get('docclass', 'article') self.preamble = options.get('preamble', '') self.linenos = get_bool_opt(options, 'linenos', False) self.linenostart = abs(get_int_opt(options, 'linenostart', 1)) self.linenostep = abs(get_int_opt(options, 'linenostep', 1)) self.verboptions = options.get('verboptions', '') self.nobackground = get_bool_opt(options, 'nobackground', False) self.commandprefix = options.get('commandprefix', 'PY') self.texcomments = get_bool_opt(options, 'texcomments', False) self.mathescape = get_bool_opt(options, 'mathescape', False) self.escapeinside = options.get('escapeinside', '') if len(self.escapeinside) == 2: self.left = self.escapeinside[0] self.right = self.escapeinside[1] else: self.escapeinside = '' self.envname = options.get('envname', 'Verbatim') self._create_stylesheet() def _create_stylesheet(self): t2n = self.ttype2name = {Token: ''} c2d = self.cmd2def = {} cp = self.commandprefix def rgbcolor(col): if col: return ','.join(['%.2f' % (int(col[i] + col[i + 1], 16) / 255.0) for i in (0, 2, 4)]) else: return '1,1,1' for ttype, ndef in self.style: name = _get_ttype_name(ttype) cmndef = '' if ndef['bold']: cmndef += r'\let\$$@bf=\textbf' if ndef['italic']: cmndef += r'\let\$$@it=\textit' if ndef['underline']: cmndef += r'\let\$$@ul=\underline' if ndef['roman']: cmndef += r'\let\$$@ff=\textrm' if ndef['sans']: cmndef += r'\let\$$@ff=\textsf' if ndef['mono']: cmndef += r'\let\$$@ff=\textsf' if ndef['color']: cmndef += (r'\def\$$@tc##1{{\textcolor[rgb]{{{}}}{{##1}}}}'.format(rgbcolor(ndef['color']))) if ndef['border']: cmndef += (r'\def\$$@bc##1{{{{\setlength{{\fboxsep}}{{\string -\fboxrule}}' r'\fcolorbox[rgb]{{{}}}{{{}}}{{\strut ##1}}}}}}'.format(rgbcolor(ndef['border']), rgbcolor(ndef['bgcolor']))) elif ndef['bgcolor']: cmndef += (r'\def\$$@bc##1{{{{\setlength{{\fboxsep}}{{0pt}}' r'\colorbox[rgb]{{{}}}{{\strut ##1}}}}}}'.format(rgbcolor(ndef['bgcolor']))) if cmndef == '': continue cmndef = cmndef.replace('$$', cp) t2n[ttype] = name c2d[name] = cmndef def get_style_defs(self, arg=''): """ Return the command sequences needed to define the commands used to format text in the verbatim environment. ``arg`` is ignored. """ cp = self.commandprefix styles = [] for name, definition in self.cmd2def.items(): styles.append(rf'\@namedef{{{cp}@tok@{name}}}{{{definition}}}') return STYLE_TEMPLATE % {'cp': self.commandprefix, 'styles': '\n'.join(styles)} def format_unencoded(self, tokensource, outfile): # TODO: add support for background colors t2n = self.ttype2name cp = self.commandprefix if self.full: realoutfile = outfile outfile = StringIO() if not self.nowrap: outfile.write('\\begin{' + self.envname + '}[commandchars=\\\\\\{\\}') if self.linenos: start, step = self.linenostart, self.linenostep outfile.write(',numbers=left' + (start and ',firstnumber=%d' % start or '') + (step and ',stepnumber=%d' % step or '')) if self.mathescape or self.texcomments or self.escapeinside: outfile.write(',codes={\\catcode`\\$=3\\catcode`\\^=7' '\\catcode`\\_=8\\relax}') if self.verboptions: outfile.write(',' + self.verboptions) outfile.write(']\n') for ttype, value in tokensource: if ttype in Token.Comment: if self.texcomments: # Try to guess comment starting lexeme and escape it ... start = value[0:1] for i in range(1, len(value)): if start[0] != value[i]: break start += value[i] value = value[len(start):] start = escape_tex(start, cp) # ... but do not escape inside comment. value = start + value elif self.mathescape: # Only escape parts not inside a math environment. parts = value.split('$') in_math = False for i, part in enumerate(parts): if not in_math: parts[i] = escape_tex(part, cp) in_math = not in_math value = '$'.join(parts) elif self.escapeinside: text = value value = '' while text: a, sep1, text = text.partition(self.left) if sep1: b, sep2, text = text.partition(self.right) if sep2: value += escape_tex(a, cp) + b else: value += escape_tex(a + sep1 + b, cp) else: value += escape_tex(a, cp) else: value = escape_tex(value, cp) elif ttype not in Token.Escape: value = escape_tex(value, cp) styles = [] while ttype is not Token: try: styles.append(t2n[ttype]) except KeyError: # not in current style styles.append(_get_ttype_name(ttype)) ttype = ttype.parent styleval = '+'.join(reversed(styles)) if styleval: spl = value.split('\n') for line in spl[:-1]: if line: outfile.write(f"\\{cp}{{{styleval}}}{{{line}}}") outfile.write('\n') if spl[-1]: outfile.write(f"\\{cp}{{{styleval}}}{{{spl[-1]}}}") else: outfile.write(value) if not self.nowrap: outfile.write('\\end{' + self.envname + '}\n') if self.full: encoding = self.encoding or 'utf8' # map known existings encodings from LaTeX distribution encoding = { 'utf_8': 'utf8', 'latin_1': 'latin1', 'iso_8859_1': 'latin1', }.get(encoding.replace('-', '_'), encoding) realoutfile.write(DOC_TEMPLATE % dict(docclass = self.docclass, preamble = self.preamble, title = self.title, encoding = encoding, styledefs = self.get_style_defs(), code = outfile.getvalue())) class LatexEmbeddedLexer(Lexer): """ This lexer takes one lexer as argument, the lexer for the language being formatted, and the left and right delimiters for escaped text. First everything is scanned using the language lexer to obtain strings and comments. All other consecutive tokens are merged and the resulting text is scanned for escaped segments, which are given the Token.Escape type. Finally text that is not escaped is scanned again with the language lexer. """ def __init__(self, left, right, lang, **options): self.left = left self.right = right self.lang = lang Lexer.__init__(self, **options) def get_tokens_unprocessed(self, text): # find and remove all the escape tokens (replace with an empty string) # this is very similar to DelegatingLexer.get_tokens_unprocessed. buffered = '' insertions = [] insertion_buf = [] for i, t, v in self._find_safe_escape_tokens(text): if t is None: if insertion_buf: insertions.append((len(buffered), insertion_buf)) insertion_buf = [] buffered += v else: insertion_buf.append((i, t, v)) if insertion_buf: insertions.append((len(buffered), insertion_buf)) return do_insertions(insertions, self.lang.get_tokens_unprocessed(buffered)) def _find_safe_escape_tokens(self, text): """ find escape tokens that are not in strings or comments """ for i, t, v in self._filter_to( self.lang.get_tokens_unprocessed(text), lambda t: t in Token.Comment or t in Token.String ): if t is None: for i2, t2, v2 in self._find_escape_tokens(v): yield i + i2, t2, v2 else: yield i, None, v def _filter_to(self, it, pred): """ Keep only the tokens that match `pred`, merge the others together """ buf = '' idx = 0 for i, t, v in it: if pred(t): if buf: yield idx, None, buf buf = '' yield i, t, v else: if not buf: idx = i buf += v if buf: yield idx, None, buf def _find_escape_tokens(self, text): """ Find escape tokens within text, give token=None otherwise """ index = 0 while text: a, sep1, text = text.partition(self.left) if a: yield index, None, a index += len(a) if sep1: b, sep2, text = text.partition(self.right) if sep2: yield index + len(sep1), Token.Escape, b index += len(sep1) + len(b) + len(sep2) else: yield index, Token.Error, sep1 index += len(sep1) text = b PK i��Z�Ң0� � formatters/groff.pynu �[��� """ pygments.formatters.groff ~~~~~~~~~~~~~~~~~~~~~~~~~ Formatter for groff output. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import math from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.util import get_bool_opt, get_int_opt __all__ = ['GroffFormatter'] class GroffFormatter(Formatter): """ Format tokens with groff escapes to change their color and font style. .. versionadded:: 2.11 Additional options accepted: `style` The style to use, can be a string or a Style subclass (default: ``'default'``). `monospaced` If set to true, monospace font will be used (default: ``true``). `linenos` If set to true, print the line numbers (default: ``false``). `wrap` Wrap lines to the specified number of characters. Disabled if set to 0 (default: ``0``). """ name = 'groff' aliases = ['groff','troff','roff'] filenames = [] def __init__(self, **options): Formatter.__init__(self, **options) self.monospaced = get_bool_opt(options, 'monospaced', True) self.linenos = get_bool_opt(options, 'linenos', False) self._lineno = 0 self.wrap = get_int_opt(options, 'wrap', 0) self._linelen = 0 self.styles = {} self._make_styles() def _make_styles(self): regular = '\\f[CR]' if self.monospaced else '\\f[R]' bold = '\\f[CB]' if self.monospaced else '\\f[B]' italic = '\\f[CI]' if self.monospaced else '\\f[I]' for ttype, ndef in self.style: start = end = '' if ndef['color']: start += '\\m[{}]'.format(ndef['color']) end = '\\m[]' + end if ndef['bold']: start += bold end = regular + end if ndef['italic']: start += italic end = regular + end if ndef['bgcolor']: start += '\\M[{}]'.format(ndef['bgcolor']) end = '\\M[]' + end self.styles[ttype] = start, end def _define_colors(self, outfile): colors = set() for _, ndef in self.style: if ndef['color'] is not None: colors.add(ndef['color']) for color in sorted(colors): outfile.write('.defcolor ' + color + ' rgb #' + color + '\n') def _write_lineno(self, outfile): self._lineno += 1 outfile.write("%s% 4d " % (self._lineno != 1 and '\n' or '', self._lineno)) def _wrap_line(self, line): length = len(line.rstrip('\n')) space = ' ' if self.linenos else '' newline = '' if length > self.wrap: for i in range(0, math.floor(length / self.wrap)): chunk = line[i*self.wrap:i*self.wrap+self.wrap] newline += (chunk + '\n' + space) remainder = length % self.wrap if remainder > 0: newline += line[-remainder-1:] self._linelen = remainder elif self._linelen + length > self.wrap: newline = ('\n' + space) + line self._linelen = length else: newline = line self._linelen += length return newline def _escape_chars(self, text): text = text.replace('\\', '\\[u005C]'). \ replace('.', '\\[char46]'). \ replace('\'', '\\[u0027]'). \ replace('`', '\\[u0060]'). \ replace('~', '\\[u007E]') copy = text for char in copy: if len(char) != len(char.encode()): uni = char.encode('unicode_escape') \ .decode()[1:] \ .replace('x', 'u00') \ .upper() text = text.replace(char, '\\[u' + uni[1:] + ']') return text def format_unencoded(self, tokensource, outfile): self._define_colors(outfile) outfile.write('.nf\n\\f[CR]\n') if self.linenos: self._write_lineno(outfile) for ttype, value in tokensource: while ttype not in self.styles: ttype = ttype.parent start, end = self.styles[ttype] for line in value.splitlines(True): if self.wrap > 0: line = self._wrap_line(line) if start and end: text = self._escape_chars(line.rstrip('\n')) if text != '': outfile.write(''.join((start, text, end))) else: outfile.write(self._escape_chars(line.rstrip('\n'))) if line.endswith('\n'): if self.linenos: self._write_lineno(outfile) self._linelen = 0 else: outfile.write('\n') self._linelen = 0 outfile.write('\n.fi') PK i��Zn�dB�. �. formatters/rtf.pynu �[��� """ pygments.formatters.rtf ~~~~~~~~~~~~~~~~~~~~~~~ A formatter that generates RTF files. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from collections import OrderedDict from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.style import _ansimap from pip._vendor.pygments.util import get_bool_opt, get_int_opt, get_list_opt, surrogatepair __all__ = ['RtfFormatter'] class RtfFormatter(Formatter): """ Format tokens as RTF markup. This formatter automatically outputs full RTF documents with color information and other useful stuff. Perfect for Copy and Paste into Microsoft(R) Word(R) documents. Please note that ``encoding`` and ``outencoding`` options are ignored. The RTF format is ASCII natively, but handles unicode characters correctly thanks to escape sequences. .. versionadded:: 0.6 Additional options accepted: `style` The style to use, can be a string or a Style subclass (default: ``'default'``). `fontface` The used font family, for example ``Bitstream Vera Sans``. Defaults to some generic font which is supposed to have fixed width. `fontsize` Size of the font used. Size is specified in half points. The default is 24 half-points, giving a size 12 font. .. versionadded:: 2.0 `linenos` Turn on line numbering (default: ``False``). .. versionadded:: 2.18 `lineno_fontsize` Font size for line numbers. Size is specified in half points (default: `fontsize`). .. versionadded:: 2.18 `lineno_padding` Number of spaces between the (inline) line numbers and the source code (default: ``2``). .. versionadded:: 2.18 `linenostart` The line number for the first line (default: ``1``). .. versionadded:: 2.18 `linenostep` If set to a number n > 1, only every nth line number is printed. .. versionadded:: 2.18 `lineno_color` Color for line numbers specified as a hex triplet, e.g. ``'5e5e5e'``. Defaults to the style's line number color if it is a hex triplet, otherwise ansi bright black. .. versionadded:: 2.18 `hl_lines` Specify a list of lines to be highlighted, as line numbers separated by spaces, e.g. ``'3 7 8'``. The line numbers are relative to the input (i.e. the first line is line 1) unless `hl_linenostart` is set. .. versionadded:: 2.18 `hl_color` Color for highlighting the lines specified in `hl_lines`, specified as a hex triplet (default: style's `highlight_color`). .. versionadded:: 2.18 `hl_linenostart` If set to ``True`` line numbers in `hl_lines` are specified relative to `linenostart` (default ``False``). .. versionadded:: 2.18 """ name = 'RTF' aliases = ['rtf'] filenames = ['*.rtf'] def __init__(self, **options): r""" Additional options accepted: ``fontface`` Name of the font used. Could for example be ``'Courier New'`` to further specify the default which is ``'\fmodern'``. The RTF specification claims that ``\fmodern`` are "Fixed-pitch serif and sans serif fonts". Hope every RTF implementation thinks the same about modern... """ Formatter.__init__(self, **options) self.fontface = options.get('fontface') or '' self.fontsize = get_int_opt(options, 'fontsize', 0) self.linenos = get_bool_opt(options, 'linenos', False) self.lineno_fontsize = get_int_opt(options, 'lineno_fontsize', self.fontsize) self.lineno_padding = get_int_opt(options, 'lineno_padding', 2) self.linenostart = abs(get_int_opt(options, 'linenostart', 1)) self.linenostep = abs(get_int_opt(options, 'linenostep', 1)) self.hl_linenostart = get_bool_opt(options, 'hl_linenostart', False) self.hl_color = options.get('hl_color', '') if not self.hl_color: self.hl_color = self.style.highlight_color self.hl_lines = [] for lineno in get_list_opt(options, 'hl_lines', []): try: lineno = int(lineno) if self.hl_linenostart: lineno = lineno - self.linenostart + 1 self.hl_lines.append(lineno) except ValueError: pass self.lineno_color = options.get('lineno_color', '') if not self.lineno_color: if self.style.line_number_color == 'inherit': # style color is the css value 'inherit' # default to ansi bright-black self.lineno_color = _ansimap['ansibrightblack'] else: # style color is assumed to be a hex triplet as other # colors in pygments/style.py self.lineno_color = self.style.line_number_color self.color_mapping = self._create_color_mapping() def _escape(self, text): return text.replace('\\', '\\\\') \ .replace('{', '\\{') \ .replace('}', '\\}') def _escape_text(self, text): # empty strings, should give a small performance improvement if not text: return '' # escape text text = self._escape(text) buf = [] for c in text: cn = ord(c) if cn < (2**7): # ASCII character buf.append(str(c)) elif (2**7) <= cn < (2**16): # single unicode escape sequence buf.append('{\\u%d}' % cn) elif (2**16) <= cn: # RTF limits unicode to 16 bits. # Force surrogate pairs buf.append('{\\u%d}{\\u%d}' % surrogatepair(cn)) return ''.join(buf).replace('\n', '\\par') @staticmethod def hex_to_rtf_color(hex_color): if hex_color[0] == "#": hex_color = hex_color[1:] return '\\red%d\\green%d\\blue%d;' % ( int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16) ) def _split_tokens_on_newlines(self, tokensource): """ Split tokens containing newline characters into multiple token each representing a line of the input file. Needed for numbering lines of e.g. multiline comments. """ for ttype, value in tokensource: if value == '\n': yield (ttype, value) elif "\n" in value: lines = value.split("\n") for line in lines[:-1]: yield (ttype, line+"\n") if lines[-1]: yield (ttype, lines[-1]) else: yield (ttype, value) def _create_color_mapping(self): """ Create a mapping of style hex colors to index/offset in the RTF color table. """ color_mapping = OrderedDict() offset = 1 if self.linenos: color_mapping[self.lineno_color] = offset offset += 1 if self.hl_lines: color_mapping[self.hl_color] = offset offset += 1 for _, style in self.style: for color in style['color'], style['bgcolor'], style['border']: if color and color not in color_mapping: color_mapping[color] = offset offset += 1 return color_mapping @property def _lineno_template(self): if self.lineno_fontsize != self.fontsize: return '{{\\fs{} \\cf{} %s{}}}'.format(self.lineno_fontsize, self.color_mapping[self.lineno_color], " " * self.lineno_padding) return '{{\\cf{} %s{}}}'.format(self.color_mapping[self.lineno_color], " " * self.lineno_padding) @property def _hl_open_str(self): return rf'{{\highlight{self.color_mapping[self.hl_color]} ' @property def _rtf_header(self): lines = [] # rtf 1.8 header lines.append('{\\rtf1\\ansi\\uc0\\deff0' '{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset0%s;}}' % (self.fontface and ' ' + self._escape(self.fontface) or '')) # color table lines.append('{\\colortbl;') for color, _ in self.color_mapping.items(): lines.append(self.hex_to_rtf_color(color)) lines.append('}') # font and fontsize lines.append('\\f0\\sa0') if self.fontsize: lines.append('\\fs%d' % self.fontsize) # ensure Libre Office Writer imports and renders consecutive # space characters the same width, needed for line numbering. # https://bugs.documentfoundation.org/show_bug.cgi?id=144050 lines.append('\\dntblnsbdb') return lines def format_unencoded(self, tokensource, outfile): for line in self._rtf_header: outfile.write(line + "\n") tokensource = self._split_tokens_on_newlines(tokensource) # first pass of tokens to count lines, needed for line numbering if self.linenos: line_count = 0 tokens = [] # for copying the token source generator for ttype, value in tokensource: tokens.append((ttype, value)) if value.endswith("\n"): line_count += 1 # width of line number strings (for padding with spaces) linenos_width = len(str(line_count+self.linenostart-1)) tokensource = tokens # highlight stream lineno = 1 start_new_line = True for ttype, value in tokensource: if start_new_line and lineno in self.hl_lines: outfile.write(self._hl_open_str) if start_new_line and self.linenos: if (lineno-self.linenostart+1)%self.linenostep == 0: current_lineno = lineno + self.linenostart - 1 lineno_str = str(current_lineno).rjust(linenos_width) else: lineno_str = "".rjust(linenos_width) outfile.write(self._lineno_template % lineno_str) while not self.style.styles_token(ttype) and ttype.parent: ttype = ttype.parent style = self.style.style_for_token(ttype) buf = [] if style['bgcolor']: buf.append('\\cb%d' % self.color_mapping[style['bgcolor']]) if style['color']: buf.append('\\cf%d' % self.color_mapping[style['color']]) if style['bold']: buf.append('\\b') if style['italic']: buf.append('\\i') if style['underline']: buf.append('\\ul') if style['border']: buf.append('\\chbrdr\\chcfpat%d' % self.color_mapping[style['border']]) start = ''.join(buf) if start: outfile.write(f'{{{start} ') outfile.write(self._escape_text(value)) if start: outfile.write('}') start_new_line = False # complete line of input if value.endswith("\n"): # close line highlighting if lineno in self.hl_lines: outfile.write('}') # newline in RTF file after closing } outfile.write("\n") start_new_line = True lineno += 1 outfile.write('}\n') PK i��Z����U� U� formatters/html.pynu �[��� """ pygments.formatters.html ~~~~~~~~~~~~~~~~~~~~~~~~ Formatter for HTML output. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import functools import os import sys import os.path from io import StringIO from pip._vendor.pygments.formatter import Formatter from pip._vendor.pygments.token import Token, Text, STANDARD_TYPES from pip._vendor.pygments.util import get_bool_opt, get_int_opt, get_list_opt try: import ctags except ImportError: ctags = None __all__ = ['HtmlFormatter'] _escape_html_table = { ord('&'): '&', ord('<'): '<', ord('>'): '>', ord('"'): '"', ord("'"): ''', } def escape_html(text, table=_escape_html_table): """Escape &, <, > as well as single and double quotes for HTML.""" return text.translate(table) def webify(color): if color.startswith('calc') or color.startswith('var'): return color else: return '#' + color def _get_ttype_class(ttype): fname = STANDARD_TYPES.get(ttype) if fname: return fname aname = '' while fname is None: aname = '-' + ttype[-1] + aname ttype = ttype.parent fname = STANDARD_TYPES.get(ttype) return fname + aname CSSFILE_TEMPLATE = '''\ /* generated by Pygments <https://pygments.org/> Copyright 2006-2024 by the Pygments team. Licensed under the BSD license, see LICENSE for details. */ %(styledefs)s ''' DOC_HEADER = '''\ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!-- generated by Pygments <https://pygments.org/> Copyright 2006-2024 by the Pygments team. Licensed under the BSD license, see LICENSE for details. --> <html> <head> <title>%(title)s</title> <meta http-equiv="content-type" content="text/html; charset=%(encoding)s"> <style type="text/css"> ''' + CSSFILE_TEMPLATE + ''' </style> </head> <body> <h2>%(title)s</h2> ''' DOC_HEADER_EXTERNALCSS = '''\ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>%(title)s</title> <meta http-equiv="content-type" content="text/html; charset=%(encoding)s"> <link rel="stylesheet" href="%(cssfile)s" type="text/css"> </head> <body> <h2>%(title)s</h2> ''' DOC_FOOTER = '''\ </body> </html> ''' class HtmlFormatter(Formatter): r""" Format tokens as HTML 4 ``<span>`` tags. By default, the content is enclosed in a ``<pre>`` tag, itself wrapped in a ``<div>`` tag (but see the `nowrap` option). The ``<div>``'s CSS class can be set by the `cssclass` option. If the `linenos` option is set to ``"table"``, the ``<pre>`` is additionally wrapped inside a ``<table>`` which has one row and two cells: one containing the line numbers and one containing the code. Example: .. sourcecode:: html <div class="highlight" > <table><tr> <td class="linenos" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"> <pre>1 2</pre> </td> <td class="code"> <pre><span class="Ke">def </span><span class="NaFu">foo</span>(bar): <span class="Ke">pass</span> </pre> </td> </tr></table></div> (whitespace added to improve clarity). A list of lines can be specified using the `hl_lines` option to make these lines highlighted (as of Pygments 0.11). With the `full` option, a complete HTML 4 document is output, including the style definitions inside a ``<style>`` tag, or in a separate file if the `cssfile` option is given. When `tagsfile` is set to the path of a ctags index file, it is used to generate hyperlinks from names to their definition. You must enable `lineanchors` and run ctags with the `-n` option for this to work. The `python-ctags` module from PyPI must be installed to use this feature; otherwise a `RuntimeError` will be raised. The `get_style_defs(arg='')` method of a `HtmlFormatter` returns a string containing CSS rules for the CSS classes used by the formatter. The argument `arg` can be used to specify additional CSS selectors that are prepended to the classes. A call `fmter.get_style_defs('td .code')` would result in the following CSS classes: .. sourcecode:: css td .code .kw { font-weight: bold; color: #00FF00 } td .code .cm { color: #999999 } ... If you have Pygments 0.6 or higher, you can also pass a list or tuple to the `get_style_defs()` method to request multiple prefixes for the tokens: .. sourcecode:: python formatter.get_style_defs(['div.syntax pre', 'pre.syntax']) The output would then look like this: .. sourcecode:: css div.syntax pre .kw, pre.syntax .kw { font-weight: bold; color: #00FF00 } div.syntax pre .cm, pre.syntax .cm { color: #999999 } ... Additional options accepted: `nowrap` If set to ``True``, don't add a ``<pre>`` and a ``<div>`` tag around the tokens. This disables most other options (default: ``False``). `full` Tells the formatter to output a "full" document, i.e. a complete self-contained document (default: ``False``). `title` If `full` is true, the title that should be used to caption the document (default: ``''``). `style` The style to use, can be a string or a Style subclass (default: ``'default'``). This option has no effect if the `cssfile` and `noclobber_cssfile` option are given and the file specified in `cssfile` exists. `noclasses` If set to true, token ``<span>`` tags (as well as line number elements) will not use CSS classes, but inline styles. This is not recommended for larger pieces of code since it increases output size by quite a bit (default: ``False``). `classprefix` Since the token types use relatively short class names, they may clash with some of your own class names. In this case you can use the `classprefix` option to give a string to prepend to all Pygments-generated CSS class names for token types. Note that this option also affects the output of `get_style_defs()`. `cssclass` CSS class for the wrapping ``<div>`` tag (default: ``'highlight'``). If you set this option, the default selector for `get_style_defs()` will be this class. .. versionadded:: 0.9 If you select the ``'table'`` line numbers, the wrapping table will have a CSS class of this string plus ``'table'``, the default is accordingly ``'highlighttable'``. `cssstyles` Inline CSS styles for the wrapping ``<div>`` tag (default: ``''``). `prestyles` Inline CSS styles for the ``<pre>`` tag (default: ``''``). .. versionadded:: 0.11 `cssfile` If the `full` option is true and this option is given, it must be the name of an external file. If the filename does not include an absolute path, the file's path will be assumed to be relative to the main output file's path, if the latter can be found. The stylesheet is then written to this file instead of the HTML file. .. versionadded:: 0.6 `noclobber_cssfile` If `cssfile` is given and the specified file exists, the css file will not be overwritten. This allows the use of the `full` option in combination with a user specified css file. Default is ``False``. .. versionadded:: 1.1 `linenos` If set to ``'table'``, output line numbers as a table with two cells, one containing the line numbers, the other the whole code. This is copy-and-paste-friendly, but may cause alignment problems with some browsers or fonts. If set to ``'inline'``, the line numbers will be integrated in the ``<pre>`` tag that contains the code (that setting is *new in Pygments 0.8*). For compatibility with Pygments 0.7 and earlier, every true value except ``'inline'`` means the same as ``'table'`` (in particular, that means also ``True``). The default value is ``False``, which means no line numbers at all. **Note:** with the default ("table") line number mechanism, the line numbers and code can have different line heights in Internet Explorer unless you give the enclosing ``<pre>`` tags an explicit ``line-height`` CSS property (you get the default line spacing with ``line-height: 125%``). `hl_lines` Specify a list of lines to be highlighted. The line numbers are always relative to the input (i.e. the first line is line 1) and are independent of `linenostart`. .. versionadded:: 0.11 `linenostart` The line number for the first line (default: ``1``). `linenostep` If set to a number n > 1, only every nth line number is printed. `linenospecial` If set to a number n > 0, every nth line number is given the CSS class ``"special"`` (default: ``0``). `nobackground` If set to ``True``, the formatter won't output the background color for the wrapping element (this automatically defaults to ``False`` when there is no wrapping element [eg: no argument for the `get_syntax_defs` method given]) (default: ``False``). .. versionadded:: 0.6 `lineseparator` This string is output between lines of code. It defaults to ``"\n"``, which is enough to break a line inside ``<pre>`` tags, but you can e.g. set it to ``"<br>"`` to get HTML line breaks. .. versionadded:: 0.7 `lineanchors` If set to a nonempty string, e.g. ``foo``, the formatter will wrap each output line in an anchor tag with an ``id`` (and `name`) of ``foo-linenumber``. This allows easy linking to certain lines. .. versionadded:: 0.9 `linespans` If set to a nonempty string, e.g. ``foo``, the formatter will wrap each output line in a span tag with an ``id`` of ``foo-linenumber``. This allows easy access to lines via javascript. .. versionadded:: 1.6 `anchorlinenos` If set to `True`, will wrap line numbers in <a> tags. Used in combination with `linenos` and `lineanchors`. `tagsfile` If set to the path of a ctags file, wrap names in anchor tags that link to their definitions. `lineanchors` should be used, and the tags file should specify line numbers (see the `-n` option to ctags). The tags file is assumed to be encoded in UTF-8. .. versionadded:: 1.6 `tagurlformat` A string formatting pattern used to generate links to ctags definitions. Available variables are `%(path)s`, `%(fname)s` and `%(fext)s`. Defaults to an empty string, resulting in just `#prefix-number` links. .. versionadded:: 1.6 `filename` A string used to generate a filename when rendering ``<pre>`` blocks, for example if displaying source code. If `linenos` is set to ``'table'`` then the filename will be rendered in an initial row containing a single `<th>` which spans both columns. .. versionadded:: 2.1 `wrapcode` Wrap the code inside ``<pre>`` blocks using ``<code>``, as recommended by the HTML5 specification. .. versionadded:: 2.4 `debug_token_types` Add ``title`` attributes to all token ``<span>`` tags that show the name of the token. .. versionadded:: 2.10 **Subclassing the HTML formatter** .. versionadded:: 0.7 The HTML formatter is now built in a way that allows easy subclassing, thus customizing the output HTML code. The `format()` method calls `self._format_lines()` which returns a generator that yields tuples of ``(1, line)``, where the ``1`` indicates that the ``line`` is a line of the formatted source code. If the `nowrap` option is set, the generator is the iterated over and the resulting HTML is output. Otherwise, `format()` calls `self.wrap()`, which wraps the generator with other generators. These may add some HTML code to the one generated by `_format_lines()`, either by modifying the lines generated by the latter, then yielding them again with ``(1, line)``, and/or by yielding other HTML code before or after the lines, with ``(0, html)``. The distinction between source lines and other code makes it possible to wrap the generator multiple times. The default `wrap()` implementation adds a ``<div>`` and a ``<pre>`` tag. A custom `HtmlFormatter` subclass could look like this: .. sourcecode:: python class CodeHtmlFormatter(HtmlFormatter): def wrap(self, source, *, include_div): return self._wrap_code(source) def _wrap_code(self, source): yield 0, '<code>' for i, t in source: if i == 1: # it's a line of formatted code t += '<br>' yield i, t yield 0, '</code>' This results in wrapping the formatted lines with a ``<code>`` tag, where the source lines are broken using ``<br>`` tags. After calling `wrap()`, the `format()` method also adds the "line numbers" and/or "full document" wrappers if the respective options are set. Then, all HTML yielded by the wrapped generator is output. """ name = 'HTML' aliases = ['html'] filenames = ['*.html', '*.htm'] def __init__(self, **options): Formatter.__init__(self, **options) self.title = self._decodeifneeded(self.title) self.nowrap = get_bool_opt(options, 'nowrap', False) self.noclasses = get_bool_opt(options, 'noclasses', False) self.classprefix = options.get('classprefix', '') self.cssclass = self._decodeifneeded(options.get('cssclass', 'highlight')) self.cssstyles = self._decodeifneeded(options.get('cssstyles', '')) self.prestyles = self._decodeifneeded(options.get('prestyles', '')) self.cssfile = self._decodeifneeded(options.get('cssfile', '')) self.noclobber_cssfile = get_bool_opt(options, 'noclobber_cssfile', False) self.tagsfile = self._decodeifneeded(options.get('tagsfile', '')) self.tagurlformat = self._decodeifneeded(options.get('tagurlformat', '')) self.filename = self._decodeifneeded(options.get('filename', '')) self.wrapcode = get_bool_opt(options, 'wrapcode', False) self.span_element_openers = {} self.debug_token_types = get_bool_opt(options, 'debug_token_types', False) if self.tagsfile: if not ctags: raise RuntimeError('The "ctags" package must to be installed ' 'to be able to use the "tagsfile" feature.') self._ctags = ctags.CTags(self.tagsfile) linenos = options.get('linenos', False) if linenos == 'inline': self.linenos = 2 elif linenos: # compatibility with <= 0.7 self.linenos = 1 else: self.linenos = 0 self.linenostart = abs(get_int_opt(options, 'linenostart', 1)) self.linenostep = abs(get_int_opt(options, 'linenostep', 1)) self.linenospecial = abs(get_int_opt(options, 'linenospecial', 0)) self.nobackground = get_bool_opt(options, 'nobackground', False) self.lineseparator = options.get('lineseparator', '\n') self.lineanchors = options.get('lineanchors', '') self.linespans = options.get('linespans', '') self.anchorlinenos = get_bool_opt(options, 'anchorlinenos', False) self.hl_lines = set() for lineno in get_list_opt(options, 'hl_lines', []): try: self.hl_lines.add(int(lineno)) except ValueError: pass self._create_stylesheet() def _get_css_class(self, ttype): """Return the css class of this token type prefixed with the classprefix option.""" ttypeclass = _get_ttype_class(ttype) if ttypeclass: return self.classprefix + ttypeclass return '' def _get_css_classes(self, ttype): """Return the CSS classes of this token type prefixed with the classprefix option.""" cls = self._get_css_class(ttype) while ttype not in STANDARD_TYPES: ttype = ttype.parent cls = self._get_css_class(ttype) + ' ' + cls return cls or '' def _get_css_inline_styles(self, ttype): """Return the inline CSS styles for this token type.""" cclass = self.ttype2class.get(ttype) while cclass is None: ttype = ttype.parent cclass = self.ttype2class.get(ttype) return cclass or '' def _create_stylesheet(self): t2c = self.ttype2class = {Token: ''} c2s = self.class2style = {} for ttype, ndef in self.style: name = self._get_css_class(ttype) style = '' if ndef['color']: style += 'color: {}; '.format(webify(ndef['color'])) if ndef['bold']: style += 'font-weight: bold; ' if ndef['italic']: style += 'font-style: italic; ' if ndef['underline']: style += 'text-decoration: underline; ' if ndef['bgcolor']: style += 'background-color: {}; '.format(webify(ndef['bgcolor'])) if ndef['border']: style += 'border: 1px solid {}; '.format(webify(ndef['border'])) if style: t2c[ttype] = name # save len(ttype) to enable ordering the styles by # hierarchy (necessary for CSS cascading rules!) c2s[name] = (style[:-2], ttype, len(ttype)) def get_style_defs(self, arg=None): """ Return CSS style definitions for the classes produced by the current highlighting style. ``arg`` can be a string or list of selectors to insert before the token type classes. """ style_lines = [] style_lines.extend(self.get_linenos_style_defs()) style_lines.extend(self.get_background_style_defs(arg)) style_lines.extend(self.get_token_style_defs(arg)) return '\n'.join(style_lines) def get_token_style_defs(self, arg=None): prefix = self.get_css_prefix(arg) styles = [ (level, ttype, cls, style) for cls, (style, ttype, level) in self.class2style.items() if cls and style ] styles.sort() lines = [ f'{prefix(cls)} {{ {style} }} /* {repr(ttype)[6:]} */' for (level, ttype, cls, style) in styles ] return lines def get_background_style_defs(self, arg=None): prefix = self.get_css_prefix(arg) bg_color = self.style.background_color hl_color = self.style.highlight_color lines = [] if arg and not self.nobackground and bg_color is not None: text_style = '' if Text in self.ttype2class: text_style = ' ' + self.class2style[self.ttype2class[Text]][0] lines.insert( 0, '{}{{ background: {};{} }}'.format( prefix(''), bg_color, text_style ) ) if hl_color is not None: lines.insert( 0, '{} {{ background-color: {} }}'.format(prefix('hll'), hl_color) ) return lines def get_linenos_style_defs(self): lines = [ f'pre {{ {self._pre_style} }}', f'td.linenos .normal {{ {self._linenos_style} }}', f'span.linenos {{ {self._linenos_style} }}', f'td.linenos .special {{ {self._linenos_special_style} }}', f'span.linenos.special {{ {self._linenos_special_style} }}', ] return lines def get_css_prefix(self, arg): if arg is None: arg = ('cssclass' in self.options and '.'+self.cssclass or '') if isinstance(arg, str): args = [arg] else: args = list(arg) def prefix(cls): if cls: cls = '.' + cls tmp = [] for arg in args: tmp.append((arg and arg + ' ' or '') + cls) return ', '.join(tmp) return prefix @property def _pre_style(self): return 'line-height: 125%;' @property def _linenos_style(self): color = self.style.line_number_color background_color = self.style.line_number_background_color return f'color: {color}; background-color: {background_color}; padding-left: 5px; padding-right: 5px;' @property def _linenos_special_style(self): color = self.style.line_number_special_color background_color = self.style.line_number_special_background_color return f'color: {color}; background-color: {background_color}; padding-left: 5px; padding-right: 5px;' def _decodeifneeded(self, value): if isinstance(value, bytes): if self.encoding: return value.decode(self.encoding) return value.decode() return value def _wrap_full(self, inner, outfile): if self.cssfile: if os.path.isabs(self.cssfile): # it's an absolute filename cssfilename = self.cssfile else: try: filename = outfile.name if not filename or filename[0] == '<': # pseudo files, e.g. name == '<fdopen>' raise AttributeError cssfilename = os.path.join(os.path.dirname(filename), self.cssfile) except AttributeError: print('Note: Cannot determine output file name, ' 'using current directory as base for the CSS file name', file=sys.stderr) cssfilename = self.cssfile # write CSS file only if noclobber_cssfile isn't given as an option. try: if not os.path.exists(cssfilename) or not self.noclobber_cssfile: with open(cssfilename, "w", encoding="utf-8") as cf: cf.write(CSSFILE_TEMPLATE % {'styledefs': self.get_style_defs('body')}) except OSError as err: err.strerror = 'Error writing CSS file: ' + err.strerror raise yield 0, (DOC_HEADER_EXTERNALCSS % dict(title=self.title, cssfile=self.cssfile, encoding=self.encoding)) else: yield 0, (DOC_HEADER % dict(title=self.title, styledefs=self.get_style_defs('body'), encoding=self.encoding)) yield from inner yield 0, DOC_FOOTER def _wrap_tablelinenos(self, inner): dummyoutfile = StringIO() lncount = 0 for t, line in inner: if t: lncount += 1 dummyoutfile.write(line) fl = self.linenostart mw = len(str(lncount + fl - 1)) sp = self.linenospecial st = self.linenostep anchor_name = self.lineanchors or self.linespans aln = self.anchorlinenos nocls = self.noclasses lines = [] for i in range(fl, fl+lncount): print_line = i % st == 0 special_line = sp and i % sp == 0 if print_line: line = '%*d' % (mw, i) if aln: line = '<a href="#%s-%d">%s</a>' % (anchor_name, i, line) else: line = ' ' * mw if nocls: if special_line: style = f' style="{self._linenos_special_style}"' else: style = f' style="{self._linenos_style}"' else: if special_line: style = ' class="special"' else: style = ' class="normal"' if style: line = f'<span{style}>{line}</span>' lines.append(line) ls = '\n'.join(lines) # If a filename was specified, we can't put it into the code table as it # would misalign the line numbers. Hence we emit a separate row for it. filename_tr = "" if self.filename: filename_tr = ( '<tr><th colspan="2" class="filename">' '<span class="filename">' + self.filename + '</span>' '</th></tr>') # in case you wonder about the seemingly redundant <div> here: since the # content in the other cell also is wrapped in a div, some browsers in # some configurations seem to mess up the formatting... yield 0, (f'<table class="{self.cssclass}table">' + filename_tr + '<tr><td class="linenos"><div class="linenodiv"><pre>' + ls + '</pre></div></td><td class="code">') yield 0, '<div>' yield 0, dummyoutfile.getvalue() yield 0, '</div>' yield 0, '</td></tr></table>' def _wrap_inlinelinenos(self, inner): # need a list of lines since we need the width of a single number :( inner_lines = list(inner) sp = self.linenospecial st = self.linenostep num = self.linenostart mw = len(str(len(inner_lines) + num - 1)) anchor_name = self.lineanchors or self.linespans aln = self.anchorlinenos nocls = self.noclasses for _, inner_line in inner_lines: print_line = num % st == 0 special_line = sp and num % sp == 0 if print_line: line = '%*d' % (mw, num) else: line = ' ' * mw if nocls: if special_line: style = f' style="{self._linenos_special_style}"' else: style = f' style="{self._linenos_style}"' else: if special_line: style = ' class="linenos special"' else: style = ' class="linenos"' if style: linenos = f'<span{style}>{line}</span>' else: linenos = line if aln: yield 1, ('<a href="#%s-%d">%s</a>' % (anchor_name, num, linenos) + inner_line) else: yield 1, linenos + inner_line num += 1 def _wrap_lineanchors(self, inner): s = self.lineanchors # subtract 1 since we have to increment i *before* yielding i = self.linenostart - 1 for t, line in inner: if t: i += 1 href = "" if self.linenos else ' href="#%s-%d"' % (s, i) yield 1, '<a id="%s-%d" name="%s-%d"%s></a>' % (s, i, s, i, href) + line else: yield 0, line def _wrap_linespans(self, inner): s = self.linespans i = self.linenostart - 1 for t, line in inner: if t: i += 1 yield 1, '<span id="%s-%d">%s</span>' % (s, i, line) else: yield 0, line def _wrap_div(self, inner): style = [] if (self.noclasses and not self.nobackground and self.style.background_color is not None): style.append(f'background: {self.style.background_color}') if self.cssstyles: style.append(self.cssstyles) style = '; '.join(style) yield 0, ('<div' + (self.cssclass and f' class="{self.cssclass}"') + (style and (f' style="{style}"')) + '>') yield from inner yield 0, '</div>\n' def _wrap_pre(self, inner): style = [] if self.prestyles: style.append(self.prestyles) if self.noclasses: style.append(self._pre_style) style = '; '.join(style) if self.filename and self.linenos != 1: yield 0, ('<span class="filename">' + self.filename + '</span>') # the empty span here is to keep leading empty lines from being # ignored by HTML parsers yield 0, ('<pre' + (style and f' style="{style}"') + '><span></span>') yield from inner yield 0, '</pre>' def _wrap_code(self, inner): yield 0, '<code>' yield from inner yield 0, '</code>' @functools.lru_cache(maxsize=100) def _translate_parts(self, value): """HTML-escape a value and split it by newlines.""" return value.translate(_escape_html_table).split('\n') def _format_lines(self, tokensource): """ Just format the tokens, without any wrapping tags. Yield individual lines. """ nocls = self.noclasses lsep = self.lineseparator tagsfile = self.tagsfile lspan = '' line = [] for ttype, value in tokensource: try: cspan = self.span_element_openers[ttype] except KeyError: title = ' title="{}"'.format('.'.join(ttype)) if self.debug_token_types else '' if nocls: css_style = self._get_css_inline_styles(ttype) if css_style: css_style = self.class2style[css_style][0] cspan = f'<span style="{css_style}"{title}>' else: cspan = '' else: css_class = self._get_css_classes(ttype) if css_class: cspan = f'<span class="{css_class}"{title}>' else: cspan = '' self.span_element_openers[ttype] = cspan parts = self._translate_parts(value) if tagsfile and ttype in Token.Name: filename, linenumber = self._lookup_ctag(value) if linenumber: base, filename = os.path.split(filename) if base: base += '/' filename, extension = os.path.splitext(filename) url = self.tagurlformat % {'path': base, 'fname': filename, 'fext': extension} parts[0] = "<a href=\"%s#%s-%d\">%s" % \ (url, self.lineanchors, linenumber, parts[0]) parts[-1] = parts[-1] + "</a>" # for all but the last line for part in parts[:-1]: if line: # Also check for part being non-empty, so we avoid creating # empty <span> tags if lspan != cspan and part: line.extend(((lspan and '</span>'), cspan, part, (cspan and '</span>'), lsep)) else: # both are the same, or the current part was empty line.extend((part, (lspan and '</span>'), lsep)) yield 1, ''.join(line) line = [] elif part: yield 1, ''.join((cspan, part, (cspan and '</span>'), lsep)) else: yield 1, lsep # for the last line if line and parts[-1]: if lspan != cspan: line.extend(((lspan and '</span>'), cspan, parts[-1])) lspan = cspan else: line.append(parts[-1]) elif parts[-1]: line = [cspan, parts[-1]] lspan = cspan # else we neither have to open a new span nor set lspan if line: line.extend(((lspan and '</span>'), lsep)) yield 1, ''.join(line) def _lookup_ctag(self, token): entry = ctags.TagEntry() if self._ctags.find(entry, token.encode(), 0): return entry['file'].decode(), entry['lineNumber'] else: return None, None def _highlight_lines(self, tokensource): """ Highlighted the lines specified in the `hl_lines` option by post-processing the token stream coming from `_format_lines`. """ hls = self.hl_lines for i, (t, value) in enumerate(tokensource): if t != 1: yield t, value if i + 1 in hls: # i + 1 because Python indexes start at 0 if self.noclasses: style = '' if self.style.highlight_color is not None: style = (f' style="background-color: {self.style.highlight_color}"') yield 1, f'<span{style}>{value}</span>' else: yield 1, f'<span class="hll">{value}</span>' else: yield 1, value def wrap(self, source): """ Wrap the ``source``, which is a generator yielding individual lines, in custom generators. See docstring for `format`. Can be overridden. """ output = source if self.wrapcode: output = self._wrap_code(output) output = self._wrap_pre(output) return output def format_unencoded(self, tokensource, outfile): """ The formatting process uses several nested generators; which of them are used is determined by the user's options. Each generator should take at least one argument, ``inner``, and wrap the pieces of text generated by this. Always yield 2-tuples: (code, text). If "code" is 1, the text is part of the original tokensource being highlighted, if it's 0, the text is some piece of wrapping. This makes it possible to use several different wrappers that process the original source linewise, e.g. line number generators. """ source = self._format_lines(tokensource) # As a special case, we wrap line numbers before line highlighting # so the line numbers get wrapped in the highlighting tag. if not self.nowrap and self.linenos == 2: source = self._wrap_inlinelinenos(source) if self.hl_lines: source = self._highlight_lines(source) if not self.nowrap: if self.lineanchors: source = self._wrap_lineanchors(source) if self.linespans: source = self._wrap_linespans(source) source = self.wrap(source) if self.linenos == 1: source = self._wrap_tablelinenos(source) source = self._wrap_div(source) if self.full: source = self._wrap_full(source, outfile) for t, piece in source: outfile.write(piece) PK i��Z��� formatters/__init__.pynu �[��� """ pygments.formatters ~~~~~~~~~~~~~~~~~~~ Pygments formatters. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import re import sys import types import fnmatch from os.path import basename from pip._vendor.pygments.formatters._mapping import FORMATTERS from pip._vendor.pygments.plugin import find_plugin_formatters from pip._vendor.pygments.util import ClassNotFound __all__ = ['get_formatter_by_name', 'get_formatter_for_filename', 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS) _formatter_cache = {} # classes by name _pattern_cache = {} def _fn_matches(fn, glob): """Return whether the supplied file name fn matches pattern filename.""" if glob not in _pattern_cache: pattern = _pattern_cache[glob] = re.compile(fnmatch.translate(glob)) return pattern.match(fn) return _pattern_cache[glob].match(fn) def _load_formatters(module_name): """Load a formatter (and all others in the module too).""" mod = __import__(module_name, None, None, ['__all__']) for formatter_name in mod.__all__: cls = getattr(mod, formatter_name) _formatter_cache[cls.name] = cls def get_all_formatters(): """Return a generator for all formatter classes.""" # NB: this returns formatter classes, not info like get_all_lexers(). for info in FORMATTERS.values(): if info[1] not in _formatter_cache: _load_formatters(info[0]) yield _formatter_cache[info[1]] for _, formatter in find_plugin_formatters(): yield formatter def find_formatter_class(alias): """Lookup a formatter by alias. Returns None if not found. """ for module_name, name, aliases, _, _ in FORMATTERS.values(): if alias in aliases: if name not in _formatter_cache: _load_formatters(module_name) return _formatter_cache[name] for _, cls in find_plugin_formatters(): if alias in cls.aliases: return cls def get_formatter_by_name(_alias, **options): """ Return an instance of a :class:`.Formatter` subclass that has `alias` in its aliases list. The formatter is given the `options` at its instantiation. Will raise :exc:`pygments.util.ClassNotFound` if no formatter with that alias is found. """ cls = find_formatter_class(_alias) if cls is None: raise ClassNotFound(f"no formatter found for name {_alias!r}") return cls(**options) def load_formatter_from_file(filename, formattername="CustomFormatter", **options): """ Return a `Formatter` subclass instance loaded from the provided file, relative to the current directory. The file is expected to contain a Formatter class named ``formattername`` (by default, CustomFormatter). Users should be very careful with the input, because this method is equivalent to running ``eval()`` on the input file. The formatter is given the `options` at its instantiation. :exc:`pygments.util.ClassNotFound` is raised if there are any errors loading the formatter. .. versionadded:: 2.2 """ try: # This empty dict will contain the namespace for the exec'd file custom_namespace = {} with open(filename, 'rb') as f: exec(f.read(), custom_namespace) # Retrieve the class `formattername` from that namespace if formattername not in custom_namespace: raise ClassNotFound(f'no valid {formattername} class found in {filename}') formatter_class = custom_namespace[formattername] # And finally instantiate it with the options return formatter_class(**options) except OSError as err: raise ClassNotFound(f'cannot read {filename}: {err}') except ClassNotFound: raise except Exception as err: raise ClassNotFound(f'error when loading custom formatter: {err}') def get_formatter_for_filename(fn, **options): """ Return a :class:`.Formatter` subclass instance that has a filename pattern matching `fn`. The formatter is given the `options` at its instantiation. Will raise :exc:`pygments.util.ClassNotFound` if no formatter for that filename is found. """ fn = basename(fn) for modname, name, _, filenames, _ in FORMATTERS.values(): for filename in filenames: if _fn_matches(fn, filename): if name not in _formatter_cache: _load_formatters(modname) return _formatter_cache[name](**options) for _name, cls in find_plugin_formatters(): for filename in cls.filenames: if _fn_matches(fn, filename): return cls(**options) raise ClassNotFound(f"no formatter found for file name {fn!r}") class _automodule(types.ModuleType): """Automatically import formatters.""" def __getattr__(self, name): info = FORMATTERS.get(name) if info: _load_formatters(info[0]) cls = _formatter_cache[info[1]] setattr(self, name, cls) return cls raise AttributeError(name) oldmod = sys.modules[__name__] newmod = _automodule(__name__) newmod.__dict__.update(oldmod.__dict__) sys.modules[__name__] = newmod del newmod.newmod, newmod.oldmod, newmod.sys, newmod.types PK i��ZC�ޝ regexopt.pynu �[��� """ pygments.regexopt ~~~~~~~~~~~~~~~~~ An algorithm that generates optimized regexes for matching long lists of literal strings. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import re from re import escape from os.path import commonprefix from itertools import groupby from operator import itemgetter CS_ESCAPE = re.compile(r'[\[\^\\\-\]]') FIRST_ELEMENT = itemgetter(0) def make_charset(letters): return '[' + CS_ESCAPE.sub(lambda m: '\\' + m.group(), ''.join(letters)) + ']' def regex_opt_inner(strings, open_paren): """Return a regex that matches any string in the sorted list of strings.""" close_paren = open_paren and ')' or '' # print strings, repr(open_paren) if not strings: # print '-> nothing left' return '' first = strings[0] if len(strings) == 1: # print '-> only 1 string' return open_paren + escape(first) + close_paren if not first: # print '-> first string empty' return open_paren + regex_opt_inner(strings[1:], '(?:') \ + '?' + close_paren if len(first) == 1: # multiple one-char strings? make a charset oneletter = [] rest = [] for s in strings: if len(s) == 1: oneletter.append(s) else: rest.append(s) if len(oneletter) > 1: # do we have more than one oneletter string? if rest: # print '-> 1-character + rest' return open_paren + regex_opt_inner(rest, '') + '|' \ + make_charset(oneletter) + close_paren # print '-> only 1-character' return open_paren + make_charset(oneletter) + close_paren prefix = commonprefix(strings) if prefix: plen = len(prefix) # we have a prefix for all strings # print '-> prefix:', prefix return open_paren + escape(prefix) \ + regex_opt_inner([s[plen:] for s in strings], '(?:') \ + close_paren # is there a suffix? strings_rev = [s[::-1] for s in strings] suffix = commonprefix(strings_rev) if suffix: slen = len(suffix) # print '-> suffix:', suffix[::-1] return open_paren \ + regex_opt_inner(sorted(s[:-slen] for s in strings), '(?:') \ + escape(suffix[::-1]) + close_paren # recurse on common 1-string prefixes # print '-> last resort' return open_paren + \ '|'.join(regex_opt_inner(list(group[1]), '') for group in groupby(strings, lambda s: s[0] == first[0])) \ + close_paren def regex_opt(strings, prefix='', suffix=''): """Return a compiled regex that matches any string in the given list. The strings to match must be literal strings, not regexes. They will be regex-escaped. *prefix* and *suffix* are pre- and appended to the final regex. """ strings = sorted(strings) return prefix + regex_opt_inner(strings, '(') + suffix PK i��Z�� style.pynu �[��� """ pygments.style ~~~~~~~~~~~~~~ Basic style object. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ from pip._vendor.pygments.token import Token, STANDARD_TYPES # Default mapping of ansixxx to RGB colors. _ansimap = { # dark 'ansiblack': '000000', 'ansired': '7f0000', 'ansigreen': '007f00', 'ansiyellow': '7f7fe0', 'ansiblue': '00007f', 'ansimagenta': '7f007f', 'ansicyan': '007f7f', 'ansigray': 'e5e5e5', # normal 'ansibrightblack': '555555', 'ansibrightred': 'ff0000', 'ansibrightgreen': '00ff00', 'ansibrightyellow': 'ffff00', 'ansibrightblue': '0000ff', 'ansibrightmagenta': 'ff00ff', 'ansibrightcyan': '00ffff', 'ansiwhite': 'ffffff', } # mapping of deprecated #ansixxx colors to new color names _deprecated_ansicolors = { # dark '#ansiblack': 'ansiblack', '#ansidarkred': 'ansired', '#ansidarkgreen': 'ansigreen', '#ansibrown': 'ansiyellow', '#ansidarkblue': 'ansiblue', '#ansipurple': 'ansimagenta', '#ansiteal': 'ansicyan', '#ansilightgray': 'ansigray', # normal '#ansidarkgray': 'ansibrightblack', '#ansired': 'ansibrightred', '#ansigreen': 'ansibrightgreen', '#ansiyellow': 'ansibrightyellow', '#ansiblue': 'ansibrightblue', '#ansifuchsia': 'ansibrightmagenta', '#ansiturquoise': 'ansibrightcyan', '#ansiwhite': 'ansiwhite', } ansicolors = set(_ansimap) class StyleMeta(type): def __new__(mcs, name, bases, dct): obj = type.__new__(mcs, name, bases, dct) for token in STANDARD_TYPES: if token not in obj.styles: obj.styles[token] = '' def colorformat(text): if text in ansicolors: return text if text[0:1] == '#': col = text[1:] if len(col) == 6: return col elif len(col) == 3: return col[0] * 2 + col[1] * 2 + col[2] * 2 elif text == '': return '' elif text.startswith('var') or text.startswith('calc'): return text assert False, f"wrong color format {text!r}" _styles = obj._styles = {} for ttype in obj.styles: for token in ttype.split(): if token in _styles: continue ndef = _styles.get(token.parent, None) styledefs = obj.styles.get(token, '').split() if not ndef or token is None: ndef = ['', 0, 0, 0, '', '', 0, 0, 0] elif 'noinherit' in styledefs and token is not Token: ndef = _styles[Token][:] else: ndef = ndef[:] _styles[token] = ndef for styledef in obj.styles.get(token, '').split(): if styledef == 'noinherit': pass elif styledef == 'bold': ndef[1] = 1 elif styledef == 'nobold': ndef[1] = 0 elif styledef == 'italic': ndef[2] = 1 elif styledef == 'noitalic': ndef[2] = 0 elif styledef == 'underline': ndef[3] = 1 elif styledef == 'nounderline': ndef[3] = 0 elif styledef[:3] == 'bg:': ndef[4] = colorformat(styledef[3:]) elif styledef[:7] == 'border:': ndef[5] = colorformat(styledef[7:]) elif styledef == 'roman': ndef[6] = 1 elif styledef == 'sans': ndef[7] = 1 elif styledef == 'mono': ndef[8] = 1 else: ndef[0] = colorformat(styledef) return obj def style_for_token(cls, token): t = cls._styles[token] ansicolor = bgansicolor = None color = t[0] if color in _deprecated_ansicolors: color = _deprecated_ansicolors[color] if color in ansicolors: ansicolor = color color = _ansimap[color] bgcolor = t[4] if bgcolor in _deprecated_ansicolors: bgcolor = _deprecated_ansicolors[bgcolor] if bgcolor in ansicolors: bgansicolor = bgcolor bgcolor = _ansimap[bgcolor] return { 'color': color or None, 'bold': bool(t[1]), 'italic': bool(t[2]), 'underline': bool(t[3]), 'bgcolor': bgcolor or None, 'border': t[5] or None, 'roman': bool(t[6]) or None, 'sans': bool(t[7]) or None, 'mono': bool(t[8]) or None, 'ansicolor': ansicolor, 'bgansicolor': bgansicolor, } def list_styles(cls): return list(cls) def styles_token(cls, ttype): return ttype in cls._styles def __iter__(cls): for token in cls._styles: yield token, cls.style_for_token(token) def __len__(cls): return len(cls._styles) class Style(metaclass=StyleMeta): #: overall background color (``None`` means transparent) background_color = '#ffffff' #: highlight background color highlight_color = '#ffffcc' #: line number font color line_number_color = 'inherit' #: line number background color line_number_background_color = 'transparent' #: special line number font color line_number_special_color = '#000000' #: special line number background color line_number_special_background_color = '#ffffc0' #: Style definitions for individual token types. styles = {} #: user-friendly style name (used when selecting the style, so this # should be all-lowercase, no spaces, hyphens) name = 'unnamed' aliases = [] # Attribute for lexers defined within Pygments. If set # to True, the style is not shown in the style gallery # on the website. This is intended for language-specific # styles. web_style_gallery_exclude = False PK i��ZTs��g �g ! __pycache__/lexer.cpython-310.pycnu �[��� o �h� � @ s� d Z ddlZddlZddlZddlmZmZ ddlmZ ddl m Z mZmZm Z mZ ddlmZmZmZmZmZmZ ddlmZ g d�Ze�d �Zg d �Zedd� �ZG d d� de�ZG dd� ded�Z G dd� de �Z!G dd� de"�Z#G dd� d�Z$e$� Z%G dd� de&�Z'G dd� d�Z(dd� Z)G dd� d�Z*e*� Z+d d!� Z,G d"d#� d#�Z-G d$d%� d%e�Z.G d&d'� d'e�Z/G d(d)� d)e e/d�Z0G d*d+� d+�Z1G d,d-� d-e0�Z2d.d/� Z3G d0d1� d1e/�Z4G d2d3� d3e0e4d�Z5dS )4z� pygments.lexer ~~~~~~~~~~~~~~ Base lexer classes. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. � N)� apply_filters�Filter)�get_filter_by_name)�Error�Text�Other� Whitespace� _TokenType)�get_bool_opt�get_int_opt�get_list_opt�make_analysator�Future�guess_decode)� regex_opt) �Lexer� RegexLexer�ExtendedRegexLexer�DelegatingLexer�LexerContext�include�inherit�bygroups�using�this�default�words�line_rez.*? ))s �utf-8)s �� zutf-32)s ��zutf-32be)s ��zutf-16)s ��zutf-16bec C � dS )N� � ��xr! r! �P/usr/local/CyberPanel/lib/python3.10/site-packages/pip/_vendor/pygments/lexer.py�<lambda>"