Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
sphinxext.py248 linesDownload Raw Back to pygments
1"""2    pygments.sphinxext3    ~~~~~~~~~~~~~~~~~~4 5    Sphinx extension to generate automatic documentation of lexers,6    formatters and filters.7 8    :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.9    :license: BSD, see LICENSE for details.10"""11 12import sys13 14from docutils import nodes15from docutils.statemachine import ViewList16from docutils.parsers.rst import Directive17from sphinx.util.nodes import nested_parse_with_titles18 19 20MODULEDOC = '''21.. module:: %s22 23%s24%s25'''26 27LEXERDOC = '''28.. class:: %s29 30    :Short names: %s31    :Filenames:   %s32    :MIME types:  %s33 34    %s35 36    %s37 38'''39 40FMTERDOC = '''41.. class:: %s42 43    :Short names: %s44    :Filenames: %s45 46    %s47 48'''49 50FILTERDOC = '''51.. class:: %s52 53    :Name: %s54 55    %s56 57'''58 59 60class PygmentsDoc(Directive):61    """62    A directive to collect all lexers/formatters/filters and generate63    autoclass directives for them.64    """65    has_content = False66    required_arguments = 167    optional_arguments = 068    final_argument_whitespace = False69    option_spec = {}70 71    def run(self):72        self.filenames = set()73        if self.arguments[0] == 'lexers':74            out = self.document_lexers()75        elif self.arguments[0] == 'formatters':76            out = self.document_formatters()77        elif self.arguments[0] == 'filters':78            out = self.document_filters()79        elif self.arguments[0] == 'lexers_overview':80            out = self.document_lexers_overview()81        else:82            raise Exception('invalid argument for "pygmentsdoc" directive')83        node = nodes.compound()84        vl = ViewList(out.split('\n'), source='')85        nested_parse_with_titles(self.state, vl, node)86        for fn in self.filenames:87            self.state.document.settings.record_dependencies.add(fn)88        return node.children89 90    def document_lexers_overview(self):91        """Generate a tabular overview of all lexers.92 93        The columns are the lexer name, the extensions handled by this lexer94        (or "None"), the aliases and a link to the lexer class."""95        from pygments.lexers._mapping import LEXERS96        import pygments.lexers97        out = []98 99        table = []100 101        def format_link(name, url):102            if url:103                return f'`{name} <{url}>`_'104            return name105 106        for classname, data in sorted(LEXERS.items(), key=lambda x: x[1][1].lower()):107            lexer_cls = pygments.lexers.find_lexer_class(data[1])108            extensions = lexer_cls.filenames + lexer_cls.alias_filenames109 110            table.append({111                'name': format_link(data[1], lexer_cls.url),112                'extensions': ', '.join(extensions).replace('*', '\\*').replace('_', '\\') or 'None',113                'aliases': ', '.join(data[2]),114                'class': f'{data[0]}.{classname}'115            })116 117        column_names = ['name', 'extensions', 'aliases', 'class']118        column_lengths = [max([len(row[column]) for row in table if row[column]])119                          for column in column_names]120 121        def write_row(*columns):122            """Format a table row"""123            out = []124            for length, col in zip(column_lengths, columns):125                if col:126                    out.append(col.ljust(length))127                else:128                    out.append(' '*length)129 130            return ' '.join(out)131 132        def write_seperator():133            """Write a table separator row"""134            sep = ['='*c for c in column_lengths]135            return write_row(*sep)136 137        out.append(write_seperator())138        out.append(write_row('Name', 'Extension(s)', 'Short name(s)', 'Lexer class'))139        out.append(write_seperator())140        for row in table:141            out.append(write_row(142                row['name'],143                row['extensions'],144                row['aliases'],145                f':class:`~{row["class"]}`'))146        out.append(write_seperator())147 148        return '\n'.join(out)149 150    def document_lexers(self):151        from pygments.lexers._mapping import LEXERS152        import pygments153        import inspect154        import pathlib155 156        out = []157        modules = {}158        moduledocstrings = {}159        for classname, data in sorted(LEXERS.items(), key=lambda x: x[0]):160            module = data[0]161            mod = __import__(module, None, None, [classname])162            self.filenames.add(mod.__file__)163            cls = getattr(mod, classname)164            if not cls.__doc__:165                print(f"Warning: {classname} does not have a docstring.")166            docstring = cls.__doc__167            if isinstance(docstring, bytes):168                docstring = docstring.decode('utf8')169 170            example_file = getattr(cls, '_example', None)171            if example_file:172                p = pathlib.Path(inspect.getabsfile(pygments)).parent.parent /\173                    'tests' / 'examplefiles' / example_file174                content = p.read_text(encoding='utf-8')175                if not content:176                    raise Exception(177                        f"Empty example file '{example_file}' for lexer "178                        f"{classname}")179 180                if data[2]:181                    lexer_name = data[2][0]182                    docstring += '\n\n    .. admonition:: Example\n'183                    docstring += f'\n      .. code-block:: {lexer_name}\n\n'184                    for line in content.splitlines():185                        docstring += f'          {line}\n'186 187            if cls.version_added:188                version_line = f'.. versionadded:: {cls.version_added}'189            else:190                version_line = ''191 192            modules.setdefault(module, []).append((193                classname,194                ', '.join(data[2]) or 'None',195                ', '.join(data[3]).replace('*', '\\*').replace('_', '\\') or 'None',196                ', '.join(data[4]) or 'None',197                docstring,198                version_line))199            if module not in moduledocstrings:200                moddoc = mod.__doc__201                if isinstance(moddoc, bytes):202                    moddoc = moddoc.decode('utf8')203                moduledocstrings[module] = moddoc204 205        for module, lexers in sorted(modules.items(), key=lambda x: x[0]):206            if moduledocstrings[module] is None:207                raise Exception(f"Missing docstring for {module}")208            heading = moduledocstrings[module].splitlines()[4].strip().rstrip('.')209            out.append(MODULEDOC % (module, heading, '-'*len(heading)))210            for data in lexers:211                out.append(LEXERDOC % data)212 213        return ''.join(out)214 215    def document_formatters(self):216        from pygments.formatters import FORMATTERS217 218        out = []219        for classname, data in sorted(FORMATTERS.items(), key=lambda x: x[0]):220            module = data[0]221            mod = __import__(module, None, None, [classname])222            self.filenames.add(mod.__file__)223            cls = getattr(mod, classname)224            docstring = cls.__doc__225            if isinstance(docstring, bytes):226                docstring = docstring.decode('utf8')227            heading = cls.__name__228            out.append(FMTERDOC % (heading, ', '.join(data[2]) or 'None',229                                   ', '.join(data[3]).replace('*', '\\*') or 'None',230                                   docstring))231        return ''.join(out)232 233    def document_filters(self):234        from pygments.filters import FILTERS235 236        out = []237        for name, cls in FILTERS.items():238            self.filenames.add(sys.modules[cls.__module__].__file__)239            docstring = cls.__doc__240            if isinstance(docstring, bytes):241                docstring = docstring.decode('utf8')242            out.append(FILTERDOC % (cls.__name__, name, docstring))243        return ''.join(out)244 245 246def setup(app):247    app.add_directive('pygmentsdoc', PygmentsDoc)248 
codekingpro/portable-devtools · Team Ai