docs: def process_task_topic_list(app, doctree, fromdocname):
      """Process the ``task_topic_list`` node to generate a rendered listing of
      Task, Configurable, or Config topics (as determined by the types
      key of the ``task_topic_list`` node).
  
      This is called during the "doctree-resolved" phase so that the
      ``lsst_task_topcs`` environment attribute is fully set.
      """
      logger = getLogger(__name__)
      logger.debug('Started process_task_list')
  
      env = app.builder.env
  
      for node in doctree.traverse(task_topic_list):
          try:
              topics = env.lsst_task_topics
          except AttributeError:
              message = (
                  "Environment does not have 'lsst_task_topics', "
                  "can't process the listing."
              )
              logger.warning(message)
              node.replace_self(nodes.paragraph(text=message))
              continue
  
          root = node['root_namespace']
  
          # Sort tasks by the topic's class name.
          # NOTE: if the presentation of the link is changed to the fully
          # qualified name, with full Python namespace, then the topic_names
          # should be changed to match that.
          topic_keys = [k for k, topic in topics.items()
                        if topic['type'] in node['types']
                        if topic['fully_qualified_name'].startswith(root)]
          topic_names = [topics[k]['fully_qualified_name'].split('.')[-1]
                         for k in topic_keys]
          topic_keys = [
              k for k, _ in
              sorted(zip(topic_keys, topic_names), key=lambda pair: pair[1])]
  
          if len(topic_keys) == 0:
              # Fallback if no topics are found
              p = nodes.paragraph(text='No topics.')
              node.replace_self(p)
              continue
  
          dl = nodes.definition_list()
          for key in topic_keys:
              topic = topics[key]
              class_name = topic['fully_qualified_name'].split('.')[-1]
              summary_text = topic['summary_node'][0].astext()
  
              # Each topic in the listing is a definition list item. The term is
              # the linked class name and the description is the summary
              # sentence from the docstring _or_ the content of the
              # topic directive
              dl_item = nodes.definition_list_item()
  
              # Can insert an actual reference since the doctree is resolved.
              ref_node = nodes.reference('', '')
              ref_node['refdocname'] = topic['docname']
              ref_node['refuri'] = app.builder.get_relative_uri(
                  fromdocname, topic['docname'])
              # NOTE: Not appending an anchor to the URI because task topics
              # are designed to occupy an entire page.
              link_label = nodes.Text(class_name, class_name)
              ref_node += link_label
  
              term = nodes.term()
              term += ref_node
              dl_item += term
  
              # We're degrading the summary to plain text to avoid syntax issues
              # and also because it may be distracting
              def_node = nodes.definition()
              def_node += nodes.paragraph(text=summary_text)
              dl_item += def_node
              dl += dl_item
  
          # Replace the task_list node (a placeholder) with this renderable
          # content
          node.replace_self(dl)