
    Fe                       d Z ddlmZ ddlZddlmZ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mZ ddlmZ ddlmZ ddl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Any)nodesutils)__)SphinxPostTransform)loggingrst)split_explicit_title)Sequence)Nodesystem_message)Inliner)Sphinx)RoleFunctionc                  $    e Zd ZdZdZddZddZy)ExternalLinksCheckerz
    For 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      5/usr/lib/python3/dist-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                  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)astextappr   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=   s9   
  HG$;h +/88??+C+C+I+I+K 	H'E'Hh**RYYx%8%@%@%WXK%%c*E!%%g.5??,W55  2 3)--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|
      }|gg fS )NF)r$   r%   )r   unescaper   r   r   )typrawtexttextlinenoinlineroptionscontenthas_explicit_titler9   partfull_urlpnodebase_urlcaptions               r    rolezmake_link_role.<locals>.roleb   sd     ~~d#*>t*D'E4d?! $uuXNw{r"   )NrG   )rK   strrL   rY   rM   rY   rN   intrO   r   rP   zdict | NonerQ   zSequence[str]r@   z'tuple[list[Node], list[system_message]]rG   )namerV   rW   rX   s    `` r    make_link_roler\   \   s6     VX(3ER9 Kr"   c           	         | j                   j                  j                         D ]%  \  }\  }}| j                  |t	        |||             ' y r   )r   r-   r.   add_roler\   )r,   r[   rV   rW   s       r    setup_link_rolesr_   r   sG    %(ZZ%8%8%>%>%@ D!!xT>$'BCDr"   c                    | j                  di d       | j                  ddd       | j                  dt               | j                  t               t
        j                  ddS )Nr-   envr   Fzbuilder-initedT)versionparallel_read_safe)add_config_valueconnectr_   add_post_transformr   sphinx__display_version__)r,   s    r    setupri   w   sW    R/:E5IKK "23/011NNr"   )r[   rY   rV   rY   rW   rY   r@   r   )r,   r   r@   rA   )r,   r   r@   zdict[str, Any])&rE   
__future__r   r/   typingr   r   docutilsr   r   rg   sphinx.localer   !sphinx.transforms.post_transformsr	   sphinx.utilr
   r   sphinx.util.nodesr   collections.abcr   docutils.nodesr   r   docutils.parsers.rst.statesr   sphinx.applicationr   sphinx.util.typingr   	getLoggerrB   r6   r   r\   r_   ri   rG   r"   r    <module>rw      sl   & # 	 % !   A $ 2(33)/			8	$,H. ,H^,D
Or"   