Skip to content

Commit 0d2b411

Browse files
authored
refactor: Support fallback method returning multiple identifiers
Issue #11: #11 PR #12: #12 PR mkdocstrings#350: mkdocstrings/mkdocstrings#350
1 parent 76fc551 commit 0d2b411

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

src/mkdocs_autorefs/plugin.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
and fixes them using the previously stored identifier-URL mapping.
1111
"""
1212

13+
import contextlib
1314
import functools
1415
import logging
15-
from typing import Callable, Dict, Optional
16+
from typing import Callable, Dict, Optional, Sequence
1617

1718
from mkdocs.config import Config
1819
from mkdocs.plugins import BasePlugin
@@ -68,14 +69,14 @@ def register_url(self, identifier: str, url: str):
6869
self._abs_url_map[identifier] = url
6970

7071
def get_item_url(
71-
self, identifier: str, from_url: Optional[str] = None, fallback: Optional[Callable[[str], Optional[str]]] = None
72+
self, identifier: str, from_url: Optional[str] = None, fallback: Optional[Callable[[str], Sequence[str]]] = None
7273
) -> str:
7374
"""Return a site-relative URL with anchor to the identifier, if it's present anywhere.
7475
7576
Arguments:
7677
identifier: The anchor (without '#').
7778
from_url: The URL of the base page, from which we link towards the targeted pages.
78-
fallback: An optional function to suggest an alternative anchor to try on failure.
79+
fallback: An optional function to suggest alternative anchors to try on failure.
7980
8081
Returns:
8182
A site-relative URL.
@@ -90,10 +91,12 @@ def get_item_url(
9091
return self._abs_url_map[identifier]
9192

9293
if fallback:
93-
new_identifier = fallback(identifier)
94-
if new_identifier:
95-
return self.get_item_url(new_identifier, from_url)
96-
94+
new_identifiers = fallback(identifier)
95+
for new_identifier in new_identifiers:
96+
with contextlib.suppress(KeyError):
97+
url = self.get_item_url(new_identifier, from_url)
98+
self._url_map[identifier] = url # update the map to avoid doing all this again
99+
return url
97100
raise
98101

99102
if from_url is not None:

tests/test_plugin.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ def test_url_registration_with_fallback():
3434
plugin.register_anchor(identifier="foo", page="foo1.html")
3535
plugin.register_url(identifier="bar", url="https://example.org/bar.html")
3636

37-
assert plugin.get_item_url("baz", fallback=lambda s: "foo") == "foo1.html#foo"
38-
assert plugin.get_item_url("baz", fallback=lambda s: "bar") == "https://example.org/bar.html"
37+
# URL map will be updated with baz -> foo1.html#foo
38+
assert plugin.get_item_url("baz", fallback=lambda s: ("foo",)) == "foo1.html#foo"
39+
# as expected, baz is now known as foo1.html#foo
40+
assert plugin.get_item_url("baz", fallback=lambda s: ("bar",)) == "foo1.html#foo"
41+
# unknown identifiers correctly fallback: qux -> https://example.org/bar.html
42+
assert plugin.get_item_url("qux", fallback=lambda s: ("bar",)) == "https://example.org/bar.html"
43+
3944
with pytest.raises(KeyError):
40-
plugin.get_item_url("baz", fallback=lambda s: "baaaa")
45+
plugin.get_item_url("foobar", fallback=lambda s: ("baaaa",))
4146
with pytest.raises(KeyError):
42-
plugin.get_item_url("baz", fallback=lambda s: None)
47+
plugin.get_item_url("foobar", fallback=lambda s: ())

0 commit comments

Comments
 (0)