Fix #3106: domain: Register hyperlink target for index page automatically

This commit is contained in:
Takeshi KOMIYA
2020-02-08 12:23:11 +09:00
parent 973c91bb10
commit 9db38aadfd
5 changed files with 37 additions and 1 deletions

View File

@@ -45,6 +45,7 @@ Features added
* #6830: autodoc: consider a member private if docstring contains * #6830: autodoc: consider a member private if docstring contains
``:meta private:`` in info-field-list ``:meta private:`` in info-field-list
* #6558: glossary: emit a warning for duplicated glossary entry * #6558: glossary: emit a warning for duplicated glossary entry
* #3106: domain: Register hyperlink target for index page automatically
* #6558: std domain: emit a warning for duplicated generic objects * #6558: std domain: emit a warning for duplicated generic objects
* #6830: py domain: Add new event: :event:`object-description-transform` * #6830: py domain: Add new event: :event:`object-description-transform`
* py domain: Support lambda functions in function signature * py domain: Support lambda functions in function signature

View File

@@ -122,6 +122,10 @@ all it really is is a list of tuples like ``('tomato', 'TomatoSoup', 'test',
'rec-TomatoSoup',...)``. Refer to the :doc:`domain API guide 'rec-TomatoSoup',...)``. Refer to the :doc:`domain API guide
</extdev/domainapi>` for more information on this API. </extdev/domainapi>` for more information on this API.
These index pages can be referred by combination of domain name and its
``name`` using :rst:role:`ref` role. For example, ``RecipeIndex`` can be
referred by ``:ref:`recipe-recipe```.
.. rubric:: The domain .. rubric:: The domain
A Sphinx domain is a specialized container that ties together roles, A Sphinx domain is a specialized container that ties together roles,

View File

@@ -11,6 +11,7 @@
import copy import copy
from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, Union from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, Union
from typing import cast
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node, system_message from docutils.nodes import Element, Node, system_message
@@ -70,6 +71,9 @@ class Index:
a domain, subclass Index, overriding the three name attributes: a domain, subclass Index, overriding the three name attributes:
* `name` is an identifier used for generating file names. * `name` is an identifier used for generating file names.
It is also used for a hyperlink target for the index. Therefore, users can
refer the index page using ``ref`` role and a string which is combined
domain name and ``name`` attribute (ex. ``:ref:`py-modindex```).
* `localname` is the section title for the index. * `localname` is the section title for the index.
* `shortname` is a short name for the index, for use in the relation bar in * `shortname` is a short name for the index, for use in the relation bar in
HTML output. Can be empty to disable entries in the relation bar. HTML output. Can be empty to disable entries in the relation bar.
@@ -77,6 +81,11 @@ class Index:
and providing a :meth:`generate()` method. Then, add the index class to and providing a :meth:`generate()` method. Then, add the index class to
your domain's `indices` list. Extensions can add indices to existing your domain's `indices` list. Extensions can add indices to existing
domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`. domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`.
.. versionchanged:: 3.0
Index pages can be referred by domain name and index name via
:rst:role:`ref` role.
""" """
name = None # type: str name = None # type: str
@@ -219,6 +228,17 @@ class Domain:
self.objtypes_for_role = self._role2type.get # type: Callable[[str], List[str]] self.objtypes_for_role = self._role2type.get # type: Callable[[str], List[str]]
self.role_for_objtype = self._type2role.get # type: Callable[[str], str] self.role_for_objtype = self._type2role.get # type: Callable[[str], str]
def setup(self) -> None:
"""Set up domain object."""
from sphinx.domains.std import StandardDomain
# Add special hyperlink target for index pages (ex. py-modindex)
std = cast(StandardDomain, self.env.get_domain('std'))
for index in self.indices:
if index.name and index.localname:
docname = "%s-%s" % (self.name, index.name)
std.note_hyperlink_target(docname, docname, '', index.localname)
def add_object_type(self, name: str, objtype: ObjType) -> None: def add_object_type(self, name: str, objtype: ObjType) -> None:
"""Add an object type.""" """Add an object type."""
self.object_types[name] = objtype self.object_types[name] = objtype

View File

@@ -218,6 +218,10 @@ class BuildEnvironment:
for domain in app.registry.create_domains(self): for domain in app.registry.create_domains(self):
self.domains[domain.name] = domain self.domains[domain.name] = domain
# setup domains (must do after all initialization)
for domain in self.domains.values():
domain.setup()
# initialize config # initialize config
self._update_config(app.config) self._update_config(app.config)

View File

@@ -1261,11 +1261,18 @@ def test_html_inventory(app):
with open(app.outdir / 'objects.inv', 'rb') as f: with open(app.outdir / 'objects.inv', 'rb') as f:
invdata = InventoryFile.load(f, 'https://www.google.com', os.path.join) invdata = InventoryFile.load(f, 'https://www.google.com', os.path.join)
assert set(invdata.keys()) == {'std:label', 'std:doc'} assert set(invdata.keys()) == {'std:label', 'std:doc'}
assert set(invdata['std:label'].keys()) == {'modindex', 'genindex', 'search'} assert set(invdata['std:label'].keys()) == {'modindex',
'py-modindex',
'genindex',
'search'}
assert invdata['std:label']['modindex'] == ('Python', assert invdata['std:label']['modindex'] == ('Python',
'', '',
'https://www.google.com/py-modindex.html', 'https://www.google.com/py-modindex.html',
'Module Index') 'Module Index')
assert invdata['std:label']['py-modindex'] == ('Python',
'',
'https://www.google.com/py-modindex.html',
'Python Module Index')
assert invdata['std:label']['genindex'] == ('Python', assert invdata['std:label']['genindex'] == ('Python',
'', '',
'https://www.google.com/genindex.html', 'https://www.google.com/genindex.html',