Skip to content

Keep the signature anchor when :noindex: is set - #112

Open
ggiesen wants to merge 2 commits into
sphinx-contrib:mainfrom
ggiesen:noindex-keep-anchor
Open

Keep the signature anchor when :noindex: is set#112
ggiesen wants to merge 2 commits into
sphinx-contrib:mainfrom
ggiesen:noindex-keep-anchor

Conversation

@ggiesen

@ggiesen ggiesen commented Jul 6, 2026

Copy link
Copy Markdown

Fixes #111.

add_target_and_index() already expresses the intended split - the per-page anchor is appended unconditionally and only the global route registration is gated behind :noindex: - but ObjectDescription.run() skips the whole method when the option is set (at least since Sphinx 2.4.5), so the anchor and the HTML permalink were dropped along with the registration.

Handle the option in HTTPResource.run() instead: record it, pop it before running the base class (so add_target_and_index() is called), keep the anchor, and gate only the registration. The informational noindex/no-index attributes on the desc node are preserved. On Sphinx 7.2+ the pop also happens before the base class normalizes the legacy spelling into no-index, so behaviour is identical across the supported range.

Anchors are per-document ids, so restoring them cannot introduce collisions; only the global registration participates in merge_domaindata(), which is where duplicate routes are (order-dependently) detected in parallel builds.

Includes a build-level test covering both halves: the :noindex:'d copy of a route documented on another page keeps its post--demo anchor, and the domain data contains only the canonical page's registration. The anchor assertion fails without the fix; the registration assertion passes with and without, matching the analysis.

Validated with pytest (full suite) and sphinx-build -W -b html docs on Sphinx 8.1.3 (the locked dev version), and the new tests additionally against Sphinx 6.2.1, 7.0.1, and 7.4.7.

Real-world motivation: saltstack/salt documents overlapping routes on three pages and hit nondeterministic duplicate HTTP post method definition failures in -W -j auto CI builds (saltstack/salt#69724); :noindex: on the non-canonical copies fixes that but currently costs the anchors, which this change makes unnecessary to trade away.

ggiesen added 2 commits July 5, 2026 23:01
HTTPResource.add_target_and_index() appends the per-page anchor
unconditionally and only gates the global route registration behind
the noindex option, but ObjectDescription.run() skips the whole method
when the option is set, so the anchor (and the HTML permalink) is
dropped along with the registration and deep links into the page stop
working.

Anchors are per-document ids and cannot collide across pages; only the
global registration can produce duplicate-route warnings (which are
order-dependent in parallel builds, where merge_domaindata detects
them). Handle the option in run() instead: pop it so the base class
calls add_target_and_index(), keep the anchor, and skip only the
registration. The informational noindex attribute on the desc node is
preserved.

Tested against Sphinx 6.2.1, 7.0.1, 7.4.7 and 8.1.3.
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 sphinxcontrib-httpdomain | 🛠️ Build #33452557 | 📁 Comparing 9887536 against latest (1d96b0f)

  🔍 Preview build  

1 file changed
± index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

:noindex: also drops the signature anchor and permalink, not just the index entry

1 participant