sphinx icon indicating copy to clipboard operation
sphinx copied to clipboard

Variant of ObjectDescription without signature

Open LecrisUT opened this issue 3 months ago • 2 comments

Is your feature request related to a problem? Please describe. I am working on a sphinx domain where I am getting effectively document sections from another source. For the most part ObjectDescription is what I need except for substituting the signature node for a title node/section.

I would prefer to use ObjectDescription because it already has the options for indexing, and target creation that I would not want to replicate.

Describe the solution you'd like Generalize ObjectDescription to accept a generic "header" node which we can customize. In this case I would customize it for myself with a title node.

Describe alternatives you've considered Alternatively I am using a plain SphinxDirective, but this misses quite a bit of the logic like object-description-transform. Most of the logic in the ObjectDescription directive is fine in the current state apart from the hard-coded addnodes.desc_signature

LecrisUT avatar Nov 06 '25 14:11 LecrisUT

I'm not sure I follow the suggestion. Can you explain what you're trying to achieve (high level) and then how this proposal fits into it? Some brief sample code might help too.

A

AA-Turner avatar Nov 07 '25 02:11 AA-Turner

Sure, in essence my current code does:

class MyObjDirective(SphinxDirective)
    has_content = False
    required_arguments = 1

    def run(self) -> list[Node]:
        name = self.arguments[0]
        title = name.split("/")[-1]

        # Would like to use nodes.title, but couldn't get it to work properly
        self.content.append(title, source="")
        self.content.append("=" * len(title), source="")
        self.content.append("", source="")
        # Add more autodoc-like content
        ...

        # Replicate other logic that I would put in `add_target_and_index`
        self.my_domain.objects[name] = IndexEntry(...)

        index_node = addnodes.index(entries=[])  # Still figuring out how I'm meant to use this
        target_node = nodes.target(ids=[name])
        node = nodes.paragraph()
        node += self.parse_content_to_nodes(allow_section_headings=True)
        return [
            index_node,
            target_node,
            *node.children,
        ]

(PS: if you notice I am doing something wrong in the parts above, let me know, it seems very fragile when I try to do it better, but can't figure out why)

What I would like instead is to basically use the same interface as ObjectDescription but with a change at: https://github.com/sphinx-doc/sphinx/blob/b9d5d2bacca83edcd6f7cb10c63490ec1b29fccd/sphinx/directives/init.py#L209 https://github.com/sphinx-doc/sphinx/blob/b9d5d2bacca83edcd6f7cb10c63490ec1b29fccd/sphinx/directives/init.py#L254

class MyObjDirective(ObjectDescription[str])
    has_content = False
    required_arguments = 1

    def transform_content(self, content) -> None:
        # Do the autodoc-like content here
        ...

    def get_signatures(self) -> list[str]:
        sigs = super().get_signatures()
        assert len(sigs) == 1
        return sigs

    def handle_signature(self, sig: str, sig_like_node) -> str:
        name = sig
        title = name.split("/")[-1]
        # Assuming we can make nodes.title work
        # Don't want to add the title to the sig_like_node, but to the main node instead
        sig_like_node.parent += nodes.title(txt=title)
        return title

    def add_target_and_index(self, name: str, sig: str, sig_like_node) -> None:
        self.my_domain.objects[sig] = IndexEntry(...)  # uses name and other stuff I would get from autodoc-like features
        sig_like_node['ids'].append(sig)

    # Some new interface to change addnodes.desc and addnodes.desc_signature
    def create_desc_like_node(self) -> DescLikeT:
        return nodes.section

The overall effect is that I want the directive to translate

.. my_domain:myobj:: /path/to/object

   .. my_domain:myobj:: /path/to/sub_object

into

Object
======

Some autodoc-like content injected with cross-referencing :my_domain:myobj:`/path/to/object`...

SubObject
---------

Autodoc-like content injected for the subobjects as subsections.

The issue I had when trying to use this approach is:

  • The titles become the content or the description node's title. What I would like instead is to be for the document section itself as if it is part of a plain document
  • The addnodes.desc does not render well when I am using it to construct subobjects which are meant to be subsections
  • addnodes.desc_signature would leave an empty box if I try to not use them and it renders the titles and such under addnodes.desc box.
  • Still learning how to properly use the index, particularly what the ObjectDescription.indexnode is for

LecrisUT avatar Nov 07 '25 10:11 LecrisUT