Skip to content

Commit

Permalink
Allow case-insensitive match of label-refs through intersphinx
Browse files Browse the repository at this point in the history
Look up `:std:label:` object types case-insensitively in an intersphinx
inventory. This is needed because `ref` and `numref` references (which
both resolve to `:std:label:`) are case insensitive. They lowercase
their target under the assumption that the target name in any inventory
file is also lowercased.

That assumption holds for labels in inventory files generated by Sphinx
from `.rst` files, since it generates lowercase labels. However, other
documentation generators (such as the Julia Documenter.jl, which
also writes `objects.inv` inventory files as of version 1.3) use
mixed-case labels for section title.

With the change in this commit, if the lowercase label cannot be found
in the inventory, also try a case-insensitive match.

See sphinx-doc#12008
  • Loading branch information
goerz committed Mar 2, 2024
1 parent 9a30ca7 commit 05223e0
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
6 changes: 4 additions & 2 deletions sphinx/ext/intersphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,10 @@ def _resolve_reference_in_domain_by_target(
if target in inventory[objtype]:
# Case sensitive match, use it
data = inventory[objtype][target]
elif objtype == 'std:term':
# Check for potential case insensitive matches for terms only
elif objtype in ['std:label', 'std:term']:
# Some types require case insensitive matches:
# * 'term': https://github.com/sphinx-doc/sphinx/issues/9291
# * 'label': https://github.com/sphinx-doc/sphinx/issues/12008
target_lower = target.lower()
insensitive_matches = list(filter(lambda k: k.lower() == target_lower,
inventory[objtype].keys()))
Expand Down
10 changes: 10 additions & 0 deletions tests/test_extensions/test_ext_intersphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ def test_missing_reference_stddomain(tmp_path, app, status, warning):
rn = missing_reference(app, app.env, node, contnode)
assert rn.astext() == 'A TERM'

# label reference (normal)
node, contnode = fake_node('std', 'ref', 'The-Julia-Domain', 'The-Julia-Domain')
rn = missing_reference(app, app.env, node, contnode)
assert rn.astext() == 'The Julia Domain'

# label reference (case insensitive)
node, contnode = fake_node('std', 'ref', 'the-julia-domain', 'the-julia-domain')
rn = missing_reference(app, app.env, node, contnode)
assert rn.astext() == 'The Julia Domain'


@pytest.mark.sphinx('html', testroot='ext-intersphinx-cppdomain')
def test_missing_reference_cppdomain(tmp_path, app, status, warning):
Expand Down
1 change: 1 addition & 0 deletions tests/test_util/test_util_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
foo.bar.baz js:method 1 index.html#foo.bar.baz -
foo.bar.qux js:data 1 index.html#foo.bar.qux -
a term including:colon std:term -1 glossary.html#term-a-term-including-colon -
The-Julia-Domain std:label -1 write_inventory/#$ The Julia Domain
''')

inventory_v2_not_having_version = b'''\
Expand Down

0 comments on commit 05223e0

Please sign in to comment.