Hi,

Autodoc is one of complex extension in Sphinx, I think. It is hard to
understand how it implemented. It adopted two-layered model. The first
layer; python domain describes python object in reST level. It provides
many directives for that purpose; `py:function`, `py:class`, `py:method`
and so on. The second layer is autodoc itself. It generates
reStructuredText source code based on the first layer internally.

And the `ObjectDescription` class you used is a base class of the first
layer. It is a kind of mini framework to create object-description
directives. It expects to derived classes to override `handle_signature()`
and some methods. You can see examples of it on sphinx/domains/*.py.

If your goal is making autodoc by one directive, there are no example to do
that. So I propose you to make the first layer at first.

Thanks,
Takeshi KOMIYA


2020年4月4日(土) 17:16 Sean Leavey <sean.lea...@gmail.com>:

> Hello Sphinx users,
>
> I want to create a Sphinx directive that documents custom objects for a
> domain-specific language. I want to define an object like this...
>
> My Custom Item
> ==============
>
> ..  dmn:component:: myitemcls
>
>     This is some extra text!
>
> and have Sphinx document it like it were a Python class, but not quite -
> something like this:
>
>
> (That's a mock-up of what I'd like - so far I've not managed it. Note also
> I'd like the "This is some extra text!" text to appear somewhere there
> too...)
>
> The idea is that the custom Sphinx directive would look up myitemcls in
> my library and introspect its parameters and then document them here.
> I figure this is the same as the Python autodoc module, but I'm having
> trouble understanding how it works - I find it's horrendously complicated
> and makes calls to other modules all over the place, not all of which are
> documented or require calls to non-public APIs. I tried to get it to work
> instead using a custom directive class, but I had to do something hacky -
> in the run method I grab the output from the parent (ObjectDescription)
> and inject some parameters into the middle of the node list - the problem
> is that the ObjectDescription directive appears to want the :param A:
> notation to have already been injected in before instantiation, as I
> believe autodoc would do. In contrast, with my method I have to inject
> these parameter strings into the object after instantiation (in run()),
> and that seems to be my problem. I guess the solution is to subclass some
> part of autodoc, but as I said I find it hard to figure out how.
>
> Here's what I've got so far:
>
> import docutils
> from docutils import nodes
> import sphinx
> from docutils.parsers import rst
> from docutils.parsers.rst import directives
> from docutils.statemachine import StringList
> from sphinx.domains import Domain, Index
> from sphinx.domains.std import StandardDomain
> from sphinx.roles import XRefRole
> from sphinx.directives import ObjectDescription
> from sphinx.util.nodes import make_refnode
> from sphinx.util.docfields import DocFieldTransformer, GroupedField
> from sphinx import addnodes
>
>
> class ComponentNode(ObjectDescription):
>     """A custom node that describes a component."""
>
>     required_arguments = 1
>
>     option_spec = {}
>
>     def __init__(self, *args, **kwargs):
>         super().__init__(*args, **kwargs)
>
>         self._component_name = self.arguments[0]
>
>         # Argument node list, filled later.
>         self._arglist = None
>         self._paramlist = None
>
>         # This is my own function, not shown, that populates
> self._paramlist with a list of strings containing ":param name:" etc. It
> also builds self._arglist with addnodes.desc_parameter nodes.
>         self._parse_parameters()
>
>     def run(self, *args, **kwargs):
>         nodes = super().run(*args, **kwargs)
>
>         # The following is a bit of a hack. I first overwrite the field
> type map to set up the
>         # "param" parser. I then create a list of strings containing
> ":param [x]: [description]"
>         # entries and parse the contents into a new node. Finally I stitch
> this node into the
>         # middle of the node list returned by the parent run() method.
>
>         self._doc_field_type_map = {
>             "param": (
>                 GroupedField("parameters", label="Parameters",
> names=('param',), can_collapse=True),
>                 False # is typed
>             ),
>         }
>
>         # Add parameters to content.
>         extra = StringList(
>             self._paramlist,
>             source=((self.content.parent, 0)*len(self._paramlist)),
>             parent=self.content.parent,
>             parent_offset=self.content.parent_offset
>         )
>
>         contentnode = addnodes.desc_content()
>         self.state.nested_parse(extra, self.content_offset, contentnode)
>
>         DocFieldTransformer(self).transform_all(contentnode)
>
>         return nodes[0:2] + [contentnode] + nodes[2:]
>
> I'm not happy with this, it's quite hacky and I figure I'm not doing it
> properly. It also generates documentation that looks different to that of
> class documentation - the "parameter" labels are blue not grey:
>
>
> Can anyone help me figure out how to implement this custom directive,
> ideally using autodoc?
>
> --
> You received this message because you are subscribed to the Google Groups
> "sphinx-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sphinx-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sphinx-users/5f306f1b-a565-4d16-a515-8dd2b2861d51%40googlegroups.com
> <https://groups.google.com/d/msgid/sphinx-users/5f306f1b-a565-4d16-a515-8dd2b2861d51%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"sphinx-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sphinx-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sphinx-users/CAFmkQAMcddm%3D8kgaTTi5iMmxLpN-rBoMbVvVNpu3F830%2BOUSgg%40mail.gmail.com.

Reply via email to