From 54a02a7a61cdeaed0df3f98f49be4c36d07c0b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= <dev@pawamoy.fr> Date: Fri, 10 Jan 2025 02:21:55 +0100 Subject: [PATCH] feat: Handle inline references with markup within them Inline references with markup within them get their contents stashed. We unstash it to find the identifier, that we slugify to allow later resolution. Follow-up-of-issue-58: https://github.com/mkdocstrings/autorefs/issues/58 --- src/mkdocs_autorefs/references.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/mkdocs_autorefs/references.py b/src/mkdocs_autorefs/references.py index 8eca5f0..d43001f 100644 --- a/src/mkdocs_autorefs/references.py +++ b/src/mkdocs_autorefs/references.py @@ -141,13 +141,25 @@ def handleMatch(self, m: Match[str], data: str) -> tuple[Element | None, int | N return None, None, None if slug is None and re.search(r"[\x00-\x1f]", identifier): - # Do nothing if the matched reference contains control characters (from 0 to 31 included). - # Specifically `\x01` is used by Python-Markdown HTML stash when there's inline formatting, - # but references with Markdown formatting are not possible anyway. + # Do nothing if the matched reference still contains control characters (from 0 to 31 included) + # that weren't unstashed when trying to compute a slug of the title. return None, m.start(0), end return self._make_tag(identifier, text, slug=slug), m.start(0), end + def _unstash(self, identifier: str) -> str: + stashed_nodes: dict[str, Element | str] = self.md.treeprocessors["inline"].stashed_nodes # type: ignore[attr-defined] + + def _repl(match: Match) -> str: + el = stashed_nodes.get(match[1]) + if isinstance(el, Element): + return f"`{''.join(el.itertext())}`" + if el == "\x0296\x03": + return "`" + return str(el) + + return INLINE_PLACEHOLDER_RE.sub(_repl, identifier) + def _eval_id(self, data: str, index: int, text: str) -> tuple[str | None, str | None, int, bool]: """Evaluate the id portion of `[ref][id]`. @@ -188,6 +200,12 @@ def _eval_id(self, data: str, index: int, text: str) -> tuple[str | None, str | identifier = Markup(html).striptags() self.md.htmlStash.rawHtmlBlocks[stash_index] = escape(identifier) + # In any other case, unstash the title and slugify it. + # Examples: ``[`Foo` and `Bar`]``, `[The *Foo*][]`. + else: + identifier = self._unstash(identifier) + slug = slugify(identifier, separator="-") + end = m.end(0) return identifier, slug, end, True