docs: def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None,
                                info=None, base_path=None, builder=None,
                                template_dir=None):
      """
      This function is adapted from
      `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to
      generate source for the automodsumm directives that should be
      autosummarized. Unlike generate_autosummary_docs, this function is
      called one file at a time.
      """
  
      from sphinx.jinja2glue import BuiltinTemplateLoader
      from sphinx.ext.autosummary import import_by_name, get_documenter
      from sphinx.ext.autosummary.generate import (find_autosummary_in_lines,
                                                   _simple_info, _simple_warn)
      from sphinx.util.osutil import ensuredir
      from sphinx.util.inspect import safe_getattr
      from jinja2 import FileSystemLoader, TemplateNotFound
      from jinja2.sandbox import SandboxedEnvironment
  
      if info is None:
          info = _simple_info
      if warn is None:
          warn = _simple_warn
  
      #info('[automodsumm] generating automodsumm for: ' + srcfn)
  
      # Create our own templating environment - here we use Astropy's
      # templates rather than the default autosummary templates, in order to
      # allow docstrings to be shown for methods.
      template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'),
                       os.path.join(base_path, '_templates')]
      if builder is not None:
          # allow the user to override the templates
          template_loader = BuiltinTemplateLoader()
          template_loader.init(builder, dirs=template_dirs)
      else:
          if template_dir:
              template_dirs.insert(0, template_dir)
          template_loader = FileSystemLoader(template_dirs)
      template_env = SandboxedEnvironment(loader=template_loader)
  
      # read
      #items = find_autosummary_in_files(sources)
      items = find_autosummary_in_lines(lines, filename=srcfn)
      if len(items) > 0:
          msg = '[automodsumm] {1}: found {0} automodsumm entries to generate'
          info(msg.format(len(items), srcfn))
  
  #    gennms = [item[0] for item in items]
  #    if len(gennms) > 20:
  #        gennms = gennms[:10] + ['...'] + gennms[-10:]
  #    info('[automodsumm] generating autosummary for: ' + ', '.join(gennms))
  
      # remove possible duplicates
      items = dict([(item, True) for item in items]).keys()
  
      # keep track of new files
      new_files = []
  
      # write
      for name, path, template_name in sorted(items):
          if path is None:
              # The corresponding autosummary:: directive did not have
              # a :toctree: option
              continue
  
          path = os.path.abspath(path)
          ensuredir(path)
  
          try:
              import_by_name_values = import_by_name(name)
          except ImportError as e:
              warn('[automodsumm] failed to import %r: %s' % (name, e))
              continue
  
          # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively
          if len(import_by_name_values) == 3:
              name, obj, parent = import_by_name_values
          elif len(import_by_name_values) == 4:
              name, obj, parent, module_name = import_by_name_values
  
          fn = os.path.join(path, name + suffix)
  
          # skip it if it exists
          if os.path.isfile(fn):
              continue
  
          new_files.append(fn)
  
          f = open(fn, 'w')
  
          try:
              doc = get_documenter(obj, parent)
  
              if template_name is not None:
                  template = template_env.get_template(template_name)
              else:
                  tmplstr = 'autosummary/%s.rst'
                  try:
                      template = template_env.get_template(tmplstr % doc.objtype)
                  except TemplateNotFound:
                      template = template_env.get_template(tmplstr % 'base')
  
              def get_members_mod(obj, typ, include_public=[]):
                  """
                  typ = None -> all
                  """
                  items = []
                  for name in dir(obj):
                      try:
                          documenter = get_documenter(safe_getattr(obj, name),
                                                      obj)
                      except AttributeError:
                          continue
                      if typ is None or documenter.objtype == typ:
                          items.append(name)
                  public = [x for x in items
                            if x in include_public or not x.startswith('_')]
                  return public, items
  
              def get_members_class(obj, typ, include_public=[],
                                    include_base=False):
                  """
                  typ = None -> all
                  include_base -> include attrs that are from a base class
                  """
                  items = []
  
                  # using dir gets all of the attributes, including the elements
                  # from the base class, otherwise use __slots__ or __dict__
                  if include_base:
                      names = dir(obj)
                  else:
                      if hasattr(obj, '__slots__'):
                          names = tuple(getattr(obj, '__slots__'))
                      else:
                          names = getattr(obj, '__dict__').keys()
  
                  for name in names:
                      try:
                          documenter = get_documenter(safe_getattr(obj, name),
                                                      obj)
                      except AttributeError:
                          continue
                      if typ is None or documenter.objtype == typ:
                          items.append(name)
                  public = [x for x in items
                            if x in include_public or not x.startswith('_')]
                  return public, items
  
              ns = {}
  
              if doc.objtype == 'module':
                  ns['members'] = get_members_mod(obj, None)
                  ns['functions'], ns['all_functions'] = \
                                     get_members_mod(obj, 'function')
                  ns['classes'], ns['all_classes'] = \
                                   get_members_mod(obj, 'class')
                  ns['exceptions'], ns['all_exceptions'] = \
                                     get_members_mod(obj, 'exception')
              elif doc.objtype == 'class':
                  api_class_methods = ['__init__', '__call__']
                  ns['members'] = get_members_class(obj, None)
                  ns['methods'], ns['all_methods'] = \
                                   get_members_class(obj, 'method', api_class_methods)
                  ns['attributes'], ns['all_attributes'] = \
                                   get_members_class(obj, 'attribute')
                  ns['methods'].sort()
                  ns['attributes'].sort()
  
              parts = name.split('.')
              if doc.objtype in ('method', 'attribute'):
                  mod_name = '.'.join(parts[:-2])
                  cls_name = parts[-2]
                  obj_name = '.'.join(parts[-2:])
                  ns['class'] = cls_name
              else:
                  mod_name, obj_name = '.'.join(parts[:-1]), parts[-1]
  
              ns['fullname'] = name
              ns['module'] = mod_name
              ns['objname'] = obj_name
              ns['name'] = parts[-1]
  
              ns['objtype'] = doc.objtype
              ns['underline'] = len(name) * '='
  
              # We now check whether a file for reference footnotes exists for
              # the module being documented. We first check if the
              # current module is a file or a directory, as this will give a
              # different path for the reference file. For example, if
              # documenting astropy.wcs then the reference file is at
              # ../wcs/references.txt, while if we are documenting
              # astropy.config.logging_helper (which is at
              # astropy/config/logging_helper.py) then the reference file is set
              # to ../config/references.txt
              if '.' in mod_name:
                  mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1]
              else:
                  mod_name_dir = mod_name
              if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \
                 and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])):
                  mod_name_dir = mod_name_dir.rsplit('/', 1)[0]
  
              # We then have to check whether it exists, and if so, we pass it
              # to the template.
              if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')):
                  # An important subtlety here is that the path we pass in has
                  # to be relative to the file being generated, so we have to
                  # figure out the right number of '..'s
                  ndirsback = path.replace(base_path, '').count('/')
                  ref_file_rel_segments = ['..'] * ndirsback
                  ref_file_rel_segments.append(mod_name_dir)
                  ref_file_rel_segments.append('references.txt')
                  ns['referencefile'] = os.path.join(*ref_file_rel_segments)
  
              rendered = template.render(**ns)
              f.write(rendered)
          finally:
              f.close()