3

T'ícšã@sdZddlZddlZddlZddlmZmZmZmZddl	m
Z
mZddlm
Z
mZddlmZddlZddlmZddlmZdd	lmZdd
lmZddlmZmZddlmZdd
lm Z ej!e"ƒZ#Gdd„deƒZ$e%e%e%e dœdd„Z&eddœdd„Z'eee%efdœdd„Z(dS)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 ``%%``.
éN)ÚAnyÚDictÚListÚTuple)ÚnodesÚutils)ÚNodeÚsystem_message)ÚInliner)ÚSphinx)ÚRemovedInSphinx60Warning)Ú__)ÚSphinxPostTransform)ÚloggingÚrst)Úsplit_explicit_title)ÚRoleFunctionc@s6eZdZdZdZeddœdd„Zejddœdd	„Z	dS)
Ú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ôN)ÚkwargsÚreturncKs2|jjsdSx |jjtjƒD]}|j|ƒqWdS)N)ÚconfigÚextlinks_detect_hardcoded_linksÚdocumentÚfindallrÚ	referenceÚ	check_uri)ÚselfrÚrefnode©rú5/tmp/pip-build-gk9425m9/sphinx/sphinx/ext/extlinks.pyÚrun2szExternalLinksChecker.run)rrcCsd|ksd|krdS|d}|jƒ}xØ|jjjjƒD]Æ\}\}}tjdkrdtjtj	|ƒj
ddƒƒ}ntjtj	|ƒj
ddƒƒ}|j|ƒ}|r4|jƒj
d	ƒr4td
ƒ}	|jƒj
d	ƒ}
||krÖd|›dtj	|ƒ›d
|
›d}nd|›d|
›d}tj|	|||dq4WdS)z„
        If the URI in ``refnode`` has a replacement in ``extlinks``,
        emit a warning with a replacement suggestion.
        ÚinternalÚrefuriNééz\%sz
(?P<value>.+)z%sÚvaluezHhardcoded link %r could be replaced by an extlink (try using %r instead)ú:z:`z <z>`ú`)Úlocation)r#r$)ZastextÚapprÚextlinksÚitemsÚsysÚversion_infoÚreÚcompileÚescapeÚreplaceÚmatchÚ	groupdictÚgetr
rÚloggerÚwarning)rrÚuriÚtitleÚaliasZbase_uriZ_captionZuri_patternr2Úmsgr%Úreplacementrrrr9s 

 zExternalLinksChecker.check_uri)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zdefault_priorityrr rrrrrrrr)sr)ÚnameÚbase_urlÚcaptionrcsÌyˆdWn4ttfk
r@tjdtƒˆjddƒd‰YnXˆdk	rŒyˆdWn4ttfk
rŠtjdtƒˆjddƒd‰YnXigftttttt	t
ttt
tt
t
fdœ‡‡fdd	„
}|S)
NÚdummyztextlinks: Sphinx-6.0 will require base URL to contain exactly one '%s' and all other '%' need to be escaped as '%%'.ú%z%%z%sz|extlinks: Sphinx-6.0 will require a caption string to contain exactly one '%s' and all other '%' need to be escaped as '%%'.)ÚtypÚrawtextÚtextÚlinenoÚinlinerÚoptionsÚcontentrcsVtj|ƒ}t|ƒ\}}}	ˆ|	}
|s:ˆdkr2|
}nˆ|	}tj||d|
d}|ggfS)NF)r!r")rÚunescaperrr)rErFrGrHrIrJrKZhas_explicit_titler8ÚpartÚfull_urlZpnode)rArBrrÚroleos
zmake_link_role.<locals>.role)Ú	TypeErrorÚ
ValueErrorÚwarningsÚwarnrr1ÚstrÚintr
rrrrr	)r@rArBrOr)rArBrÚmake_link_roleYs $rV)r)rcCs6x0|jjjƒD] \}\}}|j|t|||ƒƒqWdS)N)rr*r+Zadd_rolerV)r)r@rArBrrrÚsetup_link_rolessrWcCs>|jdidƒ|jdddƒ|jdtƒ|jtƒtjddœS)Nr*ÚenvrFzbuilder-initedT)ÚversionZparallel_read_safe)Zadd_config_valueÚconnectrWZadd_post_transformrÚsphinxZ__display_version__)r)rrrÚsetup„s

r\))r?r.r,rRÚtypingrrrrZdocutilsrrZdocutils.nodesrr	Zdocutils.parsers.rst.statesr
r[Zsphinx.applicationrZsphinx.deprecationrZ
sphinx.localer
Z!sphinx.transforms.post_transformsrZsphinx.utilrrZsphinx.util.nodesrZsphinx.util.typingrÚ	getLoggerr<r5rrTrVrWr\rrrrÚ<module>s(
0&