text: # -*- coding: utf-8 -*-
  """
      pygments.sphinxext
      ~~~~~~~~~~~~~~~~~~
  
      Sphinx extension to generate automatic documentation of lexers,
      formatters and filters.
  
      :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS.
      :license: BSD, see LICENSE for details.
  """
  
  import sys
  
  from docutils import nodes
  from docutils.statemachine import ViewList
  from docutils.parsers.rst import Directive
  from sphinx.util.nodes import nested_parse_with_titles
  
  
  MODULEDOC = '''
  .. module:: %s
  
  %s
  %s
  '''
  
  LEXERDOC = '''
  .. class:: %s
  
      :Short names: %s
      :Filenames:   %s
      :MIME types:  %s
  
      %s
  
  '''
  
  FMTERDOC = '''
  .. class:: %s
  
      :Short names: %s
      :Filenames: %s
  
      %s
  
  '''
  
  FILTERDOC = '''
  .. class:: %s
  
      :Name: %s
  
      %s
  
  '''
  
  
  class PygmentsDoc(Directive):
      """
      A directive to collect all lexers/formatters/filters and generate
      autoclass directives for them.
      """
      has_content = False
      required_arguments = 1
      optional_arguments = 0
      final_argument_whitespace = False
      option_spec = {}
  
      def run(self):
          self.filenames = set()
          if self.arguments[0] == 'lexers':
              out = self.document_lexers()
          elif self.arguments[0] == 'formatters':
              out = self.document_formatters()
          elif self.arguments[0] == 'filters':
              out = self.document_filters()
          else:
              raise Exception('invalid argument for "pygmentsdoc" directive')
          node = nodes.compound()
          vl = ViewList(out.split('\n'), source='')
          nested_parse_with_titles(self.state, vl, node)
          for fn in self.filenames:
              self.state.document.settings.record_dependencies.add(fn)
          return node.children
  
      def document_lexers(self):
          from pygments.lexers._mapping import LEXERS
          out = []
          modules = {}
          moduledocstrings = {}
          for classname, data in sorted(LEXERS.items(), key=lambda x: x[0]):
              module = data[0]
              mod = __import__(module, None, None, [classname])
              self.filenames.add(mod.__file__)
              cls = getattr(mod, classname)
              if not cls.__doc__:
                  print("Warning: %s does not have a docstring." % classname)
              docstring = cls.__doc__
              if isinstance(docstring, bytes):
                  docstring = docstring.decode('utf8')
              modules.setdefault(module, []).append((
                  classname,
                  ', '.join(data[2]) or 'None',
                  ', '.join(data[3]).replace('*', '\\*').replace('_', '\\') or 'None',
                  ', '.join(data[4]) or 'None',
                  docstring))
              if module not in moduledocstrings:
                  moddoc = mod.__doc__
                  if isinstance(moddoc, bytes):
                      moddoc = moddoc.decode('utf8')
                  moduledocstrings[module] = moddoc
  
          for module, lexers in sorted(modules.items(), key=lambda x: x[0]):
              if moduledocstrings[module] is None:
                  raise Exception("Missing docstring for %s" % (module,))
              heading = moduledocstrings[module].splitlines()[4].strip().rstrip('.')
              out.append(MODULEDOC % (module, heading, '-'*len(heading)))
              for data in lexers:
                  out.append(LEXERDOC % data)
  
          return ''.join(out)
  
      def document_formatters(self):
          from pygments.formatters import FORMATTERS
  
          out = []
          for classname, data in sorted(FORMATTERS.items(), key=lambda x: x[0]):
              module = data[0]
              mod = __import__(module, None, None, [classname])
              self.filenames.add(mod.__file__)
              cls = getattr(mod, classname)
              docstring = cls.__doc__
              if isinstance(docstring, bytes):
                  docstring = docstring.decode('utf8')
              heading = cls.__name__
              out.append(FMTERDOC % (heading, ', '.join(data[2]) or 'None',
                                     ', '.join(data[3]).replace('*', '\\*') or 'None',
                                     docstring))
          return ''.join(out)
  
      def document_filters(self):
          from pygments.filters import FILTERS
  
          out = []
          for name, cls in FILTERS.items():
              self.filenames.add(sys.modules[cls.__module__].__file__)
              docstring = cls.__doc__
              if isinstance(docstring, bytes):
                  docstring = docstring.decode('utf8')
              out.append(FILTERDOC % (cls.__name__, name, docstring))
          return ''.join(out)
  
  
  def setup(app):
      app.add_directive('pygmentsdoc', PygmentsDoc)
  