diff --git a/CHANGELOG.md b/CHANGELOG.md index ac842d94..984f8dcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ Instructions: Add a subsection under `[Unreleased]` for additions, fixes, change ## [Unreleased] +### Fixed + +- Bug that prevented building a project that contained dynamic FITB questions. +- Consistent alignment of slide content. + ## [2.48.0] - 2026-08-08 Includes updates to core through commit: [6f1b557](https://github.com/PreTeXtBook/pretext/commit/6f1b557cb7aed2b86eb40187c21b56009f97ea1b) diff --git a/pretext/__init__.py b/pretext/__init__.py index eddd1600..e6589b69 100644 --- a/pretext/__init__.py +++ b/pretext/__init__.py @@ -18,7 +18,7 @@ VERSION = get_version("pretext", Path(__file__).parent.parent) -CORE_COMMIT = "6f1b557cb7aed2b86eb40187c21b56009f97ea1b" +CORE_COMMIT = "94cd93d9e175822173f5a4d89870b346aedd6717" def activate() -> None: diff --git a/tests/examples/projects/dynamic-fillin/project.ptx b/tests/examples/projects/dynamic-fillin/project.ptx new file mode 100644 index 00000000..1ce8e5d8 --- /dev/null +++ b/tests/examples/projects/dynamic-fillin/project.ptx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/examples/projects/dynamic-fillin/source/main.ptx b/tests/examples/projects/dynamic-fillin/source/main.ptx new file mode 100644 index 00000000..6d808b4c --- /dev/null +++ b/tests/examples/projects/dynamic-fillin/source/main.ptx @@ -0,0 +1,57 @@ + + +
+ Hello World! +

This is a PreTeXt document.

+ + + + $a = Compute(random(1, 9, 1)); + $b = Compute(random(1, 9, 1)); + $c = $a + $b; + + +

+ Compute the sum of and : +

+

+ + = +

+
+ +

+ Add and together. +

+
+ +

+ + = . +

+
+
+
+ + Dynamic Fill-In-The-Blank + +

+ What is + ? + +

+
+ + + + + + + + + a+b + + + + + +
+
+
diff --git a/tests/test_cli.py b/tests/test_cli.py index 98e57526..36664c41 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -49,6 +49,7 @@ HAS_XELATEX = check_installed(["xelatex", "--version"]) HAS_ASY = check_installed(["asy", "--version"]) HAS_SAGE = check_installed(["sage", "--version"]) +HAS_NODE = check_installed(["node", "--version"]) @contextmanager @@ -730,6 +731,43 @@ def test_custom_webwork_server(tmp_path: Path, script_runner: ScriptRunner) -> N assert result.success +@pytest.mark.skipif( + not HAS_NODE, + reason="Skipped since node isn't found (needed to extract dynamic substitutions).", +) +def test_build_webwork_and_dynamic_fillin( + tmp_path: Path, script_runner: ScriptRunner +) -> None: + """A project mixing a WeBWorK exercise with a dynamic (randomized) + fill-in-the-blank exercise builds successfully. The build must generate + both the webwork asset (a rendered PG problem, fetched from a webwork + server) and the dynamic-subs asset (the substitution file `pretext` + extracts via node so that a static rendering shows one consistent, if + randomized, version of the question).""" + project_path = tmp_path / "dynamic-fillin" + shutil.copytree(EXAMPLES_DIR / "projects" / "dynamic-fillin", project_path) + result = script_runner.run( + [PTX_CMD, "-v", "debug", "build", "web"], cwd=project_path + ) + assert result.success + + assert ( + project_path / "generated-assets" / "webwork" / "exercise-webwork.xml" + ).exists() + + subs_file = ( + project_path / "generated-assets" / "dynamic_subs" / "dynamic_substitutions.xml" + ) + assert subs_file.exists() + assert 'id="exercise-dynamic-fillin"' in subs_file.read_text() + + output_dir = project_path / "output" / "web" + combined_html = "\n".join(p.read_text() for p in output_dir.glob("*.html")) + assert 'id="exercise-webwork"' in combined_html + assert 'id="rs-exercise-dynamic-fillin"' in combined_html + assert 'data-component="fillintheblank"' in combined_html + + # --------------------------------------------------------------------------- # 5. Validate #