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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Instructions: Add a subsection under `[Unreleased]` for additions, fixes, change

## [Unreleased]

### Changed

- The default Asymptote generation method is now `local` (using the local `asy` binary) instead of `server`. This improves reliability since the server method has been subject to breakage whenever the Asymptote web interface is updated. Users who need the server method can still opt in via `asy-method="server"` in `project.ptx`.

## [2.37.1] - 2026-02-19

Includes updates to core through commit: [4e4ff13](https://github.com/PreTeXtBook/pretext/commit/4e4ff13706654ca5eb4ff9936bc2acddbd4aa648)
Expand Down
2 changes: 1 addition & 1 deletion pretext/project/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ def validate_path(cls, path: t.Union[Path, str]) -> Path:
#
# TODO: why is this optional, if there's a non-optional default? How would it ever be optional if loaded from an XML file?
asy_method: t.Optional[AsyMethod] = pxml.attr(
name="asy-method", default=AsyMethod.SERVER
name="asy-method", default=AsyMethod.LOCAL
)

# See the docs on `Target.server`; they apply here as well.
Expand Down
2 changes: 1 addition & 1 deletion pretext/project/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class LegacyTarget(pxml.BaseXmlModel, tag="target", search_mode=SearchMode.UNORD
# The v1 file called this `deploy-dir`; the v2 file uses `site`.
deploy_dir: t.Optional[str] = pxml.element(tag="deploy-dir", default=None)
xsl: t.Optional[str] = pxml.element(default=None)
asy_method: t.Optional[str] = pxml.element(tag="asy-method", default="server")
asy_method: t.Optional[str] = pxml.element(tag="asy-method", default="local")
stringparams: t.List[LegacyStringParam] = pxml.element(
tag="stringparam", default=[]
)
Expand Down
6 changes: 3 additions & 3 deletions templates/course/project.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
site="site"
stage="output/stage"
xsl="xsl"
asy-method="server"
asy-method="local"
>
<targets>
<target
Expand All @@ -56,7 +56,7 @@
output-dir="web"
deploy-dir="interactive"
xsl="custom-html.xsl"
asy-method="server"
asy-method="local"
/>
<target
name="web-zipped"
Expand All @@ -65,7 +65,7 @@
publication="publication.ptx"
output-dir="web"
compression="zip"
asy-method="server"
asy-method="local"
/>
<target
name="runestone"
Expand Down
6 changes: 3 additions & 3 deletions templates/project.ptx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
site="site"
stage="output/stage"
xsl="xsl"
asy-method="server"
asy-method="local"
generated-cache=".cache"
>
<targets>
Expand All @@ -33,7 +33,7 @@
output-dir="web"
deploy-dir="interactive"
xsl="custom-html.xsl"
asy-method="server"
asy-method="local"
/>
<target
name="web-zipped"
Expand All @@ -42,7 +42,7 @@
publication="publication.ptx"
output-dir="web"
compression="zip"
asy-method="server"
asy-method="local"
/>
<target
name="runestone"
Expand Down
9 changes: 9 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
PY_CMD = sys.executable

HAS_XELATEX = check_installed(["xelatex", "--version"])
HAS_ASY = check_installed(["asy", "--version"])


@contextmanager
Expand Down Expand Up @@ -87,6 +88,10 @@ def test_devscript(script_runner: ScriptRunner) -> None:
not HAS_XELATEX,
reason="Skipped since xelatex isn't found.",
)
@pytest.mark.skipif(
not HAS_ASY,
reason="Skipped since asy isn't found.",
)
def test_build(tmp_path: Path, script_runner: ScriptRunner) -> None:
path_with_spaces = "test path with spaces"
project_path = tmp_path / path_with_spaces
Expand Down Expand Up @@ -237,6 +242,10 @@ def test_init_and_update_with_git(tmp_path: Path, script_runner: ScriptRunner) -
assert f"pretext == {pretext.VERSION}\n" in lines[1]


@pytest.mark.skipif(
not HAS_ASY,
reason="Skipped since asy isn't found.",
)
def test_generate_graphics(tmp_path: Path, script_runner: ScriptRunner) -> None:
graphics_path = tmp_path / "graphics"
shutil.copytree(EXAMPLES_DIR / "projects" / "graphics", graphics_path)
Expand Down
10 changes: 10 additions & 0 deletions tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ def test_defaults(tmp_path: Path) -> None:
assert target.xsl is None
assert target.latex_engine == pr.LatexEngine.XELATEX
assert target.stringparams == {}
# Default asy_method should be "local"
assert project.asy_method == pr.AsyMethod.LOCAL
for t in ts:
name, _ = t
assert project.get_target(name).asy_method == pr.AsyMethod.LOCAL


def test_serve(tmp_path: Path) -> None:
Expand Down Expand Up @@ -106,6 +111,11 @@ def test_manifest_simple(tmp_path: Path) -> None:

assert not project.has_target("foo")

# When asy-method is not specified, the default should be "local"
assert project.asy_method == pr.AsyMethod.LOCAL
assert t_web.asy_method == pr.AsyMethod.LOCAL
assert t_print.asy_method == pr.AsyMethod.LOCAL

default_project = pr.Project(ptx_version="2")
assert default_project.site == project.site
assert default_project.output_dir == project.output_dir
Expand Down
9 changes: 8 additions & 1 deletion tests/test_sample_article.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@
import pretext.utils
from .common import check_installed, EXAMPLES_DIR

HAS_XELATEX = check_installed(["xelatex", "--version"])
HAS_ASY = check_installed(["asy", "--version"])


@pytest.mark.skipif(
not check_installed(["xelatex", "--version"]),
not HAS_XELATEX,
reason="Note: several tests are skipped, since xelatex wasn't installed.",
)
@pytest.mark.skipif(
not HAS_ASY,
reason="Skipped since asy isn't found.",
)
def test_sample_article(tmp_path: Path) -> None:
error_checker = errorhandler.ErrorHandler(logger="ptxlogger")
prj_path = tmp_path / "sample"
Expand Down
Loading