text: import sys
  from paths_cli.compiling.core import Parameter
  from .json_type_handlers import json_type_to_string
  from .config_handler import DocCategoryInfo
  
  PARAMETER_RST = """* **{p.name}**{type_str} - {p.description}{required}\n"""
  
  
  class DocsGenerator:
      """This generates the RST to describe options for compile input files.
  
      Parameters
      ----------
      config : Dict[str, DocCategoryInfo]
          mapping of category name to DocCategoryInfo for that category;
          usually generated by :method:`.load_config`
      """
  
      parameter_template = PARAMETER_RST
      _ANCHOR_SEP = "--"
  
      def __init__(self, config):
          self.config = config
  
      def format_parameter(self, parameter, type_str=None):
          """Format a single :class:`.paths_cli.compiling.Parameter` in RST
          """
          required = " (required)" if parameter.required else ""
          return self.parameter_template.format(
              p=parameter, type_str=type_str, required=required
          )
  
      def _get_cat_info(self, category_plugin):
          cat_info = self.config.get(category_plugin.label, None)
          if cat_info is None:
              cat_info = DocCategoryInfo(category_plugin.label)
          return cat_info
  
      def generate_category_rst(self, category_plugin):
          """Generate the RST for a given category plugin.
  
          Parameters
          ----------
          category_plugin : :class:`.CategoryPlugin`
              the plugin for which we should generate the RST page
  
          Returns
          -------
          str :
              RST string for this category
          """
          cat_info = self._get_cat_info(category_plugin)
          type_required = cat_info.type_required
          rst = f".. _compiling--{category_plugin.label}:\n\n"
          rst += f"{cat_info.header}\n{'=' * len(str(cat_info.header))}\n\n"
          if cat_info.description:
              rst += cat_info.description + "\n\n"
          rst += ".. contents:: :local:\n\n"
          for obj in category_plugin.type_dispatch.values():
              rst += self.generate_plugin_rst(
                  obj, category_plugin.label, type_required
              )
          return rst
  
      def generate_plugin_rst(self, plugin, category_name,
                              type_required=True):
          """Generate the RST for a given object plugin.
  
          Parameters
          ----------
          plugin : class:`.InstanceCompilerPlugin`
              the object plugin for to generate the RST for
          category_name : str
              the name of the category for this object
          type_required : bool
              whether the ``type`` parameter is required in the dict input for
              compiling this type of object (usually category-dependent)
  
          Returns
          -------
          str :
              RST string for this object plugin
          """
          rst_anchor = f".. _{category_name}{self._ANCHOR_SEP}{plugin.name}:"
          rst = f"{rst_anchor}\n\n{plugin.name}\n{'-' * len(plugin.name)}\n\n"
          if plugin.description:
              rst += plugin.description + "\n\n"
          if type_required:
              type_param = Parameter(
                  "type",
                  json_type="",
                  loader=None,
                  description=(f"type identifier; must exactly match the "
                               f"string ``{plugin.name}``"),
              )
              rst += self.format_parameter(
                  type_param, type_str=""
              )
  
          name_param = Parameter(
              "name",
              json_type="string",
              loader=None,
              default="",
              description="name this object in order to reuse it",
          )
          rst += self.format_parameter(name_param, type_str=" (string)")
          for param in plugin.parameters:
              type_str = f" ({json_type_to_string(param.json_type)})"
              rst += self.format_parameter(param, type_str)
  
          rst += "\n\n"
          return rst
  
      @staticmethod
      def _get_filename(cat_info):
          fname = str(cat_info.header).lower()
          fname = fname.translate(str.maketrans(' ', '_'))
          return f"{fname}.rst"
  
      def generate(self, category_plugins, stdout=False):
          """Generate RST output for the given plugins.
  
          This is the main method used to generate the entire set of
          documentation.
  
          Parameters
          ----------
          category_plugin : List[:class:`.CategoryPlugin`]
              list of category plugins document
          stdout : bool
              if False (default) a separate output file is generated for each
              category plugin. If True, all text is output to stdout
              (particularly useful for debugging/dry runs).
          """
          for plugin in category_plugins:
              rst = self.generate_category_rst(plugin)
              if stdout:
                  sys.stdout.write(rst)
                  sys.stdout.flush()
              else:
                  cat_info = self._get_cat_info(plugin)
                  filename = self._get_filename(cat_info)
                  with open(filename, 'w') as f:
                      f.write(rst)
  