jbms / sphinx-immaterial

Adaptation of the popular mkdocs-material material design theme to the sphinx documentation system
https://jbms.github.io/sphinx-immaterial/
Other
196 stars 29 forks source link

Add additional fields in `python-apigen`? #126

Closed mhostetter closed 2 years ago

mhostetter commented 2 years ago

I really like the new section headers (Parameters, Returns, Raises) for python-apigen functions and methods. Would it be worthwhile to add section headers for other "rubrics", e.g. Notes, References, Examples? Perhaps for all rubrics in a docstring?

Just a thought...

image

jbms commented 2 years ago

For some background:

The napoleon extension actually converts the numpy-style sections in your docstrings in several different ways:

Parameters, Returns, Raises and other sections that correspond to Sphinx docfields get turned into docfields. According to https://jbms.github.io/sphinx-immaterial/apidoc/index.html#objconf-include_fields_in_toc they may then be included in the toc.

Everything else gets turned into either a rubric or admonition according to napoleon config. The Sphinx documentation for rubric https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html?highlight=rubric#directive-rubric specifically says it creates a heading that is not in the toc, but that doesn't necessarily mean this theme couldn't add them to the toc. But note that in terms of document structure a rubric is just a heading, not a heading + body, and therefore they aren't really amenable to nesting if that is desired.

An alternative would be a real rST section, as that leads to a more natural document structure. Sphinx normally doesn't allow sections inside object descriptions, but this theme adds support for that. Potentially the best solution would be to modify napoleon to generate real Sphinx sections rather than rubrics. I think that could be done by monkey-patching this method: https://github.com/Scalr/sphinx/blob/4803aa35c6e912524dd36bb755741e1ab6e47898/sphinx/ext/napoleon/docstring.py#L423

mhostetter commented 2 years ago

The Sphinx documentation for rubric https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html?highlight=rubric#directive-rubric specifically says it creates a heading that is not in the toc, but that doesn't necessarily mean this theme couldn't add them to the toc.

While rubrics aren't intended to be included in the TOC, my thought was maybe they optionally could be included for consistency with the other rubrics (Parameters, Returns, Raises) that are now optionally included in the TOC with object_description_options and include_fields_in_toc.

But note that in terms of document structure a rubric is just a heading, not a heading + body, and therefore they aren't really amenable to nesting if that is desired.

I don't personally foresee a need to nest them.

An alternative would be a real rST section, as that leads to a more natural document structure.

The only issue I see with that is I think most of us are accustomed to the styling of the smaller, bold rubric sections in the API document. I fear the quite large section titles might look strange? But I'm flexible. Just throwing out ideas for the team to consider.

Actually, I just did a little test. Perhaps level 4 section headings would have a similar aesthetic to the current rubrics?

image

2bndy5 commented 2 years ago

I don't know if custom fields are also added to the ToC, but have you tried using

def func(arg1, arg2):
    """
    :param arg1: something.
    :param arg2: something else.

    :Custom Field:
        This is a field paragraph.

        This is another field paragraph.
    """
mhostetter commented 2 years ago

Interesting... it seems work as you provided @2bndy5. However, it doesn't work if it's mix-and-matched with Google/NumPy style docstrings.

def func(x: int, y: float) -> int:
    """
    This is the docstring of func.

    :param x: Argument 1.
    :param y: Argument 2.

    :Custom Field:
    This is a field paragraph.

    This is another field paragraph.
    """

image

def func(x: int, y: float) -> int:
    """
    This is the docstring of func.

    Parameters
    ----------
    x
        Argument 1.
    y
        Argument 2.

    :Custom Field:
    This is a field paragraph.

    This is another field paragraph.
    """

image

2bndy5 commented 2 years ago

I don't use napoleon/Google/NumPy style syntax, so I'm not sure if they support creating custom fields like RST does. If I had to guess, it might be written like the following (field title may need to be 1 word though):

Custom Field: The first paragraph.

    The second paragraph (still in field description).

BTW, the indentation matters. Anything in the indented block following the field is shown as part of the field description. And just like most fields/directives, the leading and trailing blank lines might be mandatory.

jbms commented 2 years ago

Interesting... it seems work as you provided @2bndy5. However, it doesn't work if it's mix-and-matched with Google/NumPy style docstrings.

I think the issue here is that napoleon is still parsing it as a parameter since it falls under the parameters "section".

Adding an object description option to include rubrics in the TOC seems reasonable and shouldn't be too difficult. Basically could be implemented exactly like the existing include_fields_in_toc option.