Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PyPI role #11780

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/usage/restructuredtext/roles.rst
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,17 @@ The following roles generate external links:

For example: :pep:`8`

.. rst:role:: pypi

A reference to a PyPI project. This generates appropriate index entries.
In the HTML output, the project name is used as a hyperlink to its PyPI
webpage. You can link to a specific section by saying
``:pypi:`project#anchor```.

For example: :pypi:`Sphinx`

.. versionadded:: 7.3

.. rst:role:: rfc

A reference to an Internet Request for Comments. This generates appropriate
Expand Down
2 changes: 2 additions & 0 deletions sphinx/environment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
'cloak_email_addresses': True,
'pep_base_url': 'https://peps.python.org/',
'pep_references': None,
'pypi_base_url': 'https://pypi.org/project/',
'pypi_references': None,
'rfc_base_url': 'https://datatracker.ietf.org/doc/html/',
'rfc_references': None,
'input_encoding': 'utf-8-sig',
Expand Down
34 changes: 34 additions & 0 deletions sphinx/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,39 @@ def build_uri(self) -> str:
return base_url + self.inliner.rfc_url % int(ret[0])


class PyPI(ReferenceRole):
def run(self) -> tuple[list[Node], list[system_message]]:
target_id = f"index-{self.env.new_serialno('index')}"
entries = [("single", f"PyPI; PyPI {self.target}", target_id, "", None)]

index = addnodes.index(entries=entries)
target = nodes.target("", "", ids=[target_id])
self.inliner.document.note_explicit_target(target)

try:
refuri = self.build_uri()
reference = nodes.reference(
"", "", internal=False, refuri=refuri, classes=["pypi"],
)
reference += nodes.strong(self.title, self.title)
except ValueError:
msg = self.inliner.reporter.error(
__("invalid PyPI project %s") % self.target, line=self.lineno,
)
prb = self.inliner.problematic(self.rawtext, self.rawtext, msg)
return [prb], [msg]

return [index, target, reference], []

def build_uri(self) -> str:
base_url = self.inliner.document.settings.pypi_base_url
ret = self.target.split("#", 1)
if len(ret) == 2:
return f"{base_url}{ret[0]}/#{ret[1]}"
else:
return f"{base_url}{ret[0]}/"


_amp_re = re.compile(r'(?<!&)&(?![&\s])')


Expand Down Expand Up @@ -402,6 +435,7 @@ def code_role(name: str, rawtext: str, text: str, lineno: int,
'any': AnyXRefRole(warn_dangling=True),

'pep': PEP(),
'pypi': PyPI(),
'rfc': RFC(),
'guilabel': GUILabel(),
'menuselection': MenuSelection(),
Expand Down
24 changes: 24 additions & 0 deletions tests/test_markup.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,30 @@ def get(name):
'{https://peps.python.org/pep-0008/\\#id1}'
'{\\sphinxstylestrong{PEP 8\\#id1}}'),
),
(
# pypi role
'verify',
':pypi:`norwegianblue`',
('<p><span class="target" id="index-0"></span><a class="pypi reference external" '
'href="https://pypi.org/project/norwegianblue/">'
'<strong>norwegianblue</strong></a></p>'),
('\\sphinxAtStartPar\n'
'\\index{PyPI@\\spxentry{PyPI}!PyPI norwegianblue@\\spxentry{PyPI norwegianblue}}'
'\\sphinxhref{https://pypi.org/project/norwegianblue/}'
'{\\sphinxstylestrong{norwegianblue}}'),
),
(
# pypi role with anchor
'verify',
':pypi:`norwegianblue#history`',
('<p><span class="target" id="index-0"></span><a class="pypi reference external" '
'href="https://pypi.org/project/norwegianblue/#history">'
'<strong>norwegianblue#history</strong></a></p>'),
('\\sphinxAtStartPar\n'
'\\index{PyPI@\\spxentry{PyPI}!PyPI norwegianblue\\#history@\\spxentry{PyPI norwegianblue\\#history}}'
'\\sphinxhref{https://pypi.org/project/norwegianblue/\\#history}'
'{\\sphinxstylestrong{norwegianblue\\#history}}'),
),
(
# rfc role
'verify',
Expand Down
Loading