************** Advanced Usage ************** The following topics may be relevant when working on real-world documentation projects, which often demand a greater level of customization. A TOC for every class ===================== It is also possible to use :rst:dir:`autoclasstoc` in auto-generated API documentation, i.e. where all of the classes in your project are documented without you having to explicitly write an :rst:dir:`autoclass` directive for each one. The way to do this is to use the :ext:`autosummary` extension with a custom Jinja template for classes, as detailed below: 1. Configure the :ext:`autosummary` extension to automatically generate stub files each time the documentation is built: .. code-block:: python :caption: conf.py autosummary_generate = True Alternatively, you could generate stub files yourself by running the ``autogen`` command when necessary (after completing steps 2 and 3 below). I find this less convenient, but it might be better if you intend to edit the stub files by hand: .. code-block:: console $ sphinx-autogen -t _templates path/to/doc/with/autosummary.rst 2. Add an :rst:dir:`autosummary` directive with the ``:toctree:`` and ``:recursive:`` options to your documentation. Anywhere will work, but ``index.rst`` is a common choice: .. code-block:: rst :caption: index.rst .. autosummary:: :toctree: path/to/directory/for/autogenerated/files :recursive: mоdulе.tо.dосumеnt 3. Provide a custom Jinja_ template for formatting class stub files. The purpose of this template is to specify that :rst:dir:`autoclasstoc` should be used for each class: .. code-block:: rst :caption: _templates/autosummary/class.rst {{ fullname | escape | underline}} .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} :members: :undoc-members: :special-members: :private-members: :inherited-members: :show-inheritance: .. autoclasstoc:: Note that the name of the ``_templates`` directory depends on the value of the ``templates_path`` setting in ``conf.py``. .. _Jinja: https://jinja.palletsprojects.com/ Custom sections =============== By default, :rst:dir:`autoclasstoc` divides the TOC into sections based whether or not attributes are methods, and whether or not they are public. This is a reasonable default, but for many projects it may make sense to add custom sections specific to the idioms of that project. Fortunately, this is easy to configure. The basic steps are: 1. Define new :class:`autoclasstoc.Section` subclasses. 2. Reference the subclasses either in ``conf.py`` or in the documentation itself. This approach is very powerful, because the `Section` class controls all aspects of defining and formatting the TOC sections, and its subclasses can overwrite any of that behavior. Below are some specific examples showing how custom sections can be configured: Based on name ------------- Categorizing attributes based on their names is convenient, because it doesn't require making any changes or annotations to the code itself. For this example, we'll make a custom "Event Handlers" section that will consist of methods that begin with the prefix "on\_", e.g. :meth:`on_mouse_down()` or :meth:`on_key_up()`. The first step is to define a new `Section` subclass with the following attributes: - :attr:`~autoclasstoc.Section.key`: used to include or exclude the section from class TOCs. - :attr:`~autoclasstoc.Section.title`: how the section will be labeled in the documentation. - :meth:`~autoclasstoc.Section.predicate`: which attributes to include in the section. .. code-block:: :caption: conf.py from autoclasstoc import Section, is_method class EventHandlers(Section): key = 'event-handlers' title = "Event Handlers:" def predicate(self, name, attr, meta): return is_method(name, attr) and name.startswith('on_') We also have to redefine the "Public Methods" section, so that it *doesn't* include the event handlers (as it otherwise would): .. code-block:: :caption: conf.py from autoclasstoc import PublicMethods class RemainingPublicMethods(PublicMethods): exclude_section = EventHandlers Finally, we need to specify that our new sections should be used by default (and what order they should go in): .. code-block:: :caption: conf.py autoclasstoc_sections = [ 'event-handlers', 'public-methods', 'private-methods', ] Based on pattern ---------------- Excluding attributes from a section based on their name is a common desire. To make this easier, `Section` classes have a :attr:`~autoclasstoc.Section.exclude_pattern` attribute that filters any matching attributes out of the section. To demonstrate how this works, we'll make a custom "Public Methods" section that will consist of public methods but excluding all "dunders" methods, e.g. :meth:`__init__()`. The first step is to define a new `PublicSection` subclass with the following attributes: - :attr:`~autoclasstoc.Section.key`: used to include or exclude the section from class TOCs. - :attr:`~autoclasstoc.Section.exclude_pattern`: used for regex matching of the name for exclusion .. code-block:: :caption: conf.py from autoclasstoc import PublicSection, is_method class PublicMethodsWithoutDunders(PublicSection): key = 'public-methods-without-dunders' exclude_pattern = '__' autoclasstoc_sections = [ 'public-methods-without-dunders', 'private-methods', ] No more is necessary because the `PublicSection` (and all other `Section` subclasses) check for possible `exclude_pattern`. Note here, that `exclude_pattern` can also be a list of strings. This class we just created (`PublicMethodsWithoutDunders`) is already within :rst:dir:`autoclasstoc`. It can be used with the key `public-methods-without-dunders` in the `autoclasstoc_sections` variable. Based on decorator ------------------ A more explicit way to categorize methods is to use a decorator to label methods that belong to a particular section. This approach only is only applicable to methods and inner classes (because data attributes cannot be decorated), but is easy to implement. For this example, we'll make a section for "Read Only" methods that are identified by a decorator: The first step is to write a decorator to label read-only methods: .. code-block:: python def read_only(f): f.__readonly__ = True return f class MyClass: @read_only def do_nothing(self): pass Next, we have to define `Section` subclasses that are aware of the decorator: .. code-block:: python :caption: conf.py from autoclasstoc import Section class ReadOnlySection(Section): key = 'read-only' title = "Read-Only Methods:" def predicate(self, name, attr, meta): return getattr(attr, '__readonly__', False) class ReadWriteSection(Section): key = 'read-write' title = "Read/Write Methods:" def predicate(self, name, attr, meta): return not getattr(attr, '__readonly__', False) autoclasstoc_sections = [ 'read-only', 'read-write', ] Note that this example removes the distinction between private and public methods, so both the "Read-Only" and "Read/Write" sections will contain public and private methods. Based on ``:meta:`` fields -------------------------- With :ext:`autodoc`, it's possible to describe how an object should be documented by including `:meta: ` fields in that object's docstring. :rst:dir:`autoclasstoc` automatically parses these fields and provides them as an argument to :meth:`~autoclasstoc.Section.predicate()`, so they can be easily used to categorize attributes. As in the previous example, we'll make a custom section for read-only methods. The snippet below shows how such a method might be identified using a meta field: .. code-block:: python class MyClass: def do_nothing(self): """ This method doesn't do anything. :meta read-only: """ pass These meta fields are parsed into a dictionary such that ``:meta key: value`` would give ``{'key': 'value'}``. This dictionary is provided to the :meth:`~autoclasstoc.Section.predicate()` method via the *meta* argument: .. code-block:: python :caption: conf.py from autoclasstoc import Section class ReadOnlySection(Section): key = 'read-only' title = "Read-Only Methods:" def predicate(self, name, attr, meta): return 'read-only' in meta class ReadWriteSection(Section): key = 'read-write' title = "Read/Write Methods:" def predicate(self, name, attr, meta): return 'read-only' not in meta autoclasstoc_sections = [ 'read-only', 'read-write', ] Custom CSS ========== All of the HTML elements generated by :rst:dir:`autoclasstoc` are contained in a ``
`` with class ``autoclasstoc``. This can be used to select and style the elements in the class TOC. Note that the plugin includes some default rules to control the spacing around the ``
`` elements that contain TOCs for inherited attributes.