@pretextbook/pretext-html 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +106 -10
  2. package/assets/preview-html.xsl +8 -4
  3. package/assets/preview-revealjs.xsl +85 -0
  4. package/assets/upstream.json +1 -1
  5. package/assets/xsl/LICENSE-pretext +16 -0
  6. package/assets/xsl/README.md +25 -24
  7. package/assets/xsl/entities.ent +27 -0
  8. package/assets/xsl/extract-biblio-csl.xsl +6 -4
  9. package/assets/xsl/extract-dynamic.xsl +14 -12
  10. package/assets/xsl/extract-interactive.xsl +2 -2
  11. package/assets/xsl/extract-pg.xsl +123 -306
  12. package/assets/xsl/extract-qrcode.xsl +12 -2
  13. package/assets/xsl/extract-sageplot.xsl +1 -1
  14. package/assets/xsl/extract-trace.xsl +3 -3
  15. package/assets/xsl/extract-youtube.xsl +1 -1
  16. package/assets/xsl/latex/pretext-latex-texstyle.xsl +4 -5
  17. package/assets/xsl/localizations/README.md +24 -24
  18. package/assets/xsl/pretext-assembly.xsl +463 -368
  19. package/assets/xsl/pretext-beamer.xsl +43 -146
  20. package/assets/xsl/pretext-braille-preprint.xsl +458 -202
  21. package/assets/xsl/pretext-common.xsl +486 -510
  22. package/assets/xsl/pretext-epub.xsl +318 -78
  23. package/assets/xsl/pretext-fo.xsl +80 -96
  24. package/assets/xsl/pretext-html.xsl +413 -318
  25. package/assets/xsl/pretext-jupyter.xsl +534 -322
  26. package/assets/xsl/pretext-latex-classic.xsl +14 -15
  27. package/assets/xsl/pretext-latex-common.xsl +393 -2397
  28. package/assets/xsl/pretext-latex.xsl +1995 -5
  29. package/assets/xsl/pretext-markdown.xsl +919 -0
  30. package/assets/xsl/pretext-numbers.xsl +57 -39
  31. package/assets/xsl/pretext-revealjs.xsl +241 -33
  32. package/assets/xsl/pretext-runestone-fitb.xsl +34 -35
  33. package/assets/xsl/pretext-runestone-static.xsl +17 -17
  34. package/assets/xsl/pretext-runestone.xsl +36 -34
  35. package/assets/xsl/pretext-sage-doctest.xsl +2 -2
  36. package/assets/xsl/pretext-text-utilities.xsl +69 -1
  37. package/assets/xsl/pretext-text.xsl +1077 -107
  38. package/assets/xsl/pretext-view-source.xsl +5 -3
  39. package/assets/xsl/pretext-ww-problem-sets.xsl +6 -1
  40. package/assets/xsl/publisher-variables.xsl +397 -477
  41. package/assets/xsl/support/play-button/README.md +1 -3
  42. package/assets/xsl/tests/README.md +1 -1
  43. package/assets/xsl/utilities/README.md +6 -8
  44. package/assets/xsl/utilities/report-publisher-variables.xsl +15 -0
  45. package/assets/xsl-bundle.json +1 -1
  46. package/dist/cli-DZsyZERX.js +694 -0
  47. package/dist/cli.js +1 -1
  48. package/dist/index.browser.d.ts +5 -0
  49. package/dist/index.browser.js +499 -344
  50. package/dist/index.d.ts +5 -0
  51. package/dist/index.js +23 -18
  52. package/dist/publication.d.ts +26 -12
  53. package/dist/renderer.d.ts +68 -0
  54. package/dist/reveal.d.ts +77 -0
  55. package/dist/reveal.js +110 -0
  56. package/dist/target.d.ts +34 -0
  57. package/package.json +12 -1
  58. package/dist/cli-CzoinNle.js +0 -639
package/README.md CHANGED
@@ -69,6 +69,17 @@ const { html } = await renderHtml({
69
69
  - The user's publication file is respected, except
70
70
  `<html><platform portable="yes"/></html>` is always forced — that is what
71
71
  makes single-page in-memory output possible.
72
+ - `cssTheme: "denver"` supplies the PreTeXt HTML theme for projects that do not
73
+ choose one, by adding `<html><css theme="…"/></html>` to the publication file
74
+ used for the build (including the minimal one synthesized when you pass no
75
+ `publicationPath`). It is a default, never an override: a publication file
76
+ that already names a theme — `@theme`, or the deprecated `@style`/`@shell` —
77
+ keeps it, so the preview goes on matching what `pretext build` produces. The
78
+ themes the bundled stylesheets know are `default-modern` (PreTeXt's own
79
+ default), `denver`, `tacoma`, `salem`, `greeley` and `boulder`; a portable
80
+ build loads `theme-<name>.min.css` from the CDN, so an unrecognised name
81
+ gives an unstyled page. Not to be confused with `theme` below, which is the
82
+ light/dark mode _within_ whichever css theme is in force.
72
83
  - The compiled stylesheet is cached per `xslDir` (~1s to compile, then
73
84
  ~100ms–1s per render depending on document size).
74
85
  - `theme: "dark" | "light" | "system"` makes the preview follow the embedding
@@ -161,6 +172,87 @@ its native `localStorage`/`prefers-color-scheme` behaviour. The
161
172
  `isPreviewTheme`) with no dependency on the renderer, so a host can import just
162
173
  the message helper.
163
174
 
175
+ ### Slideshows (reveal.js)
176
+
177
+ A document whose top-level element is `<slideshow>` is rendered as a
178
+ [reveal.js](https://revealjs.com) deck instead, through PreTeXt's own
179
+ `pretext-revealjs.xsl`. Detection is automatic — there is nothing to turn on —
180
+ and `RenderResult.target` reports which conversion ran.
181
+
182
+ ```js
183
+ import { renderHtml } from "@pretextbook/pretext-html";
184
+ // dependency-free subpath, like ./theme:
185
+ import { injectRevealBridge } from "@pretextbook/pretext-html/reveal";
186
+
187
+ const { html, target } = await renderHtml({
188
+ sourcePath: "source/slides.ptx",
189
+ revealView: "scroll", // the default: whole deck as one scrolling page
190
+ revealTheme: "black", // fallback only; the project's own theme wins
191
+ revealZoom: 1, // content size vs. presented size (scroll view)
192
+ });
193
+ target; // "slides"
194
+
195
+ // Switch to the ordinary presentation later — no re-render, just re-inject:
196
+ const presenting = injectRevealBridge(html, "slides");
197
+ ```
198
+
199
+ Two things are forced on a slideshow render, overriding the publication file,
200
+ because the alternatives cannot work without the Python toolchain:
201
+ `revealjs/resources/@host` becomes `cdn` (a `local` host points at a `dist/`
202
+ tree that was never copied anywhere; `embedded` expects a post-processing step
203
+ that never runs), and `@math` becomes `online` (embedded mathematics is
204
+ prebuilt SVG passed in through the `mathfile` parameter, and without it a deck
205
+ renders with its mathematics silently missing). Everything else — theme,
206
+ navigation mode, controls — stays as the project authored it.
207
+
208
+ The scroll view is tuned for reading a deck rather than presenting it. It lays
209
+ slides out at reveal's nominal **960×700** and scales them to fit, stacks them
210
+ with `scrollLayout: "compact"` and an outline around each, and shows every
211
+ `@pause`/`<subslide>` fragment at once so scrolling is not interrupted. Switch
212
+ to `revealView: "slides"` to see the pauses step through as they will when
213
+ presented.
214
+
215
+ Showing the pauses at once takes more than `fragments: false`, which is worth
216
+ knowing if you ever touch this: the scroll view counts its scroll steps with
217
+ `querySelectorAll('.fragment')` and never consults that setting, so the config
218
+ alone makes fragments _visible_ while reveal still adds a scroll step — and a
219
+ full `scrollTriggerHeight` of padding — for each one. Compact layout compounds
220
+ it, because a page with any scroll trigger reverts to a full-viewport height.
221
+ A slide with two pauses ends up roughly three screens tall. The injected script
222
+ therefore removes the `fragment` class outright before `initialize` runs.
223
+
224
+ The nominal size is worth understanding, because it is the one override that
225
+ changes how a deck _looks_: PreTeXt publishes `width: "100%", height: "100%"`,
226
+ and reveal resolves a percentage against the presentation element — so the
227
+ slide becomes exactly as large as whatever is showing it, the computed scale is
228
+ always 1, and no downscaling ever happens. Full screen that is fine; in an
229
+ editor pane it means text sized for a 960px slide is drawn at full size into a
230
+ fraction of that width. Giving reveal a real deck size to scale from restores
231
+ the proportions a full-screen presentation will have.
232
+
233
+ `revealZoom` then works _in slide units_, dividing that nominal size rather than
234
+ shrinking the slide on screen — `0.5` gives a 1920×1400 slide. This is the only
235
+ arrangement that behaves like zooming out on a web page. Reveal lays content out
236
+ in slide units and scales the whole slide to fit, so a smaller _box_ fits
237
+ exactly the same content and clips exactly the same overflow; a larger box
238
+ leaves the slide the same size on screen (reveal simply scales it down further)
239
+ while fixed-pixel text occupies proportionally less of it. Since reveal clips
240
+ whatever runs past the bottom of a slide, with no way to scroll to it, zooming
241
+ out is the only way to read content that does not fit — which is also why the
242
+ default is `1`, where the deck, overflow included, looks exactly as it will when
243
+ presented.
244
+
245
+ Two further notes:
246
+
247
+ - **`RenderOptions.theme` does nothing for a deck.** reveal.js pages load none
248
+ of the PreTeXt javascript behind light/dark mode, so there is no
249
+ `setDarkMode` to drive. Pick a light or dark **reveal** theme with
250
+ `revealTheme` instead.
251
+ - **Views are baked in at render time.** reveal reads `view` once, when it
252
+ initializes, so `injectRevealBridge` returns a new page rather than talking
253
+ to a live deck — deliver it as a fresh document (`webview.html = …`, not an
254
+ in-place rewrite) for the change to take.
255
+
164
256
  ## Requirements
165
257
 
166
258
  - **Node ≥ 24** launched with **`--experimental-wasm-jspi`** (WebAssembly
@@ -191,7 +283,11 @@ the message helper.
191
283
  other file-writing templates are stubbed. The wrapper is **generated** by
192
284
  `scripts/refresh-xsl.mjs`, which also audits every `exsl:document` site
193
285
  reachable from `pretext-html.xsl` and fails if upstream adds a writer we
194
- don't cover.
286
+ don't cover. `assets/preview-revealjs.xsl` is the slideshow counterpart and
287
+ is far thinner: `pretext-revealjs.xsl` already emits one monolithic page, so
288
+ there is no template to copy — it only stubs the same file writers (a slide
289
+ holding an `<interactive>` really does reach one) and stamps `@id` onto
290
+ slides, via `apply-imports` so no upstream markup is duplicated.
195
291
  3. **Virtual-host fetch shim** — the WASM build has no filesystem
196
292
  (`FILESYSTEM=0`); every resource load (stylesheet imports, `document()`
197
293
  calls, the publication file) goes through the global `fetch`. We mount
@@ -213,13 +309,13 @@ the message helper.
213
309
 
214
310
  ## Limitations (current WASM build)
215
311
 
216
- | Limitation | Cause | Fix |
217
- | ---------------------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------- |
218
- | No multi-file output (`exsl:document`) | Compiled with `FILESYSTEM=0` | Rebuild with `FILESYSTEM=1` (files land in MEMFS) |
219
- | JSPI required (flagged on Node) | Loader fetches resources mid-transform via JSPI | Feature-detect with `isJspiAvailable()`; engines without it need a fallback |
220
- | No generated images (latex-image, sageplot, …) | Produced by the Python toolchain, not XSLT | Out of scope; run `pretext generate` and the preview will pick the files up |
221
- | `xi:include` with `xpointer` unsupported | JS resolver stands in for libxml2's | Rebuild adding `xmlXIncludeProcessFlags` to the JSPI export list |
222
- | Renders run one at a time, never in parallel | Shared libxslt state; the transform suspends mid-run | Inherent; `renderHtml` queues concurrent calls for you |
312
+ | Limitation | Cause | Fix |
313
+ | ---------------------------------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------- |
314
+ | No multi-file output (`exsl:document`) | Compiled with `FILESYSTEM=0` | Rebuild with `FILESYSTEM=1` (files land in MEMFS) |
315
+ | JSPI required (flagged on Node) | Loader fetches resources mid-transform via JSPI | Feature-detect with `isJspiAvailable()`; engines without it need a fallback |
316
+ | No generated images (latex-image, sageplot, …) | Produced by the Python toolchain, not XSLT | Out of scope; run `pretext generate` and the preview will pick the files up |
317
+ | `xi:include` with `xpointer` unsupported | JS resolver stands in for libxml2's | Rebuild adding `xmlXIncludeProcessFlags` to the JSPI export list |
318
+ | Renders run one at a time, never in parallel | Shared libxslt state; the transform suspends mid-run | Inherent; `renderHtml` queues concurrent calls for you |
223
319
 
224
320
  The whole-book stack overflow ("memory access out of bounds") that the stock
225
321
  `libxslt-wasm` build hit on large documents is **fixed** in the
@@ -228,7 +324,7 @@ The whole-book stack overflow ("memory access out of bounds") that the stock
228
324
  ### Concurrency
229
325
 
230
326
  A render is not reentrant. It drives a single cached compiled stylesheet
231
- through a patched `globalThis.fetch` and shared mount tables, and it *suspends*
327
+ through a patched `globalThis.fetch` and shared mount tables, and it _suspends_
232
328
  mid-transform to fetch stylesheets — which is precisely the window in which
233
329
  another render would get to run. Overlapping renders interleave inside libxslt
234
330
  and corrupt it.
@@ -239,7 +335,7 @@ render that rejects does not stall the queue.
239
335
 
240
336
  This matters mainly if you drive the internals yourself. If you do, serialize
241
337
  your own calls — the corruption is not self-describing: it surfaces as an
242
- out-of-bounds memory fault, and afterwards the WASM instance aborts on *every*
338
+ out-of-bounds memory fault, and afterwards the WASM instance aborts on _every_
243
339
  later call for the lifetime of the process. Once that has happened, only a
244
340
  restart (or a page reload) recovers; `renderHtml` detects the state and says so
245
341
  rather than repeating the underlying assertion.
@@ -111,11 +111,15 @@
111
111
  <!-- this *must* be first for maximum utility -->
112
112
  <xsl:call-template name="skip-to-content-link" />
113
113
  <!-- HTML5 body/header will be a "banner" landmark automatically -->
114
- <header id="ptx-masthead" class="ptx-masthead">
114
+ <header id="ptx-masthead" class="ptx-masthead" role="banner">
115
115
  <div class="ptx-banner">
116
116
  <xsl:call-template name="brand-logo" />
117
117
  <div class="title-container">
118
- <h1 class="heading">
118
+ <xsl:variable name="banner-heading-element-type">
119
+ <xsl:apply-templates select="." mode="banner-heading-element-type"/>
120
+ </xsl:variable>
121
+ <xsl:element name="{$banner-heading-element-type}">
122
+ <xsl:attribute name="class">heading ptx-banner-heading</xsl:attribute>
119
123
  <xsl:variable name="root-filename">
120
124
  <xsl:apply-templates select="$document-root" mode="containing-filename" />
121
125
  </xsl:variable>
@@ -133,7 +137,7 @@
133
137
  </span>
134
138
  </xsl:if>
135
139
  </a>
136
- </h1>
140
+ </xsl:element>
137
141
  <!-- Serial list of authors/editors -->
138
142
  <xsl:if test="$b-html-banner-byline">
139
143
  <p class="byline">
@@ -142,7 +146,7 @@
142
146
  </p>
143
147
  </xsl:if>
144
148
  </div> <!-- title-container -->
145
- </div> <!-- banner -->
149
+ </div> <!-- banner -->
146
150
  </header> <!-- masthead -->
147
151
  <xsl:apply-templates select="." mode="primary-navigation"/>
148
152
  <xsl:apply-templates select="." mode="latex-macros"/>
@@ -0,0 +1,85 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ GENERATED FILE - do not edit by hand.
4
+ Regenerate with: npm run refresh-xsl -w @pretextbook/pretext-html
5
+
6
+ Wrapper around pretext-revealjs.xsl for in-memory reveal.js slideshow builds
7
+ (previews). The reveal.js conversion is already a single-page conversion, so
8
+ unlike preview-html.xsl this copies no upstream template: it stubs the file
9
+ writers (which a slide holding an "interactive" would otherwise trip) and
10
+ stamps the ids the preview's source map needs onto slides and sections.
11
+
12
+ Intended to be applied together with a publication file that forces
13
+ <revealjs><resources host="cdn" math="online"/></revealjs>, since neither
14
+ locally hosted nor embedded reveal.js resources exist for an in-memory build.
15
+ -->
16
+ <xsl:stylesheet
17
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
18
+ xmlns:exsl="http://exslt.org/common"
19
+ extension-element-prefixes="exsl"
20
+ >
21
+
22
+ <xsl:import href="pretext-revealjs.xsl"/>
23
+ <xsl:output method="html" encoding="UTF-8" doctype-system="about:legacy-compat"/>
24
+
25
+ <!-- Stamp @id onto the reveal.js "section" that upstream builds for each -->
26
+ <!-- slide (and each section of slides), without reproducing any of the -->
27
+ <!-- upstream markup: render it via apply-imports, then re-emit the result -->
28
+ <!-- with the id added to its first element. The id is the same @unique-id -->
29
+ <!-- the rest of PreTeXt's HTML uses, which is what makes it findable from -->
30
+ <!-- the source map. Attributes are copied before the id is set, so an -->
31
+ <!-- upstream id (if one is ever added) is overridden rather than -->
32
+ <!-- duplicated, and both precede any child content, as XSLT requires. -->
33
+ <!-- -->
34
+ <!-- Only the *first* element is stamped, because a "section" does not always -->
35
+ <!-- render as one element: under the "linear" navigation mode upstream emits -->
36
+ <!-- the section's title slide followed by its slides as siblings. Those -->
37
+ <!-- slides were rendered through this same template and carry their own ids -->
38
+ <!-- already, so stamping every top-level element would duplicate the -->
39
+ <!-- section's id across all of them. -->
40
+ <xsl:template match="slide|section">
41
+ <xsl:variable name="preview-id">
42
+ <xsl:apply-templates select="." mode="html-id"/>
43
+ </xsl:variable>
44
+ <xsl:variable name="rendered">
45
+ <xsl:apply-imports/>
46
+ </xsl:variable>
47
+ <!-- Bound once: two exsl:node-set calls on one fragment are not obliged -->
48
+ <!-- to yield the same node identities, which the comparison relies on. -->
49
+ <xsl:variable name="tree" select="exsl:node-set($rendered)"/>
50
+ <xsl:for-each select="$tree/node()">
51
+ <xsl:choose>
52
+ <xsl:when test="generate-id() = generate-id($tree/*[1])">
53
+ <xsl:copy>
54
+ <xsl:copy-of select="@*"/>
55
+ <xsl:attribute name="id">
56
+ <xsl:value-of select="$preview-id"/>
57
+ </xsl:attribute>
58
+ <xsl:copy-of select="node()"/>
59
+ </xsl:copy>
60
+ </xsl:when>
61
+ <xsl:otherwise>
62
+ <xsl:copy-of select="."/>
63
+ </xsl:otherwise>
64
+ </xsl:choose>
65
+ </xsl:for-each>
66
+ </xsl:template>
67
+
68
+ <!-- Same file-writer stubs as preview-html.xsl; see FILE_WRITER_STUBS. -->
69
+ <xsl:template name="index-redirect-page"/>
70
+ <xsl:template match="*" mode="manufacture-knowl"/>
71
+ <xsl:template name="ol-marker-styles"/>
72
+ <xsl:template name="doc-manifest"/>
73
+ <xsl:template name="search-page-construction"/>
74
+ <xsl:template name="scorm-manifest"/>
75
+ <!-- standalone pages for videos and iframe pages for interactives -->
76
+ <xsl:template match="*" mode="standalone-page"/>
77
+ <xsl:template match="*" mode="create-iframe-page"/>
78
+ <!-- runestone-manifest lives in pretext-runestone.xsl -->
79
+ <xsl:template match="*" mode="runestone-manifest"/>
80
+ <xsl:template match="*" mode="simple-file-wrap">
81
+ <xsl:param name="content"/>
82
+ <xsl:copy-of select="$content"/>
83
+ </xsl:template>
84
+
85
+ </xsl:stylesheet>
@@ -3,5 +3,5 @@
3
3
  "repository": "PreTeXtBook/pretext",
4
4
  "ref": "master"
5
5
  },
6
- "refreshed": "2026-07-08T00:48:30.933Z"
6
+ "refreshed": "2026-07-29T17:38:58.196Z"
7
7
  }
@@ -0,0 +1,16 @@
1
+ Copyright 2013 Robert A. Beezer
2
+
3
+ This file is part of PreTeXt.
4
+
5
+ PreTeXt is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 2 or version 3 of the
8
+ License (at your option).
9
+
10
+ PreTeXt is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
@@ -1,31 +1,32 @@
1
- # eXtensible Stylesheet Language (XSL) Stylesheets
1
+ eXtensible Stylesheet Language (XSL) Stylesheets
2
+ ================================================
2
3
 
3
4
  XSL stylesheets are the primary vehicle for converting PreTeXt XML
4
- source into various output formats. As such, they are sometimes
5
- simply called "conversions." Here we list **some** of the available
6
- conversions, the list is not exhaustive. See _The PreTeXt Guide_
5
+ source into various output formats. As such, they are sometimes
6
+ simply called "conversions." Here we list **some** of the available
7
+ conversions, the list is not exhaustive. See _The PreTeXt Guide_
7
8
  for detailed documentation of use, in chapters of the part
8
9
  titled _Publisher's Guide_.
9
10
 
10
- - `pretext-latex.xsl` - conversion to LaTeX, which can then
11
- be converted to PDF, in print or electronic flavors.
12
- - `pretext-html.xsl` - conversion to HTML for online use.
13
- - `pretext-epub.xsl` - conversion to EPUB, which
14
- requires significant additional processing. So this stylesheet
15
- is not meant to be applied in isolation. See the `pretext/pretext`
16
- Python script for an option to initiate the processing pipeline.
17
- - `pretext-jupyter.xsl` - conversion to Jupyter notebooks.
18
- - `pretext-revealjs.xsl` - conversion of slideshows to HTML.
19
- - `pretext-beamer.xsl` - conversion of slideshows to PDF.
20
- - `pretext-braille.xsl` - conversion to a precursor for braille output, which
21
- requires significant further processing. So this stylesheet
22
- is not meant to be applied in isolation. See the `pretext/pretext`
23
- Python script for an option to initiate the processing pipeline.
24
- - `pretext-common.xsl` - base templates, and not useful in isolation.
25
- - `pretext-assembly.xsl` - pre-processing stylesheet, which creates an
26
- enhanced version of source. Applied in a controlled way by other stylesheets.
27
- See the `utilities\pretext-enhanced-source.xsl` stylesheet for a demonstration.
28
- - `extract-*.xsl` - used to isolate particular parts of a PreTeXt
29
- document, typically for subsequent processing by a script.
11
+ * `pretext-latex.xsl` - conversion to LaTeX, which can then
12
+ be converted to PDF, in print or electronic flavors.
13
+ * `pretext-html.xsl` - conversion to HTML for online use.
14
+ * `pretext-epub.xsl` - conversion to EPUB, which
15
+ requires significant additional processing. So this stylesheet
16
+ is not meant to be applied in isolation. See the `pretext/pretext`
17
+ Python script for an option to initiate the processing pipeline.
18
+ * `pretext-jupyter.xsl` - conversion to Jupyter notebooks.
19
+ * `pretext-revealjs.xsl` - conversion of slideshows to HTML.
20
+ * `pretext-beamer.xsl` - conversion of slideshows to PDF.
21
+ * `pretext-braille.xsl` - conversion to a precursor for braille output, which
22
+ requires significant further processing. So this stylesheet
23
+ is not meant to be applied in isolation. See the `pretext/pretext`
24
+ Python script for an option to initiate the processing pipeline.
25
+ * `pretext-common.xsl` - base templates, and not useful in isolation.
26
+ * `pretext-assembly.xsl` - pre-processing stylesheet, which creates an
27
+ enhanced version of source. Applied in a controlled way by other stylesheets.
28
+ See the `utilities\pretext-enhanced-source.xsl` stylesheet for a demonstration.
29
+ * `extract-*.xsl` - used to isolate particular parts of a PreTeXt
30
+ document, typically for subsequent processing by a script.
30
31
 
31
32
  (Updated: 2020-06-12)
@@ -37,6 +37,19 @@
37
37
 
38
38
  <!ENTITY SPECIALIZED-DIVISION "exercises|worksheet|handout|reading-questions|references|glossary|solutions">
39
39
 
40
+ <!-- A "printout" is a specialized division whose content is laid out -->
41
+ <!-- for printing, with workspace for a reader to write. A collection -->
42
+ <!-- of nothing but printouts is a "workbook". -->
43
+ <!ENTITY PRINTOUT "worksheet|handout">
44
+
45
+ <!-- "Division companions" are the non-structural companions of a -->
46
+ <!-- structured traditional division: they may earn their own page -->
47
+ <!-- (and links) when their parent is realized as a summary page in -->
48
+ <!-- a chunked conversion (HTML and derivatives). The schema only -->
49
+ <!-- allows these four elements, division-flavored, in the parents -->
50
+ <!-- listed. The filter form presumes context has qualified parents. -->
51
+ <!ENTITY DIVISION-COMPANION "introduction[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]|conclusion[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]|objectives[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]|outcomes[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]">
52
+
40
53
  <!-- for filtering nodes, eg *[&STRUCTURAL-FILTER;], *[not(&STRUCTURAL-FILTER;)] -->
41
54
  <!ENTITY STRUCTURAL-FILTER "self::book or self::article or self::slideshow or self::letter or self::memo or self::frontmatter or self::part or self::chapter or self::appendix or self::index or self::preface or self::acknowledgement or self::biography or self::foreword or self::dedication or self::colophon or self::section or self::subsection or self::subsubsection or self::slide or self::exercises or self::worksheet or self::handout or self::reading-questions or self::solutions or self::references or self::glossary or self::backmatter">
42
55
 
@@ -44,6 +57,10 @@
44
57
 
45
58
  <!ENTITY SPECIALIZED-DIVISION-FILTER "self::exercises or self::worksheet or self::handout or self::reading-questions or self::references or self::glossary or self::solutions">
46
59
 
60
+ <!ENTITY PRINTOUT-FILTER "self::worksheet or self::handout">
61
+
62
+ <!ENTITY DIVISION-COMPANION-FILTER "self::introduction or self::conclusion or self::objectives or self::outcomes">
63
+
47
64
  <!-- NB: (2019-06-12) Only the two metadata "filters" seem to -->
48
65
  <!-- be in use, so only those are being maintained. grep'ing on -->
49
66
  <!-- METADATA v. METADATA-FILTER, and applying "wc" makes this evident. -->
@@ -139,6 +156,16 @@
139
156
  <!ENTITY FUNDAMENTAL-BLOCK-FILTER "(&DEFINITION-FILTER;) or (&THEOREM-FILTER;) or (&AXIOM-FILTER;) or (&REMARK-FILTER;) or (&COMPUTATION-FILTER;) or (&EXAMPLE-FILTER;)">
140
157
  <!ENTITY TOP-FIGURE-FILTER "(&FIGURE-FILTER;) and not(parent::sidebyside/parent::figure or parent::sidebyside/parent::sbsgroup/parent::figure)">
141
158
 
159
+ <!-- Panels of a "sidebyside", and content of a "stack" panel. The -->
160
+ <!-- lists mirror the schema, plus grandfathered items the code still -->
161
+ <!-- tolerates: "audio", "video", "interactive" (precluded -->
162
+ <!-- 2026-07-22, may someday be removed). An "exercise" panel -->
163
+ <!-- (worksheet or handout only) and a "slate" panel (within an -->
164
+ <!-- "interactive" only) are policed by the validation-plus -->
165
+ <!-- stylesheet. -->
166
+ <!ENTITY SBSPANEL "p|pre|ol|ul|dl|program|console|poem|audio|video|interactive|slate|exercise|image|figure|table|listing|list|tabular|stack">
167
+ <!ENTITY STACKABLE "tabular|image|p|pre|ol|ul|dl|audio|video|interactive|slate|program|console">
168
+
142
169
  <!-- appendages of examples, exercises, tasks -->
143
170
  <!ENTITY SOLUTION-LIKE "hint|answer|solution">
144
171
  <!ENTITY SOLUTION-FILTER "self::hint or self::answer or self::solution">
@@ -100,7 +100,7 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
100
100
  <!-- TODO: perhaps report content also, as a better assist, or the self/parent/ancestor biblio id -->
101
101
  <!-- TODO: refine to include un-implemented bits of "citeproc-py" (e/g static-ordering) -->
102
102
  <xsl:template match="*" mode="biblio-to-json">
103
- <xsl:message>BUG: PreTeXt "biblio" markup using a "<xsl:value-of select="local-name()"/>" element is not implemented</xsl:message>
103
+ <xsl:message>PTX:BUG: PreTeXt "biblio" markup using a "<xsl:value-of select="local-name()"/>" element is not implemented</xsl:message>
104
104
  </xsl:template>
105
105
 
106
106
  <!-- Gross JSON array structure, duplicate an ID for the division -->
@@ -296,8 +296,10 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
296
296
  <xsl:variable name="the-ref">
297
297
  <xsl:value-of select="."/>
298
298
  </xsl:variable>
299
- <!-- context switch so id() function works -->
300
- <xsl:for-each select="$original">
299
+ <!-- context switch so id() function works; the assembled -->
300
+ <!-- tree, so content excluded by the version in play does -->
301
+ <!-- not validate a citation -->
302
+ <xsl:for-each select="$root">
301
303
  <xsl:variable name="target" select="id($the-ref)"/>
302
304
  <!-- vet each @ref value, only backmatter is considered -->
303
305
  <xsl:if test="$target/self::biblio/parent::references/parent::backmatter">
@@ -317,7 +319,7 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
317
319
  <xsl:element name="xref-csl" namespace="http://pretextbook.org/2020/pretext/internal">
318
320
  <!-- namespacing the attribute is sort of ugly -->
319
321
  <xsl:attribute name="id">
320
- <xsl:value-of select="@assembly-id"/>
322
+ <xsl:value-of select="@pi:assembly-id"/>
321
323
  </xsl:attribute>
322
324
  <xsl:value-of select="$citation-item-list"/>
323
325
  </xsl:element>
@@ -23,9 +23,11 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
23
23
  <!-- dynamic content. Create a standalone page for each. -->
24
24
 
25
25
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
26
+ xmlns:pi="http://pretextbook.org/2020/pretext/internal"
26
27
  xmlns:xml="http://www.w3.org/XML/1998/namespace"
27
28
  xmlns:exsl="http://exslt.org/common"
28
29
  xmlns:str="http://exslt.org/strings"
30
+ exclude-result-prefixes="pi"
29
31
  extension-element-prefixes="exsl"
30
32
  >
31
33
 
@@ -69,7 +71,7 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
69
71
  <!-- exercise/setup indicates the exercise will -->
70
72
  <!-- require Runestone and javascript to generate -->
71
73
  <!-- the content. -->
72
- <!-- Stylesheet output is text, with "visible-id" -->
74
+ <!-- Stylesheet output is text, with "unique-id" -->
73
75
  <!-- of each exercise, one per line, to be captured -->
74
76
  <!-- captured in a text file to guide snapshotting -->
75
77
  <!-- Make the standalone page for each exercise -->
@@ -82,21 +84,21 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
82
84
  <xsl:text>]</xsl:text>
83
85
  </xsl:template>
84
86
 
85
- <xsl:template match="exercise[@exercise-interactive='fillin' and setup]
86
- | project[@exercise-interactive='fillin' and setup]
87
- | activity[@exercise-interactive='fillin' and setup]
88
- | exploration[@exercise-interactive='fillin' and setup]
89
- | investigation[@exercise-interactive='fillin' and setup]
90
- | exercise//task[@exercise-interactive='fillin' and setup]
91
- | project//task[@exercise-interactive='fillin' and setup]
92
- | activity//task[@exercise-interactive='fillin' and setup]
93
- | exploration//task[@exercise-interactive='fillin' and setup]
94
- | investigation//task[@exercise-interactive='fillin' and setup]"
87
+ <xsl:template match="exercise[@pi:exercise-interactive='fillin' and setup]
88
+ | project[@pi:exercise-interactive='fillin' and setup]
89
+ | activity[@pi:exercise-interactive='fillin' and setup]
90
+ | exploration[@pi:exercise-interactive='fillin' and setup]
91
+ | investigation[@pi:exercise-interactive='fillin' and setup]
92
+ | exercise//task[@pi:exercise-interactive='fillin' and setup]
93
+ | project//task[@pi:exercise-interactive='fillin' and setup]
94
+ | activity//task[@pi:exercise-interactive='fillin' and setup]
95
+ | exploration//task[@pi:exercise-interactive='fillin' and setup]
96
+ | investigation//task[@pi:exercise-interactive='fillin' and setup]"
95
97
  mode="extraction">
96
98
  <xsl:text>,&#xa;</xsl:text>
97
99
  <xsl:text>{</xsl:text>
98
100
  <xsl:text> "exercise_id": "</xsl:text>
99
- <!-- Key the round trip on @assembly-id, the early identifier the -->
101
+ <!-- Key the round trip on @pi:assembly-id, the early identifier the-->
100
102
  <!-- substitution pass reads back. @label only exists for labeled -->
101
103
  <!-- exercises, so it would miss unlabeled exercises and tasks. -->
102
104
  <xsl:apply-templates select="." mode="assembly-id" />
@@ -51,7 +51,7 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
51
51
  <xsl:variable name="exercise-style" select="'dynamic'"/>
52
52
 
53
53
  <!-- @preview indicates custom image is present -->
54
- <!-- Stylesheet output is text, with "visible-id" -->
54
+ <!-- Stylesheet output is text, with "unique-id" -->
55
55
  <!-- of each interactive, one per line, to be -->
56
56
  <!-- captured in a text file to guide snapshotting -->
57
57
  <!-- Make the iframe and standalone page for each -->
@@ -60,7 +60,7 @@ along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
60
60
  <!-- in pretext-html.xsl. Results are HTML files -->
61
61
  <!-- (despite this stylesheet having text output). -->
62
62
  <xsl:template match="interactive[not(@preview)]" mode="extraction">
63
- <xsl:apply-templates select="." mode="visible-id" />
63
+ <xsl:apply-templates select="." mode="unique-id" />
64
64
  <xsl:text>&#xa;</xsl:text>
65
65
  <!-- (2) Identical content, but now isolated on a reader-friendly page -->
66
66
  <!-- The standalone page has its own masthead h1, so headings inside -->