Commit 8119fb3
feat: Allow customizing emphasis and bold text colors via html_theme_options (#356)
* feat: Allow customizing emphasis and bold text colors via html_theme_options
Add four new theme options to customize emphasis (em) and definition
(strong/b) text colors for both light and dark modes:
- emphasis_color: Color for em tags in light mode (default: #2d9f42)
- emphasis_color_dark: Color for em tags in dark mode (default: #66bb6a)
- definition_color: Color for strong/b tags in light mode (default: #8b4513)
- definition_color_dark: Color for strong/b tags in dark mode (default: #cd853f)
Implementation approach:
- Replace hardcoded SCSS colors with CSS custom properties (var())
with fallback values matching the original defaults
- Register new options in theme.conf with empty defaults
- Inject custom property overrides via inline style in layout.html
when theme options are set
This is fully backward-compatible: existing sites see no visual change.
When options are left empty, CSS var() fallbacks provide the original colors.
Closes #355
* refactor: rename definition_color to strong_color for accuracy
The option applies to all <strong>/<b> elements, not just definitions.
Sphinx renders actual definitions via <dl>/<dt> elements which can be
targeted separately. Renamed across SCSS, theme.conf, layout.html,
tests, and documentation.
* Add definition_color option targeting Sphinx definition list terms
Add definition_color and definition_color_dark theme options that
target actual Sphinx definition list elements (dl.simple dt,
dl.glossary dt, dl.field-list dt) separately from strong/bold text.
The definition color falls back to the strong color via CSS variable
chain: var(--qe-definition-color, var(--qe-strong-color, fallback)),
so definitions inherit from strong_color by default but can be
independently customized.
* Fix black formatting in test_custom_colors.py
* Add visual regression tests for bold and italic typography
Add 5 Playwright visual tests in a new 'Typography Styling' describe block:
- bold text styling (light mode)
- italic text styling (light mode)
- mixed bold and italic styling
- bold text in dark mode
- italic text in dark mode
Uses .qe-page__content selectors to target paragraphs containing
<strong> and <em> elements on names.html, numpy.html, and
python_by_example.html.
Note: definition list (<dl>) tests not included as the lecture site
does not currently contain definition lists.
* UPDATE: Visual regression snapshots [skip ci]
* Remove fragile mixed bold/italic visual test and snapshot
* Add CSS color value validation to prevent injection
- Validate color theme options against safe CSS patterns (hex, named colors,
rgb/hsl functions) at build time
- Invalid values are ignored with a warning logged
- Add 14 tests for validation regex (valid and malicious patterns)
- Add security note to documentation
Addresses Copilot code review feedback on PR #356.
* Add unit tests for validate_color_options to improve patch coverage
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>1 parent c25b251 commit 8119fb3
File tree
17 files changed
+598
-7
lines changed- .github
- docs
- src/quantecon_book_theme
- assets/styles
- theme/quantecon_book_theme
- tests
- visual
- __snapshots__
- desktop-chrome
- mobile-chrome
17 files changed
+598
-7
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
95 | 102 | | |
96 | 103 | | |
97 | 104 | | |
| |||
240 | 247 | | |
241 | 248 | | |
242 | 249 | | |
| 250 | + | |
| 251 | + | |
243 | 252 | | |
244 | 253 | | |
245 | | - | |
| 254 | + | |
246 | 255 | | |
247 | 256 | | |
248 | | - | |
| 257 | + | |
249 | 258 | | |
250 | 259 | | |
251 | 260 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
323 | 323 | | |
324 | 324 | | |
325 | 325 | | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
594 | 595 | | |
595 | 596 | | |
596 | 597 | | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
597 | 640 | | |
598 | 641 | | |
599 | 642 | | |
| |||
603 | 646 | | |
604 | 647 | | |
605 | 648 | | |
| 649 | + | |
606 | 650 | | |
607 | 651 | | |
608 | 652 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | | - | |
| 154 | + | |
155 | 155 | | |
156 | 156 | | |
157 | | - | |
| 157 | + | |
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
161 | | - | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
162 | 169 | | |
163 | 170 | | |
164 | 171 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
32 | 38 | | |
33 | 39 | | |
34 | 40 | | |
| |||
Lines changed: 30 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
122 | 152 | | |
123 | 153 | | |
124 | 154 | | |
| |||
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
0 commit comments