docs: def generate_contents(startpath, outfilename=DEFAULT_BUILDFILE):
      """
      Generate a build file (yaml) based on the contents of a
      directory tree.
      """
      def _ignored_name(name):
          return (
              name.startswith('.') or
              name == PACKAGE_DIR_NAME or
              name.endswith('~') or
              name == outfilename
          )
  
      def _generate_contents(dir_path):
          safename_duplicates = defaultdict(list)
          for name in os.listdir(dir_path):
              if _ignored_name(name):
                  continue
  
              path = os.path.join(dir_path, name)
  
              if os.path.isdir(path):
                  nodename = name
                  ext = None
              elif os.path.isfile(path):
                  nodename, ext = splitext_no_dot(name)
              else:
                  continue
  
              safename = to_identifier(nodename)
              safename_duplicates[safename].append((name, nodename, ext))
  
          safename_to_name = {}
          for safename, duplicates in iteritems(safename_duplicates):
              for name, nodename, ext in duplicates:
                  if len(duplicates) > 1 and ext:
                      new_safename = to_identifier(name)  # Name with ext
                  else:
                      new_safename = safename
                  existing_name = safename_to_name.get(new_safename)
                  if existing_name is not None:
                      message = "Duplicate node names in directory %r."
                      message += " %r was renamed to %r, which overlaps with %r"
                      raise BuildException(
                          message % (dir_path, name, new_safename, existing_name)
                      )
                  safename_to_name[new_safename] = name
  
          contents = {}
          for safename, name in iteritems(safename_to_name):
              path = os.path.join(dir_path, name)
  
              if os.path.isdir(path):
                  data = _generate_contents(path)
              else:
                  rel_path = os.path.relpath(path, startpath)
                  data = dict(file=rel_path)
  
              contents[safename] = data
  
          return contents
  
      return dict(
          contents=_generate_contents(startpath)
      )