Hi Daniel, I didn't see anything in your reply - did you mean to say
something or was that a mistake?
In any case, I got something to work by indeed subclassing from
sphinx.ext.autodoc. Here is my working solution:
from sphinx.ext.autodoc import Documenter, ClassDocumenter,
ModuleLevelDocumenter
__version__ = "0.1"
class MyDocumenter(ModuleLevelDocumenter):
"""Custom Sphinx autodocumeter.
Note: this disables the hooks used by numpydoc to stop it from mangling
the function signature
and docstring. This is required because numpy assumes it is documenting
a Python function and
therefore that the arguments are contained in brackets.
"""
objtype = "myobj"
directivetype = "attribute"
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return False
def document_members(self, all_members=False):
pass
def process_doc(self, docstrings):
# Stop extensions from preprocessing the docstrings.
for docstringlines in docstrings:
yield from docstringlines
def get_doc(self, ignore=1):
# Add your custom document fields here.
lines.append([":My Section:"])
lines.append([""])
lines.append(["::"])
lines.append([""])
lines.append([" Some paragraph..."])
lines.append([""])
return lines
def format_name(self):
# Ensure Python module is not added to name.
return self.name
def format_signature(self, **kwargs):
return ""
def resolve_name(self, modname, parents, path, base):
# Needs something here for Documenter to generate output; this is
also used for the index.
return "fake", [base]
def import_object(self):
return True
def setup(app):
app.add_autodocumenter(MyDocumenter)
return {"version": __version__, "parallel_read_safe": True}
On Monday, 6 April 2020 01:45:42 UTC, Daniel Scott wrote:
>
>
>
> Sent from my Metro By T-Mobile 4G LTE Android Device
> ------------------------------
> *From:* [email protected] <javascript:> <
> [email protected] <javascript:>> on behalf of Sean Leavey <
> [email protected] <javascript:>>
> *Sent:* Saturday, April 4, 2020 4:15:59 AM
> *To:* sphinx-users <[email protected] <javascript:>>
> *Subject:* [sphinx-users] Implementing custom "autodoc" style objects
>
> 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 [email protected] <javascript:>.
> 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/sphinx-users/cdce6eb4-e070-47f4-bf1b-4edf058bf7ec%40googlegroups.com.