Sphinx customizing autoclass output - python-sphinx

I have a module with several classes. Currently I am using ..automodule to document the module. I'd like each class to have its own header section with the class name. I could achieve this by replacing ..automodule foo with:
Bar
===
..autoclass foo.Bar
Baz
===
..autoclass foo.Baz
...
However, that would require me to manually list every class in every module I do this for. What is the best way to customize the content generated by automodule?

Sphinx is not as straightforward to use as Epydoc or Doxygen for generating API documentation from source code. It is a dfferent kind of tool.
Sphinx works on .rst (reStructuredText) files, and if you want each class to have its own heading with the class name, you have to add the headings yourself and use .. autoclass::. It cannot be done with just .. automodule::. Yes, this is inconvenient (similar sentiments are expressed here). See also this answer and this answer.
The problem can be mitigated by a script that walks through the Python code and generates .rst output. Sphinx already comes with such a script, sphinx-apidoc. However, it does not produce any .. autoclass:: directives, only .. automodule::.
Here is another script that can output .. autoclass::: https://github.com/PyMVPA/PyMVPA/blob/master/tools/apigen.py. Maybe you can use that.

Related

Is it possible to write only specific directives to an XML file

I'm rather new to Sphinx and ReST and I've "inherited" a big project.
The documentation consists of hundreds of pages with how to's, etc. There are several files (one for each class) where the respective functions are described using the ".. py:function::" directive.
So each of these pages is basically like this:
Some description text explaining the class
py:function:: class.myFunction(param1, param2)
parameter description
code example, ...
py:function:: class.myFunction2
parameter description
code example, ...
Now, I'd like to list all functions of all different pages in one single XML file, if possible grouped by their class, but without the descriptions and examples. Is this possible with some built-in Sphinx parser or do I have to write my own? Or is there any other directive or config option that may be helpful?
The XML file should be like this:
<class1>
<function1>
<param1>
<param2>
...
<function2>
...
<class2>
<function1>
...
I found ViewLists and the Parsing directive in the Sphinx documentation but i'm not sure how to correctly use them and if that's the solution to my problem.

Combining replace and include in reStructuredText / Sphinx [duplicate]

I want to use the .. include:: function inline, but I can only get it to actually include the file I want if I separate it with two new lines from the previous text.
Before anyone asks, the file I want to include is a protocol number, so no, it doesn't benefit from a new line, at all. I want to be able to change it easily so I can use it on multiple places of my documentation. I guess that an example would be "We currently use the protocol (proto.txt)." I'm new to Sphinx and rst, so maybe there is a very obvious solution I haven't found.
Inline includes are not possible with Sphinx.
However, you can define global aliases (substitutions) in the rst_epilog variable of your build configuration file.
For example, you can add the following lines to your conf.pyfile:
rst_epilog = """
.. |version| replace:: 4.1
.. |protocol| replace:: httpx
"""
Now, you can access the variables |version| and |protocol| from any .rst file within your project, for example like this:
Version |version| uses the |protocol| protocol.
becomes
Version 4.1 uses the httpx protocol.
If other parts of your software require protocol (or other variables) to be specified in a specific file or format, you can write a script to read it from there as a variable into the Sphinx configuration file.

Sphinx inline include

I want to use the .. include:: function inline, but I can only get it to actually include the file I want if I separate it with two new lines from the previous text.
Before anyone asks, the file I want to include is a protocol number, so no, it doesn't benefit from a new line, at all. I want to be able to change it easily so I can use it on multiple places of my documentation. I guess that an example would be "We currently use the protocol (proto.txt)." I'm new to Sphinx and rst, so maybe there is a very obvious solution I haven't found.
Inline includes are not possible with Sphinx.
However, you can define global aliases (substitutions) in the rst_epilog variable of your build configuration file.
For example, you can add the following lines to your conf.pyfile:
rst_epilog = """
.. |version| replace:: 4.1
.. |protocol| replace:: httpx
"""
Now, you can access the variables |version| and |protocol| from any .rst file within your project, for example like this:
Version |version| uses the |protocol| protocol.
becomes
Version 4.1 uses the httpx protocol.
If other parts of your software require protocol (or other variables) to be specified in a specific file or format, you can write a script to read it from there as a variable into the Sphinx configuration file.

How to name or number code-block in reStructuredText and Sphinx?

I would line to auto number code-blocks in reStructuredText, if auto numbering is not possible then name/number them manually.
.. code-block:: python
:name: super awesome code exaple no 5
a = 1
When in training we can then reference them and tell students on witch example we now work on. We don't need to reference them in the document itself.
Is it possible in any way? Out of box or by extending Sphinx?
It is possible to do that via extending Sphinx.
You have to create your own extension (see how to create an extension and where to put your own extension) which will implement you new custom directive (see how to create a directive).
Directives are usual Python classes, so your NamedCodeBlock directive class should extend the CodeBlock directive class (see sphinx.directives.code.CodeBlock) and add support for the name optional argument where you will be able to set names for your code blocks.

Adding a cross-reference to a subheading or anchor in another page

How to insert a cross-reference in a reST/Sphinx page to either a sub-header or anchor in another page in the same documentation set?
The expression "reST/Sphinx" makes the scope of the question unclear. Is it about reStructuredText in general and Sphinx, or only about reStructuredText as used in Sphinx (and not reStructuredText in general)? I'm going to cover both since people using RST are likely to run into both cases at some point:
Sphinx
Besides the domain-specific directives that can be used to link to various entities like classes (:class:) there's the general :ref: directive, documented here. They give this example:
.. _my-reference-label:
Section to cross-reference
--------------------------
This is the text of the section.
It refers to the section itself, see :ref:`my-reference-label`.
Although the general hyperlinking mechanism offered by RST does work in Sphinx, the documentation recommends against using it when using Sphinx:
Using ref is advised over standard reStructuredText links to sections (like Section title_) because it works across files, when section headings are changed, and for all builders that support cross-references.
RST, in General
The tools that convert RST files to HTML do not necessarily have a notion of collection. This is the case for instance if you rely on github to convert RST files to HTML or if you use a command line tool like rst2html. Unfortunately, the various methods to use to get the desired result vary depending on which tool you are using. For instance, if you use rst2html and you want file A.rst to link to a section named "Section" in file other.rst and you want the final HTML to work in a browser, then A.rst would contain:
`This <other.html#section>`__ is a reference to a section in another
file, which works with ``rst2html``. Unfortunately, it does not work
when the HTML is generated through github.
You have to link to the final HTML file and you have to know what the id given to the section will be. If you want to do the same for a file served through github:
`This <other.rst#section>`__ is a reference to a section in another
file, which works on github. Unfortunately, it does not work when you
use ``rst2html``.
Here too you need to know the id given to the section. However, you link to the RST file because it is only upon accessing the RST file that the HTML is created. (At the time of writing this answer, accessing the HTML directly is not allowed.)
A complete example is available here.
New, better answer for 2016!
The autosection extension lets you do this easily.
=============
Some Document
=============
Internal Headline
=================
then, later...
===============
Some Other Doc
===============
A link- :ref:`Internal Headline`
This extension is built-in, so all you need is to edit conf.py
extensions = [
.
. other
. extensions
. already
. listed
.
'sphinx.ext.autosectionlabel',
]
The only thing you have to be careful of is that now you can't duplicate internal headlines across the doc collection. (Worth it.)
Example:
Hey, read the :ref:`Installation:Homebrew` section.
where Homebrew is a section inside a different document named Installation.rst.
This uses the autosection feature, so will need to edit config.py with the following:
extensions = [
'sphinx.ext.autosectionlabel'
]
autosectionlabel_prefix_document = True
In Sphinx 3.0.3 the only solution that worked for me is :any: (see https://www.sphinx-doc.org/en/1.5/markup/inline.html#cross-referencing-anything).
Suppose, one document has such a section:
.. _my-section:
My Section
----------
Lorem ipsum blablabla
Then another document can have the following fragment to create a link:
See :any:`my-section` for the details
I was struggling to make this work and i found out that the actual notation is :ref:'{dir-path}/Installation:Homebrew' where {dir-path} is the relative path to Installation.rst from where config.py exists
Adding description of behavior that was confusing to me.
Section titles must be referenced with the file name (overview here) in front of it:
overview.rst:
************
API Overview
************
index.rst:
:ref:`overview:API Overview`
However, when referencing links, the file name (constants here) must not be there:
constants.rst:
.. _section-constants:
*******************
Enums and Constants
*******************
api.rst:
:ref:`section-constants`
Also, for this to work, one must enable extension 'autosectionlabel':
conf.py:
extensions = [
...
"sphinx.ext.autosectionlabel"
]

Resources