From 7619c2835a63b54b1f5e9e11c5f320c04e3579ac Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Fri, 30 Apr 2021 23:32:05 +0200 Subject: [PATCH] feat: Allow external tools to insert references that are OK to skip E.g. mkdocstrings-crystal can proactively insert links (by writing out the exact HTML that's prescribed here) that in the end can turn out to not be present anywhere, and since those are auto-inserted, they are not actionable for the user, so there should be no warning for them. So mkdocstrings-crystal will switch to ``. Also migrate the "required" case to new data- keys, because this is not specific to mkdocstrings now. PR #7: https://github.com/mkdocstrings/autorefs/pull/7 --- src/mkdocs_autorefs/plugin.py | 2 +- src/mkdocs_autorefs/references.py | 9 +++++++-- tests/test_references.py | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/mkdocs_autorefs/plugin.py b/src/mkdocs_autorefs/plugin.py index 3d5ba32..79698a2 100644 --- a/src/mkdocs_autorefs/plugin.py +++ b/src/mkdocs_autorefs/plugin.py @@ -148,7 +148,7 @@ def on_post_page(self, output: str, page: Page, **kwargs) -> str: # noqa: W0613 Hook for the [`on_post_page` event](https://www.mkdocs.org/user-guide/plugins/#on_post_page). In this hook, we try to fix unresolved references of the form `[title][identifier]` or `[identifier][]`. - Doing that allows the user of `mkdocstrings` to cross-reference objects in their documentation strings. + Doing that allows the user of `autorefs` to cross-reference objects in their documentation strings. It uses the native Markdown syntax so it's easy to remember and use. We log a warning for each reference that we couldn't map to an URL, but try to be smart and ignore identifiers diff --git a/src/mkdocs_autorefs/references.py b/src/mkdocs_autorefs/references.py index 2d622c1..9a5bdd6 100644 --- a/src/mkdocs_autorefs/references.py +++ b/src/mkdocs_autorefs/references.py @@ -10,7 +10,10 @@ from markdown.inlinepatterns import REFERENCE_RE, ReferenceInlineProcessor from markdown.util import INLINE_PLACEHOLDER_RE -AUTO_REF_RE = re.compile(r'[^"<>]*)\1>(?P.*?)</span>') +AUTO_REF_RE = re.compile( + r"<span data-(?P<kind>autorefs-identifier|autorefs-optional|mkdocstrings-identifier)=" + r'("?)(?P<identifier>[^"<>]*)\2>(?P<title>.*?)</span>' +) """A regular expression to match mkdocs-autorefs' special reference markers in the [`on_post_page` hook][mkdocs_autorefs.plugin.AutorefsPlugin.on_post_page]. """ @@ -94,7 +97,7 @@ def makeTag(self, identifier: str, text: str) -> Element: # noqa: N802,W0221 (p A new element. """ el = Element("span") - el.set("data-mkdocstrings-identifier", identifier) + el.set("data-autorefs-identifier", identifier) el.text = text return el @@ -152,6 +155,8 @@ def inner(match: Match): try: url = relative_url(from_url, url_mapper(unescape(identifier))) except KeyError: + if match["kind"] == "autorefs-optional": + return title unmapped.append(identifier) if title == identifier: return f"[{identifier}][]" diff --git a/tests/test_references.py b/tests/test_references.py index 7a2c020..d900613 100644 --- a/tests/test_references.py +++ b/tests/test_references.py @@ -154,3 +154,21 @@ def test_ignore_reference_with_special_char(): source="This [*a b*][].", output="<p>This [<em>a b</em>][].</p>", ) + + +def test_custom_required_reference(): + """Check that external HTML-based references are expanded or reported missing.""" + url_map = {"ok": "ok.html#ok"} + source = "<span data-autorefs-identifier=bar>foo</span> <span data-autorefs-identifier=ok>ok</span>" + output, unmapped = fix_refs(source, "page.html", url_map.__getitem__) + assert output == '[foo][bar] <a href="ok.html#ok">ok</a>' + assert unmapped == ["bar"] + + +def test_custom_optional_reference(): + """Check that optional HTML-based references are expanded and never reported missing.""" + url_map = {"ok": "ok.html#ok"} + source = '<span data-autorefs-optional="bar">foo</span> <span data-autorefs-optional=ok>ok</span>' + output, unmapped = fix_refs(source, "page.html", url_map.__getitem__) + assert output == 'foo <a href="ok.html#ok">ok</a>' + assert unmapped == []