Look in doctrees for toctree and replace with custom render

def render_toctrees(kb_app: kb, sphinx_app: Sphinx, doctree: doctree,
                    fromdocname: str):
    """ Look in doctrees for toctree and replace with custom render """

    # Only do any of this if toctree support is turned on in KaybeeSettings.
    # By default, this is off.
    settings: KaybeeSettings = sphinx_app.config.kaybee_settings
    if not settings.articles.use_toctree:
        return

    # Setup a template and context
    builder: StandaloneHTMLBuilder = sphinx_app.builder
    env: BuildEnvironment = sphinx_app.env

    # Toctree support. First, get the registered toctree class, if any
    registered_toctree = ToctreeAction.get_for_context(kb_app)
    for node in doctree.traverse(toctree):
        if node.attributes['hidden']:
            continue
        custom_toctree = registered_toctree(fromdocname)
        context = builder.globalcontext.copy()
        context['sphinx_app'] = sphinx_app

        # Get the toctree entries. We only handle one level of depth for
        # now. To go further, we need to recurse like sphinx's
        # adapters.toctree._toctree_add_classes function
        entries = node.attributes['entries']

        # The challenge here is that some items in a toctree
        # might not be resources in our "database". So we have
        # to ask Sphinx to get us the titles.
        custom_toctree.set_entries(entries, env.titles,
                                   sphinx_app.env.resources)
        output = custom_toctree.render(builder, context, sphinx_app)

        # Put the output into the node contents
        listing = [nodes.raw('', output, format='html')]
        node.replace_self(listing)