Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion pretext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

VERSION = get_version("pretext", Path(__file__).parent.parent)

CORE_COMMIT = "6f1b557cb7aed2b86eb40187c21b56009f97ea1b"
CORE_COMMIT = "94cd93d9e175822173f5a4d89870b346aedd6717"


def activate() -> None:
Expand Down
7 changes: 7 additions & 0 deletions tests/examples/projects/dynamic-fillin/project.ptx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This file, the project manifest, provides the overall configuration for your PreTeXt project. -->
<project ptx-version="2">
<targets>
<target name="web" format="html" />
</targets>
</project>
57 changes: 57 additions & 0 deletions tests/examples/projects/dynamic-fillin/source/main.ptx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version='1.0' encoding='utf-8'?>
<pretext>
<article>
<title>Hello World!</title>
<p>This is a PreTeXt document.</p>
<exercise xml:id="exercise-webwork">
<webwork>
<pg-code>
$a = Compute(random(1, 9, 1));
$b = Compute(random(1, 9, 1));
$c = $a + $b;
</pg-code>
<statement>
<p>
Compute the sum of <m><var name="$a" /></m> and <m><var name="$b" /></m>:
</p>
<p>
<m><var name="$a" /> + <var name="$b" /> =</m> <var name="$c" width="5" />
</p>
</statement>
<hint>
<p>
Add <m><var name="$a" /></m> and <m><var name="$b" /></m> together.
</p>
</hint>
<solution>
<p>
<m><var name="$a" /> + <var name="$b" /> = <var name="$c" /></m>.
</p>
</solution>
</webwork>
</exercise>
<exercise xml:id="exercise-dynamic-fillin">
<title>Dynamic Fill-In-The-Blank</title>
<statement>
<p>
What is <m><eval obj="a" /> + <eval obj="b" /></m>?
<fillin mode="number" ansobj="sum" width="5" />
</p>
</statement>
<setup seed="42">
<de-object name="a" context="number">
<de-random distribution="discrete" min="1" max="9" />
</de-object>
<de-object name="b" context="number">
<de-random distribution="discrete" min="1" max="9" />
</de-object>
<de-object name="sum" context="number">
<de-number>a+b</de-number>
</de-object>
</setup>
<evaluation>
<evaluate />
</evaluation>
</exercise>
</article>
</pretext>
38 changes: 38 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
#
Expand Down