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

sphinx.ext.extlinks: Allow %s in link caption string #8898

Merged
merged 4 commits into from Apr 11, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 8 additions & 9 deletions doc/usage/extensions/extlinks.rst
Expand Up @@ -23,29 +23,28 @@ The extension adds a config value:
.. confval:: extlinks

This config value must be a dictionary of external sites, mapping unique
short alias names to a base URL and a *prefix*. For example, to create an
short alias names to a base URL and a *caption*. For example, to create an
alias for the above mentioned issues, you would add ::

extlinks = {'issue': ('https://github.com/sphinx-doc/sphinx/issues/%s',
'issue ')}
'issue %s')}

Now, you can use the alias name as a new role, e.g. ``:issue:`123```. This
then inserts a link to https://github.com/sphinx-doc/sphinx/issues/123.
As you can see, the target given in the role is substituted in the base URL
in the place of ``%s``.

The link *caption* depends on the second item in the tuple, the *prefix*:
The link caption depends on the second item in the tuple, the *caption*:

- If the prefix is ``None``, the link caption is the full URL.
- If the prefix is the empty string, the link caption is the partial URL
given in the role content (``123`` in this case.)
- If the prefix is a non-empty string, the link caption is the partial URL,
prepended by the prefix -- in the above example, the link caption would be
- If *caption* is ``None``, the link caption is the full URL.
- If *caption* is a string, then it must contain ``%s`` exactly once. In
tk0miya marked this conversation as resolved.
Show resolved Hide resolved
this case the link caption is *caption* with the partial URL substituted
for ``%s`` -- in the above example, the link caption would be
``issue 123``.

You can also use the usual "explicit title" syntax supported by other roles
that generate links, i.e. ``:issue:`this issue <123>```. In this case, the
*prefix* is not relevant.
*caption* is not relevant.

.. note::

Expand Down
25 changes: 16 additions & 9 deletions sphinx/ext/extlinks.py
Expand Up @@ -7,15 +7,15 @@

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

extlinks = {'exmpl': ('https://example.invalid/%s.html', prefix), ...}
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 *prefix* value given:
the *caption* value given:

- If it is ``None``, the caption will be the full URL.
- If it is a string (empty or not), the caption will be the prefix prepended
to the role content.
- 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>`.

Expand All @@ -35,7 +35,7 @@
from sphinx.util.typing import RoleFunction


def make_link_role(base_url: str, prefix: str) -> RoleFunction:
def make_link_role(base_url: str, caption: str) -> RoleFunction:
def role(typ: str, rawtext: str, text: str, lineno: int,
inliner: Inliner, options: Dict = {}, content: List[str] = []
) -> Tuple[List[Node], List[system_message]]:
Expand All @@ -50,18 +50,25 @@ def role(typ: str, rawtext: str, text: str, lineno: int,
% (typ, base_url), line=lineno)
full_url = base_url + part
if not has_explicit_title:
if prefix is None:
if caption is None:
title = full_url
else:
title = prefix + part
try:
title = caption % part
except (TypeError, ValueError):
inliner.reporter.warning(
tk0miya marked this conversation as resolved.
Show resolved Hide resolved
'unable to expand %s extlink with caption %r, please make '
'sure the caption contains \'%%s\' exactly once'
% (typ, caption), line=lineno)
title = caption + part
pnode = nodes.reference(title, title, internal=False, refuri=full_url)
return [pnode], []
return role


def setup_link_roles(app: Sphinx) -> None:
for name, (base_url, prefix) in app.config.extlinks.items():
app.add_role(name, make_link_role(base_url, prefix))
for name, (base_url, caption) in app.config.extlinks.items():
app.add_role(name, make_link_role(base_url, caption))


def setup(app: Sphinx) -> Dict[str, Any]:
Expand Down