
    Ri                       d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	Z	ddl
mZ ddlmZ ddlmZmZ dd	lmZ er(dd
lmZ ddlmZ ddlmZmZ ddlmZ ddlmZ ddlmZmZ  ej@                  e!      Z" G d de      Z#ddZ$ddZ%ddZ&y)a  Extension to save typing and prevent hard-coding of base URLs in reST files.

This adds a new config value called ``extlinks`` that is created like this::

   extlinks = {'exmpl': ('https://example.invalid/%s.html', caption), ...}

Now you can use e.g. :exmpl:`foo` in your documents.  This will create a
link to ``https://example.invalid/foo.html``.  The link caption depends on
the *caption* value given:

- If it is ``None``, the caption will be the full URL.
- If it is a string, it must contain ``%s`` exactly once.  In this case the
  caption will be *caption* with the role content substituted for ``%s``.

You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`.

Both, the url string and the caption string must escape ``%`` as ``%%``.
    )annotationsN)TYPE_CHECKING)nodesutils)__)SphinxPostTransform)loggingrst)split_explicit_title)Sequence)Any)Nodesystem_message)Inliner)Sphinx)ExtensionMetadataRoleFunctionc                  $    e Zd ZdZdZddZddZy)ExternalLinksCheckerzFor each external link, check if it can be replaced by an extlink.

    We treat each ``reference`` node without ``internal`` attribute as an external link.
    i  c                    | j                   j                  sy | j                  j                  t        j
                        D ]  }| j                  |        y N)configextlinks_detect_hardcoded_linksdocumentfindallr   	reference	check_uri)selfkwargsrefnodes      K/home/agent/.friday_env/lib/python3.12/site-packages/sphinx/ext/extlinks.pyrunzExternalLinksChecker.run6   s@    {{::}},,U__= 	$GNN7#	$    c                   d|v sd|vry|d   }|j                         }| j                  j                  j                         D ]  \  }\  }}t	        j
                  t	        j                  |      j                  dd            }|j                  |      }|sU|j                         j                  d      sud|j                         d   vst        d      }	|j                         j                  d      }
||k7  r d	| d
t        j                  |       d|
 d}n	d	| d
|
 d}t        j                  |	|||        y)z{If the URI in ``refnode`` has a replacement in ``extlinks``,
        emit a warning with a replacement suggestion.
        internalrefuriNz%sz(?P<value>.+)value/zHhardcoded link %r could be replaced by an extlink (try using %r instead):z:`z <z>``)location)astextr   extlinksitemsrecompileescapereplacematch	groupdictgetr   r
   loggerwarning)r   r    urititlealiasbase_uri_captionuri_patternr3   msgr'   replacements               r!   r   zExternalLinksChecker.check_uri=   s7     HG$;h +/;;+?+?+E+E+G 	H'E'Hh**RYYx%8%@%@%WXK%%c*EOO%))'2u099 - )--g6%<$%eWBszz%/@.AE7""MK$%eWBugQ"7KsCwG'	Hr#   N)r   r   returnNone)r    znodes.referencer@   rA   )__name__
__module____qualname____doc__default_priorityr"   r    r#   r!   r   r   .   s    
 $Hr#   r   c                @     	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd}|S )Nc                    t        j                  |      }t        |      \  }}}	|	z  }
|s
|
}n|	z  }t        j                  ||d|
      }|d   j                  d        |gg fS )NF)r%   r&   classeszextlink-)r   unescaper   r   r   append)typrawtexttextlinenoinlineroptionscontenthas_explicit_titler9   partfull_urlpnodebase_urlcaptionnames               r!   rolezmake_link_role.<locals>.rolec   s~     ~~d#*>t*D'E4d?! $uuXNi(4& 12w{r#   )NrG   )rM   strrN   r\   rO   r\   rP   intrQ   r   rR   zdict[str, Any] | NonerS   zSequence[str]r@   z'tuple[list[Node], list[system_message]]rG   )rZ   rX   rY   r[   s   ``` r!   make_link_roler^   ]   sc     *.!#  	
  '  
1* Kr#   c           	         | j                   j                  j                         D ]%  \  }\  }}| j                  |t	        |||             ' y r   )r   r-   r.   add_roler^   )apprZ   rX   rY   s       r!   setup_link_rolesrb   {   sG    %(ZZ%8%8%>%>%@ D!!xT>$'BCDr#   c                
   | j                  di dt        t        h             | j                  dddt        t        h             | j	                  dt
               | j                  t               t        j                  ddS )	Nr-   env)typesr   Fzbuilder-initedT)versionparallel_read_safe)
add_config_value	frozensetdictboolconnectrb   add_post_transformr   sphinx__display_version__)ra   s    r!   setuprp      sz    Ri6GH)5%y$?P   KK "23/0--" r#   )rZ   r\   rX   r\   rY   z
str | Noner@   r   )ra   r   r@   rA   )ra   r   r@   r   )'rE   
__future__r   r/   typingr   docutilsr   r   rn   sphinx.localer   !sphinx.transforms.post_transformsr   sphinx.utilr	   r
   sphinx.util.nodesr   collections.abcr   r   docutils.nodesr   r   docutils.parsers.rst.statesr   sphinx.applicationr   sphinx.util.typingr   r   	getLoggerrB   r6   r   r^   rb   rp   rG   r#   r!   <module>r~      sn   & # 	   !   A $ 2(33)B			8	$,H. ,H^<D
r#   