Skip to content

Conversation

@mmcky
Copy link
Member

@mmcky mmcky commented Nov 3, 2025

Add exercise_style config option for solution styling

Summary

This PR adds a new configuration option to improve the styling and usability of solution directives, particularly for projects like QuantEcon lectures where solutions immediately follow exercises.

Changes

1. New Configuration Option: exercise_style

Adds a new configuration option exercise_style (default: "") that can be enabled in conf.py:

exercise_style = "solution_follow_exercise"

Purpose: When set to "solution_follow_exercise", this simplifies solution titles by:

  • Removing hyperlinks to exercises (since solutions follow exercises directly)
  • Displaying just "Solution" instead of "Solution to Exercise #.#"

Before (default behavior):

Solution to Exercise 1 (Factorial Function)  [← clickable link]

After (with exercise_style = "solution_follow_exercise"):

Solution  [← plain text, no link, no exercise reference]

This is particularly useful when solutions follow exercises directly in the content, reducing visual clutter and avoiding confusion when users click on dropdowns.

2. Order Validation System

When exercise_style = "solution_follow_exercise" is set, the extension validates that solutions actually follow their referenced exercises and provides helpful warnings:

Features:

  • ✅ Tracks exercise/solution node order as documents are processed
  • ✅ Validates solutions appear after their referenced exercises
  • ✅ Checks solutions are in the same document as their exercises
  • ✅ Provides detailed warnings with file paths and line numbers
  • ✅ Only runs when the config option is set (no performance impact otherwise)

Warning Examples:

/path/to/doc.md:15: WARNING: [sphinx-exercise] Solution 'sol-intro' (line 15) 
does not follow exercise 'ex-intro' (line 25). When 
exercise_style='solution_follow_exercise', solutions should appear after their 
referenced exercises.
/path/to/solutions.md:10: WARNING: [sphinx-exercise] Solution 'sol-chapter1' 
references exercise 'ex-chapter1' which is not in the same document. When 
exercise_style='solution_follow_exercise', solutions should appear in the same 
document as their exercises.

Implementation Details

  • Modified Files:

    • sphinx_exercise/__init__.py - Registered config option, added order tracking and validation
    • sphinx_exercise/post_transforms.py - Simplified solution title logic, cleaned up redundant code
    • docs/source/syntax.md - Documentation for configuration option
    • docs/source/install.md - Updated to use modern pip install -e .
    • CHANGELOG.md - Documented all changes
  • New Files:

    • tests/test_exercise_style.py - Tests for solution title styling
    • tests/test_order_validation.py - Tests for order validation warnings

Features

Backward compatible - Default behavior unchanged (opt-in configuration)
Well-tested - 6 new tests, all 116 tests pass
Properly handles:

  • Numbered and unnumbered exercises
  • Exercises with and without titles
  • Math expressions in titles (ensures MathJax is loaded)
  • Cross-document references (with warnings)
  • Wrong order detection (with helpful line numbers)

Testing

All tests pass across Python 3.10-3.13 and Sphinx 6-8:

======================= 116 passed, 1 warning in 35s ========================

New tests verify:

  • Simplified solution titles when exercise_style='solution_follow_exercise'
  • Full solution titles with hyperlinks when exercise_style='' (default)
  • Order validation warnings for solutions before exercises
  • Cross-document reference warnings
  • No validation when config is not set

Usage Example

Configuration (conf.py):

extensions = [
    "sphinx_exercise",
    "sphinx_togglebutton",  # for dropdown functionality
]

# Enable new styling for solutions that follow exercises
exercise_style = "solution_follow_exercise"

Content:

:::{exercise} Factorial Function
:label: ex-factorial

Write a function to calculate the factorial of a number.
:::

:::{solution} ex-factorial
:class: dropdown

Here's the solution...
:::

With exercise_style = "solution_follow_exercise":

  • Solution title displays just "Solution" (plain text, no link)
  • Build warnings if solution doesn't follow exercise
  • Build warnings if solution is in different document

Documentation

  • Updated docs/source/syntax.md with configuration documentation
  • Updated docs/source/install.md to use modern pip install
  • Added CHANGELOG.md entries for all changes

Related Issues

Addresses user request for QuantEcon lectures where solutions follow exercises, reducing visual clutter and improving UX with the dropdown class.

Breaking Changes

None - this is a fully opt-in feature. Default behavior remains unchanged.

This commit adds two requested features for better solution styling:

1. New configuration option 'style_solution_after_exercise' (default: False)
   - When enabled, removes hyperlinks from solution titles
   - Displays plain text like 'Solution to Exercise 1 (Title)'
   - Useful when solutions follow exercises directly
   - Reduces confusion when using dropdown class

2. Improved dropdown button text
   - Changed 'Click to show' to 'Show' for cleaner UI
   - Changed 'Click to hide' to 'Hide'
   - Applied via CSS customization

Features:
- Backward compatible (opt-in configuration)
- Properly handles numbered/unnumbered exercises
- Supports math expressions in titles
- Comprehensive test coverage (3 new tests)
- Full documentation in syntax.md

All 113 tests pass.
mmcky added 2 commits November 3, 2025 16:47
Changed configuration option name from 'style_solution_after_exercise'
to 'exercise_style' to make it clearer that this belongs to sphinx-exercise.

Changes:
- Config option: exercise_style = 'solution_follow_exercise' (was: style_solution_after_exercise = True)
- Default value: '' (empty string) instead of False
- More descriptive and namespaced for clarity in config files

This makes it clearer in configuration files that this is a
sphinx-exercise specific setting, especially when used alongside
other sphinx extensions like sphinx-proof.

Updated:
- sphinx_exercise/__init__.py
- sphinx_exercise/post_transforms.py
- tests/test_style_solution_after_exercise.py
- docs/source/syntax.md

All 113 tests pass.
- Renamed test file to test_exercise_style.py for consistency with new config name
- Updated CHANGELOG.md to reflect correct exercise_style configuration
- Fixed install.md to use modern pip editable install instead of deprecated setup.py
- All 113 tests pass across Python 3.11-3.13 and Sphinx 6-8
@mmcky mmcky changed the title FEAT: Add style_solution_after_exercise config option and improve dropdown UX FEAT: Add solution_after_exercise style option and improve dropdown UX Nov 3, 2025
mmcky added 2 commits November 4, 2025 10:08
- Dropdown button text styling is better handled at theme level
- Removes CSS override for toggle-button text from exercise.css
- Updates documentation to suggest theme-level customization
- Updates CHANGELOG to reflect architectural decision
- Simplified solution title to just 'Solution' when exercise_style='solution_follow_exercise'
  (instead of 'Solution to Exercise #.#' since solution follows exercise)
- Clean up redundant code in post_transforms.py title building
- Add node order tracking and validation system
  - Tracks exercise/solution node order as documents are read
  - Validates solutions follow their exercises when config is set
  - Reports helpful warnings with line numbers and labels
- Warning messages prefixed with [sphinx-exercise] for clarity
- Warnings include:
  - 'Solution X does not follow exercise Y' with line numbers
  - Cross-document reference detection
  - Only runs when exercise_style='solution_follow_exercise'
- Add comprehensive tests for order validation
- Update test assertions to check for simplified titles
@mmcky mmcky changed the title FEAT: Add solution_after_exercise style option and improve dropdown UX FEAT: Add solution_after_exercise style option Nov 5, 2025
mmcky added 2 commits November 5, 2025 11:39
- Update CHANGELOG.md to include order validation system details
- Fix syntax.md to accurately reflect simplified 'Solution' title
- Add validation behavior documentation
When exercise_style='solution_follow_exercise', the solution title
should be just 'Solution' not 'Solution to'. This fix updates the
directive to use the correct default title text based on the config.

- Update SolutionDirective to check exercise_style config
- Set title_text to 'Solution' when config is set
- Keep 'Solution to' for default behavior
- Update tests to expect correct 'Solution' title
@mmcky
Copy link
Member Author

mmcky commented Nov 5, 2025

@mmcky mmcky merged commit 8cf34d2 into main Nov 5, 2025
14 checks passed
@mmcky mmcky deleted the feature/style-solution-after-exercise branch November 5, 2025 03:15
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.

2 participants