Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std domain: Generate node_id for generic objects and targets in the right way #7237

Merged
merged 2 commits into from Mar 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 39 additions & 10 deletions sphinx/domains/std.py
Expand Up @@ -66,9 +66,17 @@ def handle_signature(self, sig: str, signode: desc_signature) -> str:
return name

def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
targetname = '%s-%s' % (self.objtype, name)
signode['ids'].append(targetname)
node_id = make_id(self.env, self.state.document, self.objtype, name)
signode['ids'].append(node_id)

# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(name)
if old_node_id not in self.state.document.ids and old_node_id not in signode['ids']:
signode['ids'].append(old_node_id)

self.state.document.note_explicit_target(signode)

if self.indextemplate:
colon = self.indextemplate.find(':')
if colon != -1:
Expand All @@ -77,11 +85,18 @@ def add_target_and_index(self, name: str, sig: str, signode: desc_signature) ->
else:
indextype = 'single'
indexentry = self.indextemplate % (name,)
self.indexnode['entries'].append((indextype, indexentry,
targetname, '', None))
self.indexnode['entries'].append((indextype, indexentry, node_id, '', None))

std = cast(StandardDomain, self.env.get_domain('std'))
std.note_object(self.objtype, name, targetname, location=signode)
std.note_object(self.objtype, name, node_id, location=signode)

def make_old_id(self, name: str) -> str:
"""Generate old styled node_id for generic objects.

.. note:: Old Styled node_id was used until Sphinx-3.0.
This will be removed in Sphinx-5.0.
"""
return self.objtype + '-' + name


class EnvVar(GenericObject):
Expand Down Expand Up @@ -124,9 +139,16 @@ class Target(SphinxDirective):
def run(self) -> List[Node]:
# normalize whitespace in fullname like XRefRole does
fullname = ws_re.sub(' ', self.arguments[0].strip())
targetname = '%s-%s' % (self.name, fullname)
node = nodes.target('', '', ids=[targetname])
node_id = make_id(self.env, self.state.document, self.name, fullname)
node = nodes.target('', '', ids=[node_id])
self.set_source_info(node)

# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(fullname)
if old_node_id not in self.state.document.ids and old_node_id not in node['ids']:
node['ids'].append(old_node_id)

self.state.document.note_explicit_target(node)
ret = [node] # type: List[Node]
if self.indextemplate:
Expand All @@ -136,18 +158,25 @@ def run(self) -> List[Node]:
if colon != -1:
indextype = indexentry[:colon].strip()
indexentry = indexentry[colon + 1:].strip()
inode = addnodes.index(entries=[(indextype, indexentry,
targetname, '', None)])
inode = addnodes.index(entries=[(indextype, indexentry, node_id, '', None)])
ret.insert(0, inode)
name = self.name
if ':' in self.name:
_, name = self.name.split(':', 1)

std = cast(StandardDomain, self.env.get_domain('std'))
std.note_object(name, fullname, targetname, location=node)
std.note_object(name, fullname, node_id, location=node)

return ret

def make_old_id(self, name: str) -> str:
"""Generate old styled node_id for targets.

.. note:: Old Styled node_id was used until Sphinx-3.0.
This will be removed in Sphinx-5.0.
"""
return self.name + '-' + name


class Cmdoption(ObjectDescription):
"""
Expand Down
10 changes: 7 additions & 3 deletions tests/test_build_epub.py
Expand Up @@ -320,9 +320,13 @@ def test_epub_anchor_id(app):
app.build()

html = (app.outdir / 'index.xhtml').read_text()
assert '<p id="std-setting-STATICFILES_FINDERS">blah blah blah</p>' in html
assert '<span id="std-setting-STATICFILES_SECTION"></span><h1>blah blah blah</h1>' in html
assert 'see <a class="reference internal" href="#std-setting-STATICFILES_FINDERS">' in html
assert ('<p id="std-setting-staticfiles-finders">'
'<span id="std-setting-STATICFILES_FINDERS"></span>'
'blah blah blah</p>' in html)
assert ('<span id="std-setting-staticfiles-section"></span>'
'<span id="std-setting-STATICFILES_SECTION"></span>'
'<h1>blah blah blah</h1>' in html)
assert 'see <a class="reference internal" href="#std-setting-staticfiles-finders">' in html


@pytest.mark.sphinx('epub', testroot='html_assets')
Expand Down
2 changes: 1 addition & 1 deletion tests/test_build_html.py
Expand Up @@ -218,7 +218,7 @@ def test_html4_output(app, status, warning):
"[@class='rfc reference external']/strong", 'RFC 1'),
(".//a[@href='https://tools.ietf.org/html/rfc1.html']"
"[@class='rfc reference external']/strong", 'Request for Comments #1'),
(".//a[@href='objects.html#envvar-HOME']"
(".//a[@href='objects.html#envvar-home']"
"[@class='reference internal']/code/span[@class='pre']", 'HOME'),
(".//a[@href='#with']"
"[@class='reference internal']/code/span[@class='pre']", '^with$'),
Expand Down