mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add `sphinx.util.index_entries
` (#11528)
This commit is contained in:
parent
fca33a203d
commit
c9f0e67cca
2
CHANGES
2
CHANGES
@ -16,6 +16,8 @@ Deprecated
|
||||
Use ``hashlib`` instead.
|
||||
* #11526: Deprecate ``sphinx.testing.path``.
|
||||
Use ``os.path`` or ``pathlib`` instead.
|
||||
* #11528: Deprecate ``sphinx.util.split_index_msg`` and ``sphinx.util.split_into``.
|
||||
Use ``sphinx.util.index_entries.split_index_msg`` instead.
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
@ -22,6 +22,16 @@ The following is a list of deprecated interfaces.
|
||||
- Removed
|
||||
- Alternatives
|
||||
|
||||
* - ``sphinx.util.split_into``
|
||||
- 7.2
|
||||
- 9.0
|
||||
- N/A
|
||||
|
||||
* - ``sphinx.util.split_index_msg``
|
||||
- 7.2
|
||||
- 9.0
|
||||
- ``sphinx.util.index_entries.split_index_msg``
|
||||
|
||||
* - ``sphinx.testing.path``
|
||||
- 7.2
|
||||
- 9.0
|
||||
|
@ -18,10 +18,11 @@ from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.errors import ThemeError
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging, split_index_msg
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.console import bold # type: ignore
|
||||
from sphinx.util.display import status_iterator
|
||||
from sphinx.util.i18n import CatalogInfo, docname_to_domain
|
||||
from sphinx.util.index_entries import split_index_msg
|
||||
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
||||
from sphinx.util.osutil import canon_path, ensuredir, relpath
|
||||
from sphinx.util.tags import Tags
|
||||
|
@ -11,8 +11,9 @@ from docutils.parsers.rst import directives
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains import Domain
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.util import logging, split_index_msg
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docutils import ReferenceRole, SphinxDirective
|
||||
from sphinx.util.index_entries import split_index_msg
|
||||
from sphinx.util.nodes import process_index_entry
|
||||
from sphinx.util.typing import OptionSpec
|
||||
|
||||
|
@ -11,7 +11,8 @@ from sphinx.builders import Builder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.errors import NoUri
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import logging, split_into
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.index_entries import _split_into
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -41,20 +42,20 @@ class IndexEntries:
|
||||
try:
|
||||
if entry_type == 'single':
|
||||
try:
|
||||
entry, sub_entry = split_into(2, 'single', value)
|
||||
entry, sub_entry = _split_into(2, 'single', value)
|
||||
except ValueError:
|
||||
entry, = split_into(1, 'single', value)
|
||||
entry, = _split_into(1, 'single', value)
|
||||
sub_entry = ''
|
||||
_add_entry(entry, sub_entry, main,
|
||||
dic=new, link=uri, key=category_key)
|
||||
elif entry_type == 'pair':
|
||||
first, second = split_into(2, 'pair', value)
|
||||
first, second = _split_into(2, 'pair', value)
|
||||
_add_entry(first, second, main,
|
||||
dic=new, link=uri, key=category_key)
|
||||
_add_entry(second, first, main,
|
||||
dic=new, link=uri, key=category_key)
|
||||
elif entry_type == 'triple':
|
||||
first, second, third = split_into(3, 'triple', value)
|
||||
first, second, third = _split_into(3, 'triple', value)
|
||||
_add_entry(first, second + ' ' + third, main,
|
||||
dic=new, link=uri, key=category_key)
|
||||
_add_entry(second, third + ', ' + first, main,
|
||||
@ -62,11 +63,11 @@ class IndexEntries:
|
||||
_add_entry(third, first + ' ' + second, main,
|
||||
dic=new, link=uri, key=category_key)
|
||||
elif entry_type == 'see':
|
||||
first, second = split_into(2, 'see', value)
|
||||
first, second = _split_into(2, 'see', value)
|
||||
_add_entry(first, _('see %s') % second, None,
|
||||
dic=new, link=False, key=category_key)
|
||||
elif entry_type == 'seealso':
|
||||
first, second = split_into(2, 'see', value)
|
||||
first, second = _split_into(2, 'see', value)
|
||||
_add_entry(first, _('see also %s') % second, None,
|
||||
dic=new, link=False, key=category_key)
|
||||
else:
|
||||
|
@ -16,7 +16,7 @@ from docutils.nodes import Element, Node
|
||||
|
||||
from sphinx import addnodes, package_dir
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.util import split_index_msg
|
||||
from sphinx.util.index_entries import split_index_msg
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterable
|
||||
|
@ -18,8 +18,9 @@ from sphinx.errors import ConfigError
|
||||
from sphinx.locale import __
|
||||
from sphinx.locale import init as init_locale
|
||||
from sphinx.transforms import SphinxTransform
|
||||
from sphinx.util import get_filetype, logging, split_index_msg
|
||||
from sphinx.util import get_filetype, logging
|
||||
from sphinx.util.i18n import docname_to_domain
|
||||
from sphinx.util.index_entries import split_index_msg
|
||||
from sphinx.util.nodes import (
|
||||
IMAGE_TYPE_NODES,
|
||||
LITERAL_TYPE_NODES,
|
||||
|
@ -16,6 +16,7 @@ from sphinx.locale import __
|
||||
from sphinx.util import display as _display
|
||||
from sphinx.util import exceptions as _exceptions
|
||||
from sphinx.util import http_date as _http_date
|
||||
from sphinx.util import index_entries as _index_entries
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import osutil as _osutil
|
||||
from sphinx.util.console import strip_colors # NoQA: F401
|
||||
@ -220,30 +221,6 @@ def parselinenos(spec: str, total: int) -> list[int]:
|
||||
return items
|
||||
|
||||
|
||||
def split_into(n: int, type: str, value: str) -> list[str]:
|
||||
"""Split an index entry into a given number of parts at semicolons."""
|
||||
parts = [x.strip() for x in value.split(';', n - 1)]
|
||||
if len(list(filter(None, parts))) < n:
|
||||
raise ValueError(f'invalid {type} index entry {value!r}')
|
||||
return parts
|
||||
|
||||
|
||||
def split_index_msg(entry_type: str, value: str) -> list[str]:
|
||||
# new entry types must be listed in util/nodes.py!
|
||||
if entry_type == 'single':
|
||||
try:
|
||||
return split_into(2, 'single', value)
|
||||
except ValueError:
|
||||
return split_into(1, 'single', value)
|
||||
if entry_type == 'pair':
|
||||
return split_into(2, 'pair', value)
|
||||
if entry_type == 'triple':
|
||||
return split_into(3, 'triple', value)
|
||||
if entry_type in {'see', 'seealso'}:
|
||||
return split_into(2, 'see', value)
|
||||
raise ValueError(f'invalid {entry_type} index entry {value!r}')
|
||||
|
||||
|
||||
def import_object(objname: str, source: str | None = None) -> Any:
|
||||
"""Import python object by qualname."""
|
||||
try:
|
||||
@ -300,6 +277,9 @@ _DEPRECATED_OBJECTS = {
|
||||
'format_exception_cut_frames': (_exceptions.format_exception_cut_frames,
|
||||
'sphinx.exceptions.format_exception_cut_frames'),
|
||||
'xmlname_checker': (_xml_name_checker, 'sphinx.builders.epub3._XML_NAME_PATTERN'),
|
||||
'split_index_msg': (_index_entries.split_index_msg,
|
||||
'sphinx.util.index_entries.split_index_msg'),
|
||||
'split_into': (_index_entries.split_index_msg, 'sphinx.util.index_entries.split_into'),
|
||||
'md5': (_md5, ''),
|
||||
'sha1': (_sha1, ''),
|
||||
}
|
||||
|
25
sphinx/util/index_entries.py
Normal file
25
sphinx/util/index_entries.py
Normal file
@ -0,0 +1,25 @@
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def split_index_msg(entry_type: str, value: str) -> list[str]:
|
||||
# new entry types must be listed in util/nodes.py!
|
||||
if entry_type == 'single':
|
||||
try:
|
||||
return _split_into(2, 'single', value)
|
||||
except ValueError:
|
||||
return _split_into(1, 'single', value)
|
||||
if entry_type == 'pair':
|
||||
return _split_into(2, 'pair', value)
|
||||
if entry_type == 'triple':
|
||||
return _split_into(3, 'triple', value)
|
||||
if entry_type in {'see', 'seealso'}:
|
||||
return _split_into(2, 'see', value)
|
||||
raise ValueError(f'invalid {entry_type} index entry {value!r}')
|
||||
|
||||
|
||||
def _split_into(n: int, type: str, value: str) -> list[str]:
|
||||
"""Split an index entry into a given number of parts at semicolons."""
|
||||
parts = [x.strip() for x in value.split(';', n - 1)]
|
||||
if len(list(filter(None, parts))) < n:
|
||||
raise ValueError(f'invalid {type} index entry {value!r}')
|
||||
return parts
|
@ -20,8 +20,9 @@ from sphinx.domains import IndexEntry
|
||||
from sphinx.domains.std import StandardDomain
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import _, __, admonitionlabels
|
||||
from sphinx.util import logging, split_into, texescape
|
||||
from sphinx.util import logging, texescape
|
||||
from sphinx.util.docutils import SphinxTranslator
|
||||
from sphinx.util.index_entries import split_index_msg
|
||||
from sphinx.util.nodes import clean_astext, get_prev_node
|
||||
from sphinx.util.template import LaTeXRenderer
|
||||
from sphinx.util.texescape import tex_replace_map
|
||||
@ -1688,37 +1689,32 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if ismain:
|
||||
m = '|spxpagem'
|
||||
try:
|
||||
parts = tuple(map(escape, split_index_msg(type, string)))
|
||||
styled = tuple(map(style, parts))
|
||||
if type == 'single':
|
||||
try:
|
||||
p1, p2 = (escape(x) for x in split_into(2, 'single', string))
|
||||
P1, P2 = style(p1), style(p2)
|
||||
p1, p2 = parts
|
||||
P1, P2 = styled
|
||||
self.body.append(fr'\index{{{p1}@{P1}!{p2}@{P2}{m}}}')
|
||||
except ValueError:
|
||||
p = escape(split_into(1, 'single', string)[0])
|
||||
P = style(p)
|
||||
p, = parts
|
||||
P, = styled
|
||||
self.body.append(fr'\index{{{p}@{P}{m}}}')
|
||||
elif type == 'pair':
|
||||
p1, p2 = (escape(x) for x in split_into(2, 'pair', string))
|
||||
P1, P2 = style(p1), style(p2)
|
||||
self.body.append(r'\index{%s@%s!%s@%s%s}\index{%s@%s!%s@%s%s}' %
|
||||
(p1, P1, p2, P2, m, p2, P2, p1, P1, m))
|
||||
p1, p2 = parts
|
||||
P1, P2 = styled
|
||||
self.body.append(fr'\index{{{p1}@{P1}!{p2}@{P2}{m}}}'
|
||||
fr'\index{{{p2}@{P2}!{p1}@{P1}{m}}}')
|
||||
elif type == 'triple':
|
||||
p1, p2, p3 = (escape(x) for x in split_into(3, 'triple', string))
|
||||
P1, P2, P3 = style(p1), style(p2), style(p3)
|
||||
p1, p2, p3 = parts
|
||||
P1, P2, P3 = styled
|
||||
self.body.append(
|
||||
r'\index{%s@%s!%s %s@%s %s%s}'
|
||||
r'\index{%s@%s!%s, %s@%s, %s%s}'
|
||||
r'\index{%s@%s!%s %s@%s %s%s}' %
|
||||
(p1, P1, p2, p3, P2, P3, m,
|
||||
p2, P2, p3, p1, P3, P1, m,
|
||||
p3, P3, p1, p2, P1, P2, m))
|
||||
elif type == 'see':
|
||||
p1, p2 = (escape(x) for x in split_into(2, 'see', string))
|
||||
P1 = style(p1)
|
||||
self.body.append(fr'\index{{{p1}@{P1}|see{{{p2}}}}}')
|
||||
elif type == 'seealso':
|
||||
p1, p2 = (escape(x) for x in split_into(2, 'seealso', string))
|
||||
P1 = style(p1)
|
||||
fr'\index{{{p1}@{P1}!{p2} {p3}@{P2} {P3}{m}}}'
|
||||
fr'\index{{{p2}@{P2}!{p3}, {p1}@{P3}, {P1}{m}}}'
|
||||
fr'\index{{{p3}@{P3}!{p1} {p2}@{P1} {P2}{m}}}')
|
||||
elif type in {'see', 'seealso'}:
|
||||
p1, p2 = parts
|
||||
P1, _P2 = styled
|
||||
self.body.append(fr'\index{{{p1}@{P1}|see{{{p2}}}}}')
|
||||
else:
|
||||
logger.warning(__('unknown index entry type %s found'), type)
|
||||
|
Loading…
Reference in New Issue
Block a user