FIX: myst-nb 1.4+ compatibility, inline_literal_box option, and --qe-literal-color#373
FIX: myst-nb 1.4+ compatibility, inline_literal_box option, and --qe-literal-color#373
Conversation
myst-nb 1.4.0 (PR executablebooks/MyST-NB#693) changed its dark mode CSS from html[data-theme="dark"] selectors to a CSS space-toggle technique that falls back to @media (prefers-color-scheme) when no data-theme attribute is present. Since quantecon-book-theme uses body.dark-theme class (not data-theme) for dark mode, mystnb never detects the theme mode and falls through to the OS color scheme preference, causing dark code cell backgrounds on light-themed sites for users with OS dark mode enabled. Fix: Set data-theme="light" on <html> by default and toggle it to data-theme="dark" when the contrast button is activated. This is the standard mechanism used by pydata-sphinx-theme, Furo, and sphinx-book-theme. Closes #372
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #373 +/- ##
=======================================
Coverage ? 46.21%
=======================================
Files ? 2
Lines ? 409
Branches ? 0
=======================================
Hits ? 189
Misses ? 220
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR fixes a compatibility issue with myst-nb 1.4.0+ where code cell backgrounds would appear dark on light-themed sites for users with OS dark mode enabled. The root cause is that myst-nb 1.4+ changed its dark mode detection to use html[data-theme="dark"] and @media (prefers-color-scheme) fallback, but this theme only used body.dark-theme class — so myst-nb would fall through to the OS preference. The fix sets the data-theme attribute on <html> to explicitly signal the theme's current mode.
Changes:
- Sets
data-themeattribute on<html>in three synchronized locations: the inline early script (FOUC prevention), thesetContrast()function on page load, and the contrast toggle click handler. - Defaults to
data-theme="light"in the catch block of the early script to ensure a safe fallback. - Preserves the existing
body.dark-themeclass mechanism for backward compatibility.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/quantecon_book_theme/theme/quantecon_book_theme/layout.html |
Adds data-theme attribute sync to the inline early script that prevents FOUC, including light default in else/catch branches |
src/quantecon_book_theme/assets/scripts/theme-settings.js |
Adds data-theme attribute sync in setContrast() and in the contrast button click handler |
You can also share your feedback on Copilot code review. Take the survey.
🎭 Visual Regression Test ResultsDetails
Skipped testsmobile-chrome › theme.spec.ts › Theme Features › f-string interpolation styling |
|
/update-snapshots |
|
✅ All visual snapshots have been regenerated and committed to this PR. 📦 Download snapshot-update-diff artifact to review before/after images. |
|
…eme attribute pydata-sphinx-theme has a rule scoped to html[data-theme=light] that sets .highlight .nf color to #0078a1 with !important. This was dormant before we set data-theme on <html>. It overrode our custom function name color (#06287e) from _code.scss since :where() has zero specificity. Add a counter-rule with higher specificity to preserve our custom highlighting when qetheme_code_style is enabled.
|
/update-snapshots |
|
✅ All visual snapshots have been regenerated and committed to this PR. 📦 Download snapshot-update-diff artifact to review before/after images. |
…ments rules pydata-sphinx-theme's overwrite_pygments_css scopes ALL Pygments rules to html[data-theme="light"] and html[data-theme="dark"] at specificity (0,3,1). Our :where() wrapper gave zero specificity, so setting data-theme activated pydata's Pygments rules which overrode ALL our custom token colors. Replace :where(body:not(.use-pygments-style)) with html body:not(.use-pygments-style) which gives specificity (0,3,2), beating pydata's (0,3,1). Applied to both _code.scss and _syntax.scss. Remove the previous .nf-specific override since higher base specificity now handles all tokens.
|
/update-snapshots |
|
✅ All visual snapshots have been regenerated and committed to this PR. 📦 Download snapshot-update-diff artifact to review before/after images. |
Add configurable theme option (default: False) that controls whether inline code elements (code.literal) show pydata-sphinx-theme's background box and border styling. When False, the boxes are stripped to match the theme's original look. Set inline_literal_box: True in html_theme_options to re-enable the box styling.
|
/update-snapshots |
|
/update-snapshots |
|
✅ All visual snapshots have been regenerated and committed to this PR. 📦 Download snapshot-update-diff artifact to review before/after images. |
Integrate inline code literal (code.literal) color into the color scheme system alongside emphasis, strong, and definition colors: - Seoul256: #af5f5f (muted rust) / #d78787 (soft rose dark) - Gruvbox: #9d0006 (dark red) / #fb4934 (bright red dark) - None: inherits text color Overridable via --qe-literal-color CSS variable.
|
/update-snapshots |
|
✅ All visual snapshots have been regenerated and committed to this PR. 📦 Download snapshot-update-diff artifact to review before/after images. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 20 changed files in this pull request and generated 2 comments.
You can also share your feedback on Copilot code review. Take the survey.
src/quantecon_book_theme/theme/quantecon_book_theme/layout.html
Outdated
Show resolved
Hide resolved
|
Both Copilot review suggestions applied in commit 1a0c1d4: added contrast ratio info to Gruvbox literal color comments and fixed the leading space in the body class template logic. |
Summary
Fix compatibility with
myst-nb1.4.0+ by setting thedata-themeattribute, increasing CSS specificity for custom syntax highlighting, adding a configurableinline_literal_boxoption, and integrating inline code literal color into the text color scheme system.Problem
myst-nb1.4.0 (executablebooks/MyST-NB#693) changed its CSS dark mode detection fromhtml[data-theme="dark"]selectors to a CSS space-toggle technique with@media (prefers-color-scheme)fallback. Sincequantecon-book-themeusesbody.dark-themeclass for dark mode (notdata-themeattribute),myst-nbnever detects the theme's mode and falls through to the OS color scheme preference — causing dark code cell backgrounds on a light-themed site.This was temporarily worked around by pinning
myst-nb<1.4.0in downstream projects (see QuantEcon/lecture-python.myst#825).Changes
1. Set
data-themeon<html>(the standard signal)Set
data-themeon<html>(the standard signal used by pydata-sphinx-theme, Furo, and sphinx-book-theme) in three places:layout.htmlearly script — setsdata-theme="light"by default, or"dark"if dark mode was previously saved, preventing flash of incorrect stylestheme-settings.jssetContrast()— syncsdata-themeon page loadtheme-settings.jsclick handler — togglesdata-themewhen the contrast button is clickedThe existing
body.dark-themeclass mechanism is preserved for backward compatibility.2. Increase CSS specificity for custom code highlighting
Setting
data-themeactivated pydata-sphinx-theme's Pygments CSS rules, which are all scoped tohtml[data-theme="light/dark"] .highlight(specificity(0,3,1)). Our custom highlighting in_code.scssand_syntax.scssused:where()for zero specificity, so pydata's rules overrode all our custom token colors.Fix: Replaced
:where(body:not(.use-pygments-style))withhtml body:not(.use-pygments-style)giving specificity(0,3,2)— beating pydata's(0,3,1).3. Add
inline_literal_boxoptionpydata-sphinx-themeapplies background, border, and padding tocode.literalelements. A new theme option controls this:inline_literal_box: False(default) — strips the box styling to match our original lookinline_literal_box: True— re-enables pydata's box/border/padding on inline code4. Add
--qe-literal-colorto text color scheme systemIntegrated inline code literal (
code.literal) color into the color scheme system alongside emphasis, strong, and definition colors:#af5f5fmuted rust#d78787soft rose#9d0006dark red#fb4934bright redOverridable via
--qe-literal-colorCSS variable in a custom stylesheet.Files Changed
layout.html—data-themein flash-prevention script +inline-literal-boxbody classtheme-settings.js—data-themesync insetContrast()and click handler_code.scss— CSS specificity fix +code.literalbox override_syntax.scss— CSS specificity fix_colors.scss— Seoul256 and Gruvbox literal color variables_base.scss—code.literalcolor rule_dark-theme.scss— dark modecode.literalcolor_color-schemes.scss— gruvbox and none scheme literal rulestheme.conf—inline_literal_boxoption__init__.py—inline_literal_boxcontext variablecode-highlighting.md— inline code box + color documentationtext-color-schemes.md— literal color in scheme tables and examplesTesting
pre-commit run --all-files)npm run build)/update-snapshots)Closes
Closes #372