@pretextbook/pretext-html 0.1.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 (110) hide show
  1. package/README.md +160 -0
  2. package/assets/preview-html.xsl +230 -0
  3. package/assets/upstream.json +7 -0
  4. package/assets/xsl/README.md +31 -0
  5. package/assets/xsl/entities.ent +154 -0
  6. package/assets/xsl/extract-asymptote.xsl +68 -0
  7. package/assets/xsl/extract-biblio-csl.xsl +327 -0
  8. package/assets/xsl/extract-datafile.xsl +71 -0
  9. package/assets/xsl/extract-dynamic.xsl +139 -0
  10. package/assets/xsl/extract-identity.xsl +136 -0
  11. package/assets/xsl/extract-interactive.xsl +81 -0
  12. package/assets/xsl/extract-latex-image.xsl +118 -0
  13. package/assets/xsl/extract-mermaid.xsl +58 -0
  14. package/assets/xsl/extract-mom.xsl +63 -0
  15. package/assets/xsl/extract-pg.xsl +2897 -0
  16. package/assets/xsl/extract-prefigure.xsl +157 -0
  17. package/assets/xsl/extract-qrcode.xsl +100 -0
  18. package/assets/xsl/extract-runestone-page-template.xsl +139 -0
  19. package/assets/xsl/extract-sageplot.xsl +166 -0
  20. package/assets/xsl/extract-stack.xsl +56 -0
  21. package/assets/xsl/extract-trace.xsl +134 -0
  22. package/assets/xsl/extract-youtube.xsl +63 -0
  23. package/assets/xsl/html-symbols.xsl +3344 -0
  24. package/assets/xsl/latex/pretext-latex-AIM.xsl +56 -0
  25. package/assets/xsl/latex/pretext-latex-CLP.xsl +148 -0
  26. package/assets/xsl/latex/pretext-latex-chaos.xsl +317 -0
  27. package/assets/xsl/latex/pretext-latex-dyslexic-font.xsl +76 -0
  28. package/assets/xsl/latex/pretext-latex-guide.xsl +104 -0
  29. package/assets/xsl/latex/pretext-latex-texstyle.xsl +862 -0
  30. package/assets/xsl/localizations/README.md +56 -0
  31. package/assets/xsl/localizations/af-ZA.xml +276 -0
  32. package/assets/xsl/localizations/bg-BG.xml +276 -0
  33. package/assets/xsl/localizations/ca-ES.xml +285 -0
  34. package/assets/xsl/localizations/cs-CZ.xml +280 -0
  35. package/assets/xsl/localizations/de-DE.xml +281 -0
  36. package/assets/xsl/localizations/en-US.xml +427 -0
  37. package/assets/xsl/localizations/es-ES.xml +287 -0
  38. package/assets/xsl/localizations/fi-FI.xml +275 -0
  39. package/assets/xsl/localizations/fr-CA.xml +276 -0
  40. package/assets/xsl/localizations/fr-FR.xml +280 -0
  41. package/assets/xsl/localizations/hu-HU.xml +280 -0
  42. package/assets/xsl/localizations/it-IT.xml +276 -0
  43. package/assets/xsl/localizations/ku-CKB.xml +275 -0
  44. package/assets/xsl/localizations/localizations.xml +48 -0
  45. package/assets/xsl/localizations/nl-NL.xml +275 -0
  46. package/assets/xsl/localizations/pt-BR.xml +288 -0
  47. package/assets/xsl/localizations/pt-PT.xml +292 -0
  48. package/assets/xsl/localizations/zh-HANS.xml +269 -0
  49. package/assets/xsl/pretext-assembly.xsl +4795 -0
  50. package/assets/xsl/pretext-basic-html.xsl +86 -0
  51. package/assets/xsl/pretext-beamer.xsl +662 -0
  52. package/assets/xsl/pretext-braille-preprint.xsl +2249 -0
  53. package/assets/xsl/pretext-common.xsl +12018 -0
  54. package/assets/xsl/pretext-dynamic.xsl +65 -0
  55. package/assets/xsl/pretext-epub.xsl +1483 -0
  56. package/assets/xsl/pretext-fo.xsl +4593 -0
  57. package/assets/xsl/pretext-html.xsl +14791 -0
  58. package/assets/xsl/pretext-json-manifest.xsl +150 -0
  59. package/assets/xsl/pretext-jupyter.xsl +868 -0
  60. package/assets/xsl/pretext-latex-classic.xsl +952 -0
  61. package/assets/xsl/pretext-latex-common.xsl +11563 -0
  62. package/assets/xsl/pretext-latex.xsl +47 -0
  63. package/assets/xsl/pretext-litprog.xsl +105 -0
  64. package/assets/xsl/pretext-merge.xsl +41 -0
  65. package/assets/xsl/pretext-numbers.xsl +875 -0
  66. package/assets/xsl/pretext-revealjs.xsl +522 -0
  67. package/assets/xsl/pretext-runestone-fitb.xsl +1233 -0
  68. package/assets/xsl/pretext-runestone-static.xsl +1438 -0
  69. package/assets/xsl/pretext-runestone.xsl +3083 -0
  70. package/assets/xsl/pretext-sage-doctest.xsl +289 -0
  71. package/assets/xsl/pretext-smc.xsl +492 -0
  72. package/assets/xsl/pretext-solution-manual-latex.xsl +323 -0
  73. package/assets/xsl/pretext-text-utilities.xsl +1217 -0
  74. package/assets/xsl/pretext-text.xsl +392 -0
  75. package/assets/xsl/pretext-units.xsl +195 -0
  76. package/assets/xsl/pretext-view-source.xsl +157 -0
  77. package/assets/xsl/pretext-ww-problem-sets.xsl +391 -0
  78. package/assets/xsl/publisher-variables.xsl +4756 -0
  79. package/assets/xsl/support/README.md +22 -0
  80. package/assets/xsl/support/extract-math.xsl +256 -0
  81. package/assets/xsl/support/package-math.xsl +141 -0
  82. package/assets/xsl/support/play-button/README.md +46 -0
  83. package/assets/xsl/support/play-button/play-button.png +0 -0
  84. package/assets/xsl/support/play-button/play-button.svg +3 -0
  85. package/assets/xsl/support/pretext-pg-macros.xsl +110 -0
  86. package/assets/xsl/support/webpack_static_imports.xml +14 -0
  87. package/assets/xsl/tests/README.md +24 -0
  88. package/assets/xsl/tests/null.xml +4 -0
  89. package/assets/xsl/tests/pretext-text-utilities-test.xsl +334 -0
  90. package/assets/xsl/utilities/README.md +31 -0
  91. package/assets/xsl/utilities/author-report.xsl +107 -0
  92. package/assets/xsl/utilities/deprecate-autoname.sed +18 -0
  93. package/assets/xsl/utilities/deprecate-index.sed +33 -0
  94. package/assets/xsl/utilities/fix-deprecations.xsl +663 -0
  95. package/assets/xsl/utilities/pretext-enhanced-source.xsl +112 -0
  96. package/assets/xsl/utilities/report-publisher-variables.xsl +162 -0
  97. package/assets/xsl/xml-to-json.xsl +326 -0
  98. package/assets/xsl/xml-to-string.xsl +328 -0
  99. package/cli.mjs +29 -0
  100. package/dist/cli-C6tfAVvi.js +553 -0
  101. package/dist/cli.d.ts +10 -0
  102. package/dist/cli.js +7 -0
  103. package/dist/index.d.ts +6 -0
  104. package/dist/index.js +10 -0
  105. package/dist/mounts.d.ts +23 -0
  106. package/dist/publication.d.ts +16 -0
  107. package/dist/renderer.d.ts +84 -0
  108. package/dist/sourcemap.d.ts +41 -0
  109. package/dist/xinclude.d.ts +45 -0
  110. package/package.json +52 -0
@@ -0,0 +1,1483 @@
1
+ <?xml version='1.0'?> <!-- As XML file -->
2
+ <!-- http://stackoverflow.com/questions/10173139/empty-blank-namespace-declarations-being-generated-within-result-document -->
3
+
4
+ <!-- http://pimpmyxslt.com/articles/entity-tricks-part2/ -->
5
+ <!DOCTYPE xsl:stylesheet [
6
+ <!ENTITY % entities SYSTEM "entities.ent">
7
+ %entities;
8
+ ]>
9
+
10
+ <!-- Building XHTML for the EPUB spec, which requires the -->
11
+ <!-- XHTML namespace on elements. But since we import the -->
12
+ <!-- base HTML conversion, no amount of messing around can -->
13
+ <!-- make it happen correctly. So we write literal elements -->
14
+ <!-- as XML and after-the-fact we stich-up the necessary -->
15
+ <!-- namespace on the output files with regular expressions -->
16
+ <!-- in Python. So...we have no namespace at all. -->
17
+ <xsl:stylesheet xmlns:pi="http://pretextbook.org/2020/pretext/internal"
18
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
19
+ xmlns:svg="http://www.w3.org/2000/svg"
20
+ xmlns:math="http://www.w3.org/1998/Math/MathML"
21
+ xmlns:epub="http://www.idpf.org/2007/ops"
22
+ xmlns:exsl="http://exslt.org/common"
23
+ xmlns:date="http://exslt.org/dates-and-times"
24
+ xmlns:pf="https://prefigure.org"
25
+ exclude-result-prefixes="pi svg math epub pf"
26
+ extension-element-prefixes="exsl date">
27
+
28
+ <!-- Trade on HTML markup, numbering, chunking, etc. -->
29
+ <!-- Override as pecularities of EPUB conversion arise -->
30
+ <xsl:import href="./pretext-common.xsl" />
31
+ <xsl:import href="./pretext-assembly.xsl" />
32
+ <xsl:import href="./pretext-html.xsl" />
33
+
34
+ <!-- TODO: free chunking level -->
35
+ <!-- TODO: liberate GeoGebra, videos -->
36
+ <!-- TODO: style Sage display-only code in a similar padded box -->
37
+
38
+ <!-- Output as well-formed xhtml -->
39
+ <!-- This may have no practical effect -->
40
+ <xsl:output method="xml" encoding="UTF-8" doctype-system="about:legacy-compat" indent="no" />
41
+
42
+ <!-- This variable controls representations of interactive exercises -->
43
+ <!-- built in pretext-assembly.xsl. The imported pretext-html.xsl -->
44
+ <!-- stylesheet sets it to "dynamic". But for this stylesheet we want -->
45
+ <!-- to utilize the "standard" PreTeXt exercise versions built with -->
46
+ <!-- "static". See both pretext-assembly.xsl and pretext-html.xsl -->
47
+ <!-- for more discussion. -->
48
+ <xsl:variable name="exercise-style" select="'static'"/>
49
+
50
+ <!-- Content will go into EPUB directory -->
51
+ <!-- package.opf is main metadata file -->
52
+ <!-- (META-INF/container.xml will point to it) -->
53
+ <!-- Unlikely to need to change this, but we could -->
54
+ <xsl:variable name="content-dir">
55
+ <xsl:text>EPUB</xsl:text>
56
+ </xsl:variable>
57
+ <xsl:variable name="css-dir">
58
+ <xsl:text>css</xsl:text>
59
+ </xsl:variable>
60
+ <xsl:variable name="xhtml-dir">
61
+ <xsl:text>xhtml</xsl:text>
62
+ </xsl:variable>
63
+ <xsl:variable name="package-file">
64
+ <xsl:text>package.opf</xsl:text>
65
+ </xsl:variable>
66
+ <xsl:variable name="endnote-file">
67
+ <xsl:text>endnotes.xhtml</xsl:text>
68
+ </xsl:variable>
69
+
70
+ <!-- The value of the unique-identifier attribute of -->
71
+ <!-- the package element of the container file must -->
72
+ <!-- match the value of the id attribute of the -->
73
+ <!-- dc:identifier element in the metadata section -->
74
+ <!-- So we fix it here for uniformity -->
75
+ <!-- TODO: determine a better way to provide this -->
76
+ <xsl:variable name="uid-string">
77
+ <xsl:text>pub-id</xsl:text>
78
+ </xsl:variable>
79
+ <xsl:variable name="mock-UUID">mock-123456789-0-987654321</xsl:variable>
80
+
81
+ <!-- We hard-code the chunking level. Level 2 is the -->
82
+ <!-- default for books, which we presume throughout. -->
83
+ <!-- Specialized divisions, to the spine, assume this. -->
84
+ <!-- NB: this override is only defined for a "book", -->
85
+ <!-- so when there is support for "article" it will -->
86
+ <!-- need new definitions. -->
87
+ <xsl:variable name="chunk-level">
88
+ <xsl:choose>
89
+ <xsl:when test="$root/book/part">3</xsl:when>
90
+ <xsl:when test="$root/book">2</xsl:when>
91
+ <!-- break "article" into "section" -->
92
+ <xsl:when test="$root/article/section">1</xsl:when>
93
+ <!-- otherwise, no real divisions -->
94
+ <xsl:when test="$root/article">0</xsl:when>
95
+ </xsl:choose>
96
+ </xsl:variable>
97
+
98
+ <!-- We disable the ToC level to avoid any conflicts with chunk level -->
99
+ <xsl:variable name="toc-level" select="number(0)" />
100
+
101
+ <!-- XHTML files as output -->
102
+ <xsl:variable name="file-extension" select="'.xhtml'" />
103
+
104
+ <xsl:param name="tmpdir"/>
105
+ <xsl:param name="mathfile"/>
106
+ <xsl:variable name="math-repr" select="document($mathfile)/pi:math-representations"/>
107
+ <!-- For MathML math, the "speechfile" is not used and an -->
108
+ <!-- empty string is passed in. This does not seem to cause -->
109
+ <!-- an error here, or in any subsequent uses in the empty case -->
110
+ <xsl:param name="speechfile"/>
111
+ <xsl:variable name="speech-repr" select="document($speechfile)/pi:math-representations"/>
112
+
113
+ <!-- One of 'svg", 'mml', 'kindle', or 'speech', always -->
114
+ <!-- Also 'kindle' dictates MathML output, but is primarily -->
115
+ <!-- responsible for integrating PNG images in place of SVG -->
116
+ <xsl:param name="math.format"/>
117
+
118
+ <!-- The mathjax_latex() routine in pretext.py is parameterized -->
119
+ <!-- by the format of the math being generated: -->
120
+ <!-- 'svg', 'mml', 'nemeth', 'speech', 'kindle' -->
121
+ <!-- In turn, this dictates if clause-ending punctuation is absorbed -->
122
+ <!-- into the math or not: -->
123
+ <!-- 'svg', 'mml', 'kindle' -> absorbed into display math only -->
124
+ <!-- 'nemeth', 'speech' -> never absorbed -->
125
+ <!-- For this stylesheet, which consumes this math, we need to set -->
126
+ <!-- the matching behavior for the adjacent text nodes via an override -->
127
+ <!-- of the global math.punctuation.include variable. -->
128
+ <xsl:variable name="math.punctuation.include">
129
+ <xsl:choose>
130
+ <xsl:when test="($math.format = 'svg') or ($math.format = 'mml') or ($math.format = 'kindle')">
131
+ <xsl:text>display</xsl:text>
132
+ </xsl:when>
133
+ <xsl:when test="($math.format = 'speech')">
134
+ <xsl:text>none</xsl:text>
135
+ </xsl:when>
136
+ </xsl:choose>
137
+ </xsl:variable>
138
+
139
+ <!-- For WeBWorK in EPUB, we force WeBWorK to be static -->
140
+ <xsl:variable name="b-webwork-inline-static" select="true()" />
141
+ <xsl:variable name="b-webwork-divisional-static" select="true()" />
142
+ <xsl:variable name="b-webwork-reading-static" select="true()" />
143
+ <xsl:variable name="b-webwork-worksheet-static" select="true()" />
144
+
145
+ <!-- Kindle needs various tweaks, way beyond just math as MathML -->
146
+ <!-- and PNG images. So a misnomer to call it a "math format", -->
147
+ <!-- but a a boolean sure helps -->
148
+ <xsl:variable name="b-kindle" select="$math.format = 'kindle'"/>
149
+
150
+ <!-- If there are footnotes, we'll build and package a "endnotes.xhtml" file -->
151
+ <xsl:variable name="b-has-endnotes" select="boolean($document-root//fn|$document-root//aside|$document-root//biographical|$document-root//historical)"/>
152
+
153
+ <xsl:variable name="endnotes-have-math">
154
+ <xsl:if test="$b-has-endnotes">
155
+ <xsl:choose>
156
+ <xsl:when test="$document-root//fn//m">
157
+ <xsl:text>true</xsl:text>
158
+ </xsl:when>
159
+ <xsl:when test="$document-root//aside//m or
160
+ $document-root//aside//md[mrow]">
161
+ <xsl:text>true</xsl:text>
162
+ </xsl:when>
163
+ <xsl:when test="$document-root//biographical//m or
164
+ $document-root//biographical//md[mrow]">
165
+ <xsl:text>true</xsl:text>
166
+ </xsl:when>
167
+ <xsl:when test="$document-root//historical//m or
168
+ $document-root//historical//md[mrow]">
169
+ <xsl:text>true</xsl:text>
170
+ </xsl:when>
171
+ </xsl:choose>
172
+ </xsl:if>
173
+ </xsl:variable>
174
+
175
+ <xsl:variable name="b-endnotes-have-math" select="$endnotes-have-math = 'true'"/>
176
+
177
+ <!-- Disable clipboardable -->
178
+ <xsl:template name="insert-clipboardable-class"/>
179
+
180
+ <!-- Printables -->
181
+ <!-- Worksheets and handouts get a near-duplicate HTML file designed for printing. -->
182
+ <!-- That is initiated very close to the entry template via a named template -->
183
+ <!-- "make-printout-printables". We explicitly *do not* include any call to this -->
184
+ <!-- template in the entry template here, so these pages are not built (good). -->
185
+ <!-- But we do get little buttons to elect a printable version. We have to kill -->
186
+ <!-- those buttons, since EPUB wants to go looking for the printable-version files. -->
187
+ <xsl:template match="worksheet|handout" mode="standalone-printout-links"/>
188
+
189
+
190
+ <!-- ############## -->
191
+ <!-- Entry Template -->
192
+ <!-- ############## -->
193
+
194
+ <!-- Deprecation warnings are universal analysis of source and parameters -->
195
+ <!-- There is always a "document root" directly under the root element, -->
196
+ <!-- and we process it with the chunking template called below -->
197
+ <!-- Note that "docinfo" is at the same level and not structural, so killed -->
198
+ <xsl:template match="/">
199
+ <!-- no hope for an "article" so fail immediately, with warning -->
200
+ <xsl:if test="not($b-is-book or $b-is-article)">
201
+ <xsl:call-template name="banner-warning">
202
+ <xsl:with-param name="warning">PTX:FATAL: EPUB creation is only implemented for a "book" or an "article",&#xa;not a "<xsl:value-of select="local-name($document-root)"/>", and we cannot recover</xsl:with-param>
203
+ </xsl:call-template>
204
+ <xsl:message terminate="yes">Quitting...</xsl:message>
205
+ </xsl:if>
206
+ <!-- analyze authored source -->
207
+ <xsl:apply-templates select="$original" mode="generic-warnings"/>
208
+ <xsl:apply-templates select="$original" mode="element-deprecation-warnings"/>
209
+ <xsl:apply-templates select="$original" mode="parameter-deprecation-warnings"/>
210
+ <!-- Following should use $root or $document-root as defined -->
211
+ <!-- by the "assembly" template. Checked 2020-07-16. -->
212
+ <xsl:call-template name="setup" />
213
+ <xsl:apply-templates select="$root"/>
214
+ <xsl:call-template name="package-document" />
215
+ <xsl:call-template name="packaging-info"/>
216
+ </xsl:template>
217
+
218
+ <!-- First, we use the frontmatter element to trigger various necessary files -->
219
+ <!-- We process structural nodes via chunking routine in xsl/mathbook-common.xsl -->
220
+ <!-- This in turn calls specific modal templates defined elsewhere in this file -->
221
+ <xsl:template match="/pretext">
222
+ <xsl:apply-templates select="$document-root//frontmatter" mode="epub" />
223
+ <xsl:call-template name="endnotes"/>
224
+ <xsl:apply-templates mode="chunking" />
225
+ </xsl:template>
226
+
227
+ <!-- ################ -->
228
+ <!-- Structural Nodes -->
229
+ <!-- ################ -->
230
+
231
+ <!-- Read the code and documentation for "chunking" in xsl/pretext-common.xsl -->
232
+
233
+ <!-- Normally a "conclusion" would be on a "summary" page, or a -->
234
+ <!-- component of the page for its containing division. In the -->
235
+ <!-- EPUB conversion with "chapter" having "section" it gets an -->
236
+ <!-- HTML page of its own as part of the "summary" hack. Ditto -->
237
+ <!-- for "outcomes" which might appear in a different order. -->
238
+ <xsl:template match="&STRUCTURAL;|chapter/conclusion|chapter/outcomes[preceding-sibling::section]" mode="file-wrap">
239
+ <xsl:param name="content" />
240
+ <xsl:variable name="file">
241
+ <xsl:value-of select="$content-dir" />
242
+ <xsl:text>/</xsl:text>
243
+ <xsl:value-of select="$xhtml-dir" />
244
+ <xsl:text>/</xsl:text>
245
+ <xsl:apply-templates select="." mode="containing-filename" />
246
+ </xsl:variable>
247
+ <!-- do not use "doctype-system" here -->
248
+ <!-- do not create faux <!DOCTYPE html> here -->
249
+ <!-- NB: If we add xmlns="http://www.w3.org/1999/xhtml" to <html> here, -->
250
+ <!-- then we get plenty of top-level-ish xmlns="" which do not validate -->
251
+ <!-- Any XML declaration seems to get scrubbed by the MathJax processing -->
252
+ <!-- (converted to a comment), so we explicitly suppress it here, and in -->
253
+ <!-- other exsl:document uses. -->
254
+ <exsl:document href="{$file}" method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no">
255
+ <html>
256
+ <xsl:call-template name="html-theme-attributes"/>
257
+ <head>
258
+ <xsl:text>&#xa;</xsl:text> <!-- a little formatting help -->
259
+ <xsl:call-template name="converter-blurb-html" />
260
+ <xsl:call-template name="epub-kindle-css"/>
261
+ <title>
262
+ <xsl:apply-templates select="." mode="type-name-number" />
263
+ </title>
264
+ </head>
265
+ <!-- use class to repurpose HTML CSS work -->
266
+ <body class="ptx-content epub">
267
+ <xsl:copy-of select="$content" />
268
+ <!-- Copy MathJax's font information to the bottom -->
269
+ <xsl:copy-of select="document($mathfile)/pi:math-representations/svg:svg[@id='font-data']"/>
270
+ </body>
271
+ </html>
272
+ </exsl:document>
273
+ </xsl:template>
274
+
275
+ <!-- The book element gets mined in various ways, -->
276
+ <!-- but the "usual" HTML treatment can/should be thrown out -->
277
+ <!-- At fixed level 2, this is a summary page from an -->
278
+ <!-- intermediate node, so we kill it -->
279
+ <xsl:template match="book" mode="intermediate" />
280
+
281
+ <!-- This seems a bit dangerous, but this content is fairly small -->
282
+ <!-- and they are going into their own files. So it seems the -->
283
+ <!-- right thing to do, while making minimal changes elsewhere. -->
284
+ <xsl:template match="chapter/conclusion|chapter/outcomes[preceding-sibling::section]" mode="containing-filename">
285
+ <xsl:apply-templates select="." mode="visible-id"/>
286
+ <xsl:text>.xhtml</xsl:text>
287
+ </xsl:template>
288
+
289
+ <!-- If a "book" has some "chapter" subdivided by "section" then -->
290
+ <!-- at a chunking level of 2, the "chapter" is an intermediate -->
291
+ <!-- node and will produce a "summary" page. We implement that -->
292
+ <!-- to produce content that is a faux chapter that is just the -->
293
+ <!-- heading and the lead-in material. Anything after the last -->
294
+ <!-- division (conclusion, outcomes) will create s of their own, -->
295
+ <!-- which will appear as a continuation/ending of the chapter. -->
296
+ <!-- NB: based on version in pretext-html.xsl -->
297
+ <xsl:template match="frontmatter|chapter|appendix" mode="intermediate">
298
+ <xsl:apply-templates select="." mode="file-wrap">
299
+ <xsl:with-param name="content">
300
+ <!-- location info for debugging efforts -->
301
+ <xsl:apply-templates select="." mode="debug-location" />
302
+ <!-- Heading, div for this structural subdivision -->
303
+ <section class="{local-name(.)}">
304
+ <xsl:apply-templates select="." mode="html-id-attribute"/>
305
+ <xsl:apply-templates select="." mode="section-heading" />
306
+ <xsl:apply-templates select="author|objectives|introduction|titlepage|abstract" />
307
+ <!-- deleted "nav" and summary links here -->
308
+ </section>
309
+ <xsl:if test="conclusion">
310
+ <xsl:apply-templates select="conclusion" mode="file-wrap">
311
+ <xsl:with-param name="content">
312
+ <xsl:apply-templates select="conclusion"/>
313
+ </xsl:with-param>
314
+ </xsl:apply-templates>
315
+ </xsl:if>
316
+ <xsl:if test="outcomes">
317
+ <xsl:apply-templates select="outcomes" mode="file-wrap">
318
+ <xsl:with-param name="content">
319
+ <xsl:apply-templates select="outcomes"/>
320
+ </xsl:with-param>
321
+ </xsl:apply-templates>
322
+ </xsl:if>
323
+ </xsl:with-param>
324
+ </xsl:apply-templates>
325
+ </xsl:template>
326
+
327
+ <!-- At level 2, the backmatter summary is useless, since it is -->
328
+ <!-- all links, so just kill the intermediate chunking template. -->
329
+ <!-- Also do not include entries in the manifest or spine. -->
330
+ <xsl:template match="backmatter" mode="intermediate" />
331
+
332
+
333
+
334
+ <!-- ##################### -->
335
+ <!-- Setup, Infrastructure -->
336
+ <!-- ##################### -->
337
+
338
+ <!-- The two fixed files of any EPUB -->
339
+ <!-- (1) mimetype at top-level with prescribed content -->
340
+ <!-- (2) META-INF/container.xml with one variable attribute -->
341
+ <xsl:template name="setup">
342
+ <!-- No carriage return at the end (20 byte file) -->
343
+ <exsl:document href="mimetype" method="text">
344
+ <xsl:text>application/epub+zip</xsl:text>
345
+ </exsl:document>
346
+ <!-- Do not use "doctype-system" here -->
347
+ <!-- Automatically writes XML header at version 1.0, no encoding -->
348
+ <!-- Points to OPF metadata file (in two variables) -->
349
+ <exsl:document href="META-INF/container.xml" method="xml" omit-xml-declaration="yes" indent="no">
350
+ <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
351
+ <rootfiles>
352
+ <rootfile full-path="{$content-dir}/{$package-file}" media-type="application/oebps-package+xml" />
353
+ </rootfiles>
354
+ </container>
355
+ </exsl:document>
356
+ </xsl:template>
357
+
358
+ <!-- ############################## -->
359
+ <!-- EPUB 3.0 Package Document file -->
360
+ <!-- ############################## -->
361
+
362
+ <!-- The primary index into various files -->
363
+ <xsl:template name="package-document">
364
+ <!-- Must be XML, UTF-8/16 -->
365
+ <!-- Required on package: version, id -->
366
+ <!-- Trying with no encoding, Gitden rejects? -->
367
+ <exsl:document href="{$content-dir}/{$package-file}" method="xml" omit-xml-declaration="yes" indent="no">
368
+ <package xmlns="http://www.idpf.org/2007/opf"
369
+ unique-identifier="{$uid-string}" version="3.0">
370
+ <xsl:call-template name="package-metadata" />
371
+ <xsl:call-template name="package-manifest" />
372
+ <xsl:call-template name="package-spine" />
373
+ </package>
374
+ </exsl:document>
375
+ </xsl:template>
376
+
377
+ <!-- Honest to goodness metadata, no attributes -->
378
+ <!-- Required first child of package element -->
379
+ <!-- Required: dc:identifier, dc:title, dc:language -->
380
+ <!-- TODO: add publisher etc from Dublin Core -->
381
+ <!-- TODO: see rights info handling in FCLA EPUB sample -->
382
+ <xsl:template name="package-metadata">
383
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.idpf.org/2007/opf">
384
+ <!-- Optional in EPUB 3.0.1 spec -->
385
+ <xsl:for-each select="$bibinfo/author|$bibinfo/editor">
386
+ <xsl:element name="dc:creator">
387
+ <xsl:apply-templates select="personname"/>
388
+ </xsl:element>
389
+ </xsl:for-each>
390
+ <!-- Required in EPUB 3.0.1 spec -->
391
+ <!-- TODO: title-types can refine this -->
392
+ <xsl:element name="dc:title">
393
+ <xsl:apply-templates select="$document-root" mode="title-full" />
394
+ </xsl:element>
395
+ <!-- Required in EPUB 3.0.1 spec -->
396
+ <!-- Repeatable and more complicated, see spec -->
397
+ <!-- id must match attribute on package element -->
398
+ <xsl:element name="dc:identifier">
399
+ <xsl:attribute name="id">
400
+ <xsl:value-of select="$uid-string" />
401
+ </xsl:attribute>
402
+ <xsl:value-of select="$mock-UUID" />
403
+ </xsl:element>
404
+ <!-- Required in EPUB 3.0.1 spec -->
405
+ <!-- Also needed for Kindle conversion -->
406
+ <!-- Codes according to RFC5646, -->
407
+ <!-- our double form, eg en-US, seems OK -->
408
+ <xsl:element name="dc:language">
409
+ <xsl:value-of select="$document-language" />
410
+ </xsl:element>
411
+ <!-- Required in EPUB 3.0.1 spec -->
412
+ <!-- Drop time zone, replace with Z -->
413
+ <!-- This is then a mild fiction -->
414
+ <xsl:element name="meta">
415
+ <xsl:attribute name="property">
416
+ <xsl:text>dcterms:modified</xsl:text>
417
+ </xsl:attribute>
418
+ <xsl:value-of select="substring(date:date-time(),1,19)" />
419
+ <xsl:text>Z</xsl:text>
420
+ </xsl:element>
421
+ <meta name="cover" content="{$xhtml-dir}/{$epub-cover-dest}" />
422
+ </metadata>
423
+ </xsl:template>
424
+
425
+ <!-- manifest element required as second element of package -->
426
+ <!-- a list of empty item elements (order unimportant), -->
427
+ <!-- Each item has -->
428
+ <!-- Required: id, for spine ordering -->
429
+ <!-- Required: href, absolute or relative -->
430
+ <!-- Required: media-type, critical (see PNG/JPG for cover) -->
431
+ <!-- Exactly one item has the "nav" property -->
432
+ <xsl:template name="package-manifest">
433
+ <!-- cruise all objects within source via modal template -->
434
+ <!-- relevant objects report themselves and then recurse -->
435
+ <!-- create as a legitimate node-set for post-filtering -->
436
+ <xsl:variable name="discovery">
437
+ <xsl:apply-templates select="$document-root" mode="manifest"/>
438
+ </xsl:variable>
439
+ <xsl:variable name="discovery-manifest" select="exsl:node-set($discovery)"/>
440
+ <!-- start "manifest" with one-off items -->
441
+ <manifest xmlns="http://www.idpf.org/2007/opf">
442
+ <xsl:choose>
443
+ <xsl:when test="$b-kindle">
444
+ <item id="css-kindle" href="{$css-dir}/kindle.css" media-type="text/css"/>
445
+ </xsl:when>
446
+ <xsl:otherwise>
447
+ <item id="css-epub" href="{$css-dir}/epub.css" media-type="text/css"/>
448
+ </xsl:otherwise>
449
+ </xsl:choose>
450
+ <item id="cover-page" href="{$xhtml-dir}/cover-page.xhtml" media-type="application/xhtml+xml"/>
451
+ <item id="table-contents"
452
+ href="{$xhtml-dir}/table-contents.xhtml"
453
+ media-type="application/xhtml+xml">
454
+ <!-- TODO: If the TOC expands to include more than -->
455
+ <!-- chapter and appendix, this will need revision. -->
456
+ <xsl:attribute name="properties">
457
+ <xsl:choose>
458
+ <xsl:when test="($b-is-book and ($document-root//chapter/title/m or $document-root//appendix/title/m))">
459
+ <xsl:choose>
460
+ <xsl:when test="$math.format = 'mml' or
461
+ $math.format = 'kindle'">
462
+ <xsl:text>nav mathml</xsl:text>
463
+ </xsl:when>
464
+ <xsl:when test="$math.format = 'svg'">
465
+ <xsl:text>nav svg</xsl:text>
466
+ </xsl:when>
467
+ </xsl:choose>
468
+ </xsl:when>
469
+ <xsl:otherwise>
470
+ <xsl:text>nav</xsl:text>
471
+ </xsl:otherwise>
472
+ </xsl:choose>
473
+ </xsl:attribute>
474
+ </item>
475
+ <item id="cover-image" href="{$xhtml-dir}/{$epub-cover-dest}" properties="cover-image">
476
+ <xsl:attribute name="media-type">
477
+ <xsl:variable name="extension">
478
+ <xsl:call-template name="file-extension">
479
+ <xsl:with-param name="filename" select="$epub-cover-dest" />
480
+ </xsl:call-template>
481
+ </xsl:variable>
482
+ <xsl:choose>
483
+ <xsl:when test="$extension='png'">
484
+ <xsl:text>image/png</xsl:text>
485
+ </xsl:when>
486
+ <xsl:when test="$extension='jpeg' or $extension='jpg'">
487
+ <xsl:text>image/jpeg</xsl:text>
488
+ </xsl:when>
489
+ </xsl:choose>
490
+ </xsl:attribute>
491
+ </item>
492
+ <!-- cruise found objects, including comments we generate to help debug -->
493
+ <!-- NB: * could be just "item", but we generally want all elements -->
494
+ <!-- Strategy: compare @href of each candidate item with the @href of each -->
495
+ <!-- preceding item, and only copy into the result tree if the @href is "new" -->
496
+ <!-- Duplication removal inspired by: -->
497
+ <!-- XSLT Cookbook, 2nd Edition, Copyright 2006, O'Reilly Media, Inc. -->
498
+ <!-- Recipe 5.1, Ignoring Duplicate Elements -->
499
+ <!-- www.oreilly.com/library/view/xslt-cookbook/0596003722/ch04s03.html -->
500
+ <xsl:for-each select="($discovery-manifest/*|$discovery-manifest/comment())[not(@href = preceding::*/@href)]">
501
+ <xsl:copy-of select="."/>
502
+ </xsl:for-each>
503
+ <xsl:if test="$b-has-endnotes">
504
+ <item id="endnotes" href="{$xhtml-dir}/{$endnote-file}"
505
+ media-type="application/xhtml+xml">
506
+ <xsl:if test="$b-endnotes-have-math">
507
+ <xsl:attribute name="properties">
508
+ <xsl:choose>
509
+ <xsl:when test="$math.format = 'mml' or
510
+ $math.format = 'kindle'">
511
+ <xsl:text>mathml</xsl:text>
512
+ </xsl:when>
513
+ <xsl:when test="$math.format = 'svg'">
514
+ <xsl:text>svg</xsl:text>
515
+ </xsl:when>
516
+ </xsl:choose>
517
+ </xsl:attribute>
518
+ </xsl:if>
519
+ </item>
520
+ </xsl:if>
521
+ </manifest>
522
+ </xsl:template>
523
+
524
+ <!-- Traverse elements only in subtree, looking for -->
525
+ <!-- items that will be files to list in the manifest -->
526
+ <xsl:template match="*" mode="manifest">
527
+ <xsl:apply-templates select="*" mode="manifest" />
528
+ </xsl:template>
529
+
530
+ <!-- Build an empty item element for each CHAPTER, -->
531
+ <!-- FRONTMATTER, BACKMATTER, -->
532
+ <!-- Don't include "backmatter", all summary -->
533
+ <!-- recurse into contents for image files, etc -->
534
+ <!-- See "Core Media Type Resources" -->
535
+ <!-- Add to spine identically -->
536
+ <!-- Specialized divisions are terminal in back -->
537
+ <!-- matter, and only a separate file when within -->
538
+ <!-- a "chapter", at level 2 -->
539
+ <xsl:template match="frontmatter|colophon|biography|dedication|acknowledgement|preface|chapter|chapter/conclusion|chapter/outcomes[preceding-sibling::section]|appendix|index|section|exercises|chapter/reading-questions|chapter/solutions|appendix/solutions|backmatter/solutions|chapter/references|appendix/references|backmatter/references" mode="manifest">
540
+ <!-- Annotate manifest entries -->
541
+ <xsl:comment>
542
+ <xsl:apply-templates select="." mode="long-name" />
543
+ </xsl:comment>
544
+ <!-- one item element per chapter -->
545
+ <xsl:element name="item" xmlns="http://www.idpf.org/2007/opf">
546
+ <xsl:apply-templates select="." mode="html-id-attribute"/>
547
+ <!-- properties are iff, so validator complains if extra -->
548
+ <!-- condition on math presence for svg/mathml property -->
549
+ <!-- TODO: use a parameter switch for output style -->
550
+ <!-- Study: https://github.com/w3c/epubcheck/issues/420 -->
551
+ <!-- Processing with page2svg makes it appear SVG images exist -->
552
+ <!-- Set properties="svg" or properties="mathml" when a -->
553
+ <!-- file contains math in one of thse formats. -->
554
+ <!-- There are simply too many edge cases to do this -->
555
+ <!-- based on document structure alone, so read the actual -->
556
+ <!-- XHTML files we've already written and look for svg -->
557
+ <!-- or math tags in them. -->
558
+ <xsl:variable name="has-math">
559
+ <xsl:variable name="contents-filename">
560
+ <xsl:value-of select="$tmpdir" />
561
+ <xsl:text>/</xsl:text>
562
+ <xsl:value-of select="$content-dir" />
563
+ <xsl:text>/</xsl:text>
564
+ <xsl:value-of select="$xhtml-dir" />
565
+ <xsl:text>/</xsl:text>
566
+ <xsl:apply-templates select="."
567
+ mode="containing-filename"/>
568
+ </xsl:variable>
569
+ <xsl:variable name="filedata"
570
+ select="document($contents-filename)"/>
571
+ <xsl:choose>
572
+ <xsl:when test="$filedata//svg:svg|$filedata//math:math">
573
+ <xsl:text>true</xsl:text>
574
+ </xsl:when>
575
+ <xsl:otherwise>
576
+ <xsl:text>false</xsl:text>
577
+ </xsl:otherwise>
578
+ </xsl:choose>
579
+ </xsl:variable>
580
+ <xsl:variable name="b-has-math" select="$has-math = 'true'" />
581
+ <xsl:if test="$b-has-math">
582
+ <xsl:attribute name="properties">
583
+ <xsl:choose>
584
+ <xsl:when test="$math.format = 'mml' or $math.format = 'kindle'">
585
+ <xsl:text>mathml</xsl:text>
586
+ </xsl:when>
587
+ <xsl:when test="$math.format = 'svg'">
588
+ <xsl:text>svg</xsl:text>
589
+ </xsl:when>
590
+ </xsl:choose>
591
+ </xsl:attribute>
592
+ </xsl:if>
593
+ <!-- TODO: coordinate with manifest/script on xhtml extension -->
594
+ <xsl:attribute name="href">
595
+ <xsl:value-of select="$xhtml-dir" />
596
+ <xsl:text>/</xsl:text>
597
+ <xsl:apply-templates select="." mode="containing-filename" />
598
+ </xsl:attribute>
599
+ <xsl:attribute name="media-type">
600
+ <xsl:text>application/xhtml+xml</xsl:text>
601
+ </xsl:attribute>
602
+ </xsl:element>
603
+ <!-- recurse, eg from chapter down into a section -->
604
+ <xsl:apply-templates select="*" mode="manifest" />
605
+ </xsl:template>
606
+
607
+ <!-- How the files are organized into the spine -->
608
+ <!-- Book opens to first time linear="no" -->
609
+ <!-- Each must reference an id in the manifest -->
610
+ <xsl:template name="package-spine">
611
+ <spine xmlns="http://www.idpf.org/2007/opf">
612
+ <itemref idref="cover-page" linear="yes" />
613
+ <itemref idref="table-contents" linear="yes"/>
614
+ <xsl:apply-templates select="$document-root" mode="spine" />
615
+ <xsl:if test="$b-has-endnotes">
616
+ <itemref idref="endnotes" linear="no" />
617
+ </xsl:if>
618
+ </spine>
619
+ </xsl:template>
620
+
621
+ <!-- Traverse subtree, looking for items to include -->
622
+ <xsl:template match="*" mode="spine">
623
+ <xsl:apply-templates select="*" mode="spine" />
624
+ </xsl:template>
625
+
626
+ <!-- Simplest scenario is spine matches manifest, all with @linear="yes" -->
627
+ <!-- Specialized divisions will only become files in the manifest at -->
628
+ <!-- chunk level 2, in other words, peers of chapters or sections -->
629
+ <!-- (book or chapter/appendix as parent, respectively) -->
630
+ <xsl:template match="frontmatter|colophon|acknowledgement|biography|dedication|preface|chapter|appendix|index|section|exercises[parent::book|parent::chapter|parent::appendix]|reading-questions[parent::book|parent::chapter|parent::appendix]|chapter/solutions|appendix/solutions|backmatter/solutions|chapter/references|appendix/references|backmatter/references|glossary[parent::book|parent::chapter|parent::appendix]|conclusion[parent::chapter]|outcomes[preceding-sibling::section]" mode="spine">
631
+ <xsl:element name="itemref" xmlns="http://www.idpf.org/2007/opf">
632
+ <xsl:attribute name="idref">
633
+ <xsl:apply-templates select="." mode="html-id" />
634
+ </xsl:attribute>
635
+ <xsl:attribute name="linear">
636
+ <xsl:text>yes</xsl:text>
637
+ </xsl:attribute>
638
+ </xsl:element>
639
+ <xsl:apply-templates select="*" mode="spine" />
640
+ </xsl:template>
641
+
642
+ <!-- This template writes out some information necessary -->
643
+ <!-- for successful organization of the necessary files to -->
644
+ <!-- make a complete package for the eventual EPUB. This is -->
645
+ <!-- the actual output of the stylesheet itself. There is -->
646
+ <!-- no namespace information, so when the Python script -->
647
+ <!-- gets this, there is no need for any namespace -->
648
+ <!-- provisions with the lxml library. -->
649
+ <!-- -->
650
+ <!-- Each image filename is a legitimate image in use in the -->
651
+ <!-- EPUB XHTML, but the filename may be duplicated is used -->
652
+ <!-- more than once. That is OK, the only inefficiency is -->
653
+ <!-- that it will simply be copied onto itself. -->
654
+ <xsl:template name="packaging-info">
655
+ <packaging>
656
+ <filename>
657
+ <!-- for actual EPUB file eventually output -->
658
+ <xsl:apply-templates select="$document-root" mode="title-filesafe"/>
659
+ </filename>
660
+ <!-- Information about the cover file to transmit to the Python build routine -->
661
+ <cover source="{$epub-cover-source}" dest="{$epub-cover-dest}">
662
+ <!-- yes/no on if the authored provided a custom image file -->
663
+ <xsl:attribute name="authored-cover">
664
+ <xsl:choose>
665
+ <xsl:when test="$b-authored-cover">
666
+ <xsl:text>yes</xsl:text>
667
+ </xsl:when>
668
+ <xsl:otherwise>
669
+ <xsl:text>no</xsl:text>
670
+ </xsl:otherwise>
671
+ </xsl:choose>
672
+ </xsl:attribute>
673
+ </cover>
674
+ <!-- These may be used in automated creation of a cover image -->
675
+ <title>
676
+ <xsl:apply-templates select="$document-root" mode="title-simple"/>
677
+ </title>
678
+ <subtitle>
679
+ <xsl:apply-templates select="$document-root" mode="subtitle"/>
680
+ </subtitle>
681
+ <author>
682
+ <xsl:apply-templates select="$bibinfo/author" mode="name-list"/>
683
+ </author>
684
+ <!-- Decide what to do with preview images, etc. -->
685
+ <images>
686
+ <xsl:for-each select="$document-root//image">
687
+ <image>
688
+ <!-- filename begins with directories from publisher file -->
689
+ <xsl:attribute name="sourcename">
690
+ <xsl:apply-templates select="." mode="epub-base-filename">
691
+ <xsl:with-param name="purpose" select="'read'"/>
692
+ </xsl:apply-templates>
693
+ </xsl:attribute>
694
+ <xsl:attribute name="filename">
695
+ <xsl:apply-templates select="." mode="epub-base-filename">
696
+ <xsl:with-param name="purpose" select="'write'"/>
697
+ </xsl:apply-templates>
698
+ </xsl:attribute>
699
+ </image>
700
+ </xsl:for-each>
701
+ </images>
702
+ </packaging>
703
+ </xsl:template>
704
+
705
+ <!-- Include the appropriate CSS file depending on output -->
706
+ <xsl:template name="epub-kindle-css">
707
+ <xsl:choose>
708
+ <xsl:when test="$b-kindle">
709
+ <link href="../{$css-dir}/kindle.css" rel="stylesheet" type="text/css"/>
710
+ </xsl:when>
711
+ <xsl:otherwise>
712
+ <link href="../{$css-dir}/epub.css" rel="stylesheet" type="text/css"/>
713
+ </xsl:otherwise>
714
+ </xsl:choose>
715
+ </xsl:template>
716
+
717
+ <!-- ############# -->
718
+ <!-- Content files -->
719
+ <!-- ############# -->
720
+
721
+ <!-- "coverpage.html" comes in two flavors: -->
722
+ <!-- -->
723
+ <!-- 1. An author provides a cover image via the publication file and -->
724
+ <!-- then this page has no need of any CSS and the body has a -->
725
+ <!-- very specific (short) form. -->
726
+ <!-- -->
727
+ <!-- 2. No cover image is provided by the author. The core Python -->
728
+ <!-- routines will try very hard to build a simple generic image, -->
729
+ <!-- very similar (but not identical) to what we create here. But -->
730
+ <!-- that process can fail, and when it does, various packaging -->
731
+ <!-- here is backed out. More immediately, we build a simple page -->
732
+ <!-- (with CSS) having title, subtitle, and authors. -->
733
+
734
+ <xsl:template match="frontmatter" mode="epub">
735
+ <exsl:document href="{$content-dir}/{$xhtml-dir}/cover-page.xhtml" method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no">
736
+ <html>
737
+ <xsl:call-template name="html-theme-attributes"/>
738
+ <!-- head element should not be empty -->
739
+ <head>
740
+ <meta charset="utf-8"/>
741
+ <title>
742
+ <xsl:apply-templates select="$document-root" mode="title-full"/>
743
+ </title>
744
+ <xsl:if test="not($b-authored-cover)">
745
+ <xsl:call-template name="epub-kindle-css"/>
746
+ </xsl:if>
747
+ </head>
748
+ <body class="ptx-content epub">
749
+ <xsl:choose>
750
+ <xsl:when test="$b-authored-cover">
751
+ <section epub:type="cover">
752
+ <!-- https://ebookflightdeck.com/handbook/coverimage -->
753
+ <img src="{$epub-cover-dest}" alt="cover image"/>
754
+ </section>
755
+ </xsl:when>
756
+ <xsl:otherwise>
757
+ <section epub:type="cover" class="frontmatter">
758
+ <h1 class="heading">
759
+ <span class="title">
760
+ <xsl:apply-templates select="$document-root" mode="title-full" />
761
+ <xsl:if test="$document-root/subtitle">
762
+ <xsl:text>:</xsl:text>
763
+ </xsl:if>
764
+ </span>
765
+ <xsl:if test="$document-root/subtitle">
766
+ <xsl:text> </xsl:text>
767
+ <span class="subtitle">
768
+ <xsl:apply-templates select="$document-root" mode="subtitle" />
769
+ </span>
770
+ </xsl:if>
771
+ </h1>
772
+ <div class="author">
773
+ <div class="author-name">
774
+ <xsl:apply-templates select="$bibinfo/author" mode="name-list"/>
775
+ </div>
776
+ </div>
777
+ </section>
778
+ </xsl:otherwise>
779
+ </xsl:choose>
780
+ </body>
781
+ </html>
782
+ </exsl:document>
783
+ <exsl:document href="{$content-dir}/{$xhtml-dir}/table-contents.xhtml" method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no">
784
+ <html xmlns:epub="http://www.idpf.org/2007/ops">
785
+ <xsl:call-template name="html-theme-attributes"/>
786
+ <head>
787
+ <meta charset="utf-8"/>
788
+ <xsl:call-template name="epub-kindle-css"/>
789
+ <title>Table of Contents</title>
790
+ </head>
791
+ <body class="ptx-content epub" epub:type="frontmatter">
792
+ <nav epub:type="toc" id="toc">
793
+ <h1>Table of Contents</h1>
794
+ <ol>
795
+ <!-- top-level divisions, for a book -->
796
+ <xsl:for-each select="$document-root/chapter[$b-is-book]|$document-root/section[$b-is-article]">
797
+ <li>
798
+ <xsl:element name="a">
799
+ <xsl:attribute name="href">
800
+ <xsl:apply-templates select="." mode="containing-filename" />
801
+ </xsl:attribute>
802
+ <xsl:apply-templates select="." mode="title-simple" />
803
+ </xsl:element>
804
+ </li>
805
+ </xsl:for-each>
806
+ <!-- following divisions identical for book v. article -->
807
+ <xsl:if test="$document-root/backmatter/appendix|$document-root/backmatter/solutions">
808
+ <li class="no-marker">
809
+ <span>Appendices</span>
810
+ <ol type="A">
811
+ <xsl:for-each select="$document-root/backmatter/appendix|$document-root/backmatter/solutions">
812
+ <li>
813
+ <xsl:element name="a">
814
+ <xsl:attribute name="href">
815
+ <xsl:apply-templates select="." mode="containing-filename" />
816
+ </xsl:attribute>
817
+ <xsl:apply-templates select="." mode="title-simple" />
818
+ </xsl:element>
819
+ </li>
820
+ </xsl:for-each>
821
+ </ol>
822
+ </li>
823
+ </xsl:if>
824
+ <xsl:for-each select="$document-root/backmatter/references|$document-root/backmatter/index">
825
+ <li class="no-marker">
826
+ <xsl:element name="a">
827
+ <xsl:attribute name="href">
828
+ <xsl:apply-templates select="." mode="containing-filename" />
829
+ </xsl:attribute>
830
+ <xsl:apply-templates select="." mode="title-simple" />
831
+ </xsl:element>
832
+ </li>
833
+ </xsl:for-each>
834
+ </ol>
835
+ </nav>
836
+ </body>
837
+ </html>
838
+ </exsl:document>
839
+ </xsl:template>
840
+
841
+ <!-- An abstract named template accepts input text and -->
842
+ <!-- output text, then wraps it for the Sage Cell Server -->
843
+ <xsl:template match="sage" mode="sage-active-markup">
844
+ <xsl:param name="in" />
845
+ <xsl:param name="out" />
846
+ <xsl:if test="$in!=''">
847
+ <pre class="code input">
848
+ <xsl:value-of select="$in" />
849
+ </pre>
850
+ </xsl:if>
851
+ <xsl:if test="$out!=''">
852
+ <pre class="code output">
853
+ <xsl:value-of select="$out" />
854
+ </pre>
855
+ </xsl:if>
856
+ </xsl:template>
857
+
858
+ <!-- An abstract named template accepts input text -->
859
+ <!-- and provides the display class, so untouchable -->
860
+ <xsl:template name="sage-display-markup">
861
+ <xsl:param name="in" />
862
+ <xsl:if test="$in!=''">
863
+ <pre>
864
+ <xsl:value-of select="$in" />
865
+ </pre>
866
+ </xsl:if>
867
+ </xsl:template>
868
+
869
+ <!-- ###### -->
870
+ <!-- Images -->
871
+ <!-- ###### -->
872
+
873
+ <!-- We assume each image is a raster image or an SVG -->
874
+ <!-- Raster: @source has an extension (eg PNG) -->
875
+ <!-- Vector/SVG: @source, no extension -->
876
+ <!-- Code: eg image/asymptote -->
877
+ <!-- Need to add to manifest accurately, -->
878
+ <!-- and also include into source -->
879
+
880
+ <!-- Base filename for an image, -->
881
+ <!-- mostly handling the @source case -->
882
+
883
+ <!-- Parametrized by "read": -->
884
+ <!-- 'read' produces path to source file in input folder tree -->
885
+ <!-- 'write' produces path to file in output folder tree -->
886
+ <xsl:template match="image" mode="epub-base-filename">
887
+ <xsl:param name="purpose"/>
888
+
889
+ <xsl:choose>
890
+ <xsl:when test="@source">
891
+ <xsl:variable name="extension">
892
+ <xsl:call-template name="file-extension">
893
+ <xsl:with-param name="filename" select="@source" />
894
+ </xsl:call-template>
895
+ </xsl:variable>
896
+ <!-- PDF LaTeX, SVG HTML, PNG Kindle if not indicated -->
897
+ <xsl:choose>
898
+ <xsl:when test="$purpose = 'read'">
899
+ <xsl:value-of select="$external-directory-source"/>
900
+ </xsl:when>
901
+ <xsl:when test="$purpose = 'write'">
902
+ <xsl:value-of select="$external-directory"/>
903
+ </xsl:when>
904
+ </xsl:choose>
905
+ <xsl:apply-templates select="@source" />
906
+ <xsl:if test="$extension=''">
907
+ <xsl:call-template name="best-file-extension"/>
908
+ </xsl:if>
909
+ </xsl:when>
910
+ <!-- Various interactive bits get static images as replacements for -->
911
+ <!-- interactivity and become images with filenames relative to the -->
912
+ <!-- *generated* directories, and hence are of predictable image types -->
913
+ <!-- -->
914
+ <!-- Audio, Video, Interactive: automatic screenshot preview, PNG -->
915
+ <!-- Audio, Video, Interactive: QR code, PNG -->
916
+ <!-- Video Play Button (FigLeaf): PNG stock image -->
917
+ <!-- YouTube: provided video preview, JPG -->
918
+ <!-- -->
919
+ <!-- Author-supplied images to be used as previews for audio, video, -->
920
+ <!-- and interactive become image/@source and so are handled above -->
921
+ <!-- and are "external", not "generated" -->
922
+ <xsl:when test="@pi:generated">
923
+ <xsl:variable name="extension">
924
+ <xsl:call-template name="file-extension">
925
+ <xsl:with-param name="filename" select="@pi:generated" />
926
+ </xsl:call-template>
927
+ </xsl:variable>
928
+ <xsl:choose>
929
+ <xsl:when test="$purpose = 'read'">
930
+ <xsl:value-of select="$generated-directory-source"/>
931
+ </xsl:when>
932
+ <xsl:when test="$purpose = 'write'">
933
+ <xsl:value-of select="$generated-directory"/>
934
+ </xsl:when>
935
+ </xsl:choose>
936
+ <!-- Maybe with an extension and OK. If not, -->
937
+ <!-- we provide a good extension right now. -->
938
+ <xsl:value-of select="@pi:generated"/>
939
+ <!-- MOM generated files come extensionless since -->
940
+ <!-- we/MOM can make them in all desirable formats, -->
941
+ <!-- so we switch on Kindle or not. -->
942
+ <xsl:if test="$extension = ''">
943
+ <xsl:call-template name="best-file-extension"/>
944
+ </xsl:if>
945
+ </xsl:when>
946
+ <xsl:when test="latex-image|sageplot|asymptote|mermaid|pf:prefigure">
947
+ <xsl:choose>
948
+ <xsl:when test="$purpose = 'read'">
949
+ <xsl:value-of select="$generated-directory-source"/>
950
+ </xsl:when>
951
+ <xsl:when test="$purpose = 'write'">
952
+ <xsl:value-of select="$generated-directory"/>
953
+ </xsl:when>
954
+ </xsl:choose>
955
+ <!-- All of the following "source language" images should -->
956
+ <!-- be available as vector graphics, and thus in SVG format, -->
957
+ <!-- or convertible to SVG format. We prefer SVG format. -->
958
+ <!-- However, Kindle is hostile to SVG, so we need to also -->
959
+ <!-- have PNG versions. -->
960
+ <xsl:choose>
961
+ <xsl:when test="latex-image">
962
+ <xsl:text>latex-image/</xsl:text>
963
+ <xsl:apply-templates select="latex-image" mode="image-source-basename"/>
964
+ <xsl:call-template name="best-file-extension"/>
965
+ </xsl:when>
966
+ <!-- A 2D "sageplot" is just like any other image built from source -->
967
+ <xsl:when test="sageplot[not(@variant) or (@variant = '2d')]">
968
+ <xsl:text>sageplot/</xsl:text>
969
+ <xsl:apply-templates select="sageplot" mode="image-source-basename"/>
970
+ <xsl:call-template name="best-file-extension"/>
971
+ </xsl:when>
972
+ <!-- NB: a 3D "sageplot" only comes in PNG and HTML variants, -->
973
+ <!-- so we cannot manufacture the preferable SVG version, -->
974
+ <!-- and the PNG is just fine for a Kindle build, so we do -->
975
+ <!-- not have to condition on a Kindle build. -->
976
+ <xsl:when test="sageplot[@variant = '3d']">
977
+ <xsl:text>sageplot/</xsl:text>
978
+ <xsl:apply-templates select="sageplot" mode="image-source-basename"/>
979
+ <xsl:text>.png</xsl:text>
980
+ </xsl:when>
981
+ <xsl:when test="asymptote">
982
+ <xsl:text>asymptote/</xsl:text>
983
+ <xsl:apply-templates select="asymptote" mode="image-source-basename"/>
984
+ <xsl:call-template name="best-file-extension"/>
985
+ </xsl:when>
986
+ <xsl:when test="mermaid">
987
+ <xsl:text>mermaid/</xsl:text>
988
+ <xsl:apply-templates select="mermaid" mode="image-source-basename"/>
989
+ <xsl:call-template name="best-file-extension"/>
990
+ </xsl:when>
991
+ <xsl:when test="pf:prefigure">
992
+ <xsl:text>prefigure/</xsl:text>
993
+ <xsl:apply-templates select="pf:prefigure" mode="image-source-basename"/>
994
+ <xsl:call-template name="best-file-extension"/>
995
+ </xsl:when>
996
+ </xsl:choose>
997
+ </xsl:when>
998
+ <xsl:otherwise>
999
+ <xsl:message>PTX:BUG: image filename not determined in EPUB conversion</xsl:message>
1000
+ <xsl:apply-templates select="." mode="location-report" />
1001
+ </xsl:otherwise>
1002
+ </xsl:choose>
1003
+ </xsl:template>
1004
+
1005
+ <!-- Manifest entry with image file information -->
1006
+ <!-- For each "image" we record basic information in the form the -->
1007
+ <!-- manifest expects (an "item"). Later, duplicate files will be -->
1008
+ <!-- scrubbed from this list based on the @href value, so that a -->
1009
+ <!-- given file is not referenced more than once in the manifest. -->
1010
+ <xsl:template match="image" mode="manifest">
1011
+ <xsl:variable name="extension">
1012
+ <xsl:call-template name="file-extension">
1013
+ <!-- at most one of these two attributes shold be present -->
1014
+ <xsl:with-param name="filename" select="@source|@pi:generated" />
1015
+ </xsl:call-template>
1016
+ </xsl:variable>
1017
+ <!-- item element for manifest -->
1018
+ <xsl:element name="item" namespace="http://www.idpf.org/2007/opf">
1019
+ <!-- internal id of the image -->
1020
+ <xsl:apply-templates select="." mode="html-id-attribute"/>
1021
+ <!-- filename relative to EPUB directory -->
1022
+ <xsl:attribute name="href">
1023
+ <xsl:value-of select="$xhtml-dir" />
1024
+ <xsl:text>/</xsl:text>
1025
+ <xsl:apply-templates select="." mode="epub-base-filename">
1026
+ <xsl:with-param name="purpose" select="'write'"/>
1027
+ </xsl:apply-templates>
1028
+ </xsl:attribute>
1029
+ <!-- media attribute -->
1030
+ <xsl:attribute name="media-type">
1031
+ <xsl:choose>
1032
+ <xsl:when test="@source and $extension='png'">
1033
+ <xsl:text>image/png</xsl:text>
1034
+ </xsl:when>
1035
+ <xsl:when test="@source and ($extension='jpeg' or $extension='jpg')">
1036
+ <xsl:text>image/jpeg</xsl:text>
1037
+ </xsl:when>
1038
+ <xsl:when test="@source and ($extension = 'svg')">
1039
+ <xsl:text>image/svg+xml</xsl:text>
1040
+ </xsl:when>
1041
+ <xsl:when test="@source and ($extension = '')">
1042
+ <xsl:call-template name="best-media-type"/>
1043
+ </xsl:when>
1044
+ <!-- MOM generated images are extensionless -->
1045
+ <xsl:when test="@pi:generated and ($extension = '')">
1046
+ <xsl:call-template name="best-media-type"/>
1047
+ </xsl:when>
1048
+ <!-- QR code, automatic preview, YouuTube fig leaf -->
1049
+ <xsl:when test="@pi:generated and ($extension = 'png')">
1050
+ <xsl:text>image/png</xsl:text>
1051
+ </xsl:when>
1052
+ <!-- YouTube-provided previews (always just *.jpg) -->
1053
+ <xsl:when test="@pi:generated and ($extension = 'jpg')">
1054
+ <xsl:text>image/jpeg</xsl:text>
1055
+ </xsl:when>
1056
+ <xsl:when test="latex-image|asymptote|mermaid|pf:prefigure">
1057
+ <xsl:text>image/svg+xml</xsl:text>
1058
+ </xsl:when>
1059
+ <!-- A 2D "sageplot" is just like any other image built from source -->
1060
+ <xsl:when test="sageplot[not(@variant) or (@variant = '2d')]">
1061
+ <xsl:text>image/svg+xml</xsl:text>
1062
+ </xsl:when>
1063
+ <!-- NB: a 3D "sageplot" only comes in PNG and HTML variants, -->
1064
+ <!-- so we cannot manufacture the preferable SVG version, -->
1065
+ <!-- and the PNG is just fine for a Kindle build, so we do -->
1066
+ <!-- not have to condition on a Kindle build. -->
1067
+ <xsl:when test="sageplot[@variant = '3d']">
1068
+ <xsl:text>image/png</xsl:text>
1069
+ </xsl:when>
1070
+ <xsl:otherwise>
1071
+ <xsl:message>PTX:BUG: EPUB image media-type not determined</xsl:message>
1072
+ <xsl:apply-templates select="." mode="location-report" />
1073
+ </xsl:otherwise>
1074
+ </xsl:choose>
1075
+ </xsl:attribute>
1076
+ </xsl:element>
1077
+ <!-- likely a dead-end here, but we examine children anyway -->
1078
+ <xsl:apply-templates select="*" mode="manifest" />
1079
+ </xsl:template>
1080
+
1081
+ <!-- Kindle has an upper limit of 25 or so SVG images. Not sure the -->
1082
+ <!-- rationale. Anyway, we prefer (our) SVG images which are generally -->
1083
+ <!-- very tight and compact and scale nicely. When we know that an image -->
1084
+ <!-- (source, or generated) does not have an extension, then we are free -->
1085
+ <!-- to choose, on the assumption that such files have actually been -->
1086
+ <!-- generated. These utility templates *only* depend on a Kindle switch. -->
1087
+
1088
+ <xsl:template name="best-file-extension">
1089
+ <xsl:choose>
1090
+ <xsl:when test="$b-kindle">
1091
+ <xsl:text>.png</xsl:text>
1092
+ </xsl:when>
1093
+ <xsl:otherwise>
1094
+ <xsl:text>.svg</xsl:text>
1095
+ </xsl:otherwise>
1096
+ </xsl:choose>
1097
+ </xsl:template>
1098
+
1099
+ <xsl:template name="best-media-type">
1100
+ <xsl:choose>
1101
+ <xsl:when test="$b-kindle">
1102
+ <xsl:text>image/png</xsl:text>
1103
+ </xsl:when>
1104
+ <xsl:otherwise>
1105
+ <xsl:text>image/svg+xml</xsl:text>
1106
+ </xsl:otherwise>
1107
+ </xsl:choose>
1108
+ </xsl:template>
1109
+
1110
+ <!-- Now the actual image inclusion where born -->
1111
+ <xsl:template match="image">
1112
+ <xsl:element name="img">
1113
+ <xsl:attribute name="src">
1114
+ <xsl:apply-templates select="." mode="epub-base-filename">
1115
+ <xsl:with-param name="purpose" select="'write'"/>
1116
+ </xsl:apply-templates>
1117
+ </xsl:attribute>
1118
+ <xsl:if test="@width">
1119
+ <xsl:attribute name="style">
1120
+ <xsl:text>width: </xsl:text>
1121
+ <xsl:value-of select="@width" />
1122
+ <xsl:text>; margin: 0 auto;</xsl:text>
1123
+ </xsl:attribute>
1124
+ </xsl:if>
1125
+ </xsl:element>
1126
+ <xsl:if test="description">
1127
+ <details class="image-description">
1128
+ <summary>
1129
+ <xsl:call-template name="insert-symbol">
1130
+ <xsl:with-param name="name" select="'description'"/>
1131
+ </xsl:call-template>
1132
+ </summary>
1133
+ <div>
1134
+ <xsl:apply-templates select="description"/>
1135
+ </div>
1136
+ </details>
1137
+ </xsl:if>
1138
+ </xsl:template>
1139
+
1140
+ <!-- ######### -->
1141
+ <!-- OverRides -->
1142
+ <!-- ######### -->
1143
+
1144
+ <!-- Knowls -->
1145
+ <!-- Nothing should be knowled, since we do not have Javascript for it -->
1146
+ <!-- We kill both cross-reference and born-hidden knowls by overriding -->
1147
+ <!-- templates designed partially for this purpose -->
1148
+ <xsl:template match="*" mode="xref-as-knowl">
1149
+ <xsl:value-of select="false()" />
1150
+ </xsl:template>
1151
+
1152
+ <!-- Everything configurable by author, 2020-01-02 -->
1153
+ <!-- Roughly in the order of old html.knowl.* switches -->
1154
+ <!-- Similar HTML templates return string for boolean test -->
1155
+ <xsl:template match="&THEOREM-LIKE;|&PROOF-LIKE;|&DEFINITION-LIKE;|&EXAMPLE-LIKE;|&PROJECT-LIKE;|task|&FIGURE-LIKE;|&REMARK-LIKE;|&GOAL-LIKE;|exercise" mode="is-hidden">
1156
+ <xsl:text>false</xsl:text>
1157
+ </xsl:template>
1158
+
1159
+
1160
+ <!-- ######## -->
1161
+ <!-- Endnotes -->
1162
+ <!-- ######## -->
1163
+
1164
+ <!-- Use "EPUB 3 Structural Semantics Vocabulary" -->
1165
+ <!-- to get desired behavior from e-reader system -->
1166
+ <!-- https://help.apple.com/itc/booksassetguide/en.lproj/itccf8ecf5c8.html -->
1167
+
1168
+ <!-- Note: Kindle wants "bidirectional" links, so you can "go back" -->
1169
+ <!-- from the content to the source location. These HTML ids are -->
1170
+ <!-- recognizable by their "-kindle-return" suffix. See 10.3.12: -->
1171
+ <!-- https://kindlegen.s3.amazonaws.com/AmazonKindlePublishingGuidelines.pdf -->
1172
+
1173
+ <!-- Asides -->
1174
+ <!-- EPUB has a semi-natural mechanism for this, though -->
1175
+ <!-- the text we drop could use some work. The marker, -->
1176
+ <!-- a simple title/paragraph, tostyle minimally -->
1177
+ <xsl:template match="&ASIDE-LIKE;">
1178
+ <xsl:variable name="hid">
1179
+ <xsl:apply-templates select="." mode="html-id" />
1180
+ </xsl:variable>
1181
+ <xsl:element name="div">
1182
+ <xsl:attribute name="class">
1183
+ <xsl:text>para</xsl:text>
1184
+ </xsl:attribute>
1185
+ <xsl:attribute name="id">
1186
+ <xsl:value-of select="$hid"/>
1187
+ </xsl:attribute>
1188
+ <a class="url" epub:type="noteref" href="{$endnote-file}#{$hid}">
1189
+ <!-- Older Kindles don't always support pop-ups, so -->
1190
+ <!-- create infrastructure for endnotes to jump back-->
1191
+ <xsl:if test="$b-kindle">
1192
+ <xsl:attribute name="id">
1193
+ <xsl:value-of select="$hid"/>
1194
+ <xsl:text>-kindle-return</xsl:text>
1195
+ </xsl:attribute>
1196
+ </xsl:if>
1197
+ <xsl:apply-templates select="." mode="heading-simple" />
1198
+ </a>
1199
+ </xsl:element>
1200
+ </xsl:template>
1201
+
1202
+ <!-- The content, unwrapped from HTML infrastructure -->
1203
+ <xsl:template match="&ASIDE-LIKE;" mode="endnote-content">
1204
+ <xsl:variable name="hid">
1205
+ <xsl:apply-templates select="." mode="html-id" />
1206
+ </xsl:variable>
1207
+ <!-- Older Kindles don't always support pop-ups, so -->
1208
+ <!-- create infrastructure for endnotes to jump back-->
1209
+ <xsl:if test="$b-kindle">
1210
+ <a epub:type="noteref">
1211
+ <xsl:attribute name="href">
1212
+ <xsl:apply-templates select="." mode="containing-filename"/>
1213
+ <xsl:text>#</xsl:text>
1214
+ <xsl:value-of select="$hid"/>
1215
+ <xsl:text>-kindle-return</xsl:text>
1216
+ </xsl:attribute>
1217
+ <xsl:apply-templates select="." mode="heading-full"/>
1218
+ </a>
1219
+ </xsl:if>
1220
+ <aside epub:type="footnote" id="{$hid}">
1221
+ <!-- mode="body" gets too much CSS -->
1222
+ <xsl:apply-templates select="." mode="wrapped-content"/>
1223
+ </aside>
1224
+ </xsl:template>
1225
+
1226
+ <!-- Footnotes -->
1227
+ <!-- First disable the "footnote" popping routine used to -->
1228
+ <!-- move the content out of HTML structures where it is -->
1229
+ <!-- not welcome (e.g a "p" inside a "p"). -->
1230
+ <xsl:template match="*" mode="pop-footnote-text"/>
1231
+
1232
+ <!-- Drop a marker as a superscript -->
1233
+ <xsl:template match="fn">
1234
+ <xsl:variable name="hid">
1235
+ <xsl:apply-templates select="." mode="html-id" />
1236
+ </xsl:variable>
1237
+ <!-- drop cross-reference, super-scripted, spaced -->
1238
+ <xsl:element name="sup">
1239
+ <xsl:attribute name="id">
1240
+ <xsl:apply-templates select="." mode="html-id" />
1241
+ </xsl:attribute>
1242
+ <a epub:type="noteref" href="{$endnote-file}#{$hid}">
1243
+ <xsl:if test="$b-kindle">
1244
+ <xsl:attribute name="id">
1245
+ <xsl:value-of select="$hid"/>
1246
+ <xsl:text>-kindle-return</xsl:text>
1247
+ </xsl:attribute>
1248
+ </xsl:if>
1249
+ <xsl:apply-templates select="." mode="serial-number" />
1250
+ </a>
1251
+ </xsl:element>
1252
+ </xsl:template>
1253
+
1254
+ <!-- The content. -->
1255
+ <xsl:template match="fn" mode="endnote-content">
1256
+ <xsl:variable name="hid">
1257
+ <xsl:apply-templates select="." mode="html-id" />
1258
+ </xsl:variable>
1259
+ <aside epub:type="footnote" id="{$hid}">
1260
+ <xsl:choose>
1261
+ <xsl:when test="$b-kindle">
1262
+ <a epub:type="noteref">
1263
+ <xsl:attribute name="href">
1264
+ <xsl:apply-templates select="." mode="containing-filename"/>
1265
+ <xsl:text>#</xsl:text>
1266
+ <xsl:value-of select="$hid"/>
1267
+ <xsl:text>-kindle-return</xsl:text>
1268
+ </xsl:attribute>
1269
+ <xsl:apply-templates select="." mode="serial-number"/>
1270
+ </a>
1271
+ </xsl:when>
1272
+ <xsl:otherwise>
1273
+ <xsl:apply-templates select="." mode="serial-number"/>
1274
+ </xsl:otherwise>
1275
+ </xsl:choose>
1276
+ <xsl:text>. </xsl:text>
1277
+ <!-- process as mixed-content, don't yet allow paragraphs -->
1278
+ <xsl:apply-templates select="node()" />
1279
+ </aside>
1280
+ </xsl:template>
1281
+
1282
+ <!-- BackMatter Endnotes page -->
1283
+ <xsl:template name="endnotes">
1284
+ <!-- No footnotes or asides, don't bother -->
1285
+ <xsl:if test="$b-has-endnotes">
1286
+ <!-- cribbed from "file-wrap" elsewhere -->
1287
+ <exsl:document href="{$content-dir}/{$xhtml-dir}/{$endnote-file}" method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no">
1288
+ <html>
1289
+ <xsl:call-template name="html-theme-attributes"/>
1290
+ <head>
1291
+ <xsl:text>&#xa;</xsl:text> <!-- a little formatting help -->
1292
+ <xsl:call-template name="converter-blurb-html" />
1293
+ <xsl:call-template name="epub-kindle-css"/>
1294
+ <title>Endnotes</title>
1295
+ </head>
1296
+ <!-- use class to repurpose HTML CSS work -->
1297
+ <body class="ptx-content epub">
1298
+ <h4>Endnotes</h4>
1299
+ <!-- structure according to footnote level -->
1300
+ <xsl:apply-templates select="$document-root//fn|$document-root//aside|$document-root//biographical|$document-root//historical" mode="endnote-content"/>
1301
+ </body>
1302
+ </html>
1303
+ </exsl:document>
1304
+ </xsl:if>
1305
+ </xsl:template>
1306
+
1307
+
1308
+ <!-- ################ -->
1309
+ <!-- Subsidiary Items -->
1310
+ <!-- ################ -->
1311
+
1312
+ <!-- These tend to "hang" off other structures and/or are routinely -->
1313
+ <!-- rendered as knowls. So we turn off automatic knowlization -->
1314
+ <xsl:template match="&SOLUTION-LIKE;" mode="is-hidden">
1315
+ <xsl:text>false</xsl:text>
1316
+ </xsl:template>
1317
+
1318
+ <!-- ##### -->
1319
+ <!-- Icons -->
1320
+ <!-- ##### -->
1321
+
1322
+ <!-- Unicode characters will relieve necessity of -->
1323
+ <!-- Font Awesome CSS loading, $icon-table is in -common -->
1324
+ <xsl:template match="icon">
1325
+ <!-- the name attribute of the "icon" in text as a string -->
1326
+ <xsl:variable name="icon-name">
1327
+ <xsl:value-of select="@name"/>
1328
+ </xsl:variable>
1329
+
1330
+ <!-- for-each is just one node, but sets context for key() -->
1331
+ <xsl:for-each select="$icon-table">
1332
+ <xsl:value-of select="key('icon-key', $icon-name)/@unicode" />
1333
+ </xsl:for-each>
1334
+ </xsl:template>
1335
+
1336
+ <!-- #### -->
1337
+ <!-- Math -->
1338
+ <!-- #### -->
1339
+
1340
+ <!-- Pluck SVGs from the file full of them, with matching IDs -->
1341
+ <xsl:template match="m|md[mrow]">
1342
+ <!-- NB: math-representation file writes with "visible-id" -->
1343
+ <xsl:variable name="id">
1344
+ <xsl:apply-templates select="." mode="unique-id"/>
1345
+ </xsl:variable>
1346
+ <xsl:variable name="math" select="$math-repr/pi:math[@id = $id]"/>
1347
+ <xsl:variable name="speech" select="$speech-repr/pi:math[@id = $id]"/>
1348
+ <!-- <xsl:message>C:<xsl:value-of select="$math/@context"/>:C</xsl:message> -->
1349
+ <!-- <xsl:copy-of select="$math-repr[../@id = $id]"/> -->
1350
+ <!-- Wrap with a CSS class for MathJax to see before/during processing -->
1351
+ <!-- as to whether or not the math is inline or display. -->
1352
+ <span>
1353
+ <xsl:attribute name="class">
1354
+ <xsl:choose>
1355
+ <xsl:when test="$math/@context = 'inline'">
1356
+ <xsl:text>mjpage</xsl:text>
1357
+ </xsl:when>
1358
+ <xsl:when test="$math/@context = 'displaymath'">
1359
+ <xsl:text>mjpage mjpage__block</xsl:text>
1360
+ </xsl:when>
1361
+ </xsl:choose>
1362
+ </xsl:attribute>
1363
+ <!-- Cannot "xref" to inline math, so we only put HTML id attributes -->
1364
+ <!-- onto display math. This is overkill, we do not examine what is, -->
1365
+ <!-- or is not numbered, to make a finer distinction. An "xref" to a -->
1366
+ <!-- target without a number is likely to fail in other ways. An -->
1367
+ <!--"xref" will not be a knowl, but a URL with fragment being this id. -->
1368
+ <xsl:if test="$math/@context = 'displaymath'">
1369
+ <xsl:apply-templates select="." mode="html-id-attribute"/>
1370
+ </xsl:if>
1371
+ <!-- Finally, drop a "svg" element, "math" element, or ASCII speech -->
1372
+ <xsl:choose>
1373
+ <xsl:when test="$math.format = 'svg'">
1374
+ <xsl:apply-templates select="$math/div[@class = 'svg']/svg:svg" mode="svg-edit">
1375
+ <xsl:with-param name="speech" select="$speech"/>
1376
+ <xsl:with-param name="base-id" select="$id"/>
1377
+ </xsl:apply-templates>
1378
+ </xsl:when>
1379
+ <xsl:when test="$math.format = 'mml'">
1380
+ <xsl:copy-of select="$math/div[@class = 'mathml']/math:math"/>
1381
+ </xsl:when>
1382
+ <!-- Kindle does best with MathML format -->
1383
+ <xsl:when test="$b-kindle">
1384
+ <xsl:copy-of select="$math/div[@class = 'mathml']/math:math"/>
1385
+ </xsl:when>
1386
+ <!-- 2020-07-17: reprs needed a new "span.speech" wrapper -->
1387
+ <xsl:when test="$math.format = 'speech'">
1388
+ <xsl:value-of select="$math/div[@class = 'speech']"/>
1389
+ </xsl:when>
1390
+ </xsl:choose>
1391
+ </span>
1392
+ </xsl:template>
1393
+
1394
+ <!-- Simple text representations of structural elements for -->
1395
+ <!-- head/title, which is really restrictive. -->
1396
+ <xsl:template match="*" mode="type-name-number">
1397
+ <xsl:apply-templates select="." mode="type-name" />
1398
+ <xsl:text> </xsl:text>
1399
+ <xsl:apply-templates select="." mode="number" />
1400
+ </xsl:template>
1401
+
1402
+ <!-- Identity template as a mode coursing through SVGs -->
1403
+ <!-- We are stream editing to satisfy the EPUB standard -->
1404
+ <!-- Mostly killing attrributes -->
1405
+ <xsl:template match="node()|@*" mode="svg-edit">
1406
+ <xsl:copy>
1407
+ <xsl:apply-templates select="node()|@*" mode="svg-edit"/>
1408
+ </xsl:copy>
1409
+ </xsl:template>
1410
+
1411
+ <!-- SVG elements to augment -->
1412
+ <!-- We enrich the main "svg" element with a speech string. -->
1413
+ <!-- 1. Since this is the "entry template" for this mode, -->
1414
+ <!-- this is the only place we accept the "speech" param. -->
1415
+ <!-- 2. MathJax seems to use SVGs inside of SVGs for placing -->
1416
+ <!-- numbers/tags of numbered equations, so we only enrich -->
1417
+ <!-- "top-level" SVG - that is the point of the filter. -->
1418
+ <!-- 3. The id of the math element will be used as the base -->
1419
+ <!-- of (unique) ids necessary to point to the speech. -->
1420
+ <!-- Pattern 11 at: -->
1421
+ <!-- https://www.deque.com/blog/creating-accessible-svgs/ -->
1422
+ <!-- 4. Seems -->
1423
+ <!-- "title" + @aria-labelledby -->
1424
+ <!-- "desc" + @aria-describedby -->
1425
+ <!-- cover all the bases. It is suggested that the two -->
1426
+ <!-- elements alone would be recognized by screen readers. -->
1427
+ <xsl:template match="svg:svg[not(ancestor::svg:svg)]" mode="svg-edit">
1428
+ <xsl:param name="speech"/>
1429
+ <xsl:param name="base-id"/>
1430
+
1431
+ <!-- manufacture id values for consistency, uniqueness -->
1432
+ <xsl:variable name="title-id">
1433
+ <xsl:value-of select="$base-id"/>
1434
+ <xsl:text>-title</xsl:text>
1435
+ </xsl:variable>
1436
+ <xsl:variable name="desc-id">
1437
+ <xsl:value-of select="$base-id"/>
1438
+ <xsl:text>-desc</xsl:text>
1439
+ </xsl:variable>
1440
+
1441
+ <xsl:copy>
1442
+ <!-- attributes first -->
1443
+ <xsl:apply-templates select="@*" mode="svg-edit"/>
1444
+ <xsl:attribute name="role">
1445
+ <xsl:text>img</xsl:text>
1446
+ </xsl:attribute>
1447
+ <xsl:attribute name="aria-labelledby">
1448
+ <xsl:value-of select="$title-id"/>
1449
+ </xsl:attribute>
1450
+ <xsl:attribute name="aria-describedby">
1451
+ <xsl:value-of select="$desc-id"/>
1452
+ </xsl:attribute>
1453
+ <!-- now additional metadata, of sorts -->
1454
+ <xsl:element name="title" namespace="http://www.w3.org/2000/svg">
1455
+ <xsl:attribute name="id">
1456
+ <xsl:value-of select="$title-id"/>
1457
+ </xsl:attribute>
1458
+ <xsl:text>Math Expression</xsl:text>
1459
+ </xsl:element>
1460
+ <xsl:element name="desc" namespace="http://www.w3.org/2000/svg">
1461
+ <xsl:attribute name="id">
1462
+ <xsl:value-of select="$desc-id"/>
1463
+ </xsl:attribute>
1464
+ <xsl:value-of select="$speech"/>
1465
+ </xsl:element>
1466
+ <!-- and all the rest of the nodes -->
1467
+ <xsl:apply-templates select="node()" mode="svg-edit"/>
1468
+ </xsl:copy>
1469
+ </xsl:template>
1470
+
1471
+ <!-- SVG attributes to remove -->
1472
+ <!-- There can be attributes of SVG images produced by MathJax -->
1473
+ <!-- which cause validation errors when used within an EPUB. -->
1474
+ <!-- 2021-09-02: these seem to have gone away in a transition from -->
1475
+ <!-- EPUB 3.0.0 to EPUB 3.2, as reported by epubcheck v4.2.2. We -->
1476
+ <!-- will remove @focusable just as an example, in case there are -->
1477
+ <!-- future changes. -->
1478
+ <xsl:template match="svg:svg/@focusable" mode="svg-edit"/>
1479
+
1480
+ <!-- We don't want any permalinks in epub -->
1481
+ <xsl:template match="*" mode="permalink"/>
1482
+
1483
+ </xsl:stylesheet>