10
10
and fixes them using the previously stored identifier-URL mapping.
11
11
"""
12
12
13
+ import functools
13
14
import logging
14
15
from typing import Callable , Dict , Optional
15
16
19
20
from mkdocs .structure .toc import AnchorLink
20
21
from mkdocs .utils import warning_filter
21
22
22
- from mkdocs_autorefs .references import AutorefsExtension , fix_refs
23
+ from mkdocs_autorefs .references import AutorefsExtension , fix_refs , relative_url
23
24
24
25
log = logging .getLogger (f"mkdocs.plugins.{ __name__ } " )
25
26
log .addFilter (warning_filter )
@@ -45,22 +46,36 @@ def __init__(self) -> None:
45
46
"""Initialize the object."""
46
47
super ().__init__ ()
47
48
self ._url_map : Dict [str , str ] = {}
48
- self .get_fallback_anchor : Callable [[str ], Optional [str ]] = lambda identifier : None
49
+ self ._abs_url_map : Dict [str , str ] = {}
50
+ self .get_fallback_anchor : Optional [Callable [[str ], Optional [str ]]] = None
49
51
50
- def register_anchor (self , page : str , anchor : str ):
52
+ def register_anchor (self , page : str , identifier : str ):
51
53
"""Register that an anchor corresponding to an identifier was encountered when rendering the page.
52
54
53
55
Arguments:
54
56
page: The relative URL of the current page. Examples: `'foo/bar/'`, `'foo/index.html'`
55
- anchor : The HTML anchor (without '#') as a string.
57
+ identifier : The HTML anchor (without '#') as a string.
56
58
"""
57
- self ._url_map [anchor ] = f"{ page } #{ anchor } "
59
+ self ._url_map [identifier ] = f"{ page } #{ identifier } "
58
60
59
- def get_item_url (self , anchor : str ) -> str :
61
+ def register_url (self , identifier : str , url : str ):
62
+ """Register that the identifier should be turned into a link to this URL.
63
+
64
+ Arguments:
65
+ identifier: The new identifier.
66
+ url: The absolute URL (including anchor, if needed) where this item can be found.
67
+ """
68
+ self ._abs_url_map [identifier ] = url
69
+
70
+ def get_item_url (
71
+ self , identifier : str , from_url : Optional [str ] = None , fallback : Optional [Callable [[str ], Optional [str ]]] = None
72
+ ) -> str :
60
73
"""Return a site-relative URL with anchor to the identifier, if it's present anywhere.
61
74
62
75
Arguments:
63
- anchor: The anchor (without '#').
76
+ identifier: The anchor (without '#').
77
+ 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.
64
79
65
80
Returns:
66
81
A site-relative URL.
@@ -69,13 +84,22 @@ def get_item_url(self, anchor: str) -> str:
69
84
KeyError: If there isn't an item by this identifier anywhere on the site.
70
85
"""
71
86
try :
72
- return self ._url_map [anchor ]
87
+ url = self ._url_map [identifier ]
73
88
except KeyError :
74
- new_anchor = self .get_fallback_anchor (anchor )
75
- if new_anchor and new_anchor in self ._url_map :
76
- return self ._url_map [new_anchor ]
89
+ if identifier in self ._abs_url_map :
90
+ return self ._abs_url_map [identifier ]
91
+
92
+ if fallback :
93
+ new_identifier = fallback (identifier )
94
+ if new_identifier :
95
+ return self .get_item_url (new_identifier , from_url )
96
+
77
97
raise
78
98
99
+ if from_url is not None :
100
+ return relative_url (from_url , url )
101
+ return url
102
+
79
103
def on_config (self , config : Config , ** kwargs ) -> Config : # noqa: W0613,R0201 (unused arguments, cannot be static)
80
104
"""Instantiate our Markdown extension.
81
105
@@ -166,7 +190,8 @@ def on_post_page(self, output: str, page: Page, **kwargs) -> str: # noqa: W0613
166
190
"""
167
191
log .debug (f"{ __name__ } : Fixing references in page { page .file .src_path } " )
168
192
169
- fixed_output , unmapped = fix_refs (output , page .url , self .get_item_url )
193
+ url_mapper = functools .partial (self .get_item_url , from_url = page .url , fallback = self .get_fallback_anchor )
194
+ fixed_output , unmapped = fix_refs (output , url_mapper )
170
195
171
196
if unmapped and log .isEnabledFor (logging .WARNING ):
172
197
for ref in unmapped :
0 commit comments