Repository navigation
♻️ Card header/footer sub-directives: a pure parse replaces raw-text splitting - #294
Merged
Merged
Conversation
Add parser-portable `card-header` / `card-footer` sub-directives (plus
inline `:header:` / `:footer:` options for one-liners) that are hoisted
into the card's header/footer slots, replacing the `^^^` / `+++`
separators that regex-scanned the card's raw source lines.
The card body is now parsed in a single pass, so source lines are
attributed correctly (kills the old `TODO set proper lines`): an error
inside a card-footer now reports the footer's line, not the card's.
`grid-item-card` inherits the same behaviour via `create_card`.
The legacy separators remain on by default behind the new
`sd_card_legacy_separators` config field (flat `sd_card_legacy_separators`,
bool, default True, rebuild=env). They emit a single, suppressible
`design.card_legacy` deprecation warning per document. Note the raw-line
scan still runs on every card while enabled, so a stray `^^^` / `+++`
(e.g. inside a code block) keeps mis-splitting until the separators are
disabled with `sd_card_legacy_separators=False`; the single-parse
robustness is only fully realised then (default flip planned at 1.0).
Both syntaxes produce identical doctrees (asserted by dedicated tests and
by the unchanged snippet fixtures). Mixing separators and directives warns
(`design.card`, wording points at the flag for incidental separator lines),
directives win and merge with no doubled slot wrappers even when nested in
a separator chunk; multiple headers/footers merge with a warning; a
card-header/card-footer outside a card warns (mirrors tab-item). An empty
card-header/card-footer directive now errors ("Content block expected")
where an empty legacy chunk produced an empty slot.
The private `CardDirective._create_component` helper is renamed to
`_create_slot`, with a back-compatible alias kept for one release.
Docs switch every card/grid example to the new syntax and gain a
"Legacy separator syntax" migration section (rst + myst) with a
migrate-then-flip note.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #294 +/- ##
==========================================
+ Coverage 93.43% 93.85% +0.42%
==========================================
Files 16 16
Lines 1675 1823 +148
==========================================
+ Hits 1565 1711 +146
- Misses 110 112 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The design.card_legacy deprecation warning stays on by default in 0.8.0, so a -W build that still uses ^^^/+++ fails. The changelog and the cards page now say so and name both remedies (migrate to card-header/card-footer, or suppress_warnings = ["design.card_legacy"]); a test pins that the warning text itself names both.
The default-on design.card_legacy warning listed disabling the separators as a third way out, but setting sd_card_legacy_separators=False while cards still use ^^^/+++ turns a failing -W build green and silently drops their header/footer slots. The message now gives it as the step after migrating. Also: the cards docs say a -W build fails while any document still uses the separators (Sphinx >= 8.1 no longer stops at the first), and the changelog upgrade note ends with the PR reference like the other entries.
No conflicts. Drop this branch's CHANGELOG entries: the release PR writes the changelog.
chrisjsewell
added a commit
to dipinknair/sphinx-design
that referenced
this pull request
Nov 10, 2026
…ecutablebooks#293 executablebooks#294 executablebooks#295 and others) Keep both sides in sphinx_design/extension.py (the new-tab doctree-resolved handler and the sd_custom_roles config-inited hook) and in tests/test_buttons.py (the new-tab tests and main's line-block tests). cards.py merged cleanly: the stretched link is still built by _create_link, which marks it for the new-tab handler.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the card directive's bespoke
^^^/+++raw-line surgery with structural sub-directives, following thetab-set/tab-itempattern from the roadmap (#265 §4):plus
:header:/:footer:options for the one-liner case. The card body is parsed with a single ordinarynested_parseand slots are hoisted by doctree manipulation — no raw-text processing, so the structure is visible to formatters, linters, and any non-Python MyST implementation, and source-line attribution is finally correct (errors inside a footer report the footer's line; the oldTODO set proper linesis gone).Compatibility: zero behaviour change by default
^^^/+++syntax remains default-on behind the newsd_card_legacy_separatorsconfval. Review verified byte-identical doctrees vsmainacross a legacy stress corpus (rst + myst: header-only, footer-only, 4+ carets, separators in code blocks, grid-item-card, carousel).--force-regendrift, on sphinx 7.2.6 / 7.4.7 / 8.2.3.design.card_legacydeprecation (with inline remedies in the message), parallel-read-safe. Timeline: deprecated now → default off at 1.0 → removed at 2.0, documented with a migration table.+++inside a code block keeps mis-splitting (exactly as before) — the single-parse benefits are fully realized once you migrate and setsd_card_legacy_separators = False.Review coverage
Two independent adversarial reviews (structural correctness; syntax compatibility/migration): no structural findings — the transient parse marker was proven absent from pickled doctrees at the raw-byte level across all error paths; the #281/#282 button-ref transforms work on slot content; gettext now extracts header/footer content (an i18n improvement); latex/text/man degrade cleanly. The private
_create_componentwas renamed — a one-release alias is kept and the rename is changelog-noted for downstream.Verification
-nWdocs build greensd-card-header/sd-card-footerclasses); artifact untouched