diff --git a/sphinx_exercise/transforms.py b/sphinx_exercise/transforms.py index fdf2f48..17ce3ae 100644 --- a/sphinx_exercise/transforms.py +++ b/sphinx_exercise/transforms.py @@ -100,8 +100,8 @@ def apply(self): new_node.attributes = node.attributes # Update Attributes new_node["classes"] = [ - attr.replace("solution-start", "solution") - for attr in node.attributes["classes"] + "solution" if cls == "solution-start" else cls + for cls in node.attributes["classes"] ] new_node["type"] = "solution" new_node.parent = node.parent @@ -157,9 +157,11 @@ def merge_nodes(self, node): if not parent_end: return parent = node.parent - # Use Current Node and remove "-start" from class names and type + # Use Current Node and drop "-start" from the marker class and type, + # leaving user supplied classes untouched updated_classes = [ - cls.replace("-start", "") for cls in node.attributes["classes"] + "exercise" if cls == "exercise-start" else cls + for cls in node.attributes["classes"] ] node.attributes["classes"] = updated_classes node.attributes["type"] = node.attributes["type"].replace("-start", "") diff --git a/tests/books/test-gatedclasses/conf.py b/tests/books/test-gatedclasses/conf.py new file mode 100644 index 0000000..28c7a1c --- /dev/null +++ b/tests/books/test-gatedclasses/conf.py @@ -0,0 +1,11 @@ +# Configuration file for the Sphinx documentation builder. + +project = "sphinx-exercise" +copyright = "2020-2021, Executable Book Developers" +author = "Executable Book Developers" + +extensions = ["sphinx_exercise"] + +exclude_patterns = ["build", "_build"] + +html_theme = "alabaster" diff --git a/tests/books/test-gatedclasses/index.rst b/tests/books/test-gatedclasses/index.rst new file mode 100644 index 0000000..27c0a17 --- /dev/null +++ b/tests/books/test-gatedclasses/index.rst @@ -0,0 +1,18 @@ +Gated Directive Classes +======================= + +.. exercise-start:: + :label: ex-gated-class + :class: quick-start + +Gated exercise body. + +.. exercise-end:: + +.. solution-start:: ex-gated-class + :label: sol-gated-class + :class: my-solution-start-thing + +Gated solution body. + +.. solution-end:: diff --git a/tests/test_gateddirective.py b/tests/test_gateddirective.py index 7e3e180..9944644 100644 --- a/tests/test_gateddirective.py +++ b/tests/test_gateddirective.py @@ -216,3 +216,17 @@ def test_gated_solution_errors_3(app, warning): assert True else: assert False + + +@pytest.mark.sphinx("html", testroot="gatedclasses") +def test_gated_user_classes_preserved(app): + app.build() + soup = BeautifulSoup( + (Path(app.outdir) / "index.html").read_text(encoding="utf8"), "html.parser" + ) + exercise = soup.select_one("div#ex-gated-class") + assert exercise["class"] == ["exercise", "quick-start", "admonition"] + solution = soup.select_one("div#sol-gated-class") + assert "my-solution-start-thing" in solution["class"] + assert "solution" in solution["class"] + assert "solution-start" not in solution["class"]