diff --git a/CHANGELOG.md b/CHANGELOG.md
index 791e59e7..a92bbddb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,13 @@ Instructions: Add a subsection under `[Unreleased]` for additions, fixes, change
## [Unreleased]
+### Added
+- Experimental support for beamer format builds (from a ``). Use `` in the manifest to build a beamer PDF.
+- Publication variable to use cdn javascript/css for HTML output instead of local copies.
+
+### Fixed
+- Better heading levels for HTML output to improve accessibility.
+
## [2.43.2] - 2026-07-07
Includes updates to core through commit: [ad605bb](https://github.com/PreTeXtBook/pretext/commit/ad605bb27faf9f12c2bcb3b98ea953533f1aacb4)
diff --git a/poetry.lock b/poetry.lock
index ed2f0ce7..b90844e4 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
[[package]]
name = "annotated-types"
@@ -17,32 +17,6 @@ type = "legacy"
url = "https://pypi.org/simple"
reference = "pypi-public"
-[[package]]
-name = "anyio"
-version = "4.13.0"
-description = "High-level concurrency and networking framework on top of asyncio or Trio"
-optional = true
-python-versions = ">=3.10"
-groups = ["main"]
-markers = "extra == \"homepage\" or extra == \"all\""
-files = [
- {file = "anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708"},
- {file = "anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc"},
-]
-
-[package.dependencies]
-exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
-idna = ">=2.8"
-typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
-
-[package.extras]
-trio = ["trio (>=0.32.0)"]
-
-[package.source]
-type = "legacy"
-url = "https://pypi.org/simple"
-reference = "pypi-public"
-
[[package]]
name = "autocommand"
version = "2.2.2"
@@ -648,12 +622,12 @@ version = "1.2.2"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
-groups = ["main", "dev"]
+groups = ["dev"]
+markers = "python_version == \"3.10\""
files = [
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
]
-markers = {main = "(extra == \"homepage\" or extra == \"all\") and python_version == \"3.10\"", dev = "python_version == \"3.10\""}
[package.extras]
test = ["pytest (>=6)"]
@@ -677,7 +651,7 @@ files = [
]
[package.dependencies]
-pytz = ">=0a0"
+pytz = ">=0a"
[package.source]
type = "legacy"
@@ -2041,15 +2015,15 @@ reference = "pypi-public"
[[package]]
name = "prefig"
-version = "0.6.5"
+version = "0.6.7"
description = "An authoring system for mathematical diagrams"
optional = true
python-versions = ">=3.10,<4.0"
groups = ["main"]
markers = "extra == \"prefigure\" or extra == \"all\""
files = [
- {file = "prefig-0.6.5-py3-none-any.whl", hash = "sha256:2b9fd5aee2d007e5283d82ab2e01b34812aeef1e6751f0703fdea32d2ed15bb9"},
- {file = "prefig-0.6.5.tar.gz", hash = "sha256:93fd53be07ff981192ad31cab94c00f9d20835c694cbe038351f6c1ca903e609"},
+ {file = "prefig-0.6.7-py3-none-any.whl", hash = "sha256:6a857179fa14bc16c938adbf4ca12ba2f94745f8a788f4b15eb0879fe0f148c3"},
+ {file = "prefig-0.6.7.tar.gz", hash = "sha256:6a3664e284dfe9b8a40fa05d84a0a9d45637948c9bd54b29539593d47479025c"},
]
[package.dependencies]
@@ -3363,9 +3337,9 @@ reference = "pypi-public"
[[package]]
name = "watchfiles"
version = "0.24.0"
-description = "Simple, modern and high performance file watching and code reload in python."
+description = ""
optional = true
-python-versions = ">=3.8"
+python-versions = "*"
groups = ["main"]
markers = "extra == \"homepage\" or extra == \"all\""
files = [
@@ -3454,9 +3428,6 @@ files = [
{file = "watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1"},
]
-[package.dependencies]
-anyio = ">=3.0.0"
-
[package.source]
type = "legacy"
url = "https://pypi.org/simple"
@@ -3617,4 +3588,4 @@ prefigure = ["prefig"]
[metadata]
lock-version = "2.1"
python-versions = "^3.10"
-content-hash = "51f765b499df48be46c7907930c9a189c3e2faec4bc43c43253ef137a5f4564a"
+content-hash = "0ab0b613cb7b2c30649b74a16d92b7d02ab99cc090c2fbf779d71443c06dfd7e"
diff --git a/pretext/__init__.py b/pretext/__init__.py
index e794a8d5..ebc96c78 100644
--- a/pretext/__init__.py
+++ b/pretext/__init__.py
@@ -18,8 +18,7 @@
VERSION = get_version("pretext", Path(__file__).parent.parent)
-
-CORE_COMMIT = "ad605bb27faf9f12c2bcb3b98ea953533f1aacb4"
+CORE_COMMIT = "07c8b5c9a9a55e95ec27073e88bd5c9c61b9c161"
def activate() -> None:
diff --git a/pretext/constants.py b/pretext/constants.py
index bc840a17..66603bcf 100644
--- a/pretext/constants.py
+++ b/pretext/constants.py
@@ -12,6 +12,7 @@
"kindle",
"braille",
"revealjs",
+ "beamer",
"webwork",
"custom",
]
@@ -123,6 +124,20 @@
"datafile",
"myopenmath",
],
+ "beamer": [
+ "webwork",
+ "sageplot",
+ "asymptote",
+ "prefigure",
+ "youtube",
+ "codelens",
+ "datafile",
+ "interactive",
+ "qrcode",
+ "mermaid",
+ "myopenmath",
+ "dynamic-subs",
+ ],
"webwork": [
"webwork",
],
@@ -239,6 +254,13 @@
"sageplot": ["html", "svg"],
"prefigure": ["svg"],
},
+ "beamer": {
+ "asymptote": ["pdf"],
+ "latex-image": [],
+ "sageplot": ["pdf", "png"],
+ "prefigure": ["pdf"],
+ "mermaid": ["png"],
+ },
"webwork": {
"asymptote": [],
"latex-image": [],
diff --git a/pretext/project/__init__.py b/pretext/project/__init__.py
index c31eaba6..a8cc5e24 100644
--- a/pretext/project/__init__.py
+++ b/pretext/project/__init__.py
@@ -56,6 +56,7 @@ class Format(str, Enum):
KINDLE = "kindle"
BRAILLE = "braille"
REVEALJS = "revealjs"
+ BEAMER = "beamer"
WEBWORK = "webwork"
CUSTOM = "custom"
@@ -67,6 +68,7 @@ class Format(str, Enum):
Format.EPUB: ".epub",
Format.KINDLE: ".epub",
Format.BRAILLE: ".brl",
+ Format.BEAMER: ".pdf",
}
@@ -874,6 +876,7 @@ def build(
dest_dir=self.output_dir_abspath().as_posix(),
method=self.pdf_method,
outputs="all" if latex else "pdf-only",
+ format_xsl=None,
)
elif self.format == Format.LATEX:
core.pdf(
@@ -885,6 +888,7 @@ def build(
dest_dir=self.output_dir_abspath().as_posix(),
method=self.pdf_method,
outputs="prebuild",
+ format_xsl=None,
)
elif self.format == Format.EPUB:
utils.mjsre_npm_install()
@@ -930,6 +934,17 @@ def build(
out_file=out_file,
dest_dir=self.output_dir_abspath().as_posix(),
)
+ elif self.format == Format.BEAMER:
+ core.beamer(
+ xml=self.source_abspath(),
+ pub_file=self.publication_abspath().as_posix(),
+ stringparams=stringparams_copy,
+ extra_xsl=custom_xsl,
+ out_file=out_file,
+ dest_dir=self.output_dir_abspath().as_posix(),
+ method=self.pdf_method,
+ outputs="all" if latex else "pdf-only",
+ )
elif self.format == Format.BRAILLE:
log.warning(
"Braille output is still experimental, and requires additional libraries from liblouis (specifically the file2brl software)."
diff --git a/pyproject.toml b/pyproject.toml
index 541c124e..08166013 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -45,7 +45,7 @@ plastex = "^3"
jinja2 = "^3"
coloraide = "^4"
pelican = { extras = ["markdown"], version = "^4.10", optional = true }
-prefig = { extras = ["text"], version = "^0.6.5", optional = true }
+prefig = { extras = ["text"], version = "^0.6.7", optional = true }
citeproc-py = "^0"
diff --git a/schema/project-ptx.rnc b/schema/project-ptx.rnc
index ff87f624..7d11bbc6 100644
--- a/schema/project-ptx.rnc
+++ b/schema/project-ptx.rnc
@@ -44,7 +44,7 @@ Target = element target {
## Unique identifier for this build target. This is the name you pass on the
## command line when building via the `pretext` CLI.
attribute name { text },
- ## the required format can be `html`, `pdf`, `latex`, `epub`, `kindle`, `braille`, `revealjs`, `webwork`, or `custom`.
+ ## the required format can be `html`, `pdf`, `latex`, `epub`, `kindle`, `braille`, `revealjs`, `beamer`, `webwork`, or `custom`.
(
HtmlAttributes
| PdfAttributes
@@ -52,6 +52,7 @@ Target = element target {
| EpubAttributes
| BrailleAttributes
| RevealjsAttributes
+ | BeamerAttributes
| WebworkAttributes
| CustomAttributes
),
@@ -81,6 +82,7 @@ HtmlAttributes = (
PdfAttributes = (
attribute format { "pdf" },
+ attribute pdf-method { "xelatex" | "pdflatex" | "latex" | "pdf-fo"}?,
attribute latex-engine { "xelatex" | "pdflatex" | "latex" }?,
attribute output-filename { text }?
)
@@ -105,6 +107,11 @@ RevealjsAttributes = (
attribute output-filename { text }?
)
+BeamerAttributes = (
+ attribute format { "beamer" },
+ attribute output-filename { text }?
+)
+
WebworkAttributes = (
attribute format { "webwork" },
attribute compression { "zip" }?
@@ -127,4 +134,4 @@ Stringparams = element stringparams {
attribute html.css.extra { text }?
}
-}
\ No newline at end of file
+}
diff --git a/schema/project-ptx.rng b/schema/project-ptx.rng
index 8862b7ec..f498fb4c 100644
--- a/schema/project-ptx.rng
+++ b/schema/project-ptx.rng
@@ -74,13 +74,14 @@
command line when building via the `pretext` CLI.
- the required format can be `html`, `pdf`, `latex`, `epub`, `kindle`, `braille`, `revealjs`, `webwork`, or `custom`.
+ the required format can be `html`, `pdf`, `latex`, `epub`, `kindle`, `braille`, `revealjs`, `beamer`, `webwork`, or `custom`.
+
@@ -158,6 +159,16 @@ These parameters are rarely used by content authors.
pdf
+
+
+
+ xelatex
+ pdflatex
+ latex
+ pdf-fo
+
+
+
@@ -211,6 +222,14 @@ These parameters are rarely used by content authors.
+
+
+ beamer
+
+
+
+
+ webwork
diff --git a/templates/slideshow/assets/images/complete-graph.pdf b/templates/slideshow/assets/images/complete-graph.pdf
new file mode 100644
index 00000000..175e77d8
Binary files /dev/null and b/templates/slideshow/assets/images/complete-graph.pdf differ
diff --git a/templates/slideshow/assets/images/complete-graph.svg b/templates/slideshow/assets/images/complete-graph.svg
new file mode 100644
index 00000000..569d1af7
--- /dev/null
+++ b/templates/slideshow/assets/images/complete-graph.svg
@@ -0,0 +1,513 @@
+
+
diff --git a/templates/slideshow/project.ptx b/templates/slideshow/project.ptx
index 8d31e02c..a77a15c7 100644
--- a/templates/slideshow/project.ptx
+++ b/templates/slideshow/project.ptx
@@ -7,5 +7,10 @@
format="revealjs"
output-filename="index.html"
/>
+
diff --git a/templates/slideshow/source/main.ptx b/templates/slideshow/source/main.ptx
index 63f58dd1..a551d691 100644
--- a/templates/slideshow/source/main.ptx
+++ b/templates/slideshow/source/main.ptx
@@ -2,15 +2,19 @@
@@ -20,6 +24,10 @@ along with PreTeXt. If not, see .
\newcommand{\definiteintegral}[4]{\int_{#1}^{#2}\,#3\,d#4}
+
+ \usepackage{tikz}
+ \usepackage{nicematrix} % for multi-run latex-image (label="latex-three-pass")
+
@@ -27,13 +35,16 @@ along with PreTeXt. If not, see .
A Slideshow
-
+ Robert A. BeezerUniversity of Puget SoundAt a Test Conference
+
+
+
@@ -177,6 +188,10 @@ along with PreTeXt. If not, see .
+
+
+
+ Blocks and codeBlocks: definition
@@ -188,7 +203,7 @@ along with PreTeXt. If not, see .
indefinite integral of f(x)
-
Suppose that \frac{d}{dx}F(x)=f(x). Then the indefinite integral of f(x) is F(x) and is written as \int\,f(x)\,dx=F(x).
+
Suppose that \frac{d}{dx}F(x)=f(x). Then the indefinite integral of f(x) is F(x) and is written as \int\,f(x)\,dx=F(x).
@@ -203,7 +218,7 @@ along with PreTeXt. If not, see .
Fundamental Theorem of Calculus
-
If f(x) is continuous, and the derivative of F(x) is f(x), then \definiteintegral{a}{b}{f(x)}{x}=F(b)-F(a)test: buried in theorem/statement/p
+
If f(x) is continuous, and the derivative of F(x) is f(x), then \definiteintegral{a}{b}{f(x)}{x}=F(b)-F(a)test: buried in theorem/statement/p
Left to the reader.
@@ -211,6 +226,33 @@ along with PreTeXt. If not, see .
+
+ Code
+
+
Here is an inline bit of code with surrounding text. print("hello world"). Here is a more text. And some more. And yet more. And a full program... with Prism support.
+
+ A simple program
+
+ def f(x):
+ return x**2
+
+ # many intentional blank lines below...
+ # you may to zoom out, but at some point better to scroll a long listing
+
+
+
+
+
+
+
+
+
+
+ print(f(3))
+
+
+
+
@@ -219,9 +261,9 @@ along with PreTeXt. If not, see .
Ramanujan and Integration
-
This Sage Cell should execute properly, but some extra CSS is being applied. It is also difficult to edit properly. Perhaps the two are related. You may need to zoom out your browser to see all the content, especially after running the cell.
+
This Sage Cell is testing styling.
-
We have some mathematics on the page, to look for Javascript interference with MathJax. An identity due to Ramanujan:\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\ldots} } } }.
+
We have some mathematics on the page, to look for Javascript interference with MathJax. An identity due to Ramanujan:\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\ldots} } } }.
numerical_integral(sin(x)^2, (0, 2))
@@ -229,7 +271,89 @@ along with PreTeXt. If not, see .
-
And some more mathematics. An identity due to Ramanujan:\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\ldots} } } }.
+
And some more mathematics. An identity due to Ramanujan:\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\ldots} } } }.
+
+
+
+
+ More Elements
+
+
+ Displayed Mathematics
+
+
A single displayed equation, unnumbered on a slide.
+ \definiteintegral{0}{\pi}{\sin(x)}{x} = 2
+
+
+
And a multi-line display, with alignment on the equals signs.
+ (a+b)^2 \amp= (a+b)(a+b)
+ \amp= a^2 + ab + ba + b^2
+ \amp= a^2 + 2ab + b^2
+
+
+
+
+ A Table
+
+
A tabular inside a table, whose title serves as a caption.
+
+
+ Conversions of a slideshow
+
+
+
+
+
+ Format
+ Engine
+ Output
+
+
+ reveal.js
+ browser
+ HTML
+
+
+ Beamer
+
+ PDF
+
+
+
+
+
+
+ Console Sessions
+
+
A console reproduces an interactive command-line session, input distinguished from output.
The problem with quotes on the Internet is that it is hard to verify their authenticity.
+ Abraham Lincoln
+
+
+
A blockquote can carry an attribution, as above.
+
+
+
+ Cross-References and URLs
+
+
A cross-reference to a block on another slide renders as static text, since a PDF slideshow has no knowls: see .
+
+
One with text from the target's title: .
+
+
An external reference is live in capable outputs: .
@@ -262,6 +386,260 @@ along with PreTeXt. If not, see .
But this is still visible from the outset.
+
+ Images, from an external source
+
+
+ Images can be included from external sources.
+ As with other formats,
+ you can specify the location of your exteral images in the publication file.
+ The image below also appears in the Sample Article,
+ and originated at www.texample.net.
+
+
+
+
+ You will want to ensure your image has an width if you want it to fit correctly in your slide.
+
+
+
+
+ Images, from source
+
+
+ Images can also be generated from source. TikZ works well, and Asymptote.
+ They can be placed in a sidebyside, and inside a figure (or both).
+
+
+
+ Common formatting macros for TikZ and Asymptote (which you expect to use repeatedly)
+ can be placed in docinfo, using latex-image-preamble
+ and asymptote-preamble, respectively.
+
+
+
+ Note that 3D Asymptote images will be rendered in WebGL, and will be interactive within your slide.
+
+
+
+
Two cone images borrowed from the Sample Article. The one on the left is written in TiZ, and the one on the right is written in Asymptote