def automodapi_replace(sourcestr, app, dotoctree=True, docname=None,
                       warnings=True):
    """
    Replaces `sourcestr`'s entries of ".. automdapi::" with the
    automodapi template form based on provided options.

    This is used with the sphinx event 'source-read' to replace
    `automodapi`_ entries before sphinx actually processes them, as
    automodsumm needs the code to be present to generate stub
    documentation.

    Parameters
    ----------
    sourcestr : str
        The string with sphinx source to be checked for automodapi
        replacement.
    app : `sphinx.application.Application`
        The sphinx application.
    dotoctree : bool
        If `True`, a ":toctree:" option will be added in the "..
        automodsumm::" sections of the template, pointing to the
        appropriate "generated" directory based on the Astropy convention
        (e.g. in ``docs/api``)
    docname : str
        The name of the file for this `sourcestr` (if known - if not, it
        can be `None`). If not provided and `dotoctree` is `True`, the
        generated files may end up in the wrong place.
    warnings : bool
        If `False`, all warnings that would normally be issued are
        silenced.

    Returns
    -------
    newstr :str
        The string with automodapi entries replaced with the correct
        sphinx markup.
    """

    spl = _automodapirex.split(sourcestr)
    if len(spl) > 1:  # automodsumm is in this document

        if dotoctree:
            toctreestr = ':toctree: '
            dirnm = app.config.automodapi_toctreedirnm
            if not dirnm.endswith("/"):
                dirnm += "/"
            if docname is not None:
                toctreestr += '../' * docname.count('/') + dirnm
            else:
                toctreestr += dirnm
        else:
            toctreestr = ''

        newstrs = [spl[0]]
        for grp in range(len(spl) // 3):
            modnm = spl[grp * 3 + 1]

            # find where this is in the document for warnings
            if docname is None:
                location = None
            else:
                location = (docname, spl[0].count('\n'))

            # initialize default options
            toskip = []
            inhdiag = maindocstr = top_head = True
            hds = '-^'
            allowedpkgnms = []

            # look for actual options
            unknownops = []
            for opname, args in _automodapiargsrex.findall(spl[grp * 3 + 2]):
                if opname == 'skip':
                    toskip.append(args.strip())
                elif opname == 'no-inheritance-diagram':
                    inhdiag = False
                elif opname == 'no-main-docstr':
                    maindocstr = False
                elif opname == 'headings':
                    hds = args
                elif opname == 'no-heading':
                    top_head = False
                elif opname == 'allowed-package-names':
                    allowedpkgnms.append(args.strip())
                else:
                    unknownops.append(opname)

            #join all the allowedpkgnms
            if len(allowedpkgnms) == 0:
                allowedpkgnms = ''
                onlylocals = True
            else:
                allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms)
                onlylocals = allowedpkgnms

            # get the two heading chars
            if len(hds) < 2:
                msg = 'Not enough headings (got {0}, need 2), using default -^'
                if warnings:
                    app.warn(msg.format(len(hds)), location)
                hds = '-^'
            h1, h2 = hds.lstrip()[:2]

            # tell sphinx that the remaining args are invalid.
            if len(unknownops) > 0 and app is not None:
                opsstrs = ','.join(unknownops)
                msg = 'Found additional options ' + opsstrs + ' in automodapi.'
                if warnings:
                    app.warn(msg, location)

            ispkg, hascls, hasfuncs = _mod_info(modnm, toskip, onlylocals=onlylocals)

            # add automodule directive only if no-main-docstr isn't present
            if maindocstr:
                automodline = '.. automodule:: {modname}'.format(modname=modnm)
            else:
                automodline = ''
            if top_head:
                newstrs.append(automod_templ_modheader.format(modname=modnm,
                    modhds=h1 * len(modnm),
                    pkgormod='Package' if ispkg else 'Module',
                    pkgormodhds=h1 * (8 if ispkg else 7),
                    automoduleline=automodline))
            else:
                newstrs.append(automod_templ_modheader.format(
                    modname='',
                    modhds='',
                    pkgormod='',
                    pkgormodhds='',
                    automoduleline=automodline))

            #construct the options for the class/function sections
            #start out indented at 4 spaces, but need to keep the indentation.
            clsfuncoptions = []
            if toctreestr:
                clsfuncoptions.append(toctreestr)
            if toskip:
                clsfuncoptions.append(':skip: ' + ','.join(toskip))
            if allowedpkgnms:
                clsfuncoptions.append(allowedpkgnms)
            clsfuncoptionstr = '\n    '.join(clsfuncoptions)

            if hasfuncs:
                newstrs.append(automod_templ_funcs.format(
                    modname=modnm,
                    funchds=h2 * 9,
                    clsfuncoptions=clsfuncoptionstr))

            if hascls:
                newstrs.append(automod_templ_classes.format(
                    modname=modnm,
                    clshds=h2 * 7,
                    clsfuncoptions=clsfuncoptionstr))

            if inhdiag and hascls:
                # add inheritance diagram if any classes are in the module
                newstrs.append(automod_templ_inh.format(
                    modname=modnm,
                    clsinhsechds=h2 * 25,
                    allowedpkgnms=allowedpkgnms))

            newstrs.append(spl[grp * 3 + 3])

        newsourcestr = ''.join(newstrs)

        if app.config.automodapi_writereprocessed:
            # sometimes they are unicode, sometimes not, depending on how
            # sphinx has processed things
            if isinstance(newsourcestr, text_type):
                ustr = newsourcestr
            else:
                ustr = newsourcestr.decode(app.config.source_encoding)

            if docname is None:
                with open(os.path.join(app.srcdir, 'unknown.automodapi'), 'a') as f:
                    f.write('\n**NEW DOC**\n\n')
                    f.write(ustr)
            else:
                env = app.builder.env
                # Determine the filename associated with this doc (specifically
                # the extension)
                filename = docname + os.path.splitext(env.doc2path(docname))[1]
                filename += '.automodapi'

                with open(os.path.join(app.srcdir, filename), 'w') as f:
                    f.write(ustr)

        return newsourcestr
    else:
        return sourcestr
dataset/ETHPy150Open astroML/gatspy/doc/sphinxext/numpy_ext/automodapi.py/automodapi_replace/original