1010from functools import lru_cache
1111from html import escape , unescape
1212from html .parser import HTMLParser
13+ from io import StringIO
1314from typing import TYPE_CHECKING , Any , Callable , ClassVar , Literal
1415from urllib .parse import urlsplit
1516from xml .etree .ElementTree import Element
@@ -376,22 +377,48 @@ def _find_url(
376377 raise KeyError (f"None of the identifiers { identifiers } were found" )
377378
378379
379- def _tooltip (identifier : str , title : str | None ) -> str :
380+ def _tooltip (identifier : str , title : str | None , * , strip_tags : bool = False ) -> str :
380381 if title :
381382 # Don't append identifier if it's already in the title.
382383 if identifier in title :
383384 return title
384385 # Append identifier (useful for API objects).
386+ if strip_tags :
387+ return f"{ title } ({ identifier } )"
385388 return f"{ title } (<code>{ identifier } </code>)"
386389 # No title, just return the identifier.
390+ if strip_tags :
391+ return identifier
387392 return f"<code>{ identifier } </code>"
388393
389394
395+ class _TagStripper (HTMLParser ):
396+ def __init__ (self ) -> None :
397+ super ().__init__ ()
398+ self .reset ()
399+ self .strict = False
400+ self .convert_charrefs = True
401+ self .text = StringIO ()
402+
403+ def handle_data (self , data : str ) -> None :
404+ self .text .write (data )
405+
406+ def get_data (self ) -> str :
407+ return self .text .getvalue ()
408+
409+
410+ def _strip_tags (html : str ) -> str :
411+ stripper = _TagStripper ()
412+ stripper .feed (html )
413+ return stripper .get_data ()
414+
415+
390416def fix_ref (
391417 url_mapper : Callable [[str ], tuple [str , str | None ]],
392418 unmapped : list [tuple [str , AutorefsHookInterface .Context | None ]],
393419 * ,
394420 link_titles : bool | Literal ["external" ] = True ,
421+ strip_title_tags : bool = False ,
395422) -> Callable :
396423 """Return a `repl` function for [`re.sub`](https://docs.python.org/3/library/re.html#re.sub).
397424
@@ -406,6 +433,7 @@ def fix_ref(
406433 such as [mkdocs_autorefs.plugin.AutorefsPlugin.get_item_url][].
407434 unmapped: A list to store unmapped identifiers.
408435 link_titles: How to set HTML titles on links. Always (`True`), never (`False`), or external-only (`"external"`).
436+ strip_title_tags: Whether to strip HTML tags from link titles.
409437
410438 Returns:
411439 The actual function accepting a [`Match` object](https://docs.python.org/3/library/re.html#match-objects)
@@ -449,14 +477,14 @@ def inner(match: Match) -> str:
449477 if optional :
450478 # The `optional` attribute is generally only added by mkdocstrings handlers,
451479 # for API objects, meaning we can and should append the full identifier.
452- tooltip = _tooltip (identifier , original_title )
480+ tooltip = _tooltip (identifier , original_title , strip_tags = strip_title_tags )
453481 else :
454482 # Autorefs without `optional` are generally user-written ones,
455483 # so we should only use the original title.
456484 tooltip = original_title or ""
457485
458486 if tooltip and tooltip not in f"<code>{ title } </code>" :
459- title_attr = f' title="{ escape (tooltip )} "'
487+ title_attr = f' title="{ _strip_tags ( tooltip ) if strip_title_tags else escape (tooltip )} "'
460488
461489 return f'<a class="{ class_attr } "{ title_attr } href="{ escape (url )} "{ remaining } >{ title } </a>'
462490
@@ -468,6 +496,7 @@ def fix_refs(
468496 url_mapper : Callable [[str ], tuple [str , str | None ]],
469497 * ,
470498 link_titles : bool | Literal ["external" ] = True ,
499+ strip_title_tags : bool = False ,
471500 # YORE: Bump 2: Remove line.
472501 _legacy_refs : bool = True ,
473502) -> tuple [str , list [tuple [str , AutorefsHookInterface .Context | None ]]]:
@@ -478,13 +507,14 @@ def fix_refs(
478507 url_mapper: A callable that gets an object's site URL by its identifier,
479508 such as [mkdocs_autorefs.plugin.AutorefsPlugin.get_item_url][].
480509 link_titles: How to set HTML titles on links. Always (`True`), never (`False`), or external-only (`"external"`).
510+ strip_title_tags: Whether to strip HTML tags from link titles.
481511
482512 Returns:
483513 The fixed HTML, and a list of unmapped identifiers (string and optional context).
484514 """
485515 unmapped : list [tuple [str , AutorefsHookInterface .Context | None ]] = []
486516 html = AUTOREF_RE .sub (
487- fix_ref (url_mapper , unmapped , link_titles = link_titles ),
517+ fix_ref (url_mapper , unmapped , link_titles = link_titles , strip_title_tags = strip_title_tags ),
488518 html ,
489519 )
490520
0 commit comments