sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.43k stars 2.1k forks source link

C++, surprising cross-references in substitutions #5077

Open other-mickk opened 6 years ago

other-mickk commented 6 years ago

Cross-references inside substitutions seemingly do not resolve at the point of substitution:

.. |subst| replace:: :any:`item`

.. cpp:type:: item

.. cpp:concept:: template<typename item> demo

    Direct reference: :any:`item`.

    Reference in substitution: |subst|.

In this example the direct reference resolves to the template parameter as expected, whereas the reference in the substitution resolves to the cpp:type item.

It's the same if the substitution definition appears e.g. at the end of the document. However, if the substitution is defined in the demo directive then it resolves to that directive's parameter. It's not really a workaround for my case: I use e.g. |underlying_type_t| substitutions short for :texpr:`underlying_type_t<Param>` across multiple items which each have their own Param.

edit: ping @jakobandersen

jakobandersen commented 4 years ago

I think this issue is affecting all domains, and in general everything that uses env.ref_context may have problems. If I understand correctly, then substitution is happening after the complete parsing, so what is substituted is really doctrees, using a transform (https://docutils.sourceforge.io/docs/ref/transforms.html). One way to fix it may be to hook into the substitution and then recursively replace the env.ref_context with the one set in the substitution reference. Is it correct that a substitution can only contain inline elements? Specifically, it can not contain another directive? (otherwise this gets much more complicated)

I tried to make a similar example in Python, but both xrefs points to the global scope. Not sure if this is intended:

.. |subst2| replace:: :py:func:`item`

.. py:function:: item()

.. py:class:: A

    .. py:function:: item()

        Direct reference: :py:func:`item`.

        Reference in substitution: |subst2|.