diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba25a01..25c8a72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,8 +23,13 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] sphinx-version: ["6", "7", "8"] + exclude: + # Python 3.13 with Sphinx 6 generates many deprecation warnings + # from Sphinx's use of deprecated datetime methods. Unlikely combination. + - python-version: "3.13" + sphinx-version: "6" steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -42,24 +47,23 @@ jobs: - name: Create cov run: coverage xml - name: Upload to Codecov - if: false && (matrix.python-version == '3.11' && matrix.sphinx-version == '8') + if: matrix.python-version == '3.12' && matrix.sphinx-version == '8' uses: codecov/codecov-action@v4 with: - name: sphinx-exercise-pytest-py3.11-sphinx8 - token: "${{ secrets.CODECOV_TOKEN }}" + name: sphinx-exercise-pytest-py3.12-sphinx8 flags: pytests file: ./coverage.xml - fail_ci_if_error: true + fail_ci_if_error: false docs: name: Documentation build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip @@ -78,10 +82,10 @@ jobs: steps: - name: Checkout source uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.10 uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.10" - name: Build package run: | pip install wheel build diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fa2c3f..7c57742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [Unreleased] + +## [v1.1.1](https://github.com/executablebooks/sphinx-exercise/tree/v1.1.1) (2025-10-23) + +### Improved πŸ‘Œ + +- **Restored Python 3.10 support** - Re-added compatibility with Python 3.10 as it remains actively supported until October 2026 +- Updated test matrix to include Python 3.10 with Sphinx 6, 7, and 8 +- Test matrix now covers 11 combinations (excludes Python 3.13 + Sphinx 6 due to deprecation warnings) +- **Note**: Python 3.10 is limited to Sphinx 8.1.x (max 8.1.3) due to Sphinx 8.2+ requiring Python >=3.11. This is handled automatically in the test configuration. +- Updated codecov integration to use Python 3.12 + Sphinx 8 baseline +- Configured tokenless codecov uploads for public repository + ## [v1.1.0](https://github.com/executablebooks/sphinx-exercise/tree/v1.1.0) (2025-10-22) ### New ✨ diff --git a/docs/source/releases/index.md b/docs/source/releases/index.md index c301282..4d932b0 100644 --- a/docs/source/releases/index.md +++ b/docs/source/releases/index.md @@ -5,6 +5,7 @@ This section contains detailed release notes for sphinx-exercise versions. ```{toctree} :maxdepth: 1 +v1.1.1 v1.1.0 ``` diff --git a/docs/source/releases/v1.1.1.md b/docs/source/releases/v1.1.1.md new file mode 100644 index 0000000..bad2ebb --- /dev/null +++ b/docs/source/releases/v1.1.1.md @@ -0,0 +1,75 @@ +# Release v1.1.1 + +**Release Date**: October 23, 2025 + +This is a patch release that restores Python 3.10 compatibility while maintaining support for newer Python versions. + +## πŸ‘Œ Improvements + +### Python 3.10 Support Restored + +Python 3.10 support has been re-added to the project. Python 3.10 remains actively supported until October 2026, making it an important version to maintain compatibility with. + +**Key details:** +- Python 3.10 is now fully supported alongside Python 3.11, 3.12, and 3.13 +- All existing features work identically across all supported Python versions +- Comprehensive test coverage ensures compatibility + +### Technical Implementation + +**Version-Specific Sphinx Constraints:** +- Python 3.10 is limited to **Sphinx 8.1.x** (maximum 8.1.3) +- Python 3.11+ continues to use **Sphinx 8.2+** as normal +- This constraint exists because Sphinx 8.2.0+ requires Python >=3.11 + +The test infrastructure automatically handles these version-specific requirements, ensuring correct behavior across all combinations. + +### Test Matrix Updates + +**Supported Combinations:** +- Python 3.10, 3.11, 3.12: Sphinx 6, 7, 8 +- Python 3.13: Sphinx 7, 8 + +**Total: 11 test environments** (excludes Python 3.13 + Sphinx 6) + +Python 3.13 + Sphinx 6 was excluded because Sphinx 6.2.1 generates 1870+ deprecation warnings on Python 3.13 due to its use of deprecated `datetime.utcfromtimestamp()`. This is an unlikely real-world combination. + +### CI/CD Improvements + +- Updated GitHub Actions CI matrix to include Python 3.10 +- Configured codecov to use Python 3.12 + Sphinx 8 as baseline +- Implemented tokenless codecov uploads for public repository +- Added version-specific test fixtures for Sphinx 8.1 vs 8.2+ compatibility + +## πŸ“¦ Installation + +Install or upgrade via pip: + +```bash +pip install --upgrade sphinx-exercise +``` + +## πŸ”„ Migration Notes + +**If you're upgrading from v1.1.0:** +- No breaking changes +- No action required +- Python 3.10 users can now upgrade safely + +**If you're on Python 3.10:** +- You can now use sphinx-exercise v1.1.1 +- Sphinx 8 support is limited to 8.1.x on Python 3.10 +- All features work identically to newer Python versions + +## πŸ› Bug Fixes + +- Fixed test fixtures to handle Sphinx 8.1.x vs 8.2+ XML output differences +- Ensured consistent test behavior across all Python/Sphinx combinations + +## πŸ“ Full Changelog + +For complete details, see the [CHANGELOG.md](https://github.com/executablebooks/sphinx-exercise/blob/main/CHANGELOG.md). + +## πŸ™ Acknowledgments + +Thank you to all contributors and users who reported the need for Python 3.10 support! diff --git a/pyproject.toml b/pyproject.toml index f26001b..1600f3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "A Sphinx extension for producing exercises and solutions." readme = "README.md" license = { file = "LICENSE" } -requires-python = ">=3.11" +requires-python = ">=3.10" authors = [ { name = "QuantEcon", email = "admin@quantecon.org" }, ] @@ -22,6 +22,7 @@ classifiers = [ "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", diff --git a/sphinx_exercise/__init__.py b/sphinx_exercise/__init__.py index 37d1700..16a5b78 100644 --- a/sphinx_exercise/__init__.py +++ b/sphinx_exercise/__init__.py @@ -7,7 +7,7 @@ :license: MIT, see LICENSE for details. """ -__version__ = "1.1.0" +__version__ = "1.1.1" from pathlib import Path from typing import Any, Dict, Set, Union, cast diff --git a/tests/test_exercise_references.py b/tests/test_exercise_references.py index 5b419e7..5409caa 100644 --- a/tests/test_exercise_references.py +++ b/tests/test_exercise_references.py @@ -2,7 +2,12 @@ import pytest import sphinx -SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" +# Sphinx 8.1.x (Python 3.10 only) has different XML output than 8.2+ +# Use .sphinx8.1 for 8.1.x, .sphinx8 for 8.2+ (the standard) +if sphinx.version_info[0] == 8 and sphinx.version_info[1] == 1: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}.{sphinx.version_info[1]}" +else: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" @pytest.mark.sphinx("html", testroot="mybook") diff --git a/tests/test_exercise_references/_enum_numref_mathtitle.sphinx8.1.html b/tests/test_exercise_references/_enum_numref_mathtitle.sphinx8.1.html new file mode 100644 index 0000000..16a3e5b --- /dev/null +++ b/tests/test_exercise_references/_enum_numref_mathtitle.sphinx8.1.html @@ -0,0 +1,6 @@ +

This is a reference Exercise 1.

+

This is a second reference some text 1.

+

This is a third reference some text 1.

+

This is a fourth reference some text Exercise.

+

_enum_numref_title

+

_unenum_mathtitle_label

\ No newline at end of file diff --git a/tests/test_exercise_references/_enum_numref_notitle.sphinx8.1.html b/tests/test_exercise_references/_enum_numref_notitle.sphinx8.1.html new file mode 100644 index 0000000..eb699a4 --- /dev/null +++ b/tests/test_exercise_references/_enum_numref_notitle.sphinx8.1.html @@ -0,0 +1,6 @@ +

This is a reference Exercise 2.

+

This is a second reference some text 2.

+

This is a third reference some text 2.

+

This is a fourth reference some text Exercise.

+

_enum_ref_mathtitle

+

_enum_numref_title

\ No newline at end of file diff --git a/tests/test_exercise_references/_enum_numref_placeholders.sphinx8.1.html b/tests/test_exercise_references/_enum_numref_placeholders.sphinx8.1.html new file mode 100644 index 0000000..9bc2e26 --- /dev/null +++ b/tests/test_exercise_references/_enum_numref_placeholders.sphinx8.1.html @@ -0,0 +1,12 @@ +

This reference does not include math some 3 text %s test Exercise.

+

This reference does not include math some 3 text %s test.

+

This reference does not include math some Exercise text %s test.

+

This reference does not include math some Exercise text 3 test.

+

This reference does not include math some 3 text test.

+

This reference includes math some 1 text %s test Exercise.

+

This reference includes math some 1 text %s test.

+

This reference includes math some Exercise text %s test.

+

This reference includes math some Exercise text 1 test.

+

This reference includes math some 1 text test.

+

_unenum_numref_mathtitle

+

_enum_duplicate_label

\ No newline at end of file diff --git a/tests/test_exercise_references/_enum_numref_title.sphinx8.1.html b/tests/test_exercise_references/_enum_numref_title.sphinx8.1.html new file mode 100644 index 0000000..e3e637c --- /dev/null +++ b/tests/test_exercise_references/_enum_numref_title.sphinx8.1.html @@ -0,0 +1,6 @@ +

This is a reference Exercise 3.

+

This is a second reference some text 3.

+

This is a third reference some text 3.

+

This is a fourth reference some text Exercise.

+

_enum_numref_notitle

+

_enum_numref_mathtitle

\ No newline at end of file diff --git a/tests/test_exercise_references/_enum_ref_mathtitle.sphinx8.1.html b/tests/test_exercise_references/_enum_ref_mathtitle.sphinx8.1.html new file mode 100644 index 0000000..e12e85d --- /dev/null +++ b/tests/test_exercise_references/_enum_ref_mathtitle.sphinx8.1.html @@ -0,0 +1,4 @@ +

This is a reference Exercise 1.

+

This is a second reference some text.

+

_enum_ref_title

+

_enum_numref_notitle

\ No newline at end of file diff --git a/tests/test_exercise_references/_enum_ref_notitle.sphinx8.1.html b/tests/test_exercise_references/_enum_ref_notitle.sphinx8.1.html new file mode 100644 index 0000000..2f1474c --- /dev/null +++ b/tests/test_exercise_references/_enum_ref_notitle.sphinx8.1.html @@ -0,0 +1,4 @@ +

This is a reference Exercise 2.

+

This is a second reference some text.

+

_enum_title_nolabel

+

_enum_ref_title

\ No newline at end of file diff --git a/tests/test_exercise_references/_enum_ref_title.sphinx8.1.html b/tests/test_exercise_references/_enum_ref_title.sphinx8.1.html new file mode 100644 index 0000000..53e83f8 --- /dev/null +++ b/tests/test_exercise_references/_enum_ref_title.sphinx8.1.html @@ -0,0 +1,4 @@ +

This is a reference Exercise 3.

+

This is a second reference some text.

+

_enum_ref_notitle

+

_enum_ref_mathtitle

\ No newline at end of file diff --git a/tests/test_exercise_references/_unenum_numref_mathtitle.sphinx8.1.html b/tests/test_exercise_references/_unenum_numref_mathtitle.sphinx8.1.html new file mode 100644 index 0000000..0773678 --- /dev/null +++ b/tests/test_exercise_references/_unenum_numref_mathtitle.sphinx8.1.html @@ -0,0 +1,6 @@ +

This is a reference unen-exc-label-math.

+

This is a second reference some text %s.

+

This is a third reference some text {number}.

+

This is a fourth reference some text {name}.

+

_unenum_numref_title

+

_enum_numref_placeholders

\ No newline at end of file diff --git a/tests/test_exercise_references/_unenum_numref_notitle.sphinx8.1.html b/tests/test_exercise_references/_unenum_numref_notitle.sphinx8.1.html new file mode 100644 index 0000000..a7329f2 --- /dev/null +++ b/tests/test_exercise_references/_unenum_numref_notitle.sphinx8.1.html @@ -0,0 +1,6 @@ +

This is a reference unen-exc-notitle.

+

This is a second reference some text %s.

+

This is a third reference some text {number}.

+

This is a fourth reference some text {name}.

+

_unenum_ref_mathtitle

+

_unenum_numref_title

\ No newline at end of file diff --git a/tests/test_exercise_references/_unenum_numref_title.sphinx8.1.html b/tests/test_exercise_references/_unenum_numref_title.sphinx8.1.html new file mode 100644 index 0000000..25c62f2 --- /dev/null +++ b/tests/test_exercise_references/_unenum_numref_title.sphinx8.1.html @@ -0,0 +1,6 @@ +

This is a reference unen-exc-label.

+

This is a second reference some text %s.

+

This is a third reference some text {number}.

+

This is a fourth reference some text {name}.

+

_unenum_numref_notitle

+

_unenum_numref_mathtitle

\ No newline at end of file diff --git a/tests/test_exercise_references/_unenum_ref_mathtitle.sphinx8.1.html b/tests/test_exercise_references/_unenum_ref_mathtitle.sphinx8.1.html new file mode 100644 index 0000000..3a9cdc0 --- /dev/null +++ b/tests/test_exercise_references/_unenum_ref_mathtitle.sphinx8.1.html @@ -0,0 +1,4 @@ +

This is a reference Exercise.

+

This is a second reference some text.

+

_unenum_ref_title

+

_unenum_numref_notitle

\ No newline at end of file diff --git a/tests/test_exercise_references/_unenum_ref_notitle.sphinx8.1.html b/tests/test_exercise_references/_unenum_ref_notitle.sphinx8.1.html new file mode 100644 index 0000000..9678f3d --- /dev/null +++ b/tests/test_exercise_references/_unenum_ref_notitle.sphinx8.1.html @@ -0,0 +1,4 @@ +

This is a reference Exercise.

+

This is a second reference some text.

+

_unenum_title_nolabel

+

_unenum_ref_title

\ No newline at end of file diff --git a/tests/test_exercise_references/_unenum_ref_title.sphinx8.1.html b/tests/test_exercise_references/_unenum_ref_title.sphinx8.1.html new file mode 100644 index 0000000..f9e2427 --- /dev/null +++ b/tests/test_exercise_references/_unenum_ref_title.sphinx8.1.html @@ -0,0 +1,4 @@ +

This is a reference Exercise.

+

This is a second reference some text.

+

_unenum_ref_notitle

+

_unenum_ref_mathtitle

\ No newline at end of file diff --git a/tests/test_gateddirective.py b/tests/test_gateddirective.py index 8edbe70..7e3e180 100644 --- a/tests/test_gateddirective.py +++ b/tests/test_gateddirective.py @@ -17,7 +17,12 @@ def strip_escseq(text: str) -> str: return re.sub(r"\x1b\[[0-9;]*m", "", text) -SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" +# Sphinx 8.1.x (Python 3.10 only) has different XML output than 8.2+ +# Use .sphinx8.1 for 8.1.x, .sphinx8 for 8.2+ (the standard) +if sphinx.version_info[0] == 8 and sphinx.version_info[1] == 1: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}.{sphinx.version_info[1]}" +else: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" @pytest.mark.sphinx("html", testroot="gateddirective") diff --git a/tests/test_gateddirective/exercise-gated-0.sphinx8.1.html b/tests/test_gateddirective/exercise-gated-0.sphinx8.1.html new file mode 100644 index 0000000..efd2440 --- /dev/null +++ b/tests/test_gateddirective/exercise-gated-0.sphinx8.1.html @@ -0,0 +1,9 @@ +
+

Exercise 3

+
+

Replicate this figure using matplotlib

+
+_images/sphx_glr_cohere_001_2_0x.png +
+
+
\ No newline at end of file diff --git a/tests/test_gateddirective/exercise-gated-1.sphinx8.1.html b/tests/test_gateddirective/exercise-gated-1.sphinx8.1.html new file mode 100644 index 0000000..bded47e --- /dev/null +++ b/tests/test_gateddirective/exercise-gated-1.sphinx8.1.html @@ -0,0 +1,8 @@ +
+

Exercise 4 (Replicate Matplotlib Plot)

+
+
+_images/sphx_glr_cohere_001_2_0x.png +
+
+
\ No newline at end of file diff --git a/tests/test_gateddirective/exercise-gated.sphinx8.1.xml b/tests/test_gateddirective/exercise-gated.sphinx8.1.xml new file mode 100644 index 0000000..40285bf --- /dev/null +++ b/tests/test_gateddirective/exercise-gated.sphinx8.1.xml @@ -0,0 +1,24 @@ + +
+ + Gated Exercises + <paragraph> + Some Gated reference exercises + <exercise_enumerable_node classes="exercise" docname="exercise-gated" hidden="False" ids="gated-exercise-1" label="gated-exercise-1" names="gated-exercise-1" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <section ids="exercise-content"> + <paragraph> + Replicate this figure using matplotlib + <figure> + <image candidates="{'*': 'sphx_glr_cohere_001_2_0x.png'}" uri="sphx_glr_cohere_001_2_0x.png"> + <paragraph> + and another version with a title embedded + <exercise_enumerable_node classes="exercise" docname="exercise-gated" hidden="False" ids="gated-exercise-2" label="gated-exercise-2" names="gated-exercise-2" serial_number="1" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + Replicate Matplotlib Plot + <section ids="exercise-content"> + <figure> + <image candidates="{'*': 'sphx_glr_cohere_001_2_0x.png'}" uri="sphx_glr_cohere_001_2_0x.png"> diff --git a/tests/test_gateddirective/solution-exercise-0.sphinx8.1.html b/tests/test_gateddirective/solution-exercise-0.sphinx8.1.html new file mode 100644 index 0000000..609f4a5 --- /dev/null +++ b/tests/test_gateddirective/solution-exercise-0.sphinx8.1.html @@ -0,0 +1,43 @@ +<div class="solution admonition" id="solution-gated-1"> +<p class="admonition-title">Solution to<a class="reference internal" href="exercise.html#exercise-1"> Exercise 1</a></p> +<section id="solution-content"> +<p>This is a solution to Non-Gated Exercise 1</p> +<div class="cell docutils container"> +<div class="cell_input docutils container"> +<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">numpy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">np</span> +<span class="kn">import</span><span class="w"> </span><span class="nn">matplotlib.pyplot</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">plt</span> + +<span class="c1"># Fixing random state for reproducibility</span> +<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">19680801</span><span class="p">)</span> + +<span class="n">dt</span> <span class="o">=</span> <span class="mf">0.01</span> +<span class="n">t</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">nse1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 1</span> +<span class="n">nse2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 2</span> + +<span class="c1"># Two signals with a coherent part at 10Hz and a random part</span> +<span class="n">s1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse1</span> +<span class="n">s2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse2</span> + +<span class="n">fig</span><span class="p">,</span> <span class="n">axs</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">s1</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'time'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'s1 and s2'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">grid</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span> + +<span class="n">cxy</span><span class="p">,</span> <span class="n">f</span> <span class="o">=</span> <span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">cohere</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">,</span> <span class="n">NFFT</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span> <span class="n">Fs</span><span class="o">=</span><span class="mf">1.</span> <span class="o">/</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'coherence'</span><span class="p">)</span> + +<span class="n">fig</span><span class="o">.</span><span class="n">tight_layout</span><span class="p">()</span> +<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span> +</pre></div> +</div> +</div> +<div class="cell_output docutils container"> +<img alt="_images/IMAGEHASH.png" src="_images/IMAGEHASH.png"/> +</div> +</div> +<p>With some follow up text to the solution</p> +</section> +</div> \ No newline at end of file diff --git a/tests/test_gateddirective/solution-exercise-1.sphinx8.1.html b/tests/test_gateddirective/solution-exercise-1.sphinx8.1.html new file mode 100644 index 0000000..912e9fe --- /dev/null +++ b/tests/test_gateddirective/solution-exercise-1.sphinx8.1.html @@ -0,0 +1,43 @@ +<div class="solution admonition" id="solution-gated-2"> +<p class="admonition-title">Solution to<a class="reference internal" href="exercise.html#exercise-2"> Exercise 2 (Replicate Matplotlib Plot)</a></p> +<section id="solution-content"> +<p>This is a solution to Non-Gated Exercise 1</p> +<div class="cell docutils container"> +<div class="cell_input docutils container"> +<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">numpy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">np</span> +<span class="kn">import</span><span class="w"> </span><span class="nn">matplotlib.pyplot</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">plt</span> + +<span class="c1"># Fixing random state for reproducibility</span> +<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">19680801</span><span class="p">)</span> + +<span class="n">dt</span> <span class="o">=</span> <span class="mf">0.01</span> +<span class="n">t</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">nse1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 1</span> +<span class="n">nse2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 2</span> + +<span class="c1"># Two signals with a coherent part at 10Hz and a random part</span> +<span class="n">s1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse1</span> +<span class="n">s2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse2</span> + +<span class="n">fig</span><span class="p">,</span> <span class="n">axs</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">s1</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'time'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'s1 and s2'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">grid</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span> + +<span class="n">cxy</span><span class="p">,</span> <span class="n">f</span> <span class="o">=</span> <span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">cohere</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">,</span> <span class="n">NFFT</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span> <span class="n">Fs</span><span class="o">=</span><span class="mf">1.</span> <span class="o">/</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'coherence'</span><span class="p">)</span> + +<span class="n">fig</span><span class="o">.</span><span class="n">tight_layout</span><span class="p">()</span> +<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span> +</pre></div> +</div> +</div> +<div class="cell_output docutils container"> +<img alt="_images/IMAGEHASH.png" src="_images/IMAGEHASH.png"/> +</div> +</div> +<p>With some follow up text to the solution</p> +</section> +</div> \ No newline at end of file diff --git a/tests/test_gateddirective/solution-exercise-gated-0.sphinx8.1.html b/tests/test_gateddirective/solution-exercise-gated-0.sphinx8.1.html new file mode 100644 index 0000000..cb426ea --- /dev/null +++ b/tests/test_gateddirective/solution-exercise-gated-0.sphinx8.1.html @@ -0,0 +1,43 @@ +<div class="solution admonition" id="gated-exercise-solution-1"> +<p class="admonition-title">Solution to<a class="reference internal" href="exercise-gated.html#gated-exercise-1"> Exercise 3</a></p> +<section id="solution-content"> +<p>This is a solution to Gated Exercise 1</p> +<div class="cell docutils container"> +<div class="cell_input docutils container"> +<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">numpy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">np</span> +<span class="kn">import</span><span class="w"> </span><span class="nn">matplotlib.pyplot</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">plt</span> + +<span class="c1"># Fixing random state for reproducibility</span> +<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">19680801</span><span class="p">)</span> + +<span class="n">dt</span> <span class="o">=</span> <span class="mf">0.01</span> +<span class="n">t</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">nse1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 1</span> +<span class="n">nse2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 2</span> + +<span class="c1"># Two signals with a coherent part at 10Hz and a random part</span> +<span class="n">s1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse1</span> +<span class="n">s2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse2</span> + +<span class="n">fig</span><span class="p">,</span> <span class="n">axs</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">s1</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'time'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'s1 and s2'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">grid</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span> + +<span class="n">cxy</span><span class="p">,</span> <span class="n">f</span> <span class="o">=</span> <span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">cohere</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">,</span> <span class="n">NFFT</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span> <span class="n">Fs</span><span class="o">=</span><span class="mf">1.</span> <span class="o">/</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'coherence'</span><span class="p">)</span> + +<span class="n">fig</span><span class="o">.</span><span class="n">tight_layout</span><span class="p">()</span> +<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span> +</pre></div> +</div> +</div> +<div class="cell_output docutils container"> +<img alt="_images/IMAGEHASH.png" src="_images/IMAGEHASH.png"/> +</div> +</div> +<p>With some follow up text to the solution</p> +</section> +</div> \ No newline at end of file diff --git a/tests/test_gateddirective/solution-exercise-gated-1.sphinx8.1.html b/tests/test_gateddirective/solution-exercise-gated-1.sphinx8.1.html new file mode 100644 index 0000000..76bf8b2 --- /dev/null +++ b/tests/test_gateddirective/solution-exercise-gated-1.sphinx8.1.html @@ -0,0 +1,43 @@ +<div class="solution admonition" id="gated-exercise-solution-2"> +<p class="admonition-title">Solution to<a class="reference internal" href="exercise-gated.html#gated-exercise-2"> Exercise 4 (Replicate Matplotlib Plot)</a></p> +<section id="solution-content"> +<p>This is a solution to Gated Exercise 2</p> +<div class="cell docutils container"> +<div class="cell_input docutils container"> +<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">numpy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">np</span> +<span class="kn">import</span><span class="w"> </span><span class="nn">matplotlib.pyplot</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">plt</span> + +<span class="c1"># Fixing random state for reproducibility</span> +<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">19680801</span><span class="p">)</span> + +<span class="n">dt</span> <span class="o">=</span> <span class="mf">0.01</span> +<span class="n">t</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">nse1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 1</span> +<span class="n">nse2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="c1"># white noise 2</span> + +<span class="c1"># Two signals with a coherent part at 10Hz and a random part</span> +<span class="n">s1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse1</span> +<span class="n">s2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">+</span> <span class="n">nse2</span> + +<span class="n">fig</span><span class="p">,</span> <span class="n">axs</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">s1</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'time'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'s1 and s2'</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">grid</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span> + +<span class="n">cxy</span><span class="p">,</span> <span class="n">f</span> <span class="o">=</span> <span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">cohere</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">,</span> <span class="n">NFFT</span><span class="o">=</span><span class="mi">256</span><span class="p">,</span> <span class="n">Fs</span><span class="o">=</span><span class="mf">1.</span> <span class="o">/</span> <span class="n">dt</span><span class="p">)</span> +<span class="n">axs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'coherence'</span><span class="p">)</span> + +<span class="n">fig</span><span class="o">.</span><span class="n">tight_layout</span><span class="p">()</span> +<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span> +</pre></div> +</div> +</div> +<div class="cell_output docutils container"> +<img alt="_images/IMAGEHASH.png" src="_images/IMAGEHASH.png"/> +</div> +</div> +<p>With some follow up text to the solution</p> +</section> +</div> \ No newline at end of file diff --git a/tests/test_gateddirective/solution-exercise-gated.sphinx8.1.xml b/tests/test_gateddirective/solution-exercise-gated.sphinx8.1.xml new file mode 100644 index 0000000..87e88a5 --- /dev/null +++ b/tests/test_gateddirective/solution-exercise-gated.sphinx8.1.xml @@ -0,0 +1,111 @@ +<document source="solution-exercise-gated.md"> + <section ids="gated-solutions-to-exercise-gated-md" names="gated\ solutions\ to\ exercise-gated.md"> + <title> + Gated Solutions to exercise-gated.md + <paragraph> + A solution using the gated directive + <solution_node classes="solution" docname="solution-exercise-gated" hidden="False" ids="gated-exercise-solution-1" label="gated-exercise-solution-1" names="gated-exercise-solution-1" serial_number="0" target_label="gated-exercise-1" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + This is a solution to Gated Exercise 1 + <container cell_index="1" cell_metadata="{}" classes="cell" exec_count="1" nb_element="cell_code"> + <container classes="cell_input" nb_element="cell_code_source"> + <literal_block language="ipython3" xml:space="preserve"> + import numpy as np + import matplotlib.pyplot as plt + + # Fixing random state for reproducibility + np.random.seed(19680801) + + dt = 0.01 + t = np.arange(0, 30, dt) + nse1 = np.random.randn(len(t)) # white noise 1 + nse2 = np.random.randn(len(t)) # white noise 2 + + # Two signals with a coherent part at 10Hz and a random part + s1 = np.sin(2 * np.pi * 10 * t) + nse1 + s2 = np.sin(2 * np.pi * 10 * t) + nse2 + + fig, axs = plt.subplots(2, 1) + axs[0].plot(t, s1, t, s2) + axs[0].set_xlim(0, 2) + axs[0].set_xlabel('time') + axs[0].set_ylabel('s1 and s2') + axs[0].grid(True) + + cxy, f = axs[1].cohere(s1, s2, NFFT=256, Fs=1. / dt) + axs[1].set_ylabel('coherence') + + fig.tight_layout() + plt.show() + <container classes="cell_output" nb_element="cell_code_output"> + <container nb_element="mime_bundle"> + <container mime_type="text/plain"> + <literal_block classes="output text_plain" language="myst-ansi" xml:space="preserve"> + <Figure size 640x480 with 2 Axes> + <container mime_type="image/png"> + <image candidates="{'*': '_build/jupyter_execute/IMAGEHASH.png'}" uri="_build/jupyter_execute/IMAGEHASH.png"> + <paragraph> + With some follow up text to the solution + <paragraph> + and then a solution to + <pending_xref refdoc="solution-exercise-gated" refdomain="std" refexplicit="False" reftarget="gated-exercise-2" reftype="ref" refwarn="True"> + <inline classes="xref std std-ref"> + gated-exercise-2 + <paragraph> + A solution using the gated directive + <solution_node classes="solution" docname="solution-exercise-gated" hidden="False" ids="gated-exercise-solution-2" label="gated-exercise-solution-2" names="gated-exercise-solution-2" serial_number="1" target_label="gated-exercise-2" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + This is a solution to Gated Exercise 2 + <container cell_index="3" cell_metadata="{}" classes="cell" exec_count="2" nb_element="cell_code"> + <container classes="cell_input" nb_element="cell_code_source"> + <literal_block language="ipython3" xml:space="preserve"> + import numpy as np + import matplotlib.pyplot as plt + + # Fixing random state for reproducibility + np.random.seed(19680801) + + dt = 0.01 + t = np.arange(0, 30, dt) + nse1 = np.random.randn(len(t)) # white noise 1 + nse2 = np.random.randn(len(t)) # white noise 2 + + # Two signals with a coherent part at 10Hz and a random part + s1 = np.sin(2 * np.pi * 10 * t) + nse1 + s2 = np.sin(2 * np.pi * 10 * t) + nse2 + + fig, axs = plt.subplots(2, 1) + axs[0].plot(t, s1, t, s2) + axs[0].set_xlim(0, 2) + axs[0].set_xlabel('time') + axs[0].set_ylabel('s1 and s2') + axs[0].grid(True) + + cxy, f = axs[1].cohere(s1, s2, NFFT=256, Fs=1. / dt) + axs[1].set_ylabel('coherence') + + fig.tight_layout() + plt.show() + <container classes="cell_output" nb_element="cell_code_output"> + <container nb_element="mime_bundle"> + <container mime_type="text/plain"> + <literal_block classes="output text_plain" language="myst-ansi" xml:space="preserve"> + <Figure size 640x480 with 2 Axes> + <container mime_type="image/png"> + <image candidates="{'*': '_build/jupyter_execute/IMAGEHASH.png'}" uri="_build/jupyter_execute/IMAGEHASH.png"> + <paragraph> + With some follow up text to the solution + <section ids="references-to-solutions" names="references\ to\ solutions"> + <title> + References to Solutions + <paragraph> + This is a reference to + <pending_xref refdoc="solution-exercise-gated" refdomain="std" refexplicit="False" reftarget="gated-exercise-solution-1" reftype="ref" refwarn="True"> + <inline classes="xref std std-ref"> + gated-exercise-solution-1 diff --git a/tests/test_gateddirective/solution-exercise.sphinx8.1.xml b/tests/test_gateddirective/solution-exercise.sphinx8.1.xml new file mode 100644 index 0000000..29cd9d9 --- /dev/null +++ b/tests/test_gateddirective/solution-exercise.sphinx8.1.xml @@ -0,0 +1,114 @@ +<document source="solution-exercise.md"> + <section ids="gated-solutions-to-exercise-md" names="gated\ solutions\ to\ exercise.md"> + <title> + Gated Solutions to exercise.md + <paragraph> + A solution using the gated directive + <solution_node classes="solution" docname="solution-exercise" hidden="False" ids="solution-gated-1" label="solution-gated-1" names="solution-gated-1" serial_number="0" target_label="exercise-1" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + This is a solution to Non-Gated Exercise 1 + <container cell_index="1" cell_metadata="{}" classes="cell" exec_count="1" nb_element="cell_code"> + <container classes="cell_input" nb_element="cell_code_source"> + <literal_block language="ipython3" xml:space="preserve"> + import numpy as np + import matplotlib.pyplot as plt + + # Fixing random state for reproducibility + np.random.seed(19680801) + + dt = 0.01 + t = np.arange(0, 30, dt) + nse1 = np.random.randn(len(t)) # white noise 1 + nse2 = np.random.randn(len(t)) # white noise 2 + + # Two signals with a coherent part at 10Hz and a random part + s1 = np.sin(2 * np.pi * 10 * t) + nse1 + s2 = np.sin(2 * np.pi * 10 * t) + nse2 + + fig, axs = plt.subplots(2, 1) + axs[0].plot(t, s1, t, s2) + axs[0].set_xlim(0, 2) + axs[0].set_xlabel('time') + axs[0].set_ylabel('s1 and s2') + axs[0].grid(True) + + cxy, f = axs[1].cohere(s1, s2, NFFT=256, Fs=1. / dt) + axs[1].set_ylabel('coherence') + + fig.tight_layout() + plt.show() + <container classes="cell_output" nb_element="cell_code_output"> + <container nb_element="mime_bundle"> + <container mime_type="text/plain"> + <literal_block classes="output text_plain" language="myst-ansi" xml:space="preserve"> + <Figure size 640x480 with 2 Axes> + <container mime_type="image/png"> + <image candidates="{'*': '_build/jupyter_execute/IMAGEHASH.png'}" uri="_build/jupyter_execute/IMAGEHASH.png"> + <paragraph> + With some follow up text to the solution + <paragraph> + and a solution to + <pending_xref refdoc="solution-exercise" refdomain="std" refexplicit="False" reftarget="exercise-2" reftype="ref" refwarn="True"> + <inline classes="xref std std-ref"> + exercise-2 + <solution_node classes="solution" docname="solution-exercise" hidden="False" ids="solution-gated-2" label="solution-gated-2" names="solution-gated-2" serial_number="1" target_label="exercise-2" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + This is a solution to Non-Gated Exercise 1 + <container cell_index="3" cell_metadata="{}" classes="cell" exec_count="2" nb_element="cell_code"> + <container classes="cell_input" nb_element="cell_code_source"> + <literal_block language="ipython3" xml:space="preserve"> + import numpy as np + import matplotlib.pyplot as plt + + # Fixing random state for reproducibility + np.random.seed(19680801) + + dt = 0.01 + t = np.arange(0, 30, dt) + nse1 = np.random.randn(len(t)) # white noise 1 + nse2 = np.random.randn(len(t)) # white noise 2 + + # Two signals with a coherent part at 10Hz and a random part + s1 = np.sin(2 * np.pi * 10 * t) + nse1 + s2 = np.sin(2 * np.pi * 10 * t) + nse2 + + fig, axs = plt.subplots(2, 1) + axs[0].plot(t, s1, t, s2) + axs[0].set_xlim(0, 2) + axs[0].set_xlabel('time') + axs[0].set_ylabel('s1 and s2') + axs[0].grid(True) + + cxy, f = axs[1].cohere(s1, s2, NFFT=256, Fs=1. / dt) + axs[1].set_ylabel('coherence') + + fig.tight_layout() + plt.show() + <container classes="cell_output" nb_element="cell_code_output"> + <container nb_element="mime_bundle"> + <container mime_type="text/plain"> + <literal_block classes="output text_plain" language="myst-ansi" xml:space="preserve"> + <Figure size 640x480 with 2 Axes> + <container mime_type="image/png"> + <image candidates="{'*': '_build/jupyter_execute/IMAGEHASH.png'}" uri="_build/jupyter_execute/IMAGEHASH.png"> + <paragraph> + With some follow up text to the solution + <section ids="references" names="references"> + <title> + References + <paragraph> + This is a reference to + <pending_xref refdoc="solution-exercise" refdomain="std" refexplicit="False" reftarget="solution-gated-1" reftype="ref" refwarn="True"> + <inline classes="xref std std-ref"> + solution-gated-1 + <paragraph> + This is a reference to + <pending_xref refdoc="solution-exercise" refdomain="std" refexplicit="False" reftarget="solution-gated-2" reftype="ref" refwarn="True"> + <inline classes="xref std std-ref"> + solution-gated-2 diff --git a/tests/test_latex.py b/tests/test_latex.py index 368d964..e29b5bc 100644 --- a/tests/test_latex.py +++ b/tests/test_latex.py @@ -2,7 +2,12 @@ import pytest import sphinx -SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" +# Sphinx 8.1.x (Python 3.10 only) has different XML output than 8.2+ +# Use .sphinx8.1 for 8.1.x, .sphinx8 for 8.2+ (the standard) +if sphinx.version_info[0] == 8 and sphinx.version_info[1] == 1: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}.{sphinx.version_info[1]}" +else: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" @pytest.mark.sphinx("latex", testroot="simplebook") diff --git a/tests/test_latex/test_latex_build.sphinx8.1.tex b/tests/test_latex/test_latex_build.sphinx8.1.tex new file mode 100644 index 0000000..f6293f6 --- /dev/null +++ b/tests/test_latex/test_latex_build.sphinx8.1.tex @@ -0,0 +1,181 @@ +\begin{document} + +\ifdefined\shorthandoff + \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi + \ifnum\catcode`\"=\active\shorthandoff{"}\fi +\fi + +\pagestyle{empty} +\sphinxmaketitle +\pagestyle{plain} +\sphinxtableofcontents +\pagestyle{normal} +\phantomsection\label{\detokenize{index::doc}} + + +\sphinxstepscope + + +\chapter{Exercise} +\label{\detokenize{exercise:exercise}}\label{\detokenize{exercise::doc}} +\sphinxAtStartPar +A collection of exercise directives +\phantomsection \label{exercise:exercise-1} + +\begin{sphinxadmonition}{note}{Exercise 1 (\protect\(n!\protect\) factorial)} + + + +\sphinxAtStartPar +Exercise 1 about \(n!\) factorial +\end{sphinxadmonition} +\phantomsection \label{exercise:exercise-2} +\begin{sphinxadmonition}{note}{Exercise (\protect\(n!\protect\) factorial)} + + + +\sphinxAtStartPar +Exercise 2 about \(n!\) factorial +\end{sphinxadmonition} +\phantomsection \label{exercise:exercise-3} + +\begin{sphinxadmonition}{note}{Exercise 2} + + + +\sphinxAtStartPar +Exercise 3 Content with Number +\end{sphinxadmonition} +\phantomsection \label{exercise:exercise-4} +\begin{sphinxadmonition}{note}{Exercise} + + + +\sphinxAtStartPar +Exercise 4 Content with no Number +\end{sphinxadmonition} + + +\section{References} +\label{\detokenize{exercise:references}} + +\subsection{Standard References} +\label{\detokenize{exercise:standard-references}} +\sphinxAtStartPar +This is a link to \DUrole{xref}{\DUrole{std}{\DUrole{std-ref}{exercise\sphinxhyphen{}no\sphinxhyphen{}title}}} + +\sphinxAtStartPar +This is a link to \hyperref[exercise:exercise-1]{Exercise 1} + +\sphinxAtStartPar +This is a link to {\hyperref[\detokenize{exercise:exercise-2}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Exercise}}}}} + +\sphinxAtStartPar +This ia another link with custom text \hyperref[exercise:exercise-3]{Exercise 3 Custom Text} + +\sphinxAtStartPar +This ia another link with custom text {\hyperref[\detokenize{exercise:exercise-4}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Exercise 4 Custom Text}}}}} + + +\subsection{Numbered References} +\label{\detokenize{exercise:numbered-references}} +\sphinxAtStartPar +This is a numbered reference to \hyperref[exercise:exercise-1]{Exercise 1} + +\sphinxAtStartPar +This is a numbered reference to \sphinxcode{\sphinxupquote{exercise\sphinxhyphen{}2}} and should be broken as exercise 2 is not an +enumerated exercise node. + +\sphinxAtStartPar +This is a numbered reference to \hyperref[exercise:exercise-3]{Exercise 2} + +\sphinxAtStartPar +This is a numbered reference with custom text to \hyperref[exercise:exercise-3]{Custom Text with a Number 2} + +\sphinxAtStartPar +This is a numbered reference to \sphinxcode{\sphinxupquote{exercise\sphinxhyphen{}4}} and should be broken as exercise 2 is not an +enumerated exercise node. + +\sphinxAtStartPar +This is a numbered reference with custom text to \sphinxcode{\sphinxupquote{Custom Text with a Number \{number\}}} and should be broken as exercise 2 is not an +enumerated exercise node. + +\sphinxstepscope + + +\chapter{Solution} +\label{\detokenize{solution:solution}}\label{\detokenize{solution::doc}} +\sphinxAtStartPar +A collection of solution directives +\phantomsection \label{solution:solution-1} + +\begin{sphinxadmonition}{note}{Solution to Exercise 1 (\protect\(n!\protect\) factorial)} + + + +\sphinxAtStartPar +This is a solution to exercise 1 +\end{sphinxadmonition} +\phantomsection \label{solution:solution-2} + +\begin{sphinxadmonition}{note}{Solution to Exercise (\protect\(n!\protect\) factorial)} + + + +\sphinxAtStartPar +This is a solution to exercise 2 +\end{sphinxadmonition} +\phantomsection \label{solution:solution-3} + +\begin{sphinxadmonition}{note}{Solution to Exercise 2} + + + +\sphinxAtStartPar +This is a solution to exercise 3 +\end{sphinxadmonition} +\phantomsection \label{solution:solution-4} + +\begin{sphinxadmonition}{note}{Solution to Exercise} + + + +\sphinxAtStartPar +This is a solution to exercise 4 +\end{sphinxadmonition} + + +\section{References} +\label{\detokenize{solution:references}} + +\subsection{Standard References} +\label{\detokenize{solution:standard-references}} +\sphinxAtStartPar +This is a link to {\hyperref[\detokenize{solution:solution-1}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Solution to Exercise 1 (n! factorial)}}}}} + +\sphinxAtStartPar +This is a link to {\hyperref[\detokenize{solution:solution-2}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Solution to Exercise (n! factorial)}}}}} + +\sphinxAtStartPar +This is a link to {\hyperref[\detokenize{solution:solution-3}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Solution to Exercise 2}}}}} + +\sphinxAtStartPar +This is a link to {\hyperref[\detokenize{solution:solution-4}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Solution to Exercise}}}}} + +\sphinxAtStartPar +This ia another link to a different {\hyperref[\detokenize{solution:solution-1}]{\sphinxcrossref{\DUrole{std}{\DUrole{std-ref}{Solution to Exercise 1 (n! factorial)}}}}} + + +\subsection{Numbered References} +\label{\detokenize{solution:numbered-references}} +\sphinxAtStartPar +Solution nodes are not enumerated nodes so these won’t work + +\sphinxAtStartPar +This is a link to \sphinxcode{\sphinxupquote{solution\sphinxhyphen{}1}} + + + +\renewcommand{\indexname}{Index} +\printindex +\end{document} diff --git a/tests/test_solution.py b/tests/test_solution.py index 07c50bc..07f8265 100644 --- a/tests/test_solution.py +++ b/tests/test_solution.py @@ -2,7 +2,12 @@ import pytest import sphinx -SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" +# Sphinx 8.1.x (Python 3.10 only) has different XML output than 8.2+ +# Use .sphinx8.1 for 8.1.x, .sphinx8 for 8.2+ (the standard) +if sphinx.version_info[0] == 8 and sphinx.version_info[1] == 1: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}.{sphinx.version_info[1]}" +else: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" @pytest.mark.sphinx("html", testroot="mybook") diff --git a/tests/test_solution/_linked_duplicate_label.sphinx8.1.xml b/tests/test_solution/_linked_duplicate_label.sphinx8.1.xml new file mode 100644 index 0000000..911fa54 --- /dev/null +++ b/tests/test_solution/_linked_duplicate_label.sphinx8.1.xml @@ -0,0 +1,10 @@ +<document source="_linked_duplicate_label.rst"> + <section ids="linked-duplicate-label" names="_linked_duplicate_label"> + <title> + _linked_duplicate_label + <solution_node classes="solution" docname="solution/_linked_duplicate_label" hidden="False" ids="sol-duplicate-label" label="sol-duplicate-label" names="sol-duplicate-label" serial_number="0" target_label="ex-nonumber-notitle" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/_linked_enum.sphinx8.1.xml b/tests/test_solution/_linked_enum.sphinx8.1.xml new file mode 100644 index 0000000..272bd7f --- /dev/null +++ b/tests/test_solution/_linked_enum.sphinx8.1.xml @@ -0,0 +1,29 @@ +<document source="_linked_enum.rst"> + <section ids="linked-enum" names="_linked_enum"> + <title> + _linked_enum + <exercise_enumerable_node classes="exercise" docname="solution/_linked_enum" hidden="False" ids="ex-number" label="ex-number" names="ex-number" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_enum" hidden="False" ids="sol-number" label="sol-number" names="sol-number" serial_number="1" target_label="ex-number" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <math_block docname="solution/_linked_enum" label="True" nowrap="False" number="True" xml:space="preserve"> + P_t(x, y) = \mathbb 1\{x = y\} + t Q(x, y) + o(t) + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <target refid="equation-ex-math"> + <math_block docname="solution/_linked_enum" ids="equation-ex-math" label="ex-math" nowrap="False" number="1" xml:space="preserve"> + P_t(x, y) = \mathbb 1\{x = y\} + t Q(x, y) + o(t) diff --git a/tests/test_solution/_linked_enum_class.sphinx8.1.xml b/tests/test_solution/_linked_enum_class.sphinx8.1.xml new file mode 100644 index 0000000..daa32c8 --- /dev/null +++ b/tests/test_solution/_linked_enum_class.sphinx8.1.xml @@ -0,0 +1,10 @@ +<document source="_linked_enum_class.rst"> + <section ids="linked-enum-class" names="_linked_enum_class"> + <title> + _linked_enum_class + <solution_node classes="solution test-solution" docname="solution/_linked_enum_class" hidden="False" ids="solution-label" label="solution-label" names="solution-label" serial_number="0" target_label="ex-number" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/_linked_missing_arg.sphinx8.1.xml b/tests/test_solution/_linked_missing_arg.sphinx8.1.xml new file mode 100644 index 0000000..6ecb8d7 --- /dev/null +++ b/tests/test_solution/_linked_missing_arg.sphinx8.1.xml @@ -0,0 +1,4 @@ +<document source="_linked_missing_arg.rst"> + <section ids="linked-missing-arg" names="_linked_missing_arg"> + <title> + _linked_missing_arg diff --git a/tests/test_solution/_linked_unenum_mathtitle.sphinx8.1.xml b/tests/test_solution/_linked_unenum_mathtitle.sphinx8.1.xml new file mode 100644 index 0000000..d5c931a --- /dev/null +++ b/tests/test_solution/_linked_unenum_mathtitle.sphinx8.1.xml @@ -0,0 +1,24 @@ +<document source="_linked_unenum_mathtitle.rst"> + <section ids="linked-unenum-mathtitle" names="_linked_unenum_mathtitle"> + <title> + _linked_unenum_mathtitle + <exercise_node classes="exercise" docname="solution/_linked_unenum_mathtitle" hidden="False" ids="ex-nonumber-title-math" label="ex-nonumber-title-math" names="ex-nonumber-title-math" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <math> + \mathbb{R} + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_mathtitle" hidden="False" ids="sol-nonumber-title-math" label="sol-nonumber-title-math" names="sol-nonumber-title-math" serial_number="1" target_label="ex-nonumber-title-math" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/_linked_unenum_mathtitle2.sphinx8.1.xml b/tests/test_solution/_linked_unenum_mathtitle2.sphinx8.1.xml new file mode 100644 index 0000000..a369002 --- /dev/null +++ b/tests/test_solution/_linked_unenum_mathtitle2.sphinx8.1.xml @@ -0,0 +1,24 @@ +<document source="_linked_unenum_mathtitle2.rst"> + <section ids="linked-unenum-mathtitle2" names="_linked_unenum_mathtitle2"> + <title> + _linked_unenum_mathtitle2 + <exercise_node classes="exercise" docname="solution/_linked_unenum_mathtitle2" hidden="False" ids="ex-nonumber-title-math2" label="ex-nonumber-title-math2" names="ex-nonumber-title-math2" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <math> + P_t(x, y) = \mathbb 1\{x = y\} + t Q(x, y) + o(t) + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_mathtitle2" hidden="False" ids="sol-nonumber-title-math2" label="sol-nonumber-title-math2" names="sol-nonumber-title-math2" serial_number="1" target_label="ex-nonumber-title-math2" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/_linked_unenum_notitle.sphinx8.1.xml b/tests/test_solution/_linked_unenum_notitle.sphinx8.1.xml new file mode 100644 index 0000000..8140aec --- /dev/null +++ b/tests/test_solution/_linked_unenum_notitle.sphinx8.1.xml @@ -0,0 +1,20 @@ +<document source="_linked_unenum_notitle.rst"> + <section ids="linked-unenum-notitle" names="_linked_unenum_notitle"> + <title> + _linked_unenum_notitle + <exercise_node classes="exercise" docname="solution/_linked_unenum_notitle" hidden="False" ids="ex-nonumber-notitle" label="ex-nonumber-notitle" names="ex-nonumber-notitle" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_notitle" hidden="False" ids="sol-nonumber-notitle" label="sol-nonumber-notitle" names="sol-nonumber-notitle" serial_number="1" target_label="ex-nonumber-notitle" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/_linked_unenum_title.sphinx8.1.xml b/tests/test_solution/_linked_unenum_title.sphinx8.1.xml new file mode 100644 index 0000000..da1dc3f --- /dev/null +++ b/tests/test_solution/_linked_unenum_title.sphinx8.1.xml @@ -0,0 +1,22 @@ +<document source="_linked_unenum_title.rst"> + <section ids="linked-unenum-title" names="_linked_unenum_title"> + <title> + _linked_unenum_title + <exercise_node classes="exercise" docname="solution/_linked_unenum_title" hidden="False" ids="ex-nonumber-title" label="ex-nonumber-title" names="ex-nonumber-title" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_title" hidden="False" ids="sol-nonumber-title" label="sol-nonumber-title" names="sol-nonumber-title" serial_number="1" target_label="ex-nonumber-title" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/_linked_wrong_targetlabel.sphinx8.1.xml b/tests/test_solution/_linked_wrong_targetlabel.sphinx8.1.xml new file mode 100644 index 0000000..b03b9ac --- /dev/null +++ b/tests/test_solution/_linked_wrong_targetlabel.sphinx8.1.xml @@ -0,0 +1,10 @@ +<document source="_linked_wrong_targetlabel.rst"> + <section ids="linked-wrong-targetlabel" names="_linked_wrong_targetlabel"> + <title> + _linked_wrong_targetlabel + <solution_node classes="solution" docname="solution/_linked_wrong_targetlabel" hidden="False" ids="solution/_linked_wrong_targetlabel-solution-0" label="solution/_linked_wrong_targetlabel-solution-0" names="solution/_linked_wrong_targetlabel-solution-0" serial_number="0" target_label="wrong-ex-label" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_duplicate_label.sphinx8.1.xml b/tests/test_solution/solution/_linked_duplicate_label.sphinx8.1.xml new file mode 100644 index 0000000..911fa54 --- /dev/null +++ b/tests/test_solution/solution/_linked_duplicate_label.sphinx8.1.xml @@ -0,0 +1,10 @@ +<document source="_linked_duplicate_label.rst"> + <section ids="linked-duplicate-label" names="_linked_duplicate_label"> + <title> + _linked_duplicate_label + <solution_node classes="solution" docname="solution/_linked_duplicate_label" hidden="False" ids="sol-duplicate-label" label="sol-duplicate-label" names="sol-duplicate-label" serial_number="0" target_label="ex-nonumber-notitle" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_enum.sphinx8.1.xml b/tests/test_solution/solution/_linked_enum.sphinx8.1.xml new file mode 100644 index 0000000..272bd7f --- /dev/null +++ b/tests/test_solution/solution/_linked_enum.sphinx8.1.xml @@ -0,0 +1,29 @@ +<document source="_linked_enum.rst"> + <section ids="linked-enum" names="_linked_enum"> + <title> + _linked_enum + <exercise_enumerable_node classes="exercise" docname="solution/_linked_enum" hidden="False" ids="ex-number" label="ex-number" names="ex-number" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_enum" hidden="False" ids="sol-number" label="sol-number" names="sol-number" serial_number="1" target_label="ex-number" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <math_block docname="solution/_linked_enum" label="True" nowrap="False" number="True" xml:space="preserve"> + P_t(x, y) = \mathbb 1\{x = y\} + t Q(x, y) + o(t) + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <target refid="equation-ex-math"> + <math_block docname="solution/_linked_enum" ids="equation-ex-math" label="ex-math" nowrap="False" number="1" xml:space="preserve"> + P_t(x, y) = \mathbb 1\{x = y\} + t Q(x, y) + o(t) diff --git a/tests/test_solution/solution/_linked_enum_class.sphinx8.1.xml b/tests/test_solution/solution/_linked_enum_class.sphinx8.1.xml new file mode 100644 index 0000000..daa32c8 --- /dev/null +++ b/tests/test_solution/solution/_linked_enum_class.sphinx8.1.xml @@ -0,0 +1,10 @@ +<document source="_linked_enum_class.rst"> + <section ids="linked-enum-class" names="_linked_enum_class"> + <title> + _linked_enum_class + <solution_node classes="solution test-solution" docname="solution/_linked_enum_class" hidden="False" ids="solution-label" label="solution-label" names="solution-label" serial_number="0" target_label="ex-number" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_missing_arg.sphinx8.1.xml b/tests/test_solution/solution/_linked_missing_arg.sphinx8.1.xml new file mode 100644 index 0000000..6ecb8d7 --- /dev/null +++ b/tests/test_solution/solution/_linked_missing_arg.sphinx8.1.xml @@ -0,0 +1,4 @@ +<document source="_linked_missing_arg.rst"> + <section ids="linked-missing-arg" names="_linked_missing_arg"> + <title> + _linked_missing_arg diff --git a/tests/test_solution/solution/_linked_unenum_mathtitle.sphinx8.1.xml b/tests/test_solution/solution/_linked_unenum_mathtitle.sphinx8.1.xml new file mode 100644 index 0000000..d5c931a --- /dev/null +++ b/tests/test_solution/solution/_linked_unenum_mathtitle.sphinx8.1.xml @@ -0,0 +1,24 @@ +<document source="_linked_unenum_mathtitle.rst"> + <section ids="linked-unenum-mathtitle" names="_linked_unenum_mathtitle"> + <title> + _linked_unenum_mathtitle + <exercise_node classes="exercise" docname="solution/_linked_unenum_mathtitle" hidden="False" ids="ex-nonumber-title-math" label="ex-nonumber-title-math" names="ex-nonumber-title-math" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <math> + \mathbb{R} + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_mathtitle" hidden="False" ids="sol-nonumber-title-math" label="sol-nonumber-title-math" names="sol-nonumber-title-math" serial_number="1" target_label="ex-nonumber-title-math" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_unenum_mathtitle2.sphinx8.1.xml b/tests/test_solution/solution/_linked_unenum_mathtitle2.sphinx8.1.xml new file mode 100644 index 0000000..a369002 --- /dev/null +++ b/tests/test_solution/solution/_linked_unenum_mathtitle2.sphinx8.1.xml @@ -0,0 +1,24 @@ +<document source="_linked_unenum_mathtitle2.rst"> + <section ids="linked-unenum-mathtitle2" names="_linked_unenum_mathtitle2"> + <title> + _linked_unenum_mathtitle2 + <exercise_node classes="exercise" docname="solution/_linked_unenum_mathtitle2" hidden="False" ids="ex-nonumber-title-math2" label="ex-nonumber-title-math2" names="ex-nonumber-title-math2" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <math> + P_t(x, y) = \mathbb 1\{x = y\} + t Q(x, y) + o(t) + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_mathtitle2" hidden="False" ids="sol-nonumber-title-math2" label="sol-nonumber-title-math2" names="sol-nonumber-title-math2" serial_number="1" target_label="ex-nonumber-title-math2" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_unenum_notitle.sphinx8.1.xml b/tests/test_solution/solution/_linked_unenum_notitle.sphinx8.1.xml new file mode 100644 index 0000000..8140aec --- /dev/null +++ b/tests/test_solution/solution/_linked_unenum_notitle.sphinx8.1.xml @@ -0,0 +1,20 @@ +<document source="_linked_unenum_notitle.rst"> + <section ids="linked-unenum-notitle" names="_linked_unenum_notitle"> + <title> + _linked_unenum_notitle + <exercise_node classes="exercise" docname="solution/_linked_unenum_notitle" hidden="False" ids="ex-nonumber-notitle" label="ex-nonumber-notitle" names="ex-nonumber-notitle" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_notitle" hidden="False" ids="sol-nonumber-notitle" label="sol-nonumber-notitle" names="sol-nonumber-notitle" serial_number="1" target_label="ex-nonumber-notitle" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_unenum_title.sphinx8.1.xml b/tests/test_solution/solution/_linked_unenum_title.sphinx8.1.xml new file mode 100644 index 0000000..da1dc3f --- /dev/null +++ b/tests/test_solution/solution/_linked_unenum_title.sphinx8.1.xml @@ -0,0 +1,22 @@ +<document source="_linked_unenum_title.rst"> + <section ids="linked-unenum-title" names="_linked_unenum_title"> + <title> + _linked_unenum_title + <exercise_node classes="exercise" docname="solution/_linked_unenum_title" hidden="False" ids="ex-nonumber-title" label="ex-nonumber-title" names="ex-nonumber-title" serial_number="0" title="Exercise" type="exercise"> + <exercise_title> + Exercise + <exercise_subtitle> + This is a title + <section ids="exercise-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + <paragraph> + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + <paragraph> + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <solution_node classes="solution" docname="solution/_linked_unenum_title" hidden="False" ids="sol-nonumber-title" label="sol-nonumber-title" names="sol-nonumber-title" serial_number="1" target_label="ex-nonumber-title" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution/solution/_linked_wrong_targetlabel.sphinx8.1.xml b/tests/test_solution/solution/_linked_wrong_targetlabel.sphinx8.1.xml new file mode 100644 index 0000000..b03b9ac --- /dev/null +++ b/tests/test_solution/solution/_linked_wrong_targetlabel.sphinx8.1.xml @@ -0,0 +1,10 @@ +<document source="_linked_wrong_targetlabel.rst"> + <section ids="linked-wrong-targetlabel" names="_linked_wrong_targetlabel"> + <title> + _linked_wrong_targetlabel + <solution_node classes="solution" docname="solution/_linked_wrong_targetlabel" hidden="False" ids="solution/_linked_wrong_targetlabel-solution-0" label="solution/_linked_wrong_targetlabel-solution-0" names="solution/_linked_wrong_targetlabel-solution-0" serial_number="0" target_label="wrong-ex-label" title="Solution to" type="solution"> + <solution_title> + Solution to + <section ids="solution-content"> + <paragraph> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. diff --git a/tests/test_solution_references.py b/tests/test_solution_references.py index 0e789b4..8b9463b 100644 --- a/tests/test_solution_references.py +++ b/tests/test_solution_references.py @@ -2,7 +2,12 @@ import pytest import sphinx -SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" +# Sphinx 8.1.x (Python 3.10 only) has different XML output than 8.2+ +# Use .sphinx8.1 for 8.1.x, .sphinx8 for 8.2+ (the standard) +if sphinx.version_info[0] == 8 and sphinx.version_info[1] == 1: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}.{sphinx.version_info[1]}" +else: + SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}" @pytest.mark.sphinx("html", testroot="mybook") diff --git a/tests/test_solution_references/_linked_ref_enum.sphinx8.1.html b/tests/test_solution_references/_linked_ref_enum.sphinx8.1.html new file mode 100644 index 0000000..c8d1365 --- /dev/null +++ b/tests/test_solution_references/_linked_ref_enum.sphinx8.1.html @@ -0,0 +1,4 @@ +<p>referencing: <a class="reference internal" href="_linked_enum.html#sol-number"><span class="std std-ref">Solution to</span></a>.</p> +<p>referencing: <a class="reference internal" href="_linked_enum.html#sol-number"><span class="std std-ref">simple solution with number</span></a>.</p> +<p class="topless"><a href="_linked_ref_unenum_mathtitle2.html" title="previous chapter">_linked_ref_unenum_mathtitle2</a></p> +<p class="topless"><a href="_linked_ref_wronglabel.html" title="next chapter">_linked_ref_wronglabel</a></p> \ No newline at end of file diff --git a/tests/test_solution_references/_linked_ref_unenum_mathtitle.sphinx8.1.html b/tests/test_solution_references/_linked_ref_unenum_mathtitle.sphinx8.1.html new file mode 100644 index 0000000..fb0f469 --- /dev/null +++ b/tests/test_solution_references/_linked_ref_unenum_mathtitle.sphinx8.1.html @@ -0,0 +1,4 @@ +<p>referencing: <a class="reference internal" href="_linked_unenum_mathtitle.html#sol-nonumber-title-math"><span class="std std-ref">Solution to</span></a>.</p> +<p>referencing: <a class="reference internal" href="_linked_unenum_mathtitle.html#sol-nonumber-title-math"><span class="std std-ref">exercise with nonumber but with inline math title</span></a>.</p> +<p class="topless"><a href="_linked_ref_unenum_title.html" title="previous chapter">_linked_ref_unenum_title</a></p> +<p class="topless"><a href="_linked_ref_unenum_mathtitle2.html" title="next chapter">_linked_ref_unenum_mathtitle2</a></p> \ No newline at end of file diff --git a/tests/test_solution_references/_linked_ref_unenum_mathtitle2.sphinx8.1.html b/tests/test_solution_references/_linked_ref_unenum_mathtitle2.sphinx8.1.html new file mode 100644 index 0000000..d141d88 --- /dev/null +++ b/tests/test_solution_references/_linked_ref_unenum_mathtitle2.sphinx8.1.html @@ -0,0 +1,4 @@ +<p>referencing: <a class="reference internal" href="_linked_unenum_mathtitle2.html#sol-nonumber-title-math2"><span class="std std-ref">Solution to</span></a>.</p> +<p>referencing: <a class="reference internal" href="_linked_unenum_mathtitle2.html#sol-nonumber-title-math2"><span class="std std-ref">exercise with nonumber but with inline math title ex2</span></a>.</p> +<p class="topless"><a href="_linked_ref_unenum_mathtitle.html" title="previous chapter">_linked_ref_unenum_mathtitle</a></p> +<p class="topless"><a href="_linked_ref_enum.html" title="next chapter">_linked_ref_enum</a></p> \ No newline at end of file diff --git a/tests/test_solution_references/_linked_ref_unenum_notitle.sphinx8.1.html b/tests/test_solution_references/_linked_ref_unenum_notitle.sphinx8.1.html new file mode 100644 index 0000000..1911f9e --- /dev/null +++ b/tests/test_solution_references/_linked_ref_unenum_notitle.sphinx8.1.html @@ -0,0 +1,4 @@ +<p>referencing: <a class="reference internal" href="_linked_unenum_notitle.html#sol-nonumber-notitle"><span class="std std-ref">Solution to</span></a>.</p> +<p>referencing: <a class="reference internal" href="_linked_unenum_notitle.html#sol-nonumber-notitle"><span class="std std-ref">ex with nonumber and notitle</span></a>.</p> +<p class="topless"><a href="_linked_wrong_targetlabel.html" title="previous chapter">_linked_wrong_targetlabel</a></p> +<p class="topless"><a href="_linked_ref_unenum_title.html" title="next chapter">_linked_ref_unenum_title</a></p> \ No newline at end of file diff --git a/tests/test_solution_references/_linked_ref_unenum_title.sphinx8.1.html b/tests/test_solution_references/_linked_ref_unenum_title.sphinx8.1.html new file mode 100644 index 0000000..ab4d3d4 --- /dev/null +++ b/tests/test_solution_references/_linked_ref_unenum_title.sphinx8.1.html @@ -0,0 +1,4 @@ +<p>referencing: <a class="reference internal" href="_linked_unenum_title.html#sol-nonumber-title"><span class="std std-ref">Solution to</span></a>.</p> +<p>referencing: <a class="reference internal" href="_linked_unenum_title.html#sol-nonumber-title"><span class="std std-ref">exercise with nonumber but with title</span></a>.</p> +<p class="topless"><a href="_linked_ref_unenum_notitle.html" title="previous chapter">_linked_ref_unenum_notitle</a></p> +<p class="topless"><a href="_linked_ref_unenum_mathtitle.html" title="next chapter">_linked_ref_unenum_mathtitle</a></p> \ No newline at end of file diff --git a/tox.ini b/tox.ini index e8d324c..720d34f 100644 --- a/tox.ini +++ b/tox.ini @@ -8,18 +8,20 @@ # `tox -r` [tox] -envlist = py{311,312,313}-sphinx{6,7,8} +# Note: py313-sphinx6 excluded - unlikely combination that generates 1870+ +# deprecation warnings from Sphinx 6's use of datetime.utcfromtimestamp() +envlist = py{310,311,312}-sphinx{6,7,8},py313-sphinx{7,8} skip_missing_interpreters = true [testenv] usedevelop=true recreate = false -[testenv:py{311,312,313}-pre-commit] +[testenv:py{310,311,312,313}-pre-commit] extras = code_style commands = pre-commit run {posargs} -[testenv:py{311,312,313}-sphinx{6,7,8}] +[testenv:py{310,311,312}-sphinx{6,7,8},py313-sphinx{7,8}] skip_install = false package = editable # Use the 'testing' extras from pyproject.toml, but constrain Sphinx version @@ -30,7 +32,8 @@ use_frozen_constraints = true deps = sphinx6: sphinx>=6.1,<7 sphinx7: sphinx>=7,<8 - sphinx8: sphinx>=8,<9 + py310-sphinx8: sphinx>=8.1,<8.2 + py{311,312,313}-sphinx8: sphinx>=8.2,<9 commands = pytest --verbose {posargs} [testenv:docs-{update,clean}]