Skip to content

fix: Don't compute relative URLs of already relative ones #15

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

Merged
merged 1 commit into from
Mar 6, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/flake8.ini
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ ignore =
WPS326
# explicit string concatenation
WPS336
# methods order in class
WPS338
# raw strings
WPS360
# noqa overuse
Expand Down
43 changes: 24 additions & 19 deletions src/mkdocs_autorefs/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import functools
import logging
from typing import Callable, Dict, Optional, Sequence
from urllib.parse import urlsplit

from mkdocs.config import Config
from mkdocs.plugins import BasePlugin
Expand Down Expand Up @@ -68,6 +69,25 @@ def register_url(self, identifier: str, url: str):
"""
self._abs_url_map[identifier] = url

def _get_item_url( # noqa: WPS234
self,
identifier: str,
fallback: Optional[Callable[[str], Sequence[str]]] = None,
) -> str:
try:
return self._url_map[identifier]
except KeyError:
if identifier in self._abs_url_map:
return self._abs_url_map[identifier]
if fallback:
new_identifiers = fallback(identifier)
for new_identifier in new_identifiers:
with contextlib.suppress(KeyError):
url = self._get_item_url(new_identifier)
self._url_map[identifier] = url
return url
raise

def get_item_url( # noqa: WPS234
self,
identifier: str,
Expand All @@ -83,27 +103,12 @@ def get_item_url( # noqa: WPS234

Returns:
A site-relative URL.

Raises:
KeyError: If there isn't an item by this identifier anywhere on the site.
"""
try:
url = self._url_map[identifier]
except KeyError:
if identifier in self._abs_url_map:
return self._abs_url_map[identifier]

if fallback:
new_identifiers = fallback(identifier)
for new_identifier in new_identifiers:
with contextlib.suppress(KeyError):
url = self.get_item_url(new_identifier, from_url)
self._url_map[identifier] = url # update the map to avoid doing all this again
return url
raise

url = self._get_item_url(identifier, fallback)
if from_url is not None:
return relative_url(from_url, url)
parsed = urlsplit(url)
if not parsed.scheme and not parsed.netloc:
return relative_url(from_url, url)
return url

def on_config(self, config: Config, **kwargs) -> Config: # noqa: W0613,R0201 (unused arguments, cannot be static)
Expand Down
12 changes: 12 additions & 0 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,15 @@ def test_url_registration_with_fallback():
plugin.get_item_url("foobar", fallback=lambda _: ("baaaa",))
with pytest.raises(KeyError):
plugin.get_item_url("foobar", fallback=lambda _: ())


def test_dont_make_relative_urls_relative_again():
"""Check that URLs are not made relative more than once."""
plugin = AutorefsPlugin()
plugin.register_anchor(identifier="foo.bar.baz", page="foo/bar/baz.html")

for _ in range(2):
assert (
plugin.get_item_url("hello", from_url="baz/bar/foo.html", fallback=lambda _: ("foo.bar.baz",))
== "../../foo/bar/baz.html#foo.bar.baz"
)