Skip to content

Commit f9b3355

Browse files
committed
Split Index{Entry}
1 parent d56cf30 commit f9b3355

File tree

3 files changed

+133
-113
lines changed

3 files changed

+133
-113
lines changed

sphinx/domains/__init__.py

Lines changed: 13 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,31 @@
77
from __future__ import annotations
88

99
import copy
10-
from abc import ABC, abstractmethod
11-
from collections.abc import Callable
12-
from typing import TYPE_CHECKING, Any, NamedTuple, cast
10+
from typing import TYPE_CHECKING, Any, cast
1311

14-
from docutils.nodes import Element, Node, system_message
15-
16-
from sphinx.errors import SphinxError
12+
from sphinx.domains._index import Index, IndexEntry
1713
from sphinx.locale import _
1814

1915
if TYPE_CHECKING:
20-
from collections.abc import Iterable, Sequence
21-
from typing import TypeAlias
16+
from collections.abc import Callable, Iterable, Sequence
2217

2318
from docutils import nodes
19+
from docutils.nodes import Element, Node
2420
from docutils.parsers.rst import Directive
2521
from docutils.parsers.rst.states import Inliner
2622

2723
from sphinx.addnodes import pending_xref
2824
from sphinx.builders import Builder
2925
from sphinx.environment import BuildEnvironment
3026
from sphinx.roles import XRefRole
31-
from sphinx.util.typing import RoleFunction
27+
from sphinx.util.typing import RoleFunction, TitleGetter
28+
29+
__all__ = (
30+
'Domain',
31+
'Index',
32+
'IndexEntry',
33+
'ObjType',
34+
)
3235

3336

3437
class ObjType:
@@ -57,107 +60,6 @@ def __init__(self, lname: str, *roles: Any, **attrs: Any) -> None:
5760
self.attrs.update(attrs)
5861

5962

60-
class IndexEntry(NamedTuple):
61-
name: str
62-
subtype: int
63-
docname: str
64-
anchor: str
65-
extra: str
66-
qualifier: str
67-
descr: str
68-
69-
70-
class Index(ABC):
71-
"""
72-
An Index is the description for a domain-specific index. To add an index to
73-
a domain, subclass Index, overriding the three name attributes:
74-
75-
* `name` is an identifier used for generating file names.
76-
It is also used for a hyperlink target for the index. Therefore, users can
77-
refer the index page using ``ref`` role and a string which is combined
78-
domain name and ``name`` attribute (ex. ``:ref:`py-modindex```).
79-
* `localname` is the section title for the index.
80-
* `shortname` is a short name for the index, for use in the relation bar in
81-
HTML output. Can be empty to disable entries in the relation bar.
82-
83-
and providing a :meth:`generate()` method. Then, add the index class to
84-
your domain's `indices` list. Extensions can add indices to existing
85-
domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`.
86-
87-
.. versionchanged:: 3.0
88-
89-
Index pages can be referred by domain name and index name via
90-
:rst:role:`ref` role.
91-
"""
92-
93-
name: str
94-
localname: str
95-
shortname: str | None = None
96-
97-
def __init__(self, domain: Domain) -> None:
98-
if not self.name or self.localname is None:
99-
raise SphinxError('Index subclass %s has no valid name or localname'
100-
% self.__class__.__name__)
101-
self.domain = domain
102-
103-
@abstractmethod
104-
def generate(self, docnames: Iterable[str] | None = None,
105-
) -> tuple[list[tuple[str, list[IndexEntry]]], bool]:
106-
"""Get entries for the index.
107-
108-
If ``docnames`` is given, restrict to entries referring to these
109-
docnames.
110-
111-
The return value is a tuple of ``(content, collapse)``:
112-
113-
``collapse``
114-
A boolean that determines if sub-entries should start collapsed (for
115-
output formats that support collapsing sub-entries).
116-
117-
``content``:
118-
A sequence of ``(letter, entries)`` tuples, where ``letter`` is the
119-
"heading" for the given ``entries``, usually the starting letter, and
120-
``entries`` is a sequence of single entries. Each entry is a sequence
121-
``[name, subtype, docname, anchor, extra, qualifier, descr]``. The
122-
items in this sequence have the following meaning:
123-
124-
``name``
125-
The name of the index entry to be displayed.
126-
127-
``subtype``
128-
The sub-entry related type. One of:
129-
130-
``0``
131-
A normal entry.
132-
``1``
133-
An entry with sub-entries.
134-
``2``
135-
A sub-entry.
136-
137-
``docname``
138-
*docname* where the entry is located.
139-
140-
``anchor``
141-
Anchor for the entry within ``docname``
142-
143-
``extra``
144-
Extra info for the entry.
145-
146-
``qualifier``
147-
Qualifier for the description.
148-
149-
``descr``
150-
Description for the entry.
151-
152-
Qualifier and description are not rendered for some output formats such
153-
as LaTeX.
154-
"""
155-
raise NotImplementedError
156-
157-
158-
TitleGetter: TypeAlias = Callable[[Node], str | None]
159-
160-
16163
class Domain:
16264
"""
16365
A Domain is meant to be a group of "object" description directives for
@@ -268,7 +170,7 @@ def role(self, name: str) -> RoleFunction | None:
268170
def role_adapter(typ: str, rawtext: str, text: str, lineno: int,
269171
inliner: Inliner, options: dict | None = None,
270172
content: Sequence[str] = (),
271-
) -> tuple[list[Node], list[system_message]]:
173+
) -> tuple[list[Node], list[nodes.system_message]]:
272174
return self.roles[name](fullname, rawtext, text, lineno,
273175
inliner, options or {}, content)
274176
self._role_cache[name] = role_adapter

sphinx/domains/_index.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
"""Domain indices."""
2+
3+
from __future__ import annotations
4+
5+
from abc import ABC, abstractmethod
6+
from typing import TYPE_CHECKING, NamedTuple
7+
8+
from sphinx.errors import SphinxError
9+
10+
if TYPE_CHECKING:
11+
from collections.abc import Iterable
12+
13+
from sphinx.domains import Domain
14+
15+
16+
class IndexEntry(NamedTuple):
17+
name: str
18+
subtype: int
19+
docname: str
20+
anchor: str
21+
extra: str
22+
qualifier: str
23+
descr: str
24+
25+
26+
class Index(ABC):
27+
"""
28+
An Index is the description for a domain-specific index. To add an index to
29+
a domain, subclass Index, overriding the three name attributes:
30+
31+
* `name` is an identifier used for generating file names.
32+
It is also used for a hyperlink target for the index. Therefore, users can
33+
refer the index page using ``ref`` role and a string which is combined
34+
domain name and ``name`` attribute (ex. ``:ref:`py-modindex```).
35+
* `localname` is the section title for the index.
36+
* `shortname` is a short name for the index, for use in the relation bar in
37+
HTML output. Can be empty to disable entries in the relation bar.
38+
39+
and providing a :meth:`generate()` method. Then, add the index class to
40+
your domain's `indices` list. Extensions can add indices to existing
41+
domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`.
42+
43+
.. versionchanged:: 3.0
44+
45+
Index pages can be referred by domain name and index name via
46+
:rst:role:`ref` role.
47+
"""
48+
49+
name: str
50+
localname: str
51+
shortname: str | None = None
52+
53+
def __init__(self, domain: Domain) -> None:
54+
if not self.name or self.localname is None:
55+
msg = f'Index subclass {self.__class__.__name__} has no valid name or localname'
56+
raise SphinxError(msg)
57+
self.domain = domain
58+
59+
@abstractmethod
60+
def generate(
61+
self,
62+
docnames: Iterable[str] | None = None,
63+
) -> tuple[list[tuple[str, list[IndexEntry]]], bool]:
64+
"""Get entries for the index.
65+
66+
If ``docnames`` is given, restrict to entries referring to these
67+
docnames.
68+
69+
The return value is a tuple of ``(content, collapse)``:
70+
71+
``collapse``
72+
A boolean that determines if sub-entries should start collapsed (for
73+
output formats that support collapsing sub-entries).
74+
75+
``content``:
76+
A sequence of ``(letter, entries)`` tuples, where ``letter`` is the
77+
"heading" for the given ``entries``, usually the starting letter, and
78+
``entries`` is a sequence of single entries. Each entry is a sequence
79+
``[name, subtype, docname, anchor, extra, qualifier, descr]``. The
80+
items in this sequence have the following meaning:
81+
82+
``name``
83+
The name of the index entry to be displayed.
84+
85+
``subtype``
86+
The sub-entry related type. One of:
87+
88+
``0``
89+
A normal entry.
90+
``1``
91+
An entry with sub-entries.
92+
``2``
93+
A sub-entry.
94+
95+
``docname``
96+
*docname* where the entry is located.
97+
98+
``anchor``
99+
Anchor for the entry within ``docname``
100+
101+
``extra``
102+
Extra info for the entry.
103+
104+
``qualifier``
105+
Qualifier for the description.
106+
107+
``descr``
108+
Description for the entry.
109+
110+
Qualifier and description are not rendered for some output formats such
111+
as LaTeX.
112+
"""
113+
raise NotImplementedError

sphinx/domains/std/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from sphinx import addnodes
1515
from sphinx.addnodes import desc_signature, pending_xref
1616
from sphinx.directives import ObjectDescription
17-
from sphinx.domains import Domain, ObjType, TitleGetter
17+
from sphinx.domains import Domain, ObjType
1818
from sphinx.locale import _, __
1919
from sphinx.roles import EmphasizedLiteral, XRefRole
2020
from sphinx.util import docname_join, logging, ws_re
@@ -28,7 +28,12 @@
2828
from sphinx.application import Sphinx
2929
from sphinx.builders import Builder
3030
from sphinx.environment import BuildEnvironment
31-
from sphinx.util.typing import ExtensionMetadata, OptionSpec, RoleFunction
31+
from sphinx.util.typing import (
32+
ExtensionMetadata,
33+
OptionSpec,
34+
RoleFunction,
35+
TitleGetter,
36+
)
3237

3338
logger = logging.getLogger(__name__)
3439

0 commit comments

Comments
 (0)