Skip to content

[singlehtml] toctree no filename with anchor #13717

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

Closed
wants to merge 6 commits into from

Conversation

gastmaier
Copy link

Purpose

Fix toctree links to page anchor in the singlehtml output.
Only matters for themes that include the right sidebar in the singlehtml page, but particularly useful for using the singlehtml to then generate a pdf (since the toctree allows fine tuning the depth of the table of contents).

On #11970, same-document links dropped the uri (filename part). On #12551, fixes to do not include the filename on hyperlinks was added. So an anchor for a:

  • doc reference: #document-my-page
  • ref reference: #my-anchor.

On #13037, fix_refuris was removed, which would blindly rmatch #.*
However, #12551 missed the toctree constructor, which was still generating:

  • #document-my-page#my-anchor

Modify _resolve_toctree() to do not include rel_uri if the is an anchorname.

Tests failing

These two tests are failing, from the immediate previous commit:

FAILED tests/test_builders/test_build_epub.py::test_nested_toc - AssertionError: assert ('navPoint5',...o-1', 'foo.1') == ('navPoint5',...o-1', 'foo.1')
FAILED tests/test_builders/test_build_epub.py::test_escaped_toc - AssertionError: assert ('navPoint5',...1', 'foo “1”') == ('navPoint5',...1', 'foo “1”')

It may be necessary to make the code specific to when the builder is singlehtml.

References

gastmaier added 6 commits July 5, 2025 18:10
On sphinx-doc#11970, same-document links dropped the uri (filename part).
On sphinx-doc#12551, fixes to do not include the filename on hyperlinks was added.
So an anchor for a:
* doc reference: #document-my-page
* ref reference: #my-anchor.
On sphinx-doc#13037, fix_refuris was removed, which would blindly rmatch #.* .
However, sphinx-doc#12551 missed the toctree constructor, which was still
generating:
* #document-my-page#my-anchor.
Modify _resolve_toctree() to do not include rel_uri if the is an
anchorname.
The toctree for anchors do not contain the uri (filename) anymore.
The toctree for anchors do not contain the uri (filename) anymore.
@gastmaier
Copy link
Author

gastmaier commented Jul 7, 2025

Changed the approach to only affect singlehtml.
since the original approach would break toctrees that include anchor and are multi file (e.g. html):

toctree_html = context["toctree"](
    collapse=False,
    titles_only=False,
    maxdepth=-1,
    includehidden=True,
)

It may be worth considering that after all, having the filename in the anchor #document-<filename>, may be more consistent with other single file builders (epub, ...?)

pinging @jayaddison for insight

@AA-Turner
Copy link
Member

@gastmaier sorry for the delay in initial review. Please could you add a CHANGES entry and a test? Hopefully one of us will have time for a detailed review in the near future.

A

@gastmaier
Copy link
Author

My issue with my solution is that it doesn't resolve the cross-doc id collision, since id collision is resolved only per doc and not across doc.
The LaTeX builder solves it by having the sphinx/writers/latex.py#hypertarget[withdoc=True] method, where is suffixes the docutils id with the docname.
I believe doing the same for singlehtml would be better,
so a #id1 anchor becomes #document-path/to/doc/index#id1 (1)
but I am struggling to implement, at the writers/html5 stage.

Maybe it just needs its own spin of hypertarget at the exact locations as the latex writer, but I will revisit it later.

(1) These are valid HTML anchors, but but require escaping when manipulating with:
css

#document-test\/extra\#test {color: #f00;}

and javascript

document.querySelector('#document-test\\/extra\\#test')

@gastmaier gastmaier closed this Jul 20, 2025
@AA-Turner AA-Turner added the sprint For work completed at a conference or similar event. label Jul 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sprint For work completed at a conference or similar event.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants