@pretextbook/pretext-html 0.1.0 → 0.2.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 (106) hide show
  1. package/README.md +104 -4
  2. package/assets/preview-html.xsl +230 -230
  3. package/assets/upstream.json +7 -7
  4. package/assets/xsl/entities.ent +154 -154
  5. package/assets/xsl/extract-asymptote.xsl +68 -68
  6. package/assets/xsl/extract-biblio-csl.xsl +327 -327
  7. package/assets/xsl/extract-datafile.xsl +71 -71
  8. package/assets/xsl/extract-dynamic.xsl +139 -139
  9. package/assets/xsl/extract-identity.xsl +136 -136
  10. package/assets/xsl/extract-interactive.xsl +81 -81
  11. package/assets/xsl/extract-latex-image.xsl +118 -118
  12. package/assets/xsl/extract-mermaid.xsl +58 -58
  13. package/assets/xsl/extract-mom.xsl +63 -63
  14. package/assets/xsl/extract-pg.xsl +2897 -2897
  15. package/assets/xsl/extract-prefigure.xsl +157 -157
  16. package/assets/xsl/extract-qrcode.xsl +100 -100
  17. package/assets/xsl/extract-runestone-page-template.xsl +139 -139
  18. package/assets/xsl/extract-sageplot.xsl +166 -166
  19. package/assets/xsl/extract-stack.xsl +56 -56
  20. package/assets/xsl/extract-trace.xsl +134 -134
  21. package/assets/xsl/extract-youtube.xsl +63 -63
  22. package/assets/xsl/html-symbols.xsl +3344 -3344
  23. package/assets/xsl/latex/pretext-latex-AIM.xsl +56 -56
  24. package/assets/xsl/latex/pretext-latex-CLP.xsl +148 -148
  25. package/assets/xsl/latex/pretext-latex-chaos.xsl +317 -317
  26. package/assets/xsl/latex/pretext-latex-dyslexic-font.xsl +76 -76
  27. package/assets/xsl/latex/pretext-latex-guide.xsl +104 -104
  28. package/assets/xsl/latex/pretext-latex-texstyle.xsl +862 -862
  29. package/assets/xsl/localizations/af-ZA.xml +276 -276
  30. package/assets/xsl/localizations/bg-BG.xml +276 -276
  31. package/assets/xsl/localizations/ca-ES.xml +285 -285
  32. package/assets/xsl/localizations/cs-CZ.xml +280 -280
  33. package/assets/xsl/localizations/de-DE.xml +281 -281
  34. package/assets/xsl/localizations/en-US.xml +427 -427
  35. package/assets/xsl/localizations/es-ES.xml +287 -287
  36. package/assets/xsl/localizations/fi-FI.xml +275 -275
  37. package/assets/xsl/localizations/fr-CA.xml +276 -276
  38. package/assets/xsl/localizations/fr-FR.xml +280 -280
  39. package/assets/xsl/localizations/hu-HU.xml +280 -280
  40. package/assets/xsl/localizations/it-IT.xml +276 -276
  41. package/assets/xsl/localizations/ku-CKB.xml +275 -275
  42. package/assets/xsl/localizations/localizations.xml +48 -48
  43. package/assets/xsl/localizations/nl-NL.xml +275 -275
  44. package/assets/xsl/localizations/pt-BR.xml +288 -288
  45. package/assets/xsl/localizations/pt-PT.xml +292 -292
  46. package/assets/xsl/localizations/zh-HANS.xml +269 -269
  47. package/assets/xsl/pretext-assembly.xsl +4795 -4795
  48. package/assets/xsl/pretext-basic-html.xsl +86 -86
  49. package/assets/xsl/pretext-beamer.xsl +662 -662
  50. package/assets/xsl/pretext-braille-preprint.xsl +2249 -2249
  51. package/assets/xsl/pretext-common.xsl +12018 -12018
  52. package/assets/xsl/pretext-dynamic.xsl +65 -65
  53. package/assets/xsl/pretext-epub.xsl +1483 -1483
  54. package/assets/xsl/pretext-fo.xsl +4593 -4593
  55. package/assets/xsl/pretext-html.xsl +14791 -14791
  56. package/assets/xsl/pretext-json-manifest.xsl +150 -150
  57. package/assets/xsl/pretext-jupyter.xsl +868 -868
  58. package/assets/xsl/pretext-latex-classic.xsl +952 -952
  59. package/assets/xsl/pretext-latex-common.xsl +11563 -11563
  60. package/assets/xsl/pretext-latex.xsl +47 -47
  61. package/assets/xsl/pretext-litprog.xsl +105 -105
  62. package/assets/xsl/pretext-merge.xsl +41 -41
  63. package/assets/xsl/pretext-numbers.xsl +875 -875
  64. package/assets/xsl/pretext-revealjs.xsl +522 -522
  65. package/assets/xsl/pretext-runestone-fitb.xsl +1233 -1233
  66. package/assets/xsl/pretext-runestone-static.xsl +1438 -1438
  67. package/assets/xsl/pretext-runestone.xsl +3083 -3083
  68. package/assets/xsl/pretext-sage-doctest.xsl +289 -289
  69. package/assets/xsl/pretext-smc.xsl +492 -492
  70. package/assets/xsl/pretext-solution-manual-latex.xsl +323 -323
  71. package/assets/xsl/pretext-text-utilities.xsl +1217 -1217
  72. package/assets/xsl/pretext-text.xsl +392 -392
  73. package/assets/xsl/pretext-units.xsl +195 -195
  74. package/assets/xsl/pretext-view-source.xsl +157 -157
  75. package/assets/xsl/pretext-ww-problem-sets.xsl +391 -391
  76. package/assets/xsl/publisher-variables.xsl +4756 -4756
  77. package/assets/xsl/support/extract-math.xsl +256 -256
  78. package/assets/xsl/support/package-math.xsl +141 -141
  79. package/assets/xsl/support/play-button/play-button.svg +3 -3
  80. package/assets/xsl/support/pretext-pg-macros.xsl +110 -110
  81. package/assets/xsl/support/webpack_static_imports.xml +14 -14
  82. package/assets/xsl/tests/null.xml +3 -3
  83. package/assets/xsl/tests/pretext-text-utilities-test.xsl +333 -333
  84. package/assets/xsl/utilities/author-report.xsl +107 -107
  85. package/assets/xsl/utilities/deprecate-autoname.sed +18 -18
  86. package/assets/xsl/utilities/deprecate-index.sed +33 -33
  87. package/assets/xsl/utilities/fix-deprecations.xsl +663 -663
  88. package/assets/xsl/utilities/pretext-enhanced-source.xsl +112 -112
  89. package/assets/xsl/utilities/report-publisher-variables.xsl +162 -162
  90. package/assets/xsl/xml-to-json.xsl +326 -326
  91. package/assets/xsl/xml-to-string.xsl +328 -328
  92. package/assets/xsl-bundle.json +1 -0
  93. package/dist/{cli-C6tfAVvi.js → cli-B2LiKunq.js} +268 -233
  94. package/dist/cli.js +1 -1
  95. package/dist/host.browser.d.ts +29 -0
  96. package/dist/host.d.ts +41 -0
  97. package/dist/index.browser.d.ts +29 -0
  98. package/dist/index.browser.js +650 -0
  99. package/dist/index.d.ts +5 -0
  100. package/dist/index.js +16 -8
  101. package/dist/internal/posix-path.d.ts +59 -0
  102. package/dist/mounts.d.ts +18 -0
  103. package/dist/renderer.d.ts +14 -1
  104. package/dist/theme.d.ts +68 -0
  105. package/dist/theme.js +93 -0
  106. package/package.json +22 -4
package/README.md CHANGED
@@ -71,12 +71,103 @@ const { html } = await renderHtml({
71
71
  makes single-page in-memory output possible.
72
72
  - The compiled stylesheet is cached per `xslDir` (~1s to compile, then
73
73
  ~100ms–1s per render depending on document size).
74
+ - `theme: "dark" | "light" | "system"` makes the preview follow the embedding
75
+ app's light/dark theme (see [Theme control](#theme-control)).
76
+
77
+ ### API (browser)
78
+
79
+ The same renderer runs in a browser — no server, no Python. Bundlers pick it up
80
+ through the `browser` export condition automatically; there is nothing to
81
+ configure.
82
+
83
+ ```js
84
+ import { renderHtml, isJspiAvailable } from "@pretextbook/pretext-html";
85
+
86
+ if (!isJspiAvailable()) {
87
+ // No WebAssembly JSPI in this engine — fall back to a server-side build.
88
+ }
89
+
90
+ const { html } = await renderHtml({
91
+ sourcePath: "/source/main.ptx", // a *virtual* path: no filesystem is read
92
+ sourceContent: editorText, // required in the browser
93
+ projectDir: "/source",
94
+ fragment: true, // rendering one division on its own
95
+ });
96
+ ```
97
+
98
+ Differences from the Node API, all of them consequences of there being no
99
+ filesystem:
100
+
101
+ - **`sourceContent` is required.** `sourcePath` still anchors relative
102
+ `xi:include`s and the output's URLs, but nothing is read from it.
103
+ - **`xi:include`s are not resolved from disk.** Pre-merge them, or pass the
104
+ already-merged document as `sourceContent`. An unresolvable include uses its
105
+ `<xi:fallback>` if it has one, and otherwise throws.
106
+ - **`publicationPath` / `docinfoSourcePath` need absolute URLs**, since those
107
+ are the only readable locations. Prefer `docinfo` (a string) over
108
+ `docinfoSourcePath`.
109
+ - **Stylesheets are fetched from jsDelivr**, version-pinned to the installed
110
+ package, so no build configuration is needed. To self-host them, copy this
111
+ package's `assets/` directory somewhere your app serves and call
112
+ `setAssetsBase("/pretext-assets")` before the first render. (Under Node the
113
+ equivalent is `PRETEXT_HTML_ASSETS`, or the same `setAssetsBase`.)
114
+ - **A cold render costs two requests**, not ~32: `assets/xsl-bundle.json` packs
115
+ the whole stylesheet closure (13 stylesheets plus the 17 locale files
116
+ `pretext-common.xsl` eagerly loads) into one file. It is purely an
117
+ optimisation — if it is missing, each file is fetched individually and the
118
+ render still succeeds. It is recorded from a real render by
119
+ `npm run build-xsl-bundle`, which runs as part of `npm run build`.
120
+
121
+ Typical timings, measured on a single-division fragment: **~400ms cold**
122
+ (stylesheet compile plus asset fetch, paid once per session and then cached)
123
+ and **~90ms warm**. That is what makes preview-on-save feel instant.
124
+
125
+ `setMountReader()` is the escape hatch if neither delivery mode fits — it lets
126
+ you serve the stylesheets from an in-memory map, a zip, or a webview resource
127
+ URI.
128
+
129
+ ### Theme control
130
+
131
+ A rendered page can already switch between light and dark — pretext-core.js
132
+ exposes `window.setDarkMode(isDark)` — but on its own it only decides which to
133
+ use from `localStorage` and `prefers-color-scheme`. Neither reflects an
134
+ embedder's surroundings ("VS Code is in a dark editor theme", "pretext.plus is
135
+ in dark mode"). The `theme` render option lets the app drive it instead:
136
+
137
+ ```js
138
+ import { renderHtml } from "@pretextbook/pretext-html";
139
+ // dependency-free subpath — no WASM renderer pulled in:
140
+ import { previewThemeMessage } from "@pretextbook/pretext-html/theme";
141
+
142
+ const { html } = await renderHtml({
143
+ sourcePath: "source/main.ptx",
144
+ theme: "dark", // initial theme baked in (no light-then-dark flash)
145
+ });
146
+
147
+ // Later, when the host theme changes, post an update — no re-render needed:
148
+ iframe.contentWindow.postMessage(previewThemeMessage("light"), "*");
149
+ // (VS Code webview: webview.postMessage(previewThemeMessage("light")))
150
+ // (inline render: window.postMessage(previewThemeMessage("light"), "*"))
151
+ ```
152
+
153
+ When `theme` is set, the renderer injects a small script into the page `<head>`
154
+ that (1) applies the initial theme and (2) listens for
155
+ `postMessage({ type: "pretext-html:set-theme", theme })` from the embedder and
156
+ re-applies live. `"system"` follows `prefers-color-scheme`. Omit `theme`
157
+ entirely and the output is byte-identical to a plain render — the page keeps
158
+ its native `localStorage`/`prefers-color-scheme` behaviour. The
159
+ `@pretextbook/pretext-html/theme` subpath exports the protocol
160
+ (`PreviewTheme`, `PREVIEW_THEME_MESSAGE`, `previewThemeMessage`,
161
+ `isPreviewTheme`) with no dependency on the renderer, so a host can import just
162
+ the message helper.
74
163
 
75
164
  ## Requirements
76
165
 
77
- - **Node ≥ 22** launched with **`--experimental-wasm-jspi`** (WebAssembly
78
- stack switching). The flag is not allowed in `NODE_OPTIONS`; it must be on
79
- the command line. The `pretext-html` CLI re-executes itself with the flag;
166
+ - **Node ≥ 24** launched with **`--experimental-wasm-jspi`** (WebAssembly
167
+ stack switching). Node 22 does **not** work despite accepting the flag: its
168
+ V8 (12.4) has only the older Suspender-era JSPI and never exposes the
169
+ `WebAssembly.Suspending` API this package needs. The flag is not allowed in
170
+ `NODE_OPTIONS`; it must be on the command line. The `pretext-html` CLI re-executes itself with the flag;
80
171
  API users must supply it themselves (in tests, vitest's `execArgv` option
81
172
  works — see `vite.config.mts`).
82
173
  - Runtimes with V8 ≥ 13.7 (Chromium/Electron ≥ 137, and eventually Node
@@ -110,13 +201,22 @@ const { html } = await renderHtml({
110
201
  (libxml2's own XInclude pass cannot suspend in the current WASM build).
111
202
  Supports nested includes, `parse="text"`, and `xi:fallback`; `xpointer` is
112
203
  not supported.
204
+ 5. **Platform seam** — `src/host.ts` holds everything that touches the outside
205
+ world: read a file under a mount, read a caller-named file, locate
206
+ `assets/`. Under Node those are filesystem calls; in the browser build
207
+ (`src/host.browser.ts`, swapped in by `vite.config.mts`) they are `fetch`es.
208
+ The browser build also substitutes a posix-only `node:path`
209
+ (`src/internal/posix-path.ts`), which is sound because no path this package
210
+ computes ever reaches a real filesystem — with `FILESYSTEM=0` they are all
211
+ virtual, ending up as mount keys or `.ptx.invalid` URL segments. The result
212
+ has no `node:` imports at all; rollup fails the build if one survives.
113
213
 
114
214
  ## Limitations (current WASM build)
115
215
 
116
216
  | Limitation | Cause | Fix |
117
217
  | ---------------------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------- |
118
218
  | No multi-file output (`exsl:document`) | Compiled with `FILESYSTEM=0` | Rebuild with `FILESYSTEM=1` (files land in MEMFS) |
119
- | Node only, JSPI flag required | Loader fetches resources mid-transform via JSPI | Preload stylesheets into MEMFS at init, or wait for JSPI to ship unflagged |
219
+ | JSPI required (flagged on Node) | Loader fetches resources mid-transform via JSPI | Feature-detect with `isJspiAvailable()`; engines without it need a fallback |
120
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 |
121
221
  | `xi:include` with `xpointer` unsupported | JS resolver stands in for libxml2's | Rebuild adding `xmlXIncludeProcessFlags` to the JSPI export list |
122
222
 
@@ -1,230 +1,230 @@
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-html.xsl for single-page in-memory HTML builds
7
- (previews). The "file-wrap" template below is a verbatim copy of the
8
- upstream template with the <exsl:document> element removed, so the complete
9
- page is emitted on the main result tree. Intended to be applied together
10
- with a publication file that sets <html><platform portable="yes"/></html>,
11
- which forces chunk level 0 (one page) and CDN-hosted css/js, and suppresses
12
- most auxiliary file output. Remaining file writers are stubbed at the end.
13
- -->
14
- <xsl:stylesheet
15
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
16
- xmlns:xml="http://www.w3.org/XML/1998/namespace"
17
- xmlns:svg="http://www.w3.org/2000/svg"
18
- xmlns:xlink="http://www.w3.org/1999/xlink"
19
- xmlns:pi="http://pretextbook.org/2020/pretext/internal"
20
- xmlns:exsl="http://exslt.org/common"
21
- xmlns:date="http://exslt.org/dates-and-times"
22
- xmlns:str="http://exslt.org/strings"
23
- xmlns:fn="http://www.w3.org/2005/xpath-functions"
24
- xmlns:pf="https://prefigure.org"
25
- exclude-result-prefixes="svg xlink pi fn pf"
26
- extension-element-prefixes="exsl date str"
27
- >
28
-
29
- <xsl:import href="pretext-html.xsl"/>
30
- <xsl:output method="html" encoding="UTF-8" doctype-system="about:legacy-compat"/>
31
-
32
- <!-- Copied from pretext-html.xsl (mode="file-wrap"), exsl:document removed -->
33
- <xsl:template match="*" mode="file-wrap">
34
- <xsl:param name="content" />
35
- <xsl:param name="title" select="''"/>
36
- <xsl:param name="filename" select="''"/>
37
- <xsl:param name="b-has-printout" select="false()"/>
38
- <xsl:param name="b-include-bottom-nav" select="true()"/>
39
-
40
- <xsl:variable name="the-filename">
41
- <xsl:choose>
42
- <xsl:when test="not($filename = '')">
43
- <xsl:value-of select="$filename"/>
44
- </xsl:when>
45
- <xsl:otherwise>
46
- <xsl:apply-templates select="." mode="containing-filename" />
47
- </xsl:otherwise>
48
- </xsl:choose>
49
- </xsl:variable>
50
-
51
-
52
- <xsl:call-template name="converter-blurb-html-no-date"/>
53
- <html>
54
- <xsl:call-template name="language-attributes"/>
55
- <xsl:call-template name="html-theme-attributes"/>
56
- <xsl:call-template name="pretext-advertisement-and-style"/>
57
- <!-- Open Graph Protocol only in "meta" elements, within "head" -->
58
- <head xmlns:og="http://ogp.me/ns#" xmlns:book="https://ogp.me/ns/book#">
59
- <!-- optional head content that needs to come prior to other content -->
60
- <xsl:apply-templates select="." mode="file-wrap-head-pre"/>
61
- <title>
62
- <xsl:choose>
63
- <xsl:when test="$title != ''">
64
- <xsl:value-of select="$title"/>
65
- </xsl:when>
66
- <xsl:otherwise>
67
- <!-- Leading with initials is useful for small tabs -->
68
- <xsl:if test="$docinfo/initialism">
69
- <xsl:apply-templates select="$docinfo/initialism" />
70
- <xsl:text> </xsl:text>
71
- </xsl:if>
72
- <xsl:apply-templates select="." mode="title-plain" />
73
- </xsl:otherwise>
74
- </xsl:choose>
75
- </title>
76
- <!-- canonical link for better SEO -->
77
- <xsl:call-template name="canonical-link">
78
- <xsl:with-param name="filename" select="$the-filename"/>
79
- </xsl:call-template>
80
- <!-- grab the contents every page gets -->
81
- <xsl:copy-of select="$file-wrap-full-head-cache"/>
82
- <!-- now do anything that is or could be page-specific and comes after cache -->
83
- <xsl:apply-templates select="." mode="knowl" />
84
- <!-- webwork's iframeResizer needs to come before sagecell template -->
85
- <xsl:apply-templates select="." mode="sagecell" />
86
- <!-- optional head content that might override other content-->
87
- <xsl:apply-templates select="." mode="file-wrap-head-post"/>
88
- </head>
89
- <body>
90
- <xsl:if test="$b-has-stack">
91
- <xsl:attribute name="onload">
92
- <xsl:text>docHasLoaded()</xsl:text>
93
- </xsl:attribute>
94
- </xsl:if>
95
-
96
- <!-- potential document-id per-page -->
97
- <xsl:call-template name="document-id"/>
98
- <!-- React flag -->
99
- <xsl:call-template name="react-in-use-flag"/>
100
- <!-- the first class controls the default icon -->
101
- <xsl:attribute name="class">
102
- <xsl:choose>
103
- <xsl:when test="$root/book">pretext book</xsl:when>
104
- <xsl:when test="$root/article">pretext article</xsl:when>
105
- </xsl:choose>
106
- <xsl:apply-templates select="." mode="file-wrap-body-attr-extra"/>
107
- <!-- ignore MathJax signals everywhere, then enable selectively -->
108
- <xsl:text> ignore-math</xsl:text>
109
- </xsl:attribute>
110
- <!-- assistive "Skip to main content" link -->
111
- <!-- this *must* be first for maximum utility -->
112
- <xsl:call-template name="skip-to-content-link" />
113
- <!-- HTML5 body/header will be a "banner" landmark automatically -->
114
- <header id="ptx-masthead" class="ptx-masthead">
115
- <div class="ptx-banner">
116
- <xsl:call-template name="brand-logo" />
117
- <div class="title-container">
118
- <h1 class="heading">
119
- <xsl:variable name="root-filename">
120
- <xsl:apply-templates select="$document-root" mode="containing-filename" />
121
- </xsl:variable>
122
- <a href="{$root-filename}">
123
- <xsl:variable name="b-has-subtitle" select="boolean($document-root/subtitle)"/>
124
- <span class="title">
125
- <!-- Do not use shorttitle in masthead, -->
126
- <!-- which is much like cover of a book -->
127
- <xsl:apply-templates select="$document-root" mode="title-simple" />
128
- </span>
129
- <xsl:if test="$b-has-subtitle and $b-html-banner-subtitle">
130
- <xsl:text> </xsl:text>
131
- <span class="subtitle">
132
- <xsl:apply-templates select="$document-root" mode="subtitle" />
133
- </span>
134
- </xsl:if>
135
- </a>
136
- </h1>
137
- <!-- Serial list of authors/editors -->
138
- <xsl:if test="$b-html-banner-byline">
139
- <p class="byline">
140
- <xsl:apply-templates select="$bibinfo/author" mode="name-list"/>
141
- <xsl:apply-templates select="$bibinfo/editor" mode="name-list"/>
142
- </p>
143
- </xsl:if>
144
- </div> <!-- title-container -->
145
- </div> <!-- banner -->
146
- </header> <!-- masthead -->
147
- <xsl:apply-templates select="." mode="primary-navigation"/>
148
- <xsl:apply-templates select="." mode="latex-macros"/>
149
- <div class="ptx-page">
150
- <xsl:apply-templates select="." mode="sidebars" />
151
- <!-- HTML5 main will be a "main" landmark automatically -->
152
- <main class="ptx-main">
153
- <xsl:if test="$b-watermark">
154
- <xsl:attribute name="style">
155
- <xsl:value-of select="$watermark-css"/>
156
- </xsl:attribute>
157
- </xsl:if>
158
- <div id="ptx-content" class="ptx-content">
159
- <xsl:if test="$b-has-printout">
160
- <xsl:apply-templates select="." mode="print-preview-header"/>
161
- </xsl:if>
162
- <!-- Alternative to "copy-of": convert $content to a -->
163
- <!-- node-set, and then hit with an identity template -->
164
- <!-- to duplicate. Experiment indicates no change in -->
165
- <!-- output. (2023-01-11) -->
166
- <xsl:copy-of select="$content" />
167
- </div>
168
- <xsl:if test="$b-include-bottom-nav">
169
- <div id="ptx-content-footer" class="ptx-content-footer">
170
- <xsl:apply-templates select="." mode="previous-button"/>
171
- <xsl:variable name="top-localization">
172
- <xsl:apply-templates select="." mode="type-name">
173
- <xsl:with-param name="string-id" select="'top'"/>
174
- </xsl:apply-templates>
175
- </xsl:variable>
176
- <a class="top-button button" href="#" title="{$top-localization}">
177
- <xsl:call-template name="insert-symbol">
178
- <xsl:with-param name="name" select="'expand_less'"/>
179
- </xsl:call-template>
180
- <span class="name">
181
- <xsl:value-of select="$top-localization"/>
182
- </span>
183
- </a>
184
- <xsl:apply-templates select="." mode="next-button"/>
185
- </div>
186
- </xsl:if>
187
- </main>
188
- </div>
189
- <!-- formerly "extra" -->
190
- <div id="ptx-page-footer" class="ptx-page-footer">
191
- <xsl:apply-templates select="." mode="feedback-button"/>
192
- <xsl:call-template name="pretext-link" />
193
- <xsl:call-template name="runestone-link"/>
194
- <xsl:call-template name="mathjax-link" />
195
- </div>
196
- <xsl:copy-of select="$file-wrap-full-endbody-cache"/>
197
- <!-- For portable builds we stash the lunr search here -->
198
- <xsl:if test="$b-portable-html and $has-native-search">
199
- <xsl:call-template name="embedded-search-construction"/>
200
- </xsl:if>
201
- <!-- optional body content that needs to be inserted after all content -->
202
- <!-- e.g. script tags to run immediately -->
203
- <xsl:apply-templates select="." mode="file-wrap-body-post"/>
204
- </body>
205
- </html>
206
-
207
- </xsl:template>
208
-
209
- <!-- Stub out the remaining file writers (every other template reachable -->
210
- <!-- from pretext-html.xsl that contains exsl:document). Under portable- -->
211
- <!-- html several of these are already suppressed; the stubs cover the -->
212
- <!-- rest and act as a safety net if publication settings change. Any -->
213
- <!-- exsl:document that does fire aborts the FILESYSTEM=0 WASM build. -->
214
- <xsl:template name="index-redirect-page"/>
215
- <xsl:template match="*" mode="manufacture-knowl"/>
216
- <xsl:template name="ol-marker-styles"/>
217
- <xsl:template name="doc-manifest"/>
218
- <xsl:template name="search-page-construction"/>
219
- <xsl:template name="scorm-manifest"/>
220
- <!-- standalone pages for videos and iframe pages for interactives -->
221
- <xsl:template match="*" mode="standalone-page"/>
222
- <xsl:template match="*" mode="create-iframe-page"/>
223
- <!-- runestone-manifest lives in pretext-runestone.xsl -->
224
- <xsl:template match="*" mode="runestone-manifest"/>
225
- <xsl:template match="*" mode="simple-file-wrap">
226
- <xsl:param name="content"/>
227
- <xsl:copy-of select="$content"/>
228
- </xsl:template>
229
-
230
- </xsl:stylesheet>
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-html.xsl for single-page in-memory HTML builds
7
+ (previews). The "file-wrap" template below is a verbatim copy of the
8
+ upstream template with the <exsl:document> element removed, so the complete
9
+ page is emitted on the main result tree. Intended to be applied together
10
+ with a publication file that sets <html><platform portable="yes"/></html>,
11
+ which forces chunk level 0 (one page) and CDN-hosted css/js, and suppresses
12
+ most auxiliary file output. Remaining file writers are stubbed at the end.
13
+ -->
14
+ <xsl:stylesheet
15
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
16
+ xmlns:xml="http://www.w3.org/XML/1998/namespace"
17
+ xmlns:svg="http://www.w3.org/2000/svg"
18
+ xmlns:xlink="http://www.w3.org/1999/xlink"
19
+ xmlns:pi="http://pretextbook.org/2020/pretext/internal"
20
+ xmlns:exsl="http://exslt.org/common"
21
+ xmlns:date="http://exslt.org/dates-and-times"
22
+ xmlns:str="http://exslt.org/strings"
23
+ xmlns:fn="http://www.w3.org/2005/xpath-functions"
24
+ xmlns:pf="https://prefigure.org"
25
+ exclude-result-prefixes="svg xlink pi fn pf"
26
+ extension-element-prefixes="exsl date str"
27
+ >
28
+
29
+ <xsl:import href="pretext-html.xsl"/>
30
+ <xsl:output method="html" encoding="UTF-8" doctype-system="about:legacy-compat"/>
31
+
32
+ <!-- Copied from pretext-html.xsl (mode="file-wrap"), exsl:document removed -->
33
+ <xsl:template match="*" mode="file-wrap">
34
+ <xsl:param name="content" />
35
+ <xsl:param name="title" select="''"/>
36
+ <xsl:param name="filename" select="''"/>
37
+ <xsl:param name="b-has-printout" select="false()"/>
38
+ <xsl:param name="b-include-bottom-nav" select="true()"/>
39
+
40
+ <xsl:variable name="the-filename">
41
+ <xsl:choose>
42
+ <xsl:when test="not($filename = '')">
43
+ <xsl:value-of select="$filename"/>
44
+ </xsl:when>
45
+ <xsl:otherwise>
46
+ <xsl:apply-templates select="." mode="containing-filename" />
47
+ </xsl:otherwise>
48
+ </xsl:choose>
49
+ </xsl:variable>
50
+
51
+
52
+ <xsl:call-template name="converter-blurb-html-no-date"/>
53
+ <html>
54
+ <xsl:call-template name="language-attributes"/>
55
+ <xsl:call-template name="html-theme-attributes"/>
56
+ <xsl:call-template name="pretext-advertisement-and-style"/>
57
+ <!-- Open Graph Protocol only in "meta" elements, within "head" -->
58
+ <head xmlns:og="http://ogp.me/ns#" xmlns:book="https://ogp.me/ns/book#">
59
+ <!-- optional head content that needs to come prior to other content -->
60
+ <xsl:apply-templates select="." mode="file-wrap-head-pre"/>
61
+ <title>
62
+ <xsl:choose>
63
+ <xsl:when test="$title != ''">
64
+ <xsl:value-of select="$title"/>
65
+ </xsl:when>
66
+ <xsl:otherwise>
67
+ <!-- Leading with initials is useful for small tabs -->
68
+ <xsl:if test="$docinfo/initialism">
69
+ <xsl:apply-templates select="$docinfo/initialism" />
70
+ <xsl:text> </xsl:text>
71
+ </xsl:if>
72
+ <xsl:apply-templates select="." mode="title-plain" />
73
+ </xsl:otherwise>
74
+ </xsl:choose>
75
+ </title>
76
+ <!-- canonical link for better SEO -->
77
+ <xsl:call-template name="canonical-link">
78
+ <xsl:with-param name="filename" select="$the-filename"/>
79
+ </xsl:call-template>
80
+ <!-- grab the contents every page gets -->
81
+ <xsl:copy-of select="$file-wrap-full-head-cache"/>
82
+ <!-- now do anything that is or could be page-specific and comes after cache -->
83
+ <xsl:apply-templates select="." mode="knowl" />
84
+ <!-- webwork's iframeResizer needs to come before sagecell template -->
85
+ <xsl:apply-templates select="." mode="sagecell" />
86
+ <!-- optional head content that might override other content-->
87
+ <xsl:apply-templates select="." mode="file-wrap-head-post"/>
88
+ </head>
89
+ <body>
90
+ <xsl:if test="$b-has-stack">
91
+ <xsl:attribute name="onload">
92
+ <xsl:text>docHasLoaded()</xsl:text>
93
+ </xsl:attribute>
94
+ </xsl:if>
95
+
96
+ <!-- potential document-id per-page -->
97
+ <xsl:call-template name="document-id"/>
98
+ <!-- React flag -->
99
+ <xsl:call-template name="react-in-use-flag"/>
100
+ <!-- the first class controls the default icon -->
101
+ <xsl:attribute name="class">
102
+ <xsl:choose>
103
+ <xsl:when test="$root/book">pretext book</xsl:when>
104
+ <xsl:when test="$root/article">pretext article</xsl:when>
105
+ </xsl:choose>
106
+ <xsl:apply-templates select="." mode="file-wrap-body-attr-extra"/>
107
+ <!-- ignore MathJax signals everywhere, then enable selectively -->
108
+ <xsl:text> ignore-math</xsl:text>
109
+ </xsl:attribute>
110
+ <!-- assistive "Skip to main content" link -->
111
+ <!-- this *must* be first for maximum utility -->
112
+ <xsl:call-template name="skip-to-content-link" />
113
+ <!-- HTML5 body/header will be a "banner" landmark automatically -->
114
+ <header id="ptx-masthead" class="ptx-masthead">
115
+ <div class="ptx-banner">
116
+ <xsl:call-template name="brand-logo" />
117
+ <div class="title-container">
118
+ <h1 class="heading">
119
+ <xsl:variable name="root-filename">
120
+ <xsl:apply-templates select="$document-root" mode="containing-filename" />
121
+ </xsl:variable>
122
+ <a href="{$root-filename}">
123
+ <xsl:variable name="b-has-subtitle" select="boolean($document-root/subtitle)"/>
124
+ <span class="title">
125
+ <!-- Do not use shorttitle in masthead, -->
126
+ <!-- which is much like cover of a book -->
127
+ <xsl:apply-templates select="$document-root" mode="title-simple" />
128
+ </span>
129
+ <xsl:if test="$b-has-subtitle and $b-html-banner-subtitle">
130
+ <xsl:text> </xsl:text>
131
+ <span class="subtitle">
132
+ <xsl:apply-templates select="$document-root" mode="subtitle" />
133
+ </span>
134
+ </xsl:if>
135
+ </a>
136
+ </h1>
137
+ <!-- Serial list of authors/editors -->
138
+ <xsl:if test="$b-html-banner-byline">
139
+ <p class="byline">
140
+ <xsl:apply-templates select="$bibinfo/author" mode="name-list"/>
141
+ <xsl:apply-templates select="$bibinfo/editor" mode="name-list"/>
142
+ </p>
143
+ </xsl:if>
144
+ </div> <!-- title-container -->
145
+ </div> <!-- banner -->
146
+ </header> <!-- masthead -->
147
+ <xsl:apply-templates select="." mode="primary-navigation"/>
148
+ <xsl:apply-templates select="." mode="latex-macros"/>
149
+ <div class="ptx-page">
150
+ <xsl:apply-templates select="." mode="sidebars" />
151
+ <!-- HTML5 main will be a "main" landmark automatically -->
152
+ <main class="ptx-main">
153
+ <xsl:if test="$b-watermark">
154
+ <xsl:attribute name="style">
155
+ <xsl:value-of select="$watermark-css"/>
156
+ </xsl:attribute>
157
+ </xsl:if>
158
+ <div id="ptx-content" class="ptx-content">
159
+ <xsl:if test="$b-has-printout">
160
+ <xsl:apply-templates select="." mode="print-preview-header"/>
161
+ </xsl:if>
162
+ <!-- Alternative to "copy-of": convert $content to a -->
163
+ <!-- node-set, and then hit with an identity template -->
164
+ <!-- to duplicate. Experiment indicates no change in -->
165
+ <!-- output. (2023-01-11) -->
166
+ <xsl:copy-of select="$content" />
167
+ </div>
168
+ <xsl:if test="$b-include-bottom-nav">
169
+ <div id="ptx-content-footer" class="ptx-content-footer">
170
+ <xsl:apply-templates select="." mode="previous-button"/>
171
+ <xsl:variable name="top-localization">
172
+ <xsl:apply-templates select="." mode="type-name">
173
+ <xsl:with-param name="string-id" select="'top'"/>
174
+ </xsl:apply-templates>
175
+ </xsl:variable>
176
+ <a class="top-button button" href="#" title="{$top-localization}">
177
+ <xsl:call-template name="insert-symbol">
178
+ <xsl:with-param name="name" select="'expand_less'"/>
179
+ </xsl:call-template>
180
+ <span class="name">
181
+ <xsl:value-of select="$top-localization"/>
182
+ </span>
183
+ </a>
184
+ <xsl:apply-templates select="." mode="next-button"/>
185
+ </div>
186
+ </xsl:if>
187
+ </main>
188
+ </div>
189
+ <!-- formerly "extra" -->
190
+ <div id="ptx-page-footer" class="ptx-page-footer">
191
+ <xsl:apply-templates select="." mode="feedback-button"/>
192
+ <xsl:call-template name="pretext-link" />
193
+ <xsl:call-template name="runestone-link"/>
194
+ <xsl:call-template name="mathjax-link" />
195
+ </div>
196
+ <xsl:copy-of select="$file-wrap-full-endbody-cache"/>
197
+ <!-- For portable builds we stash the lunr search here -->
198
+ <xsl:if test="$b-portable-html and $has-native-search">
199
+ <xsl:call-template name="embedded-search-construction"/>
200
+ </xsl:if>
201
+ <!-- optional body content that needs to be inserted after all content -->
202
+ <!-- e.g. script tags to run immediately -->
203
+ <xsl:apply-templates select="." mode="file-wrap-body-post"/>
204
+ </body>
205
+ </html>
206
+
207
+ </xsl:template>
208
+
209
+ <!-- Stub out the remaining file writers (every other template reachable -->
210
+ <!-- from pretext-html.xsl that contains exsl:document). Under portable- -->
211
+ <!-- html several of these are already suppressed; the stubs cover the -->
212
+ <!-- rest and act as a safety net if publication settings change. Any -->
213
+ <!-- exsl:document that does fire aborts the FILESYSTEM=0 WASM build. -->
214
+ <xsl:template name="index-redirect-page"/>
215
+ <xsl:template match="*" mode="manufacture-knowl"/>
216
+ <xsl:template name="ol-marker-styles"/>
217
+ <xsl:template name="doc-manifest"/>
218
+ <xsl:template name="search-page-construction"/>
219
+ <xsl:template name="scorm-manifest"/>
220
+ <!-- standalone pages for videos and iframe pages for interactives -->
221
+ <xsl:template match="*" mode="standalone-page"/>
222
+ <xsl:template match="*" mode="create-iframe-page"/>
223
+ <!-- runestone-manifest lives in pretext-runestone.xsl -->
224
+ <xsl:template match="*" mode="runestone-manifest"/>
225
+ <xsl:template match="*" mode="simple-file-wrap">
226
+ <xsl:param name="content"/>
227
+ <xsl:copy-of select="$content"/>
228
+ </xsl:template>
229
+
230
+ </xsl:stylesheet>
@@ -1,7 +1,7 @@
1
- {
2
- "source": {
3
- "repository": "PreTeXtBook/pretext",
4
- "ref": "master"
5
- },
6
- "refreshed": "2026-07-08T00:48:30.933Z"
7
- }
1
+ {
2
+ "source": {
3
+ "repository": "PreTeXtBook/pretext",
4
+ "ref": "master"
5
+ },
6
+ "refreshed": "2026-07-08T00:48:30.933Z"
7
+ }