Improve cross-reference documentation (#12944)

Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
Tim Hoffmann
2024-10-03 16:58:37 +02:00
committed by GitHub
parent 80c4b65a2a
commit 4080be1e82
4 changed files with 152 additions and 74 deletions

View File

@@ -158,19 +158,22 @@ giving the domain name, i.e. ::
Cross-referencing syntax
~~~~~~~~~~~~~~~~~~~~~~~~
For cross-reference roles provided by domains, the same facilities exist as for
general cross-references. See :ref:`xref-syntax`.
For cross-reference roles provided by domains,
the same :ref:`cross-referencing modifiers <xref-modifiers>` exist
as for general cross-references.
In short:
* You may supply an explicit title and reference target: ``:role:`title
<target>``` will refer to *target*, but the link text will be *title*.
* You may supply an explicit title and reference target:
``:py:mod:`mathematical functions <math>``` will refer to the ``math`` module,
but the link text will be "mathematical functions".
* If you prefix the content with ``!``, no reference/hyperlink will be created.
* If you prefix the content with an exclamation mark (``!``),
no reference/hyperlink will be created.
* If you prefix the content with ``~``, the link text will only be the last
component of the target. For example, ``:py:meth:`~Queue.Queue.get``` will
refer to ``Queue.Queue.get`` but only display ``get`` as the link text.
component of the target.
For example, ``:py:meth:`~queue.Queue.get``` will
refer to ``queue.Queue.get`` but only display ``get`` as the link text.
Built-in domains
----------------

View File

@@ -716,18 +716,45 @@ a matching identifier is found:
.. versionadded:: 0.4
The name enclosed in this markup can include a module name and/or a class name.
For example, ``:py:func:`filter``` could refer to a function named ``filter``
in the current module, or the built-in function of that name. In contrast,
``:py:func:`foo.filter``` clearly refers to the ``filter`` function in the
``foo`` module.
Normally, names in these roles are searched first without any further
qualification, then with the current module name prepended, then with the
current module and class name (if any) prepended. If you prefix the name with
a dot, this order is reversed. For example, in the documentation of Python's
:mod:`codecs` module, ``:py:func:`open``` always refers to the built-in
function, while ``:py:func:`.open``` refers to :func:`codecs.open`.
Target specification
^^^^^^^^^^^^^^^^^^^^
The target can be specified as a fully qualified name
(e.g. ``:py:meth:`my_module.MyClass.my_method```)
or any shortened version
(e.g. ``:py:meth:`MyClass.my_method``` or ``:py:meth:`my_method```).
See `target resolution`_ for details on the resolution of shortened names.
:ref:`Cross-referencing modifiers <xref-modifiers>` can be applied.
In short:
* You may supply an explicit title and reference target:
``:py:mod:`mathematical functions <math>``` will refer to the ``math`` module,
but the link text will be "mathematical functions".
* If you prefix the content with an exclamation mark (``!``),
no reference/hyperlink will be created.
* If you prefix the content with ``~``, the link text will only be the last
component of the target.
For example, ``:py:meth:`~queue.Queue.get``` will
refer to ``queue.Queue.get`` but only display ``get`` as the link text.
Target resolution
^^^^^^^^^^^^^^^^^
A given link target name is resolved to an object using the following strategy:
Names in these roles are searched first without any further qualification,
then with the current module name prepended,
then with the current module and class name (if any) prepended.
If you prefix the name with a dot (``.``), this order is reversed.
For example, in the documentation of Python's :py:mod:`codecs` module,
``:py:func:`open``` always refers to the built-in function,
while ``:py:func:`.open``` refers to :func:`codecs.open`.
A similar heuristic is used to determine whether the name is an attribute of
the currently documented class.

View File

@@ -4,83 +4,84 @@
Cross-referencing syntax
========================
Cross-references are generated by many semantic interpreted text roles.
Basically, you only need to write ``:role:`target```, and a link will be
created to the item named *target* of the type indicated by *role*. The link's
text will be the same as *target*.
One of Sphinx's most useful features is creating automatic cross-references
through semantic cross-referencing roles.
A cross reference to an object description, such as ``:func:`spam```,
will create a link to the place where ``spam()`` is documented,
appropriate to each output format (HTML, PDF, ePUB, etc.).
There are some additional facilities, however, that make cross-referencing
roles more versatile:
Sphinx supports various cross-referencing roles to create links
to other elements in the documentation.
In general, writing ``:role:`target``` creates a link to
the object called *target* of the type indicated by *role*.
The link's text depends the role but is often the same as or similar to *target*.
* You may supply an explicit title and reference target,
like in reStructuredText direct hyperlinks:
``:role:`title <target>``` will refer to *target*,
but the link text will be *title*.
.. _xref-modifiers:
* If you prefix the content with ``!``, no reference/hyperlink will be created.
The behavior can be modified in the following ways:
* If you prefix the content with ``~``, the link text will only be the last
component of the target. For example, ``:py:meth:`~Queue.Queue.get``` will
refer to ``Queue.Queue.get`` but only display ``get`` as the link text. This
does not work with all cross-reference roles, but is domain specific.
* **Custom link text:**
You can specify the link text explicitly using the same
notation as in reStructuredText :ref:`external links <rst-external-links>`:
``:role:`custom text <target>``` will refer to *target*
and display *custom text* as the text of the link.
In HTML output, the link's ``title`` attribute (that is e.g. shown as a
tool-tip on mouse-hover) will always be the full target name.
* **Suppressed link:**
Prefixing with an exclamation mark (``!``) prevents the creation of a link
but otherwise keeps the visual output of the role.
For example, writing ``:py:func:`!target``` displays :py:func:`!target`,
with no link generated.
.. _any-role:
This is helpful for cases in which the link target does not exist;
e.g. changelog entries that describe removed functionality,
or third-party libraries that don't support :doc:`intersphinx
</usage/extensions/intersphinx>`.
Suppressing the link prevents warnings in :confval:`nitpicky` mode.
Cross-referencing anything
--------------------------
* **Modified domain reference:**
When :ref:`referencing domain objects <ref-objects>`,
a tilde ``~`` prefix shortens the link text the last component of the target.
For example, ``:py:meth:`~queue.Queue.get``` will
refer to ``queue.Queue.get`` but only display ``get`` as the link text.
.. rst:role:: any
In HTML output, the link's ``title`` attribute
(that is e.g. shown as a tool-tip on mouse-hover)
will always be the full target name.
.. versionadded:: 1.3
Some of the built-in cross-reference roles are:
This convenience role tries to do its best to find a valid target for its
reference text.
* :rst:role:`:any: <any>`,
:rst:role:`:doc: <doc>`,
:rst:role:`:ref: <ref>`
* :rst:role:`:confval: <confval>`,
:rst:role:`:envvar: <envvar>`,
:rst:role:`:option: <option>`
* :rst:role:`:manpage: <manpage>`,
:rst:role:`:pep: <pep>`,
:rst:role:`:rfc: <rfc>`
* :rst:role:`download`,
:rst:role:`:index: <index>`
:rst:role:`:numref: <numref>`,
:rst:role:`:keyword: <keyword>`,
:rst:role:`:term: <term>`,
:rst:role:`:token: <token>`
* :rst:role:`!:func:`
(this uses the :confval:`primary_domain`, e.g. :rst:role:`:py:func: <py:func>`)
* :ref:`Domain cross-reference roles <ref-objects>`
* First, it tries standard cross-reference targets that would be referenced
by :rst:role:`doc`, :rst:role:`ref` or :rst:role:`option`.
Custom objects added to the standard domain by extensions (see
:meth:`.Sphinx.add_object_type`) are also searched.
* Then, it looks for objects (targets) in all loaded domains. It is up to
the domains how specific a match must be. For example, in the Python
domain a reference of ``:any:`Builder``` would match the
``sphinx.builders.Builder`` class.
If none or multiple targets are found, a warning will be emitted. In the
case of multiple targets, you can change "any" to a specific role.
This role is a good candidate for setting :confval:`default_role`. If you
do, you can write cross-references without a lot of markup overhead. For
example, in this Python function documentation::
.. function:: install()
This function installs a `handler` for every signal known by the
`signal` module. See the section `about-signals` for more information.
there could be references to a glossary term (usually ``:term:`handler```), a
Python module (usually ``:py:mod:`signal``` or ``:mod:`signal```) and a
section (usually ``:ref:`about-signals```).
The :rst:role:`any` role also works together with the
:mod:`~sphinx.ext.intersphinx` extension: when no local cross-reference is
found, all object types of intersphinx inventories are also searched.
.. _ref-objects:
Cross-referencing objects
-------------------------
These roles are described with their respective domains:
* :ref:`Python <python-xref-roles>`
* :ref:`C <c-xref-roles>`
* :ref:`C++ <cpp-xref-roles>`
* :ref:`JavaScript <js-xref-roles>`
* :ref:`reStructuredText <rst-xref-roles>`
* :ref:`Python <python-xref-roles>`
.. _ref-role:
@@ -267,3 +268,48 @@ The following role creates a cross-reference to a term in a
If you use a term that's not explained in a glossary, you'll get a warning
during build.
.. _any-role:
Cross-referencing anything
--------------------------
.. rst:role:: any
.. versionadded:: 1.3
This convenience role tries to do its best to find a valid target for its
reference text.
* First, it tries standard cross-reference targets that would be referenced
by :rst:role:`doc`, :rst:role:`ref` or :rst:role:`option`.
Custom objects added to the standard domain by extensions (see
:meth:`.Sphinx.add_object_type`) are also searched.
* Then, it looks for objects (targets) in all loaded domains. It is up to
the domains how specific a match must be. For example, in the Python
domain a reference of ``:any:`Builder``` would match the
``sphinx.builders.Builder`` class.
If none or multiple targets are found, a warning will be emitted. In the
case of multiple targets, you can change "any" to a specific role.
This role is a good candidate for setting :confval:`default_role`. If you
do, you can write cross-references without a lot of markup overhead. For
example, in this Python function documentation::
.. function:: install()
This function installs a `handler` for every signal known by the
`signal` module. See the section `about-signals` for more information.
there could be references to a glossary term (usually ``:term:`handler```), a
Python module (usually ``:py:mod:`signal``` or ``:mod:`signal```) and a
section (usually ``:ref:`about-signals```).
The :rst:role:`any` role also works together with the
:mod:`~sphinx.ext.intersphinx` extension: when no local cross-reference is
found, all object types of intersphinx inventories are also searched.

View File

@@ -203,6 +203,8 @@ Two more syntaxes are supported: *CSV tables* and *List tables*. They use an
Hyperlinks
----------
.. _rst-external-links:
External links
~~~~~~~~~~~~~~