Fixed link building#133
Conversation
patdhlk
left a comment
There was a problem hiding this comment.
@patrick-sil I left a few comments in the files.
Concept is right, needs another pass. Thanks for the contribution.
And one more thing that can be done in a follow up: Taking the last # fragment is a blunt instrument. The bug is that Sphinx singlehtml emits #document-path#real-anchor. You know the shape of the bad input. It'd be more precise to strip a #document-* prefix rather than blindly taking the rightmost #. Right now if someone has a legitimate # in a fragment identifier (unlikely but not impossible), this silently eats it.
| """ | ||
| Fixes a link that refers to a sub-headline. | ||
|
|
||
| For instance the broken link: | ||
| #headline#sub-headline#sub-sub-headline | ||
| Will be fixed to: | ||
| #sub-sub-headline | ||
|
|
||
| If the link is not a sub-headline, the link isn't modified | ||
|
|
||
| Args: | ||
| link_to_fix: The link to fix | ||
|
|
||
| Returns: If no modification is needed, link_to_fix otherwise the fixed link | ||
| """ |
There was a problem hiding this comment.
The docstring is floating above the function — it's a bare string expression, not a docstring. Move it inside. But honestly, the function is three lines; the 14-line comment block is doing more harm than good. If you need a comment, one line is fine.
| pos = link_to_fix.rfind("#") | ||
| if pos != -1: | ||
| # In case we only find one #, this will still work as it won't affect the link | ||
| link_to_fix = link_to_fix [pos::] |
There was a problem hiding this comment.
Style nit: link_to_fix [pos::] — space before bracket, double colon. Should be link_to_fix[pos:]
But more importantly: this is doing too much work to express a simple idea. The whole function is:
def _fix_href(self, href):
"""Strip everything before the last '#'."""
i = href.rfind("#")
return href[i:] if i != -1 else href
Or even just inline it — href.rsplit("#", 1)[-1] prefixed with # gets you there in one expression.
The real problem though: you only call this on toc sidebar links. The issue report says body cross-references are also broken (:py:obj:, :ref:). Those aren't in .sphinxsidebarwrapper. So this fixes the table of contents but leaves the actual document links broken if I understand it correctly.
If you're going to fix this, fix it everywhere. Find all <a class="reference internal"> in the whole soup, not just the sidebar.
Also — the name fix_link tells me nothing. Every function in this class "fixes" something. What does this one actually do? _strip_document_prefix or _normalize_fragment would tell the next reader what's happening without reading the body.
And it should have a leading underscore. It's internal.
Happy to help :)
Hmm yes, correct. However, how would one even safely figure out where to split the string? Refer to the example here based on what the document we are building: Which only works, if the anchor is the same as the document name. With e.g. |
This PR is supposed to resolve #123
However, let me add to the description of the issue above that it also applies to internal references inside the PDF, hence, currently
:ref:or:numref:are not working for sub-headlines in any case.The suggested changes here, should fix the issue for both the HTML and the PDF.
What does my solution do:
###is present in the link, as it basically doen't modify the link in such cases)If anyone has a better solution, which I assume are possible, as I'm not all that familiar with this project, please suggest them.
It would be nice, if this could be resolved soon, thank you :)