Skip to content

🔧 Drop sd_custom_roles before 0.8.0: the badge roles take a tooltip role option - #316

Merged
chrisjsewell merged 5 commits into
mainfrom
maint/drop-sd-custom-roles
Nov 10, 2026
Merged

chrisjsewell merged 5 commits into
mainfrom
maint/drop-sd-custom-roles

Conversation

@chrisjsewell

@chrisjsewell chrisjsewell commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

This removes the sd_custom_roles setting added in #295 before it ships in 0.8.0, and replaces it with a standard role option.

The badge-role refactor from #295 stays. _iter_badge_roles is still the single source of the badge family, and every badge role is built by one constructor that accepts a default tooltip.

What is removed: the sd_custom_roles config value and its validation, the role registration with its handling of docutils' process-global role registry, its documentation sections and examples, and tests/test_custom_roles.py.

What is added: the badge roles (plain, link and ref, in every colour and outline variant) accept a tooltip role option, read from the docutils role-function options dictionary. A reStructuredText custom role can preset it:

.. role:: bdg-stable(bdg-success)
   :tooltip: A released, supported version

An extension that presets a badge role passes it the same way, as options={"tooltip": ...}. A ; tooltip suffix on a badge still wins over the option, and the option wins over the constructor default. Like a baked tooltip in #295, the option also applies to the bare <target> form of link and ref badges, and replaces a ref badge's automatic title.

Two docutils details shaped the implementation. docutils' role directive reads the option specification from the base role's options attribute, which Sphinx's SphinxRole overwrites with each call's options, so the badge roles restore it after every call. docutils also adds a class option to a role's specification when it is registered, so each role instance has its own copy. Badges still ignore class, as before. As a side effect, a .. role:: with :class: over a badge role that the document had already used, which failed on main, now works.

The docs describe the option for authors and for extension authors. A .. role:: defines the role for the document it appears in; to use it in every reStructuredText document, put it in rst_prolog (MyST documents do not read rst_prolog). For presets beyond default option values, the docs point to the sphinx-ub-directives package from the sphinx-needs project, whose directive presets accept sphinx-design directives as a base; role presets are planned there. sd_custom_directives is unchanged.

Tests: tests/test_badge_tooltip_option.py covers plain, link and ref badges, both through a .. role:: custom role and through a docutils CustomRole options dict. It checks the HTML output, the precedence order, a custom role defined after its base role was already used (with :class:), the option specification being restored when a role raises, an empty option, and the text, LaTeX and man builders, which are unaffected. The full suite passes on Sphinx 7.4, 8.2 and 9.2. pre-commit, generate_css.py --check and the docs build with -nW (html, man, text) are clean.

Remove the unreleased `sd_custom_roles` setting (#295) before it ships in 0.8.0:
its config value and validation, the role registration and the process-global registry handling,
its documentation and its tests.

The badge-role refactor from #295 stays: `_iter_badge_roles` is still the single source of the badge family,
and every badge role is built by one constructor that accepts a default tooltip.
In its place, the badge roles (plain, link and ref, in every colour) now accept a standard `tooltip` role option,
read from the docutils role-function options dictionary.
A reStructuredText custom role can preset it (`.. role:: bdg-stable(bdg-success)` with `:tooltip:`),
and an extension that presets a badge role passes it the same way.
A `; tooltip` suffix still wins over the option, which wins over the constructor default.

The docs describe the option, for authors and for extension authors,
and recommend the sphinx-ub-directives package for project-defined directive presets.
`sd_custom_directives` is unchanged.
…roles

# Conflicts:
#	sphinx_design/extension.py
@codecov

codecov Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.01%. Comparing base (c7b2d2f) to head (e4a8524).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #316      +/-   ##
==========================================
+ Coverage   93.96%   94.01%   +0.04%     
==========================================
  Files          16       16              
  Lines        1840     1787      -53     
==========================================
- Hits         1729     1680      -49     
+ Misses        111      107       -4     
Flag Coverage Δ
pytests 94.01% <100.00%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ate pointers

The role directive defines a role for the document it is in, so say so and
show rst_prolog for using one in every reStructuredText document. Point to
sphinx-ub-directives for what it does today (role presets are planned there),
frame the get_started tip as what sd_custom_directives does not do, and move
the tooltip accessibility warning above the role-option subsection.
…n error

A custom role defined after its base badge role was used now also passes
`:class:`, which pins that the restored option spec is the one docutils
registered (with its `class` entry): restoring a fresh copy of the class-level
spec would refuse `:class:` there. Also test that the spec is restored when
the base role raises.
@chrisjsewell
chrisjsewell merged commit cb9828f into main Nov 10, 2026
27 checks passed
@chrisjsewell
chrisjsewell deleted the maint/drop-sd-custom-roles branch November 10, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant